Saturday 31 October 2009

Fixing VirtualBox VRMMRO.r0 Error on Ubuntu

I'd just rebuilt my eeepc recently and decided to install Virtualbox. Unfortunately after installing it from the Ubuntu repository it didn't quite work, giving the error "Failed to load VMMR0.r0 (VERR_SYMBOL_NOT_FOUND)".


From googling around it quickly became apparent that there's an easy fix, to uncomment a single line in a Makefile and re-compile the Virtualbox kernel modules. Unfortunately the package on Ubuntu won't recompile due to a mismatch of paths from the package installer and the actual build script.

The suggested steps for a standard install are:

Edit src/vboxdrv*/Makefile and uncomment the line: # VBOX_USE_INSERT_PAGE = 1

Then run the script /etc/init.d/vboxdrv setup


You'll need some extra steps to create various paths that the build script expects on Ubuntu as follows:

Edit /usr/src/vboxdrv*/Makefile and uncomment the line: # VBOX_USE_INSERT_PAGE = 1

cd /usr/src
ln -s vboxdrv-2.1.4 vboxdrv
ln -s vboxnetflt-2.1.4 vboxnetflt
cd /usr/lib/virtualbox
ln -s /usr/src .

Run /etc/init.d/virtualbox-ose setup



You can work out which links are needed by looking at the startup file /etc/init.d/virtualbox-ose, locate the setup section:

setup()
{
stop

[snip]

begin_msg "Recompiling VirtualBox kernel module"
if ! $BUILDVBOXDRV \
--save-module-symvers /tmp/vboxdrv-Module.symvers \
--no-print-directory install > $LOG 2>&1; then
failure "Look at $LOG to find out what went wrong"
fi
if ! $BUILDVBOXNETFLT \
--use-module-symvers /tmp/vboxdrv-Module.symvers \
--no-print-directory install >> $LOG 2>&1; then
failure "Look at $LOG to find out what went wrong"
fi
rm -f /etc/vbox/module_not_compiled
succ_msg
start
}

BUILDVBOXNETDRV is a variable pointing to the actual build script, it is the install path in the config file /etc/vbox/vbox.cfg, the value ends up being: "/usr/lib/virtualbox/src/vboxdrv/build_in_tmp", which doesn't exist.

