Zum Inhalt springen

Lighttpd

Lighttpd is a fast, secure, and flexible open-source web server optimized for high-performance environments and low resource consumption.

Installation

Debian/Ubuntu

# Install lighttpd
sudo apt update
sudo apt install lighttpd

# Enable service to start on boot
sudo systemctl enable lighttpd

# Start lighttpd
sudo systemctl start lighttpd

# Verify installation
lighttpd -v

# Check status
sudo systemctl status lighttpd

CentOS/RHEL

# Install via EPEL repository
sudo yum install epel-release
sudo yum install lighttpd

# Enable and start
sudo systemctl enable lighttpd
sudo systemctl start lighttpd

macOS

# Install via Homebrew
brew install lighttpd

# Start service
brew services start lighttpd

# Manual start
lighttpd -f /usr/local/etc/lighttpd/lighttpd.conf

Compile from Source

# Download latest version
wget https://www.lighttpd.net/download/lighttpd-1.4.73.tar.gz
tar xzf lighttpd-1.4.73.tar.gz
cd lighttpd-1.4.73

# Configure and compile
./configure --prefix=/opt/lighttpd
make
sudo make install

# Create systemd service or init script
sudo cp ./doc/lighttpd.service /etc/systemd/system/

Basic Commands

# Check version
lighttpd -v

# Validate configuration
lighttpd -t -f /etc/lighttpd/lighttpd.conf

# Start server
sudo systemctl start lighttpd
sudo /etc/init.d/lighttpd start

# Stop server
sudo systemctl stop lighttpd

# Restart server
sudo systemctl restart lighttpd

# Reload configuration (graceful)
sudo systemctl reload lighttpd
sudo /etc/init.d/lighttpd reload

# Check if running
ps aux | grep lighttpd
sudo systemctl is-active lighttpd

Configuration File

Main Configuration Structure

# Location of lighttpd.conf
/etc/lighttpd/lighttpd.conf

Basic Configuration

# lighttpd.conf

# Server modules
server.modules = (
    "mod_indexfile",
    "mod_access",
    "mod_alias",
    "mod_accesslog",
    "mod_compress",
    "mod_dirlisting",
    "mod_fastcgi",
    "mod_rewrite"
)

# Server root (document root)
server.document-root = "/var/www/html"

# Listen on ports
server.port = 80
$SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/ssl/private/server.pem"
}

# Process user/group
server.username = "www-data"
server.groupname = "www-data"

# Server PID file
server.pid-file = "/var/run/lighttpd.pid"

# Error and access logs
server.errorlog = "/var/log/lighttpd/error.log"
accesslog.filename = "/var/log/lighttpd/access.log"

# Default files to serve
index-file.names = (
    "index.html",
    "index.php",
    "index.cgi"
)

# Gzip compression
compress.cache-dir = "/var/cache/lighttpd/compress"
compress.filetype = (
    "text/plain",
    "text/html",
    "text/xml",
    "text/css",
    "text/javascript",
    "application/json"
)

# Timeout settings
server.max-request-size = 2097152
server.max-connections = 1024
server.max-worker = 4
connection.idle-timeout = 300

Virtual Hosts

Single Virtual Host

# Basic virtual host configuration
$HTTP["host"] == "example.com" {
    server.document-root = "/var/www/example.com"
    server.errorlog = "/var/log/lighttpd/example.error.log"
    accesslog.filename = "/var/log/lighttpd/example.access.log"
}

Multiple Virtual Hosts

# www.example.com
$HTTP["host"] == "www.example.com" {
    server.document-root = "/var/www/example.com"
    server.errorlog = "/var/log/lighttpd/example.error.log"
    accesslog.filename = "/var/log/lighttpd/example.access.log"
}

# api.example.com
$HTTP["host"] == "api.example.com" {
    server.document-root = "/var/www/api.example.com"
    server.errorlog = "/var/log/lighttpd/api.error.log"
    accesslog.filename = "/var/log/lighttpd/api.access.log"
}

# Catch-all redirect
$HTTP["host"] =~ ".*" {
    url.redirect = (
        "^/(.*)" => "https://www.example.com/$1"
    )
}

Virtual Host with SSL

$SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/ssl/private/server.pem"

    $HTTP["host"] == "example.com" {
        server.document-root = "/var/www/example.com"
    }
}

