added tasks for a bastion host

This commit is contained in:
2025-10-01 14:22:25 +02:00
parent 54fc2ad535
commit 19e616845e
13 changed files with 299 additions and 11 deletions

9
hosts
View File

@@ -37,6 +37,7 @@ zoneminder.universe.local
[server:children] [server:children]
auth auth
backup backup
bastionhost
cluster cluster
database database
dhcpserver dhcpserver
@@ -51,11 +52,15 @@ mastodon
nameserver nameserver
printspooler printspooler
proxyserver proxyserver
webservers webserver
[auth] [auth]
freeradius.universe.local freeradius.universe.local
[bastionhost]
bastion.universe.local
newbastion.universe.local
[backup] [backup]
backup.universe.local backup.universe.local
@@ -143,7 +148,7 @@ endor.universe.local
endorvm.universe.local endorvm.universe.local
tuxedo-book-xp1511.universe.local tuxedo-book-xp1511.universe.local
[webservers] [webserver]
nextcloud.universe.local nextcloud.universe.local
searx.universe.local searx.universe.local
webserver.universe.local webserver.universe.local

View File

@@ -42,18 +42,18 @@
portage: portage:
sync: yes sync: yes
when: ansible_distribution == 'Gentoo' when: ansible_distribution == 'Gentoo'
ignore_errors: True
- hosts: all:!database - hosts: all:!database
pre_tasks: pre_tasks:
- name: pre-run | upgrade system (debian, ubuntu, etc.) - name: pre-run | upgrade system (debian, ubuntu, etc.)
apt: upgrade=dist apt: upgrade=dist
#changed_when: false #changed_when: false
notify: update aide database
when: ansible_distribution in ["Debian", "Ubuntu", "Linux Mint"] when: ansible_distribution in ["Debian", "Ubuntu", "Linux Mint"]
- name: pre-run | upgrade system (arch) - name: pre-run | upgrade system (arch)
pacman: upgrade=true pacman: upgrade=true
notify: update aide database
when: ansible_distribution == 'Archlinux' when: ansible_distribution == 'Archlinux'
ignore_errors: True
# run roles # run roles
- hosts: all - hosts: all
@@ -80,11 +80,11 @@
roles: roles:
- nameserver - nameserver
- hosts: webservers - hosts: webserver
tags: server,webservers tags: server,webserver
become: true become: true
roles: roles:
- webservers - webserver
- hosts: mailserver - hosts: mailserver
tags: server,mailserver tags: server,mailserver

View File

@@ -0,0 +1,21 @@
---
- name: update aide database
listen: "update aide db"
tags: aide,hardening,system
block:
- name: system setup | aide | run aide --update to check for legitimate changes
command: aide --update
register: aide_update_result
changed_when: "'new database written to' in aide_update_result.stdout"
async: 1800 # Allow up to 30 minutes for update
poll: 15
- name: system setup | aide | activate updated database
copy:
src: /var/lib/aide/aide.db.new
dest: /var/lib/aide/aide.db
remote_src: true
owner: root
group: root
mode: '0600'
when: aide_update_result.changed

View File

@@ -0,0 +1,42 @@
---
- name: system setup | aide | install aide package
tags: aide,hardening,system
package:
name: aide
state: present
- name: system setup | aide | check if aide database exists
tags: aide,hardening,system
stat:
path: /var/lib/aide/aide.db
register: aide_db
- name: system setup | aide | initialize aide database if it does not exist
tags: aide,hardening,system
block:
- name: system setup | aide | run aide --init (this may take a while)
command: aide --init
register: aide_init_result
changed_when: "'AIDE, version' in aide_init_result.stdout"
async: 1800 # Allow up to 30 minutes for initialization
poll: 15
- name: system setup | aide | copy new database to be the active one
copy:
src: /var/lib/aide/aide.db.new
dest: /var/lib/aide/aide.db
remote_src: true
owner: root
group: root
mode: '0600'
when: aide_init_result.changed
when: not aide_db.stat.exists
- name: system setup | aide | schedule daily check
tags: aide,hardening,system
cron:
name: "AIDE daily check"
minute: "0"
hour: "5"
job: "/usr/bin/aide --check"
cron_file: aide_check # Creates /etc/cron.d/aide_check

View File

@@ -0,0 +1,27 @@
---
- name: system setup | firewall | install ufw
package:
name: ufw
state: present
- name: system setup | firewall | deny all incoming traffic by default and enable firewall
community.general.ufw:
state: enabled
policy: deny
- name: system setup | firewall | allow ssh from anywhere
community.general.ufw:
rule: allow
port: '22'
proto: tcp
src: 'any'
- name: system setup | firewall | allow monitoring traffic from internal networks
community.general.ufw:
rule: allow
proto: "{{ item.proto }}"
port: "{{ item.port | default(omit) }}"
src: '192.168.1.0/24' # Passe dies an dein internes Netzwerk an
loop:
- { proto: 'icmp', comment: 'Allow Ping' }
- { proto: 'udp', port: '161', comment: 'Allow SNMP' }

View File

