Configuration Reference
Variable Source Hierarchy
Variables resolve in standard Ansible precedence order. The role uses three layers:
- Role defaults —
roles/ssh-baseline/defaults/main.yml(lowest precedence; the safe baseline) - Group vars —
inventory/group_vars/all/main.yml(organisation-wide overrides, including vault-sourced secrets) - Host vars —
inventory/host_vars/<hostname>.yml(per-host overrides; not currently used in this repo but supported)
The group_vars/all/main.yml file overrides the most security-sensitive defaults (AD domain, OUs, groups, SCEPman URL) so they cannot drift even if a role default is accidentally edited.
Group Vars (Organisation-Wide)
File: inventory/group_vars/all/main.yml
---
# AD join credentials - sourced from vault.yml (encrypted)
ad_join_user: "{{ vault_ad_join_user }}"
ad_join_password: "{{ vault_ad_join_password }}"
# Domain configuration
ad_domain: "pbr.org.au"
ad_computer_ou: "OU=Linux,OU=Servers,OU=Computers,OU=PBR,DC=pbr,DC=org,DC=au"
# Access control via AD security groups (must exist in AD)
ad_server_access_group: "SG_ServerAccess"
ad_sudo_group: "SG_Sudo"
# SCEPman PKI - root CA distribution endpoint
scepman_ca_url: "https://pki.pbr.org.au/ca"
Vault-Sourced Variables
| Group var | Vault key | Purpose |
|---|---|---|
ad_join_user | vault_ad_join_user | UPN of the AD service account used by realm join. Must have create-computer rights in the target OU. |
ad_join_password | vault_ad_join_password | Password for the join service account. |
The Duo credentials are also vault-sourced and referenced in roles/ssh-baseline/templates/pam_duo.conf.j2:
| Template var | Vault key | Purpose |
|---|---|---|
duo_ikey | vault_duo_ikey | Duo Auth API integration key |
duo_skey | vault_duo_skey | Duo Auth API secret key |
duo_api_host | vault_duo_api_host | Duo API hostname (e.g. api-XXXXXXXX.duosecurity.com) |
To edit the vault:
cd ~/pbr-infra
ansible-vault edit inventory/group_vars/all/vault.yml \
--vault-password-file ~/.ansible_vault_pass
Role Defaults: AD & Access
File: roles/ssh-baseline/defaults/main.yml (referenced; group_vars override these)
| Variable | Default | Purpose |
|---|---|---|
ad_domain | pbr.org.au | AD DNS domain. Used for realm membership, krb5.conf, SSSD. |
ad_computer_ou | Linux servers OU | OU where computer objects are created by realm join. |
ad_server_access_group | SG_ServerAccess | AD security group for read-only SSH access (no sudo). |
ad_sudo_group | SG_Sudo | AD security group for sudo-enabled users. Members trigger Duo on sudo. |
pbr_admin_allowed_sources | 10.1.0.0/16,192.168.0.0/16 | Source-IP allow-list (CIDR, comma-separated, no spaces) for the pbr_admin break-glass Match block. |
ad_access_filter | See below | LDAP filter applied by SSSD for access control. Default is memberOf=<ServerAccess DN> OR memberOf=<Sudo DN>, both fully qualified. |
ad_access_filter default:
(|(memberOf=CN=SG_ServerAccess,OU=Security,OU=Groups,DC=pbr,DC=org,DC=au)(memberOf=CN=SG_Sudo,OU=Security,OU=Groups,DC=pbr,DC=org,DC=au))
Role Defaults: PKI (SCEPman)
| Variable | Default | Purpose |
|---|---|---|
scepman_ca_url | https://pki.pbr.org.au/ca | Endpoint that returns the SCEPman root CA in DER format. |
scepman_ca_cert | /usr/local/share/ca-certificates/pbr-root-ca.crt | PEM-format location of the trusted root CA (added to system trust store). |
scepman_ca_der | /etc/ssl/certs/pbr-root-ca.der | DER-format location of the root CA (kept for reference; PEM is what's trusted). |
Role Defaults: System
| Variable | Default | Purpose |
|---|---|---|
timezone | Australia/Melbourne | System timezone applied via community.general.timezone. |
manage_auditd | auto | Whether to enable auditd. auto = skip on LXC (kernel audit netlink isolated), enable elsewhere. Accepts true, false, or auto. |
Role Defaults: SSH Hardening
These map directly to sshd_config directives in 10-pbr-hardening.conf.
| Variable | Default | sshd_config directive | Notes |
|---|---|---|---|
ssh_port | 22 | Port | Changing this requires systemd ssh.socket overrides on Ubuntu 22.10+. |
ssh_banner | /etc/issue.net | Banner | Path to legal banner file. |
ssh_log_level | VERBOSE | LogLevel | CIS Ubuntu 22.04 recommendation. |
ssh_login_grace_time | 60 | LoginGraceTime | Seconds before unauthenticated connection drops. |
ssh_max_auth_tries | 3 | MaxAuthTries | Per-connection auth attempt cap. |
ssh_max_sessions | 4 | MaxSessions | Concurrent multiplexed sessions per connection. |
ssh_max_startups | 10:30:60 | MaxStartups | Concurrent unauthenticated connections (start:rate:full). |
ssh_client_alive_interval | 300 | ClientAliveInterval | Seconds between keepalive probes. |
ssh_client_alive_count_max | 2 | ClientAliveCountMax | Idle connections drop after interval × count_max seconds. |
ssh_permit_root_login | no | PermitRootLogin | Hard no. |
ssh_password_authentication | no | PasswordAuthentication | Disabled globally; re-enabled for pbr_admin via Match block. |
ssh_pubkey_authentication | yes | PubkeyAuthentication | Required by all flows. |
ssh_kbdint | yes | KbdInteractiveAuthentication | Required for Duo PAM keyboard-interactive. |
ssh_allow_tcp_forwarding | no | AllowTcpForwarding | Disabled. |
ssh_x11_forwarding | no | X11Forwarding | Disabled. |
ssh_allow_agent_forwarding | no | AllowAgentForwarding | Disabled. |
ssh_compression | no | Compression | Defence against compression-side-channel attacks. |
ssh_tcp_keep_alive | no | TCPKeepAlive | Use SSH-level keep-alive instead. |
ssh_authentication_methods | publickey,keyboard-interactive | AuthenticationMethods | Both required; keyboard-interactive is Duo via PAM. |
Modern Crypto
Algorithm lists prepended with the post-quantum hybrid KEX where available:
| Variable | Default |
|---|---|
ssh_ciphers | [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr |
ssh_macs | [email protected],[email protected],[email protected] |
ssh_kex_algorithms | [email protected],curve25519-sha256,[email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256 |
Role Defaults: fail2ban
| Variable | Default | Purpose |
|---|---|---|
fail2ban_bantime_default | 3600 | Default ban duration in seconds (1 hour) for non-sshd jails. |
fail2ban_findtime | 600 | Window in seconds during which maxretry failures trigger a ban. |
fail2ban_maxretry_default | 5 | Failures within findtime before ban (default for non-sshd jails). |
fail2ban_sshd_maxretry | 3 | Tighter setting for the sshd jail. |
fail2ban_sshd_bantime | 86400 | 24-hour ban for sshd failures. |
fail2ban_ignoreip | list, see below | CIDRs exempt from banning. |
Default fail2ban_ignoreip:
fail2ban_ignoreip:
- "127.0.0.1/8"
- "::1"
- "10.1.0.0/16" # PBR server LAN
- "10.1.8.80/32" # pbr-ansible-kl1 control node (explicit)
- "192.168.0.0/16" # Admin workstation VLANs supernet (TEMPORARY)
The 192.168.0.0/16 entry is annotated TEMPORARY in the role — intended to be removed when VLAN segmentation completes and admin workstations land on a single, well-defined CIDR.
Role Defaults: Duo MFA
| Variable | Default | Purpose |
|---|---|---|
duo_failmode | safe | safe = allow login if Duo cloud unreachable (fall through to single-factor publickey); secure = deny login during outage. |
duo_pushinfo | yes | Include hostname and command in the Duo push notification. |
duo_prompts | 3 | Max retries at the Duo prompt before failure. |
duo_autopush | yes | Auto-send push to user's primary device. |
break_glass_user | pbr_admin | Username carved out of the Duo PAM flow. |
duo_sudo_enabled | true | Toggle Duo MFA on sudo (v2.4+). |
sudo_timestamp_timeout | 30 | Minutes the sudo credential cache lasts; reduces Duo prompts during a session. |
Preflight Role Defaults
File: roles/preflight/defaults/main.yml
| Variable | Default | Purpose |
|---|---|---|
preflight_min_ubuntu_major | 22 | Minimum Ubuntu major version. 22.04 LTS is the floor. |
preflight_required_users | [ansible, pbr_admin] | Local accounts that must exist before baseline. |
preflight_ad_ports | [88, 389] | Ports tested for AD DC reachability. 88 = Kerberos, 389 = LDAP. |
preflight_skip_schema_check | false | Set true to bypass the AD schema check if python3-ldap is unavailable on the control node and you've verified schema manually. |
Override Patterns
Per-host override via host_vars
Create inventory/host_vars/<hostname>.yml. Example: a host that requires a tighter source-IP allow-list:
---
# inventory/host_vars/pbr-pos-belgrave.yml
pbr_admin_allowed_sources: "10.1.8.0/24" # POS LAN only
fail2ban_sshd_bantime: 604800 # 7 days for POS hosts
Forcing auditd on/off per host
---
# inventory/host_vars/pbr-graylog-kl1.yml
# Force-skip auditd even if the host migrates from LXC to KVM
manage_auditd: false
Adding a CIDR to fail2ban ignoreip
Override the full list (Ansible doesn't merge list defaults by default):
fail2ban_ignoreip:
- "127.0.0.1/8"
- "::1"
- "10.1.0.0/16"
- "10.1.8.80/32"
- "192.168.0.0/16"
- "203.0.113.42/32" # NEW: external admin static IP
ansible.cfg Settings
The runtime configuration on pbr-ansible-kl1 is fixed by ansible.cfg in the repo root:
[defaults]
inventory = inventory/hosts.yml
remote_user = ansible
private_key_file = ~/.ssh/ansible_svc
host_key_checking = True
retry_files_enabled = False
stdout_callback = yaml
interpreter_python = auto_silent
vault_password_file = ~/.ansible_vault_pass
roles_path = roles
collections_path = collections
forks = 5
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
Notable settings:
host_key_checking = True— rejects connection to hosts with unknown SSH host keys. Adding a new host requires accepting its host key once (the bootstrap step naturally surfaces this).vault_password_fileis set inansible.cfg, so the--vault-password-fileflag is technically redundant on the command line. It's included explicitly in this book's runbooks for portability if the config changes.forks = 5caps concurrency. Combined withserial: 1in playbooks, the effective concurrency is 1 host at a time.pipelining = Truereduces task overhead by skipping the SCP/SFTP transfer of small modules.
Collection Requirements
File: requirements.yml
---
collections:
- name: ansible.posix
version: ">=2.1.0"
- name: community.general
version: ">=12.0.0"
- name: paloaltonetworks.panos
version: ">=2.20"
- name: arubanetworks.aoscx
version: ">=10.0"
Used by ssh-baseline: ansible.posix (assorted modules), community.general (timezone module, ldap_search for schema check).
Other collections: paloaltonetworks.panos and arubanetworks.aoscx are listed for future use cases (Palo Alto NGFW automation, AOS-CX switch config) but are not used by the ssh-baseline role.
Install/update collections:
cd ~/pbr-infra
ansible-galaxy collection install -r requirements.yml --upgrade
Where to Read Next
- AD Integration & SSSD — how the AD variables map to SSSD config
- Duo MFA Integration — how the Duo variables map to
pam_duo.confand the PAM stacks - SSH Hardening Reference — how each SSH variable lands in the deployed config
No comments to display
No comments to display