<?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: Volyte</title>
    <description>The latest articles on DEV Community by Volyte (@volyte).</description>
    <link>https://dev.to/volyte</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4206366%2F8b7c5cab-7ff3-4f92-aa2c-0ec8b3e1e0e9.png</url>
      <title>DEV Community: Volyte</title>
      <link>https://dev.to/volyte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/volyte"/>
    <language>en</language>
    <item>
      <title>How to Point Your Domain to Your VPS (DNS A Record + Free SSL)</title>
      <dc:creator>Volyte</dc:creator>
      <pubDate>Fri, 30 Oct 2026 08:19:46 +0000</pubDate>
      <link>https://dev.to/volyte/how-to-point-your-domain-to-your-vps-dns-a-record-free-ssl-kd</link>
      <guid>https://dev.to/volyte/how-to-point-your-domain-to-your-vps-dns-a-record-free-ssl-kd</guid>
      <description>&lt;p&gt;You have a VPS and a domain name. To make &lt;code&gt;example.com&lt;/code&gt; open your website, you add one small DNS record that says &lt;em&gt;"this domain lives at this server's IP address"&lt;/em&gt;. It takes about 5 minutes to set up, and usually works within an hour.&lt;/p&gt;

&lt;p&gt;This guide works wherever your domain is registered — GoDaddy, Hostinger, Namecheap or anyone else — and for Linux and Windows VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your VPS IP address&lt;/strong&gt; — in your provider's welcome email or client area. We'll use the example &lt;code&gt;203.0.113.25&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A login to wherever your domain's DNS is managed&lt;/strong&gt; — usually your domain registrar. If you use Cloudflare, make the changes in Cloudflare instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your website ready on the VPS&lt;/strong&gt; — or set it up after Step 3 while DNS updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Find where your DNS is managed
&lt;/h2&gt;

&lt;p&gt;Your DNS is managed wherever your domain's &lt;strong&gt;nameservers&lt;/strong&gt; point. Open your registrar's domain page and look at "Nameservers":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If they are the registrar's own (for example &lt;code&gt;ns1.registrar.com&lt;/code&gt;), edit DNS at the registrar.&lt;/li&gt;
&lt;li&gt;If they say something like &lt;code&gt;xxx.ns.cloudflare.com&lt;/code&gt;, edit DNS in your Cloudflare account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Add the A records
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;A record&lt;/strong&gt; connects a name to an IPv4 address. Add (or edit) these two records:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Name / Host&lt;/th&gt;
&lt;th&gt;Value / Points to&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@&lt;/code&gt; (the domain itself)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;203.0.113.25&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto or 1 hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;&lt;code&gt;www&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;203.0.113.25&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto or 1 hour&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Some panels want the full name instead of &lt;code&gt;@&lt;/code&gt; — type &lt;code&gt;example.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Instead of the second A record, you can use a &lt;strong&gt;CNAME&lt;/strong&gt;: name &lt;code&gt;www&lt;/code&gt;, value &lt;code&gt;example.com&lt;/code&gt;. Either works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete any old A records&lt;/strong&gt; for &lt;code&gt;@&lt;/code&gt; and &lt;code&gt;www&lt;/code&gt; that point somewhere else (such as a "parked" page). Two different A records for the same name make visitors land on either server at random.&lt;/li&gt;
&lt;li&gt;If there is an &lt;strong&gt;AAAA&lt;/strong&gt; record (IPv6) pointing to your old host, delete it too — or change it to your VPS's IPv6 address if it has one.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't touch your MX records.&lt;/strong&gt; They decide where your email goes. Changing A records moves your website only — your email keeps working where it is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 3: Check that DNS has updated
&lt;/h2&gt;

&lt;p&gt;Changes usually show within &lt;strong&gt;5–60 minutes&lt;/strong&gt;. Sometimes it takes a few hours, because internet providers remember (cache) the old address until the old TTL runs out.&lt;/p&gt;

&lt;p&gt;On Windows, open Command Prompt and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nslookup example.com 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Mac or Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig +short example.com @8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it shows your VPS IP (&lt;code&gt;203.0.113.25&lt;/code&gt;), DNS is ready. You can also check from many countries at once with a free online "DNS checker".&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Tell your web server about the domain
&lt;/h2&gt;

&lt;p&gt;DNS sends visitors to your server — now the server must know which website to show for that domain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cPanel / Plesk:&lt;/strong&gt; add the domain in the panel (cPanel: &lt;em&gt;Domains → Create a New Domain&lt;/em&gt;; Plesk: &lt;em&gt;Websites &amp;amp; Domains → Add Domain&lt;/em&gt;). Done — skip to Step 5.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx:&lt;/strong&gt; put both names in your site's &lt;code&gt;server_name&lt;/code&gt; line, then reload:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;nginx &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache:&lt;/strong&gt; set &lt;code&gt;ServerName example.com&lt;/code&gt; and &lt;code&gt;ServerAlias www.example.com&lt;/code&gt; in your virtual host, then &lt;code&gt;sudo systemctl reload apache2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows VPS (IIS):&lt;/strong&gt; in IIS Manager, open your site → &lt;em&gt;Bindings&lt;/em&gt; → add &lt;code&gt;example.com&lt;/code&gt; and &lt;code&gt;www.example.com&lt;/code&gt; on port 80.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure ports &lt;strong&gt;80 and 443&lt;/strong&gt; are open in your server's firewall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Add a free SSL certificate (HTTPS)
&lt;/h2&gt;

