{"id":32661,"date":"2026-08-02T23:47:10","date_gmt":"2026-08-02T21:47:10","guid":{"rendered":"https:\/\/contabo.com\/blog\/?p=32661"},"modified":"2026-08-02T23:47:13","modified_gmt":"2026-08-02T21:47:13","slug":"vps-security-checklist","status":"publish","type":"post","link":"https:\/\/contabo.com\/blog\/vps-security-checklist\/","title":{"rendered":"VPS Security Checklist: 9 Essential Steps Right After Setup (2026)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A new <a href=\"https:\/\/contabo.com\/en\/vps\/\">VPS<\/a> is being scanned by automated bots within minutes of going live. Before you install applications or point a domain at your server, run through this checklist. These nine steps cover the attack surface that automated exploits target first \u2014 root login, weak SSH, open ports, and unpatched packages.<a href=\"https:\/\/contabo.com\/en\/vps\/\"> Contabo VPS<\/a> and <a href=\"https:\/\/contabo.com\/en\/vps-dedicated\/\">VDS <\/a>plans also include a free network-level <a href=\"https:\/\/contabo.com\/en\/firewall\/\">firewall <\/a>managed from the Customer Control Panel (CCP), which adds a hardware layer before traffic ever reaches your OS. Step 9 covers that.<\/p>\n\n\n\n<h2 id=\"h-the-9-step-vps-security-checklist\" class=\"wp-block-heading\">The 9-Step VPS Security Checklist<\/h2>\n\n\n\n<div class=\"vps-checklist-table-wrap\" role=\"region\" aria-label=\"VPS Security Checklist Table\" tabindex=\"0\">\n  <style>\n    .vps-checklist-table-wrap {\n      overflow-x: auto;\n      margin: 1.5em 0;\n      font-family: Calibri, \"Segoe UI\", Arial, sans-serif;\n    }\n    .vps-checklist-table {\n      width: 100%;\n      border-collapse: collapse;\n      font-family: Calibri, \"Segoe UI\", Arial, sans-serif;\n      font-size: 15px;\n      color: #000000;\n      background: #ffffff;\n      min-width: 560px;\n    }\n    .vps-checklist-table caption {\n      text-align: left;\n      font-family: Calibri, \"Segoe UI\", Arial, sans-serif;\n      font-size: 13px;\n      color: #5F5E5A;\n      margin-bottom: 8px;\n      caption-side: top;\n    }\n    .vps-checklist-table thead th {\n      background-color: #4F81BD;\n      color: #ffffff;\n      font-weight: 700;\n      text-align: left;\n      padding: 10px 14px;\n      border: 1px solid #365F91;\n    }\n    .vps-checklist-table tbody td {\n      padding: 10px 14px;\n      border: 1px solid #DCE6F1;\n      vertical-align: top;\n    }\n    .vps-checklist-table tbody tr:nth-child(even) {\n      background-color: #F2F6FC;\n    }\n    .vps-checklist-table tbody tr:hover {\n      background-color: #E5EDF8;\n    }\n    .vps-checklist-table td:first-child {\n      font-weight: 600;\n      color: #365F91;\n      white-space: nowrap;\n    }\n    .vps-checklist-table td:last-child {\n      white-space: nowrap;\n      color: #333333;\n    }\n    @media (max-width: 600px) {\n      .vps-checklist-table { font-size: 14px; }\n      .vps-checklist-table td:first-child,\n      .vps-checklist-table td:last-child { white-space: normal; }\n    }\n  <\/style>\n\n  <table class=\"vps-checklist-table\" itemscope itemtype=\"https:\/\/schema.org\/Table\">\n    <caption>The 9-Step VPS Security Checklist \u2014 quick reference for hardening a new VPS after setup<\/caption>\n    <thead>\n      <tr>\n        <th scope=\"col\">Step<\/th>\n        <th scope=\"col\">What It Does<\/th>\n        <th scope=\"col\">Time<\/th>\n      <\/tr>\n    <\/thead>\n    <tbody>\n      <tr><td>1. Update the OS<\/td><td>Patches known vulnerabilities in the base image<\/td><td>2 min<\/td><\/tr>\n      <tr><td>2. Create a non-root sudo user<\/td><td>Eliminates root-as-default risk<\/td><td>2 min<\/td><\/tr>\n      <tr><td>3. Set up SSH key authentication<\/td><td>Removes password brute-force attack surface<\/td><td>5 min<\/td><\/tr>\n      <tr><td>4. Disable root login + password auth<\/td><td>Closes the two most-exploited SSH vectors<\/td><td>2 min<\/td><\/tr>\n      <tr><td>5. Configure UFW firewall<\/td><td>Default-deny all non-essential inbound ports<\/td><td>3 min<\/td><\/tr>\n      <tr><td>6. Install Fail2ban<\/td><td>Auto-bans IPs after repeated failed logins<\/td><td>3 min<\/td><\/tr>\n      <tr><td>7. Enable automatic security updates<\/td><td>Keeps patches current without manual runs<\/td><td>2 min<\/td><\/tr>\n      <tr><td>8. Enable 2FA\/TOTP for SSH<\/td><td>Second factor even if SSH keys are compromised<\/td><td>5 min<\/td><\/tr>\n      <tr><td>9. Activate Contabo&#8217;s CCP network firewall<\/td><td>Network-level block before traffic reaches the OS<\/td><td>2 min<\/td><\/tr>\n    <\/tbody>\n  <\/table>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Update the Operating System First<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The VPS image may have been built weeks ago \u2014 patching first ensures every subsequent step runs on a clean, patched base.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"># Ubuntu \/ Debian<br>sudo apt update &amp;&amp; sudo apt upgrade -y<br>sudo reboot&nbsp; # if a kernel update was applied<br><br># AlmaLinux \/ Rocky Linux<br>sudo dnf update -y<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create a Non-Root Sudo User<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Running everything as root means a single compromised process has full system access. Create a dedicated admin user and use it for all subsequent steps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">adduser [username]<br>usermod -aG sudo [username]<br>su &#8211; [username]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Set Up SSH Key Authentication<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Passwords can be brute-forced; cryptographic key pairs cannot. Generate a key pair locally, copy it to the server, and verify it works before touching any SSH configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"># On your LOCAL machine:<br>ssh-keygen -t ed25519 -C &#8220;your@email.com&#8221;<br><br># Copy public key to the VPS:<br>ssh-copy-id [username]@[server-ip]<br><br># Verify key login works BEFORE proceeding:<br>ssh [username]@[server-ip]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Disable Root Login and Password Authentication<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With SSH key access confirmed, close the two most-exploited entry points: direct root login and password authentication.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sudo nano \/etc\/ssh\/sshd_config<br><br># Set these lines:<br>PermitRootLogin no<br>PasswordAuthentication no<br>PubkeyAuthentication yes<br><br># Restart SSH:<br>sudo systemctl restart sshd<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Optional: change the default SSH port from 22 to a non-standard port (add Port [number] to sshd_config). This reduces automated scanning noise significantly \u2014 particularly useful if your auth logs show high volume. Not a replacement for proper authentication. If you change the port, update UFW rules (Step 5) and the Contabo CCP firewall (Step 9) to allow the new port.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Configure UFW Firewall (Default-Deny)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A default-deny firewall blocks all inbound connections you haven&#8217;t explicitly allowed. Allow SSH first \u2014 or you will lock yourself out.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sudo apt install ufw -y<br><br># Allow SSH (use your custom port if changed in Step 4):<br>sudo ufw allow 22\/tcp<br><br># Allow web traffic if needed:<br>sudo ufw allow 80\/tcp<br>sudo ufw allow 443\/tcp<br><br># Set policies and enable:<br>sudo ufw default deny incoming<br>sudo ufw default allow outgoing<br>sudo ufw enable<br>sudo ufw status verbose<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Install Fail2ban<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban monitors auth logs and bans IPs that exceed a threshold of failed login attempts. It appeared in 86 out of 90 AI responses for this topic \u2014 the near-universal recommendation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sudo apt install fail2ban -y<br><br># Copy config (never edit jail.conf directly):<br>sudo cp \/etc\/fail2ban\/jail.conf \/etc\/fail2ban\/jail.local<br><br># Edit jail.local \u2014 find [sshd] and set:<br># bantime = 1h<br># maxretry = 5<br># findtime = 10m<br><br>sudo systemctl enable &#8211;now fail2ban<br>sudo fail2ban-client status sshd<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Enable Automatic Security Updates<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Manual patching gaps are a leading cause of successful server exploits. Unattended-upgrades applies critical security patches automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sudo apt install unattended-upgrades -y<br>sudo dpkg-reconfigure &#8211;priority=low unattended-upgrades<br><br># Verify security updates are enabled:<br>grep &#8216;security&#8217; \/etc\/apt\/apt.conf.d\/50unattended-upgrades<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 8: Enable 2FA\/TOTP for SSH<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Two-factor authentication adds a second layer even if SSH keys are compromised \u2014 login still requires a time-based one-time password from your authenticator app. The full setup (Google Authenticator PAM module, sshd_config, and PAM configuration) is covered in the dedicated guide \u2014 see the internal link below. Keep this step brief here; the guide walks through each command.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 9: Activate Contabo&#8217;s Network-Level Firewall in the CCP<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Every Contabo Cloud VPS and Cloud VDS plan includes a free network-level firewall managed from the Customer Control Panel. It operates at the network layer, before traffic reaches the VPS OS, complementing the UFW software firewall configured in Step 5.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To activate: Contabo CCP \u2192 select your server \u2192 Firewall \u2192 create inbound rules matching the ports allowed in Step 5 (SSH, 80, 443, and any custom ports). Set all other inbound to deny. The network-level firewall provides hardware-level defence against port scans and volumetric attacks before they consume any server resources \u2014 a feature most providers charge extra for or don&#8217;t include at all.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bonus: Set Up Regular Backups<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The best security posture still fails without a tested backup. If a server is compromised, ransomware-encrypted, or misconfigured beyond recovery, a recent backup is the difference between a one-hour recovery and a complete rebuild. Backups are treated as a core security measure \u2014 not an optional extra.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Contabo CCP snapshots \u2014 take a full-server snapshot before significant changes. Restorable from the CCP within minutes.<\/li>\n\n\n\n<li>Offsite backups to Contabo Object Storage \u2014 use rclone to schedule automated backups of critical data to an S3-compatible bucket. A compromised server cannot delete an offsite backup.<\/li>\n\n\n\n<li>Test your backups \u2014 a backup that has never been restored is a backup you don&#8217;t actually have.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ: VPS Security After Setup<\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1785707012549\"><strong class=\"schema-faq-question\">What is the most important security step after setting up a VPS?<\/strong> <p class=\"schema-faq-answer\">Disabling root login and switching to SSH key authentication are the two highest-impact steps \u2014 they eliminate the primary vectors that automated bots use within minutes of a VPS going live. If you can only do two things immediately, do Steps 3 and 4 in this checklist.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1785707023696\"><strong class=\"schema-faq-question\">Does Contabo provide any built-in security features?<\/strong> <p class=\"schema-faq-answer\">Yes. Every Contabo Cloud VPS and Cloud VDS includes a free network-level firewall managed from the Customer Control Panel \u2014 hardware-level traffic filtering before packets reach the server OS, complementing software firewalls like UFW. The CCP also supports 2FA for account login. Neither feature requires installation or additional payment.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1785707035260\"><strong class=\"schema-faq-question\">How long does it take to complete the VPS security checklist?<\/strong> <p class=\"schema-faq-answer\">The nine core steps take approximately 30 minutes for a developer with basic Linux experience. Step 8 (2FA\/TOTP) adds 5-10 minutes if it&#8217;s your first time. The bonus backup setup adds 10-15 minutes. Total: under one hour for a production-ready security baseline.<\/p> <\/div> <\/div>\n","protected":false},"excerpt":{"rendered":"<p>A new VPS is being scanned by automated bots within minutes of going live. Before you install applications or point a domain at your server, run through this checklist. These nine steps cover the attack surface that automated exploits target first \u2014 root login, weak SSH, open ports, and unpatched packages. Contabo VPS and VDS [&hellip;]<\/p>\n","protected":false},"author":78,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[18],"tags":[],"ppma_author":[4285],"class_list":["post-32661","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Jie Guo","author_link":"https:\/\/contabo.com\/blog\/author\/jieguo\/"},"uagb_comment_info":0,"uagb_excerpt":"A new VPS is being scanned by automated bots within minutes of going live. Before you install applications or point a domain at your server, run through this checklist. These nine steps cover the attack surface that automated exploits target first \u2014 root login, weak SSH, open ports, and unpatched packages. Contabo VPS and VDS&hellip;","authors":[{"term_id":4285,"user_id":78,"is_guest":0,"slug":"jieguo","display_name":"Jie Guo","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/4e0d981b06988d6d456834e9d55bc9e713e918fa8444325543d14f448154106b?s=96&d=mm&r=g","author_category":"","user_url":"","last_name":"Guo","first_name":"Jie","job_title":"","description":""}],"_links":{"self":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/32661","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/comments?post=32661"}],"version-history":[{"count":1,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/32661\/revisions"}],"predecessor-version":[{"id":32662,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/32661\/revisions\/32662"}],"wp:attachment":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/media?parent=32661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/categories?post=32661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/tags?post=32661"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=32661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}