Skip to content

Latest commit

 

History

History
474 lines (339 loc) · 16.3 KB

INSTALL.rst

File metadata and controls

474 lines (339 loc) · 16.3 KB

INSTALLING

Note

These installation instructions assume you're installing on RHEL-6.

Start by installing the library files themselves. You can do that by installing the package provided by your distribution, or, if such package is not available, you can run:

python setup.py build
python setup.py install

Next, create the secrets and state directories:

mkdir -p -m 0750 /etc/totpcgi/totp
mkdir -p -m 0700 /var/lib/totpcgi

Next, create the user that the CGI will be running as:

useradd -M -s/sbin/nologin -d/var/lib/totpcgi totpcgi

Set the ownership on directories:

chgrp -R totpcgi /etc/totpcgi
chown -R totpcgi /var/lib/totpcgi

SSL Mutual Authentication

To ensure that only trusted clients are allowed to talk to the server, you should configure mutual SSL authentication. For that, you'd need to generate a CA certificate, a server certificate, and a certificate for each of your clients.

Steps to do that can be found in many places on the web, so google for something like "sslverifyclient openssl genrsa" -- you should have a couple of decent hits.

Copy the certificates and keys as follows:

/etc/pki/tls/certs/totp-server.crt
/etc/pki/tls/certs/totpcgi-ca.crt
/etc/pki/tls/private/totp-server.key
/etc/pki/tls/private/totpcgi-ca.key

Make sure the .key files are owned and readable by root only.

Hint

If you use puppet or func, you can reuse certificates generated by them. For puppet, the files are:

  • /var/lib/puppet/ssl/ca/ca.pem
  • /var/lib/puppet/ssl/private_keys/[your-server-hostname].pem
  • /var/lib/puppet/ssl/certs/[your-server-hostname].pem

You can just use them directly in the httpd config file.

Hint

If you already have puppet-managed infrastructure, check out the puppet module and the quickstart doc in contrib/puppet!

Next, you'll need to install one of the CGIs.

Install Regular CGI

Copy totp.cgi into /var/www/totpcgi/index.cgi and set the permissions:

mkdir -p -m 0551 /var/www/totpcgi
cp -a cgi/totp.cgi /var/www/totpcgi/index.cgi
chown -R totpcgi:totpcgi /var/www/totpcgi
chmod 0550 /var/www/totpcgi/index.cgi

Create the config file in /etc/httpd/conf.d/totpcgi.conf using the vhost-totpcgi.conf template provided in contrib directory, and modify it accordingly to use FCGI instead of CGI.

Note

The default configuration runs on port 8443, as this makes it easier to deploy provisioning.cgi on the same host. It is up to you whether you want to use this configuration or not.

Install FastCGI

Nearly identical to what is above. The benefit of FastCGI is that it is quite a bit faster than CGI (as the name implies), without the extra overhead of starting another CGI process on each HTTP request hit. Though it is unlikely that your totpcgi server will see much traffic to really matter, if you are interested in avoiding performance problems, use FastCGI.

Start by installing mod_fcgid and flup:

yum install mod_fcgid python-flup

Next, copy the .fcgi in place, following the same procedure as .cgi:

mkdir -p -m 0551 /var/www/totpcgi
cp -a cgi/totp.fcgi /var/www/totpcgi/index.fcgi
chown -R totpcgi:totpcgi /var/www/totpcgi
chmod 0550 /var/www/totpcgi/index.fcgi

Create the config file in /etc/httpd/conf.d/totpcgi.conf using the vhost-totpcgi.conf template provided in contrib directory, and modify it accordingly to use FCGI instead of CGI.

Note

Major thing to remember with .fcgi is that you will need to restart the server any time you make changes to the .fcgi file.

Install SELinux policy

Yes, you really should. SELinux policy files come bundled in the tarball. Copy them over to the server and run:

sh totpcgi.sh

Warning

If you have modified any of the paths used above, you'll also need to modify the totpcgi.fc file and the totpcgi.sh file.

Provision some secrets

Totpcgi uses the same file format for TOTP secrets as files generated by google-authenticator, so if you already have some secrets generated with google-authenticator, just copy them into place:

cp ~/.google-authenticator /etc/totpcgi/totp/[username].totp
chgrp totpcgi /etc/totpcgi/totp/[username].totp
chmod 0440 /etc/totpcgi/totp/[username].totp

Alternatively, use the totpprov utility from the contrib/ directory. To install and use it, do the following:

cp conf/provisioning.conf /etc/totpcgi/

Edit the provisioning.conf file and change the "totp_user_mask" value to reflect your environment. After that, you should be able to run the following command to provision a user:

[root@totphost totpcgi]# totpprov generate-user-token wakka
Generating new token for user wakka
Are you sure [y/N]: y
New token generated for user wakka
otpauth://totp/[email protected]?secret=EBJVHOQTYVYIVMUG
Scratch tokens:
23374296
25160754
86583002
93195170
32611388

You can pass this information to clients. To generate a QR code, you can install "qrencode" and run the following command with the otpauth:// URL returned by the totpprov command:

qrencode -s 5 -o totp-qrcode.png otpauth://totp/[...]

The "totpprov" utility doesn't set the token file ownership automatically, so the last thing you will need to do is set the ownership on the .totp file correctly:

chown root:totpcgi /etc/totpcgi/totp/wakka.totp
chmod 0640 /etc/totpcgi/totp/wakka.totp

See "man totpprov" for more information on this utility, and don't forget to check out Provisioning CGI chapter.

Set up the clients

First, create a SSL key and certificate for the client, and sign it with your CA key.

cp [your-client].crt /etc/pki/tls/certs/totpcgi.crt cp [your-ca].crt /etc/pki/tls/certs/totpcgi-ca.crt cp [your-client].pem /etc/pki/tls/private/totpcgi.pem

chown root:root /etc/pki/tls/private/totpcgi.pem chmod 0400 /etc/pki/tls/private/totpcgi.pem

Hint

If you are using puppet's SSL keys, you can just use them directly. They are in the following locations:

  • /var/lib/puppet/ssl/certs/ca.pem
  • /var/lib/puppet/ssl/certs/[your-client-hostname].pem
  • /var/lib/puppet/ssl/private_keys/[your-client-hostname].pem

You are now ready to test to see if all is working right! Run the following command, replacing [username] and [token] with valid entries:

curl --cacert /etc/pki/tls/certs/totpcgi-ca.crt \
     --cert /etc/pki/tls/certs/totpcgi.crt \
     --data 'user=[username];token=[token];mode=PAM_SM_AUTH' \
     https://totp.example.com:8443/

If all worked well, you should see:

OK

Warning

You shouldn't proceed to the next step unless the above test succeeds for you. You will lock yourself out of the system.

Configure pam_url on the clients

Install pam_url and create a configuration file in /etc/pam_url.conf as provided in the contrib directory.

Now you need to add it to your pam configuration. Let's change it so users can sudo with their Google-Authenticator token. Edit /etc/pam.d/sudo and add this line above all other auth lines:

auth sufficient pam_url.so config=/etc/pam_url.conf

Alternatively, see other pam examples in the contrib directory.

Using pincodes

If you've ever used RSA tokens, you'll know that they support user pins in addition to numeric tokens. This functionality is duplicated in totpcgi. To enable it, you'll need to tweak a number of things.

First, create /etc/totpcgi/pincodes. The file format is the same as /etc/shadow, except we only pay attention to the first 2 parts (username:password-hash). Totpcgi supports sha-512 and sha-256 password hashes, so some tools exist that can help you manage that file just like an /etc/shadow file.

Alternatively, you can maintain the file on your own using bcrypt hashes. To generate a bcrypt hash, install py-bcrypt and run:

python -c "import bcrypt; print bcrypt.hashpw('pincode', bcrypt.gensalt())"

Warning

Any time you specify passwords on command line like that, they will be viewable in "ps" and stored in your .bash_history.

Warning

You should NOT use the same pin as the user system password, at least as long as you're using the file-based backend.

Make sure you set the right permissions on the pincodes file:

chown root:totpcgi /etc/totpcgi/pincodes
chmod 0640 /etc/totpcgi/pincodes

You should now be able to log in using pincode+tokencode. E.g. if you set your pincode to 'secret' and your token is 555555, you enter 'secret555555'. You should be able to use that the moment the pincodes file is in place.

You will now need to adjust /etc/totpcgi/totpcgi.conf to require that pincodes are used:

[main]
require_pincode = True

The following PAM settings for sudo will require your users authenticate with their Pincode+Token:

#%PAM-1.0
auth       required     pam_env.so
auth       sufficient   pam_url.so config=/etc/pam_url.conf
auth       requisite    pam_succeed_if.so uid >= 500 quiet
auth       required     pam_deny.so

account        include      system-auth
password   include      system-auth
session    optional     pam_keyinit.so revoke
session    required     pam_limits.so

You can additionally adjust the sshd pam configuration to do the same -- look in the contrib directory for it. Keep in mind, that when public key authentication is used, it completely bypasses pam.

Using encrypted secrets

Once you require the use of pincodes, you may consider using them to encrypt the master secrets used to generate TOTP codes. This gives you extra protection in case something happens and someone is able to read the contents of your TOTP secrets (for example, by getting access to your backups). Without knowing the users' pincodes, it would be impossible to decrypt the secrets.

It's important to realize that this comes with a trade-off -- if a client forgets their pincode, the TOTP token will need to be re-provisioned.

Encryption needs to be done during the provisioning stage. If the administrator provisions the tokens manually, they can use the "totpprov" utility in the contrib directory to encrypt existing secrets. If some other process is used, you should rely on the implementation in that file to generate encrypted secrets that totpcgi can handle.

Warning

One-time scratch tokens are completely ignored by totpcgi when encrypted secrets are used, as doing otherwise would defeat the point of encrypting the master secret.

PostgreSQL backend

If you want to use a load-balanced configuration, you will need to save the state files in a central database.

Warning