&lt;p&gt;Once the domain opens your site, add HTTPS so browsers show the padlock. It's free with Let's Encrypt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cPanel / Plesk:&lt;/strong&gt; AutoSSL (cPanel) or the Let's Encrypt extension (Plesk) does it automatically, usually within minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx on Ubuntu / Debian:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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;certbot python3-certbot-nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; example.com &lt;span class="nt"&gt;-d&lt;/span&gt; www.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Certbot sets up HTTPS and renews the certificate automatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows (IIS):&lt;/strong&gt; use the free &lt;em&gt;win-acme&lt;/em&gt; tool, which adds and renews Let's Encrypt certificates for IIS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SSL only works &lt;strong&gt;after&lt;/strong&gt; DNS points to your VPS — if Certbot says the domain can't be verified, wait a little and try again.&lt;/p&gt;

&lt;h2&gt;
  
  
  If it doesn't work
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you see&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The old website still shows&lt;/td&gt;
&lt;td&gt;DNS hasn't updated for you yet. Check with &lt;code&gt;nslookup example.com 8.8.8.8&lt;/code&gt;. If that shows the new IP, clear your browser cache or try mobile data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sometimes old site, sometimes new&lt;/td&gt;
&lt;td&gt;There are two A (or AAAA) records for the same name. Delete the one that points to the old server.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"This site can't be reached"&lt;/td&gt;
&lt;td&gt;DNS is fine but the server isn't answering: check the web server is running and ports 80/443 are open in the firewall.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The server's default page appears&lt;/td&gt;
&lt;td&gt;Your web server doesn't know the domain yet — repeat Step 4.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email stopped working&lt;/td&gt;
&lt;td&gt;An MX record was changed or deleted. Put back the MX records your email provider gave you.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://volyte.com/blog/point-domain-to-vps" rel="noopener noreferrer"&gt;Volyte blog&lt;/a&gt;. Next step: &lt;a href="https://volyte.com/blog/secure-linux-vps" rel="noopener noreferrer"&gt;secure your Linux VPS in 10 minutes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dns</category>
      <category>webdev</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Secure Your Linux VPS in 10 Minutes: 8 First Steps (Ubuntu, Debian, AlmaLinux)</title>
      <dc:creator>Volyte</dc:creator>
      <pubDate>Sun, 25 Oct 2026 10:27:47 +0000</pubDate>
      <link>https://dev.to/volyte/secure-your-linux-vps-in-10-minutes-8-first-steps-ubuntu-debian-almalinux-38jj</link>
      <guid>https://dev.to/volyte/secure-your-linux-vps-in-10-minutes-8-first-steps-ubuntu-debian-almalinux-38jj</guid>
      <description>&lt;p&gt;A new server with a public IP gets its first login attempts from bots within minutes. The good news: a handful of steps stop almost all of them. Do these &lt;strong&gt;right after your VPS is ready&lt;/strong&gt; — it takes about 10 minutes.&lt;/p&gt;

&lt;p&gt;Commands are for &lt;strong&gt;Ubuntu and Debian&lt;/strong&gt;, with the &lt;strong&gt;AlmaLinux / Rocky Linux&lt;/strong&gt; version where it differs. Log in as &lt;code&gt;root&lt;/code&gt; with the details from your welcome email.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Golden rule:&lt;/strong&gt; when you change SSH settings, keep your current session open and test the new login in a &lt;em&gt;second&lt;/em&gt; window. If something is wrong, you can still fix it from the first one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Update everything
&lt;/h2&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;AlmaLinux / Rocky: &lt;code&gt;dnf upgrade -y&lt;/code&gt;. Reboot if the kernel was updated: &lt;code&gt;reboot&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create your own user with sudo
&lt;/h2&gt;

&lt;p&gt;Working as &lt;code&gt;root&lt;/code&gt; all the time is risky — one wrong command can damage the system. Create a normal user (replace &lt;code&gt;deploy&lt;/code&gt; with your name):&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Debian says &lt;em&gt;sudo: command not found&lt;/em&gt;? Install it first: &lt;code&gt;apt install sudo -y&lt;/code&gt;. AlmaLinux / Rocky: &lt;code&gt;adduser deploy &amp;amp;&amp;amp; passwd deploy &amp;amp;&amp;amp; usermod -aG wheel deploy&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Log in with an SSH key instead of a password
&lt;/h2&gt;

