<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: byte-guard</title>
    <description>The latest articles on DEV Community by byte-guard (@byte-guard).</description>
    <link>https://dev.to/byte-guard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3874887%2F0b20b60b-2582-4d1f-b098-8efd21b4295c.png</url>
      <title>DEV Community: byte-guard</title>
      <link>https://dev.to/byte-guard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/byte-guard"/>
    <language>en</language>
    <item>
      <title>How to Harden Your Linux VPS in 10 Minutes</title>
      <dc:creator>byte-guard</dc:creator>
      <pubDate>Sun, 12 Apr 2026 12:55:49 +0000</pubDate>
      <link>https://dev.to/byte-guard/how-to-harden-your-linux-vps-in-10-minutes-5dgo</link>
      <guid>https://dev.to/byte-guard/how-to-harden-your-linux-vps-in-10-minutes-5dgo</guid>
      <description>&lt;p&gt;The moment you spin up a fresh Linux VPS, the clock starts ticking. Within hours — sometimes minutes — your IP shows up in scanner logs and bots begin trying default credentials, common SSH usernames, and known web exploits. I've watched a brand-new server log over four thousand brute-force SSH attempts in its first 24 hours of life.&lt;/p&gt;

&lt;p&gt;Most of those attacks are stoppable in 10 minutes of work. Here's the no-fluff checklist I run on every new VPS — the same one I used when I built &lt;a href="https://blog.byte-guard.net/building-byteguard-from-scratch-hetzner-vps/" rel="noopener noreferrer"&gt;byte-guard.net itself&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A fresh VPS running &lt;strong&gt;Ubuntu 22.04+&lt;/strong&gt; or &lt;strong&gt;Debian 11+&lt;/strong&gt; (most steps work on any modern distro)&lt;/li&gt;
&lt;li&gt;Root SSH access — ideally a just-provisioned server, before you've done anything else&lt;/li&gt;
&lt;li&gt;10 minutes&lt;/li&gt;
&lt;li&gt;An SSH key on your local machine (we'll generate one if you don't have it)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; these commands assume &lt;code&gt;apt&lt;/code&gt;-based distros. If you're on Rocky, Alma, or RHEL, swap &lt;code&gt;apt&lt;/code&gt; for &lt;code&gt;dnf&lt;/code&gt; and &lt;code&gt;ufw&lt;/code&gt; for &lt;code&gt;firewalld&lt;/code&gt; — the principles are identical.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 1 — Update Everything
&lt;/h2&gt;

&lt;p&gt;Bots love unpatched systems. The first thing to do on any new server is apply outstanding updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pulls down the package index and installs every available update. On a fresh VPS this typically takes 1-2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Create a Non-Root User
&lt;/h2&gt;

&lt;p&gt;You should never SSH in as root for daily work. If your root account gets compromised, you've handed an attacker complete control. A regular user with &lt;code&gt;sudo&lt;/code&gt; access gives you the same power but keeps an audit trail and adds a small barrier between mistakes and disaster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser amine
usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;amine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;amine&lt;/code&gt; with your username. &lt;code&gt;adduser&lt;/code&gt; will prompt you for a password — make it strong (a passphrase from &lt;code&gt;pwgen -s 32 1&lt;/code&gt; is excellent), but you'll mostly be using SSH keys after the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Set Up SSH Key Authentication
&lt;/h2&gt;

&lt;p&gt;Passwords get brute-forced. Ed25519 SSH keys don't, in any practical sense. If you don't have one yet, generate it on your &lt;strong&gt;local machine&lt;/strong&gt;, not the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why &lt;code&gt;ed25519&lt;/code&gt; over &lt;code&gt;rsa&lt;/code&gt;? It's faster, smaller, and more modern. The default &lt;code&gt;rsa&lt;/code&gt; 3072-bit key is also fine, but &lt;code&gt;ed25519&lt;/code&gt; is the current best practice.&lt;/p&gt;

&lt;p&gt;Then copy it to the server, replacing the placeholder with your user and IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-copy-id amine@your-server-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now test it from a new terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh amine@your-server-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should log in without being asked for a password. If that works, you're ready to lock down SSH itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Lock Down SSH
&lt;/h2&gt;

