rss logo

Set Up HTTP File Sharing on Debian with Lighttpd

Lighttpd logo Debian logo

If you have a good Internet connection, you might find it useful to share files with friends using a simple home-made solution.

In this guide, we’ll show how to set up a web server for easy file sharing over the HTTP protocol on GNU/Linux.

The goal is to keep things quick and minimal in terms of configuration.

We’ll be using Lighttpd, an open-source web server optimized for speed-critical environments, while remaining standards-compliant, secure, and flexible. For more information, see the Wikipedia page: https://en.wikipedia.org/wiki/Lighttpd.

In short: low CPU usage and a small memory footprint — exactly what we're looking for.

Installing Lighttpd

  • Install the lighttpd package:
root@host:~# apt update && apt install lighttpd

Edit Configuration File

  • Now edit the main configuration file at /etc/lighttpd/lighttpd.conf, and add these two lines:
server.modules = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
)

server.dir-listing          = "enable"
dir-listing.encoding = "utf-8"
server.document-root        = "/var/www/html"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80

# strict parsing and normalization of URL for consistency and security
# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
# (might need to explicitly set "url-path-2f-decode" = "disable"
#  if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
  "header-strict"           => "enable",# default
  "host-strict"             => "enable",# default
  "host-normalize"          => "enable",# default
  "url-normalize-unreserved"=> "enable",# recommended highly
  "url-normalize-required"  => "enable",# recommended
  "url-ctrls-reject"        => "enable",# recommended
  "url-path-2f-decode"      => "enable",# recommended highly (unless breaks app)
 #"url-path-2f-reject"      => "enable",
  "url-path-dotseg-remove"  => "enable",# recommended highly (unless breaks app)
 #"url-path-dotseg-reject"  => "enable",
 #"url-query-20-plus"       => "enable",# consistency in query string
)

index-file.names            = ( "index.php", "index.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

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

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.conf.pl"
include "/etc/lighttpd/conf-enabled/*.conf"

#server.compat-module-load   = "disable"
server.modules += (
        "mod_compress",
        "mod_dirlisting",
        "mod_staticfile",
)
  • Create an upload directory:
root@host:~# mkdir /var/www/html/upload
  • Create a test file:
root@host:~# echo "titi" > /var/www/html/upload/toto
  • Restart the lighttpd service:
root@host:~# systemctl restart lighttpd.service

Connect to the Web Server

Open your web browser and go to the following URL, replacing IP_ADDRESS with your server’s actual IP: http://IP_ADDRESS/upload. You should see a directory listing with your test file visible under the Index of /upload/ page:

Directory listing of /upload/ folder on Lighttpd server showing a file named toto with details

Securing Your Web Server

Your HTTP server is now up and running. However, if it's accessible from the Internet (which is likely the goal), it means that anyone can potentially connect to it.

Let’s look at a few ways to improve its security.

Restrict Access with a Firewall

You can use iptables or nftables to limit access to specific IP addresses only.

Using iptables

root@host:~# iptables -A INPUT -p tcp --dport 80 -m state -s ALLOWED_IP --state NEW,ESTABLISHED,RELATED -j ACCEPT
root@host:~# iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j DROP

Using nftables

root@host:~# nft add rule ip filter INPUT tcp dport 80 ip saddr ALLOWED_IP ct state new,established counter accept
root@host:~# nft add rule ip filter INPUT tcp dport 80 ct state new,established counter drop

Add Basic Authentication

To prevent unwanted users from accessing your files, you can enable a username/password prompt.

  • Edit the configuration file /etc/lighttpd/lighttpd.conf and add the following lines:
server.modules = (
	"mod_indexfile",
	"mod_access",
	"mod_alias",
 	"mod_redirect",
	"mod_auth",
"mod_authn_file"
)

auth.backend = "plain"
auth.backend.plain.userfile = "/etc/lighttpd/lighttpd-plain.user"

auth.require = ( "/" =>
        (
        "method" => "basic",
        "realm" => "Auth",
        "require" => "valid-user"
        )
)
  • Create a new user by specifying a login:password pair in a plain text file:
root@host:~# echo "agent007:secret" > /etc/lighttpd/lighttpd-plain.user
  • Restart the Lighttpd service to apply the authentication settings:
root@host:~# systemctl restart lighttpd.service
  • Now, when someone accesses the server, a login prompt will appear requesting valid credentials:
Authentication prompt requesting username and password, showing username as 'agent007' and obscured password

Add HTTPS Support

To encrypt traffic between your server and clients, you can enable HTTPS by creating a self-signed certificate and configuring Lighttpd accordingly.

  • Create a Self-Signed Certificate:
root@host:~# openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/ssl/private/lighttpd-selfsigned.key -out /etc/ssl/certs/lighttpd-selfsigned.crt
  • Then combine the key and certificate into a single file:
root@host:~# cat /etc/ssl/private/lighttpd-selfsigned.key /etc/ssl/certs/lighttpd-selfsigned.crt > /etc/lighttpd/cert.pem
  • Restrict access to the certificate file:
root@host:~# chmod 600 /etc/lighttpd/cert.pem
  • Edit /etc/lighttpd/lighttpd.conf and add the following to enable HTTPS:
server.modules = (
	"mod_indexfile",
	"mod_access",
	"mod_alias",
 	"mod_redirect",
	"mod_auth",
	"mod_authn_file",
	"mod_openssl"
)

$SERVER["socket"] == ":443" {
	ssl.engine = "enable"
	ssl.pemfile = "/etc/lighttpd/cert.pem"
}
  • Restart the lighttpd service:
root@host:~# systemctl restart lighttpd.service