Control SSH access and sudo privileges on your Linux servers through a centralized bastion server.
Open Bastion integrates your servers with LemonLDAP::NG (LLNG) to centrally manage who can SSH into which servers and who can use sudo. Administrators define access rules in the portal, and the PAM/NSS modules enforce them on each server.
The module supports two authentication methods:
- Token-based authentication: Users generate temporary access tokens from the portal to use as SSH passwords
- Key-based authorization: When users connect via SSH keys, the module checks if they're authorized to access this server
- Token introspection via OIDC introspection endpoint
- Server authorization via
/pam/authorizeendpoint - Server groups support for granular access control
- Token caching to reduce server load
- Secure communication with SSL/TLS support
- Easy server enrollment with
ob-enrollscript - Offline mode:
- Encrypted authorization cache (AES-256-GCM)
- Continue SSH key authentication when LLNG server is unavailable
- Configurable cache TTL with shorter TTL for high-risk services (sudo, su)
- Cache brute-force protection with rate limiting
- NSS module:
- Resolve users from LLNG via
/pam/userinfoendpoint - Automatic UID generation from username hash
- Cross-process file cache for performance
- Resolve users from LLNG via
- Automatic user provisioning:
- Auto-create Unix accounts on first login
- Configurable shell, home directory, UID/GID ranges
- Skeleton directory support
- Group synchronization:
- Sync Unix supplementary groups from LLNG on each login
- Automatic group creation if needed
- Local whitelist for defense-in-depth (
allowed_managed_groups) - Groups outside managed pool are never modified
- Service accounts (ansible, backup, etc.):
- SSH key authentication without OIDC
- Per-server configuration file
- Fine-grained sudo permissions
- Automatic account creation
- Bastion-to-backend authentication:
- JWT-based proof of connection origin
- Backends only accept SSH from authorized bastions
- Offline verification via cached JWKS public keys
ob-ssh-proxyscript for seamless bastion connections
- Session recording (optional):
- Record all terminal I/O for audit compliance
- Multiple formats: script, asciinema, ttyrec
- Session metadata with unique IDs
- Security hardening:
- Structured JSON audit logging with correlation IDs
- Rate limiting with exponential backoff
- AES-256-GCM encrypted secret storage
- Webhook notifications for security events
- Token binding (IP, fingerprint)
- SSH key policy enforcement (allowed types, minimum sizes)
- CrowdSec integration (optional):
- Pre-authentication IP blocking via CrowdSec bouncer
- Post-authentication failure reporting via CrowdSec watcher
- Auto-ban after configurable failure threshold
- Compatible with Crowdsieve for centralized alert management
- Monitoring:
- Server heartbeat via
ob-heartbeat - Statistics reporting to portal
- Server heartbeat via
- Desktop SSO (LightDM integration):
- Authenticate workstations via LLNG Single Sign-On
- LightDM webkit2-greeter theme with embedded LLNG portal
- Offline mode with cached credentials (Argon2id + AES-256-GCM)
- Multi-factor authentication support (TOTP, WebAuthn, etc.)
- Automatic session and desktop environment selection
Pre-built packages are available for:
- Debian/Ubuntu: Debian 12, Debian 13, Ubuntu 24.04
- RHEL/Rocky Linux: Rocky Linux 9, Rocky Linux 10
See installation instructions at: https://linagora.github.io/open-bastion/
# Install dependencies (Debian/Ubuntu)
sudo apt-get install libcurl4-openssl-dev libjson-c-dev libpam0g-dev libssl-dev libkeyutils-dev cmake curl jq
# Build
mkdir build && cd build
cmake ..
make
sudo make installSee LemonLDAP::NG Configuration for detailed setup.
sudo cp /etc/open-bastion/openbastion.conf.example /etc/open-bastion/openbastion.conf
sudo chmod 600 /etc/open-bastion/openbastion.confEdit with your settings:
portal_url = https://auth.example.com
client_id = pam-access
client_secret = your-secret
server_group = defaultsudo ob-enrollThe script will display a user code. An administrator must visit the LLNG portal and enter this code to approve the server.
Edit /etc/pam.d/sshd (recommended mode - LLNG tokens only):
auth sufficient pam_openbastion.so
auth required pam_deny.so
account required pam_openbastion.so
account required pam_unix.so
session required pam_unix.so
See PAM Authentication Modes for other configurations.
Important: Open a new terminal and keep your current session open as backup!
ssh user@server
Password: <paste LLNG token from portal>See the full documentation index or jump directly to:
| Document | Description |
|---|---|
| LemonLDAP::NG Configuration | Server-side LLNG setup and plugins |
| PAM Authentication Modes | All 4 PAM configurations with examples |
| Configuration Reference | All configuration options |
| Service Accounts | Ansible, backup, CI/CD accounts |
| Bastion Architecture | Bastion-to-backend JWT authentication |
| Session Recording | SSH session recording for audit |
| CrowdSec Integration | IP blocking and alert reporting |
| Security Features | Key policies, rate limiting, audit |
| Admin Guide | Complete administration guide |
# System auth log
sudo tail -f /var/log/auth.log
# Or journald
sudo journalctl -u sshd -fIn /etc/open-bastion/openbastion.conf:
log_level = debugcurl -X POST https://auth.example.com/oauth2/introspect \
-u "pam-access:secret" \
-d "token=<user_token>"curl -X POST https://auth.example.com/pam/authorize \
-H "Authorization: Bearer $(sudo cat /etc/open-bastion/token)" \
-H "Content-Type: application/json" \
-d '{"user": "testuser", "host": "'$(hostname)'", "server_group": "default"}'| Issue | Cause | Solution |
|---|---|---|
PAM unable to load module |
Module not in path | Check /lib/security/ or /lib64/security/ |
Token introspection failed |
Wrong credentials | Verify client_id and client_secret |
Server not enrolled |
Missing/invalid token | Run ob-enroll |
User not authorized |
Server group rules | Check LLNG Manager configuration |
Connection refused |
Portal unreachable | Check network and portal_url |
If the server token expires or is compromised:
sudo rm /etc/open-bastion/token
sudo ob-enroll- A LemonLDAP::NG system >= 2.21.0 (LTS) with additional plugins installed and enabled
- libcurl, json-c, OpenSSL, libkeyutils, PAM development headers
- curl and jq (for enrollment script)
Open Bastion can authenticate desktop workstations via LemonLDAP::NG Single Sign-On using LightDM.
# Install the greeter package
sudo apt install lightdm-openbastion-greeter
# Run the setup script
sudo ob-desktop-setup -p https://auth.example.com
# For offline mode support
sudo ob-desktop-setup -p https://auth.example.com --offline- SSO Authentication: Users login with their LLNG credentials via embedded portal
- Multi-Factor Authentication: Supports TOTP, WebAuthn/FIDO2, SMS, and more
- Offline Mode: Cached credentials allow login when LLNG is unreachable
- Session Selection: Choose between multiple desktop environments
- Desktop SSO Guide - Complete setup and configuration
- Offline Mode - Cached credential authentication
- Security Architecture - Security details
# Show cache statistics
sudo ob-cache-admin stats
# List cached users
sudo ob-cache-admin list
# Invalidate a user's cache (after termination)
sudo ob-cache-admin invalidate usernameAGPL-3.0
Xavier Guimard [email protected]
Copyright (C) 2025 Linagora