The same Notakey auth-proxy that already protects your
VPN and your
MikroTik admin login can protect Linux
logins too. Linux’s PAM stack ships a standard RADIUS module: point it at
the proxy, and SSH, sudo and su all require a phone approval on top of
the password.
sshd / sudo ──PAM──▶ pam_radius ──RADIUS──▶ Notakey auth-proxy ──▶ your RADIUS server
│
└──▶ push ──▶ user's phone
This guide is for Debian/Ubuntu (libpam-radius-auth); on RHEL-family
distros the module is packaged as pam_radius (EPEL) and the PAM files live
under the same /etc/pam.d/ layout.
Requirements
- A working auth-proxy in front of a RADIUS server, set up exactly as in steps 1–3 of the VPN guide.
- The same username in the downstream RADIUS server, in the Notakey service (with an onboarded phone), and as an account on the Linux box. PAM only authenticates; the user still needs a local (or directory) account to log into.
- The Linux box able to reach the proxy on UDP 1812. The password travels as PAP between them, so keep this on a management network, or run the dockerized proxy on the host itself.
Step 0 — Set up your emergency exit first
Before touching PAM, make sure a purely local login works: give root (or a dedicated break-glass admin) a strong local password and verify it at the console. The configuration below always falls back to local passwords, so this account is your way in if the proxy, the RADIUS server or the network is ever down. Do this first, not after something breaks.
Step 1 — Install the module
sudo apt-get install libpam-radius-auth
Step 2 — Point it at the proxy
Edit /etc/pam_radius_auth.conf and add one line: the proxy’s address,
the shared secret (pairs with the proxy’s vpn_secret_in), and the
timeout in seconds:
# server[:port] shared_secret timeout (s)
10.0.1.20 secret_to_radius_server 60
Then lock the file down, since it contains the secret:
sudo chmod 0600 /etc/pam_radius_auth.conf
The timeout is the same trap as everywhere else in this series. The
module’s default is 3 seconds: fine for a password check, hopeless for a
human approval. Set it to at least the proxy’s vpn_message_ttl (30 s);
60 gives comfortable slack.
Step 3 — Enable it in PAM
For each entry point you want protected, add one line just above the
@include common-auth line. For SSH:
sudo nano /etc/pam.d/sshd
auth sufficient pam_radius_auth.so
@include common-auth
sufficient means: if RADIUS answers Access-Accept (password verified
downstream and push approved), the login succeeds immediately. If not,
PAM falls through to the normal local password check below it.
Add the same line to any of these, as desired:
/etc/pam.d/loginfor console logins/etc/pam.d/sudo— everysudoasks the phone (strong, but chatty; sudo’s credential caching keeps it tolerable)/etc/pam.d/sufor switching users
Finally, edit /etc/pam.d/common-auth and add try_first_pass to the
existing pam_unix.so line:
auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
(The other options on that line vary by release; only try_first_pass is
the addition.) Without it, a user falling back to local authentication gets
prompted for the password a second time; with it, the password already
typed is reused silently.
Step 4 — Check sshd is actually using PAM
In /etc/ssh/sshd_config, PAM-based authentication needs:
UsePAM yes
KbdInteractiveAuthentication yes
(both are the Debian/Ubuntu defaults). One thing to know: SSH public-key
logins skip PAM’s auth phase entirely: a key-based login will not
trigger a push. If you want key plus push, set
AuthenticationMethods publickey,keyboard-interactive, but test that
variant separately before rolling it out.
Step 5 — Create push-only users
Here is the trick that makes the setup clean: create users without a local password.
sudo useradd -m -G sudo john
No passwd afterwards: the account’s local password stays locked. That
user now has exactly one way in: RADIUS through the proxy, meaning password
and phone approval. There is nothing local to brute-force. Your
break-glass admin from step 0 remains the only account with a purely local
password.
Test it, carefully
Keep your working session open and SSH in from a second terminal with a RADIUS username:
- The password prompt behaves as usual; after you enter it, the session waits: that’s the proxy holding the exchange open.
- The push lands on the phone. Approve → shell. Deny or ignore → the login fails after the timeout.
- Confirm the break-glass account still gets in with its local password.
Only close your original session after both checks pass.
Troubleshooting
- Login fails instantly, no push. The timeout in
/etc/pam_radius_auth.confis still at its 3-second default, or the secret doesn’t match the proxy’svpn_secret_in. - No push, but the wait happens. Username mismatch between RADIUS and the Notakey service, or the phone isn’t onboarded to this application.
- Asked for the password twice.
try_first_passis missing from thepam_unixline incommon-auth. - Key-based SSH logins get no push. That’s expected; public-key auth bypasses PAM’s auth phase (see step 4).
Where this fits
With one proxy and one RADIUS server, the VPN, the router’s admin plane and your Linux fleet all now require a phone approval. Anything that speaks RADIUS or PAM can join the same setup.
Related guides
- VPN 2FA with RADIUS — the complete auth-proxy setup: the proxy configuration this guide builds on
- MikroTik router login 2FA: the same pattern for the router’s own WinBox/SSH login