NSLU2-Linux
view · edit · print · history

Once Apache is running correctly, you have to do three things to enable the https server:

  • create your server key
  • create your certificate authority (CA)
  • enable SSL in the init script and reload apache

Remark: this small HowTo is an aggregation of the Apache SSL-FAQ.

At the bottom of this HowTo is a detailed script which will automate the creation and signing of all the keys and certificates. All that remains is the configuration of the apache configuration files.

server key

Navigate to /opt/etc/apache2, create two new directories:

 $ mkdir ssl.key
 $ mkdir ssl.crt

and your server key:

 $ cd ssl.key
 $ openssl genrsa -des3 -out server.key 1024

If you want to remove the passphrase from the key, you can do it like this:

 $ mv server.key server.key.orig
 $ openssl rsa -in server.key.orig -out server.key
 $ chmod 400 server.key

Now, prepare a certificate signing request (CSR):

 $ openssl req -new -key server.key -out server.csr

Important: you will be asked for the CommonName. Enter your web servers name, i.e. www.example.com.

If you want to make it work, use localhost for your CommonName.

certificate authority

You have to create a new key for your CA:

 $ openssl genrsa -des3 -out ca.key 1024

Just like above, if you want to remove the passphrase from the key, you can do it like this:

 $ mv ca.key ca.key.orig
 $ openssl rsa -in ca.key.orig -out ca.key
 $ chmod 400 ca.key

and generate a self signed certificate it:

 $ openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Now, you can sign your server key. Therefore you should use a script that is shipped with mod_ssl. For your convenience the script can be found at the end of this page.

 $ ./sign.sh server.csr

You should see something like this:

CA signing: server.csr -> server.crt:
Using configuration from ca.config
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'ZZ'
stateOrProvinceName :PRINTABLE:'Blah'
localityName :PRINTABLE:'Blah Blah'
organizationName :PRINTABLE:'Bogotron Ltd'
organizationalUnitName:PRINTABLE:'NSLU2 Division'
commonName :PRINTABLE:'localhost'
Certificate is to be certified until Apr 19 21:11:57 2006 GMT (365 days)
Sign the certificate? [y/n]:

Double-check that your commonName is actually a verifyable hostname by the NSLU2 and press Y...

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
CA verifying: server.crt <-> CA cert
server.crt: OK

If you see anything else, chances are that it won't work properly and you may have to regenerate your keys with a proper commonName.

Copy the result to the right place:

 $ cp server.crt ../ssl.crt/

enable SSL in the init script

Last but not least you have to add a directive to the S80apache script

 $ vi /opt/etc/init.d/S80apache

 -/opt/sbin/httpd -k restart
 +/opt/sbin/httpd -DSSL -k restart

... change any required settings for SSL page serving...

 $ vi /opt/etc/apache2/ssl.conf

... and restart the server:

 $ /opt/etc/init.d/S80apache

Testing

To see that SSL is working correctly, issue the following command:

 $ openssl s_client -connect localhost:443 -state -debug

Automated CA and key setup script

I couldn't get the self signing script above to work, so I wrote a more comprehensive alternative which creates the CA and server key and signs it.

Copy this script to your NSLU2, ensure that it is executable (chmod +x apache2-ssl-setup.sh). Edit it to add your specific details and then execute it. This script will build all your directories and keys and certificates for you automatically. It will create and then request you to edit certain paramater files when first run. Just follow the on-screen instructions.

By default it does not remove the security from the server key.

I actually got a set of working ssl keys out of this.

 

#!/bin/sh -e
#
# detailed comments extracts from http://www.tc.umn.edu/~brams006/selfsign.html
# inspired by the debian apache2-ssl-certificate script
# inspired by openssl sign.sh script

KEY_SIZE=4096

TARGET_ROOT=/opt/etc/apache2
TARGET_CA_KEY=$TARGET_ROOT/ssl.key/ca.key
TARGET_CA_CRT=$TARGET_ROOT/ssl.crt/ca.crt
TARGET_SRV_KEY=$TARGET_ROOT/ssl.key/server.key
TARGET_SRV_CSR=$TARGET_ROOT/ssl.key/server.csr
TARGET_SRV_CRT=$TARGET_ROOT/ssl.crt/server.crt

#Challenge passwords used in the script
CA_CHPWD=<password>
SRV_CHPWD=<password>

if [ "$1" != "--force" -a -f $TARGET_CA_CRT ]; then
  echo "$TARGET_CA_CRT exists!  Use \"$0 --force.\""
  exit 0
fi

if [ "$1" = "--force" ]; then
  shift
fi     

echo
echo creating selfsigned certificate
echo "replace it with one signed by a certification authority (CA)"
echo
echo If you want your certificate to expire after x days call this programm 
echo with "-days x" 
echo