DO NOT use the File state backend in a multiple-server setup. This will make you vulnerable to token reuse, as one server will not know that the token was already presented to the other server.

Running databases is a complex task, but this is a quick guide. First, install postgresql-server:

yum install postgresql-server

Now init the database and start the server:

service postgresql initdb
service postgresql start

Now create the database and tables using the provided file. First, though, edit totpcgi.psql and adjust the password to a non-default value.

To create and populate the database, run:

su -l postgres
createdb totpcgi
psql totpcgi < totpcgi.psql

Now you need to edit /var/lib/pgsql/data/pg_hba.conf and add the following line before all the "all" lines:

host   totpcgi   totpcgi   your.subnet/24   md5

Restart the server:

service postgresql restart

Now, install python-psycopg2 on your totpcgi servers:

yum install python-psycopg2

Now modify /etc/totpcgi/totpcgi.conf and enable the postgresql state backend:

[state_backend]
engine = pgsql
pg_connect_string = user=totpcgi password=wakkawakka host=localhost dbname=totpcgi

Restart the http server if you're using FastCGI. Make sure your iptables rules on the server allow incoming postgresql traffic.

Note

You can also use postgresql for your secrets and pincodes backend. If you use "totpprov" or provisioning.cgi, it will read the configuration from /etc/totpcgi/provisioning.conf and know where to put the provisioned information.

LDAP backend

You can use a LDAP directory for your pincode backend -- the CGI will validate pincodes by trying to bind to the LDAP server using the provided credentials. To enable the LDAP pincode backend, modify /etc/totpcgi/totpcgi.conf and set the following:

[pincode_backend]
engine = ldap
ldap_url = ldaps://ldap.example.com:636/
ldap_cacert = /etc/pki/tls/certs/ca.crt
ldap_dn = uid=$username,cn=users,cn=accounts,dc=example,dc=com

The ldap_dn listed above is for use with FreeIPA -- you will need to modify it to reflect the valid DN for your users. The "$username" entry will be replaced by whatever the authenticating clients provide as their username (or, when using sudo, the username will be their current system usersname).

Configuring LDAP is way beyond this document, so I leave this task up to you. If you've never done it before but would like to try, I suggest you look at FreeIPA (in RHEL6.2 and above as "ipa-server").

Provisioning CGI

Starting with version 0.5, we include full support for provisioning tokens. You can use the provisioning.cgi that ships with the project for user-initiated provisioning, or you can use it as an example implementation in order to incorporate provisioning support into your existing web infrastructure.

Note

Provisioning CGI requires that pincodes are used, otherwise there is no way to authenticate the user that logs in to obtain the token. Alternatively, use trust_http_auth option and authenticate users on the apache level.

Start by installing the CGI and configuration files:

mkdir -p -m 0551 /var/www/totpcgi-provisioning
cp -a cgi/provisioning.cgi /var/www/totpcgi-provisioning/index.cgi
cp -a cgi/*.css /var/www/totpcgi-provisioning/
chmod 0550 /var/www/totpcgi/index.cgi

To only allow the provisioning.cgi to modify .totp files, we will need to set up provisioning.cgi to run as a separate user from totp.cgi. Let's start by creating that user:

useradd -M -s/sbin/nologin -d/var/lib/totpcgi totpcgiprov

Now we'll need to adjust the ownership on directories:

chown totpcgiprov:totpcgi /etc/totpcgi
chown totpcgiprov:totpcgi /var/lib/totpcgi
chmod 0770 /var/lib/totpcgi
chmod 0666 /var/lib/totpcgi/*.json
chown -R totpcgiprov:totpcgi /etc/totpcgi/totp
chown -R totpcgiprov:totpcgiprov /var/www/totpcgi-provisioning

Now copy conf/templates into /etc/totpcgi/templates. You want to edit the .html files in the templates directory to your liking, unless you work for Example Company, LTD. Review the settings in /etc/totpcgi/provisioning.conf as well, to make sure the defaults are sane.

Configuring Apache is going to be less straightforward. To run these two CGIs as two different users, we'll need to create two separate VirtualHost entries, but this becomes tricky with SSL:

  1. These two VirtualHosts must have different hostnames and run on separate IPs, in which case:

    1. You must use a wildcard certificate that is correct for both hostnames
    2. You must use a certificate with a host alias that is correct for both hostnames
  2. These two VirtualHosts can run on the same IP, but listen on different ports

The default configuration uses the 2nd scenario -- we run totp.cgi on port 8443, since it's not a user-visible address, and the provisioning cgi on the standard https port 443. It is entirely up to you how you make it work in your environment.

To use the default scenario, copy the vhost-totpcgi-provisioning.conf from the contrib directory into /etc/httpd/conf.d/totpcgi-provisioning.conf and edit accordingly to use the right hostname and SSL certificates.

Restart httpd, and see if everything is working right.

Using with web services

The only way to use totpcgi with web services is via mod_auth_pam or mod_authnz_auth -- either directly on the Apache host, or via a SSO solution, such as CAS, Webauth or Pubcookie.

If someone feels like contributing a native module for any of these services, that initiative will be welcomed. :)