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

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

root@host:~# apt-get install lighttpd

Edit configuration file

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",
)
root@host:~# mkdir /var/www/html/upload
root@host:~# echo "titi" > /var/www/html/upload/toto
root@host:~# systemctl restart lighttpd.service

Connect to the web server

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.

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"
        )
)
root@host:~# echo "agent007:secret" > /etc/lighttpd/lighttpd-plain.user
root@host:~# systemctl restart lighttpd.service
GNU/Linux | Lighttpd auth window

Add https support

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
root@host:~# chmod 600 /etc/lighttpd/cert.pem
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"
}
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 :