&lt;p&gt;A key is far harder to guess than any password. On &lt;strong&gt;your own computer&lt;/strong&gt; (Windows PowerShell, Mac or Linux terminal), create a key once:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Enter to accept the defaults (adding a passphrase is a good idea). Then copy it to the server — on Mac / Linux:&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 deploy@203.0.113.25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="n"&gt;\.ssh\id_ed25519.pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;deploy&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;203.0.113.25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open a &lt;strong&gt;new&lt;/strong&gt; window and check you can log in without a password: &lt;code&gt;ssh deploy@203.0.113.25&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Turn off root login and password login
&lt;/h2&gt;

&lt;p&gt;Only after the key login works, edit the SSH settings:&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;nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set these two lines (remove the &lt;code&gt;#&lt;/code&gt; at the start if there is one):&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Ubuntu, also check the files in &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; — a file such as &lt;code&gt;50-cloud-init.conf&lt;/code&gt; can switch &lt;code&gt;PasswordAuthentication yes&lt;/code&gt; back on. Change it to &lt;code&gt;no&lt;/code&gt; there too. Then test and restart 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;sshd &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AlmaLinux / Rocky: the service is called &lt;code&gt;sshd&lt;/code&gt; — &lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;. Test the login again in a new window before closing the old one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Optional:&lt;/em&gt; moving SSH from port 22 to another port (for example 2222) doesn't make it unbreakable, but it cuts automated login attempts dramatically. If you do, open the new port in the firewall (Step 5) &lt;strong&gt;before&lt;/strong&gt; restarting SSH. On Ubuntu 24.04, also run &lt;code&gt;sudo systemctl daemon-reload &amp;amp;&amp;amp; sudo systemctl restart ssh.socket&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Switch on the firewall
&lt;/h2&gt;

&lt;p&gt;Allow only what you use — SSH, and web traffic if you host websites:&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 OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80,443/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable
sudo &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Changed the SSH port? Use &lt;code&gt;sudo ufw allow 2222/tcp&lt;/code&gt; instead of &lt;code&gt;OpenSSH&lt;/code&gt;. AlmaLinux / Rocky use firewalld, which is on by default and already allows 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;firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https
&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Block repeated login attempts with Fail2ban
&lt;/h2&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;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client status sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail2ban bans an IP for a while after several failed logins. On Ubuntu the SSH protection is on out of the box. On Debian 12, if Fail2ban doesn't start, create &lt;code&gt;/etc/fail2ban/jail.local&lt;/code&gt; with these lines and restart it — Debian 12 keeps logs in the system journal instead of &lt;code&gt;auth.log&lt;/code&gt;:&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="w"&gt;
&lt;/span&gt;&lt;span class="py"&gt;backend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;systemd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AlmaLinux / Rocky: install it from EPEL (&lt;code&gt;sudo dnf install epel-release -y &amp;amp;&amp;amp; sudo dnf install fail2ban -y&lt;/code&gt;) and turn on the &lt;code&gt;sshd&lt;/code&gt; jail in &lt;code&gt;/etc/fail2ban/jail.local&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Install security updates automatically
&lt;/h2&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;-plow&lt;/span&gt; unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose &lt;strong&gt;Yes&lt;/strong&gt;. Security fixes now install by themselves every day. AlmaLinux / Rocky:&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;dnf &lt;span class="nb"&gt;install &lt;/span&gt;dnf-automatic &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; dnf-automatic.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Set &lt;code&gt;apply_updates = yes&lt;/code&gt; in &lt;code&gt;/etc/dnf/automatic.conf&lt;/code&gt; so updates are installed, not just downloaded.)&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Take a snapshot and set up backups
&lt;/h2&gt;

&lt;p&gt;Security also means being able to recover. Now that the server is clean and configured, take a &lt;strong&gt;snapshot&lt;/strong&gt; from your hosting control panel — if anything goes wrong later, you can roll back in minutes. Turn on automatic backups too, so you always have a recent copy kept off the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick check: what is listening?
&lt;/h2&gt;

&lt;p&gt;See which services accept connections from the internet:&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;ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything you don't recognise or don't need (an old database open to the world, a test app) — stop it, or allow it only from your own IP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Done when…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Updates&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;apt upgrade&lt;/code&gt; shows nothing left to install&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Own sudo user&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sudo whoami&lt;/code&gt; prints &lt;code&gt;root&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSH key&lt;/td&gt;
&lt;td&gt;You log in without typing the server password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No root / password login&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ssh root@your-ip&lt;/code&gt; is refused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firewall&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ufw status&lt;/code&gt; shows &lt;em&gt;active&lt;/em&gt; with only the ports you need&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fail2ban&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fail2ban-client status sshd&lt;/code&gt; shows the jail running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto updates&lt;/td&gt;
&lt;td&gt;unattended-upgrades (or dnf-automatic) is enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot + backups&lt;/td&gt;
&lt;td&gt;A snapshot exists and backups are on&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://volyte.com/blog/secure-linux-vps" rel="noopener noreferrer"&gt;Volyte blog&lt;/a&gt;. Next step: &lt;a href="https://volyte.com/blog/point-domain-to-vps" rel="noopener noreferrer"&gt;point your domain to your VPS&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>
