How to Set Up & Harden Ubuntu 24.04 LTS on a Netcup VPS or Root Server (Production Runbook)
When a fresh Netcup VPS or Root Server finishes installing Ubuntu 24.04 LTS inside the Server Control Panel (SCP), the initial 25 minutes of systems engineering determine whether your server runs reliably for years or suffers from unquiesced snapshot corruption, SSH brute-force floods, and suboptimal TCP throughput. This production runbook walks through verifying KVM paravirtualized drivers, installing the QEMU Guest Agent for live SCP snapshot freeze hooks, creating an unprivileged administrative account, tuning NVMe swap and TCP BBR congestion control for high-bandwidth VirtIO interfaces, and locking down dual-stack network exposure.
PREREQUISITES // ENVIRONMENT REQUIREMENTS
CHECKLIST- ✓ An active Netcup VPS or Root Server running a fresh Ubuntu 24.04 LTS image
- ✓ Access to the Netcup Server Control Panel (SCP) at servercontrolpanel.de
- ✓ An OpenSSH client (Linux/macOS terminal or Windows PowerShell) with a locally generated Ed25519 SSH key pair
Key Takeaways
EXECUTIVE BRIEFING-
01 Install and enable
qemu-guest-agentimmediately so Netcup’s SCP hypervisor can executefsfreeze(FIFREEZE) hooks during live Copy-on-Write snapshots and issue clean ACPI shutdowns. -
02 Verify that your block storage device uses
virtio_scsiorvirtio_blkwith weeklyfstrim.timerdiscard enabled so deleted blocks are reclaimed on Netcup’s Ceph/NVMe storage backend. -
03 Create a dedicated sudo user and verify Ed25519 public-key login in a second terminal before disabling root password authentication via
/etc/ssh/sshd_config.d/99-netcup-hardening.conf. -
04 Configure a tier-appropriate swapfile with
vm.swappiness = 10and enable Google TCP BBR (net.ipv4.tcp_congestion_control = bbr) to maximize throughput across Netcup’s 1 Gbit/s and 2.5 Gbit/s network ports.
📑 Quick Jump Table of Contents (4 Sections) ▼
- 01 Step 1: Verify KVM Paravirtualization, Upgrade Packages & Enable QEMU Guest Agent
- 02 Step 2: Create an Unprivileged Admin User & Configure Chrony Time Sync
- 03 Step 3: Provision NVMe Swap Space & Tune Kernel Network/VM Parameters (sysctl)
- 04 Step 4: Lock Down OpenSSH, Enable UFW Firewall & Configure Unattended Upgrades
Step 1: Verify KVM Paravirtualization, Upgrade Packages & Enable QEMU Guest Agent
Inside the Netcup Server Control Panel (SCP), ensure under Settings → General that the storage driver is set to virtio-scsi (or virtio) and the network card model is set to virtio. Paravirtualized VirtIO drivers bypass legacy emulated IDE or Intel e1000 hardware overhead in QEMU, allowing the Ubuntu 24.04 LTS Linux 6.8+ kernel to communicate directly with the host hypervisor via shared ring buffers (virtqueue). This zero-copy descriptor ring architecture reduces host-to-guest context switches and lowers CPU soft-interrupt overhead under heavy random 4K disk I/O and high packet-per-second network loads.
Why is qemu-guest-agent mandatory on Netcup? Without it, creating an online snapshot in SCP captures a crash-consistent raw disk state while dirty pages sit in the Linux page cache and uncommitted transactions remain in PostgreSQL or MariaDB memory buffers. With qemu-guest-agent listening on the /dev/virtio-ports/org.qemu.guest_agent.0 character socket, SCP instructs the guest kernel to flush filesystem buffers (sync) and freeze mounted filesystems (ioctl FIFREEZE) for a fraction of a second before snapping the volume—guaranteeing application-consistent backups.
Alongside the guest agent, production KVM block volumes require periodic SCSI UNMAP (NVMe TRIM / discard) commands so the underlying storage pool knows which filesystem blocks have been freed after log rotation or container image pruning. Enabling Ubuntu’s built-in fstrim.timer schedules a weekly discard pass across all mounted ext4 or XFS filesystems, preventing write amplification and keeping sustained random write IOPS consistent over multi-year uptimes.
# Connect to your Netcup server IPv4 address
ssh [email protected]
# Refresh APT repositories and apply all pending kernel/security updates
export DEBIAN_FRONTEND=noninteractive
apt update && apt full-upgrade -y
# Install essential systems administration utilities and the QEMU Guest Agent
apt install -y qemu-guest-agent chrony curl wget git ufw fail2ban htop iotop sysstat jq unattended-upgrades
# Enable and verify QEMU Guest Agent communication with Netcup SCP
systemctl enable --now qemu-guest-agent
systemctl status qemu-guest-agent --no-pager
# Enable weekly SSD/NVMe TRIM discard timer
systemctl enable --now fstrim.timer Command Explanation: Upgrades Ubuntu 24.04 LTS packages non-interactively, installs core diagnostic tools plus qemu-guest-agent, and activates fstrim.timer so unused blocks are returned to the Netcup storage array.
● qemu-guest-agent.service - QEMU Guest Agent
Loaded: loaded (/usr/lib/systemd/system/qemu-guest-agent.service; enabled)
Active: active (running) SECURITY NOTE: If apt full-upgrade -y installs a newer Linux kernel image, /var/run/reboot-required will be created. Complete Steps 2 through 4 first, then execute a clean sudo reboot.
Activating systemd fstrim.timer issues SCSI UNMAP / TRIM commands over virtio-scsi every week, preventing write amplification and keeping sustained random IOPS high across Netcup SSD and NVMe volumes.
Step 2: Create an Unprivileged Admin User & Configure Chrony Time Sync
Running daily maintenance, CI/CD pipelines, or container deployments as root risks catastrophic filesystem mistakes and exposes UID 0 to automated SSH credential stuffing. Create a dedicated administrative account (deployadmin), grant it sudo group privileges, and migrate your authorized SSH public keys with strict POSIX permissions (0700 on ~/.ssh and 0600 on authorized_keys). OpenSSH’s StrictModes yes check will reject public-key authentication immediately if either directory or file is writable by group or others.
At the same time, set your server’s Fully Qualified Domain Name (FQDN) hostname, lock the system timezone to UTC so log timestamps correlate cleanly across distributed services, and configure chrony to synchronize the system clock against the KVM paravirtualized hardware clock (/dev/ptp_kvm) and European NTP pools. Sub-millisecond clock accuracy is essential for TLS 1.3 OCSP stapling, TOTP 2FA token verification, distributed Raft consensus, and PostgreSQL write-ahead log (WAL) transaction timestamps.
Before proceeding to SSH daemon lockdown in Step 4, always verify your new administrative account in a separate terminal window on your workstation. Confirm both passwordless public-key login (ssh [email protected]) and interactive privilege escalation (sudo whoami returning root) so you never risk locking yourself out of UID 0.
# 1. Set FQDN hostname and UTC timezone
hostnamectl set-hostname prod-nc-01.example.com
timedatectl set-timezone UTC
systemctl enable --now chrony
chronyc tracking
# 2. Create administrative user and add to sudo group
adduser --gecos "" deployadmin
usermod -aG sudo deployadmin
# 3. Copy root's authorized_keys (or inject your Ed25519 public key) with strict permissions
install -d -m 0700 -o deployadmin -g deployadmin /home/deployadmin/.ssh
if [ -f /root/.ssh/authorized_keys ]; then
install -m 0600 -o deployadmin -g deployadmin /root/.ssh/authorized_keys /home/deployadmin/.ssh/authorized_keys
else
cat << 'EOF' > /home/deployadmin/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleReplaceWithYourRealPublicKey admin@workstation
EOF
chown deployadmin:deployadmin /home/deployadmin/.ssh/authorized_keys
chmod 0600 /home/deployadmin/.ssh/authorized_keys
fi Command Explanation: Establishes UTC timekeeping via chrony, creates deployadmin, and enforces 0700/0600 ownership on /home/deployadmin/.ssh/authorized_keys.
Reference ID : C0A80101 (ntp1.netcup.net)
Stratum : 2
System time : 0.000041231 seconds fast of NTP time SECURITY NOTE: Before logging out of your root session, open a second terminal window on your workstation and test ssh [email protected] followed by sudo whoami to confirm you have working administrative access.
Step 3: Provision NVMe Swap Space & Tune Kernel Network/VM Parameters (sysctl)
Default Netcup cloud images often ship with zero swap or a minimal swap partition. Even on an 8 GB ECC RAM instance like the VPS 1000 G12.5 or RS 1000 G12.5, running with zero swap means a sudden anonymous memory spike during a multi-stage Docker image build (such as compiling Next.js, Rust, or Go binaries), apt package decompression, or pg_dump backup immediately triggers the Linux kernel Out-Of-Memory (oom-killer) daemon to terminate your database or web server.
Provisioning a 4 GB /swapfile on fast NVMe storage gives the kernel a safety valve for cold anonymous memory pages. However, Ubuntu’s default vm.swappiness = 60 is far too aggressive for latency-sensitive servers, swapping out application pages even when gigabytes of RAM remain free. Lowering vm.swappiness to 10 instructs the kernel to keep database buffers and application heaps pinned in physical ECC RAM unless memory utilization crosses ~90%, while vm.vfs_cache_pressure = 50 keeps filesystem dentry and inode metadata cached in memory.
On the networking side, Ubuntu 24.04 defaults to the loss-based cubic TCP congestion control algorithm, which halves its congestion window (cwnd) whenever a single packet is dropped on long-haul international links. Switching the packet scheduler to Fair Queueing (net.core.default_qdisc = fq) and enabling Google TCP BBR (net.ipv4.tcp_congestion_control = bbr), combined with net.ipv4.tcp_slow_start_after_idle = 0 and an expanded somaxconn = 8192 listen backlog, significantly improves throughput across Netcup’s 1 Gbit/s and 2.5 Gbit/s VirtIO network interfaces.
| Netcup Server Model | CPU / vCPU Allocation | Physical ECC RAM | Recommended Swapfile | Target vm.swappiness & Network Profile |
|---|---|---|---|---|
| VPS pico G11.5s / VPS nano G11.5s | 1 – 2 vCPU Cores | 1 GB – 2 GB ECC | 2 GB Swapfile | vm.swappiness = 20, BBR + 4096 somaxconn |
| VPS 500 G12.5 | 4 vCPU Cores | 4 GB ECC | 4 GB Swapfile | vm.swappiness = 10, BBR + 8192 somaxconn |
| VPS 1000 G12.5 | 6 vCPU Cores | 8 GB ECC | 4 GB Swapfile | vm.swappiness = 10, BBR + 8192 somaxconn |
| RS 1000 G12.5 | 4 Dedicated AMD EPYC Zen 5 Cores | 8 GB DDR5 ECC | 4 GB – 8 GB Swapfile | vm.swappiness = 10, BBR + 2.5G fq pacing |
# 1. Create and activate a 4 GB swapfile if no swap is active
if [ "$(swapon --show | wc -l)" -eq 0 ]; then
sudo fallocate -l 4G /swapfile
sudo chmod 0600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
fi
# 2. Apply VM and TCP BBR network tuning for Netcup 1G / 2.5G virtio-net ports
cat << 'EOF' | sudo tee /etc/sysctl.d/99-netcup-tuning.conf
# Virtual Memory & Filesystem Cache Tuning
vm.swappiness = 10
vm.vfs_cache_pressure = 50
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
# Network Queue & Google TCP BBR Congestion Control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.somaxconn = 8192
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_slow_start_after_idle = 0
EOF
sudo sysctl --system
free -h && sysctl net.ipv4.tcp_congestion_control Command Explanation: Provisions a persistent 4 GB /swapfile (chmod 0600), configures conservative swapping (vm.swappiness = 10), disables TCP slow-start after idle periods, and activates bbr packet pacing.
total used free shared buff/cache available
Mem: 7.8Gi 412Mi 6.9Gi 8.0Mi 640Mi 7.2Gi
Swap: 4.0Gi 0B 4.0Gi
net.ipv4.tcp_congestion_control = bbr Step 4: Lock Down OpenSSH, Enable UFW Firewall & Configure Unattended Upgrades
Notice a critical operational detail on Ubuntu 24.04 LTS: OpenSSH uses a drop-in configuration directory (/etc/ssh/sshd_config.d/) where Cloud-Init frequently writes /etc/ssh/sshd_config.d/50-cloud-init.conf containing PasswordAuthentication yes. Because OpenSSH evaluates directives using a first-match-wins model and Include /etc/ssh/sshd_config.d/*.conf sits at the very top of /etc/ssh/sshd_config, any directives you append to the bottom of /etc/ssh/sshd_config are ignored if an earlier drop-in file already defined them! Always remove 50-cloud-init.conf, place your hardening rules in /etc/ssh/sshd_config.d/99-netcup-hardening.conf, and validate syntax with sudo sshd -t before reloading.
Once SSH is restricted exclusively to cryptographic public keys (AuthenticationMethods publickey) and PermitRootLogin no, enable the Uncomplicated Firewall (ufw) with dual-stack IPv4 and IPv6 enforcement (IPV6=yes in /etc/default/ufw). Allow only your essential ingress ports—typically 22/tcp (OpenSSH), 80/tcp (HTTP), 443/tcp (HTTPS), and 443/udp (HTTP/3 QUIC)—while denying all other unsolicited inbound connections.
Finally, enable unattended-upgrades so Debian and Ubuntu Security Notices (USNs) for openssl, glibc, curl, and the Linux kernel are applied automatically overnight. You can inspect /var/log/unattended-upgrades/unattended-upgrades.log at any time to audit patched packages and schedule a controlled maintenance reboot whenever /var/run/reboot-required is generated.
# 1. Enforce key-only SSH login and disable root SSH access
sudo rm -f /etc/ssh/sshd_config.d/50-cloud-init.conf
cat << 'EOF' | sudo tee /etc/ssh/sshd_config.d/99-netcup-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
EOF
# Validate SSH config syntax before reloading
sudo sshd -t && sudo systemctl reload ssh
# 2. Configure UFW dual-stack firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'OpenSSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw allow 443/udp comment 'HTTP/3 QUIC'
sudo ufw --force enable
sudo ufw status verbose
# 3. Enable automatic daily CVE security patching
sudo dpkg-reconfigure -f noninteractive unattended-upgrades Command Explanation: Removes Cloud-Init’s password override, disables root and password SSH logins via a drop-in file, opens only ports 22, 80, and 443 (TCP/UDP) in UFW, and enables unattended-upgrades.
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed) Common Troubleshooting Scenarios
DIAGNOSTIC RUNBOOK [SYMPTOM] Password authentication still works even after editing /etc/ssh/sshd_config
Root Cause: On Ubuntu 24.04 LTS, /etc/ssh/sshd_config includes /etc/ssh/sshd_config.d/*.conf at the top of the file, and first-match wins in OpenSSH. If 50-cloud-init.conf sets PasswordAuthentication yes, edits at the bottom of sshd_config are ignored.
Resolution: Remove /etc/ssh/sshd_config.d/50-cloud-init.conf and verify the effective runtime configuration with sudo sshd -T | grep -E "passwordauthentication|permitrootlogin".
[SYMPTOM] SCP Snapshot creation warns that filesystem freeze failed or timed out
Root Cause: Either qemu-guest-agent is not installed/running inside Ubuntu, or the VirtIO serial channel was disabled in SCP settings.
Resolution: Run sudo systemctl status qemu-guest-agent inside the VM and confirm that /dev/virtio-ports/org.qemu.guest_agent.0 exists.
[SYMPTOM] Locked out of SSH after enabling UFW or editing sshd_config
Root Cause: Port 22 (or your custom SSH port) was omitted from UFW rules, or the public key in authorized_keys had incorrect permissions (0644 instead of 0600).
Resolution: Log in to the Netcup Server Control Panel (SCP) → Screen (HTML5 VNC Console), log in locally at the TTY prompt, fix /home/deployadmin/.ssh/authorized_keys permissions or run sudo ufw allow 22/tcp, and reload SSH.
Frequently Asked Questions
VERIFIED Q&AShould I choose the Netcup minimal Ubuntu image or the Cloud-Init Ubuntu image in SCP?
Both images install canonical Ubuntu 24.04 LTS packages. Choose the Cloud-Init image if you want zero-touch YAML bootstrapping and automatic SSH key injection on first boot; choose the standard minimal image if you prefer interactive setup.
Do I need to install custom VirtIO drivers on Ubuntu 24.04 for Netcup?
No. The mainline Linux 6.8+ kernel shipped with Ubuntu 24.04 LTS includes compiled-in virtio_scsi, virtio_blk, virtio_net, and virtio_balloon kernel modules out of the box.
How much disk space do system logs consume over time on a Netcup SSD/NVMe server?
By default, systemd-journald can grow up to 4 GB. You can cap journal disk usage to 500 MB by running sudo mkdir -p /etc/systemd/journald.conf.d && printf "[Journal]\nSystemMaxUse=500M\n" | sudo tee /etc/systemd/journald.conf.d/size.conf && sudo systemctl restart systemd-journald.
Should I also enable the Netcup SCP Firewall in addition to UFW?
Yes! Enabling the SCP Stateful Firewall at the hypervisor edge drops unwanted scan traffic before it even reaches your guest OS kernel—and protects you against Docker containers bypassing host UFW rules.
Which Netcup VPS or Root Server tier is best for production Ubuntu 24.04 workloads?
For lightweight personal services, WireGuard gateways, or reverse proxies, the 2 GB ECC RAM VPS nano G11.5s or 4 GB ECC RAM VPS 500 G12.5 is ideal. For multi-container Docker stacks, relational databases, and CI/CD runners, we recommend an 8 GB ECC RAM instance such as the VPS 1000 G12.5 (6 vCPU cores) or the dedicated-core RS 1000 G12.5 (4 dedicated AMD EPYC Zen 5 cores).
REFERENCES // VERIFIED TECHNICAL SOURCES
- [1] Ubuntu 24.04 LTS Server Administration Documentation (https://ubuntu.com/server/docs)
- [2] Netcup Helpcenter — Server Control Panel (SCP) & Images (https://helpcenter.netcup.com/)