{"id":1972,"date":"2026-01-28T04:09:48","date_gmt":"2026-01-28T04:09:48","guid":{"rendered":"https:\/\/veerhost.com\/docs\/vps\/how-to-secure-your-vps-ssh-keys-new-user-firewall\/"},"modified":"2026-03-31T17:54:48","modified_gmt":"2026-03-31T17:54:48","slug":"how-to-secure-your-vps-ssh-keys-new-user-firewall","status":"publish","type":"docs","link":"https:\/\/veerhost.com\/de\/docs\/vps\/how-to-secure-your-vps-ssh-keys-new-user-firewall\/","title":{"rendered":"How to Secure Your VPS (SSH Keys, New User, Firewall)"},"content":{"rendered":"<p class=\"wp-block-paragraph\">A freshly provisioned VPS with root login enabled and a password is one of the most targeted things on the internet. Within minutes of going live, bots will start attempting brute-force logins. This guide walks through every step to properly lock down your VeerHost VPS on Ubuntu 22.04, Ubuntu 24.04, or Debian.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Create a New Sudo User<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Running everything as root is dangerous. One mistake can destroy your server. Create a regular user with sudo privileges:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adduser deploy<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Follow the prompts to set a password. Then add the user to the sudo group:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>usermod -aG sudo deploy<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test that sudo works by switching to the new user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>su - deploy\nsudo whoami<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see <code>root<\/code> as the output. Keep this terminal open \u2014 do not log out until SSH key login is confirmed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Generate an SSH Key Pair (on Your Local Machine)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">SSH keys are far stronger than passwords. Run this on <strong>your own computer<\/strong> (not the server):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t ed25519 -C \"your@email.com\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Press Enter to accept the default file location (<code>~\/.ssh\/id_ed25519<\/code>). Optionally add a passphrase for extra security. This creates two files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>~\/.ssh\/id_ed25519<\/code> \u2014 your <strong>private key<\/strong> (never share this)<\/li>\n<li><code>~\/.ssh\/id_ed25519.pub<\/code> \u2014 your <strong>public key<\/strong> (this goes on the server)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Copy Your Public Key to the Server<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>From your local machine:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-copy-id deploy@YOUR_VPS_IP<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>ssh-copy-id<\/code> isn&#8217;t available (e.g., Windows), manually copy the public key. On the server, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/.ssh\nchmod 700 ~\/.ssh\nnano ~\/.ssh\/authorized_keys<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste the contents of your <code>id_ed25519.pub<\/code> file, save and exit (<code>Ctrl+X<\/code>, then <code>Y<\/code>, then <code>Enter<\/code>). Then set permissions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod 600 ~\/.ssh\/authorized_keys<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Test SSH key login in a new terminal (do not close the current one yet):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh deploy@YOUR_VPS_IP<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you can log in without a password, SSH keys are working correctly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Disable Root SSH Login and Password Authentication<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now harden the SSH daemon config. On the server, edit the SSH config file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano \/etc\/ssh\/sshd_config<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Find and change (or add) these lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PermitRootLogin no\nPasswordAuthentication no\nPubkeyAuthentication yes\nAuthorizedKeysFile .ssh\/authorized_keys<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file, then reload SSH (do <strong>not<\/strong> restart \u2014 reload keeps your current session alive):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl reload sshd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Test that root login is blocked<\/strong> by opening a new terminal and trying:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh root@YOUR_VPS_IP<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It should say <code>Permission denied (publickey)<\/code>. If it does, you&#8217;re secure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Change the Default SSH Port (Optional but Recommended)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Port 22 is constantly scanned by bots. Changing to a custom port (e.g., 2299) greatly reduces log noise:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano \/etc\/ssh\/sshd_config<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Find <code>#Port 22<\/code> and change it to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Port 2299<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After saving, <strong>allow the new port in the firewall first<\/strong> (see Step 6), then reload SSH:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl reload sshd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To connect with a custom port: <code>ssh -p 2299 deploy@YOUR_VPS_IP<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Set Up UFW Firewall<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">UFW (Uncomplicated Firewall) is the easiest firewall tool on Ubuntu\/Debian. Install and configure it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install -y ufw<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set default rules (deny all incoming, allow all outgoing):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ufw default deny incoming\nufw default allow outgoing<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Allow SSH (use port 22 or your custom port):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># If keeping default port 22:\nufw allow 22\/tcp\n\n# If you changed SSH to port 2299:\nufw allow 2299\/tcp<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Allow HTTP and HTTPS for websites:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ufw allow 80\/tcp\nufw allow 443\/tcp<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Enable the firewall:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ufw enable<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check the status:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ufw status verbose<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Install Fail2Ban (Brute-Force Protection)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2Ban automatically bans IPs that repeatedly fail SSH login attempts:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install -y fail2ban<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create a local config (never edit the default jail.conf directly):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cp \/etc\/fail2ban\/jail.conf \/etc\/fail2ban\/jail.local\nsystemctl enable fail2ban\nsystemctl start fail2ban<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check that the SSH jail is active:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fail2ban-client status sshd<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Security Checklist<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u2705 New sudo user created (not using root for daily tasks)<\/li>\n<li>\u2705 SSH key authentication enabled<\/li>\n<li>\u2705 Root SSH login disabled<\/li>\n<li>\u2705 Password authentication disabled<\/li>\n<li>\u2705 UFW firewall enabled with minimal open ports<\/li>\n<li>\u2705 Fail2Ban running<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>A freshly provisioned VPS with root login enabled and a password is one of the most targeted things on the internet. Within [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1967,"menu_order":2,"comment_status":"open","ping_status":"closed","template":"","doc_tag":[],"class_list":["post-1972","docs","type-docs","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/1972","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/comments?post=1972"}],"version-history":[{"count":3,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/1972\/revisions"}],"predecessor-version":[{"id":2282,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/1972\/revisions\/2282"}],"up":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/1967"}],"wp:attachment":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/media?parent=1972"}],"wp:term":[{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/doc_tag?post=1972"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}