{"id":7,"date":"2022-04-15T16:33:41","date_gmt":"2022-04-15T08:33:41","guid":{"rendered":"https:\/\/deigel.me\/blog\/?p=7"},"modified":"2026-01-31T16:36:50","modified_gmt":"2026-01-31T08:36:50","slug":"vps-ssh-configuration","status":"publish","type":"post","link":"https:\/\/deigel.me\/blog\/?p=7","title":{"rendered":"VPS SSH configuration"},"content":{"rendered":"<h2>0) SSH Tool<\/h2>\n<p>Before you secure your server, the first step is choosing an SSH client. While veterans are familiar with the command-line <code>OpenSSH<\/code> on Linux and macOS, or the classic <code>PuTTY<\/code> on Windows, modern tools can offer a much more polished experience.<\/p>\n<p>For this guide, a fantastic option is <strong>Termius<\/strong>. It&#8217;s a modern, cross-platform SSH client that works on Windows, macOS, Linux, iOS, and Android. What sets it apart is its clean interface and host management, which is far more intuitive than manual config files. The free version includes an SFTP client for file transfers, port forwarding, and excellent mobile keyboard support.<\/p>\n<p><img decoding=\"async\" src=\"c7228965-afd5-4457-968a-ecc9a95eea4f.png\" alt=\"Termius\" \/><\/p>\n<p>Termius is especially appealing for students, as they can access premium features for free through the GitHub Student Developer Pack. This unlocks secure cloud-sync for your hosts and settings across all your devices, making it a powerful and convenient choice for managing your VPS from anywhere.<\/p>\n<h2>1) Safety net first<\/h2>\n<p>Keep your current SSH session open <strong>and<\/strong> test changes in a <strong>second<\/strong> terminal. If anything breaks, the original session lets you roll back.<\/p>\n<pre><code class=\"lang-bash language-bash bash\"># Sanity checks (Debian\/Ubuntu-ish)\nwhoami &amp;&amp; id\nssh -V\nss -ltnp | head<\/code><\/pre>\n<h2>2) Create a user + keys (no passwords)<\/h2>\n<p>On your laptop (or iPad\/desktop), create a modern key and copy it over.<\/p>\n<pre><code class=\"lang-bash language-bash bash\"># On your client\nssh-keygen -t ed25519 -C &quot;me@laptop&quot; -f ~\/.ssh\/id_vps_ed25519\nssh-copy-id -i ~\/.ssh\/id_vps_ed25519.pub root@YOUR.VPS.IP\n# or manually:\n# cat ~\/.ssh\/id_vps_ed25519.pub | ssh root@YOUR.VPS.IP &#039;mkdir -p ~\/.ssh &amp;&amp; cat &gt;&gt; ~\/.ssh\/authorized_keys &amp;&amp; chmod 700 ~\/.ssh &amp;&amp; chmod 600 ~\/.ssh\/authorized_keys&#039;<\/code><\/pre>\n<p>If you prefer a non-root user:<\/p>\n<pre><code class=\"lang-bash language-bash bash\"># On the VPS\nadduser deploy\nusermod -aG sudo deploy     # if you want sudo\nmkdir -p ~deploy\/.ssh &amp;&amp; chown -R deploy:deploy ~deploy\/.ssh\n# From your client:\nssh-copy-id -i ~\/.ssh\/id_vps_ed25519.pub deploy@YOUR.VPS.IP<\/code><\/pre>\n<h2>3) Harden sshd (keys only, no root login)<\/h2>\n<p>I like dropping a dedicated snippet so the distro\u2019s default file stays readable:<\/p>\n<pre><code class=\"lang-bash language-bash bash\"># On the VPS (Debian\/Ubuntu paths)\nsudo tee \/etc\/ssh\/sshd_config.d\/01-hardening.conf &gt;\/dev\/null &lt;&lt;&#039;CONF&#039;\n# --- sensible hardening ---\nProtocol 2\nPort 22                      # you can change to a high port if you want; it&#039;s optional\nPermitRootLogin no\nPasswordAuthentication no\nKbdInteractiveAuthentication no\nChallengeResponseAuthentication no\nPubkeyAuthentication yes\nAllowUsers deploy            # or your chosen user\n\n# Keep sessions healthy, drop zombies quickly\nClientAliveInterval 300\nClientAliveCountMax 2\nLoginGraceTime 20\nMaxAuthTries 3\n\n# turn off rarely used stuff\nX11Forwarding no\nUseDNS no\nCompression no\nCONF\n\nsudo sshd -t &amp;&amp; sudo systemctl reload ssh  # (on some distros it&#039;s sshd)```\n\n**Test in a new terminal**:\n\n```bash\nssh -i ~\/.ssh\/id_vps_ed25519 deploy@YOUR.VPS.IP<\/code><\/pre>\n<p>If it works, you\u2019re golden. If it doesn\u2019t, don\u2019t close your original session\u2014fix and retry.<\/p>\n<h2>4) UFW: default deny, allow only what you need<\/h2>\n<pre><code class=\"lang-bash language-bash bash\">sudo apt update &amp;&amp; sudo apt install -y ufw\n\n# defaults\nsudo ufw default deny incoming\nsudo ufw default allow outgoing\n\n# allow SSH (adjust if you changed the port)\nsudo ufw allow 22\/tcp comment &#039;SSH&#039;\n\n# optional: rate-limit SSH against brute-force\nsudo ufw limit 22\/tcp\n\n# optionally allow your own IP only (replace with your real IP)\n# sudo ufw allow from 203.0.113.42 to any port 22 proto tcp\n\n# web stuff\nsudo ufw allow 80,443\/tcp comment &#039;HTTP\/HTTPS&#039;\n\nsudo ufw enable\nsudo ufw status verbose<\/code><\/pre>\n<blockquote>\n<p>Tip: if you allowlist your home\/office IP, keep a fallback path (VPN, a second IP, or VPS console) in case your IP changes.<\/p>\n<\/blockquote>\n<h2>5) (Optional) Tiny fail2ban<\/h2>\n<pre><code class=\"lang-bash language-bash bash\">sudo apt install -y fail2ban\nsudo tee \/etc\/fail2ban\/jail.local &gt;\/dev\/null &lt;&lt;&#039;JAIL&#039;\n[sshd]\nenabled  = true\nport     = 22\nmaxretry = 5\nfindtime = 10m\nbantime  = 1h\nJAIL\nsudo systemctl restart fail2ban\nsudo fail2ban-client status sshd<\/code><\/pre>\n<h2>6) Nice client config<\/h2>\n<pre><code class=\"lang-bash language-bash bash\"># ~\/.ssh\/config\nHost my-vps\n  HostName YOUR.VPS.IP\n  User deploy\n  IdentityFile ~\/.ssh\/id_vps_ed25519\n  ServerAliveInterval 30\n  ServerAliveCountMax 3\n  StrictHostKeyChecking accept-new<\/code><\/pre>\n<p>Connect with <code>ssh my-vps<\/code>.<\/p>\n<h2>7) Quick rollback plan<\/h2>\n<ul>\n<li>Still have your original SSH session? Undo the last change and <code>systemctl reload ssh<\/code>.<\/li>\n<li>Totally locked out? Use your provider\u2019s web console, revert the snippet (or flip <code>PasswordAuthentication yes<\/code> temporarily), fix keys, and re-harden.<\/li>\n<\/ul>\n<p><strong>That\u2019s it.<\/strong> Quiet logs, fewer bots, no drama.<\/p>","protected":false},"excerpt":{"rendered":"<ol start=\"0\">\n<li>SSH Tool Before you secure your server, the first st [&hellip;]<\/li>\n<\/ol>","protected":false},"author":1,"featured_media":8,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[2],"tags":[],"class_list":["post-7","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vps"],"_links":{"self":[{"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7"}],"version-history":[{"count":1,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7\/revisions"}],"predecessor-version":[{"id":9,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7\/revisions\/9"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=\/wp\/v2\/media\/8"}],"wp:attachment":[{"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/deigel.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}