Table of Contents

This Howto explains how you can create your own SSL Certification Authority and then secure multiple services (Apache, Courier, Postfix, ProFTPD).

[Thanks for the SSL-CA-Part goes to http://fra.nksteidl.de/Erinnerungen/OpenSSL.php]

1. Create the SSL CA

1.1 Install the openssl-package

At first, you have to install the openssl package:

<cli> apt-get install openssl </cli>

1.2 Edit the config file

Then, the openssl config file /etc/ssl/openssl.cnf has to be edited like this (I assume, your CA name is “RootCA”… you can change this name if you want to):

<cli> Line 32: default_ca = RootCA Line 35: [ RootCA ] Line 37: dir = /root/RootCA Line 41: unique_subject = no # only if you need this Line 70: default_md = sha1 </cli>

If you want to, you can change the values in the section [req_destinquished_name] to your language, which would be in german: <cli> [ req_distinguished_name ] countryName = Land (2stelliger Code) countryName_default = DE countryName_min = 2 countryName_max = 2

stateOrProvinceName = Bundesland (voller Name) stateOrProvinceName_default = MeinBundesland

localityName = Ort, Stadt localityName_default = MeineStadt

0.organizationName = Firmenname 0.organizationName_default = MeineFirma

# we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd

organizationalUnitName = Abteilung #organizationalUnitName_default =

commonName = Common Name (z.B. IHR Name, die Serverdomain) commonName_max = 64

emailAddress = E-Mail-Addresse emailAddress_max = 64 </cli>

1.3 Create the necessary directories and files

Now you have to create the directories and files you specified in the openssl.cnf:

<cli> mkdir /root/RootCA # or whatever your CA-Name / directory is cd /root/RootCA mkdir newcerts certs crl private touch index.txt # Serialnr starts with 01 echo “01” > serial </cli>

1.4 Generate random data for the CA certificate

You need to install the package sharutils to be able to use the uuencode program.

<cli> cat /dev/urandom | uuencode -m bla | head -19 | sed “s/begin.*g”\ | tail -18 | xargs | sed “s/ g” > /root/RootCA/private/.rand chmod 770 /root/RootCA/private/.rand ls -alh /root/RootCA/private/.rand </cli>

1.5 Create the CA certificate

Now we can create our CA certificate…

Generate the key. You should use a very strong passphrase for this key - it has to be secure for the next few years! <cli>

openssl genrsa -aes256 -out private/RootCA.key.pem -rand private/.rand 2048

</cli>

Generate the certificate: <cli> openssl req -new -x509 -days 1827 -key private/RootCA.key.pem -out RootCA.cert.pem </cli>

(-days 1827 generates a certificate which is valid for 5 years)

Check if the certificate-data is alright: <cli> openssl x509 -in RootCA.cert.pem -text | less </cli>

Copy the certificate and the private key to the locations specified in the openssl.cnf: <cli> cp /root/RootCA/RootCA.cert.pem /root/RootCA/cacert.pem cp /root/RootCA/private/RootCA.key.pem /root/RootCA/private/cakey.pem </cli>

Put the certificate under the control of the CA. Therefore it has to be copied with its serialnumber as filename into the directory certs and linked there with its hash-value: <cli> cd /root/RootCA cp RootCA.cert.pem /root/RootCA/certs/00.pem cd /root/RootCA/certs/ ln -s 00.pem `openssl x509 -hash -noout -in 00.pem`.0 </cli>

1.6 Publish the CA certificate

Now the CA is initialized and you can distribute its certificate. To do so, rename the .cert.pem-file as .crt-file, copy it in a place reachable via the internet and make it accessible by everybody:

<cli> cp /root/RootCA/RootCA.cert.pem /var/www/virtual/yourdomain.com/htdocs/RootCA.crt chmod 444 /var/www/virtual/yourdomain.com/htdocs/RootCA.crt </cli>

Now it's time to import the certificate into your browser. Therefore, just surf to http://yourdomain.com/RootCA.crt

2. Create the server certificates

2.1 Sample server certificate generation

All server certificates are created the same way. They shouldn't have a passphrase because you don't want to enter this passphrase everytime you start your apache or another server. Disabling the passphrase is done by omitting the encryption-algorithm when creating the private key.

<cli> cd /root/RootCA touch /root/RootCA/index.txt openssl genrsa -out server.key.pem -rand private/.rand 2048 # Generate the key openssl req -new -key server.key.pem -out server.req.pem # Generate the certificate request openssl ca -name RootCA -in server.req.pem -out server.cert.pem # Sign the request with your CA (you have to enter the CA-passphrase) </cli>

[note by Quattro]: Something is missing here, not certain what is missing though [note by sseitz]: Yes, openssl ca expects an index.txt in place. Added above.

Move the certificate into the certs-directory and link it with its hash-value: <cli> mv newcerts/01.pem certs/ # the certificate is named with its serialnumber - so its name is 01.pem only the first time, of course) cd certs ln -s 01.pem `openssl x509 -hash -noout -in 01.pem`.0 </cli>

I suppose to save the originial certificate-files into a subdirectory called server:

<cli> mkdir /root/RootCA/server mv server.*.pem server/ </cli>

2.1.1 Automated service creation

If you tired to do manually steps above, you can put in /root/RootCA/makecert that script:

#!/bin/bash

SERVER=$1
CA=/root/RootCA

# Print error and exit.
die()
{
   echo "ERROR: $1" 1>&2
   exit 1
}

if [ -z "$1" ]; then
        echo "Usage: makecert <servername>"
        exit
fi
if [ -f "$SERVER.cert.pem" ]; then
        die "Remove old cert before generation of new"
fi

if [ ! -f "$SERVER.key.pem" ]; then
        openssl genrsa -out $SERVER.key.pem 2048 || die "Error in keygen"
        chmod 400 $SERVER.key.pem
        chmod 400 $SERVER.key.pem
fi
if [ ! -f "$SERVER.req.pem" ]; then
        openssl req -new -key $SERVER.key.pem -out $SERVER.req.pem || die "Error in req gen"
fi
openssl ca -name FloCA -in $SERVER.req.pem -out $SERVER.cert.pem || die "Error in cert gen"
NAME=$(basename $CA/newcerts/*pem)
mv $CA/newcerts/$NAME $CA/certs/$NAME || die "Can't copy $NAME"
ln -s $NAME $CA/certs/`openssl x509 -hash -noout -in $CA/certs/$NAME`.0

echo "New $SERVER.cert.pem generated"

<fc #FF0000>The above Code didn't work for me, till i delete -name FlohCA in the source-code of the bash-script</fc>

Then, to create certificate just do

<cli> /root/RootCA/makecert server </cli>

And you will get in current directory server.key.pem with private key, server.req.pem with key request and server.cert.pem with certificate.

If your certificate get outdated, remove/rename server.cert.pem and run makecert again, it will generate new cert based on old req. If you have entered wrong info in request, just remove .req. and .cert. file, and run makecert again.

2.2 Create the certificate for the apache server

Generate a server certificate as described under 2.1 (choose apache.key.pem, apache.req.pem and apache.cert.pem as filenames). When generating the apache.req.pem, enter this:

<cli> Organizational Unit Name []:Apache Webserver Common Name (eg, YOUR name) []:yourdomain.com </cli>

It is important to enter the domain name under which you want to reach ispCP, because otherwise you get a domain mismatch error when connecting via ssl.

After you've generated the certificate, change the following settings in /etc/apache2/mods-available/ssl.conf (replace 512 with 2048): <cli> SSLRandomSeed startup /dev/urandom 2048 SSLRandomSeed connect /dev/urandom 2048 </cli>

Then copy the certificate files (with secure file permissions): <cli> cp apache.cert.pem apache.key.pem /etc/apache2/ssl chmod 400 /etc/apache2/ssl/apache.cert.pem /etc/apache2/ssl/apache.key.pem </cli>

Tell apache to listen on the ssl-port (443) - therefore add <cli> Listen 443 </cli> to the file /etc/apache2/ports.conf and enable mod_ssl: <cli> a2enmod ssl </cli>

As last step you have to add a new VirtualHost, which listens on port 443 and has the SSL engine enabled:

<cli> cp /etc/apache2/sites-available/00_master.conf /etc/apache2/sites-available/01_ssl_master.conf </cli>

Change the 01_ssl_master.conf file like this:

<cli> # # SSL Master Begin #

<VirtualHost xxx.xxx.xxx.xxx:443>

  #
  # SSL Start
  #
  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl/apache.cert.pem
  SSLCertificateKeyFile /etc/apache2/ssl/apache.key.pem
  #
  # SSL End
  #
  ServerAdmin     admin@yourdomain.com
  DocumentRoot    /var/www/ispcp/gui
  ServerName      yourdomain.com
  ErrorLog        /var/log/apache2/users/ssl.yourdomain.com-error.log
  TransferLog     /var/log/apache2/users/ssl.yourdomain.com-access.log
  CustomLog       /var/log/apache2/ssl.yourdomain.com-traf.log traff
  CustomLog       /var/log/apache2/ssl.yourdomain.com-combined.log combined

# # … below here, nothing has to be changed #

</VirtualHost>

# # SSL Master End # </cli>

Enable the ssl site: <cli> a2ensite 01_ssl_master.conf </cli> Now reload the apache server: <cli> /etc/init.d/apache2 reload </cli> and you're done!

Open your browser and enter https://yourdomain.com and you should see the ispCP login - SSL encrypted. (By the way, phpMyAdmin and the Webmail interface are now also encrypted)

2.3 Create the certificate for the courier server

At first, you have to install the ssl-packages for courier: <cli> apt-get install courier-imap-ssl courier-pop-ssl </cli>

Now you can generate the server certificate as described under 2.1 (choose courier.key.pem, courier.req.pem and courier.cert.pem as filenames). When generating the courier.req.pem, enter this:

<cli> Organizational Unit Name []:Courier Mailserver Common Name (eg, YOUR name) []:mail.yourdomain.com </cli>

The courier server needs the cert and the key-file together in one file: <cli> cd /root/RootCA/server cat courier.cert.pem courier.key.pem > courier.pem </cli>

Put the Certificates under /etc/courier:

<cli> cd /etc/courier cp /root/RootCA/server/courier.pem . chmod 400 courier.pem ln -s courier.pem imapd.pem ln -s courier.pem pop3d.pem </cli>

Now you can restart the courier-ssl servers: <cli> /etc/init.d/courier-imap-ssl restart /etc/init.d/courier-pop-ssl restart </cli> and SSL is working for your IMAP and POP3-Server!

2.4 Create the certificate for the ProFTPD server

Generate the server certificate as described under 2.1 (choose proftpd.key.pem, proftpd.req.pem and proftpd.cert.pem as filenames). When generating the proftpd.req.pem, enter this:

<cli> Organizational Unit Name []:ProFTPD FTP-Server Common Name (eg, YOUR name) []:ftp.yourdomain.com </cli>

Copy the files in /etc/proftpd: <cli> cd /etc/proftpd cp /root/RootCA/server/proftpd.cert.pem /root/RootCA/server/proftpd.key.pem . chmod 400 proftpd.cert.pem proftpd.key.pem </cli>

Activate TLS in /etc/proftpd.conf (uncomment these lines): <cli> # # SSL via TLS # <IfModule mod_tls.c>

TLSEngine                   on                                      # on for use of TLS
TLSLog                      /var/log/proftpd/ftp_ssl.log            # where to log to
TLSProtocol                 SSLv23                                  # SSLv23 or TLSv1
TLSOptions                  NoCertRequest                           # either to request the certificate or not
TLSRSACertificateFile       /etc/proftpd/proftpd.cert.pem           # SSL certfile
TLSRSACertificateKeyFile    /etc/proftpd/proftpd.key.pem            # SSL keyfile
TLSVerifyClient             off                                     # client verification

</IfModule> </cli>

Restart ProFTPD: <cli> /etc/init.d/proftpd restart </cli> That's all! Now you can connect to ftp.yourdomain.com via FTP with explicit TLS/SSL.

2.5 Create the certificate for the postfix server

Generate the server certificate as described under 2.1 (choose postfix.key.pem, postfix.req.pem and postfix.cert.pem as filenames). When generating the postfix.req.pem, enter this:

<cli> Organizational Unit Name []:Postfix Mailserver Common Name (eg, YOUR name) []:mail.yourdomain.com </cli>

Copy the files in /etc/postfix: <cli> cd /etc/postfix cp /root/RootCA/server/postfix.cert.pem /root/RootCA/server/postfix.key.pem . chmod 400 postfix.cert.pem postfix.key.pem </cli>

Activate TLS/SSL in /etc/postfix/main.cf (uncomment these lines): <cli> smtpd_tls_loglevel = 2 smtpd_tls_cert_file = /etc/postfix/postfix.cert.pem smtpd_tls_key_file = /etc/postfix/postfix.key.pem smtpd_use_tls = yes smtpd_tls_auth_only = no smtpd_tls_received_header = yes </cli>

Restart postfix: <cli> /etc/init.d/postfix restart </cli> And another one… You can now send your emails over an SSL-encrypted connection.

3. Finished

Now you have configured your webserver (for ispCP), your mailservers and your ftp-server to use a ssl-encrypted connection.

Don't forget to distribute the CA-Certificate (it's accessible via http://yourdomain.com/RootCA.crt, isn't it?) to the people who access your server, so that they don't have to accept each single server certificate.