add keyserver ansible playbook to deploy oob keyserver [ci skip]

This commit is contained in:
Viktor Barzin 2025-11-29 11:38:32 +00:00
parent 480b3e748d
commit 8dc04de0da
No known key found for this signature in database
GPG key ID: 4056458DBDBF8863
4 changed files with 230 additions and 0 deletions

View file

@ -0,0 +1,155 @@
# @nocommit: job to periodically update the certs
---
- name: Deploy Nginx-based key server for TrueNAS unlock
hosts: keyserver
become: true
vars:
server_name: "keyserver.viktorbarzin.me"
key_filename: "truenas.key"
htpasswd_user: "truenas"
htpasswd_password: "EcDZgBnUtGM09qiUXts81HjHybM" # replace with vault
ssl_cert_path: "/etc/ssl/certs/keyserver.crt"
ssl_key_path: "/etc/ssl/private/keyserver.key"
local_ssl_cert: "../../../secrets/fullchain.pem" # LOCAL path
local_ssl_key: "../../../secrets/privkey.pem" # LOCAL path
tasks:
- name: Install packages
apt:
name:
- nginx
- apache2-utils
- python3-passlib
state: present
update_cache: yes
- name: Create basic-auth file
community.general.htpasswd:
path: /etc/nginx/.htpasswd
name: "{{ htpasswd_user }}"
password: "{{ htpasswd_password }}"
crypt_scheme: bcrypt
- name: Create key directory
file:
path: /srv/keys
state: directory
owner: root
group: root
mode: '0755'
- name: Create key file if it doesn't exist
command: "head -c 128 /dev/urandom > /srv/keys/{{ key_filename }}"
args:
creates: "/srv/keys/{{ key_filename }}"
- name: Set key file permissions
file:
path: "/srv/keys/{{ key_filename }}"
owner: www-data
group: www-data
mode: '0640'
- name: Enable info logging in nginx.conf
lineinfile:
path: /etc/nginx/nginx.conf
regexp: '^(\s*)error_log'
line: ' error_log /var/log/nginx/error.log info;'
insertafter: 'http {'
notify: reload nginx
- name: Ensure rate limit config exists
copy:
dest: /etc/nginx/conf.d/ratelimit.conf
content: |
limit_req_zone $binary_remote_addr zone=authfail:10m rate=5r/m;
notify: reload nginx
- name: Deploy keyserver nginx site
copy:
dest: /etc/nginx/sites-available/keyserver.conf
content: |
server {
listen 443 ssl;
server_name {{ server_name }};
ssl_certificate {{ ssl_cert_path }};
ssl_certificate_key {{ ssl_key_path }};
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
limit_req zone=authfail burst=2 nodelay;
location /keys/ {
alias /srv/keys/;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
autoindex off;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
}
}
notify: reload nginx
- name: Enable keyserver site
file:
src: /etc/nginx/sites-available/keyserver.conf
dest: /etc/nginx/sites-enabled/keyserver.conf
state: link
notify: reload nginx
- name: Remove default site
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: reload nginx
- name: Copy SSL certificate to server
copy:
src: "{{ local_ssl_cert }}"
dest: "{{ ssl_cert_path }}"
owner: root
group: root
mode: '0644'
notify: reload nginx
- name: Copy SSL private key to server
copy:
src: "{{ local_ssl_key }}"
dest: "{{ ssl_key_path }}"
owner: root
group: root
mode: '0644'
notify: reload nginx
# - name: Create self-signed SSL certificate if missing
# command: >
# openssl req -x509 -newkey rsa:2048 -nodes
# -keyout {{ ssl_key_path }}
# -out {{ ssl_cert_path }}
# -days 365
# -subj "/CN={{ server_name }}"
# args:
# creates: "{{ ssl_cert_path }}"
notify: reload nginx
- name: Test nginx config
command: nginx -t
register: nginx_test
failed_when: "'successful' not in nginx_test.stderr"
- name: Ensure nginx is running
service:
name: nginx
state: started
enabled: true
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded

View file

@ -0,0 +1,73 @@
This contains the setup for setting up a remote machine that serves a keyfile for decrypting a luks volume
1. Install nginx
```
sudo apt update
sudo apt install nginx apache2-utils -y
```
2. Create User for basic auth
```
sudo htpasswd -c /etc/nginx/.htpasswd truenas
```
3. Create secure directory and key file
```
sudo mkdir -p /srv/keys
head -c 128 /dev/urandom | sudo tee /srv/keys/truenas.key >/dev/null
```
4. Create rate limit zone
```
# /etc/nginx/conf.d/ratelimit.conf
# Allow only 3 key requests per minute per IP
limit_req_zone $binary_remote_addr zone=keylimit:10m rate=3r/m;
```
5. Configure nginx virtual host
```
# /etc/nginx/sites-available/keyserver.conf
server {
listen 443 ssl;
server_name <ip address here>;
# TLS certificate and key (we will set these in the next step)
ssl_certificate /etc/ssl/certs/keyserver.crt;
ssl_certificate_key /etc/ssl/private/keyserver.key;
# Enforce strong TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Rate limiting zone created earlier
limit_req zone=keylimit burst=2 nodelay;
location /keys/ {
alias /srv/keys/;
# Basic auth
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
# Disable directory listing
autoindex off;
# Prevent caching
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
}
}
```
6. Enable the host:
```
sudo ln -s /etc/nginx/sites-available/keyserver.conf /etc/nginx/sites-enabled/
```
7. Disable default host:
```
sudo rm /etc/nginx/sites-enabled/default
```

View file

@ -0,0 +1,2 @@
[keyserver]
130.162.165.220 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_ed25519

Binary file not shown.