Using CAcert.org signed certificates for TLS

Setting up Transport Layer Security (TLS), or as previously known as Secure Sockets Layer (SSL), for Apache, Postfix and IMAP like Dovecot is fairly easy. You just need some digital certificates and configuration. If you don’t want to pay for certificates from trusted sources like Thawte or you just don’t need that kind of trust (for development purposes), you can always produce your own certificates. But there is also a middle way: using CAcert.org signed certificates.

Background
Wikipedia tells us that CAcert.org is a community-driven certificate authority that issues free public key certificates. CAcert automatically signs certificates for email addresses controlled by the requester and for domains for which certain addresses (such as “hostmaster@example.com”) are controlled by the requester. Thus it operates as a robot certificate authority. CAcert certificates can be used like any other SSL certificates although they are considered weak because CAcert does not emit any information in the certificates other than the domain name or email address. To create higher-trust certificates, users can participate in a web of trust system whereby users physically meet and verify each other’s identities. They are also not as useful in web browsers as certificates issued by commercial CAs such as VeriSign, because most installed web browsers do not distribute CAcert’s root certificate. Thus, for most web users, a certificate signed by CAcert behaves like a self-signed certificate.

Generating Certificates
The procedure to sign your certificate at CAcert is rather simple. This guide assumes that the certificates are in /etc/ssl/cacert/ and you are as root.

0. Join CAcert.org and fill in your details. After email verification and login, add domain and service will try to verify that you can read mail on one of following accounts: root, hostmaster, postmaster, admin, webmaster or email addresses that can be found on whois data of domain that you provided.

1. Generate a private key that is not file encrypted:

openssl genrsa -out domainname.key 1024
chown root:root domainname.key
chmod 0400 domainname.key

Private keys should belong to “root” and be readable only by root.

You could also create a private key that is encrypted: openssl genrsa -des3 -out domainname.key 1024

2. Create a CSR with the RSA private key (output will be PEM format). Do not enter extra attributes at the prompt and leave the challenge password blank (press enter):

openssl req -new -key domainname.key -out domainname.csr

3. Verify the contents of the CSR or private key:

openssl req -noout -text -in domainname.csr
openssl rsa -noout -text -in domainname.key

4. Send your public key to be signed by and request new server certificate from CAcert.org web site (Class 1 certificate). When you are asked for CSR paste content of domainname.csr. It should look like this:

-----BEGIN CERTIFICATE REQUEST-----
MIIB3TCCAUYCAQAwgZwxCzAJBgNVBAYTAkZJMRAwDgYDVQQIEwdVdXNpbWFhMQ8w
...clip...
MQ==
-----END CERTIFICATE REQUEST-----

You can verify the content of request before sending it

openssl req -in domainname.csr -text -verify -noout

5. Copy the Server Certificate from the CAcert.org webpage and put it in domainname.crt file and add permissions.

chmod a=r domainname.crt

Check at least the contents of Validity and Subject fields:

openssl x509 -in domainname.crt -text -noout

6. Get CAcert.org root certificate

wget -nv https://www.cacert.org/certs/root.crt -O cacert-org.crt
chmod a=r cacert-org.crt

Check the contents:

openssl x509 -in cacert-org.crt -text -noout

After that you’re ready to configure your services like Apache, Postfix and Dovecot to use the new certificate. Read about it later.

For year 2012

The year 2011 has been pretty quiet in this blog as I managed to write just one post. In the backlog I have had for some time a couple of articles almost done and several topics to write about but as it sometimes happens, the time runs out.

For the coming year 2012 I have made a promise to myself to research technology related issues and also write about them to this blog and to my Finnish blog. Now I have just done the former and kept the new information to myself :) Including the articles in the backlog I also have some new topics to write. So subscribe to the RSS feed and stay tuned.

Happy New Year!

WordPress mod_rewrite rules taking over mod_status and mod_info

After moving Rule of Tech to a new server and setting up monitoring I noticed that server-status and server-info Apache modules weren’t working as expected. As usual a little bit of Googling solved this problem.

The problem was that the .htaccess rules in WordPress were taking over non-existing server-info and server-status urls given in Apache’s config and were returning a page not found error. The rewrite rules by WordPress were setup to handle all the permalinks on the site and for any non-existing file send it to index.php. It really wasn’t a WordPress problem and should happen with any application that uses the same type of catch-all rewrite rules to handle all the urls inside the application.

The solution was to specifically add a rewrite rule to not have the server-status and server-info urls processed by adding a rule like: RewriteCond %{REQUEST_URI} !=/server-status. The other way is to stop the rewriting process when the urls are found by adding a rule like: RewriteRule ^(server-info|server-status) - [L].

The WordPress rewrite rules should look like this:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# server info and status
RewriteRule ^(server-info|server-status) - [L]
# RewriteCond %{REQUEST_URI} !=/server-status
# /server info and status
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . index.php [L]
</IfModule>
# END WordPress