# HTTP to HTTPS redirect
$HTTP["scheme"] == "http" {
    $HTTP["host"] =~ "^(.*)$" {
        url.redirect = ("^/(.*)" => "https://%1/$1")
    }
}

FastCGI Setup

PHP Configuration

# Enable FastCGI module
server.modules += ("mod_fastcgi")

# FastCGI PHP setup
fastcgi.server = (
    ".php" => (
        "localhost" => (
            "socket" => "/run/php/php-fpm.sock",
            "broken-scriptfilename" => "enable"
        )
    )
)

# Alternative TCP socket
fastcgi.server = (
    ".php" => (
        "localhost" => (
            "host" => "127.0.0.1",
            "port" => 9000,
            "broken-scriptfilename" => "enable"
        )
    )
)

Python FastCGI

fastcgi.server = (
    ".py" => (
        "localhost" => (
            "socket" => "/tmp/python-fcgi.sock",
            "check-local" => "disable"
        )
    )
)

URL Rewriting and Redirects

Rewrite Rules

# Enable rewrite module
server.modules += ("mod_rewrite")

# Remove trailing slash
url.rewrite-once = (
    "^(.+)/$" => "$1"
)

# Clean URLs (remove .php extension)
url.rewrite-once = (
    "^/(.*)$" => "/index.php?q=$1"
)

# Pretty URLs for blog
url.rewrite-once = (
    "^/([0-9]+)/([a-z0-9-]+)/?$" => "/post.php?id=$1&slug=$2"
)

# Force HTTPS
$HTTP["scheme"] == "http" {
    url.redirect = (
        "^/(.*)" => "https://%{HTTP_HOST}/$1"
    )
}

Conditional Rewrites

# Rewrite if file doesn't exist
$HTTP["url"] !~ "\.(js|css|png|jpg|gif|ico)$" {
    $HTTP["url"] !~ "^/admin/" {
        url.rewrite-once = (
            "^/(.*)$" => "/index.php?request=$1"
        )
    }
}

SSL/TLS Configuration

Basic HTTPS Setup

# Enable SSL
$SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/ssl/private/server.pem"
    ssl.ca-file = "/etc/ssl/certs/ca-bundle.crt"
}

# Redirect HTTP to HTTPS
$HTTP["scheme"] == "http" {
    $HTTP["host"] =~ "(.*)" {
        url.redirect = ("^/(.*)" => "https://%1/$1")
    }
}

Modern TLS Configuration

$SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/ssl/private/server.pem"
    ssl.ca-file = "/etc/ssl/certs/ca.pem"

    # TLS versions (disable old versions)
    ssl.openssl.ssl-conf-cmd = (
        "MinProtocol" => "TLSv1.2",
        "Options" => "-ServerPreference"
    )

    # Ciphers
    ssl.cipher-list = "HIGH:!aNULL:!MD5"

    # HSTS header
    setenv.add-response-header = (
        "Strict-Transport-Security" => "max-age=31536000; includeSubDomains"
    )
}

Security Configuration

Access Control

# Enable access module
server.modules += ("mod_access")

# Block directory listing
$HTTP["url"] =~ "^/private/" {
    url.access-deny = ("~")
}

# Disable access to certain files
url.access-deny = (
    ".htaccess",
    ".htpasswd",
    "*.conf",
    "*.log"
)

# IP-based access control
$HTTP["remoteip"] == "192.168.1.100" {
    url.access-deny = ("/admin/")
}

# Allow only specific IPs to /admin
$HTTP["url"] =~ "^/admin/" {
    $HTTP["remoteip"] !~ "^(192\.168\.1\.|10\.0\.0\.)" {
        url.access-deny = ("~")
    }
}

Basic Authentication

# Enable auth module
server.modules += ("mod_auth")

# Create password file
# htpasswd -c /etc/lighttpd/.htpasswd username

auth.backend = "plain"
auth.backend.plain.userfile = "/etc/lighttpd/.htpasswd"

# Protect directory
$HTTP["url"] =~ "^/admin/" {
    auth.require = (
        "" => (
            "method" => "basic",
            "realm" => "Admin Area",
            "require" => "user=admin"
        )
    )
}

Performance Tuning

Connection Settings

# Maximum connections
server.max-connections = 2048

# Worker threads
server.max-worker = 4

