rss logo

How to quickly set up http file sharing on GNU/Linux

Lighttpd logo Debian logo

If've got a good Internet connexion, it might be interesting to be able to share files with friends thanks to a home-made solution.

Here we'll look at how to set up a web server for easy file sharing via the http protocol under GNU/Linux.

The aim is to do this quickly, with a minimum of configuration.

We'll be using lighttpd, an open-source web server optimized for speed-critical environments, while remaining standards-compliant, secure and flexible. See the wikipedia web page: https://en.wikipedia.org/.

In short: low CPU load and small memory footprint, just what I'm looking for.

Installing lighttpd

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

Edit configuration file

  • Edit /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 a upload directory:
root@host:~# mkdir /var/www/html/upload
  • Create a test file:
root@host:~# echo "titi" > /var/www/html/upload/toto
  • Reload the lighttpd service:
root@host:~# systemctl restart lighttpd.service

Connect to the web server

  • From your web browser, connect to your brand-new web server (at http://IP_ADDRESS/upload). You should see your file appear in the Index of:
Directory listing of /upload/ folder on Lighttpd server showing a file named toto with details

How do we secure it?

We've got a brand-new http server, but if we make it accessible from the Internet (which is what we wanted, right?), anyone can potentially connect to it.

Here's a look at how we can improve security.

Firewall rules

We can use the iptables or nftables to restrict access and authorize only certain IP addresses.

iptables rules

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

nftables rules

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 authentication

We can also add a user/password prompt window to prevent unwanted users.

  • Edit /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" ) )
  • Add a new user in login:password format:
root@host:~# echo "agent007:secret" > /etc/lighttpd/lighttpd-plain.user
  • Restart the lighttpd service:
root@host:~# systemctl restart lighttpd.service
  • The next time someone tries to log in, an authentication prompt appears:
Authentication prompt requesting username and password, showing username as 'agent007' and obscured password

Add https support

We can also encrypt our exchanges by adding https support.

  • 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 root@host:~# cat /etc/ssl/private/lighttpd-selfsigned.key /etc/ssl/certs/lighttpd-selfsigned.crt > /etc/lighttpd/cert.pem
  • Set rights:
root@host:~# chmod 600 /etc/lighttpd/cert.pem
  • Edit /etc/lighttpd/lighttpd.conf, and add following lines:
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
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address