[root tip] [How To] Set up your own SSH service

Difficulty: ★★★☆☆

Updated by: @linux-aarhus 2026-04-09T22:00:00Z

SSH server security

When you setup a SSH server on a public IP, your service will be spammed within minutes attempting to brute force your login.

Your first task as admin of a SSH server is to secure it.

Topic assumptions

  1. A Manjaro instance with at least two users, a root user and a user belonging to the %wheel group.
  2. A drop-in config in /etc/sudoers.d/ assigning permissions to the group.
  3. Such file is created with default Manjaro install
    $ cat /etc/sudoers.d/10-installer
    %wheel ALL=(ALL) ALL
    

If you have installed Manjaro by hand you will need to establish such file by hand. Always use visudo as the filepermissions are important.

SSH security

Your SSH server is not the only server you may come across using a public key infrastucture. If you are a using services like Github, GitLab, SourceForge, OSDN and many more - you have come across this before.

There is several options to secure the SSH service against malicious logins.

The most widely used method is a SSH key-pair.

It is possible to use two-factor authentication; that is a ssh key (with or without passphrase) combined with your username and password.

Public key login

Create key pair

SSH public key infrastructure is actually a key pair consisting of both a public and a private key. The public part has the extension .pub and this is the key you place on the server or service.

You create key pair using the ssh-keygen utility. This utility takes various arguments which affects how the key-pair is generated and where the files are placed.

The defaults are sane but in case you want a stronger key, you can use the man-pages to expand your knowledge.

man ssh-keygen

It is recommended to use a separate key for each server and each device you are using to connect with and to tell the keys apart you use a different filename e.g. the name of the service. If you have a Linode cloud instance you could name the file linode or if you are using OSDN you may name it osdn.

To create a key-pair for a service using the service name for the key-pair, you supply the path to the file using the -f argument.

When you create the key you have the option of using a password - or you can leave password blank. This of course lowers the security on client side - but you don’t have to unlock the key-pair on use - and it is a matter of choice - just remember to keep you private keys safe - no matter using key password or not.

EDIT: 2021-10-16T07:45:00Z
Due to recent changes and deprecation of ciphers considered unsafe you should add the -t option to specify the cipher to be used preferably as strong method like ed25519

ssh-keygen -t ed25519  -f ~/.ssh/my-server.key

:reminder_ribbon: If you want to access your service using sftp and filezilla - consider using .ppk as the extension (Filezilla recognize the PuTTY naming of keys)

Transfer the public key to the server

Many VPS providers only provide a root account on the initial device in which case you will have to target root for the keyfile.

Manjaro installations defaults to keyfile only for root login. Therefore you will need the other user account created on the device to be able to upoload the keyfile.

Using ssh-copy to send the file to your ssh service and add it to the user’s $HOME/.ssh/authorized_keys file on the host

ssh-copy-id -i ~/.ssh/my-server.key user@my-server

Log off the server and test your connection using your identity file

ssh user@my-server -i ~/.ssh/my-server.key

If you - in the above key-generation supplied a password to protect your key-pair - you will be prompted to unlock the key-pair.

If you did it right - you are now in a remote shell without being prompted for credentials.

Authentication

Depending on your security requirements you may want to secure your service with a two-factor authentication (public key and username:password).

Disable password login

This is useful if you plan to use only keyfile to login. When you are logged in - using the keyfile - edit the file /etc/ssh/sshd_config.

sudo micro /etc/ssh/sshd_config

Scroll down to the lines reading:

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

And change them to:

PasswordAuthentication no

:reminder_ribbon: This configuration will prevent any login using user credentials (username:password)

Two-factor login

If you want to make the authentication based on both a keyfile and your credentials (username:password) you need another change to the /etc/ssh/sshd_config configuration file.

Locate the comment reading # Authentication and insert below the line

AuthenticationMethods "publickey,password" "publickey,keyboard-interactive"

If you are tighting security on an existing service - be sure to locate the lines below - ensure PasswordAuthentication is commented (the default) or set to yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

Connecting to the server

Connecting to SSH server can be automated by means of the user’s local configuration. Some points to remember:

  • the file is parsed from top to bottom
  • the first match is used

so don’t keep duplicated entries!

If you plan to connect to the same server using different users, this can easily be done using different names for the Host entry.

Every server or service is designated by the Host - all lines between Host entries belong to the preceding Host.

micro ~/.ssh/config

Add your server details - examples

Host nickname
  Hostname server.domain.tld
  IdentityFile ~/.ssh/my-server.key
  user root
  Port 22
Host fido.domain.tld
  IdentityFile ~/.ssh/fido.ppk
  user fido
ssh nickname

:information_source: Note on host key fingerprint

Upon first connection to a - previously unknown - ssh service you will be challenged before connection - something like

$ ssh user@hostname
The authenticity of host 'hostname (ip.x.y.z)' can't be established.
ED25519 key fingerprint is SHA256:P4QBIqLt6g6JU5P3po0WRLF+mr0ypYhhG3iGgCprM20.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:15: ip.x.y.z
Are you sure you want to continue connecting (yes/no/[fingerprint])?

The ssh client will always try to match the remote system to a list of known hosts found in ~/.ssh/known_hosts and if no match is found the client challenge you to trust the host. If you accept the challenge - the host key fingerprint will be added to the list.

If you - for any reason want to skip this check you can do so by adding an option to your connection command

ssh -o StrictHostKeyChecking=no

If you are wearing a blackhat and have a host which regularly changes IP or if you only connect to your own systems you could opt to completely ignore the fingerprints by adding it to your local ~/.ssh/config

Host *
  StrictHostKeyChecking no

