[HCoop-Discuss] SSL without warnings (ie X.509 v3)
Anders Petersson
demitar at worldforge.org
Thu Sep 14 08:24:31 EDT 2006
(This became rather long and probably belongs on the wiki, I'll just
toss it out here first though and we'll see what becomes of it.)
I've investigated the murky depths of (Open)SSL and discovered how we
can use a single SSL certificate for all hcoop hosted domains. (I
stumbled upon this while experimenting with shared certificiates, which
basically are globbing patterns for hostnames.)
X.509 is the standard for certificate metadata. In version 1 you set the
CN (Common Name) to the (virtual) host which the client tries to connect
to and if they do not match the client warns the user.
X.509 version 3 allows a number of extensions, among those the most
interesting one is subjectAltName, it allows you to specify a list of
names (not only hostnames) the certificate is valid for.
subjectAltName is detailed in http://rfc.sunsite.dk/rfc/rfc2459.html and
http://www.openssl.org/docs/apps/x509v3_config.html#Subject_Alternative_Name_
The subjectAltName is of the form:
subjectAltName=DNS:hcoop.net,DNS:members.hcoop.net,DNS:soddensquirrel.net
and so on. They also allow the same basic globbing as CN names does.
For self-signed certificates the subjectAltName line should be in the
[v3_ca] section of the config and for sign requests in the [v3_req]
section. Also the x509_extensions and req_extensions fields need to
contain v3_ca and v3_req respectively.
Most likely we'll want the v1 field CN (only accepting a single name) to
be set to members.hcoop.net meaning if a client doesn't support v3
(quite unlikely today) we'll still be no worse off than we already are.
This way we could generate a single certificate for all the domains
hosted, we could even have domtool generate it for all the specified ssl
hosts automagically. You want a complete copy of openssl.cnf (here it's
located in /etc/ssl) to be modified since openssl doesn't accept more
than one -config option (the latter overwrite the complete previous).
However, the fun does not end here.
If we generate new self-signed certificates the users will have to
accept a new certificate every time we add a new ssl host.
The solution is to generate a certificate authority and sign the newly
generated certificates using that. That way the users only have to
install that single certificate authority, or even better, we get ours
signed from an upsteam source, such as http://www.cacert.org/
To set up our own Certificate Authority we need to take the following steps:
1. Create a directory, say hcoop.netCA/
2. In that directory create the directories hcoop.netCA/newcerts/ and
hcoop.netCA/private/
3. Create a serial file: echo "01" > hcoop.netCA/serial
4. Create an index: touch hcoop.netCA/index.txt
5. Finally generate our CA key:
* Self signed: openssl req -x509 -newkey rsa:1024 -keyout
hcoop.netCA/private/cakey.pem -out hcoop.netCA/cacert.pem -days 9999
-nodes -config openssl.cnf
* Or to be signed: openssl req -new -key
hcoop.netCA/private/cakey.pem -out req.pem -config openssl.cnf
Now since we want the v3 fields to get into our signed certificate we'll
have to enable copy_extensions = copy in the CA section [CA_default]
most likely.
Also we probably want the CA policy to allow different organizations in
the signed certificates, which means we want to change organizationName
in [policy_match] from match to supplied.
Finally we're ready to start signing our own keys:
1. Generate a whole new key and certificate request (it's possible to
generate them separately and reuse the key in the future - only generate
a new certificate request - see the x509 manpage): openssl req -new -key
key.pem -out req.pem -config openssl.cnf
2. Then we sign it using our CA: openssl ca -in req.pem -out
newcert.pem -config openssl.cnf
3. And finally we make them something the server likes: cat key.pem
newcert.pem > server.pem
Finally, I've attached the config I've experimented with and the diff
against the system default.
There are ways to make openssl not prompt for specifics basically you
chenge the [req_distinguished_name] section to something like:
[ req_distinguished_name ]
C = GB
ST = Test State or Province
L = Test Locality
O = Organization Name
OU = Organizational Unit Name
CN = Common Name
emailAddress = test at email.address
and
[ req_attributes ]
challengePassword =
This is all detailed in http://www.openssl.org/docs/apps/req.html
There is one issue which I'm not quite certain of though, which is how
our CA sitting in the middle is exposed to the client. Perhaps it's
determined by an apache directive?
Oh, and I should probably turn this into a wiki page instead. :)
Be sure to let me know what is confusing in here.
More information about the HCoop-Discuss
mailing list