Lighttpd Advanced security: Difference between revisions
Ginjachris (talk | contribs) |
Ginjachris (talk | contribs) |
||
Line 124: | Line 124: | ||
ssl.cipher-list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK" | ssl.cipher-list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK" | ||
</pre> | </pre> | ||
Also see https://freakattack.com/ | |||
== Other configurations == | == Other configurations == |
Revision as of 11:22, 10 March 2015
For higher security Lighttpd can be configured to allow https access.
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.pem -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.
/etc/init.d/mini_httpd stop && rc-update del mini_httpd
Removing the mini_http package
apk del mini_httpd
Configure Lighttpd
The configuration of lighttpd needs to be modified.
nano /etc/lighttpd/lighttpd.conf
Uncomment this section and adjust the path so 'ssl.pemfile' points to where our cert/key pair is stored. Or copy the example below into your configuration file if you saved it to /etc/lighttpd/server.pem.
ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/server.pem"
You'll also want to set the server to listen on port 443. Replace this:
server.port = 80
with this:
server.port = 443
Restart lighttpd
rc-service lighttpd restart
Security
BEAST attack, CVE-2011-3389
To help mitigate the BEAST attack add the following to your configuration:
#### Mitigate BEAST attack: # A stricter base cipher suite. For details see: # http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-3389 # or # http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3389 ssl.cipher-list = "ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM" # # Make the server prefer the order of the server side cipher suite instead of the client suite. # This is necessary to mitigate the BEAST attack (unless you disable all non RC4 algorithms). # This option is enabled by default, but only used if ssl.cipher-list is set. ssl.honor-cipher-order = "enable" # Mitigate CVE-2009-3555 by disabling client triggered renegotiation # This option is enabled by default. # ssl.disable-client-renegotiation = "enable" #
Perfect Forward Secrecy (PFS)
Perfect Forward Secrecy isn't perfect, but what it does mean is that an adversary who gains the private key of a server does not have the ability to decrypt every encrypted SSL/TLS session. Without it, an adversary can simply obtain the private key of a server and decrypt and and all SSL/TLS sessions using that key. This is a major security and privacy concern and so using PFS is probably a good idea long term. It means that every session would have to be decrypted individually, regardless of the state (whether obtained by the adversary or otherwise).
Ultimately when choosing SSL/TLS ciphers it is the usual chose of security or usability? Increasing one usually decreases the other. Nonetheless, an example to prevent the BEAST attack and offer PFS is:
ssl.cipher-list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
POODLE attack (CVE-2014-3566)
In light of the recent POODLE findings, it's advisable to wherever possible turn off support for SSLv3. This is quite simple, you can just append the following to your cipher list to explicitly disable SSLv3 support:
:!SSLv3
FREAK attack (CVE-2015-0204)
To prevent the so called FREAK attack, keep your SSL library up to date, and do not offer support for export grade ciphers.
There's multiple ways to do this, like turning off export cipher support in the cipher list:
:!EXPORT
Although now might be a good time to review the cipher list in use, and use a stronger, explicit set like the one from the Perfect Forward Secrecy section, or another example:
ssl.cipher-list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
Also see https://freakattack.com/
Other configurations
The following are example configs, they will likely need to be modified to suite your particular setup. Nonetheless they should provide an indication of how to implement the relevant configuration options.
redirecting HTTP to HTTPS
Any requests to the server via HTTP (TCP port 80 by default) will be redirected to HTTPS (port 443):
server.port = 80 server.username = "lighttpd" server.groupname = "lighttpd" server.document-root = "/var/www/localhost/htdocs" server.errorlog = "/var/log/lighttpd/error.log" dir-listing.activate = "enable" index-file.names = ( "index.html" ) mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".jpg" => "image/jpeg", ".png" => "image/png", "" => "application/octet-stream" ) ## Ensure mod_redirect is enabled! server.modules = ( "mod_redirect", ) $SERVER["socket"] == ":80" { $HTTP["host"] =~ "(.*)" { url.redirect = ( "^/(.*)" => "https://%1/$1" ) } } $SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/certs/www.example.com.pem" ## Make sure the line above points to your SSL cert/key pair! }
Serving both HTTP and HTTPS requests
Simple, just add in the SSL server port, enable the SSL engine and point to the relevant SSL cert/key pair:
server.port = 80 server.username = "lighttpd" server.groupname = "lighttpd" server.document-root = "/var/www/localhost/htdocs" server.errorlog = "/var/log/lighttpd/error.log" dir-listing.activate = "enable" index-file.names = ( "index.html" ) mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".jpg" => "image/jpeg", ".png" => "image/png", "" => "application/octet-stream" ) ## Below is HTTPS setup. Make sure to point at relevant cert/key pair for HTTPS to work! $SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/certs/www.example.com.pem" }