Key Takeaways
- Harden Ubuntu 24.04 for sovereign production with CIS Benchmark controls, AppArmor policy hardening, auditd event logging, SSH + login security, kernel tuning, and file system protections.
- This guide includes local-first commands, expected output, example AppArmor profiles for
nginxandpostgresql, and a compliance checklist for air-gapped or vendor-free environments. - SovereignScore: 96/100 — local tooling, open-source, no cloud telemetry required, and explicit recommendations for minimizing attacker surface on Ubuntu nodes.
Direct Answer: Harden Ubuntu 24.04 by applying CIS Benchmark controls for accounts, SSH, auditing, and file permissions; enable AppArmor with custom profiles for nginx and postgresql; configure auditd to log security events locally; lock down SSH and console access; and use kernel and filesystem hardening to protect local data and services.
This article provides a full step-by-step implementation tailored for sovereign server deployments with local-only security tooling and verifiable audit outputs.
Why Ubuntu 24.04 Hardening Matters for Sovereign Deployments
Ubuntu 24.04 LTS is a popular server platform for sovereign applications because it is stable, widely supported, and compatible with local hardware and virtualization. Hardening that platform means:
- reducing the attack surface on local nodes
- enforcing least privilege for services and users
- logging security events to local, auditable stores
- removing default or unnecessary services that increase risk
- applying AppArmor policies to contain compromised software
A hardened Ubuntu server is the foundation for a sovereign stack where data and operations remain under your control.
What This Guide Covers
- Ubuntu 24.04 hardening baseline for CIS Benchmark and AppArmor
- Package and service minimization with local tools
- AppArmor profile creation for
nginxandpostgresql auditdpolicy, file integrity, and login monitoring- SSH hardening, account policy, and scheduled maintenance
- Local kernel and filesystem protections
- Compliance checklist and troubleshooting patterns
1. Hardening Baseline: Start with Clean, Minimal Ubuntu
The first step is a minimal Ubuntu 24.04 install with only required packages.
Initial package cleanup
sudo apt update
sudo apt upgrade -y
sudo apt purge -y snapd lxd lxd-client cloud-init
sudo apt autoremove -y
Expected output:
Reading package lists... Done
Building dependency tree... Done
The following packages will be REMOVED:
cloud-init lxd lxd-client snapd
Removals like snapd and cloud-init reduce extra package surfaces and align with local-first sovereignty.
Disable unused network services
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now unattended-upgrades
sudo systemctl disable --now snapd.socket
sudo systemctl disable --now rpcbind
This ensures only the services you explicitly deploy are running.
2. CIS Benchmark Implementation for Ubuntu 24.04
The CIS Benchmark is the de facto local security baseline for Linux servers. We implement the most relevant controls for a sovereign Ubuntu node.
2.1 Account and password policies
Enforce local password complexity and lockout rules.
sudo apt install -y libpam-pwquality auditd
Update /etc/security/pwquality.conf:
minlen = 14
minclass = 4
maxrepeat = 3
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
Update /etc/pam.d/common-password:
auth required pam_pwquality.so retry=3
password required pam_pwhistory.so remember=24 use_authtok
password required pam_unix.so obscure sha512
This enforces strong local passwords and prevents reuse.
2.2 Lock inactive accounts
sudo usermod -L root
sudo usermod -L ubuntu
Verify locked accounts:
sudo passwd -S root ubuntu
Expected output:
root LK 2024-01-01 0 99999 7 -1 (Password locked.)
ubuntu LK 2024-01-01 0 99999 7 -1 (Password locked.)
2.3 Remove inactive users and groups
sudo deluser --remove-home guest
sudo delgroup --only-unused nogroup
2.4 Audit sudoers and user rights
Use visudo to enforce requiretty and command restrictions.
Defaults !visiblepw
Defaults logfile="/var/log/sudo.log"
Defaults log_input, log_output
Defaults timestamp_timeout=0
root ALL=(ALL) ALL
admin ALL=(ALL) NOPASSWD: /usr/bin/systemctl status nginx
This keeps all privilege elevations local and logged.
3. SSH and Remote Access Hardening
SSH is the most common vector for remote compromise. Harden it aggressively while preserving legitimate remote administration.
3.1 Install and secure OpenSSH
sudo apt install -y openssh-server
sudo systemctl enable --now ssh
3.2 Harden /etc/ssh/sshd_config
Update SSH config:
Port 22
AddressFamily inet
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
UsePAM yes
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 2
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
ClientAliveInterval 300
ClientAliveCountMax 2
Restart SSH: sudo systemctl restart ssh
3.3 Use key-based authentication only
Create a local admin key for the operator.
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "ubuntu-admin"
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Verify the key works and disable password login.
3.4 Allow only specific admin users
Add this to /etc/ssh/sshd_config:
AllowUsers ubuntu-admin
This ensures only named local accounts can connect.
3.5 Configure fail2ban for brute force protection
sudo apt install -y fail2ban
sudo tee /etc/fail2ban/jail.d/sshd.local <<'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600
EOF
sudo systemctl enable --now fail2ban
Check status:
sudo fail2ban-client status sshd
This protects local SSH access without requiring cloud rate-limiting.
4. AppArmor Hardening for Local Services
AppArmor is Ubuntu’s mandatory access control framework for local process confinement. We enable it globally and create targeted profiles.
4.1 Enable and audit AppArmor
sudo apt install -y apparmor apparmor-utils
sudo systemctl enable --now apparmor
sudo aa-status
Expected AppArmor status should show profiles loaded and in enforce mode.
4.2 Use AppArmor utilities
Inspect profile status:
sudo aa-status --enabled
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
If a profile is in complain mode, fix violations and switch to enforce.
4.3 AppArmor profile for nginx
Create /etc/apparmor.d/usr.sbin.nginx with the following content:
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/apache2-common>
/usr/sbin/nginx ix,
/etc/nginx/** r,
/var/www/** r,
/var/log/nginx/** rw,
/var/lib/nginx/** rw,
/etc/ssl/** r,
/run/nginx.pid w,
/var/run/nginx.sock w,
network inet stream,
capability net_bind_service,
capability setgid,
capability setuid,
deny /** mrwklx,
}
Load and enforce it:
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
4.4 AppArmor profile for postgresql
Create /etc/apparmor.d/usr.postgresql:
#include <tunables/global>
/usr/lib/postgresql/** {
#include <abstractions/base>
/usr/lib/postgresql/** rm,
/etc/postgresql/** r,
/var/lib/postgresql/** rwk,
/var/log/postgresql/** rw,
/run/postgresql/** rw,
/var/run/postgresql/** rw,
/tmp/** rw,
capability net_bind_service,
deny /** mrwklx,
}
Load and enforce:
sudo apparmor_parser -r /etc/apparmor.d/usr.postgresql
sudo aa-enforce /etc/apparmor.d/usr.postgresql
4.5 AppArmor troubleshooting
If a service fails after profile enforcement:
sudo dmesg | grep apparmor
sudo journalctl -u nginx -e
sudo aa-logprof
aa-logprof helps convert audit denials into profile allowances securely. Always prefer minimal privileges.
5. Auditd and Local Event Logging
The local audit subsystem is the authoritative record for security events on sovereign systems.
5.1 Install and enable auditd
sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
5.2 Harden audit configuration
Edit /etc/audit/auditd.conf:
audit_log = /var/log/audit/audit.log
action_mail_acct = root
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SUSPEND
max_log_file = 30
auditd_plugins = /etc/audit/plugins.d
Reload auditd:
sudo systemctl restart auditd
5.3 Define audit rules
Add rules in /etc/audit/rules.d/99-vucense.rules:
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k privilege
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /var/log/auth.log -p wa -k authlog
-a always,exit -F arch=b64 -S execve -k exec
-a always,exit -F arch=b64 -S execveat -k exec
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system
-a always,exit -F arch=b64 -S mount -S umount2 -k mounts
Reload rules:
sudo augenrules --load
sudo systemctl restart auditd
5.4 Validate audit rules
sudo auditctl -l
Expected output includes rules for /etc/passwd, /etc/ssh/sshd_config, and execve.
5.5 Local audit reporting
Generate a report from local audit logs:
sudo aureport -u -ts today
sudo aureport -f -ts today
sudo ausearch -k sshd_config -i
This gives you local evidence for changes and suspicious activity.
6. Filesystem and Kernel Hardening
A hardened Ubuntu server is also a hardened file system and kernel.
6.1 Mount options for protections
Add these mount options in /etc/fstab for critical mounts:
UUID=... / ext4 defaults,noexec,nodev,nosuid 0 1
UUID=... /tmp ext4 defaults,noexec,nodev,nosuid 0 2
UUID=... /var/log ext4 defaults,nodev,nosuid 0 2
For /tmp, add a systemd mount if using a tmpfs scratch area.
6.2 Disable unused filesystem features
Add these sysctl settings to /etc/sysctl.d/99-hardening.conf:
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.suid_dumpable = 0
kernel.yama.ptrace_scope = 1
kernel.sysrq = 0
Reload:
sudo sysctl --system
6.3 Harden core dumps
Disable core dumps with PAM and sysctl:
echo "* hard core 0" | sudo tee /etc/security/limits.d/99-nocoredump.conf
sudo sysctl -w fs.suid_dumpable=0
6.4 Enable address space layout randomization
Add to /etc/sysctl.d/99-hardening.conf:
kernel.randomize_va_space = 2
This protects local processes from memory corruption exploits.
6.5 Configure local network firewall
Use ufw for a simple stateful firewall.
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status verbose
For services like postgresql, restrict ports to localhost or specific trusted subnets.
7. Systemd and Service Hardening
Systemd is the service manager for Ubuntu. Hardening services with unit files reduces risk from compromised daemons.
7.1 Harden individual services
Add sandboxing directives to service units.
Example /etc/systemd/system/nginx.service.d/harden.conf:
[Service]
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=true
NoNewPrivileges=true
PrivateDevices=true
ReadOnlyPaths=/etc/nginx
ReadWritePaths=/var/log/nginx /var/lib/nginx
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Reload systemd and restart nginx:
sudo systemctl daemon-reload
sudo systemctl restart nginx
7.2 Limit user processes and memory
Use TasksMax and memory limits in service units:
[Service]
TasksMax=512
MemoryMax=512M
7.3 Ensure logging stays local
For services on sovereign nodes, do not forward logs to remote cloud platforms by default. Use journalctl and local file rotation.
Configure journald in /etc/systemd/journald.conf:
Storage=persistent
SystemMaxUse=200M
RuntimeMaxUse=50M
Compress=yes
Reload:
sudo systemctl restart systemd-journald
8. Service-Specific Hardening Patterns
This section walks through hardened configurations for common local services.
8.1 Harden nginx
Install and remove default site files.
sudo apt install -y nginx
sudo rm -f /etc/nginx/sites-enabled/default
Configure nginx for secure headers and TLS.
/etc/nginx/nginx.conf:
server_tokens off;
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;
Secure server block example:
server {
listen 443 ssl http2;
server_name example.local;
ssl_certificate /etc/ssl/localcerts/example.crt;
ssl_certificate_key /etc/ssl/localcerts/example.key;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "DENY";
add_header Referrer-Policy "no-referrer";
add_header X-XSS-Protection "1; mode=block";
root /var/www/html;
index index.html;
}
Use local certificates, ideally generated with openssl or mkcert, not cloud CA automation.
8.2 Harden postgresql
Install PostgreSQL and disable remote access by default.
sudo apt install -y postgresql postgresql-contrib
sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" /etc/postgresql/15/main/postgresql.conf
sudo tee /etc/postgresql/15/main/pg_hba.conf <<'EOF'
# local connections only
local all all scram-sha-256
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
EOF
sudo systemctl restart postgresql
Use SCRAM authentication and local socket connections.
8.3 Harden auditd and login monitoring
Use pam_tally2 or faillock to lock accounts after failed logins.
Update /etc/pam.d/common-auth:
auth required pam_faillock.so preauth silent deny=5 unlock_time=900 fail_interval=900
auth [default=die] pam_unix.so
auth sufficient pam_faillock.so authfail deny=5 unlock_time=900 fail_interval=900
This blocks brute force attempts on local accounts.
9. File Permission and Ownership Hardening
Proper ownership and file permissions are critical on local nodes.
9.1 Protect sensitive configuration files
sudo chown root:root /etc/ssh/sshd_config
sudo chmod 600 /etc/ssh/sshd_config
sudo chown root:root /etc/sudoers
sudo chmod 440 /etc/sudoers
9.2 Harden shell history and local secrets
For admin shells, disable history on sensitive commands.
echo 'export HISTFILE=/dev/null' | sudo tee -a /etc/profile.d/no_history.sh
Store application secrets in restricted directories:
sudo mkdir -p /etc/vucense/secrets
sudo chmod 700 /etc/vucense/secrets
sudo chown root:root /etc/vucense/secrets
9.3 Read-only mount for static config
Add a bind mount or read-only path for static application configuration.
Example in /etc/fstab:
/opt/vucense/config /etc/vucense/config none bind,ro 0 0
This prevents a compromised service from tampering with configuration.
10. Local Compliance and Governance for Ubuntu Nodes
A sovereign server should have evidence of its hardening state.
10.1 Create a local compliance checklist
Keep the checklist near the system documentation.
sshconfigured for key-only loginfail2banprotecting SSHauditdenabled with local rules- AppArmor profiles loaded in enforce mode
ufwor firewall policy activesysctlhardening appliedsudologging enabled- sensitive files locked down with correct permissions
10.2 Document local change control
Save changes to /var/local/vucense/hardening-changelog.md:
2026-05-22: Applied CIS account password and login policies.
2026-05-22: Added AppArmor profiles for nginx and postgresql.
2026-05-22: Enabled audit rules for /etc/ssh/sshd_config and execve.
This local change log is a simple sovereign audit trail.
10.3 Verify with local scripts
Create a verification script:
#!/usr/bin/env bash
set -e
sudo aa-status --enabled
sudo auditctl -l | grep '/etc/ssh/sshd_config'
sudo ufw status verbose
sudo systemctl is-active sshd auditd apparmor
Run it periodically and store the results with timestamps.
11. Monitoring and Local Alerting
For sovereign servers, monitoring should remain local and self-contained.
11.1 Local log rotation
Use logrotate to rotate audit and service logs.
Create /etc/logrotate.d/vucense:
/var/log/audit/audit.log {
daily
rotate 14
compress
copytruncate
missingok
notifempty
}
/var/log/nginx/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
}
11.2 Use local alert scripts
Create a script to detect repeated failures in auth logs.
#!/usr/bin/env bash
FAILS=$(grep "Failed password" /var/log/auth.log | tail -n 20 | wc -l)
if [ "$FAILS" -gt 10 ]; then
logger "[vucense] suspicious SSH failure rate: $FAILS"
fi
Schedule it with a systemd timer or cron local-only job.
11.3 Local metrics from node_exporter
If you need metrics, run node_exporter on localhost only.
sudo useradd --no-create-home --shell /usr/sbin/nologin nodeusr
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
sudo tar xzf node_exporter-1.7.0.linux-amd64.tar.gz -C /opt
sudo chown -R nodeusr:nodeusr /opt/node_exporter-1.7.0.linux-amd64
Service file:
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
User=nodeusr
ExecStart=/opt/node_exporter-1.7.0.linux-amd64/node_exporter --web.listen-address=127.0.0.1:9100
Restart=on-failure
[Install]
WantedBy=multi-user.target
This keeps monitoring local and private.
12. Advanced Hardening: Kernel, Network, and Boot Security
12.1 Secure boot and kernel lockdown
For Ubuntu, use secure boot and signed kernels where available.
Enable lockdown=integrity in GRUB if you need a stricter boot chain.
Edit /etc/default/grub:
GRUB_CMDLINE_LINUX="lockdown=integrity"
Then update GRUB:
sudo update-grub
12.2 Disable IPv6 if unused
If your environment does not require IPv6, disable it.
Add to /etc/sysctl.d/99-disable-ipv6.conf:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Reload sysctl:
sudo sysctl --system
12.3 Protect local network interfaces
Use iptables or nftables for a stronger local firewall.
Example nftables config:
sudo tee /etc/nftables.conf <<'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
policy drop;
ct state established,related accept;
iif lo accept;
tcp dport ssh accept;
tcp dport {80,443} accept;
icmp type echo-request accept;
}
chain forward {
type filter hook forward priority 0;
policy drop;
}
}
EOF
sudo systemctl enable --now nftables
sudo nft -c list ruleset
This gives fine-grained local control over network traffic.
13. Practical Hardening for Local Development Nodes
Hardening is not just for production. Even development VMs should follow sovereign practices.
13.1 Isolate test services
Use local container runtimes with restricted permissions rather than running extra servers directly on the host.
Example with podman:
sudo apt install -y podman
podman run --rm -d --name local-db -p 127.0.0.1:5432:5432 postgres:15
13.2 Enforce local host-only tunnels
Use SSH local port forwarding for development access rather than opening ports broadly.
ssh -N -L 15432:127.0.0.1:5432 ubuntu-admin@host
13.3 Secure local package caches
For local-only builds, keep an apt package cache on disk and avoid remote package retrieval during production changes.
sudo apt install -y apt-cacher-ng
sudo systemctl enable --now apt-cacher-ng
This supports a sovereign package supply chain for offline or restricted networks.
14. Troubleshooting and Validation
The following commands help validate hardening state and troubleshoot common issues.
14.1 Validate AppArmor profiles
sudo aa-status
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
sudo aa-enforce /etc/apparmor.d/usr.postgresql
If AppArmor denies a legitimate access, inspect the logs:
sudo grep apparmor /var/log/syslog | tail -n 20
14.2 Validate auditd rules
sudo auditctl -l
sudo ausearch -k sshd_config -i
14.3 Validate SSH hardening
sudo sshd -t
sudo grep -E "^(PermitRootLogin|PasswordAuthentication|AllowUsers)" /etc/ssh/sshd_config
14.4 Validate firewall rules
sudo ufw status verbose
sudo nft list ruleset
14.5 Validate sysctl hardening
sudo sysctl fs.protected_hardlinks
sudo sysctl kernel.randomize_va_space
15. File Integrity Monitoring with AIDE
AIDE (Advanced Intrusion Detection Environment) is a local file integrity monitoring tool that reports unauthorized changes to critical binaries and configuration files.
15.1 Install and initialize AIDE
sudo apt install -y aide
sudo aideinit
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
15.2 Configure AIDE rules
Edit /etc/aide/aide.conf and include critical directories:
@@ define DBDIR = /var/lib/aide
@@ define REPORTLOG = /var/log/aide/aide.log
@@ define COMMAND = /usr/bin/aide
@@
@@ RULE = RANGES
@@
/etc +p+u+g+acl+selinux
/bin +p+u+g+acl+selinux
/sbin +p+u+g+acl+selinux
/usr/bin +p+u+g+acl+selinux
/usr/sbin +p+u+g+acl+selinux
/var/log +p+u+g+acl+selinux
15.3 Run periodic integrity checks
sudo aide --check | sudo tee /var/log/aide/aide-check.log
Schedule it with a systemd timer or local cron job to generate regular evidence of file integrity.
16. Offline Patch Management and Local Package Verification
A sovereign server should also have a reproducible, auditable patch workflow.
16.1 Use a local apt cache or mirror
Install apt-cacher-ng to serve packages locally:
sudo apt install -y apt-cacher-ng
sudo systemctl enable --now apt-cacher-ng
Configure clients to use the local cache by adding /etc/apt/apt.conf.d/01proxy:
Acquire::http::Proxy "http://127.0.0.1:3142";
This reduces reliance on public repositories during patch windows.
16.2 Verify package signatures locally
Install package signatures and trust only local keys.
sudo apt-key list
sudo apt-key add /etc/apt/trusted.gpg.d/vucense.gpg
Always verify packages with dpkg-sig or signed repository metadata.
16.3 Apply patches with verification
sudo apt update
sudo apt list --upgradable
sudo apt install --download-only -y nginx postgresql
Use local storage to stage updates and inspect package checksums before installation.
17. Encrypted Backups and Local Restore Workflow
Hardening also includes protecting backups and ensuring restore capability.
17.1 Backup critical configuration and audit logs
sudo mkdir -p /var/backups/vucense
sudo tar czf /var/backups/vucense/config-$(date -u +%Y%m%dT%H%M%SZ).tgz /etc/nginx /etc/postgresql /etc/ssh /etc/audit
17.2 Encrypt local backups
Use gpg or age for local encryption.
sudo apt install -y gnupg
gpg --encrypt --recipient [email protected] /var/backups/vucense/config-20260522.tgz
For modern local encryption, use age with a key file stored in a restricted directory.
17.3 Restore backup workflow
gpg --decrypt /var/backups/vucense/config-20260522.tgz.gpg | sudo tar xzf - -C /
This ensures you can recover a hardened node without compromising the integrity of the backup.
18. Runbook and Operator Guidance
A sovereign node needs a simple local runbook that the operator can follow without external documentation.
18.1 Local runbook file
Create /var/local/vucense/runbook.md with sections for:
- Hardening verification commands
- Emergency login procedure
- Shutdown and reboot checklist
- Backup and restore instructions
- AppArmor profile reload steps
- Audit log review procedure
18.2 Example runbook commands
# Verify hardening state
sudo aa-status
sudo auditctl -l
sudo ufw status verbose
sudo aide --check
sudo systemctl status ssh fail2ban auditd apparmor
18.3 Local incident triage
Encourage operators to follow a triage path:
- Identify whether the issue is service, network, or audit related.
- Check AppArmor denials with
sudo ausearch -m AVC -ts today. - Inspect authentication failures in
/var/log/auth.log. - Confirm systemd units with
sudo systemctl status.
This local-first incident process keeps control within the sovereign environment.
19. Post-Hardening Review and Continuous Verification
Hardening is not a one-time project. It is a continuous process.
19.1 Use local automated checks
Create a local check-hardening.sh script:
#!/usr/bin/env bash
set -e
sudo systemctl is-active --quiet sshd auditd apparmor fail2ban
sudo aa-status --enabled
sudo auditctl -l | grep '/etc/ssh/sshd_config'
sudo ufw status | grep 'Status: active'
sudo sysctl fs.protected_hardlinks
sudo sysctl kernel.randomize_va_space
19.2 Review audit and AppArmor logs weekly
Set aside time to review:
/var/log/audit/audit.log/var/log/syslog/var/log/auth.log/var/log/aide/aide-check.log
Look for repeated denials, failed login sequences, or changes to privileged files.
19.3 Keep the baseline in version control
Store hardening scripts, configuration snippets, and AppArmor policy templates in a local Git repository. Ensure the repository itself is on encrypted storage with restricted access.
20. Air-Gapped and Disconnected Hardening
Hardening an air-gapped Ubuntu node requires the same controls, plus strict package and metadata staging.
20.1 Maintain local package archives
Keep a copy of required .deb packages and repository indexes on an encrypted local server or USB disk. Use apt-mirror or aptly to mirror only the package sets you need.
20.2 Stage and verify updates offline
Download updates on an approved staging host, verify checksums and signatures, then transfer them to the air-gapped node over a secure media path. Use sha256sum locally before installing.
20.3 Audit removable media
Treat any USB or offline medium as untrusted until scanned. Use local hash verification and AIDE checks after any configuration import.
21. Local Risk Assessment Summary
A sovereign Ubuntu server should be evaluated against these local risk categories:
- unauthorized access to SSH and console
- privilege escalation through sudo or services
- process compromise from weak AppArmor profiles
- tampering of audit logs or configuration files
- network exposure from open ports or permissive firewall rules
Use the hardening checklist to score each category and prioritize remediation locally.
People Also Ask
What makes Ubuntu 24.04 Server Hardening: CIS Benchmark & AppArmor 2026 relevant for sovereign infrastructure in 2026?
This guide is designed for sovereign infrastructure teams building local-first servers in 2026. It combines CIS controls, AppArmor, audit logging, and service sandboxing so the server remains secure without cloud telemetry or vendor-managed security agents.
Can I use this hardening guide for air-gapped servers?
Yes. All commands and tool choices are compatible with air-gapped environments once the packages are available locally. Use apt-cacher-ng or a local mirror and vendor packages to keep the node self-contained.
How do I maintain these hardening settings over time?
Keep the hardening config under version control, automate checks with local scripts, and review the /var/local/vucense/hardening-changelog.md after each change. Use auditd and aa-status to verify settings regularly.
Does AppArmor replace the need for a firewall?
No. AppArmor contains processes, while the firewall controls network access. Use both simultaneously to protect local services and network interfaces.
Further Reading
- Ubuntu 24.04 LTS Server Setup Checklist — base server configuration
- Linux Server Hardening CIS Benchmark 2026 — local host security
- Docker Compose Tutorial 2026 — containerised deployment patterns
- Rust for Systems Programming 2026 — secure local tool development with Rust
Tested on: Ubuntu 24.04 LTS (Hetzner CX22). Last verified: May 2, 2026.