Certificate Authentication Behind a Bastion Host

I needed Certificate Authentication on a Bastion host. I was pointed to the article from Zeitoun.net (below) by a friend, but it did not work with Apache 2.2.

Apache took my SSL_* variables and passed them along as HTTP_SSL_* variables. This is ok, but not good enough if I don’t want to change source code.

After hacking it a little I found the following seemed to work:

Bastion:

#LoadModule proxy_module   modules/mod_proxy.so
#LoadModule headers_module modules/mod_headers.so
LoadModule ssl_module     modules/mod_ssl.so

Listen 443


AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

SSLPassPhraseDialog  builtin
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300
SSLMutex default
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin

SSLCryptoDevice builtin


<VirtualHost _default_:443>
Servername bastion
# this did not work the way I wanted
# SSLProxyEngineSSLProxyMachineCertificateFile /usr/local/etc/proxyUser.crt

ErrorLog logs/bastion_error_log
TransferLog logs/bastion_access_log
LogLevel warn

SSLEngine on

SSLProtocol all -SSLv2

SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

SSLCACertificatePath /usr/local/etc/auth/

SSLVerifyClient require
SSLVerifyDepth 2

SSLOptions +ExportCertData

   <Proxy *>
     AddDefaultCharset Off
     Order deny,allow
     Allow from all
   </Proxy>
 
   # initialize the special headers to a blank value to avoid http header forgeries
   RequestHeader set SSL_CLIENT_S_DN    ""
   RequestHeader set SSL_CLIENT_I_DN    ""
   RequestHeader set SSL_SERVER_S_DN_OU ""
   RequestHeader set SSL_CLIENT_VERIFY  ""
   RequestHeader set SSL_CLIENT_S_DN_CN ""
 
   <Location />
     # add all the SSL_* you need in the internal web application
     RequestHeader set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"
     RequestHeader set SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s"
     RequestHeader set SSL_SERVER_S_DN_OU "%{SSL_SERVER_S_DN_OU}s"
     RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
     RequestHeader set SSL_CLIENT_S_DN_CN "%{SSL_CLIENT_S_DN_CN}s"
 
     ProxyPass          https://internal/
     ProxyPassReverse   https://internal/
   </Location>

SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog logs/bastion_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>                                  

On the Internal machine
Turn off Client SSL Authentication
# SSLVerifyClient require
and add the following for each SSL variable that you need
SetEnvIfNoCase SSL_CLIENT_S_DN_CN “(.*)” SSL_CLIENT_S_DN_CN=$1

Cool thing is that I can run HTTPS on the backside, just not Client Certificate authentication.

http://www.zeitoun.net/articles/client-certificate-x509-authentication-behind-reverse-proxy/start
http://www.askapache.com/htaccess/setenvif.html
http://httpd.apache.org/docs/2.2/mod/mod_headers.html
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
http://httpd.apache.org/docs/2.2/mod/mod_ssl.html

make an external luks encrypted disk

fdisk /dev/sdb
cryptsetup –verbose –verify-passphrase –cipher aes-cbc-essiv:sha256 luksformat /dev/sdb1
cryptsetup luksOpen /dev/sdb1 name
mke2fs -j -L “Label” -m 1 /dev/mapper/name
mkdir /mnt/name
mount /dev/mapper/name /mnt/name

Unmount
umount /mnt/name
cryptsetup luksClose /dev/sdb1

Now add a keyfile
dd if=/dev/urandom of=/etc/keyfile bs=512 count=4
chmod 400 /etc/keyfile
cryptsetup luksAddKey /dev/sdb1 /etc/key
cryptsetup –key-file /etc/keyfile luksOpen /dev/sdb1 name

Ref:
http://www.hermann-uwe.de/blog/howto-disk-encryption-with-dm-crypt-luks-and-debian
http://wiki.archlinux.org/index.php/System_Encryption_with_LUKS_for_dm-crypt

Quick & Dirty PGP / GPG Verification

Quick & Dirty commands to verify a Download with GPG:

Make 3 Downloads:
File
File.sig
Author.asc

Import Author’s key:
gpg –import Author.asc

Verify File
gpg –verify File.sig
(note: will probably get an unsigned warning because you don’t trust the key) OK – BUt verify key finger print to make sure that it is author’s

Example:
user@host:~/Downloads$ gpg –import TrueCrypt-Foundation-Public-Key.asc
gpg: key F0D6B1E0: public key “TrueCrypt Foundation <contact@truecrypt.org>” imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: no ultimately trusted keys found

user@host:~/Downloads$ gpg –verify truecrypt-6.3a-linux-x86.tar.gz.sig
gpg: Signature made Fri 02 Apr 2010 04:40:07 PM EDT using DSA key ID F0D6B1E0
gpg: Good signature from “TrueCrypt Foundation <contact@truecrypt.org>”
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: C5F4 BAC4 A7B2 2DB8 B8F8  5538 E3BA 73CA F0D6 B1E0

From:
How to Verify Digital Signatures