From b1bb4ba0acb8f90ebbfa958ac1f9314396a6dca6 Mon Sep 17 00:00:00 2001 From: Joshua Lusk Date: Tue, 26 May 2026 09:04:43 -0400 Subject: update ssh port --- .vscode/extensions.json | 1 + .vscode/settings.json | 2 +- Makefile | 8 +- README.md | 12 +-- inventory.yaml | 1 + playbooks/bootstrap.yaml | 76 +++++++++++++++++ playbooks/files/sshd_config | 129 ----------------------------- playbooks/security.yaml | 24 ++++-- playbooks/templates/ssh.socket.conf.j2 | 3 + playbooks/templates/sshd_hardening.conf.j2 | 4 + playbooks/users.yaml | 42 ---------- vault.yaml | 35 ++++---- 12 files changed, 130 insertions(+), 207 deletions(-) create mode 100644 playbooks/bootstrap.yaml delete mode 100644 playbooks/files/sshd_config create mode 100644 playbooks/templates/ssh.socket.conf.j2 create mode 100644 playbooks/templates/sshd_hardening.conf.j2 delete mode 100644 playbooks/users.yaml diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 1f661d2..9bda081 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,6 +2,7 @@ "recommendations": [ "redhat.ansible", "redhat.vscode-yaml", + "samuelcolvin.jinjahtml", "tamasfe.even-better-toml", ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index ea8f51a..4c21f86 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ }, "[markdown]": { "editor.rulers": [ - 65 + 72 ] }, "[toml]": { diff --git a/Makefile b/Makefile index f79af57..154808b 100644 --- a/Makefile +++ b/Makefile @@ -22,13 +22,13 @@ lint: .PHONY: ping ping: - $(BIN)/ansible hollyhock -m ping -e @vault.yaml -e "ansible_user=$(or $(ANSIBLE_USER),ansible)" + $(BIN)/ansible hollyhock -m ping -e @vault.yaml -e "ansible_user=$(or $(ANSIBLE_USER),ansible)" $(if $(ANSIBLE_PORT),-e "ansible_port=$(ANSIBLE_PORT)") # Playbook targets (applicable order) -.PHONY: users -users: - $(BIN)/ansible-playbook -e @vault.yaml -e "ansible_user=$(or $(ANSIBLE_USER),ansible)" playbooks/users.yaml +.PHONY: bootstrap +bootstrap: + $(BIN)/ansible-playbook -e @vault.yaml -e "ansible_user=$(or $(ANSIBLE_USER),ansible)" $(if $(ANSIBLE_PORT),-e "ansible_port=$(ANSIBLE_PORT)") playbooks/bootstrap.yaml .PHONY: security security: diff --git a/README.md b/README.md index 98df690..acdae6c 100644 --- a/README.md +++ b/README.md @@ -32,19 +32,21 @@ _Listed in applicable order._ | Target | Description | | ----------------------- | ------------------ | -| `users`* | Add users | +| `bootstrap`* | Bootstrap access | | `security` | Security hardening | ### *Pre-bootstraped targets -Before the automation user is created, the `ping` and `users` +Before the automation user is created, the `ping` and `bootstrap` targets need to initially connect to the server host using an existing user. Set `ANSIBLE_USER` to override the default -connection user: +connection user, and set `ANSIBLE_PORT` to override the SSH port +before the `bootstrap` playbook has updated it to the port specified in +`vault.yaml`: ```sh -$ make ping ANSIBLE_USER=root -$ make users ANSIBLE_USER=root +$ make ping ANSIBLE_USER=root ANSIBLE_PORT=22 +$ make bootstrap ANSIBLE_USER=root ANSIBLE_PORT=22 ``` ## CI / deployments diff --git a/inventory.yaml b/inventory.yaml index 734d694..985e6df 100644 --- a/inventory.yaml +++ b/inventory.yaml @@ -11,6 +11,7 @@ all: ansible_host: "hollyhock.{{ domain }}" ansible_user: "{{ automation_user }}" + ansible_port: "{{ ssh_port }}" ansible_become_password: "{{ automation_password }}" admin_user: admin diff --git a/playbooks/bootstrap.yaml b/playbooks/bootstrap.yaml new file mode 100644 index 0000000..73da248 --- /dev/null +++ b/playbooks/bootstrap.yaml @@ -0,0 +1,76 @@ +- name: Bootstrap host access + hosts: hollyhock + become: "{{ ansible_user != 'root' }}" + tasks: + - name: Configure ssh hardening + ansible.builtin.template: + src: sshd_hardening.conf.j2 + dest: /etc/ssh/sshd_config.d/99-hardening.conf + mode: "0644" + backup: true + validate: /usr/sbin/sshd -t -f %s + notify: Restart ssh + + - name: Configure ssh socket port + ansible.builtin.template: + src: ssh.socket.conf.j2 + dest: /etc/systemd/system/ssh.socket.d/10-listen.conf + mode: "0644" + backup: true + notify: Restart ssh + + - name: Create groups + ansible.builtin.group: + name: "{{ item }}" + state: present + loop: + - "{{ admin_group }}" + - "{{ automation_group }}" + - "{{ deploy_group }}" + + - name: Create users + ansible.builtin.user: + name: "{{ item.user }}" + password: "{{ item.password | password_hash('sha512') }}" + update_password: on_create + groups: "{{ item.groups }}" + shell: /bin/bash + create_home: true + loop: + - user: "{{ admin_user }}" + password: "{{ admin_password }}" + groups: "{{ admin_group }},sudo" + - user: "{{ automation_user }}" + password: "{{ automation_password }}" + groups: "{{ automation_group }},sudo" + - user: "{{ deploy_user }}" + password: "{{ deploy_password }}" + groups: "{{ deploy_group }}" + no_log: true + + - name: Add ssh keys + ansible.posix.authorized_key: + user: "{{ item }}" + state: present + key: "{{ ssh_key }}" + loop: + - "{{ admin_user }}" + - "{{ automation_user }}" + - "{{ deploy_user }}" + + - name: Apply ssh changes + ansible.builtin.meta: flush_handlers + + handlers: + - name: Restart ssh socket + ansible.builtin.systemd: + name: ssh.socket + state: restarted + daemon_reload: true + listen: Restart ssh + + - name: Restart ssh service + ansible.builtin.systemd: + name: ssh + state: restarted + listen: Restart ssh diff --git a/playbooks/files/sshd_config b/playbooks/files/sshd_config deleted file mode 100644 index c8da404..0000000 --- a/playbooks/files/sshd_config +++ /dev/null @@ -1,129 +0,0 @@ -# This is the sshd server system-wide configuration file. See -# sshd_config(5) for more information. - -# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games - -# The strategy used for options in the default sshd_config shipped with -# OpenSSH is to specify options with their default value where -# possible, but leave them commented. Uncommented options override the -# default value. - -Include /etc/ssh/sshd_config.d/*.conf - -# When systemd socket activation is used (the default), the socket -# configuration must be re-generated after changing Port, AddressFamily, or -# ListenAddress. -# -# For changes to take effect, run: -# -# systemctl daemon-reload -# systemctl restart ssh.socket -# -# Port 22 -#AddressFamily any -#ListenAddress 0.0.0.0 -#ListenAddress :: - -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key - -# Ciphers and keying -#RekeyLimit default none - -# Logging -#SyslogFacility AUTH -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -#StrictModes yes -#MaxAuthTries 6 -#MaxSessions 10 - -#PubkeyAuthentication yes - -# Expect .ssh/authorized_keys2 to be disregarded by default in future. -#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 - -#AuthorizedPrincipalsFile none - -#AuthorizedKeysCommand none -#AuthorizedKeysCommandUser nobody - -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -PasswordAuthentication no # <- overwritten -#PermitEmptyPasswords no - -# Change to yes to enable challenge-response passwords (beware issues with -# some PAM modules and threads) -KbdInteractiveAuthentication no - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes -#GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the KbdInteractiveAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via KbdInteractiveAuthentication may bypass -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and KbdInteractiveAuthentication to 'no'. -UsePAM yes - -#AllowAgentForwarding yes -#AllowTcpForwarding yes -#GatewayPorts no -X11Forwarding yes -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PermitTTY yes -PrintMotd no -#PrintLastLog yes -#TCPKeepAlive yes -#PermitUserEnvironment no -#Compression delayed -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS no -#PidFile /run/sshd.pid -#MaxStartups 10:30:100 -#PermitTunnel no -#ChrootDirectory none -#VersionAddendum none - -# no default banner path -#Banner none - -# Allow client to pass locale environment variables -AcceptEnv LANG LC_* - -# override default of no subsystems -Subsystem sftp /usr/lib/openssh/sftp-server - -# Example of overriding settings on a per-user basis -#Match User anoncvs -# X11Forwarding no -# AllowTcpForwarding no -# PermitTTY no -# ForceCommand cvs server -PermitRootLogin no # <- overwritten diff --git a/playbooks/security.yaml b/playbooks/security.yaml index 14c3550..2a0424e 100644 --- a/playbooks/security.yaml +++ b/playbooks/security.yaml @@ -2,13 +2,11 @@ hosts: hollyhock become: true tasks: - - name: Configure ssh - ansible.builtin.copy: - src: sshd_config - dest: /etc/ssh/sshd_config - mode: "0644" - backup: true - notify: Restart ssh + - name: Install ufw + ansible.builtin.apt: + name: ufw + state: present + update_cache: true - name: Deny all incoming traffic by default community.general.ufw: @@ -23,7 +21,7 @@ - name: Allow ssh traffic through firewall community.general.ufw: rule: allow - port: 22 + port: "{{ ssh_port }}" proto: tcp - name: Enable ufw @@ -49,7 +47,15 @@ dest: /etc/apt/apt.conf.d/20auto-upgrades handlers: - - name: Restart ssh + - name: Restart ssh socket + ansible.builtin.systemd: + name: ssh.socket + state: restarted + daemon_reload: true + listen: Restart ssh + + - name: Restart ssh service ansible.builtin.systemd: name: ssh state: restarted + listen: Restart ssh diff --git a/playbooks/templates/ssh.socket.conf.j2 b/playbooks/templates/ssh.socket.conf.j2 new file mode 100644 index 0000000..48c68dd --- /dev/null +++ b/playbooks/templates/ssh.socket.conf.j2 @@ -0,0 +1,3 @@ +[Socket] +ListenStream= +ListenStream={{ ssh_port }} diff --git a/playbooks/templates/sshd_hardening.conf.j2 b/playbooks/templates/sshd_hardening.conf.j2 new file mode 100644 index 0000000..77815bd --- /dev/null +++ b/playbooks/templates/sshd_hardening.conf.j2 @@ -0,0 +1,4 @@ +Port {{ ssh_port }} +PasswordAuthentication no +KbdInteractiveAuthentication no +PermitRootLogin no diff --git a/playbooks/users.yaml b/playbooks/users.yaml deleted file mode 100644 index 913e6a9..0000000 --- a/playbooks/users.yaml +++ /dev/null @@ -1,42 +0,0 @@ -- name: Add users - hosts: hollyhock - become: "{{ ansible_user != 'root' }}" - tasks: - - name: Create groups - ansible.builtin.group: - name: "{{ item }}" - state: present - loop: - - "{{ admin_group }}" - - "{{ automation_group }}" - - "{{ deploy_group }}" - - - name: Create users - ansible.builtin.user: - name: "{{ item.user }}" - password: "{{ item.password | password_hash('sha512') }}" - update_password: on_create - groups: "{{ item.groups }}" - shell: /bin/bash - create_home: true - loop: - - user: "{{ admin_user }}" - password: "{{ admin_password }}" - groups: "{{ admin_group }},sudo" - - user: "{{ automation_user }}" - password: "{{ automation_password }}" - groups: "{{ automation_group }},sudo" - - user: "{{ deploy_user }}" - password: "{{ deploy_password }}" - groups: "{{ deploy_group }}" - no_log: true - - - name: Add ssh keys - ansible.posix.authorized_key: - user: "{{ item }}" - state: present - key: "{{ ssh_key }}" - loop: - - "{{ admin_user }}" - - "{{ automation_user }}" - - "{{ deploy_user }}" diff --git a/vault.yaml b/vault.yaml index 814efde..b4ac7f8 100644 --- a/vault.yaml +++ b/vault.yaml @@ -1,18 +1,19 @@ $ANSIBLE_VAULT;1.1;AES256 -34653436613830653830323564303661373830616637656235386362643935353935623663636366 -6536323565363363663761623735666432303435326462610a666562383539356462333562653336 -64336365393864636430643463386337633432326462656234326633346532366132356231346263 -3735333936636238630a616233646562623534333362623265323332663636653032386230336536 -36326339316661303030616665626331616535373564336666663436306265653263613330613233 -30653631633938356330656631626236616331343963383939613933326436626436643366633666 -31316264653763326430643337306538623531636633386664343866383661393264366566386238 -64313732303136636530356334376662633065393964333766356564346133363837333966656162 -31666237333137383966316231336533666262383031623461313732363666383830366233663661 -33356365303632626637316337313131336130383139626134303065613732303735316234373865 -65393731653339633336636361373265653966366663316365333333303262623637346639386436 -37323566616636623866633638373833643037613161373136383262303165363238396665613331 -63316135613064333439383561643537666333663035643462323961353937613132306364656164 -30353561646638643130326533613937366135386137663437373264386136656536643231613030 -34376635633366326164623031623530663633373634613565333762353931376164326236313136 -37613634623938626535626233626330623966383332353339343261633132336261343065333837 -66373136626336373830646635366363646531313032616534393433316466663239 +65306666313531353535326534363963303433383662353838666133356537616233343135366461 +3833356361373265333634333263313639383433316435350a623831623237633630663533363431 +37396234386462383939613061623563353135376233396337313737636164623530623033366261 +3535626461653137630a626334646463346363643633623566323038353266373331353765323539 +31373531663962336433383861393465396534376130333063393339336339653239383839393264 +61343730316665626338626430336432373033646636373062626134393361653932303030313235 +36666461363032333866343265646365316332313638306661636336646666306665306365643965 +38373330343233316565653233616566313931343734646562363035336366666566363133623561 +38343730373061363339653130373130646338653839643061383236336437636538613334363238 +31316336376330363033653863373734663863333333353563396161393666336165646230323139 +38333637303438303237643734383139623666363435363632366632666137333236323031306239 +64633039633061623165373833376132386633643562613931653833633138616536663238303230 +62343637303266666232353536373230363334633561633362613339326633323263613032636437 +35633438313261383539373065306536396233613830376339666661663534373636306630396437 +35373264623036313430366232643031373134326434623433663239366365343032396164626535 +61613435353665653261613663353065376234636364333863653261316231396330363835646638 +39363662616532343738666466336430656161376139313561326463383939333361646236333138 +3832663930616633313439386664336361646166643938323937 -- cgit v1.2.3