Requirement 8: Assign a unique ID to each person with computer access
8.1 Assign all users a unique ID before allowing them to access system components or cardholder data.
In our post about Rootsh logging we touched on the PCI DSS Requirement that all users must use a unique user id and never use shared accounts. This is where that requirement is made more explicit.
In the linux world the most common shared account you are likely to come
across as a system administrator is the
root account, and we covered
how we can safely disable this once
sudo is properly configured.
But even if we have unique accounts on every system which is in, or connected to, the cardholder data environment, we still have more work to do.
8.2 In addition to assigning a unique ID, employ at least one of the following methods to authenticate all users:
- Something you know, such as a password or passphrase
- Something you have, such as a token device or smart card
- Something you are, such as a biometric
8.3 Incorporate two-factor authentication for remote access (network-level access originating from outside the network) to the network by employees, administrators, and third parties. (For example, remote authentication and dial-in service (RADIUS) with tokens; terminal access controller access control system (TACACS) with tokens; or other technologies that facilitate two-factor authentication.)
Note: Two-factor authentication requires that two of the three authentication methods (see Requirement 8.2 for descriptions of authentication methods) be used for authentication. Using one factor twice (for example, using two separate passwords) is not considered two-factor authentication.
So before any user can gain access to the cardholder data environment, they must undergo a two factor authentication. There are many commercial solutions for this which involve distribution of tokens or the use of biometrics, but we were looking for an open-source route which did not involve additional hardware.
One Time Passwords
We need 2 out of the 3 methods listed in Requirement 8.2 to have true two-factor authentication.
The first method, “something you know”, is the users’ standard system password (for their unique user id). More on the requirements for this in a later post.
An accepted second method is a one-time password. You’ll note Requirement 8.3 above mentions two separate passwords are not sufficient, so how can we use a one-time passwords for the second authentication method?
This is because one time passwords are in effect “something you have” and not “something you know”. You need to be in possession of a means of password generation whether that be a token, a mobile phone to receive it as an SMS, or even a paper list. People don’t, and generally can’t, memorise a one-time password for each login.
The S/Key system is a means of generating one-time passwords based on a random seed, a secret key, and a sequence number. A user can use an offline calculator to generate these passwords as needed.
S/Key takes an initial secret (which ideally should never be typed into anything except an offline device), and along with a random seed, applies a one-way hash function to this secret n times. Lets say n was 500.
The server then stores the 500th hash result. There is no way of moving backwards through the hash chain to expose the initial secret so this is perfectly safe.
Upon login, the user is required to supply the 499th hash result. The server can easily check if it is given the correct answer by applying the hash function to the 499th hash, to see if it equals the 500th hash result. If it does, the 499th hash result is stored and the user is authenticated.
Next login will require the 498th hash result and so on. And because we cannot move backwards through the hash chain, the user must use an S/Key calculator to produce the desired result by supplying the secret, and applying the hash the required number of times to it.
It may sound complicated, but it is very easy in practice, so lets look at an implementation.
SSH Gateways & Firewall Configuration
Before we move onto installation of a one-time password system, we should mention the network design. Two factor authentication is required for all “remote access”. Unless you have few enough machines in your environment that you’d be happy to install one-time password implementations on all of them, we’d highly recommend designating two or more SSH gateway machines which must be remotely logged into first before any of the rest of your environment can be accessed.
The firewall should be configured to only allow inbound traffic on port 22 to your SSH gateways, and all SSH gateways would have one time passwords enforced in addition to standard system level user passwords. So to remotely access any machine in your environment, you are forced to undergo two factor authentication. Once on a gateway machine, you can SSH internally to other machines in the environment using user passwords only.
OPIE stands for One-Time Password in Everything and is an implementation which is packaged for Debian.
On a designated SSH gateway server, do the following to install:
apt-get install libpam-opie opie-server
Then you need to configure SSH so that it requires authentication from the OPIE PAM module as well as the current method of authentication.
We found we needed the following changes.
/etc/ssh/sshd_config we needed:
ChallengeResponseAuthentication yes ... PasswordAuthentication yes ... UsePAM yes
/etc/pam.d/sshd, after the
@include common-auth line, add:
auth required pam_opie.so
(we preferred to have this line outside of
that when installing or configuring other PAM modules, the OPIE
requirement would be left alone).
This means, once the standard
common-auth authentication has been
pam_opie.so is then called… these are our two factors of
So to activate this (but don’t do it yet!) we would:
Setting up OPIE Users
Of course, if we activated OPIE now, no-one would be able to log in since we first need to initialise the users.
For maximum security, the user should have an offline S/Key calculator ready for use at this point. There are many implementations around for iOS or Android etc. so choose whichever you find easiest to use.
A user would log into the SSH gateway server and run:
opiepasswd never asks for the initial secret. This is important since
if it was sniffed then all the S/Key passwords generated would be
compromised. Only the offline S/Key calculator needs the initial secret.
opiepasswd by default asks for a response from your S/Key calculator
for a the 499th password and supplies the random(ish) salt to use:
[david@debian:~]$ opiepasswd Adding david: You need the response from an OTP generator. New secret pass phrase: otp-md5 499 de6448 Response:
Now on your calculator you supply the challenge
499 de6448, a secret,
md5 as your hash method. You will then be provided with a
response similar to the following to enter:
VALE EMMA DIG LEW OTTO SALT
The server is now initialised for this user. You can see inside
/etc/opiekeys that this password has been recorded (in hex) as the
499th for user
david 0499 de6448 f32f743a123c9bac Sep 27,2012 12:36:38
Once OPIE is activated, on the next login,
libpam-opie will challenge
$ ssh david@ssh_gate1 Password: otp-md5 498 de6448 ext, Response:
And again, the calculator is used to provide the response.
Low Tech OPIE
If the user doesn’t have, or prefers not to use, a mobile device capable to running a S/Key calculator, two-factor authentication can still be achieved.
One way would be to use a separate, local linux machine to generate
a list of passwords.
The user can install
apt-get install opie-server
then generate a list of one-time passwords based on a secret key and
chosen sequence number and salt (increase
-n for more):
[david@debian:~]$ opiekey -n 20 499 lo123 Using the MD5 algorithm to compute response. Reminder: Don't use opiekey from telnet or dial-in sessions. Enter secret pass phrase: 480: AMRA INN VEND BULL YAWN LACE 481: DRUG DOLT CURD BIEN SEC BALM 482: BID HUH MOLE SNAG WOLF MEN 483: NEAT ADDS COED SULK DUNE MOVE 484: LINK SOFA DON TOOK WONT GAL 485: LORD FOND MILK VET PAW EEL 486: MAIL TRAY FLAT NEED KUDO BYTE 487: LOIS FOSS RIDE FAST GUST KANT 488: SOOT TOP TOWN MEND NIB WATT 489: DANK ASIA FORE WORM BLUR LOW 490: HATE WELL ALOE BETH HAP GREG 491: SILK CUP CANE NEON WAVE EM 492: BOY MOO SILT NOR ARTY LAND 493: KARL SOB AMEN HUGH KNOW TACK 494: LOAF SWAN SOD JOE ONES MOW 495: WON NAY BEEN TUBA BARE KEY 496: DOLE SAUL CAFE SNUB DOVE TRUE 497: GIG SLAB DEAR HOLM FIR MALE 498: MUCK SINE COST HEEL BODE DIET 499: SANG BOOK CHUM CAKE MINI GAFF
This old-fashioned user can then print this list off and keep it with them for future reference when needing to log in. Very low tech indeed, but it’s really not all that different to having a token.
Then on the SSH gateway, to set up the user for the first time, we would
opiepasswd as before except we specify the sequence
lo123, which the user used on their local machine – note the
response is the same as number 499 on the list:
[david@debian:~]$ opiepasswd -s lo123 -n 499 Adding david: You need the response from an OTP generator. New secret pass phrase: otp-md5 499 lo123 Response: SANG BOOK CHUM CAKE MINI GAFF ID david OTP key is 499 lo123 SANG BOOK CHUM CAKE MINI GAFF
So the user is set up with the last key from the list and will work their way down it every time they log in.