[P1] SSH root login — harden with dedicated keypair and from= restriction #1

Open
opened 2026-03-22 18:04:11 +00:00 by jeet · 0 comments
Owner

Problem

inventory.yml uses ansible_user: root with a shared personal key (id_rsa). UniFi OS only exposes root over SSH so the user cannot be changed, but the key exposure can be significantly hardened.

Steps

1. Generate a dedicated keypair just for this automation:

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_unifi -C "ansible-unifi" -N ""

2. Restrict the key in /root/.ssh/authorized_keys on the UDMP:

from="192.168.1.X" ssh-ed25519 AAAA...your-new-key... ansible-unifi

Replace 192.168.1.X with your Ansible machine LAN IP. Key is useless from any other source IP.

3. Update inventory.yml:

ansible_ssh_private_key_file: ~/.ssh/id_ed25519_unifi

4. Update playbooks/config-nextdns.yml:
Add become: false — already root, escalation behaves unexpectedly on UniFi OS.

Note: Firmware upgrades wipe /root/.ssh/authorized_keys. Re-running the setup after upgrades is expected and is the whole reason this playbook exists.

Files: inventory.yml, playbooks/config-nextdns.yml

## Problem `inventory.yml` uses `ansible_user: root` with a shared personal key (`id_rsa`). UniFi OS only exposes root over SSH so the user cannot be changed, but the key exposure can be significantly hardened. ## Steps **1. Generate a dedicated keypair just for this automation:** ```bash ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_unifi -C "ansible-unifi" -N "" ``` **2. Restrict the key in `/root/.ssh/authorized_keys` on the UDMP:** ``` from="192.168.1.X" ssh-ed25519 AAAA...your-new-key... ansible-unifi ``` Replace `192.168.1.X` with your Ansible machine LAN IP. Key is useless from any other source IP. **3. Update `inventory.yml`:** ```yaml ansible_ssh_private_key_file: ~/.ssh/id_ed25519_unifi ``` **4. Update `playbooks/config-nextdns.yml`:** Add `become: false` — already root, escalation behaves unexpectedly on UniFi OS. > Note: Firmware upgrades wipe `/root/.ssh/authorized_keys`. Re-running the setup after upgrades is expected and is the whole reason this playbook exists. **Files:** `inventory.yml`, `playbooks/config-nextdns.yml`
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jeet/Unifi-NextDNS#1