# create the folders
if [ -d $TARGET_ROOT/ssl.key ]; then
    echo "$TARGET_ROOT/ssl.key folder already exists"
else
    echo "creating $TARGET_ROOT/ssl.key folder"
    mkdir $TARGET_ROOT/ssl.key
fi

if [ -d $TARGET_ROOT/ssl.crt ]; then
    echo "$TARGET_ROOT/ssl.crt folder already exists"
else
    echo "creating $TARGET_ROOT/ssl.crt folder"
    mkdir $TARGET_ROOT/ssl.crt
fi

# --- CREATE CERTIFICATE AUTHORITY ---

# use special .cnf, because with normal one no valid selfsigned
# server certificate is created

# It's been noted that the organizational name, unit name and common
# name should not match what you supply when you create your server key
# These fields for the CA are not quite as crucial
# as your server key fields. For
# instance, if your common name is "www.somesite.edu" you might want to
# provide something like "Somesite Cert Authority" for the common name
# of the CA in this step, and "www.somesite.edu" -- the fully qualified
# domain name (or IP) for the common name in the server key generating
# step. Do something similar with the unit and organizational
# names also. Just make sure the entries for these three fields don't
# match what you provide while generating a CA (this step) and the
# server key (next step).

if [ ! -f ~/ca.config ]; then

#   create a config file for req
cat >~/ca.config <<EOT
[ req ]
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no

[ req_distinguished_name ]
C                      = <Country Name (2 letter code)>
ST                     = <State or Province Name (full name)>
L                      = <localityName = Locality Name (eg, city)>
O                      = <Organization Name (eg, company; recommended) -- MUST BE DIFFERENT FROM SERVER KEY VALUE >
OU                     = <Organizational Unit Name (eg, section)-- MUST BE DIFFERENT FROM SERVER KEY VALUE >
CN                     = <common name (eg. Somesite Certificate Authority; required!!!)-- MUST BE DIFFERENT FROM SERVER KEY VALUE >
emailAddress           = <email address>

[ req_attributes ]
unstructuredName       = <unstructured name>
EOT

echo
echo "Please edit and configure the file '~/ca.config' with your server details and then try again"
exit 1

fi

#export RANDFILE=/dev/random
#openssl req $@ -config ~/ca.config \
#               -new \
#               -x509 \
#               -nodes \
#               -out $TARGET_CA_CRT \
#               -keyout $TARGET_CA_CRT
#chmod 600 $TARGET_CA_CRT

#ln -sf /etc/apache2/ssl/apache.pem \
#  /etc/apache2/ssl/`/usr/bin/openssl \
#  x509 -noout -hash < /etc/apache2/ssl/apache.pem`.0

echo
echo "Creating CA Key: $TARGET_CA_KEY"
echo
openssl genrsa -des3 -passout pass:$CA_CHPWD -out $TARGET_CA_KEY $KEY_SIZE
echo
echo "Creating CA Certificate: $TARGET_CA_CRT"
echo
openssl req $@ -new -x509 -config ~/ca.config -passin pass:$CA_CHPWD -key $TARGET_CA_KEY -out $TARGET_CA_CRT


## -- CREATE SERVER KEY -- 
# 
# 
# Think carefully when inputting a Common Name (CN) as you generate the 
# .csr file below. This should
# match the DNS name, or the IP address you specify in the httpd.conf or
# ssl.conf (if this portion is separated outside of httpd.conf) for your
# server. If they don't match, client browsers will get a "domain
# mismatch" message when going to your https web server. If you're doing
# this for home use, and you don't have a static IP or DNS name, you
# might not even want worry about the message (but you sure will need to
# worry if this is a production/public server). For example, you could
# match it to an internal and static IP you use behind your router, so
# that you'll never get the "domain mismatch" message if you're
# accessing the computer on your home LAN, but will always get that
# message when accessing it elsewhere. Your call -- is your IP stable,
# do you want to repeat these steps every time your IP changes, do you
# have a DNS name, do you mainly use it inside your home or LAN, or
# outside?


if [ ! -f ~/server.config ]; then

#   create a config file for req
cat >~/server.config <<EOT
[ req ]
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no

[ req_distinguished_name ]
C                      = <Country Name (2 letter code)>
ST                     = <State or Province Name (full name)>
L                      = <localityName = Locality Name (eg, city)>
O                      = <Organization Name (eg, company; recommended)>
OU                     = <Organizational Unit Name (eg, section)>
CN                     = <server name (eg. ssl.domain.tld; required!!!)>
emailAddress           = <email address>

[ req_attributes ]
unstructuredName       = <unstructured name>
EOT

echo
echo "Please edit and configure the file '~/server.config' with your server details and then try again"
exit 1

