Daniel Watrous on Software Engineering

A Collection of Software Problems and Solutions

Posts tagged ssl

Software Engineering

Encryption of secrets in source code (AESCrypt + Ansible)

The more I automate, the more I have to answer the question of how to manage my secrets. Secrets that frequently come up include:

  • SSH key pairs
  • SSL private keys
  • Credentials for external resources, such as databases and SaaS integrations

Before cloud, when server resources were not ephemeral, these could be managed manually when the server was created. In cloud environments, servers are created and destroyed automatically and from minute to minute, which leaves the question about how to manage secrets.

The OpenStack community is working on one solution called Barbican. I’ve been looking at more local solutions to secret management that accommodates storage in a code repository alongside the application code that will be deployed. Some benefits to a local solution include:

  • No additional systems to maintain
  • Secrets can be versioned
  • Infrastructure as code

Most of my automation efforts recently are centered on Ansible. One Ansible specific solution is Vault. The drawback to building secrets in to Ansible Vault is lock in to Ansible. In the future I may want to leverage other orchestration tools, such as puppet, chef or salt.

openssl

One option that works well for *nix only workloads is openssl. OpenSSL is widely used and available by default on virtually every Linux system.

Using openssl is straight forward:

openssl enc -aes-256-cbc -salt -in server.key -out server.key.aes -pass pass:secret
openssl enc -d -aes-256-cbc -in server.key.aes -out server.key -pass pass:secret

AESCrypt

I ended up choosing AESCrypt as my solution. Some key reasons for this choice include native binaries for Windows, Linux and Mac. AES encryption is very strong. The decryption key can be provided to ansible as a variable or handled manually on resulting servers.

Using AESCrypt is very simple. Below is a simple session on Windows.

C:\Users\Daniel Watrous\Documents\work\aescrypt>ls -la
total 204
drw-rw-rw-   2 Daniel Watrous 2 0      0 2015-06-30 16:06 .
drw-rw-rw-  73 Daniel Watrous 2 0  49152 2015-06-30 16:04 ..
-rwxrwxrwx   1 Daniel Watrous 2 0 155136 2015-06-30 16:05 aescrypt.exe
-rw-rw-rw-   1 Daniel Watrous 2 0    896 2015-06-30 16:06 mykey.txt
 
C:\Users\Daniel Watrous\Documents\work\aescrypt>cat mykey.txt
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----
C:\Users\Daniel Watrous\Documents\work\aescrypt>aescrypt -e -p secret mykey.txt
 
C:\Users\Daniel Watrous\Documents\work\aescrypt>ls -la
total 208
drw-rw-rw-   2 Daniel Watrous 2 0      0 2015-06-30 16:07 .
drw-rw-rw-  73 Daniel Watrous 2 0  49152 2015-06-30 16:04 ..
-rwxrwxrwx   1 Daniel Watrous 2 0 155136 2015-06-30 16:05 aescrypt.exe
-rw-rw-rw-   1 Daniel Watrous 2 0    896 2015-06-30 16:06 mykey.txt
-rw-rw-rw-   1 Daniel Watrous 2 0   1188 2015-06-30 16:07 mykey.txt.aes
 
C:\Users\Daniel Watrous\Documents\work\aescrypt>cat mykey.txt.aes
AES☻  ↑CREATED_BY aescrypt 3.10 ?
                                           <%8±d>áFo♥p♠xÿ~
C:\Users\Daniel Watrous\Documents\work\aescrypt>rm mykey.txt
 
C:\Users\Daniel Watrous\Documents\work\aescrypt>aescrypt.exe -d -p secret mykey.txt.aes
 
C:\Users\Daniel Watrous\Documents\work\aescrypt>cat mykey.txt
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----

Automation

It should be obvious from the above example that at some point the decryption still requires a password and that password should NOT be stored in the code repository. The decrypted files should also be ignored (not added to revision control). In other words, only commit the encrypted files.

The encryption password needs to be stored somewhere. One option is to keep it in your head. Another might be to keep it in lastpass or some other password manager, but be sure to keep it out of the repository where you have the encrypted secrets.

The password can be provided when calling the Ansible playbook.

Software Engineering

Install SSL Enabled MongoDB Subscriber Build

10gen offers a subscriber build of MongoDB which includes support for SSL communication between nodes in a replicaset and between client and mongod. If the cost of a service subscription is prohibitive, it is possible to build it with SSL enabled.

After download, I followed the process below to get it running. For a permanent solution, more attention should be given to where these are installed and how upgrades are handled.

$ tar xzvf mongodb-linux-x86_64-subscription-rhel62-2.2.3.tgz
$ cp mongodb-linux-x86_64-subscription-rhel62-2.2.3/bin/* /usr/local/bin/

Next, it’s necessary to provide an SSL certificate. For testing, it’s easy to create an SSL certificate.

$ cd /etc/ssl
$ openssl req -new -x509 -days 365 -nodes -out mongodb-cert.pem -keyout mongodb-cert.key -passout pass:mypass
Generating a 2048 bit RSA private key
........................+++
.....................................+++
writing new private key to 'mongodb-cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Idaho
Locality Name (eg, city) [Default City]:Boise
Organization Name (eg, company) [Default Company Ltd]:ACME
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:host0123
Email Address []:myemail@mail.com

With the certificate created, make a combined pem file as follows

$ cat mongodb-cert.key mongodb-cert.pem > mongodb.pem
$ ll
total 12
lrwxrwxrwx 1 root root   16 May 10  2012 certs -> ../pki/tls/certs
-rw-r--r-- 1 root sys  1704 Feb 14 19:21 mongodb-cert.key
-rw-r--r-- 1 root sys  1395 Feb 14 19:21 mongodb-cert.pem
-rw-r--r-- 1 root sys  3099 Feb 14 19:21 mongodb.pem

Finally, you can start mongodb as follows

$ mongod -dbpath /opt/webhost/local/mongod -logpath /var/log/mongo/mongod.log -keyFile /home/mongod/mongokey --sslOnNormalPorts --sslPEMKeyFile /etc/ssl/mongodb.pem --sslPEMKeyPassword mypass --replSet wildcatset --rest --logappend &

Accessing over SSL

SSL certificate management can be complicated. It is possible to bypass certificate validation when using a self issued certificate. Python does this by default. Java may require additional work to bypass certificate validation.