@@ -0,0 +1,19 @@
# Load distro-specific variables
- include_vars: "{{ ansible_distribution | lower }}.yml"
tags: always
ignore_errors: True
- block:
- debug:
msg: Debug
# Perform remaining tasks:
- import_tasks: users.yml
- import_tasks: system_setup/openssh_hardening.yml
- import_tasks: system_setup/firewall.yml
- import_tasks: system_setup/package_hardening.yml
- import_tasks: system_setup/user_hardening.yml
- import_tasks: system_setup/aide.yml
rescue:
- set_fact: task_failed=true

View File

@@ -0,0 +1,38 @@
---
- name: system setup | openssh | copy hardened sshd config for bastion
tags: openssh,ssh,system,settings
copy:
dest: /etc/ssh/sshd_config.d/hardened.conf
owner: root
group: root
mode: '0644'
content: |
# This file is managed by Ansible for the bastion role
# It overwrites/complements settings from the base role.
LogLevel VERBOSE
MaxAuthTries 3
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
UsePAM yes
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PrintMotd no
# Harden Ciphers and Algorithms
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256
PrintLastLog no
TCPKeepAlive yes
Subsystem sftp /usr/lib/ssh/sftp-server
AcceptEnv *
AllowUsers lowpriv sshjumpuser
Match User lowpriv,sshjumpuser
AllowAgentForwarding yes
AllowTcpForwarding yes
notify: [ "restart_sshd", "update aide database" ]

View File

@@ -0,0 +1,42 @@
---
- name: system setup | package hardening | remove unnecessary packages (Debian family)
tags: packages,hardening,system
package:
name:
# Daemons not needed on a bastion host
- apache2*
- nginx*
- lighttpd*
- samba*
- nfs-kernel-server
- bind9
- postfix
- cups*
- avahi-daemon
# Common utilities not required for a minimal system
- popularity-contest
- whoopsie
- command-not-found
# Games and fun stuff
- bsdgames
- fortune-mod
state: absent
purge: true # Also removes configuration files
notify: update aide database
when: ansible_os_family == "Debian"
- name: system setup | package hardening | remove unnecessary packages (RedHat family)
tags: packages,hardening,system
package:
name:
- httpd*
- nginx*
- samba*
- nfs-utils
- named
- postfix
- cups*
- avahi
state: absent
notify: update aide database
when: ansible_os_family == "RedHat"

View File

@@ -0,0 +1,24 @@
---
- name: system setup | user hardening | remove unnecessary system accounts
tags: users,hardening,system
user:
name: "{{ item }}"
state: absent
remove: true # Also removes home directory and mail spool
loop:
# Legacy or unused service accounts
- lp
- sync
- shutdown
- halt
- mail
- news
- uucp
- proxy
- backup
- list
- irc
- gnats
- games
notify: update aide database
ignore_errors: true # Some users might not exist, which is fine

View File

@@ -0,0 +1,7 @@
# Configure users for the bastion host
- name: Manage bastion user accounts by including user-specific task files
include_tasks: "users/{{ item }}.yml"
loop:
- rene
- lowpriv
- sshjumpuser

View File

@@ -0,0 +1,28 @@
- name: users | lowpriv | add user to system
user:
name: lowpriv
comment: Restricted user for interactive shell
shell: /usr/bin/rbash
state: present
create_home: True
generate_ssh_key: False
password_lock: True
- name: users | lowpriv | getent user home directory
getent:
database: passwd
key: "lowpriv"
split: ":"
register: getent_passwd_lowpriv
changed_when: false
- name: users | lowpriv | set home directory fact
set_fact:
user_home: "{{ getent_passwd_lowpriv.ansible_facts.getent_passwd['lowpriv'][4] }}"
user: "lowpriv"
- name: users | lowpriv | import ssh configuration tasks from base role
import_tasks: ../../../base/tasks/users/install_public_keys.yml
- name: users | lowpriv | import known_hosts task from base role
import_tasks: ../../../base/tasks/users/install_known_hosts.yml

View File

@@ -0,0 +1,7 @@
- include_vars: 'users.yml'
- name: users | rene | remove user from system
user:
name: rene
state: absent
remove: True

View File

@@ -0,0 +1,28 @@
- name: users | sshjumpuser | add user to system
user:
name: sshjumpuser
comment: SSH Jump User - no tty - no password
shell: /bin/false
state: present
create_home: True
generate_ssh_key: False
password_lock: True
- name: users | sshjumpuser | getent user home directory
getent:
database: passwd
key: "sshjumpuser"
split: ":"
register: getent_passwd_sshjumpuser
changed_when: false
- name: users | sshjumpuser | set home directory fact
set_fact:
user_home: "{{ getent_passwd_sshjumpuser.ansible_facts.getent_passwd['sshjumpuser'][4] }}"
user: "sshjumpuser"
- name: users | sshjumpuser | import ssh configuration tasks from base role
import_tasks: ../../../base/tasks/users/install_public_keys.yml
- name: users | sshjumpuser | import known_hosts task from base role
import_tasks: ../../../base/tasks/users/install_known_hosts.yml