# Request body size limit
server.max-request-size = 2097152  # 2MB

# Connection timeout
connection.idle-timeout = 300

# Keep-alive timeout
connection.request-timeout = 20

Caching and Compression

# Enable compression
server.modules += ("mod_compress")

compress.cache-dir = "/var/cache/lighttpd/compress"
compress.filetype = (
    "text/plain",
    "text/html",
    "text/xml",
    "text/css",
    "application/javascript",
    "application/json",
    "image/svg+xml"
)

# Set cache headers
setenv.add-response-header = (
    "Cache-Control" => "public, max-age=3600"
)

# Etag configuration
etag.use-inode = "enable"
etag.use-mtime = "enable"
etag.use-size = "enable"

Monitoring and Logging

Log Configuration

# Access log format
accesslog.filename = "/var/log/lighttpd/access.log"
accesslog.format = "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""

# Conditional logging
$HTTP["url"] =~ "\.(css|js|jpg|png|gif)$" {
    accesslog.filename = "/dev/null"
}

# Error log
server.errorlog = "/var/log/lighttpd/error.log"

Log Rotation

# Setup logrotate for lighttpd
sudo cat > /etc/logrotate.d/lighttpd << 'EOF'
/var/log/lighttpd/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        /bin/kill -SIGUSR1 `cat /var/run/lighttpd.pid 2>/dev/null` 2>/dev/null || true
    endscript
}
EOF

Troubleshooting

Check Configuration

# Validate syntax
lighttpd -t -f /etc/lighttpd/lighttpd.conf

# Test start with debug output
sudo lighttpd -D -f /etc/lighttpd/lighttpd.conf

# Verbose output
sudo lighttpd -D -f /etc/lighttpd/lighttpd.conf 2>&1 | head -50

Common Issues

# Port already in use
sudo lsof -i :80
sudo netstat -tulpn | grep :80

# Check permissions
ls -la /var/www/html/
ls -la /var/log/lighttpd/
sudo chown -R www-data:www-data /var/www/

# Check PHP-FPM connection
sudo systemctl status php-fpm
netstat -an | grep 9000

# View recent errors
tail -f /var/log/lighttpd/error.log

# Check resource usage
ps aux | grep lighttpd

Example Configurations

Static Website

server.modules = (
    "mod_indexfile",
    "mod_access",
    "mod_alias",
    "mod_accesslog",
    "mod_compress",
    "mod_dirlisting"
)

server.document-root = "/var/www/html"
server.port = 80
index-file.names = ("index.html")

compress.filetype = (
    "text/plain",
    "text/html",
    "text/css",
    "application/javascript"
)

accesslog.filename = "/var/log/lighttpd/access.log"
server.errorlog = "/var/log/lighttpd/error.log"

PHP Application

server.modules = (
    "mod_indexfile",
    "mod_access",
    "mod_alias",
    "mod_accesslog",
    "mod_fastcgi",
    "mod_rewrite",
    "mod_compress"
)

server.document-root = "/var/www/app"
index-file.names = ("index.php", "index.html")

fastcgi.server = (
    ".php" => (
        "localhost" => (
            "socket" => "/run/php/php-fpm.sock",
            "broken-scriptfilename" => "enable"
        )
    )
)

url.rewrite-once = (
    "^/(.*)$" => "/index.php?request=$1"
)

Reverse Proxy

server.modules += ("mod_proxy")

$HTTP["url"] =~ "^/api" {
    proxy.server = (
        "" => (
            "host" => "127.0.0.1",
            "port" => 3000
        )
    )
}

$HTTP["url"] =~ "^/admin" {
    proxy.server = (
        "" => (
            "host" => "admin-server.internal",
            "port" => 8080
        )
    )
}

Best Practices

  • Always validate configuration before restarting: lighttpd -t -f /etc/lighttpd/lighttpd.conf
  • Use separate log files for different virtual hosts
  • Enable gzip compression for text content to reduce bandwidth
  • Set appropriate timeout values based on application needs
  • Implement HTTP to HTTPS redirect for security
  • Use strong SSL/TLS ciphers and protocols
  • Monitor access and error logs regularly
  • Keep system and lighttpd updated with security patches
  • Test configuration changes in staging before production
  • Use conditional logging to reduce log file size

Resources


Last updated: 2025-03-30