{"id":168,"date":"2026-05-28T09:30:06","date_gmt":"2026-05-28T09:30:06","guid":{"rendered":"https:\/\/blog.offshorekaka.in\/?p=168"},"modified":"2026-08-27T05:43:54","modified_gmt":"2026-08-27T05:43:54","slug":"ssh-hardening-for-offshore-vps","status":"publish","type":"post","link":"https:\/\/offshorekaka.in\/blog\/ssh-hardening-for-offshore-vps\/","title":{"rendered":"SSH Hardening for Offshore VPS Servers"},"content":{"rendered":"<div class=\"ok-pro-panel\">\n<p><span class=\"ok-pro-kicker\">Server Security<\/span><\/p>\n<h2>What this guide does<\/h2>\n<p>By the end of it you will log in to your <a href=\"https:\/\/offshorekaka.in\/offshore-vps-server\/\">offshore VPS<\/a> with a key file instead of a password, and password logins and direct root logins will be switched off. Bots that spend all day guessing passwords on port 22 will have nothing left to guess.<\/p>\n<p>One rule matters more than everything else here. <strong>Do not close the terminal you are already logged in with.<\/strong> Open a second window to test. We have watched people lock themselves out of a brand new server in under five minutes by skipping that.<\/p>\n<div class=\"ok-pro-grid\">\n<div class=\"ok-pro-card\"><strong>Level<\/strong><span>You need to be comfortable running commands.<\/span><\/div>\n<div class=\"ok-pro-card\"><strong>Time<\/strong><span>About 10 minutes.<\/span><\/div>\n<div class=\"ok-pro-card\"><strong>You need<\/strong><span>Root or sudo, and your provider panel login.<\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"ok-toc\"><strong>On this page<\/strong><a href=\"#check\">Check what you have now<\/a><a href=\"#steps\">The four steps<\/a><a href=\"#extra\">Useful commands<\/a><a href=\"#lockout\">If you get locked out<\/a><a href=\"#test\">Testing<\/a><a href=\"#faq\">FAQ<\/a><\/div>\n<h2 id=\"check\">Check what you have now<\/h2>\n<p>Before changing anything, ask the server what it is actually doing. Reading the config file is not enough, because a setting can be overridden further down the file or by a drop-in in <code>\/etc\/ssh\/sshd_config.d\/<\/code>. This command prints the settings that are really in force:<\/p>\n<pre><code>sshd -T | grep -Ei '^(port|permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries) '<\/code><\/pre>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-ssh-hardening-check.webp\" alt=\"Terminal output of sshd -T showing password authentication and root login still enabled\" loading=\"lazy\" width=\"2296\" height=\"570\"><figcaption>A fresh VPS almost always looks like this. Password login on, root login on.<\/figcaption><\/figure>\n<p>That is a default install, and it is what every scanner on the internet is hoping to find. Write these values down before you change them, so you know exactly what to put back if you need to.<\/p>\n<p><strong>Take a snapshot if your panel offers one.<\/strong> A snapshot takes a minute and turns a lockout from a bad afternoon into a two minute rollback.<\/p>\n<h2 id=\"steps\">The four steps<\/h2>\n<h3>Step 1: Make a key pair on your own computer<\/h3>\n<p>The key pair has two halves. The private half stays on your laptop and never moves. The public half gets copied to the server. Run this on your computer, not on the VPS:<\/p>\n<pre><code>ssh-keygen -t ed25519 -C \"laptop-to-vps\"<\/code><\/pre>\n<p>Press Enter to accept the default location. Use a passphrase if the laptop is ever out of your sight. Ed25519 is the right choice in 2026: the keys are short, they are fast, and they are supported everywhere. Only fall back to <code>ssh-keygen -t rsa -b 4096<\/code> if you are dealing with something genuinely ancient.<\/p>\n<p>Now push the public half up:<\/p>\n<pre><code>ssh-copy-id youruser@your-server-ip<\/code><\/pre>\n<p><strong>Test before moving on.<\/strong> Run <code>ssh youruser@your-server-ip<\/code>. If it logs you in without asking for a password, the key works. If it still asks for a password, stop here and fix that first. Everything after this step assumes key login is working.<\/p>\n<h3>Step 2: Turn off password login and root login<\/h3>\n<p>Open <code>\/etc\/ssh\/sshd_config<\/code> and set these three lines. If a line is already there with a <code>#<\/code> in front of it, delete the <code>#<\/code> rather than adding a second copy lower down.<\/p>\n<pre><code>PasswordAuthentication no\nPermitRootLogin no\nPubkeyAuthentication yes<\/code><\/pre>\n<p>On Ubuntu 22.04 and newer, check <code>\/etc\/ssh\/sshd_config.d\/<\/code> as well. Cloud images often drop a file in there that sets <code>PasswordAuthentication yes<\/code>, and because those files are read first, they win. This is the single most common reason people follow a hardening guide, restart SSH, and find passwords still work.<\/p>\n<h3>Step 3: Move SSH off port 22 (optional)<\/h3>\n<p>Changing the port does not make SSH stronger. What it does is drop the noise in your logs by roughly 95 percent, because the bulk of automated scanning only tries port 22. That alone makes real attacks easier to spot.<\/p>\n<pre><code>Port 2222<\/code><\/pre>\n<p><strong>Open the new port in the firewall before you restart SSH.<\/strong> Not after. If you restart first, the service moves to a port your firewall is dropping and you are locked out. Our <a href=\"https:\/\/offshorekaka.in\/blog\/firewall-setup-for-offshore-vps\/\">firewall setup guide<\/a> covers the rules in more detail.<\/p>\n<h3>Step 4: Restart and test in a second window<\/h3>\n<pre><code>sshd -t &amp;&amp; systemctl restart ssh<\/code><\/pre>\n<p>The <code>sshd -t<\/code> part checks the config for syntax errors and only restarts if it passes. A typo in <code>sshd_config<\/code> stops the service from coming back up at all, and that is a lockout you cannot talk your way out of.<\/p>\n<p>Now open a <strong>new<\/strong> terminal, leaving the first one connected, and log in there. Confirm the settings took:<\/p>\n<figure class=\"wp-block-image size-large ok-inline-visual\"><img decoding=\"async\" src=\"https:\/\/offshorekaka.in\/blog\/wp-content\/uploads\/2026\/08\/ok-ssh-hardening-done.webp\" alt=\"Terminal showing permitrootlogin no and passwordauthentication no after hardening, with the SSH service active\" loading=\"lazy\" width=\"2296\" height=\"630\"><figcaption>What the same command should print once the two doors are shut.<\/figcaption><\/figure>\n<p>Only when that second login works should you close the first one.<\/p>\n<h2 id=\"extra\">Useful commands<\/h2>\n<h3>Confirm the port SSH is really listening on<\/h3>\n<pre><code>ss -tulpn | grep ssh<\/code><\/pre>\n<h3>Allow the new port in UFW<\/h3>\n<pre><code>ufw allow 2222\/tcp\nufw reload<\/code><\/pre>\n<h3>Read recent login attempts<\/h3>\n<pre><code>tail -n 50 \/var\/log\/auth.log<\/code><\/pre>\n<p>On AlmaLinux, Rocky and CentOS the file is <code>\/var\/log\/secure<\/code> instead. Look for <code>Accepted publickey<\/code> lines, which are your own successful logins, and <code>Failed password<\/code> lines, which are the bots. After this guide the failed lines should stop appearing entirely, because passwords are no longer an option.<\/p>\n<h3>Fix key permissions when the key is refused<\/h3>\n<p>SSH ignores a key file that other users on the box can read. If your key is not being accepted and you are certain it is the right one, this is almost always why:<\/p>\n<pre><code>chmod 700 ~\/.ssh\nchmod 600 ~\/.ssh\/authorized_keys<\/code><\/pre>\n<h2 id=\"lockout\">If you get locked out<\/h2>\n<p>Every VPS panel worth using has a web console, sometimes called VNC or noVNC. It talks to the server the way a physical monitor and keyboard would, so it keeps working when SSH is dead. That is your way back in.<\/p>\n<p>From the console, log in as root, set <code>PasswordAuthentication yes<\/code> again, restart SSH, and you are back where you started. If you changed the port and cannot connect, either reopen the old port in the firewall or set the port back to 22.<\/p>\n<p>The thing that turns a small mistake into a big one is changing several things at once. Change one setting, restart, test, then move to the next.<\/p>\n<h2 id=\"test\">How to test when you are done<\/h2>\n<ol>\n<li>Log in from a new terminal using your key.<\/li>\n<li>Add <code>-p 2222<\/code> if you changed the port.<\/li>\n<li>Try <code>ssh root@your-server-ip<\/code>. It should be refused.<\/li>\n<li>Force a password attempt with <code>ssh -o PubkeyAuthentication=no youruser@your-server-ip<\/code>. It should also be refused.<\/li>\n<li>Run <code>sshd -T | grep -i passwordauth<\/code> and confirm it reads <code>no<\/code>.<\/li>\n<li>Check the auth log for clean <code>Accepted publickey<\/code> lines.<\/li>\n<\/ol>\n<h2>When it does not work<\/h2>\n<table>\n<thead>\n<tr>\n<th>What you see<\/th>\n<th>Why<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Password login still works after the restart<\/td>\n<td>A file in <code>\/etc\/ssh\/sshd_config.d\/<\/code> is overriding your change<\/td>\n<td>Edit that file too, or delete the line from it, then restart<\/td>\n<\/tr>\n<tr>\n<td>Key refused, password prompt appears<\/td>\n<td>Wrong username, or permissions on <code>~\/.ssh<\/code><\/td>\n<td>Check the username, then run the two chmod commands above<\/td>\n<\/tr>\n<tr>\n<td>SSH does not come back after restart<\/td>\n<td>Syntax error in the config<\/td>\n<td>Use the panel console and run <code>sshd -t<\/code> to see the exact line number<\/td>\n<\/tr>\n<tr>\n<td>Cannot connect after a port change<\/td>\n<td>Firewall is still only allowing 22<\/td>\n<td>Allow the new port, then connect with <code>-p<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"checklist\">Checklist<\/h2>\n<ul>\n<li>Key pair created and the public key copied to the server.<\/li>\n<li>Key login tested and working before anything was disabled.<\/li>\n<li><code>PasswordAuthentication no<\/code> and <code>PermitRootLogin no<\/code> confirmed with <code>sshd -T<\/code>.<\/li>\n<li><code>\/etc\/ssh\/sshd_config.d\/<\/code> checked for overrides.<\/li>\n<li>Firewall updated if you moved the port.<\/li>\n<li>A second login tested before closing the first terminal.<\/li>\n<\/ul>\n<div class=\"ok-cta-box\">\n<p><strong>Want a VPS with real root access?<\/strong><\/p>\n<p>OffshoreKaka VPS servers run on KVM in Amsterdam and Frankfurt, with a web console in the panel so a lockout is never permanent.<\/p>\n<p><a class=\"btn ok-cta-link\" href=\"https:\/\/offshorekaka.in\/offshore-vps-server\/\">See the VPS plans<\/a><\/p>\n<\/div>\n<h2 id=\"faq\">FAQ<\/h2>\n<h3>Is changing the SSH port actually worth doing?<\/h3>\n<p>It is worth doing for the quiet logs, not for the security. Anyone running a real port scan will find SSH on 2222 in seconds. The value is that once the background noise is gone, a genuine attempt stands out instead of being buried under ten thousand bot logins.<\/p>\n<h3>Should I use fail2ban as well?<\/h3>\n<p>Yes, and it takes about two minutes. Once password login is off it has less to block, but it still handles the slow scanners that keep probing. There is more on it in our <a href=\"https:\/\/offshorekaka.in\/blog\/secure-offshore-vps-server-checklist\/\">VPS security checklist<\/a>.<\/p>\n<h3>What if I lose my private key?<\/h3>\n<p>Then you lose that route in, which is exactly the point of a key. Get in through the panel console, add a new public key to <code>~\/.ssh\/authorized_keys<\/code>, and remove the old one. Keep a second key on a different machine if you would rather not rely on the console.<\/p>\n<h3>Does any of this help my Google ranking?<\/h3>\n<p>No, not on its own. It keeps the server up and out of trouble, and a site that is online and clean is easier to rank than one that keeps getting compromised. But the ranking itself comes from content and links.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Key only login, root login off, and the config override on modern Ubuntu that quietly undoes it if you do not know to look.<\/p>\n","protected":false},"author":1,"featured_media":913,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-168","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server-security"],"_links":{"self":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/comments?post=168"}],"version-history":[{"count":5,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/168\/revisions"}],"predecessor-version":[{"id":1011,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/posts\/168\/revisions\/1011"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/media\/913"}],"wp:attachment":[{"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/media?parent=168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/categories?post=168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/offshorekaka.in\/blog\/wp-json\/wp\/v2\/tags?post=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}