Installing Apache Tomcat 6 on CentOS

CentOS is great substitute for Red Hat Enterprise Linux but is missing some useful packages like Apache Tomcat 6. Installing Apache Tomcat 6 on CentOS 5 from gzip-package is fairly easy. The following guide is at least for CentOS 5.4.

Pre-Requirements
First you need to install Sun JDK and you can follow the instructions given in Installing Sun JDK 1.6 on CentOS

After Java is on place it’s time to get ready for Tomcat.

Download Apache Ant and Tomcat

  1. Download apache-ant and apache-tomcat -packages.
  2. Extract those packages to /opt/
    • #[root@srv ~]# cd /opt
      # tar -xzf apache-tomcat-6.0.26.tar.gz
      # tar -xzf apache-ant-1.7.1-bin.tar.gz
      
  3. Create a symbolic link for Ant
    • # ln -s /opt/apache-ant-1.7.1/bin/ant /usr/bin/
      

Create start script

  1. Create a tomcat user so that we don’t need root privileges for Tomcat
    • # useradd -d /opt/apache-tomcat-6.0.26/ tomcat
      
  2. Create start script to /etc/init.d for starting and stopping Tomcat
    • #  vim /etc/init.d/tomcat
      
  3. The script is (via Build a safe cage for Tomcat)
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      
      #!/bin/bash
      #
      # tomcat       Starts Tomcat Java server.
      #
      #
      # chkconfig: 345 88 12
      # description: Tomcat is the server for 
      # Java servlet applications.
      ### BEGIN INIT INFO
      # Provides: $tomcat
      ### END INIT INFO
       
      JAVA_HOME=/usr/java/jdk1.6.0_18
      export JAVA_HOME
      TOMCAT_HOME=/opt/apache-tomcat-6.0.26/bin
      START_TOMCAT=/opt/apache-tomcat-6.0.26/bin/startup.sh
      STOP_TOMCAT=/opt/apache-tomcat-6.0.26/bin/shutdown.sh
       
      # Source function library.
      . /etc/init.d/functions
       
      [ -f $START_TOMCAT ] || exit 0
      [ -f $STOP_TOMCAT ] || exit 0
       
      RETVAL=0
       
      umask 077
       
      start() {
              echo -n $"Starting Tomcat Java server: "
              daemon su -c $START_TOMCAT tomcat
              echo
              return $RETVAL
      }
      stop() {
              echo -n $"Shutting down Tomcat Java server: "
              daemon su -c $STOP_TOMCAT tomcat
              echo
              return $RETVAL
      }
      restart() {
              stop
              start
      }
      case "$1" in
        start)
              start
              ;;
        stop)
              stop
              ;;
        restart|reload)
              restart
              ;;
        *)
              echo $"Usage: $0 {start|stop|restart}"
              exit 1
      esac
       
      exit $?
  4. Give executable rights for that script
    • # chmod 755 /etc/init.d/tomcat
      
  5. Add the script to CentOS services
    • # chkconfig --add tomcat
      
  6. Check the changes
    • # chkconfig --level 234 tomcat on
      # chkconfig --list tomcat
      
      tomcat 0:off 1:off 2:on 3:on 4:on 5:off 6:off
      
  7. You should see that the service uses levels 2, 3 and 4
  8. Test that the script is working and it gives no errors
    • # service tomcat start
      # service tomcat stop
      
  9. Everythings ready

Installing Sun JDK 1.6 on CentOS

CentOS doesn’t have a package for Sun JDK so it has to installed manually. It’s fairly easy but there are some steps to do that. This guide has been tested on CentOS 5.4 x64_86.

Step 1. Initial setup for building RPM
-!- Do this with a non-root user

  1. Create ~/.rpmmacros
    • $ vim ~/.rpmmacros
      %_topdir /home//rpmbuild
      %_tmppath %{_topdir}/tmp
      
  2. Create needed folders:
    • $ mkdir -p ~/rpmbuild/{SOURCES,SRPMS,SPECS,RPMS,tmp,BUILD}
      
  3. Build environment needs to be complete. Some needed packages are:
    • $ sudo yum install -y rpm-build gcc gcc-c++ redhat-rpm-config
      

Step 2. Installing your favorite JDK

  1. Download Sun JDK 1.6 update 14 from Sun Java download or the Sun JDK archive.
    • Choose the correct platform (for me it’s Linux x64) and download jdk-6u18-linux-x64-rpm.bin
  2. Give it executable rights: $ chmod 755 jdk-6u18-linux-x64-rpm.bin
  3. Run the binary to extract it into RPM form: $ ./jdk-6u18-linux-x64-rpm.bin
  4. Install it:
    • $ sudo rpm -Uvh jdk-6u18-linux-amd64.rpm
      
  5. Log out and in again to make the changes in the paths take effect
  6. Check the install
    • $ java -version
      java version "1.6.0_18"
      Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
      Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
      
  7. Java is now installed on /usr/bin/java