Project

General

Profile

Docs SSL » History » Revision 40

Revision 39 (presbrey, 2009-11-05 22:09) → Revision 40/166 (presbrey, 2009-11-05 22:12)

h1. Secure HTTP 

 bq. Module: core 

 bq. keywords: lighttpd, ssl 

 {{>toc}} 

 h2. Description 

 lighttpd supports _SSLv2_ (disabled in 1.4.21 and 1.5) and _SSLv3_ if it is compiled against _openssl_. 

 h2. How to install SSL 

 To use SSL you must have ssl compiled into lighty. You must first have 
 openssl-devel installed and openssl installed as well. On Fedora or 
 Centos you may use yum to install this by running this command:  

 bq.    yum install openssl* 

 And type _yes_ when it asks for a confirmation of what you would like to install. 

 Once installed please download the lighttpd tarball from http://www.lighttpd.net/download and extract it with 

 bq.    tar zxvf lighttpd-1.4.20.tar.gz 

 Enter into the extracted folder and compile with these configuration flags: :: 

 bq.    --with-openssl --with-openssl-libs=/usr/lib 

 Remember to change _ --with-openssl-libs= _ to the folder where your openssl libraries are installed into. 

 Once compiled, run make and make install. If lighty has successfully compiled SSL the command 

 bq.    lighttpd -v 

 Should display (Keep in mind that this new lighty version now has _(ssl)_ after lightys name) 

 bq.    lighttpd-1.4.11 (ssl) - a light and fast webserver 
   Build-Date: Sep    1 2006 19:09:15 

 Remember if you used the RPM packages to install lighty, the init.d scripts will point to the wrong binary of lighty than the one you just compiled. The location of where you compiled lighty should be displayed near the end of make install. Once the location of the binary is found please edit the /etc/init.d/lighttpd script and change what is defined in the lighttpd="/usr/sbin/lighttpd" to your new lighty location. 

 h2. Configuration 

 table{margin-left: 2em}. 
 |_.option |_. description | 
 | ssl.engine | enable/disable ssl engine | 
 | ssl.pemfile | path to the PEM file for SSL support | 
 | ssl.ca-file | path to the CA file for support of chained certificates | 
 | ssl.use-sslv2 | enable/disable use of SSL version 2 | 
 | ssl.cipher-list | Configure the allowed SSL ciphers | 
 | ssl.verifyclient.activate | enable/disable client verification | 
 | ssl.verifyclient.enforce | enable/disable enforcing client verification |  
 | ssl.verifyclient.depth | certificate depth for client verification | 
 | ssl.verifyclient.exportcert | enable/disable client certificate export to env:SSL_CLIENT_CERT | 
 | ssl.verifyclient.username | set client certificate entity to export as env:REMOTE_USER (eg. SSL_CLIENT_S_DN_emailAddress, SSL_CLIENT_S_DN_UID, etc.) | 

 If your openssl version supports TLS SNI, you can set some ssl.* option in conditionals (for example in $HTTP["host"]) to support different certificates for different hostnames. 

 h3. Example 

 To enable SSL for the whole server you have to provide a valid certificate and have to enable the SSL engine. If you want to use chained certificates you must also include the CA file, without it browsers will pop up an _unknown certificate authority_ or some such error. 

   ssl.engine = "enable" 
   ssl.pemfile = "/path/to/server.pem" 
   ssl.ca-file = "/path/to/CA.crt" 

 Please note that enabling SSL for the whole server as shown above, seem to replace (disable) the non-SSL operations, and if without ssl.ca-file configured, MS IE will accept this certificate but firefox will not. 

 The HTTPS protocol does not allow you to use name-based virtual hosting with SSL (see UCC certs below). If you want to run multiple SSL servers with one lighttpd instance you must use IP-based virtual hosting: 

   $SERVER["socket"] == "10.0.0.1:443" { 
     ssl.engine                    = "enable" 
     ssl.pemfile                   = "www.example.org.pem" 
     ssl.ca-file                   = "/etc/CA.crt" 
     server.name                   = "www.example.org" 
     server.document-root          = "/www/servers/www.example.org/pages/" 
   } 

 If you have a .crt and a .key file, cat them together into a single PEM file (the order isn't strictly important): 

   $ cat host.key host.crt > host.pem 

 h3. UCC Certificates 

 If you have a UCC (Unified Communications Certificates) certificate, then you _can_ use name-based virtual hosting with SSL support for multiple domains/subdomains on one IP address. Bind the UCC cert to the socket as above. 


 h3. Self-Signed Certificates 

 A self-signed SSL certificate can be generated like this: :: 

   $ openssl req -new -x509 \ 
     -keyout server.pem -out server.pem \ 
     -days 365 -nodes 


 h3. PCI DSS compliance 

 Matthew Glubb wrote: 

 I should clarify the reason for this work. From September 19th, all major online vendors taking card payments will be required to comply with the Payment Card Industry (PCI) Data Security Standard. Smaller vendors may self-certify but they will be more liable if fraud is committed. 

 Part of this standard is the disabling of SSLv2 and the removal of support for ciphers that have a key length of less than 128 bits. For this reason, I believe that the default SSL configuration for lighttpd should reflect this standard.  


 Since 1.4.12 you can use: :: 

   ssl.use-sslv2 = "disable"     -     (No longer needed as of 1.4.21 and 1.5 this is disabled by default.) 
   ssl.cipher-list = "..." 

 to disable SSLv2 and set a cipher-list. Make sure this settings are in the same block than ssl.engine = "enable", this will not work as global options. 

 cipher-list accepts a string containing the ciphers you would like to accept separated by whitespace.    A list of strings will not work. 

 Matthew also provide a list of possible ciphers: 

 Hope it can be of use. Next time I'll submit a proper svn patch but I was in a hurry! Which might explain my somewhat short list of supported ciphers. I've since done some research and this list of supported ciphers is much more comprehensive. It supports all ciphers >= 128 bit key lengths for SSL v3.0, TLS v1.0, and AES cipher suites from RFC3268, extending TLS v1.0 (these seem to be the ones used by recent browsers, not included in the original list): :: 

     RC4-SHA 
     RC4-MD5 
     ADH-RC4-MD5 
     EDH-RSA-DES-CBC3-SHA 
     EDH-DSS-DES-CBC3-SHA 
     DES-CBC3-SHA 
     ADH-DES-CBC3-SHA 
     DES-CBC3-MD5 
     AES128-SHA 
     AES256-SHA 
     DH-DSS-AES128-SHA 
     DH-DSS-AES256-SHA 
     DH-RSA-AES128-SHA 
     DH-RSA-AES256-SHA 
     DHE-DSS-AES128-SHA 
     DHE-DSS-AES256-SHA 
     DHE-RSA-AES128-SHA 
     DHE-RSA-AES256-SHA  

 [FYI] bb says: the requirements permit use of SSLv2 as long as it isn't the only version available.    for example, having SSLv2, SSLv3, and TLSv1 enabled is PCI compliant.    SSLv2 should still be disabled, however, both because it is weak and because you can expect the PCI requirements to become more stringent in the future.    here is my recommended cipher list, in order, which also happens to be PCI compliant: :: 

     DHE-RSA-AES256-SHA  
     DHE-RSA-AES128-SHA 
     EDH-RSA-DES-CBC3-SHA 
     AES256-SHA 
     AES128-SHA 
     DES-CBC3-SHA 
     DES-CBC3-MD5 
     RC4-SHA 
     RC4-MD5 


 * Note: you are forgetting the CAMELLIA cipher (Firefox 3 default) which going by it's wikipedia page is roughly equivalent to AES.    For a good list do `openssl ciphers HIGH` 


 h3. PCI DSS compliance 

 How to enable that the server requests a SSL client certificate? 


 h3. HTTPS detection in PHP 

 Some PHP scripts try to detect HTTPS by checking if $_SERVER['HTTPS'] equals 'on'. To allow that, you can try this: :: 

     server.modules = ( 
         "mod_setenv", 
     ) 
     $SERVER["socket"] == "0.0.0.0:443" { 
         ssl.engine               = "enable" 
         ssl.pemfile              = "/etc/lighttpd/server.pem" 
         ssl.use-sslv2            = "disable" 
         setenv.add-environment = ( 
             "HTTPS" => "on" 
         ) 
     } 

 h3. Trouble-shooting : 

 * Please note that certificates's files are opened before the server goes chrooted (if it's have to). So these paths are system wide. 
 * On server side, ssldump is your friend: @ssldump -i your_network_interface_goes_here port 443@ 
 * On client side, openssl will help you: @openssl s_client -connect your_server_name_goes_here:443@ 
 * Using both _server.bind/server.port_ and _$SERVER["socket"] == "your_ip_goes_here:443"_ will leads to ssl handshake failure. You can't use _server.bind/server.port_ within ssl enabled server. 

 h3. SSL passwords 

 * If you set a password on your SSL certificate, then each time lighttpd starts you will be requested to enter it manually.    ie: "Enter PEM pass phrase:". At present there is no configuration option to enable storage of SSL certificate passwords in the lighttpd config file. 

 h3. Links : 

 * [[HowToSimpleSSL]] 
 * "Setting up Lighttpd with a SSL certificate":http://www.varlogarthas.net/blog/2007/03/installing_a_godaddy_ssl_certi.html 
 * [[HowToRedirectHttpToHttps|Redirect HTTP requests to HTTPS]] 
 * "ssl.ca-file ticket resolution":http://trac.lighttpd.net/trac/ticket/19