But the public key can be extracted from the
private key:
# openssl rsa -in server.key -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtLL9Tb27Tg/KWdPbhNXAwQFfJ
8cxkAQW8W9yI5dZMMObpO3kZ4MUep2OmiEGI6gsBSyZ8tSnl3AfD/XFWwCfrcTWQ
i4qwS1sQiGMV+DglPJNKMOfqtR1cqTUIpajqt12Zc57LVhIQJV3Q6Cnpupo5n40a
vwUXzEm5VmUxwzmmWQIDAQAB
-----END PUBLIC KEY-----
3. Generating a Certificate
Signing Request
The next step is to create a certificate-signing
request (CSR). This is a formal request asking a
certificate authority to sign a certificate, and it contains
the public key of the entity requesting the certificate and
information about the entity. The information becomes part of
the certificate.
CSR creation is an interactive process, which
takes the private server key as input. Read the instructions
given by the openssl tool
carefully: if you want a field to be empty, you must enter a
single dot (.) and not just press Return because doing so
would populate the field with the default value.
# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:.
Locality Name (eg, city) [Newbury]:London
Organization Name (eg, company) [My Company Ltd]:Apache Security
Organizational Unit Name (eg, section) [ ]:.
Common Name (eg, your name or your server's hostname) [ ]:
www.apachesecurity.net
Email Address [ ]:webmaster@apachesecurity.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password [ ]:
An optional company name [ ]:
After a CSR is generated, you use it to sign
your own certificate and/or send it to a public CA and ask him
to sign the certificate. Both approaches are described in the
sections that follow.
4. Signing Your Own
Certificate
For testing purposes, you should sign your
own certificate; it may be days before the CA completes the
certificate generation process. You have the files you need:
the CSR and the private key. The
x509 command with
the -req switch creates a self-signed certificate.
Other switches on the following command line instruct
openssl to create a certificate valid for 365 days
using the private key specified in server.key:
# openssl x509 -req -days 365 -in server.csr \
> -signkey server.key -out server.crt
Signature ok
subject=/C=GB/L=London/O=Apache
Security/CN=www.apachesecurity.net/emailAddress=webmaster@apachesecurity.net
Getting Private key
Use the
x509 command to examine the
contents of the certificate you have created:
# openssl x509 -text -in server.crt
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 0 (0x0)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=GB, L=London, O=Apache Security,
CN=www.apachesecurity.net/emailAddress=webmaster@apachesecurity.net
Validity
Not Before: Jul 26 13:36:34 2004 GMT
Not After : Jul 26 13:36:34 2005 GMT
Subject: C=GB, L=London, O=Apache Security,
CN=www.apachesecurity.net/emailAddress=webmaster@apachesecurity.net
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:d0:b6:1e:63:f1:39:9c:17:d2:56:97:e9:6d:0d:
a5:a1:de:80:6b:66:f9:62:53:91:43:bf:b9:ff:57:
b3:54:0b:89:34:3e:93:5f:46:bc:74:f8:88:92:bd:
3c:0a:bb:43:b4:57:81:e7:aa:b6:f0:3f:e7:70:bf:
84:2e:04:aa:05:61:fb:c9:f7:65:9a:95:23:d7:24:
97:75:6e:14:dc:94:48:c0:cd:7b:c7:2e:5b:8c:ad:
ad:db:6c:ab:c4:dd:a3:90:5b:84:4f:94:6c:eb:6e:
93:f4:0f:f9:76:9f:70:94:5e:99:12:15:8f:b7:d8:
f0:ff:db:f6:ee:0c:85:44:43
Exponent: 65537 (0x10001)
Signature Algorithm: md5WithRSAEncryption
9e:3b:59:a4:89:7e:30:c7:b3:3d:82:ea:3e:f5:99:4a:e9:b2:
53:25:9f:04:66:e0:b7:43:47:48:a2:b9:27:bc:b6:37:bb:6a:
2f:66:d2:58:bf:b8:50:19:4f:7f:51:54:ba:a9:c9:8a:3c:70:
25:0d:29:d1:af:78:f2:3a:0b:74:de:a6:36:c1:f8:f9:6c:b2:
9d:4e:f5:3a:e6:87:99:99:b9:c6:25:33:c2:84:4e:81:e8:b3:
e4:e3:5b:20:1e:09:3c:b3:60:88:90:1c:a2:29:dd:91:25:3e:
cb:44:55:97:9e:96:97:52:49:38:77:03:0d:59:b8:7d:4f:32:
44:45
-----BEGIN CERTIFICATE-----
MIICfTCCAeYCAQAwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAkdCMQ8wDQYD
VQQHEwZMb25kb24xGDAWBgNVBAoTD0FwYWNoZSBTZWN1cml0eTEfMB0GA1UEAxMW
d3d3LmFwYWNoZXNlY3VyaXR5Lm5ldDErMCkGCSqGSIb3DQEJARYcd2VibWFzdGVy
QGFwYWNoZXNlY3VyaXR5Lm5ldDAeFw0wNDA3MjYxMzM2MzRaFw0wNTA3MjYxMzM2
MzRaMIGGMQswCQYDVQQGEwJHQjEPMA0GA1UEBxMGTG9uZG9uMRgwFgYDVQQKEw9B
cGFjaGUgU2VjdXJpdHkxHzAdBgNVBAMTFnd3dy5hcGFjaGVzZWN1cml0eS5uZXQx
KzApBgkqhkiG9w0BCQEWHHdlYm1hc3RlckBhcGFjaGVzZWN1cml0eS5uZXQwgZ8w
DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANC2HmPxOZwX0laX6W0NpaHegGtm+WJT
kUO/uf9Xs1QLiTQ+k19GvHT4iJK9PAq7Q7RXgeeqtvA/53C/hC4EqgVh+8n3ZZqV
I9ckl3VuFNyUSMDNe8cuW4ytrdtsq8Tdo5BbhE+UbOtuk/QP+XafcJRemRIVj7fY
8P/b9u4MhURDAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAnjtZpIl+MMezPYLqPvWZ
SumyUyWfBGbgt0NHSKK5J7y2N7tqL2bSWL+4UBlPf1FUuqnJijxwJQ0p0a948joL
dN6mNsH4+WyynU71OuaHmZm5xiUzwoROgeiz5ONbIB4JPLNgiJAcoindkSU+y0RV
l56Wl1JJOHcDDVm4fU8yREU=
-----END CERTIFICATE-----
5. Getting a Certificate Signed
by a CA
To get a publicly recognized certificate, you
will send the generated CSR to a CA. The CA will collect
payment, validate your organization's identity, and issue a
certificate. Certificates used to be very expensive but,
thanks to competing CAs, are now inexpensive enough to allow
all but the smallest organizations to use valid public
certificates for internal installations.
Most CAs offer free trials so you can
practice before making the purchase. Thawte, for example, is
offering a script that generates test certificates instantly
when fed with CSRs. That script and further information is
available at https://www.thawte.com/cgi/server/try.exe.
|
Forgetting to renew a certificate
is one of the most common problems with SSL. Take
a minute to create a cron job right on the server
to send you an email reminder for this important
task. | |
After receiving the certificate, overwrite
the self-signed certificate used for testing and restart
Apache. No other changes should be required, but the CA may
provide specific installation instructions.
6. Configuring SSL
A minimal SSL configuration consists of three
directives in the Apache configuration file:
# Enable SSL
SSLEngine On
# Path to the server certificate
SSLCertificateFile /usr/local/apache/conf/ssl/server.crt
# Path to the server private key
SSLCertificateKeyFile /usr/local/apache/conf/ssl/server.key
You may wish to make the default
configuration slightly more secure by adjusting the allowed
protocols. SSLv2 is known to be flawed. (For details, see http://www.meer.net/~ericm/papers/ssl_servers.html#1.2.)
Unless your installation has to support browsers that do not
speak SSLv3 (which is unlikely), there is no reason to allow
SSLv2. The following disallows it:
# Allow SSLv3 and TLSv1 but not SSLv2
SSLProtocol All -SSLv2
One other useful configuration option is the
following, which disallows the situation where, though the
server supports high-grade encryption, the client negotiates a
low-grade (e.g., 40-bit) protocol suite, which offers little
protection:
# Disallow ciphers that are weak (obsolete or
# known to be flawed in some way). The use of
# an exclamation mark in front of a cipher code
# tells Apache never to use it. EXP refers to 40-bit
# and 56-bit ciphers, NULL ciphers offer no encryption.
# ADH refers to Anonymous Diffie-Hellman key exchange
# which effectively disables server certificate validation,
# and LOW refers to other low strength ciphers.
SSLCipherSuite ALL:!EXP:!NULL:!ADH:!LOW
After the certificate is installed, you can
test it by opening the web site in your browser. You should
get no warnings for a certificate issued by a well-known CA.
You will get at least one warning if you are using a
self-signed certificate for testing. In the Appendix
A, I introduce SSLDigger, a tool designed to evaluate the
strength of a site's SSL protection.
6.1 Supporting broken SSL
clients
Some browsers do not have fully compliant SSL
implementations. To make them work with Apache, you need a
workaround. The code below is a workaround for problems
related to Internet Explorer. The code is in the default SSL
configurations, but I have provided it here because you need
to be aware of what it does. Whenever the Internet Explorer
browser is detected, this configuration fragment disables the
HTTP Keep-Alive feature, downgrades the HTTP protocol to 1.0
(from the usual 1.1), and allows the SSL channel to be closed
by closing the TCP/IP connection:
# Make SSL work with Internet Explorer
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
6.2 Securing the server private
key
On a server with many user accounts (and not
all of them trusted), relaxed permissions on the file with the
server private key may result in the key being retrieved by
one of the users. The root user should be the only one
with permission to read the private key and certificate
files:
# cd /usr/local/apache/conf/ssl
# chmod 400 server.crt server.key
6.3 Ensuring reliable SSL
startup
If you are using the apachectl script
to start and stop Apache, then you have probably noticed it
must be invoked with the
startssl command in order to
activate SSL. This can lead to problems (and service downtime)
when you forget about it and execute the usual
apachectl
start.
I suggest that you modify this script to make
the start command behave in the same manner as
startssl, always activating SSL. In the following
script fragment, I emphasize where you need to add the
-DSSL switch:
case $ARGV in
start|stop|restart|graceful)
$HTTPD -k $ARGV -DSSL
ERROR=$?
;;
6.4 Preventing configuration
mistakes
If you are running a web site that needs to
be available only over SSL, then avoid a chance of making the
same content available through a non-SSL channel and create a
virtual host that points to an empty folder. Use a
RedirectPermanent directive to redirect users to the
correct (secure) location:
<VirtualHost 217.160.182.153:80>
ServerName www.apachesecurity.net
DirectoryRoot /var/www/empty
RedirectPermanent / https://www.apachesecurity.net/
</VirtualHost>
If the site contains SSL and non-SSL content,
separating the content into two virtual hosts and separate
directories decreases the chance of providing sensitive
information without SSL. If the content must be put under the
same directory tree, consider creating a special folder where
the secure content will go. Then tell Apache to allow access
to that folder only when SSL is used:
<Directory /var/www/htdocs/secure>
# SSL must be used to access this location
SSLRequireSSL
# Do not allow SSLRequireSSL to be overriden
# by some other authorization directive
SSLOptions +StrictRequire
</Directory>
A site that contains SSL and non-SSL
content is more difficult to secure than an
SSL-only web site. This is because it is possible
for an attacker to eavesdrop on the non-SSL
connection to retrieve a cookie that contains the
session ID, and then use the stolen session ID to
enter the SSL-protected area. The correct approach
to handle a case like this is to operate two
independent user sessions, one exclusively for the
non-SSL part of the site and the other exclusively
for the SSL part of the
site. | |
A slightly more user-friendly approach to
ensuring content is served over SSL is to use a few
mod_rewrite rules to detect access to non-SSL content and
redirect the user to the correct location, as demonstrated in
Apache Cookbook by Ken Coar and
Rich Bowen (O'Reilly) in Recipe 5.15 and online at http://rewrite.drbacchus.com/rewritewiki/SSL:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/secure(.*) https://%{SERVER_NAME}/secure$1 [R,L]
If neither of these two choices is possible
(separating the content into two virtual hosts and separate
directories or placing the content in a special folder that
can only be accessed using SSL), the burden of controlling SSL
access will be on the shoulders of the programmers. You should
check (during final site testing) that the secure content
available, for example at https://www.example.com/my-sensitive-data/,
cannot be accessed using a nonsecure URL, such as http://www.example.com/my-sensitive-data/