rss logo

Set Up Multiple Shared Folders with Lighttpd on GNU/Linux

Lighttpd logo

In a previous article, I explained how to install Lighttpd and share files over HTTP. You can read that guide by clicking here. Recently, I faced the need to share two different directories, each protected by its own authentication credentials. In this article, I’ll walk you through how to configure this setup — which, as you'll see, involves a few subtle steps.

Installing Lighttpd

Start by installing Lighttpd and preparing the directories you want to share.

  • Install Lighttpd:
root@host:~# apt-get install lighttpd
  • Create the upload directories:
root@host:~# mkdir /var/www/upload1
root@host:~# mkdir /var/www/upload2
  • Set the correct ownership:
root@host:~# chown -R www-data:www-data /var/www/upload1
root@host:~# chown -R www-data:www-data /var/www/upload2
  • Create authentication files:
root@host:~# echo "user1:PASSWORD1" > /etc/lighttpd/upload1-plain.user
root@host:~# echo "user2:PASSWORD2" > /etc/lighttpd/upload2-plain.user

Edit the Lighttpd Configuration File

Next, open the Lighttpd configuration file to define access rules and enable folder-specific authentication:

  • Edit: /etc/lighttpd/lighttpd.conf:
server.modules = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
        "mod_auth",
        "mod_authn_file"
)

auth.backend = "plain"

#UPLOAD1 (http://X.X.X.X/)
$HTTP["url"] =~ "^/$" {
        auth.backend.plain.userfile = "/etc/lighttpd/upload1-plain.user"
        auth.require = ( "" =>
                (
                "method" => "basic",
                "realm" => "Auth",
                "require" => "valid-user"
                )
        )
}
#UPLOAD2 (http://X.X.X.X/upload2)
$HTTP["url"] =~ "^/upload2($|/)" {
        auth.backend.plain.userfile = "/etc/lighttpd/upload2-plain.user"
        server.dir-listing          = "enable"
        alias.url = ( "/upload2" => "/var/www/upload2/" )
        auth.require = ( "" =>
                (
                "method" => "basic",
                "realm" => "Auth",
                "require" => "valid-user"
                )
        )
}

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

# features
#https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_feature-flagsDetails
server.feature-flags       += ("server.h2proto" => "enable")
server.feature-flags       += ("server.h2c"     => "enable")
server.feature-flags       += ("server.graceful-shutdown-timeout" => 5)
#server.feature-flags       += ("server.graceful-restart-bg" => "enable")

# 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" )

# 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_dirlisting",
        "mod_staticfile",
)
  • Restart the Lighttpd service to apply the new configuration:
root@host:~# systemctl restart lighttpd.service