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

Lighttpd logo Debian logo

If you have a good internet connexion it could be useful to be able to share files with friends via a home made solution.

We will see here how to set up a web server in order to easily share files via a http protocol on GNU/Linux.

The goal here is to do it quickly with minimal configuration.

We will use lighttpd wich is an open-source web server optimized for speed-critical environments while remaining standards-compliant, secure and flexible.

Small CPU load and low memory footprint, everything I'm looking for.

Installing lighttpd

  • Install lighttpd :
root@host:~# apt-get install lighttpd

Edit configuration file

  • Edit /etc/lighttpd/lighttpd.conf, and add this line :
server.modules = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
)

server.dir-listing          = "enable"
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 upload directory :
root@host:~# mkdir /var/www/html/upload
  • Create example file :
root@host:~# echo "titi" > /var/www/html/upload/toto
  • Reload lighttpd service :
root@host:~# systemctl restart lighttpd.service

Connect to the web server

  • From your web browser connect to your newly web server (http://IP_ADDRESS/upload). From the Index of page you should see your file :
GNU/Linux | Lighttpd Index of

How to secure?

We have a our brand new http server but if we make it accessible from the internet (that's what we wanted right?), everyone can potentially connect to it.

We will see here, how we can improve security.

Firewall rules

We can use the netfilter/iptables or nftables firewall to restrict access and thus allow only certain ip addresses.

Netfilter/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 this lines :
server.modules = (
	"mod_indexfile",
	"mod_access",
	"mod_alias",
 	"mod_redirect",
	"mod_auth"
)

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

auth.require = ( "/" =>
        (
        "method" => "basic",
        "realm" => "Auth",
        "require" => "valid-user"
        )
)
  • Add new user login:password :
root@host:~# echo "agent007:secret" > /etc/lighttpd/lighttpd-plain.user
  • Restart lighttpd service :
root@host:~# systemctl restart lighttpd.service
  • The next time someone tries to log in an authentication request will appear :
GNU/Linux | Lighttpd auth window

Add 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 this lines :
server.modules = (
	"mod_indexfile",
	"mod_access",
	"mod_alias",
 	"mod_redirect",
	"mod_auth",
	"mod_openssl"
)

$SERVER["socket"] == ":443" {
	ssl.engine = "enable"
	ssl.pemfile = "/etc/lighttpd/cert.pem"
}
  • Restart 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 :