This project demonstrates how to harden SSH access on a 32‑bit Alpine Linux system.
It was developed on an Asus Eee PC 4G (32‑bit), used for monitoring purposes, with access restricted to a single user via SSH key authentication.
After installing Alpine Linux using the initial setup-alpine wizard, the system starts with a basic /etc/passwd layout like:
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
user:x:1000:1000:user:/home/user:/bin/sh
The goal is to harden SSH so that:
- Root login is disabled.
- Password authentication is disabled.
- Only the
useraccount can log in via SSH key.
After setup-alpine, install required packages:
apk add sudo
apk add python3These are needed for Ansible to connect and manage the system.
The Alpine node must be configured with a static private IP (e.g. 192.168.1.31). This ensures Ansible can consistently reach the host.
If your Alpine node uses a different IP, update the following files:
hosts.ini-> changeansible_host=192.168.1.31to your node’s IP.tests/test_ssh_hardening.sh-> updateHOST="192.168.1.31"to match your node’s IP.
Install Ansible and SSH utilities:
dnf install ansible-core
dnf install openssh-clients # provides ssh, ssh-keygen, ssh-copy-idGenerate and copy your SSH key to the Alpine host:
ssh-keygen -t ed25519
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@<ALPINE_NODE_IP>Test login:
ssh user@<ALPINE_NODE_IP>.
├── ansible.cfg
├── hosts.ini
├── playbooks
│ └── ssh_hardening.yml
├── roles
│ └── ssh_hardening
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
└── tests
└── test_ssh_hardening.sh
ansible.cfg-> points to inventory and roles path.hosts.ini-> defines the Alpine host and connection details.playbooks/ssh_hardening.yml-> applies the hardening role.roles/ssh_hardening/tasks/main.yml-> disables root login, password authentication, and restricts users.roles/ssh_hardening/handlers/main.yml-> restarts SSH after changes.tests/test_ssh_hardening.sh-> Bash script to verify hardening.
- Run the playbook:
ansible-playbook playbooks/ssh_hardening.yml- Verify with the test script:
bash tests/test_ssh_hardening.shExpected output:
[TEST] User 'user' login with key (should succeed)
[INFO] pass
[TEST] User 'user' login with password (should fail)
[INFO] pass
[TEST] User 'root' login with password (should fail)
[INFO] pass
[TEST] User 'guest' login with password (should fail)
[INFO] pass
- Defense in depth: multiple SSH restrictions applied.
- Minimal attack surface: only one non‑root account (
user) can log in, and only with a key. - Lightweight: designed for 32‑bit Alpine on legacy hardware.
- This project assumes a fresh Alpine install via
setup-alpine. - Tested on an Asus Eee PC 4G (32‑bit).
- Intended for monitoring setups where only one trusted node manager connects.
- If your Alpine node uses a different IP, update both
hosts.iniandtests/test_ssh_hardening.sh.
MIT License - feel free to adapt and extend.
Ty for reading me!
Muchas gracias por leerme!
Moitas por lerme!