fi

echo
echo "Creating Server Key: $TARGET_SRV_KEY"
echo
openssl genrsa -des3 -passout pass:$SRV_CHPWD -out $TARGET_SRV_KEY $KEY_SIZE
echo
echo "Creating Server Key Signing Request: $TARGET_SRV_CSR"
echo
openssl req -new -config ~/server.config -passin pass:$SRV_CHPWD -key $TARGET_SRV_KEY -out $TARGET_SRV_CSR

#--- SIGN SERVER KEY USING CA ---
#
# Note also that I set the serial number of the signed server
# certificate to "01". Each time you do this, especially if you do this
# before a previously-signed certificate expires,
# you'll need to change the serial key to something else -- otherwise
# everyone who's visited your site with a cached version of your certificate 
# will get a warning message to the effect that your certificate signing
# authority has screwed up -- they've signed a new key/request, but kept
# the old serial number.
# 
# The command below does a number of things. It takes your signing
# request (csr) and makes a one-year valid signed server certificate (
# crt) out of it. In doing so, we need to tell it which certificate
# authority (ca) to use, which ca key to use, and which server key to
# sign. We set the serial number to 01, and output the signed key in the
# file named server.crt. If you do this again after people have visited
# your site and trusted your CA (storing it in their browser), you might
# want to use 02 for the next serial number, and so on.

echo
echo "Creating Signed Server Certificate: $TARGET_SRV_CRT"
echo
openssl x509 -req $@ -passin pass:$SRV_CHPWD -in $TARGET_SRV_CSR -CA $TARGET_CA_CRT -CAkey $TARGET_CA_KEY -set_serial 01 -out $TARGET_SRV_CRT

#--- UNSECURE KEY ---
#
# Make a server.key which doesn't cause apache to prompt for a password.
#
# Here we create an insecure version of the server.key. The insecure one
# will be used for when Apache starts, and will not require a password
# with every restart of the web server. But keep in mind that while this
# means you don't have to type in a password when restarting Apache (or
# worse -- coding it somewhere in plaintext), it does mean that anyone
# obtaining this insecure key will be able to decrypt your
# transmissions. Guard it for permissions VERY carefully.

# uncomment if you want this option

#openssl rsa -in $TARGET_SRV_CRT -out $TARGET_SRV_CRT.insecure
#mv $TARGET_SRV_CRT $TARGET_SRV_CRT.secure
#mv $TARGET_SRV_CRT.insecure $TARGET_SRV_CRT

exit 0




sign.sh

This script has broadly been incorporated in the script above, although the script above does not attempt to verify the signing since it is problematic on the NSLU2.

 

#!/bin/sh
##
##  sign.sh -- Sign a SSL Certificate Request (CSR)
##  Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.
##

#   argument line handling
CSR=$1
if [ $# -ne 1 ]; then
    echo "Usage: sign.sign <whatever>.csr"; exit 1
fi
if [ ! -f $CSR ]; then
    echo "CSR not found: $CSR"; exit 1
fi
case $CSR in
   *.csr ) CERT="`echo $CSR | sed -e 's/\.csr/.crt/'`" ;;
       * ) CERT="$CSR.crt" ;;
esac

#   make sure environment exists
if [ ! -d ca.db.certs ]; then
    mkdir ca.db.certs
fi
if [ ! -f ca.db.serial ]; then
    echo '01' >ca.db.serial
fi
if [ ! -f ca.db.index ]; then
    cp /dev/null ca.db.index
fi

#   create an own SSLeay config
cat >ca.config <<EOT
[ ca ]
default_ca              = CA_own
[ CA_own ]
dir                     = .
certs                   = \$dir
new_certs_dir           = \$dir/ca.db.certs
database                = \$dir/ca.db.index
serial                  = \$dir/ca.db.serial
RANDFILE                = \$dir/ca.db.rand
certificate             = \$dir/ca.crt
private_key             = \$dir/ca.key
unique_subject          = no
default_days            = 365
default_crl_days        = 30
default_md              = md5
preserve                = no
policy                  = policy_anything
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
EOT

#  sign the certificate
echo "CA signing: $CSR -> $CERT:"
openssl ca -config ca.config -out $CERT -infiles $CSR
echo "CA verifying: $CERT <-> CA cert"
openssl verify -CAfile ca.crt $CERT

#  cleanup after SSLeay
rm -f ca.config
rm -f ca.db.serial.old
rm -f ca.db.index.old

#  die gracefully
exit 0


view · edit · print · history · Last edited by RalphFinch.
Based on work by MattMcNeill, tman, RobHam, pTweety, and barrym.
Originally by pTweety.
Page last modified on October 14, 2008, at 11:39 PM