Before you start
Environment: Ubuntu Server 24.04 LTS VM with OpenSSH, UFW, sudo access, and a working provider or VM console. Commands use Bash. Other distributions use different service names and firewall tools.
Take a VM snapshot. Keep your current SSH session open and test console access before changing authentication or firewall rules. Use a disposable VM for your first attempt.
Commands run in your own terminal. This website cannot inspect or secure your environment.
Inspect · no configuration change
1. Find the services you expose
An unused listening service is another entry point to maintain. Start with an inventory before deciding which ports belong on the internet.
cat /etc/os-release
sudo ss -lntup
sudo ufw status verbose
systemctl --failedWhat to check
Map each listening address and port to an owner and purpose. A listener on 0.0.0.0 or [::] needs an explicit exposure decision; a firewall may still block it.
Try it deliberately
Write down the administrative port, application ports, source networks, and recovery contact. Check cloud firewall rules as well as the host firewall.
Recovery & cleanup
These commands only inspect state. Do not stop unfamiliar services until you know what depends on them.
Official guidance: Ubuntu security guidance ↗
Change · authentication
2. Prove key access before disabling passwords
A key-only login reduces password-based attacks, but a syntactically valid setting can still lock out the administrator.
# On your workstation: replace admin and SERVER_IP
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no admin@SERVER_IP
# On the server, inspect effective settings first
sudo sshd -T | grep -E "^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin|pubkeyauthentication) "
sudoedit /etc/ssh/sshd_config.d/00-opsrung-lab.confPubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin nosudo sshd -t && sudo systemctl reload ssh.service
sudo sshd -T | grep -E "^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin) "What to check
The syntax check exits successfully; the effective values are no. From a second terminal, repeat the key-only login and run sudo -v. Keep the first session open until both succeed.
Try it deliberately
Check Include order and Match blocks: sshd uses the first applicable value, so a later snippet may not override earlier settings. Use sshd -T -C with the real user/address for Match rules. Do not disable keyboard-interactive authentication on an MFA system without adapting its policy.
Recovery & cleanup
From the still-open session or console, remove only the new 00-opsrung-lab.conf snippet, run sudo sshd -t, then reload ssh.service. If the file already exists, back it up and use another filename rather than overwriting it.
Official guidance: Ubuntu OpenSSH configuration ↗
Change · network access
3. Allow administration before enabling the firewall
A default-deny policy is useful only when legitimate administration and application traffic still work.
# Example only: replace the documentation address with YOUR trusted admin IP.
# Confirm the SSH port first; this example assumes TCP 22.
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw show added
# Enable only after reviewing all required application and monitoring rules.
sudo ufw enable
sudo ufw status numberedWhat to check
A second SSH connection from the allowed address succeeds. Test application access from both an allowed source and a blocked source. Review IPv6 and the cloud firewall too.
Try it deliberately
On this practice VM, add only the application ports you actually need before enabling. Docker-published ports interact with firewall forwarding rules: UFW alone is not proof that those ports are blocked.
Recovery & cleanup
Record the previous UFW state and rules first. If this lab enabled a previously inactive firewall, use the console to run sudo ufw disable to recover access. If it was already active, restore its prior rules instead of disabling protection.
Official guidance: Ubuntu firewall guide ↗ · Docker firewall interactions ↗
Inspect · update policy
4. Make updates and recovery routine
A patch policy needs an owner, a maintenance window, and a tested restore path.
apt list --upgradable
systemctl list-timers apt-daily-upgrade.timer
sudo unattended-upgrade --dry-run --debug
test ! -f /var/run/reboot-required || cat /var/run/reboot-requiredWhat to check
Review the proposed updates and allowed origins. A timer alone does not prove updates installed; inspect /var/log/unattended-upgrades/ and record any reboot requirement. The dry run needs unattended-upgrades installed.
Try it deliberately
Schedule a reviewed update on the VM, check your service afterward, and restore a backup into a separate VM. Record recovery time and confirm the restored data is usable. Never put real credentials in the exercise notes.
Recovery & cleanup
A package downgrade is not a universal rollback. Keep a tested snapshot or rebuild-and-restore procedure and protect backups separately from the server.
Official guidance: Ubuntu automatic updates ↗
Reviewed 31 October 2026. Adapt to your installed versions and environment; these guides cover selected controls, not a compliance certification.