Med hjälp av en PAM-modul går det att aktivera tvåfaktorsautentisering i Linux med exempelvis Google Authenticator-appen. Linuxsystemet kräver då både användarens lösenord samt ett engångslösenord. Det går även att kombinera en SSH-nyckel med ett engångslösenord.

CAD Bild: Gerd Altmann

Att kräva tvåfaktorsautentisering vid lösenordsinloggning över SSH höjer säkerheten ett snäpp. Angriparen måste då ha tillgång till både användarens lösenord och dennes enhet som genererar engångslösenorden.

I denna artikel kommer vi endast att aktivera tvåfaktorsautentisering när inloggningen sker över SSH. Om man vill går det däremot att aktivera vid all form av inloggning i Linux, från konsolinloggningen till upplåsningen av skärmsläckaren.

Stegen i denna artikeln är endast testade på Ubuntu 22.04.

Börja med att installera PAM-modulen för Google Authenticator:

$> sudo apt install -y libpam-google-authenticator

Trots namnet går modulen att använda även med andra 2FA-appar, exempelvis Authy eller 1Password.

När modulen är installerad behöver vi lägga in den i PAM-kedjan för SSH. Öppna /etc/pam.d/sshd. På den femte raden, raden under @include common-auth lägger vi in följande rad:

auth    required        pam_google_authenticator.so nullok

De översta raderna i min /etc/pam.d/sshd ser därför ut som följande:

ANNONS FÖR VÅRA EGNA BÖCKER Demonerna på internet

# PAM configuration for the Secure Shell service

# Standard Un*x authentication.
@include common-auth
auth    required        pam_google_authenticator.so nullok

# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so

Argumentet nullok till PAM-modulen Google Authenticator betyder att det är okej att släppa in användare som inte har aktiverat sin tvåfaktorsautentisering ännu.

Nu kan vi aktivera tvåfaktorsautentisering för den egna användaren. Detta kommer att köra en guide där vi kopierar en kod från terminalen till vår 2FA-app, alternativt skannar QR-koden som visas. Vi måste också svara på några frågor om hur vi vill att 2FA-inloggningen ska fungera:

$> google-authenticator

Do you want authentication tokens to be time-based (y/n) y
Warning: pasting the following URL into your browser exposes the OTP secret to Google:
[...]

Your new secret key is: YZGAATGZ5KWB7CC4HYG7R6BO4B
Enter code from app (-1 to skip): 1398439
Code confirmed
Your emergency scratch codes are:
  41501547
  58060132
  24377953
  41912180
  67580287

Do you want me to update your "/home/jake/.google_authenticator" file? (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
[...]
Do you want to do so? (y/n) n

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

Därefter behöver vi aktivera något som heter Keyboard interactive i SSH-demonens konfiguration. Gör vi inte detta kommer ingen användare att kunna logga in!

I filen /etc/ssh/sshd_config ändrar vi KbdInteractiveAuthentication från no till yes. Raden ska alltså se ut så här:

KbdInteractiveAuthentication yes

Därefter laddar vi om SSH-demonen så att den nya inställningen får effekt:

$> sudo systemctl reload ssh

Nu kan vi testa att logga ut och logga in igen (över SSH). Om du bara loggar in med lösenord i vanliga fall kommer du nu bli tillfrågad efter både lösenord och ett engångslösenord (benämnns Verification Code av modulen).

$> exit
localhost$> ssh jake@192.168.0.43
Password: 
Verification code:
$> 

Om du däremot loggar in med en SSH-nyckel kommer du loggas in direkt, utan att bli tillfrågad efter 2FA-koden.

Demonstration