With a secure web server, clients can connect to your server secure in the knowledge both that it is who it claims to be and that the transaction is well-encrypted so their data is safe. The best way of doing this is with Apache 2, the leading Linux web server software, and Secure Sockets Layer, a secure communication protocol. Transport Layer Security (TLS) is the successor to SSL, but they work in basically the same way. I’ll refer from here on just to SSL.
SSL is a protocol for cryptographically securing transactions between a web browser and a web server. In most cases, only the server end is authenticated, which means that the client has a guarantee that the server is who it claims to be, but not vice versa. However, once the connection is established, both ends are secure, as only the client and the server have access to the key material. This makes sense since for many transactions, the server doesn’t care who the client is, as long as it stays the same client throughout the transaction. If you do care about client authentication, it is possible to use client SSL certificates (or htaccess, Kerberos, or other similar methods), but that won’t be covered in this article.
As a client, obviously you do care that you’re sending whatever private data you wish to encrypt to the person (server) you think you’re sending it to. Hence the server, not the client, being authenticated. You also care about preventing a third party from accessing your data as you send it. SSL provides both of these types of security.
The SSL process works as follows:
- Client connects to web server and gives a list of available ciphers.
- Server picks the strongest cipher that both it and the client support, and sends back a certificate with its name and public encryption key, signed by a trusted Certificate Authority (such as Verisign).
- The client checks the certificate with the CA. In practice, clients tend to have a collection of CAs locally, so this can be done without having to contact the CA in realtime, and therefore more quickly.
- The client sends back a random number encrypted with the server’s public key. Only the client knows the number, and only the server can decrypt it (using its private key); this is where the third-party security comes in.
- Server and client use this random number to generate key material to use for the rest of the transaction.
We want this to be as transparent as possible on the client side, to make the transaction as easy as possible.
Setting up Apache with SSL is straightforward, but there are several necessary steps. This article covers how to get a certificate signed by a CA, and how to compile and configure Apache with SSL. I’m using Apache2 with mod_ssl. ApacheSSL (an implementation of Apache with SSL capabilities) is also available, but is now quite old; mod_ssl is a better bet.
• Package – mod_ssl
• Port number – 443
• Certificate – conf/ssl.crt/server.crt
• Private key – conf/ssl.key/server.key
• Self-signed cert – make testcert
• Certificate signature req – make certreq
#yum install mod_ssl openssl
Creating a Certificate
The first step is certificate creation. You can create your certificate either with or without a passphrase. The major disadvantage of using a passphrase is that it must be typed every time the web server starts up. So it won’t start unattended or automatically on boot, for example, after a power cut. Depending on your setup, this may or may not be significant for you.
In theory, the advantage of having a passphrase is that it increases protection. However, in practice the passphrase doesn’t actually give that much protection. If someone can read or copy the private key, then they already have root-level access to the system and could obtain the passphrase, for example by using a program like keylogger. A passphrase will protect against script kiddies, but not against a serious hacker. For most people it’s probably not worth using one.
Generate a self-signed certificate
1. Generate private key
#openssl genrsa -out ca.key 1024
2. Generate CSR
#openssl req -new -key ca.key -out ca.csr
3. Generate Self Signed Key
#openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
- -x509 identifies that a certificate is required, rather than just a certificate request (see below).
- -days 365 sets the certificate to expire in a year. You may want to extend this period. Make a note of the expiry date so that you can renew it when necessary
- rsa:1024 sets the key as 1024 bit RSA.
- -out specify where to store the certificate and key. The key should be root-readable only; the certificate can be world-readable, and must be readable by the user that Apache runs as.
The problem with using a self-signed certificate for a real-life working web server is that any browser connecting to the site will not recognize the certificate authority. This means that the user will be asked to verify the certificate. Obviously, in most cases this is suboptimal. However, it’s fine for test purposes, and on small LANs it may not be worth paying for a certificate from an external CA.
Copy the files to the correct locations
#cp ca.crt /etc/pki/tls/certs
#cp ca.key /etc/pki/tls/private/ca.key
#cp ca.csr /etc/pki/tls/private/ca.csr
To avoid SELinux Problem (due to file copy/move)
#restorecon -RvF /etc/pki
To update the Apache SSL configuration file
#vi +/SSLCertificateFile /etc/httpd/conf.d/ssl.conf
Change the paths to match where the Key file is stored. If you’ve used the method above it will be
SSLCertificateKeyFile /etc/pki/tls/private/ca key
Configuring the firewall to allow https permanently
#iptables -A INPUT -p tcp –dport 443 -j ACCEPT
#service iptables save
Then point your web browser at https://www.yoursite.com. You should see an SSL connection opened and the page delivered. If you’re using a self-signed certificate, your browser will pop up an alert warning you that the server’s identity cannot be verified. You can choose to view and accept the certificate. If using an external certificate, it should all happen without intervention.
If it’s not working as expected, first check that your server is actually running, using ps -a | grep apache. If that doesn’t return anything, try restarting it, and check for error messages on the terminal.
Also check that the permissions on your key and certificate files are set correctly (see above), as well as the permissions on your test HTML file and its parent directory.
Next, check the logs. You should check both the main server logs and also the SSL logs that you set up in your config file above. If you don’t get anything useful, try changing the LogLevel value in the Apache2 config file to “debug”, restart Apache2, and test again. This should give more logfile data.
If you are running a regular web server on port 80 as well, try fetching a test page via https:// rather than https:// to help identify whether the problem is with the web server or with the SSL connection. Note that in the setup above, the web server’s root directory is different for https:// and https://, so you won’t (or shouldn’t!) be able to access the same content. If your test page in the https:// root directory works fine, though, and your test page in the https:// root directory doesn’t, then that can help you to pinpoint the problem.
If the problem is the SSL connection, a useful tool is s_client, which is a diagnostic tool for troubleshooting TLS/SSL connections. The basic usage is: /usr/bin/openssl s_client -connect localhost:443.
Congratulations! You should now have a working secure server, with a certificate that will be automatically verified by the majority of modern browsers.