Application Servers AWS

lighttpd on AWS User Guide

| Product: lighttpd

Overview

This guide covers the deployment and configuration of lighttpd on AWS using cloudimg Amazon Machine Images. lighttpd, pronounced lighty, is a secure, fast and flexible web server optimised for high performance environments. Its small memory footprint and efficient event driven design make it an excellent choice for serving static websites and assets, fronting application back ends, and running on resource constrained instances where efficiency matters.

The image installs lighttpd 1.4.x from the operating system package repository, run under systemd as the standard unprivileged www-data account. lighttpd serves HTTPS on port 443 directly through its mod_openssl TLS engine, so there is no separate reverse proxy to run or maintain. Plain HTTP on port 80 is permanently redirected with a 301 status to HTTPS. There is no web interface and no database: a single readable configuration file (/etc/lighttpd/lighttpd.conf plus the cloudimg drop in at /etc/lighttpd/conf-enabled/50-cloudimg.conf) is the whole configuration.

Secure and lean by default. On the first boot of every instance a one shot service generates a unique self signed TLS certificate for that specific instance, so no certificate or private key is ever baked into the image. Directory listing is disabled, so a directory that has no index file returns 403 rather than exposing its contents, and the server version token is suppressed so the software version is not advertised in response headers. lighttpd has no login, so no shared or default credential of any kind ships in the image.

What is included:

  • lighttpd 1.4.x with the mod_openssl TLS module, run under systemd as www-data (lighttpd.service)

  • HTTPS on port 443 served directly by lighttpd through mod_openssl, and HTTP on port 80 permanently redirected (301) to HTTPS

  • A unique self signed certificate generated for each instance on first boot into /etc/lighttpd/certs, so no key material is shared across deployments

  • A hardened default posture: directory listing disabled, the server version token suppressed, and only modern TLS protocol versions enabled

  • A simple document root at /var/www/html with a cloudimg landing page you replace with your own site

  • The whole configuration in readable text you version control, with no database and no administrative web console

Connecting to your instance

Connect over SSH on port 22 using the login user for the operating system variant you launched. lighttpd itself has no login or password.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>

Prerequisites

  • An AWS account with EC2 access, and an SSH key pair in the target region

  • A subscription to the lighttpd listing on AWS Marketplace

  • A security group allowing inbound TCP 22 for administration, and TCP 80 and TCP 443 from the clients that will reach the web server

Recommended instance type: m5.large is a comfortable general purpose default. lighttpd is extremely light; smaller types such as t3.small serve static sites well, and larger types are only needed for very high request volumes.

Step 1: Launch from AWS Marketplace

Find lighttpd on AWS Marketplace, published by cloudimg, and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch. Select your instance type, key pair and subnet, and a security group that allows inbound TCP 443 (HTTPS) and TCP 80 (HTTP, which redirects to HTTPS) from the clients that will reach the server, and TCP 22 for administration.

Step 2: Launch with the AWS CLI

AMI_ID="<lighttpd-ami-id>"     # from the Marketplace listing, for your region
aws ec2 run-instances \
  --image-id "$AMI_ID" \
  --instance-type m5.large \
  --key-name your-key \
  --security-group-ids sg-xxxxxxxx \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=lighttpd1}]'

Open ports 80, 443 and 22 in the instance's security group to the appropriate source ranges.

Step 3: First boot

On first boot the image resolves this instance's IP through EC2 instance metadata, generates a unique self signed TLS certificate into /etc/lighttpd/certs/cloudimg.crt and cloudimg.key, writes the informational note /root/lighttpd-info.txt (recording the served URL), and starts lighttpd. This completes within seconds. SSH in as ubuntu and read the note:

sudo cat /root/lighttpd-info.txt

The note records the served HTTPS URL, the document root, the config paths and the certificate path. lighttpd has no password, so the note holds no secret.

Step 4: Confirm the service is running

lighttpd.service is active, lighttpd -v reports the installed version, and ss confirms it is listening on :443 for HTTPS and :80 for the HTTP redirect.

systemctl is-active lighttpd.service
lighttpd -v
sudo ss -tlnp | grep -E ':80 |:443 '

lighttpd.service reports active, lighttpd -v reports version lighttpd 1.4.74 with ssl support, and ss shows the server listening on port 443 for HTTPS and port 80 for the HTTP to HTTPS redirect on all interfaces

Step 5: Confirm HTTPS and the per instance certificate

lighttpd answers HTTPS on port 443 directly. Request the site over HTTPS on the loopback address (the -k flag accepts the self signed certificate), then inspect the certificate. The response Server header is just lighttpd with no version, and the certificate subject is cloudimg-lighttpd, unique to this instance.

curl -ksI https://127.0.0.1/
sudo openssl x509 -in /etc/lighttpd/certs/cloudimg.crt -noout -subject -issuer -dates

The HTTP status is 200 and the certificate was generated on this instance's first boot, so no private key is shared with any other deployment.

curl over HTTPS to the loopback address returns HTTP 200 with the Server header set to just lighttpd and no version, and openssl shows the per instance self signed certificate with subject and issuer CN cloudimg-lighttpd and a ten year validity window

Step 6: Confirm the HTTP to HTTPS redirect and directory listing hardening

