Lighttpd Advanced security: Difference between revisions
m (→More details: Changed a hyperlink to https) |
(Condense the HTTPS stuff down even further and remove the ridiculous contradiction with the "redirecting HTTP to HTTPS" section.) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 69: | Line 69: | ||
</pre> | </pre> | ||
== Modern HTTPS access == | |||
For higher security [[lighttpd]] 1.4.56 and up can be configured to allow HTTPS access with modern TLS versions and ciphersuites. | |||
For higher security [[ | |||
The configuration of lighttpd needs to be modified. | The configuration of lighttpd needs to be modified. | ||
Line 142: | Line 77: | ||
{{Cmd|nano /etc/lighttpd/lighttpd.conf}} | {{Cmd|nano /etc/lighttpd/lighttpd.conf}} | ||
Adjust the paths below so 'ssl.pemfile' and 'ssl.privkey' point to where the cert and private key are stored. | |||
<pre> | <pre> | ||
ssl.engine | $SERVER["socket"] == "[::]:80" { } | ||
ssl.pemfile | $SERVER["socket"] == ":443" { ssl.engine = "enable" } | ||
$SERVER["socket"] == "[::]:443" { ssl.engine = "enable" } | |||
ssl.privkey = "/etc/lighttpd/server.key" | |||
ssl.pemfile = "/etc/lighttpd/server.pem" | |||
ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.3") | |||
ssl.openssl.ssl-conf-cmd += ("Options" => "-ServerPreference") | |||
</pre> | </pre> | ||
Restart lighttpd | Restart lighttpd | ||
Line 172: | Line 108: | ||
With the command below the self-signed certificate and key pair are generated. A 2048 bit key is the minimum recommended at the time of writing, so we use '-newkey rsa:2048' in the command. Change to suit your needs. Answer all questions. | With the command below the self-signed certificate and key pair are generated. A 2048 bit key is the minimum recommended at the time of writing, so we use '-newkey rsa:2048' in the command. Change to suit your needs. Answer all questions. | ||
{{Cmd|openssl req -newkey rsa:2048 -x509 -keyout server. | {{Cmd|openssl req -newkey rsa:2048 -x509 -keyout server.key -out server.pem -days 365 -nodes}} | ||
Adjust the permissions | Adjust the permissions | ||
Line 195: | Line 131: | ||
mini_http is no longer needed. | mini_http is no longer needed. | ||
{{Cmd| | {{Cmd|rc-service mini_httpd stop && rc-update del mini_httpd}} | ||
Removing the mini_http package | Removing the mini_http package |
Latest revision as of 02:07, 9 January 2024
Access Control List
This is a way you can define a directory and only allow clients coming from the specified ip's to have access. This might be nice to allow internal LAN clients access to the status pages or employee contact information and deny other clients.
#### access control list for hidden_dir (not for use behind proxies) CAUTION REMOVE "#" to work $HTTP["remoteip"] !~ "127.0.0.1|10.10.10.2|20.10.20.30" { $HTTP["url"] =~ "^/hidden_dir/" { url.access-deny = ( "" ) } }
remoteip
will be compared again single ip only, in that example again 3 ip's. The !~ are only used for those ip's that ar allowed, the rest will be denied (negative comparison).hidden_dir
are the name of the relative path under your root htdocs webserver place, or absolute path where are the files that are served.
$HTTP["url"] =~ "^/hidden_dir/" { $HTTP["remoteip"] == "33.222.0.0/16" { } else $HTTP["remoteip"] == "75.209.116.4" { } else $HTTP["remoteip"] == "79.31.34.79" { } else $HTTP["remoteip"] != "" { # (dummy match everything) url.access-deny = ( "" ) } }
- 33.222.0.0/16 in this case, we first match the denied entry to, then check the ip that access to that entry and for each network range at the last will be the acces deny rule.
See also
- https://redmine.lighttpd.net/boards/2/topics/1279
- https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModAccess
stop image hijacking
Image hijacking is when someone makes a link to your site to one of your pictures or videos, but displays it on their site as their own content. The reason this is done is to send a browser to your server to use your bandwidth and make the content look like part of the hijacker's site. This is most common as people make links to pictures and add them to a public forum or blog listing. They get to use your picture in their content and not have to use their bandwidth or server to host the file. In order to keep your bandwidth usage low you should block access to images from those clients who are not requesting the connection from your site. Note, this function can be used for any kind on content. Just add the file types to the url.access-deny list. If would like more ideas on lowering bandwidth usage check out our Saving Webserver Bandwidth (Tips).
#### stop image hijacking (anti-hotlinking) CAUTION REMOVE "#" to work # $HTTP["referer"] !~ "^(http://midominio\.org|http://www\.midominio\.org)" { # url.access-deny = ( ".jpg", ".jpeg", ".png", ".avi", ".mov" ) # }
virtual host limits
A virtual host is the hostname of your web server. For example this site is called calomel.org. Some bots and scanners will try to access your site using the ip address or no hostname header at all to bypass virtual host limitations. We can block this type of behavior by requiring all clients who want to access our server to reference us by our official host name. This will block anyone who is scanning ip addresses or trying to be mischievous, but allow normal clients like browsers and bots like Google.
#### virtual host limits CAUTION REMOVE "#" to work # $HTTP["host"] !~ "^(midominio\.org|www\.midominio\.org)" { # url.access-deny = ( "" ) # }
stop referer spam
Referer spam is more of an annoyance than a problem. A web site will connect to your server with the referer field referencing their web site. The idea is that if you publish your web logs or statistics then their hostname will show up on your page. When a search bot like Google comes by it will see the link from your site to theirs and give them more PageRank credit. First, never make your weblogs public. Second, block access to referer spammers with these lines.
#### stop referer spam CAUTION REMOVE "#" to work # $HTTP["referer"] =~ "(tarotathome|casinospam)" { # url.access-deny = ( "" ) # }
Modern HTTPS access
For higher security lighttpd 1.4.56 and up can be configured to allow HTTPS access with modern TLS versions and ciphersuites.
The configuration of lighttpd needs to be modified.
nano /etc/lighttpd/lighttpd.conf
Adjust the paths below so 'ssl.pemfile' and 'ssl.privkey' point to where the cert and private key are stored.
$SERVER["socket"] == "[::]:80" { } $SERVER["socket"] == ":443" { ssl.engine = "enable" } $SERVER["socket"] == "[::]:443" { ssl.engine = "enable" } ssl.privkey = "/etc/lighttpd/server.key" ssl.pemfile = "/etc/lighttpd/server.pem" ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.3") ssl.openssl.ssl-conf-cmd += ("Options" => "-ServerPreference")
Restart lighttpd
rc-service lighttpd restart
Generate Certificate and Keys
Either generate the public key and certificate and private key using openssl, or by using the ones generated by installing ACF. You don't need to do both, just do one or the other. The former method, with OpenSSL, is preferred since it gives greater control.
Generate self-signed certificates with openssl
To generate certificates, openssl is needed.
apk add openssl
Change to the lighttpd configuration directory
cd /etc/lighttpd
With the command below the self-signed certificate and key pair are generated. A 2048 bit key is the minimum recommended at the time of writing, so we use '-newkey rsa:2048' in the command. Change to suit your needs. Answer all questions.
openssl req -newkey rsa:2048 -x509 -keyout server.key -out server.pem -days 365 -nodes
Adjust the permissions
chmod 400 /etc/lighttpd/server.pem
Generate self-signed certificates with acf
Install the ACF
setup-acf
Copy the generated certificate to the lighttpd configuration directory.
mv /etc/ssl/mini_httpd/server.pem /etc/lighttpd/server.pem
Adjust the permissions
chown root:root /etc/lighttpd/server.pem
chmod 400 /etc/lighttpd/server.pem
mini_http is no longer needed.
rc-service mini_httpd stop && rc-update del mini_httpd
Removing the mini_http package
apk del mini_httpd
redirecting HTTP to HTTPS
Any requests to the server via HTTP (TCP port 80 by default) will be redirected to HTTPS (port 443):
## Ensure mod_redirect is enabled! server.modules = ( "mod_redirect", ) $SERVER["socket"] == ":80" { $HTTP["host"] =~ "(.*)" { url.redirect = ( "^/(.*)" => "https://%1/$1" ) } }