Spiral Two: Secure remote access
The goal of Spiral 2 is to prepare Piawake for exposure to the Internet. This includes hardening the operating system, reducing the attack surface, and creating a secure method of remote access over SSH.
Overview
- Configuration
- Change Hostname
- Configure Router
- Hardening
- Update and Establish a Trusted Software Source
- Harden SSH
- Disable Password Authentication and Root Login
- Configure the Firewall
- Install Fail2ban
- Reduce the Attack Surface
- Secure VNC
- Resilience
- Hardware Watchdog
- Persistent System Logs
-
Audit
- Test SSH Tunnel on Local Network
- Test SSH Tunnel on Other Networks
The sections are organized by topic rather than implementation order.
Configuration
This section covers the initial system and network steps I took to establish the infrastructure for secure remote access.
System
Change the Hostname
Since the Project was developing I wanted to call the first connection point pi@piawake
The pi had a nice TUI to change settings:
![]()
Network
Configure the Router
I did this step after hardening the piawake.
Port forwarding
On the router I added a port forwarding ruleI made sure to pick a random port that is not common or coliding with other ports. These are the things I configured.
- Active: Enable
- Name: can be anything
- Start and endpoint external Port: a random numbered port.
- Internal (translation) port: the Raspberry Pi SSH port (22 is default it's a good idea to change it).
- Server IP address: the static IP address assigned to the Raspberry Pi.
Static DHCP reservation
I created a static DHCP reservation for the Raspberry Pi. This binds the Pi's MAC address to a fixed IP address, ensuring it always receives the same local IP address from the DHCP server.
The flow looks like this after doing this <public IP> => <external port> => <Pi local IP> => <SSH port>
Hardening
This section goes trough the security measures implemented to reduce the system's attack surface and protect against unauthorized access.
System
Update and establish a trusted software source
First, I updated the operating system and all installed APT packages:
To reduce the attack surface, this project will only use software installed through the APT package manager. The following will not be used:
- Flatpak applications
- Snap packages
- Docker containers
- Software compiled from source
- Software installed from GitHub releases or tarballs
Enable automatic security updates
unattended-upgrades automatically installs security updates released through the APT repositories.
Install:
enable it:
A text-based configuration dialog (TUI) will appear. I Selected Yes to enable automatic security updates.

Authentication
Harden SSH
I was connecting with ssh to the pi but with a password that was "1234" not so safe.
On my laptop I created a dedicated key:
Explanation:
-t ed25519→ modern, recommended key type.-a 100→ increases the key derivation work factor for better passphrase protection.
For a real system, I would protect the private key with a passphrase. I skipped it here to keep the demonstration simple.
Next step is to copy it to the pi.
Then I tested the connection using only that key. The account password should no longer be required, only the SSH key passphrase if one was set.
quality of life improvements
Instead of typing -i every time, I added a entry to my local ~/.ssh/config:
Now I can simply connect with ssh piawake
Disable assword authentication & No Root login
Now it's important to do this so I don't accidentally lock my self out so I followed these steps:
a) Verify the SSH key works
Don't close this existing SSH session until everything is confirmed.
b) Edit the SSH configuration
Find (or add) these lines:
c) test the configuration:
If the command produces no output, the configuration is valid and safe to restart the ssh.
d) Test the connection in another terminal window without closing current session:
This should now work I also tested to see that the password was disabled:
Password authentication still worked. After checking the effective SSH configuration, I discovered that 50-cloud-init.conf was overriding my settings.
This highlighted the importance of checking the effective SSH configuration rather than assuming changes to sshd_config are the final settings.
change to no:
I then restarded the ssh and I could use grep to check it:
sudo sshd -T | grep -E 'passwordauthentication|kbdinteractiveauthentication|usepam|permitrootlogin|pubkeyauthentication'
I confirmed the hardening was successful by testing both authentication methods:
- SSH key authentication succeeded.
- Password authentication was denied with: "Permission denied (publickey)."
Network
Configure the Firewall
Next, I configured the firewall to allow only SSH connections.
Install UFW:
Allow only SSH:
Verify the configuration:
Result:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
This means all incoming connections are blocked by default except SSH. VNC will later be accessed through an SSH tunnel, so no additional ports need to be opened.
Install Fail2ban
Next I setup Fail2ban it's a intrusion prevention software that automatically blocks IP addresses after repeated failed authentication attempts.
Install:
Enable it:
This blocks repeated failed login attempts.
Reduce the Attack Surface
Check what is listening:
Every listening service represents another potential entry point, so unnecessary services should either be removed or restricted. This is what I will keep,restrict and disable:
- Keep
- SSH (22/tcp): Remote access.
- **Restrict **
- WayVNC (5900/tcp): bind it to 127.0.0.1 only accessible through an SSH tunnel.
- Disable
- rpcbind (111/tcp and 111/udp): NFS/RPC services.
- Avahi (5353/udp): .local hostname discovery.
Disable rpcbind and Avahi
sudo systemctl disable --now rpcbind
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now rpcbind.socket
sudo systemctl disable --now avahi-daemon.socket
Restrict WayVNC
First I checked how it was started with:
I saw that there was a config file:
I inspected the file and changed the address line:
Then restart WayVNC:
Verify:
The listening services were much cleaner and easier to keep track of. The only externally reachable service is SSH. The goal is to access the graphical desktop by tunneling the VNC connection through SSH.
Resilience
This section focuses on improving system reliability and ensuring continued operation and recovery in the event of failures.
Reliability
Hardware Watchdog
Install:
Enable the hardware watchdog:
Verify the watchdog :
That confired:
- That ehe BCM2835 hardware watchdog is detected.
- systemd is using the hardware watchdog.
/dev/watchdog0is active.- If the kernel or userspace stops kicking the watchdog for about 60 seconds, the Pi will automatically reboot.
Persistent System Logs
By default, Raspberry Pi OS stores system logs in RAM, causing them to be lost after a reboot. Enabling persistent logging stores the logs on disk instead, making it easier to troubleshoot issues and investigate crashes or system freezes after the device comes back online.
Create the journal directory:
Restart systemd-journald and flush the logs to enable persistent storage:
Verify that the logs are stored on disk:
Example output:
Audit
This section verifies that the implemented security measures function as intended through testing and validation.
Verification
Test ssh tunnel on local network
I've never done ssh tunnel before so before I open the pi to the internet I tested it out I had restikted the VNC. I tried to conect like I would do normaly and it was closed.

Test the ssh tunnel on other networks.
I tested it on other networks and it worked there as well.
Troubleshooting
Good commands
- Pi Temperature monitoring:
- Pi Power protection:
- Monitor memory :
-
Check journar logs:
-
Check the previous boot:
-
bash sudo journalctl -b -1 -e --no-pager -
Previous boot, kernel messages only:
-
bash sudo journalctl -b -1 -k --no-pager -
List all recorded boots:
-
bash sudo journalctl --list-boots
Piawake freezing
Piawake would occasionally freeze, making it difficult to diagnose because it happened randomly. After enabling persistent system logs, I was able to investigate the previous boot and look for clues.
Test 1: Disable Wi-Fi power saving
I found this in the system log:
To check whether Wi-Fi power saving was enabled, I ran:
Since the piawake is used as an always-on remotly, I disabled Wi-Fi power saving as a test:
To make it perminite:
Restart or reboot:
The system will now be monitored to determine whether disabling Wi-Fi power saving prevents the random freezes.