feat(infra-controller): add restricted SSH access role

- Add infra_controller role to provision a dedicated user\n- Install register/deregister forced-command authorized_keys entries\n- Read SSH public keys from vault/env and restrict access by source IP
This commit is contained in:
Jeremie Fraeys 2026-01-20 17:13:55 -05:00
parent 9e7b51b69a
commit a22381492e
No known key found for this signature in database
2 changed files with 98 additions and 0 deletions

View file

@ -0,0 +1,6 @@
---
service_ssh_user: infra_controller
service_ssh_allowed_host: web
service_ssh_allowed_ip: ""
service_ssh_register_key: ""
service_ssh_deregister_key: ""

View file

@ -0,0 +1,92 @@
---
- name: Compute service SSH allowed IP
set_fact:
service_ssh_allowed_ip_effective: >-
{{
(service_ssh_allowed_ip | default('', true))
if (service_ssh_allowed_ip | default('', true) | length) > 0
else (hostvars[service_ssh_allowed_host].public_ipv4
| default(hostvars[service_ssh_allowed_host].ansible_host, true))
}}
- name: Compute service SSH register public key
set_fact:
service_ssh_register_key_effective: >-
{{
(service_ssh_register_key | default('', true))
if (service_ssh_register_key | default('', true) | length) > 0
else (
SERVICE_SSH_REGISTER_PUBLIC_KEY
| default(lookup('env', 'SERVICE_SSH_REGISTER_PUBLIC_KEY'), true)
)
}}
no_log: true
- name: Compute service SSH deregister public key
set_fact:
service_ssh_deregister_key_effective: >-
{{
(service_ssh_deregister_key | default('', true))
if (service_ssh_deregister_key | default('', true) | length) > 0
else (
SERVICE_SSH_DEREGISTER_PUBLIC_KEY
| default(lookup('env', 'SERVICE_SSH_DEREGISTER_PUBLIC_KEY'), true)
)
}}
no_log: true
- name: Fail if service SSH register public key is missing
fail:
msg: "SERVICE_SSH_REGISTER_PUBLIC_KEY is required (must be an SSH public key like 'ssh-ed25519 AAAA...')"
when: service_ssh_register_key_effective | length == 0
- name: Fail if service SSH deregister public key is missing
fail:
msg: "SERVICE_SSH_DEREGISTER_PUBLIC_KEY is required (must be an SSH public key like 'ssh-ed25519 AAAA...')"
when: service_ssh_deregister_key_effective | length == 0
- name: Fail if service SSH register public key does not look like an SSH key
fail:
msg: "SERVICE_SSH_REGISTER_PUBLIC_KEY does not look like an SSH public key"
when: not (service_ssh_register_key_effective is match('^ssh-'))
- name: Fail if service SSH deregister public key does not look like an SSH key
fail:
msg: "SERVICE_SSH_DEREGISTER_PUBLIC_KEY does not look like an SSH public key"
when: not (service_ssh_deregister_key_effective is match('^ssh-'))
- name: Fail if service SSH allowed host/IP cannot be determined
fail:
msg: "Unable to determine service SSH allowed IP (set service_ssh_allowed_ip or ensure hostvars[{{ service_ssh_allowed_host }}] has public_ipv4/ansible_host)"
when: service_ssh_allowed_ip_effective | length == 0
- name: Ensure service SSH user exists
user:
name: "{{ service_ssh_user }}"
state: present
create_home: true
shell: /bin/bash
- name: Ensure .ssh directory exists
file:
path: "/home/{{ service_ssh_user }}/.ssh"
state: directory
owner: "{{ service_ssh_user }}"
group: "{{ service_ssh_user }}"
mode: "0700"
- name: Install restricted authorized key for register
authorized_key:
user: "{{ service_ssh_user }}"
state: present
key: "{{ service_ssh_register_key_effective }}"
key_options: >-
command="/usr/local/sbin/infra-register-stdin",from="{{ service_ssh_allowed_ip_effective }}",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding
- name: Install restricted authorized key for deregister
authorized_key:
user: "{{ service_ssh_user }}"
state: present
key: "{{ service_ssh_deregister_key_effective }}"
key_options: >-
command="/usr/local/sbin/infra-deregister",from="{{ service_ssh_allowed_ip_effective }}",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding