Skip to main content

Configuration Reference

Variable Source Hierarchy

Variables resolve in standard Ansible precedence order. The role uses three layers:

  1. Role defaultsroles/ssh-baseline/defaults/main.yml (lowest precedence; the safe baseline)
  2. Group varsinventory/group_vars/all/main.yml (organisation-wide overrides, including vault-sourced secrets)
  3. Host varsinventory/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 varVault keyPurpose
ad_join_uservault_ad_join_userUPN of the AD service account used by realm join. Must have create-computer rights in the target OU.
ad_join_passwordvault_ad_join_passwordPassword for the join service account.

The Duo credentials are also vault-sourced and referenced in roles/ssh-baseline/templates/pam_duo.conf.j2:

Template varVault keyPurpose
duo_ikeyvault_duo_ikeyDuo Auth API integration key
duo_skeyvault_duo_skeyDuo Auth API secret key
duo_api_hostvault_duo_api_hostDuo 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)

VariableDefaultPurpose
ad_domainpbr.org.auAD DNS domain. Used for realm membership, krb5.conf, SSSD.
ad_computer_ouLinux servers OUOU where computer objects are created by realm join.
ad_server_access_groupSG_ServerAccessAD security group for read-only SSH access (no sudo).
ad_sudo_groupSG_SudoAD security group for sudo-enabled users. Members trigger Duo on sudo.
pbr_admin_allowed_sources10.1.0.0/16,192.168.0.0/16Source-IP allow-list (CIDR, comma-separated, no spaces) for the pbr_admin break-glass Match block.
ad_access_filterSee belowLDAP 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)

VariableDefaultPurpose
scepman_ca_urlhttps://pki.pbr.org.au/caEndpoint that returns the SCEPman root CA in DER format.
scepman_ca_cert/usr/local/share/ca-certificates/pbr-root-ca.crtPEM-format location of the trusted root CA (added to system trust store).
scepman_ca_der/etc/ssl/certs/pbr-root-ca.derDER-format location of the root CA (kept for reference; PEM is what's trusted).

Role Defaults: System

VariableDefaultPurpose
timezoneAustralia/MelbourneSystem timezone applied via community.general.timezone.
manage_auditdautoWhether 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.

VariableDefaultsshd_config directiveNotes
ssh_port22PortChanging this requires systemd ssh.socket overrides on Ubuntu 22.10+.
ssh_banner/etc/issue.netBannerPath to legal banner file.
ssh_log_levelVERBOSELogLevelCIS Ubuntu 22.04 recommendation.
ssh_login_grace_time60LoginGraceTimeSeconds before unauthenticated connection drops.
ssh_max_auth_tries3MaxAuthTriesPer-connection auth attempt cap.
ssh_max_sessions4MaxSessionsConcurrent multiplexed sessions per connection.
ssh_max_startups10:30:60MaxStartupsConcurrent unauthenticated connections (start:rate:full).
ssh_client_alive_interval300ClientAliveIntervalSeconds between keepalive probes.
ssh_client_alive_count_max2ClientAliveCountMaxIdle connections drop after interval × count_max seconds.
ssh_permit_root_loginnoPermitRootLoginHard no.
ssh_password_authenticationnoPasswordAuthenticationDisabled globally; re-enabled for pbr_admin via Match block.
ssh_pubkey_authenticationyesPubkeyAuthenticationRequired by all flows.
ssh_kbdintyesKbdInteractiveAuthenticationRequired for Duo PAM keyboard-interactive.
ssh_allow_tcp_forwardingnoAllowTcpForwardingDisabled.
ssh_x11_forwardingnoX11ForwardingDisabled.
ssh_allow_agent_forwardingnoAllowAgentForwardingDisabled.
ssh_compressionnoCompressionDefence against compression-side-channel attacks.
ssh_tcp_keep_alivenoTCPKeepAliveUse SSH-level keep-alive instead.
ssh_authentication_methodspublickey,keyboard-interactiveAuthenticationMethodsBoth required; keyboard-interactive is Duo via PAM.

Modern Crypto

Algorithm lists prepended with the post-quantum hybrid KEX where available:

VariableDefault
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

VariableDefaultPurpose
fail2ban_bantime_default3600Default ban duration in seconds (1 hour) for non-sshd jails.
fail2ban_findtime600Window in seconds during which maxretry failures trigger a ban.
fail2ban_maxretry_default5Failures within findtime before ban (default for non-sshd jails).
fail2ban_sshd_maxretry3Tighter setting for the sshd jail.
fail2ban_sshd_bantime8640024-hour ban for sshd failures.
fail2ban_ignoreiplist, see belowCIDRs 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

VariableDefaultPurpose
duo_failmodesafesafe = allow login if Duo cloud unreachable (fall through to single-factor publickey); secure = deny login during outage.
duo_pushinfoyesInclude hostname and command in the Duo push notification.
duo_prompts3Max retries at the Duo prompt before failure.
duo_autopushyesAuto-send push to user's primary device.
break_glass_userpbr_adminUsername carved out of the Duo PAM flow.
duo_sudo_enabledtrueToggle Duo MFA on sudo (v2.4+).
sudo_timestamp_timeout30Minutes the sudo credential cache lasts; reduces Duo prompts during a session.

Preflight Role Defaults

File: roles/preflight/defaults/main.yml

VariableDefaultPurpose
preflight_min_ubuntu_major22Minimum 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_checkfalseSet 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_file is set in ansible.cfg, so the --vault-password-file flag is technically redundant on the command line. It's included explicitly in this book's runbooks for portability if the config changes.
  • forks = 5 caps concurrency. Combined with serial: 1 in playbooks, the effective concurrency is 1 host at a time.
  • pipelining = True reduces 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

  • AD Integration & SSSD — how the AD variables map to SSSD config
  • Duo MFA Integration — how the Duo variables map to pam_duo.conf and the PAM stacks
  • SSH Hardening Reference — how each SSH variable lands in the deployed config