:information_source: A note on passwordless keyfiles

When you have a lot of key-pairs (using no password) - you may run into the message - too many failed logins and subsequently - on a Manjaro system - the user may be locked.

You can create a workaround for this by disabling identity agent for the host or you can specify the identity file on the command line when you connect to the host.

This can be done for all or for a single host

Host nickname
  Hostname server.domain.tld
  IdentityAgent none
...

Or using a wildcard

Host *
  IdentityAgent none
...

Secure your key-pairs

You don’t want to loose your key collection.

IMPORTANT: Keep a copy of your ~/.ssh folder in a secure location and if you are using password less keys - keep them safe by:

  • using a strong password on your system
  • root account can always bypass permissions so
    • either disable the root account
      or use a strong password that is not your user password
  • it is mandatory to ensure the files is only readable by your user and they need not being executable
    chown $USER:$USER .ssh -R
    chmod u-x,go-rwx ~/.ssh/*
    

Remote access to local SSH

To access you service from a location outside your home network

  • Ensure your router has a static public IP
  • Ensure the SSH device is secure
  • Ensure the SSH device is using a static IP in your local network
  • Open your routers web administration interface
  • Create a rule to forward traffic to your service internal IP

Options

The following is not required, but depending on use case they are worth your consideration.

Hide the service

Hide your service by changing the port from the default 22 to e.g. 30022.

:information_source: Consult /etc/services to avoid a collision with known services - but in reality any port over 10000 can be used.

The port is located at the top of the configuration

# Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

Uncomment the line and change the port number e.g. use 30022

Port 30022

Save the changes and restart the sshd daemon

sudo systemctl reload sshd

Firewall configuration

Depending on your use case you may want to ensure only allowed services are accessible by implementing a firewall.

Firewalld

Firewalld a very good firewall service - well suited on systemd based systems like Manjaro. Firewalld can be configured using the term application since an application is merely a definition of which ports should be allowed - e.g. a http application or ssh or smtp.

When you configure the firewall you use zones to define where you are and services to define what you allow. Install firewalld:

sudo pacman -Syu firewalld

Then enable and start the service

sudo systemctl enable --now firewalld

When firewalld is enabled and started the default zone is public which allows the computer to be visible but all ports closed.

Adding a specific service (application) is done using the command line but you can also use the applet found in your system configuration area. A systray application is available if you install the dependencies for it (python-pyqt5). Adding services has immediate effect - no need to reload the service. Simply add the service to the allowed service to the desired zone

Example - adding ssh to public zone

sudo firewall-cmd --zone=public --add-service=ssh

It is important to realize that changes you make on the fly are not permanent. To make a certain service available permanently, add the --permanent argument

sudo firewall-cmd --permanent --zone=public --add-service=ssh

What if you want to add your own service definition? Continuing with ssh - you want to run your ssh server on a non default port.

Browse the folder /usr/lib/firewalld/services and make a copy of an appropriate service definition.

Copy the ssh.xml service definition to /etc/firewalld/services

sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/my-ssh.xml

Edit the service definition

sudo micro /etc/firewalld/services/my-ssh.xml

Change the port to match your service and the short name to distinguish from the original service.

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>My SSH service</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="30022"/>
</service>

Wait 5-10 seconds for the service file to be recognized and activate it (Same rule on permanent applies)

sudo firewall-cmd --zone=public --add-service=my-ssh --permanent

That’s it - more info on firewalld can be found using the dedicated webpage

20 Likes
Can't connect to my SSH server
Unable to connect to my manjaro via ssh
Remote Access to home machine?
Using Remmina to RDP from Manjaro on one machine to Manjaro on another machine
How to change "either VNC or SSHD" to "VNC and SSHD"
Sshguard errors
Not able to connect to my manjaro desktop remotely
Cannot successfully SSH to Raspberry Pi 4
Timeout when sshfs mount not reached
Can't ssh into linux box via PUBLIC_URL
Creating virtual monitor for teamviewer?
Accessing a thick client from a thin client - - advice needed for a clamshell purchase
Getting VPS vnc working
Change screen resolution without monitor connected using remote desktop
Server exposed to the internet
How to open a port on rpi400 manjaro arm?
Remotely log into computer's GUI
[root tip] Topic Collection List View
Help with file sharing
[root tip] [How To] Remote Desktop with Plasma Wayland
Ssh rsa public key not accepted
Remote Desktop between 2 Manjaro Machines
Remote desktop?
Firewall or intrusion detection tools for Manjaro
Can't ssh into computer on my lan
VNC server's systemd service
Neugierde zum Thema NAS Thinclient
How to use remmina or other easy way to perform a remote desktop access?
User account periodically fails to login with correct password
Raspberry Pis will not connect via SSH
Stupidly basic: how to deal with "Unit file vncserver.service does not exist"?
OpenSSH rejecting root password when trying to ssh using root@ip
[root tip] [How To] TigerVNC over SSH
Setting up SSH for incoming logins
OpenSSH use scp with identification file
How to connect vnc ( server and viewer or tigervnc) manjaro OS for raspberry pi?
Access Manjaro RPI through internet

I got the error:

❯ chown $USER:$USER .ssh -R && chmod 600 ~/.ssh -R
chmod: cannot access '/home/zesko/.ssh/ed25519': Permission denied
chmod: cannot access '/home/zesko/.ssh/ed25519.pub': Permission denied
chmod: cannot access '/home/zesko/.ssh/config': Permission denied

Fix:

That should be chown $USER:$USER ~/.ssh -R && chmod 600 ~/.ssh/* -R

3 Likes

Thank you for making me aware of this typo :slight_smile:

1 Like