Plain HTTP on port 80 is permanently redirected to HTTPS with a 301 status, so clients are always upgraded to an encrypted connection. Directory listing is disabled, so a directory that has no index file returns 403 Forbidden rather than exposing its contents, while individual files inside it are still served by their path.

curl -sI http://127.0.0.1/
curl -ks -o /dev/null -w 'GET /downloads/ -> %{http_code}\n' https://127.0.0.1/downloads/
curl -ks -o /dev/null -w 'GET /downloads/README.txt -> %{http_code}\n' https://127.0.0.1/downloads/README.txt

The HTTP request returns 301 Moved Permanently with a Location header pointing at https://, the index less /downloads/ directory returns 403, and the file inside it returns 200.

curl over HTTP returns 301 Moved Permanently with a Location header pointing at the HTTPS URL, a request for the index less downloads directory returns 403 Forbidden proving directory listing is disabled, and a request for a file inside that directory returns 200

Step 7: Review the cloudimg configuration

Everything cloudimg adds is in one readable drop in file: it loads mod_openssl, opens the HTTPS socket, defines the 301 redirect and minimises the server token. Directory listing is off because the listing generator module is deliberately not loaded. The base lighttpd configuration lives in /etc/lighttpd/lighttpd.conf.

sudo cat /etc/lighttpd/conf-enabled/50-cloudimg.conf

the cloudimg lighttpd hardening drop in file showing mod_openssl loaded, the server tag set to lighttpd, directory listing off because mod_dirlisting is not loaded, the HTTPS socket on port 443 with ssl engine enabled pointing at the per instance certificate, and the HTTP to HTTPS 301 redirect block

Step 8: Browse to the served site

Browse to https://<instance-public-ip>/ to see the cloudimg landing page served over TLS. Your browser will warn about the self signed certificate until you install your own (Step 10); accept the warning to view the page.

the cloudimg lighttpd landing page rendered in a browser over HTTPS, confirming the web server is running and serving the default document root over TLS

Step 9: Serve your own site

Replace the cloudimg landing page with your own site by writing your files into the document root /var/www/html, or point the document root at a different directory in the configuration. The example below is illustrative; substitute your own content.

# copy your static site into the document root
#   sudo rsync -a ./my-site/ /var/www/html/
# or change server.document-root in /etc/lighttpd/lighttpd.conf to another path,
# then apply the change:
#   sudo systemctl reload lighttpd

lighttpd validates its configuration on reload; if there is a syntax error it keeps serving the previous configuration. You can check the configuration at any time with sudo lighttpd -tt -f /etc/lighttpd/lighttpd.conf.

Step 10: Install a browser trusted certificate for your domain

The image ships with a self signed certificate so HTTPS works immediately. For a browser trusted certificate, point your domain's DNS A record at this instance's public IP, obtain a certificate for your domain from a certificate authority, then point lighttpd at the new certificate and key.

# 1) obtain a certificate + key for your domain (for example with acme.sh or certbot)
# 2) install them, then set in /etc/lighttpd/conf-enabled/50-cloudimg.conf:
#      ssl.pemfile = "/etc/lighttpd/certs/your-domain.crt"
#      ssl.privkey = "/etc/lighttpd/certs/your-domain.key"
# 3) apply the change:
#      sudo systemctl reload lighttpd

Keep the private key readable only by root. lighttpd loads the certificate at start up, so a reload is enough to serve the new certificate.

Step 11: Front an application back end

lighttpd can proxy or FastCGI to an application running on the same instance. Load the relevant module and add a handler in the configuration; the pattern below forwards a path prefix to a local application port.

# enable the proxy module and route a prefix to a local app on your app port:
#   server.modules += ( "mod_proxy" )
#   $HTTP["url"] =~ "^/app/" {
#       proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8080 ) ) )
#   }
# then: sudo systemctl reload lighttpd

For dynamic languages lighttpd also ships FastCGI (mod_fastcgi) and CGI handlers; see the lighttpd documentation for the handler syntax.

Step 12: Security recommendations

  • Restrict the security group to your use case. Allow TCP 443 and TCP 80 only from the networks that need to reach the site, and keep TCP 22 restricted to your administration network.

  • Terminate TLS at a load balancer where appropriate. Place instances behind an Application Load Balancer and use AWS Certificate Manager to provision and auto renew public certificates, or install a CA issued certificate directly on the instance as in Step 10.

  • Replace the self signed certificate for public sites. The per instance self signed certificate secures the transport immediately, but browsers will warn on it; install a CA issued certificate for public facing sites.

  • Keep directory listing disabled. The cloudimg default does not load the directory listing generator, so directories without an index file are never exposed; leave it that way unless you deliberately want a listing for a specific path.

  • Keep the OS patched. Unattended security upgrades remain enabled on the running instance, and lighttpd itself patches with the OS.

Step 13: Support and Licensing

lighttpd is an open source project distributed under the BSD 3 Clause License. This cloudimg image installs the unmodified lighttpd package from the operating system repository. cloudimg provides the packaging, the systemd hardening, the secure by default TLS and redirect configuration, the per instance certificate automation, the paired deploy guide, and 24/7 support.

cloudimg is not affiliated with or endorsed by the lighttpd project. lighttpd is a mark of its respective owner and is used here only to identify the software.

Need Help?

Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.