&lt;p&gt;This is the single biggest security win. Open the SSH server config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find and change these lines (uncomment them if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;PermitRootLogin&lt;/span&gt; &lt;span class="no"&gt;no&lt;/span&gt;
&lt;span class="k"&gt;PasswordAuthentication&lt;/span&gt; &lt;span class="no"&gt;no&lt;/span&gt;
&lt;span class="k"&gt;PubkeyAuthentication&lt;/span&gt; &lt;span class="no"&gt;yes&lt;/span&gt;
&lt;span class="k"&gt;ChallengeResponseAuthentication&lt;/span&gt; &lt;span class="no"&gt;no&lt;/span&gt;
&lt;span class="k"&gt;UsePAM&lt;/span&gt; &lt;span class="no"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PermitRootLogin no&lt;/code&gt; — root cannot SSH in at all&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PasswordAuthentication no&lt;/code&gt; — only SSH keys work, no passwords&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PubkeyAuthentication yes&lt;/code&gt; — explicitly enable SSH keys (usually default but be explicit)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ChallengeResponseAuthentication no&lt;/code&gt; and &lt;code&gt;UsePAM no&lt;/code&gt; — close fallback authentication paths&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't close your current session yet.&lt;/strong&gt; Test that you can log in via key from a &lt;em&gt;new&lt;/em&gt; terminal first. If you've made a config mistake, you'll need that working session to fix it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save and reload SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open a brand new terminal and SSH in as your user. If it works, your server is now key-only. Now you can safely close the old root session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Set Up UFW (the Firewall)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; is Ubuntu's user-friendly firewall. It ships with most modern distros and just needs to be enabled with a sensible default policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ufw &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status verbose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see only port 22 (SSH) open. If you're running a web server, also allow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Don't allow ports you're not actually using.&lt;/strong&gt; Every open port is a potential attack surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 — Install fail2ban
&lt;/h2&gt;

&lt;p&gt;Even with key-only SSH, your logs will fill up with rejected brute-force attempts. &lt;code&gt;fail2ban&lt;/code&gt; watches the auth log and bans IPs that repeatedly fail to authenticate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;fail2ban &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Out of the box, the default config protects SSH. Check that the SSH jail is active:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client status sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tighten the defaults (out of the box: 5 attempts, 10-minute ban), create a local override:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/fail2ban/jail.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[sshd]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;maxretry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;findtime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10m&lt;/span&gt;
&lt;span class="py"&gt;bantime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three failed attempts in 10 minutes now earns a one-hour ban. Aggressive enough to deter bots, lenient enough that you can recover from your own typos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7 — Enable Unattended Upgrades
&lt;/h2&gt;

&lt;p&gt;Security patches matter most when they actually get installed. Unattended upgrades automatically apply security updates so you don't have to remember to log in and &lt;code&gt;apt upgrade&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;unattended-upgrades &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg-reconfigure &lt;span class="nt"&gt;--priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;low unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose &lt;strong&gt;Yes&lt;/strong&gt; when prompted. This installs a systemd timer that runs daily and applies security updates only — not feature upgrades, so you won't get surprise breaking changes.&lt;/p&gt;

&lt;p&gt;Verify it's running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;active (running)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8 — Sanity Check
&lt;/h2&gt;

&lt;p&gt;Run these to verify everything is in place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH config — both should say "no"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;sshd &lt;span class="nt"&gt;-T&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"permitrootlogin|passwordauthentication"&lt;/span&gt;

&lt;span class="c"&gt;# Firewall — should show only the ports you opened&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status

&lt;span class="c"&gt;# fail2ban — should show the sshd jail as active&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client status sshd

&lt;span class="c"&gt;# Unattended upgrades — should be active&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl is-active unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything checks out, your VPS is hardened against the most common automated attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus — Change the SSH Port (Optional)
&lt;/h2&gt;

&lt;p&gt;Moving SSH off port 22 doesn't add real security (it's security through obscurity), but it does massively cut log noise from drive-by scanners. Edit &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;Port&lt;/span&gt; &lt;span class="m"&gt;2222&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update UFW:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw delete allow OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 2222/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect with &lt;code&gt;ssh -p 2222 amine@your-server-ip&lt;/code&gt;. Add it to your &lt;code&gt;~/.ssh/config&lt;/code&gt; so you never type the port again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;Host&lt;/span&gt; my-vps
    &lt;span class="k"&gt;HostName&lt;/span&gt; your-server-ip
    &lt;span class="k"&gt;User&lt;/span&gt; amine
    &lt;span class="k"&gt;Port&lt;/span&gt; &lt;span class="m"&gt;2222&lt;/span&gt;
    &lt;span class="k"&gt;IdentityFile&lt;/span&gt; ~/.ssh/id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can just type &lt;code&gt;ssh my-vps&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Does NOT Cover
&lt;/h2&gt;

&lt;p&gt;10 minutes gets you the essentials. It does not cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application-layer security&lt;/strong&gt; — if you're running a web app, you still need to harden Nginx, your reverse proxy, your CMS, and so on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intrusion detection&lt;/strong&gt; — tools like AIDE or Wazuh for filesystem integrity and behavioral monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized logging&lt;/strong&gt; — shipping logs to a separate server so an attacker who lands on the box can't quietly cover their tracks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backups&lt;/strong&gt; — hardening means nothing if you can't restore after an incident&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll cover those in future posts. For now, you've blocked the overwhelming majority of automated attacks that hit any new VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;If you're spinning up a VPS for self-hosting, check out the full build: &lt;a href="https://blog.byte-guard.net/building-byteguard-from-scratch-hetzner-vps/" rel="noopener noreferrer"&gt;How I Built byte-guard.net from Scratch on a Hetzner VPS&lt;/a&gt;. It uses every step in this post and adds Docker, a reverse proxy, and monitoring on top.&lt;/p&gt;

&lt;p&gt;I also wrote a deep dive on &lt;a href="https://blog.byte-guard.net/docker-security-best-practices/" rel="noopener noreferrer"&gt;Docker Security Best Practices&lt;/a&gt; — the container-level companion to this guide.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Quick recap — the 10-minute checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create non-root user with sudo&lt;/li&gt;
&lt;li&gt;SSH key auth set up&lt;/li&gt;
&lt;li&gt;Root login + password auth disabled in &lt;code&gt;sshd_config&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;UFW firewall enabled, only the ports you need&lt;/li&gt;
&lt;li&gt;fail2ban watching the SSH jail&lt;/li&gt;
&lt;li&gt;Unattended security updates running&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run this on every new server you build. After a few times you'll be doing it in closer to 5 minutes than 10.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.byte-guard.net/harden-linux-vps-10-minutes/" rel="noopener noreferrer"&gt;byte-guard.net&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
