PAM (Pluggable Authentication Module) for Linux/Unix systems that provides two-factor authentication via Werbot service for SSH logins.
wpam integrates with the PAM authentication system and adds two-factor authentication (2FA) for SSH connections. The module supports:
- TOTP (Time-based One-Time Password) - 6-digit codes
- U2F (Universal 2nd Factor) - hardware security keys
- Offline mode for specified users
- Centralized access management via Werbot API
- Go 1.25 or higher
- C compiler (gcc)
- PAM development headers
- Linux/Unix system with PAM support
- Access to Werbot API server
Ubuntu/Debian:
sudo apt install build-essential
sudo apt-get install pkg-config
sudo apt-get install libpam0g-devCentOS/RHEL:
sudo yum install gcc
sudo yum install pkgconfig
sudo yum install pam-develFreeBSD:
sudo pkg install go
sudo pkg install gcc
sudo pkg install pam-develOpenBSD:
doas pkg_add go gcc
# PAM is part of base systemNetBSD:
sudo pkgin install go gcc
sudo pkgin install pam-develFor current platform:
go build -buildmode=c-shared -o wpam.soOr using Makefile:
make buildCross-compilation for specific platforms:
# Linux amd64
make build-linux
# Linux arm64
make build-linux-arm64
# FreeBSD amd64
make build-freebsd
# OpenBSD amd64
make build-openbsd
# NetBSD amd64
make build-netbsd
# All platforms
make build-allLinux:
sudo cp wpam.so /lib/security/pam_wpam.so
sudo chmod 644 /lib/security/pam_wpam.soFreeBSD/OpenBSD/NetBSD:
sudo cp wpam.so /usr/lib/pam_wpam.so
sudo chmod 644 /usr/lib/pam_wpam.soOr using Makefile (builds and installs for current platform):
make installNote: PAM module directory varies by platform:
- Linux:
/lib/security/or/lib64/security/ - FreeBSD/OpenBSD/NetBSD:
/usr/lib/ - macOS:
/usr/lib/pam/(not recommended for production)
Edit /etc/pam.d/sshd and add the lines after @include common-auth:
auth required /lib/security/pam_wpam.so server_url=api.werbot.com service_id=YOUR_SERVICE_ID service_key=YOUR_SERVICE_KEY
account required /lib/security/pam_wpam.so server_url=api.werbot.com service_id=YOUR_SERVICE_ID service_key=YOUR_SERVICE_KEY
#@include common-auth
Important:
- Comment out or remove the
@include common-authline if you want to use only Werbot for authentication auth requiredperforms 2FA authentication (requires TOTP/U2F)account requiredperforms account validation (checks access without TFA)
Edit /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
UsePam yes
Restart SSH service:
Linux (systemd):
sudo systemctl restart sshdFreeBSD/OpenBSD/NetBSD:
sudo service sshd restart
# or
sudo /etc/rc.d/sshd restartAll parameters are passed via PAM module arguments in key=value format:
| Parameter | Required | Description | Example |
|---|---|---|---|
server_url |
Yes | Werbot API server URL (without protocol) | api.werbot.com |
service_id |
Yes | Service ID in Werbot | bef57548-dfdd-4aba-a545-50aa9e4f50db |
service_key |
Yes | Service key in Werbot | 7ba94fcbac95b794fc6efc25e1c23f0d6b |
offline_users |
No | Comma-separated list of users for offline access | admin,backup |
debug |
No | Enable debug logging (true/false or 1/0) |
debug=true |
insecure_skip_verify |
No | Disable SSL certificate verification (true/false or 1/0) |
insecure_skip_verify=false |
auth required /lib/security/pam_wpam.so \
server_url=api.werbot.com \
service_id=bef57548-dfdd-4aba-a545-50aa9e4f50db \
service_key=7ba94fcbac95b794fc6efc25e1c23f0d6b \
offline_users=admin,backup \
debug=false \
insecure_skip_verify=false
- User connects via SSH
- System prompts for Werbot ID (email or username in Werbot)
- System prompts for TOTP code (6 digits) or empty string for U2F
- Module sends request to Werbot API
- On successful authentication, access is granted
$ ssh user@server
Enter your Werbot ID (email or username): user@example.com
Enter your totp code (submit empty for U2F): 123456
Or for U2F:
$ ssh user@server
Enter your Werbot ID (email or username): user@example.com
Enter your totp code (submit empty for U2F): [press Enter]
[Connect U2F key and press button]
The module writes logs to /var/log/wpam.log. To view:
sudo tail -f /var/log/wpam.log- INFO - informational messages (offline access, successful authentication)
- WARN - warnings (failed authentication)
- ERROR - errors (connection issues, parsing problems)
- DEBUG - debug information (only when
debug=true)
sudo chmod 640 /var/log/wpam.log
sudo chown root:adm /var/log/wpam.log- Disable debug in production:
debug=false(default) - Do not use
insecure_skip_verifyin production environment - Limit offline access: specify only necessary users in
offline_users - Protect service_key: do not log or transmit in plain text
- Check module permissions:
/lib/security/pam_wpam.soshould be accessible only to root
The module automatically hides sensitive data in logs:
service_keyis replaced with[REDACTED]totp_codeis replaced with[REDACTED]- Tokens and keys in API responses are also hidden
If the Werbot server is unavailable, the module can grant access for specified users:
offline_users=admin,backup,emergency
Warning: Use offline mode only for critical accounts and only when necessary.
Solution: Ensure that /etc/ssh/sshd_config has:
ChallengeResponseAuthentication yes
UsePam yes
After changes, restart SSH: sudo systemctl restart sshd
Solution:
- Check file permissions:
ls -l /lib/security/pam_wpam.so - Check syntax in
/etc/pam.d/sshd - Check logs:
sudo tail -f /var/log/wpam.log
Solution:
- Check server availability:
curl https://api.werbot.com - Verify
server_url,service_id,service_keyare correct - Check firewall rules
- Enable
debug=truefor detailed logging
Solution:
- Check logs:
sudo tail -f /var/log/wpam.log - Ensure user is registered in Werbot
- Verify TOTP code or U2F key is correct
- Check service settings in Werbot
Current platform:
make build
# or
go build -buildmode=c-shared -o wpam.soCross-compilation:
For individual platforms:
make build-linux # Linux amd64
make build-linux-arm64 # Linux arm64
make build-freebsd # FreeBSD amd64
make build-openbsd # OpenBSD amd64
make build-netbsd # NetBSD amd64Build for all platforms:
Cross-compilation with CGO requires cross-compilers. Recommended approaches:
- Using Docker (recommended):
./build-all.sh- Using Makefile (may fail without cross-compilers):
make build-all- Build on target platforms:
- Build on Linux for Linux binaries
- Build on FreeBSD for FreeBSD binaries
- etc.
Note: CGO cross-compilation from macOS to Linux requires special setup. For reliable builds, use Docker or build directly on target platforms.
Help:
make helpmake installmake cleanThe project uses only Go standard library (net/http), no external dependencies required.
[Specify project license]
[Specify support contacts]