HOWTO setup a small server
OpenSSL (Keys and Certificates)
Installation
Install OpenSSL by running:
apt-get install openssl ssl-cert
OpenSSL Helper Tools
You can use one of the numerous scripts and tools for easier key and
certificate management (e.g., easy-rsa
which is shipped with
OpenVPN). To make your decision even a bit harder, I also wrote such a tool
(ssl-util.sh
).
More details are given by the tools.
If you do not want to use such a helper, the next two section will give an introduction on how to do key and certificate management manually.
Configuration
Configure OpenSSL using the following example which seems to work with most applications:
File: /etc/ssl/openssl.cnf
# # OpenSSL configuration based on sample configuration shipped # with OpenVPN. # ############################################################# # modify according to your needs KEY_SIZE = 2048 KEY_COUNTRY = DE KEY_PROVINCE = NO KEY_CITY = NOWHERE KEY_ORG = EXAMPLE.COM KEY_ORGUNIT = IT-DIVISION KEY_EMAIL = root@server.example.com HOME = /root KEY_DIR = $ENV::HOME/certs RANDFILE = $ENV::HOME/.rnd ############################################################# openssl_conf = openssl_init [ openssl_init ] oid_section = new_oids engines = engine_section [ new_oids ] [ engine_section ] [ ca ] default_ca = CA_default [ CA_default ] dir = $ENV::KEY_DIR certs = $dir crl_dir = $dir database = $dir/index.txt new_certs_dir = $dir certificate = $dir/ca.crt serial = $dir/serial crl = $dir/crl.pem private_key = $dir/ca.key RANDFILE = $dir/.rand x509_extensions = usr_cert default_days = 3650 default_crl_days = 30 # IMPORTANT: The next must no longer be md5, if used with # Debian's OpenLDAP package being compiled against libgnutls. default_md = sha1 preserve = no policy = policy_match [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = $ENV::KEY_SIZE default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca string_mask = nombstr [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = $ENV::KEY_COUNTRY countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = $ENV::KEY_PROVINCE localityName = Locality Name (eg, city) localityName_default = $ENV::KEY_CITY 0.organizationName = Organization Name (eg, company) 0.organizationName_default = $ENV::KEY_ORG organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = $ENV::KEY_ORGUNIT commonName = Common Name (eg, your name or your server\'s hostname) commonName_max = 64 emailAddress = Email Address emailAddress_default = $ENV::KEY_EMAIL emailAddress_max = 40 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always extendedKeyUsage = clientAuth keyUsage = digitalSignature [ server ] basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always extendedKeyUsage = serverAuth keyUsage = digitalSignature, keyEncipherment [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation,digitalSignature,keyEncipherment [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true [ crl_ext ] authorityKeyIdentifier = keyid:always,issuer:always
Now you will have to initialize the directory specified as
KEY_DIR
in the above configuration file:
# mkdir -m 700 /root/certs # touch /root/certs/index.txt # echo "01" > /root/certs/serial
Generation of Keys and Certificates
In order to create the certificate authority (CA),
run the following command. The question for the common name (CN) might, e.g.,
be answered with CA
. It might be a good idea to omit the
-nodes
parameter and thus encrypting the CA key.
# cd /root/certs # openssl req -nodes -new -x509 -keyout ca.key -out ca.crt
In order to create server key and certificate, run the following commands. The question for the common name (CN) should be answered with the FQDN of the server, so server.example.com in our example.
# cd /root/certs # openssl req -nodes -new -extensions server \ -keyout server.key -out server.csr # openssl ca -extensions server \ -out server.crt -in server.csr
In order to create a client key and certificate,
run the following commands. As the option -nodes
has been omitted,
the key will be encrypted by the supplied password and because of
-days 365
the certificate is only valid for one year. Concerning
the question for the CN the same as for a server certificate applies.
# cd /root/certs # openssl req -days 365 -new \ -keyout client.key -out client.csr # openssl ca -days 365 \ -out client.crt -in client.csr
In order to revoke a certificate (the last command should fail, if revoking was successful):
# cd /root/certs # openssl ca -revoke certificate.crt # openssl ca -gencrl -out crl.pem # cat ca.crt crl.pem > revoke-test.pem # openssl verify -CAfile revoke-test.pem -crl_check certificate.crt
WARNING: Do not forget to distribute the
new certificate revokation list (CRL) crl.pem
to any application
and/or host using the public key infrastructure!
Note: OpenSSL is also able to print certificate details at a later time. This is particularly useful when debugging connection problems.
# openssl x509 -in certificate.crt -noout -text
Installation of Keys and Certificates
Finally, you will have to install the CA certificate and the server's key and certificate:
# cd /root/certs # cp ca.crt server.crt /etc/ssl/certs # cp server.key /etc/ssl/private # chown root:ssl-cert /etc/ssl/private/server.key # chmod 640 /etc/ssl/private/server.key