If you look in /usr/lib/virtualbox then there is no src path, so create one of those to /usr/src (or you could change the INSTALL_DIR in vbox.cfg but I'm not sure what else that breaks). Then look in /usr/src, no "vboxdrv" directory, so make a link to that. Later in the build you'll run into the same thing for vboxnetflt.



Footnote:
Virtualbox is a great piece of software from Sun, although ESX may be master of the type 1 hypervisor, Virtualbox is (in my opinion) the best type 2 hypervisor around, especially for networking labs. The ability to bind physical NICs to seperate VMs is very handy and being able to do it all from a straightforward GUI in a few minutes is great. It allows Linux and XP to run in parallel on my eeepc and still get 5+ hours battery life.

Read more...

Friday 23 October 2009

ASA Site-to-Site VPN Using Certificates from OpenSSL

To provide increased security over pre-shared keys you can authenticate VPN endpoints using certificates. Ideally this would be using a full PKI solution but a simpler method is available if you don't need revocation.

This guide is for the Cisco ASA. As with most things it's a doddle in the ASDM because you can take full advantage of the GUI and be prompted for each step, however I'll show the CLI commands.


I'll use OpenSSL as a CA, following on from the previous article. There is a Cisco guide for using Microsofts CA (search for "asa site-to-site vpn certificate microsoft" if the link dies), but OpenSSL works just as well. This guide pretty much mirrors the Microsoft one above except for the editing of certificates and OpenSSL commands used to sign the certs.

The ASA can run it's own CA, however it seems aimed squarely at supporting remote user VPNs, it doesn't support signing CSRs and the user certificates it outputs are passcode protected so not usable by another ASA in a site-to-site VPN. If Cisco include that functionality it'd be very useful, if they add SCEP features to allow enrollment of devices then it'll be very handy indeed.


The procedure is:
  1. Install the CA public key onto the ASA.
  2. Generate a Certificate Signing Request (CSR) on the ASA.
  3. Sign the CSR using the CA.
  4. Install the signed certificate onto the ASA.
  5. Configure the VPN.


1. Install the CA public key onto the ASA


If you've followed the directions from the previous article then the public key is called cacert.pem, open this file in a text editor (wordpad rather than notepad if using Windows). On the ASA configure a CA trust point for terminal enrollment (pasting the key into the terminal), the authenticate command will then prompt you to paste the key:
crypto ca trustpoint Test_CA
enrollment terminal

crypto ca authenticate Test_CA
* At this point you'll be prompted to paste the CA public key (from cacert.pem) *


That's it, the ASA will now trust keys signed by your CA.

2. Generate a Certificate Signing Request (CSR) on the ASA.


You could just use the general keys for this but I'd make a specific key for each VPN. You then need a trustpoint where you can fine tune the certificate options. The enroll command will output the key to console.
!Generate the RSA key pair
crypto key generate rsa label FW1-Key modulus 1024

!Configure a trustpoint for the signed certificate
crypto ca trustpoint FW1-Key-trustpoint
enrollment terminal
fqdn 10.0.0.1
subject-name CN=10.0.0.1
keypair FW1-Key
crl configure

!output the CSR to console
crypto ca enroll FW1-Key-trustpoint


Copy this key into a text editor. It'll need the format changed slightly, by default the ASA outputs keys like:
MIIBnicE+P+jvc8JQBSbElTZUH8e7ULzXt8KWZQH6M/0U70wp6lqH6caHeCfDgKW
QIDAQABoDMwMQYJKoZIhbvHyAplT4ToJAATL7GwRhXqcmIpxL8k3xjP3XMkzorMZ
mLZdV8X4byX7Z9MlIEU44iWF+nePEJc60RQRgqTiLPqZcyO8besQxh74FVLW5H40
FE1/FceBzgz4ImgXMcC+0DxrNNToS2wZQDoYo7uL5I6hc9KBiV8Ki0drPe7ZOu4G
Pwdq+Ah9axuXtDua8xPe6G1bRQ9dGCgE4NSeQPnSz380WNqv6TZNddZhERlTNDoX
lbDQG0v+k5zJpCktRYa+f18IvJJxY9pVlpD4WKvyRHdaQydtudPejObY9prIg3rU
Gn1aJyCv0mjgF/JH4wnbhXgNbxBk0J1alpIEupq6Xo=

---End - This line not part of the certificate request---

But you need to edit the key so it looks like this:
-----BEGIN CERTIFICATE REQUEST-----
MIIBnicE+P+jvc8JQBSbElTZUH8e7ULzXt8KWZQH6M/0U70wp6lqH6caHeCfDgKW
QIDAQABoDMwMQYJKoZIhbvHyAplT4ToJAATL7GwRhXqcmIpxL8k3xjP3XMkzorMZ
mLZdV8X4byX7Z9MlIEU44iWF+nePEJc60RQRgqTiLPqZcyO8besQxh74FVLW5H40
FE1/FceBzgz4ImgXMcC+0DxrNNToS2wZQDoYo7uL5I6hc9KBiV8Ki0drPe7ZOu4G
Pwdq+Ah9axuXtDua8xPe6G1bRQ9dGCgE4NSeQPnSz380WNqv6TZNddZhERlTNDoX
lbDQG0v+k5zJpCktRYa+f18IvJJxY9pVlpD4WKvyRHdaQydtudPejObY9prIg3rU
Gn1aJyCv0mjgF/JH4wnbhXgNbxBk0J1alpIEupq6Xo=
-----END CERTIFICATE REQUEST-----


3. Sign the CSR using the CA.


To sign the key, copy it onto the system you've installed OpenSSL as per the previous guide. Use the following command to sign the CSR, mine's saved in a text file as "FW1-req.txt":
openssl ca -in FW1-req.txt -out FW1-signed.txt



4. Install the signed certificate onto the ASA.


To copy this certificate back to the ASA, import it for the trustpoint created earlier:
crypto ca import FW1-Key-trustpoint certificate
* Paste in the edited key as per above *


5. Configure the VPN.



The authentication method is configured in the crypto map, this will appear as follows:

crypto map outside_map 1 match address outside_1_cryptomap
crypto map outside_map 1 set pfs group2
crypto map outside_map 1 set peer 10.0.0.2
crypto map outside_map 1 set transform-set ESP-AES-128-SHA
crypto map outside_map 1 set trustpoint FW1-Key-trustpoint
crypto map outside_map interface outside


The rest of the VPN configuration is the same as pre-shared keys. Congratulations, you've got a certificate based VPN! If it's not working then try with a PSK to verify that the VPN is configured correctly, if that doesn't work then welcome to the wonderful world of debugging VPNs.

Read more...

OpenSSL CA for VPN Certificates

The aim of this article is to provide some pointers to getting a certificate authority (CA) up and running with OpenSSL and provide a few handy commands for reference. This will be used in some future articles about certificate based VPNs.


To do certificate based VPNs you need a couple of things:
  • A Certificate Authority (CA) that your end devices trust.
  • Host certificates signed by the CA.

I'll use the manual signing procedure which is done in several steps:
  1. Install the CA public key on the end devices.
  2. Create a Certificate Signing Request (CSR) on each end device.
  3. Use the CA to sign the CSR.
  4. Install the signed certificate back onto the device.
  5. Configure the VPN to use that certificate for authentication.

I've used the Ubuntu docs project guide to setting up a CA, that can be found here.

Update - August 2012 - Because Ubuntu are redirecting that site to another page with a different domain name the SSL cert is being rejected by strict filtering systems, so I'm copy/pasting some of it here for reference. The following is taken from the link above:
Creating the Certificate Authority
First, create an initial working environment, for example within your home directory by issuing the following command from a terminal prompt:


cd && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCA
The above command will place you in a newly-created subdirectory of your home directory named myCA, and within this subdirectory, you should have two additional subdirectories named signedcerts and private.

Within this initial working environment, the significance of the subdirectories, and their contents is as follows:

~/myCA : contains CA certificate, certificates database, generated certificates, keys, and requests

~/myCA/signedcerts : contains copies of each signed certificate 

~/myCA/private : contains the private key

Next, create an initial certificate database in the ~/myCA subdirectory with the following command at a terminal prompt:

echo '01' > serial  && touch index.txt

Now create an initial caconfig.cnf file suitable for the creation of CA certificates. Using your favorite editor, edit the file ~/myCA/caconfig.cnf, and insert the following content into the file:

sudo nano ~/myCA/caconfig.cnf

# My sample caconfig.cnf file.
#
# Default configuration to use when one is not provided on the command line.
#
[ ca ]
default_ca      = local_ca
#
#
# Default location of directories and files needed to generate certificates.
#
[ local_ca ]
dir             = /home//myCA
certificate     = $dir/cacert.pem
database        = $dir/index.txt
new_certs_dir   = $dir/signedcerts
private_key     = $dir/private/cakey.pem
serial          = $dir/serial
#       
#
# Default expiration and encryption policies for certificates.
#
default_crl_days        = 365
default_days            = 1825
default_md              = md5
#       
policy          = local_ca_policy
x509_extensions = local_ca_extensions
#       
#
# Default policy to use when generating server certificates.  The following
# fields must be defined in the server certificate.
#
[ local_ca_policy ]
commonName              = supplied
stateOrProvinceName     = supplied
countryName             = supplied
emailAddress            = supplied
organizationName        = supplied
organizationalUnitName  = supplied
#       
#
# x509 extensions to use when generating server certificates.
#
[ local_ca_extensions ]
subjectAltName          = DNS:alt.tradeshowhell.com
basicConstraints        = CA:false
nsCertType              = server
#       
#
# The default root certificate generation policy.
#
[ req ]
default_bits    = 2048
default_keyfile = /home//myCA/private/cakey.pem
default_md      = md5
#       
prompt                  = no
distinguished_name      = root_ca_distinguished_name
x509_extensions         = root_ca_extensions
#
#
# Root Certificate Authority distinguished name.  Change these fields to match
# your local environment!
#
[ root_ca_distinguished_name ]
commonName              = MyOwn Root Certificate Authority
stateOrProvinceName     = NC
countryName             = US
emailAddress            = root@tradeshowhell.com
organizationName        = Trade Show Hell
organizationalUnitName  = IT Department
#       
[ root_ca_extensions ]
basicConstraints        = CA:true
 IMPORTANT: Make sure to adjust the obvious site-specific details in the file, such as the two instances of /home// under [ local_ca ] and [ req ]. Also change commonName, stateOrProvinceName countryName etc under [ root_ca_distinguished_name ] to personalize for your environment. For more information on the directives contained within this configuration file, use the man config command.

When you've edited the file to match your environment, save the file as ~/myCA/caconfig.cnf.

Next, you need to generate the Certificate Authority Root Certificate and Key, by issuing a few commands. First, do this:

export OPENSSL_CONF=~/myCA/caconfig.cnf
The previous command sets an environment variable, OPENSSL_CONF, which forces the openssl tool to look for a configuration file in an alternative location (in this case, ~/myCA/caconfig.cnf).

Now, generate the CA certificate and key with the following command:

openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825
You should be prompted for a passphrase, and see output similar to this:


Generating a 2048 bit RSA private key
.................................+++
.................................................................................................+++
writing new private key to '/home/bshumate/myCA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
Do not forget the passphrase used with the command above! You'll need it every time you want to generate and sign a new server or client certificate!

The above process will create a self-signed certificate using PEM format and RSA public/private key encryption. The certificate will be valid for 1825 days. The location, and purpose of the resultant files is as follows:

~/myCA/cacert.pem : CA public certificate

~/myCA/private/cakey.pem : CA private key

Optional Step
Strip the certificate from all its text to keep only the -CERTIFICATE- section to create a crt

openssl x509 -in cacert.pem -out cacert.crt
Creating a Self-Signed Server Certificate
Now that you have a Certificate Authority configured, you may use it to sign self-signed certificates. Prior to beginning the steps below, you may wish to encrypt the certificate's private key with a passphrase. The advantages of encrypting the key with a passphrase include protection of the certificate in the event it is stolen. 

The certificate cannot be used with SSL-enabled applications without entering the passphrase every time the SSL-enabled application is started. This condition, while being most secure, can present a problem: If the server must be started in an unattended manner as in the case of a computer restart, then no one will be available to enter the passphrase, and subsequently the server will not start. One way to eliminate this condition involves a trade-off in security: The key may be decrypted, to remove the passphrase necessity; thus SSL-enabled applications will start automatically, without a need for you to enter a passphrase.

To actually generate a self-signed certificate for use with an SSL application, follow this process:

Create the server configuration file, by editing ~/myCA/exampleserver.cnf with your favorite text editor. Add this example content:


#
# exampleserver.cnf
#

[ req ]
prompt                  = no
distinguished_name      = server_distinguished_name

[ server_distinguished_name ]
commonName              = tradeshowhell.com
stateOrProvinceName     = NC
countryName             = US
emailAddress            = root@tradeshowhell.com
organizationName        = My Organization Name
organizationalUnitName  = Subunit of My Large Organization
Be sure to change the values under server_distinguished_name especially the commonName value. The commonName value must match the host name, or CNAME for the host you wish to use the key for. If the commonName does not match the intended hostname, then host / certificate mismatch errors will appear in the client applications of clients attempting to access the server.

Once you've edited the file appropriately, save it as ~/myCA/exampleserver.cnf. Generate the server certificate, and key with the following commands:

export OPENSSL_CONF=~/myCA/exampleserver.cnf

The previous command sets an environment variable OPENSSL_CONF which forces the openssl tool to look for a configuration file in an alternative location (in this case, ~/myCA/exampleserver.cnf).

Now generate the certificate, and key:

openssl req -newkey rsa:1024 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM

You should be prompted for a passphrase, and see output similar to this:


Generating a 1024 bit RSA private key
...++++++
...............++++++
writing new private key to 'tempkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
Don't forget the passphrase!

Next, you may translate the temporary private key into an unencrypted key by using the following command:

openssl rsa < tempkey.pem > server_key.pem

You should be prompted for the passphrase used above, and see the following output:


Enter pass phrase:
writing RSA key
If you wish to leave the key encrypted with a passphrase, simply rename the temporary key using the following command, instead of following the step above:

mv tempkey.pem server_key.pem

 Remember: If you use a server key encrypted with a passphrase, the passphrase will have to be entered each time the server application using the encrypted key is started. This means the server application will not start unless someone, or something enters the key.

Now you need to sign the server certificate with the Certificate Authority (CA) key using these commands:

export OPENSSL_CONF=~/myCA/caconfig.cnf

The previous command modifies the environment variable OPENSSL_CONF which forces the openssl tool to look for a configuration file in an alternative location (in this case, ~/myCA/caconfig.cnf to switch back to the CA configuration).

Then sign the certificate as follows:

openssl ca -in tempreq.pem -out server_crt.pem

You will be prompted for the passphrase of the CA key as created in the Certificate Authority setup from above. Enter this passphrase at the prompt, and you will then be prompted to confirm the information in the exampleserver.cnf, and finally asked to confirm signing the certificate. Output should be similar to this:


Using configuration from /home/bshumate/myCA/caconfig.cnf
Enter pass phrase for /home/bshumate/myCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :PRINTABLE:'tradeshowhell.com'
stateOrProvinceName   :PRINTABLE:'NC'
countryName           :PRINTABLE:'US'
emailAddress          :IA5STRING:'root@tradeshowhell.com'
organizationName      :PRINTABLE:'Trade Show Hell'
organizationalUnitName:PRINTABLE:'Black Ops'
Certificate is to be certified until Jan  4 21:50:08 2011 GMT (1825 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Remove the temporary certificate, and key files with the following command:

rm -f tempkey.pem && rm -f tempreq.pem

Congratulations! You now have a self-signed server application certificate, and key pair:

server_crt.pem : Server application certificate file

server_key.pem : Server application key file

END OF COPY/PASTE

The instructions should work for any Unix system with OpenSSL.

The only changes I've made to their configuration were the hostname/path/DN changes and to alter policy about which fields needed to be supplied in the CSRs. This is just to save filling out every field each time I want to change certificates in the lab.


[ local_ca_policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = optional
organizationalUnitName = optional


With your directory structure created as per that article, config file created and appropriate environmental variables set you have a functional CA.

Handy OpenSSL Commands


Generate the CA public and private keys:

openssl req -x509 -newkey rsa:1024 -out cacert.pem -outform PEM -days 1825

Show information on a certificate:

openssl x509 -text -in <CERT>

Show information in a CSR:

openssl req -text -noout -in <CSR>

Verify the signature of a CSR:

openssl req -text -noout -in <CSR> -verify

Sign a CSR:

openssl ca -in <CSR> -out <SIGNED-CERT>


Read more...

Monday 19 October 2009

Checkpoint Traffic Sniffing

There are a couple of handy commands for sniffing traffic on Checkpoint.

Tcpdump and fw monitor.


The following runs a tcpdump capture on IPSO, snagging the entire packet to a file:
tcpdump -s1700 -w output.cap -ni <interface> host <IP-addr>

Without the -s1700 it'll just grab the first part of each packet and not the full contents. If you're running it on a newer platform (e.g. SPLAT) then you can probably use -s0 instead, it's to specify the size of the packets that are recorded.

The problem with tcpdump is that running it on a device designed to filter traffic means you may not be seeing exactly what you expect. So it's probably better to use "fw monitor", the Checkpoint tool that lets you specify exactly where in the stack you are sniffing packets from.

The official guide is here.

Not much more to say about it except to give a simple example for reference:
fw monitor -e 'accept src=<src-ip> or dst=<dst-ip>;'

Just remember to terminate each line with a semi-colon.

Read more...