Authentication and encryption

I want to make my environment cryptographically sound. No plaintext muck except maybe boot images and installation media. So NFS V4 encrypted, encrypted Samba shares, HTTPS servers with signed certificates and so on. So. I will have to install and use OpenSSL. Also, FreeIPA will have an important role to play as it provides authentication services for every machine in the net.

If I do it right, I can even have some Outside Authority sign the Nerdhole web certificates and enjoy encrypted and authenticated access to the Nerdhole from the Great Outdoors. Maybe then Work will allow me to access my home server.

The subjects for now are:

  • Ansible vaults
  • Kerberos
  • SSL/TLS
  • FreeIPA support
  • Encrypted NFS drives
  • Web server certificates

Storing passwords in Ansible Vault

I have sort of faked Ansible Vault variables up to now, but it is now time to do this properly. I need to store my credentials, secret keys, and other sensitive information somewhere secure. Time to set up a Vault. For now, I will have a single vault for all the things that I want to keep out of sight. Maybe I will support multiple vaults in the future.

Vault passwords are a little shaky when you actually start to use them. You can put the password in a textfile (in plaintext) and point ansible-playbook at that whenever you need to decrypt a vault. You can also type in the vault password every time you run ansible-playbook. Every user of the vault shares the same password. Not ideal, but for now it's all we have.

Ansible offers four ways of supplying passwords:

  1. Ask for it by a command line option --ask-vault-pass as if we don't have password prompts enough already.
  2. Read it from a password file, where it is stored in plaintext using --vault-password-file.
  3. Execute a little script to put the password on stdout. Also --vault-password-file but set to executable.
  4. Use a vault-id so you can supply different vault passwords for different files. This uses the --vault-id parameter, and can be done multiple times.

Information:

I think I'll standardise on encrypted files with vault IDs. So I'll need to document the things or I'll lose track of them. An encrypted file with a vault ID looks like this:

$ cat group_vars/main/passwords.yml 
$ANSIBLE_VAULT;1.2;AES256;nschool
38353837333366343632656365353731303132376237646236383337643937636363396266326664
3563663238393562383834376433323066353638386636630a633535623238623737323231656438
...

This means it is an Ansible Vault file with encryption standard 1.2, using the AES256 cypher, and that its vault ID is "nschool". When an Ansible run encounters this file, it will look for the ansible vault password with the nschool ID. And of course if it doesn't exist, it crashes.

I have to say I don't like this mechanism much. It forces you to share passwords. I much prefer to have users prove who they are first and only then give them access to specific parts of the environment. But that can't be helped. You also need to specify the vault password if you have even one encrypted file in your entire environment even if you don't use it.

Kerberos

Kerberos is still an utter ###### to install. I think FreeIPA can do it for you.

SSL/TLS certificates

Everything cryptographic hangs together with certificates. We are using a self signed certificate for our authentication purposes.

Web resources:

Input data

The needed information is stored in the Ansible variables within the nschool role. The non-sensitive variables are stored in the role's main/public.yml, and the sensitive information is stored in the role's main/private.yml, and encrypted using the nschool vault ID password. The variables are:

  • Information for the CA certificates and keys
    • nschool.environment.name - Name of this environment
    • nschool.environment.locality - Location where the network is
    • nschool.environment.state - Superfluous "State" or county info
    • nschool.environment.organizationalunit - Nerdhole department
    • nschool.environment.commonname - Name of someone in the organization
    • nschool.environment.emailaddress - Email contact for this organization
    • nschool.aliases.'hostname' - Aliases for the main server
  • Information for other generated files
    • nschool.environment.main_domain - Main domain name
    • nschool.environment.main_server_fqdn - Full name of the main server
    • nschool.environment.main_server_ip - IP address of the main server
    • nschool.environment.main_server_os - Operating system of the main server
    • nschool.environment.nschool_home - Directory where nschool files are stored.
  • Vault variables
    • nschool_vault.secrets.ca_privkey_passphrase - Passphrase put on the CA private key

