This episode summarizes hardening practices for remote access: strong passwords and non-default ports, SSH-only exposure, fail2ban for VNC/RDP ports, TCP wrappers as a legacy defense, and connection log monitoring and access auditing with journalctl.

You now have working VNC and RDP servers, complete with authentication, encryption, and tunnels. Episode 16 brings it all together into a complete defense posture. Hardening isn't one magic command — it's a series of small decisions that, combined, make your server far harder to compromise.
This episode covers five areas: strong passwords and non-default ports, SSH-only exposure, fail2ban for VNC/RDP ports, TCP wrappers, and access monitoring and auditing. By the end of the episode, you'll have a checklist you can apply directly to a production server.
Default ports make it easy for attackers to scan quickly. Changing the port won't stop a determined attacker, but it removes thousands of automated attempts. For xrdp, change it in /etc/xrdp/xrdp.ini:
[Globals]
port=3390For x11vnc, use -autoport with a port range, or specify an explicit port:
x11vnc -display :0 -rfbauth /etc/x11vnc.pass -rfbport 5907The x11vnc -rfbport 5907 command moves the server to port 5907. Remember: changing the port isn't security in itself, but obscurity — it still must be combined with the other layers.
Change passwords periodically, never reuse a password for other services, and make sure server users don't use weak passwords. Remember the VNC 8-character limit from episode 12: for VNC, transport encryption is what really protects you.
The safest pattern, built since episode 14: never expose VNC/RDP ports to the internet. Close those ports in the firewall, leave only SSH open, and access remote services through a tunnel.
sudo ufw deny 5900/tcp
sudo ufw deny 3389/tcp
sudo ufw allow OpenSSH
sudo ufw status verboseThe ufw deny 5900/tcp and ufw deny 3389/tcp commands close the VNC and RDP ports from the outside network, while ufw allow OpenSSH keeps the tunnel path open. From the user's side, access is done with ssh -L and then a viewer to the local port — a pattern that doesn't change how the server works at all.
Tip
Test the firewall's correctness from another machine, not from the server itself. nc -zv <server-ip> 5900 should fail, while nc -zv <server-ip> 22 should succeed. If both are open, there's a wrong firewall rule.
fail2ban monitors logs, counts failed login attempts, and blocks attacking IPs. For services that use their own logfile, create a filter and jail. Create /etc/fail2ban/filter.d/x11vnc.conf:
[Definition]
failregex = ^.*Client connection from <HOST>.*failed.*$
ignoreregex =Then enable the jail in /etc/fail2ban/jail.local:
[x11vnc]
enabled = true
filter = x11vnc
logpath = /var/log/x11vnc.log
maxretry = 3
bantime = 3600Make sure x11vnc writes logs to that file with -logfile:
x11vnc -display :0 -rfbauth /etc/x11vnc.pass -logfile /var/log/x11vnc.log -foreverThe x11vnc -logfile /var/log/x11vnc.log command directs authentication logs to the file fail2ban monitors. Reload fail2ban and check the jail status:
sudo systemctl reload fail2ban
sudo fail2ban-client status x11vncFor RDP tunneled through SSH, fail2ban's built-in sshd jail is sufficient — attackers will never touch port 3389.
Some older services support TCP wrappers via /etc/hosts.allow and /etc/hosts.deny:
sshd : 192.168.1.0/24 : allow
sshd : ALL : denyBe aware: TCP wrappers (libwrap) are deprecated, and many modern distributions no longer compile them into OpenSSH. If your distribution doesn't support them, replace them with modern mechanisms like AllowUsers rules in sshd_config or firewall rules. The principle is the same: only certain machines are allowed in.
Monitoring is half of security. Record who logs in, when, and from where. For systemd services, everything is available in the journal:
journalctl -u x11vnc.service -f
journalctl -u xrdp.service --since todayThe journalctl -u x11vnc.service -f command displays logs live, and journalctl -u xrdp.service --since today shows today's activity. Get in the habit of checking these logs after configuration changes or when there's suspicious activity.
To check who's currently connected to your remote services:
ss -tnp | grep -E ":(5900|3389)"ss -tnp | grep -E ":(5900|3389)" shows active TCP connections to the VNC/RDP ports along with the process and source address. Combine this with a regular log review schedule to detect unusual access patterns early.
Episode 16 brought together the hardening practices: changing default ports, ensuring SSH-only exposure, protecting VNC/RDP ports with fail2ban, understanding TCP wrappers' limitations, and monitoring and auditing access through journalctl and ss.
Key takeaways:
journalctl -u <service> is the main window for monitoring access.ss -tnp shows active connections to remote service ports.In the next episode, episode 17, we cover the architectural topic that determines VNC's future: X11 versus Wayland — why classic VNC is limited on Wayland, and how GNOME Remote Desktop, w0vncserver, and KDE krfb become the bridge. See you there!