Certificate authority files

We divide up the files between files that need to stay secret and files that need to be published. These are the files used:

  • /local/ca/ - The home directory of all Certificate Authority files.
  • private - Files containing secrets and private keys
    • passphrase.tmp - A temporary file that contains the passphrase
    • nerdhole.me.uk.key - The root key for the nerdhole.me.uk domain
    • sypha.nerdhole.me.uk.key - The private key for the webserver on Sypha
  • public - Files that need to be published or copied out
    • nerdhole.me.uk.crt - The self-signed root certificate for nerdhole.me.uk
    • sypha.nerdhole.me.uk.csr - A key signing request for the webserver on Sypha
    • main_webserver.v3.ext - A file to create the web server certificate
    • sypha.nerdhole.me.uk.crt - The web server's certificate

Procedures and automation

Globally speaking, the tasks carried out in the environment bootstrap playbook are:

  1. Set up the /local/ca/ directory structure
  2. Create the passphrase.tmp file to avoid putting the passphrase in the process table
  3. Generate the OpenSSL Certificate Authority private key using openssl genrsa.
  4. Sign the key using itself as the signature. (Normally you get an Internet authority to do this for you).
  5. Copy the key file to /etc/pki/ca-trust/source/anchors so the server will trust its own certificates.
  6. Create a key and a signing request for the main webserver
  7. Generate an extension file main_webserver.v3.ext to make a web server certificate
  8. Sign the main web server certificate using the v3.ext file.
  9. Copy the key and the certificate into /etc/pki/tls/private/
  10. Configure Apache to use the key and certificate for its SSL module.

Free Identity Policy Audit (FreeIPA)

From the webpage:

"FreeIPA is an integrated security information management solution combining Linux (Fedora), 389 Directory Server, MIT Kerberos, NTP, DNS, Dogtag (Certificate System). It consists of a web interface and command-line administration tools. FreeIPA is an integrated Identity and Authentication solution for Linux/UNIX networked environments. A FreeIPA server provides centralized authentication, authorization and account information by storing data about user, groups, hosts and other objects necessary to manage the security aspects of a network of computers."

Web resources:

Installation

FreeIPA 4.12 lives in the Appstream repository, so we will need to install that first on any Main server. The packages are:

  • ipa-client
  • ipa-server
  • ipa-server-dns

Since I already have a very nice DNS setup, I won't use FreeIPA for that. The installer ipa-server-install needs the following information:

Information Flag Values/Comments
Unattended install --unattended Exactly what we want
FQDN of the server --hostname sypha.nerdhole.me.uk
IP address of the server --ip-address 10.12.0.2
Domain name --domain nerdhole.me.uk
Kerberos realm --realm NERDHOLE.ME.UK
Directory manager password --ds-password Get it from nschool_vault
IPA admin password --admin-password Get it from nschool_vault
Do not configure NTP --no-ntp We already have NTP set up

The command to set up the IPA server is:

/usr/sbin/ipa-server-install \
--unattended \
--hostname sypha.nerdhole.me.uk \
--ip-address 10.12.0.2 \
--domain nerdhole.me.uk \
--realm NERDHOLE.ME.UK \
--ds-password "******" \
--admin-password "******" \
--no-ntp

This actually works right out of the box! I added myself as a user, did not get a home directory, but could log in. However, I then tried to access the web interface and ran into trouble. IPA sets itself up as a Certificate Authority, and I have just done that myself already so Firefox doesn't believe Sypha's IPA is genuine. And rightly so.

So after all the trouble I took to generate my own self-signed certificate, I'll have to undo that and let IPA take care of this. Maybe for the better.

After the installation, I need to make one modification to /etc/httpd/conf.d/ipa-rewrite.conf: By default it assumes it owns the web server, and there is one line that you have to remove to disabuse it of that notion. One stanza in the playbooks.