Top 20 OpenSSH Server Best Security Practices

OpenSSH is the implementation of the SSH protocol. OpenSSH is recommended for remote login, making backups, remote file transfer via scp or sftp, and much more. SSH is perfect to keep confidentiality and integrity for data exchanged between two networks and systems. However, the main advantage is server authentication, through the use of public key cryptography. From time to time there are rumors about OpenSSH zero day exploit. This page shows how to secure your OpenSSH server running on a Linux or Unix-like system to improve sshd security.

OpenSSH defaults

  • TCP port – 22
  • OpenSSH server config file – sshd_config (located in /etc/ssh/)
  • OpenSSH client config file – ssh_config (located in /etc/ssh/)

1. Use SSH public key based login

OpenSSH server supports various authentication. It is recommended that you use public key based authentication. First, create the key pair using following ssh-keygen command on your local desktop/laptop:

DSA and RSA 1024 bit or lower ssh keys are considered weak. Avoid them. RSA keys are chosen over ECDSA keys when backward compatibility is a concern with ssh clients. All ssh keys are either ED25519 or RSA. Do not use any other type.

$ ssh-keygen -t key_type -b bits -C "comment"
$ ssh-keygen -t ed25519 -C "Login to production cluster at xyz corp"
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_aws_$(date +%Y-%m-%d) -C "AWS key for abc corp clients"

Next, install the public key using ssh-copy-id command:
$ ssh-copy-id -i /path/to/public-key-file user@host
$ ssh-copy-id user@remote-server-ip-or-dns-name
$ ssh-copy-id vivek@rhel7-aws-server

When promoted supply user password. Verify that ssh key based login working for you:
$ ssh vivek@rhel7-aws-server

For more info on ssh public key auth see:

2. Disable root user login

Before we disable root user login, make sure regular user can log in as root. For example, allow vivek user to login as root using the sudo command.

How to add vivek user to sudo group on a Debian/Ubuntu

Allow members of group sudo to execute any command. Add user vivek to sudo group:
$ sudo adduser vivek sudo
Verify group membership with id command $ id vivek

How to add vivek user to sudo group on a CentOS/RHEL server

Allows people in group wheel to run all commands on a CentOS/RHEL and Fedora Linux server. Use the usermod command to add the user named vivek to the wheel group:
$ sudo usermod -aG wheel vivek
$ id vivek

Test sudo access and disable root login for ssh

Test it and make sure user vivek can log in as root or run the command as root:
$ sudo -i
$ sudo /etc/init.d/sshd status
$ sudo systemctl status httpd

Once confirmed disable root login by adding the following line to sshd_config:
PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

See “How to disable ssh password login on Linux to increase security” for more info.

3. Disable password based login

All password-based logins must be disabled. Only public key based logins are allowed. Add the following in your sshd_config file:
AuthenticationMethods publickey
PubkeyAuthentication yes

Older version of SSHD on CentOS 6.x/RHEL 6.x user should use the following setting:
PubkeyAuthentication yes

4. Limit Users’ ssh access

By default, all systems user can login via SSH using their password or public key. Sometimes you create UNIX / Linux user account for FTP or email purpose. However, those users can log in to the system using ssh. They will have full access to system tools including compilers and scripting languages such as Perl, Python which can open network ports and do many other fancy things. Only allow root, vivek and jerry user to use the system via SSH, add the following to sshd_config:
AllowUsers vivek jerry
Alternatively, you can allow all users to login via SSH but deny only a few users, with the following line in sshd_config:
DenyUsers root saroj anjali foo
You can also configure Linux PAM allows or deny login via the sshd server. You can allow list of group name to access or deny access to the ssh.

5. Disable Empty Passwords

You need to explicitly disallow remote login from accounts with empty passwords, update sshd_config with the following line:
PermitEmptyPasswords no

6. Use strong passwords and passphrase for ssh users/keys

It cannot be stressed enough how important it is to use strong user passwords and passphrase for your keys. Brute force attack works because user goes to dictionary based passwords. You can force users to avoid passwords against a dictionary attack and use john the ripper tool to find out existing weak passwords. Here is a sample random password generator (put in your ~/.bashrc):

genpasswd() {
	local l=$1
       	[ "$l" == "" ] && l=20
      	tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}

Run it:
genpasswd 16
Output:

uw8CnDVMwC6vOKgW

7. Firewall SSH TCP port # 22

You need to firewall ssh TCP port # 22 by updating iptables/ufw/firewall-cmd or pf firewall configurations. Usually, OpenSSH server must only accept connections from your LAN or other remote WAN sites only.

Netfilter (Iptables) Configuration

Update /etc/sysconfig/iptables (Redhat and friends specific file) to accept connection only from 192.168.1.0/24 and 202.54.1.5/29, enter:

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT

If you’ve dual stacked sshd with IPv6, edit /etc/sysconfig/ip6tables (Redhat and friends specific file), enter:

 -A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT

Replace ipv6network::/ipv6mask with actual IPv6 ranges.

UFW for Debian/Ubuntu Linux

UFW is an acronym for uncomplicated firewall. It is used for managing a Linux firewall and aims to provide an easy to use interface for the user. Use the following command to accept port 22 from 202.54.1.5/29 only:
$ sudo ufw allow from 202.54.1.5/29 to any port 22
Read “Linux: 25 Iptables Netfilter Firewall Examples For New SysAdmins” for more info.

*BSD PF Firewall Configuration

If you are using PF firewall update /etc/pf.conf as follows:

pass in on $ext_if inet proto tcp from {192.168.1.0/24, 202.54.1.5/29} to $ssh_server_ip port ssh flags S/SA synproxy state

8. Change SSH Port and limit IP binding

By default, SSH listens to all available interfaces and IP address on the system. Limit ssh port binding and change ssh port (many brutes forcing scripts only try to connect to TCP port # 22). To bind to 192.168.1.5 and 202.54.1.5 IPs and port 300, add or correct the following line in sshd_config:

Port 300
ListenAddress 192.168.1.5
ListenAddress 202.54.1.5

A better approach to use proactive approaches scripts such as fail2ban or denyhosts when you want to accept connection from dynamic WAN IP address.

9. Use TCP wrappers (optional)

TCP Wrapper is a host-based Networking ACL system, used to filter network access to the Internet. OpenSSH does support TCP wrappers. Just update your /etc/hosts.allow file as follows to allow SSH only from 192.168.1.2 and 172.16.23.12 IP address:

sshd : 192.168.1.2 172.16.23.12 

See this FAQ about setting and using TCP wrappers under Linux / Mac OS X and UNIX like operating systems.

10. Thwart SSH crackers/brute force attacks

Brute force is a method of defeating a cryptographic scheme by trying a large number of possibilities (combination of users and passwords) using a single or distributed computer network. To prevents brute force attacks against SSH, use the following software:

  • DenyHosts is a Python based security tool for SSH servers. It is intended to prevent brute force attacks on SSH servers by monitoring invalid login attempts in the authentication log and blocking the originating IP addresses.
  • Explains how to setup DenyHosts under RHEL / Fedora and CentOS Linux.
  • Fail2ban is a similar program that prevents brute force attacks against SSH.
  • sshguard protect hosts from brute force attacks against ssh and other services using pf.
  • security/sshblock block abusive SSH login attempts.
  • IPQ BDB filter May be considered as a fail2ban lite.

11. Rate-limit incoming traffic at TCP port # 22 (optional)

Both netfilter and pf provides rate-limit option to perform simple throttling on incoming connections on port # 22.

Iptables Example

The following example will drop incoming connections which make more than 5 connection attempts upon port 22 within 60 seconds:

#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --set
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --update --seconds 60 --hitcount 5 -j DROP

Call above script from your iptables scripts. Another config option:

$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
# another one line example
# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT

See iptables man page for more details.

*BSD PF Example

The following will limits the maximum number of connections per source to 20 and rate limit the number of connections to 15 in a 5 second span. If anyone breaks our rules add them to our abusive_ips table and block them for making any further connections. Finally, flush keyword kills all states created by the matching rule which originate from the host which exceeds these limits.

sshd_server_ip="202.54.1.5"
table <abusive_ips> persist
block in quick from <abusive_ips>
pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload <abusive_ips> flush)

12. Use port knocking (optional)

Port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports. Once a correct sequence of connection attempts is received, the firewall rules are dynamically modified to allow the host which sent the connection attempts to connect to the specific port(s). A sample port Knocking example for ssh using iptables:

$IPT -N stage1
$IPT -A stage1 -m recent --remove --name knock
$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2
 
$IPT -N stage2
$IPT -A stage2 -m recent --remove --name knock2
$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven
 
$IPT -N door
$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2
$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1
$IPT -A door -p tcp --dport 1234 -m recent --set --name knock
 
$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT
$IPT -A INPUT -p tcp --syn -j door

For more info see:

13. Configure idle log out timeout interval

A user can log in to the server via ssh, and you can set an idle timeout interval to avoid unattended ssh session. Open sshd_config and make sure following values are configured:
ClientAliveInterval 300
ClientAliveCountMax 0

You are setting an idle timeout interval in seconds (300 secs == 5 minutes). After this interval has passed, the idle user will be automatically kicked out (read as logged out). See how to automatically log BASH / TCSH / SSH users out after a period of inactivity for more details.

14. Enable a warning banner for ssh users

Set a warning banner by updating sshd_config with the following line:
Banner /etc/issue
Sample /etc/issue file:

----------------------------------------------------------------------------------------------
You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:

+ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limited to,
penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM),
law enforcement (LE), and counterintelligence (CI) investigations.

+ At any time, the XYZG may inspect and seize data stored on this IS.

+ Communications using, or data stored on, this IS are not private, are subject to routine monitoring,
interception, and search, and may be disclosed or used for any XYZG authorized purpose.

+ This IS includes security measures (e.g., authentication and access controls) to protect XYZG interests--not
for your personal benefit or privacy.

+ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching
or monitoring of the content of privileged communications, or work product, related to personal representation
or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work
product are private and confidential. See User Agreement for details.
----------------------------------------------------------------------------------------------

Above is a standard sample, consult your legal team for specific user agreement and legal notice details.

15. Disable .rhosts files (verification)

Don’t read the user’s ~/.rhosts and ~/.shosts files. Update sshd_config with the following settings:
IgnoreRhosts yes
SSH can emulate the behavior of the obsolete rsh command, just disable insecure access via RSH.

16. Disable host-based authentication (verification)

To disable host-based authentication, update sshd_config with the following option:
HostbasedAuthentication no

17. Patch OpenSSH and operating systems

It is recommended that you use tools such as yum, apt-get, freebsd-update and others to keep systems up to date with the latest security patches:

18. Chroot OpenSSH (Lock down users to their home directories)

By default users are allowed to browse the server directories such as /etc/, /bin and so on. You can protect ssh, using os based chroot or use special tools such as rssh. With the release of OpenSSH 4.8p1 or 4.9p1, you no longer have to rely on third-party hacks such as rssh or complicated chroot(1) setups to lock users to their home directories. See this blog post about new ChrootDirectory directive to lock down users to their home directories.

19. Disable OpenSSH server on client computer

Workstations and laptop can work without OpenSSH server. If you do not provide the remote login and file transfer capabilities of SSH, disable and remove the SSHD server. CentOS / RHEL users can disable and remove openssh-server with the yum command:
$ sudo yum erase openssh-server
Debian / Ubuntu Linux user can disable and remove the same with the apt command/apt-get command:
$ sudo apt-get remove openssh-server
You may need to update your iptables script to remove ssh exception rule. Under CentOS / RHEL / Fedora edit the files /etc/sysconfig/iptables and /etc/sysconfig/ip6tables. Once done restart iptables service:
# service iptables restart
# service ip6tables restart

20. Bonus tips from Mozilla

If you are using OpenSSH version 6.7+ or newer try following settings:

#################[ WARNING ]########################
# Do not use any setting blindly. Read sshd_config #
# man page. You must understand cryptography to    #
# tweak following settings. Otherwise use defaults #
####################################################
 
# Supported HostKey algorithms by order of preference.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
 
# Specifies the available KEX (Key Exchange) algorithms.
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
 
# Specifies the ciphers allowed
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
 
#Specifies the available MAC (message authentication code) algorithms
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
 
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
 
# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp  /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO

You can grab list of cipher and alog supported by your OpenSSH server using the following commands:
$ ssh -Q cipher
$ ssh -Q cipher-auth
$ ssh -Q mac
$ ssh -Q kex
$ ssh -Q key

How do I test sshd_config file and restart/reload my SSH server?

To check the validity of the configuration file and sanity of the keys for any errors before restarting sshd, run:
$ sudo sshd -t
Extended test mode:
$ sudo sshd -T
Finally restart sshd on a Linux or Unix like systems as per your distro version:
$ sudo systemctl start ssh ## Debian/Ubunt Linux##
$ sudo systemctl restart sshd.service ## CentOS/RHEL/Fedora Linux##
$ doas /etc/rc.d/sshd restart ## OpenBSD##
$ sudo service sshd restart ## FreeBSD##

Other susggesions

  1. Tighter SSH security with 2FA – Multi-Factor authentication can be enabled with OATH Toolkit or DuoSecurity.
  2. Use keychain based authentication – keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible. It offers various security benefits over passphrase-free keys

See also:

  • The official OpenSSH project.
  • Man pages: sshd(8),ssh(1),ssh-add(1),ssh-agent(1)

If you have a technique or handy software not mentioned here, please share in the comments below to help your fellow readers keep their OpenSSH based server secure.

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source & DevOps topics via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
174 comments… add one
  • Philippe Petrinko Jan 26, 2015 @ 13:41

    @ Cody,

    Thanks for your update, you made your point quite clear, shorter and simplier than your average post I read in this topic. 😉

    Please accept my apologies for my laziness with english spelling! (Thanks for letting me know, I think I’ll recall it better now. Let’s go back to practice my merriam-webster online – I do enjoy this one, even if it’s US, not UK 🙂 ).

    • Cody Jan 26, 2015 @ 14:43

      .. ick. Merriam Webster. (Indeed the reason I say that is exactly because it is US and more than that Noah Webster and his absurd amount of changes – and attempts at further changes – in English. Language is for communication and changing a language by creating many differences (in spelling and otherwise) is hardly helpful for communication).

      (And no problem on the update. I did suggest I can easily confuse and while I wasn’t then – and don’t here in general – I do admit sometimes (probably a lot! it is really funny to me to make people think “what the hell is he saying” and even more so when I’m subtly saying something they wouldn’t expect; *shrug* no one is perfect, eh ?) I do it just out of the great amusement it gives me. I am quirky in many ways and I show it just as many ways, writing included. And for the spelling – love the pun there! No such thing as a bad pun, far as I”m concerned. No, I was only correcting you because I know many who do not speak (as first language) English like to know what is correct and what isn’t – I really find that trait commendable!).

      Cheers.

  • Cody Jan 25, 2015 @ 18:01

    Ironically I rather agree with you. On the other hand you need to improve your reading comprehension (to be fair it might also be the way I word things – that can trip people up even when I’m not doing it deliberately). I was not at all suggesting it was a good idea. Quite the opposite.

    • Philippe Petrinko Jan 25, 2015 @ 21:35

      @Cody

      Well, to be fair,
      Your answer was so long to me, and your wording was so unprecise, vague, ambiguous (again, to me) and that it seems that you also meant
      “yes in a way,
      but may be not,
      it depends,
      somehow, blah, blahn blah, and that’s life…”

      Anyway, to keep it short and simple (you may need to improve on this 😉 ),
      for saying a simple thing (that I tried to sum up in a punchy way : no good reason to let “root” use ssh) that I figured out :
      – either you were making a joke
      – either we disagree.

      AFAIK, TINA: there is no alternative: kill the root access through ssh, unless you want to get in trouble…

      –P

      • Cody Jan 26, 2015 @ 0:20

        Let me try explaining it then.

        I was responding to this bit: “Isnt the point about preventing root login, being still valid in 2015, to prevent an attacker to have a valid user to attemp connection to ssh server?”

        So when I write:
        “That is one of the points, yes. Some dismiss it, though. Some have their own reasons, needs, whatever. Doesn’t mean the point you refer to is less valid though.”
        It means yes, it is A point (hence one of THE). BUT some dismiss it (the second sentence as starter). Then I elaborate on how others have different needs/wants and even refuse to acknowledge the existence of other alternatives (that would solve their so called problem). That is – just as I also explain – much like so many other things in this life. No, there was no ambiguity in my points; you just didn’t follow it all – something tripped you up (I suspect the fact I was remarking on those for and those against). It really doesn’t matter what, though – what matters is you accept that. See, just like people dismissing things because they do whatever they want to (and believe what they want to and can’t admit they’re wrong when they are)… well so too can people make mistakes. The only true mistake is not accepting you can make mistakes (and if you can – which I gather you can – you can learn so much more). Basically, I was responding to all angles of the point: those for the restrictions (and they’re right and you agree) and those against it (and they’re wrong but they still have their reasons – just like everything in this world). Yes, it is asking for trouble as you rightly point out. Even if it wasn’t asking for trouble security wise, it is asking for trouble in other ways. Doesn’t mean everyone cares though!

        Does that make sense ? Maybe I shouldn’t ask…

        • Philippe Petrinko Jan 26, 2015 @ 12:08

          @Cody

          First, let me say I do appreciate your contributions to this site and topic.

          At least, you build a strong technical answer and give and share your experience and knowledge, that is my first agreement.

          Second, I am confortable with the fact I could make any mistake, including misinterpreting your wording. And I have no problem admitting I could be wrong and learn from my mistakes, and admitting I do not own “truth” in any way. Plus, english is not my native language, nobody’s perfect. 🙂

          Third, I am just asking : Do you know any good reasons you would _personally_ let root a direct login through ssh? (Would you please just answer a simple “No”. If you mean “Yes”, then please elaborate your personal arguments in a specific environment, just to prevent a generic answer that would lead to nowhere precise and useful – IMNSHO ).

          • Cody Jan 26, 2015 @ 13:03

            I deny it outright. Just like I deny password logins (keys + passphrases). I thought I was clear with that. So ANSWER: No. There is no valid (keyword valid) reason.

            Elaboration here: Indeed I am not at all perfect either. I find that a strength even because it means I can learn more. I actually thought I did answer that question but apparently I neglected it in the end (a consequence of wording things on the go as well as being preoccupied at the same time). Not only do I not think there’s any good reason, I KNOW there isn’t a single valid reason to allow root to log in via ssh. There is no need for it. I might have referred to that here, even (in another post in this thread). I don’t know why people think they need to. I also don’t understand it: if they can LOG IN with root (via ssh) WHY CAN’T they log in with a normal user ? root IS the privileged account so certainly if they have that the privileges that way they can obtain them after logging in ? Their logic is flawed 100%.

            But what I was trying to get at is: they’ll still make excuses. I believe one of their excuses is they need it for backups. I don’t buy that theory. Even if it IS what they do use it for, there certainly are ways around it (and if they refuse to do acknowledge it, it is as you say – they’re asking for trouble and you’re right. they’re also as I say – they’re refusing to acknowledge the problems with it and they’re making up their excuses, their different environment, blah blah.. it is all flawed though).

            As for your English: it is fine. Lastly, your original message to me, that you ended it with:

            “Ah yeah, except lazyness and incompetence, that’s right! ;-)”

            1. Just as a helpful note: laziness 🙂
            2. You’re right: it is laziness (and a workaround to a supposed problem and workarounds ignore the real issue) and indeed it is incompetency (and ignoring the seriousness of the problems they are ironically creating (when they think they’re fixing a problem)).

  • Gui Jan 8, 2015 @ 14:41

    Isnt the point about preventing root login, being still valid in 2015, to prevent an attacker to have a valid user to attemp connection to ssh server?

    I’ve been told that then the attacker must guess both username and password thus increasing security.

    • Cody Jan 25, 2015 @ 15:37

      That is one of the points, yes. Some dismiss it, though. Some have their own reasons, needs, whatever. Doesn’t mean the point you refer to is less valid though. It IS a fairly static thing, whether it is acceptable given the needs (and what they’re willing to do to solve any potential problems, and I mean solve outside of doing it the way they insist they have to (it isn’t always true but that is also how it works)) is another issue entirely. Indeed, different environments and different circumstances do change things – potentially a lot – but that is how life is with everything, is it not ?

      • Philippe Petrinko Jan 25, 2015 @ 17:16

        Let’s agree we disagree, Cody.

        I haven’t seen yet a single good reason why a responsible administrator should let “root” use ssh.

        Ah yeah, except lazyness and incompetence, that’s right! 😉

        –P

  • Azat Khanzadyan Sep 12, 2014 @ 11:34

    Hi.
    Thank you !!!!!!!!!!!!!!!

  • Forrest Jul 15, 2014 @ 17:32

    I have the need to implement Idle Log Out Timeout policies on some systems. But, I would like to have exceptions on a couple of accounts. From what I can tell, the SSH configuration doesn’t provide for this.

    Can someone confirm/elaborate?

    • Cody Jul 16, 2014 @ 12:00

      Well I think I should make clear why #4 works at all. It is more like a hack.
      From the sshd_config(5):

      “If this threshold is reached while client alive messages are being sent, sshd will disconnect the client, terminating the session. It is important to note that the use of client alive messages is very different from TCPKeepAlive (below). The client alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by TCPKeepAlive is spoofable. The client alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive.”

      Okay, what does that mean? TCP Keepalives allow idle connections (no packets seen) to maintain a connection under the conditions as such:
      1) Server sends keepalive probe.
      2) If client responds, keep connection and stop. Else, continue.
      3) Send another probe at a (programmable) interval. Do this up to X times (also programmable, as is keepalive in general). If no response from the client is seen, the connection is considered ‘dead’ and it timesout.

      Above it states TCP keepalive being spoofable. I don’t know for sure but I suspect what it is getting at is you don’t have to actually USE the connection in order for keepalive responses to be sent (so you can remain idle yet your connection is maintained).

      Meanwhile, the other option is saying: if connection is idle, as in no command input (maybe output – not sure.. didn’t check), then send a probe. But since the max is 0, it doesn’t give the client a chance.
      It is interesting to note, however, that based on a test just now: not sending a command while max > 0 it still seems fine (this is connecting/logging in AFTER setting the max and reloading/restarting configuration). However, at 0 (and same thing: logging in AFTER) it disconnects. That seems more like tcp keepalives but given that it is not yet 5 (actually looked back and now it is 5, about to hit submit) and I’ve been awake since a bit before 2, well… I could be reading something wrong (or doing something wrong). As for TCP keepalives, I know that part is correct because I use those options in a service I am the programmer for.

      That being noted: I don’t immediately see an option for this, aside from (and not confirmed) placing it in to their own ssh file (and in which case they could update). So unless I’m missing something (which IS entirely possible) then no, you’ll need to resort to other methods. The only thought is if you can use this in one of the client matches in the sshd config file itself. Hmm, looking at the man page again, the Match blocks do not allow the above options, so you’ll need to resort to something else. This is for sshd 5.3p1-94.

      HTH.

  • male Jul 2, 2014 @ 7:14

    #16: Thwart SSH Crackers (Brute Force Attack)
    pam-abl is missing, which is pretty usefull thing.

  • Bobba Jun 25, 2014 @ 8:27

    Bob is an Idiot.
    The reason to disallow remote-root logins is so you could track which of your sysadmins logged in and used su/do to become root.
    I, for one, prefer that someone who wants to pwn my servers will have to figure out TWO passwords, and not just one.
    It was never about “first packets”. That attack was for telnet, not SSH. SSH was always properly encrypted.

    • Cody Jun 25, 2014 @ 16:51

      He is an idiot. But I think that he was getting at now that there IS encryption there is no need to disable it. Problems of that logic are many and that is not even considering that yes, two passwords are better than one. And even more than that: ssh key with passphrase on top of normal user passwords and root passwords. But even his wording of spoof and passwords makes one wonder what he was on … spoofed passwords ? What you see is that he’s using spoof and sniff interchangeably and that is hilarious itself. And I do not believe for a nanosecond that he made a typo more than once (and he wrote sniff then spoof more than one time both in the idea of sniffing) but I do believe he is talking from the mouth of exactly what he is claiming the idea of ‘disable root logins’ is. In other words, he’s talking/writing as horseshit.

      On the other hand, encryption doesn’t always mean 100% guarantee that there is no interception. Indeed, I seem to remember (and a quick search suggests this) there being a MiTM attack with SSH1.

      As for the suggestions on this page, I cannot recall if I ever remarked about them. But I’ll point out some things anyway: changing port doesn’t really do much except for script kiddies. If you are running sshd and they want to find out they will (They = more skilled than script kiddies). But see later where I discuss that even this is not really all that useful. I’d argue that similar is for port knocking although there’s definitely more to it (but if you can filter by IP then there’s usually no need to do that). As I seem to remember, port knocking has other uses though, including getting around filters (I might be remembering something wrong or even mixing this up with other techniques… one that just came to mind being tunnels which could definitely be an option there.. but I seem to remember port knocking having uses otherwise as well).
      As for su versus sudo (which after checking, I think this was a different thread on this site… but well, it applies to logging in, so..) I think there’s one key difference that some seem to miss, with whether or not is a good option. Indeed it has its uses. But depending on setup and who needs access to what logins, then not using sudo means they need more than one password. Of course there is also requiring them being in the wheel group in addition to that. sudo definitely has uses (for instance: one command and the defined options/etc. allowed and nothing else is forbidden) but it isn’t the only option and some times it is not the best option; it all depends on the environment.

      While ssh chroot might be OK just keep in mind that it has inherent security risks (chroot in general, that is).

      Ignoring .rhosts file is obviously a good thing because let’s not forget that it allowed logging in with any IP with no password, aside from other issues.

      I seriously doubt a warning will matter to an attacker. Such legal statements are silly as it has (in most countries) long been illegal to log in to another computer with a password that you yourself are not authorised to use. So what difference does it make to add a warning? It won’t make them thing, “Well I thought this was a good idea but maybe I better not…” The fact they already connected is likely noticed and if they were meaning to attack they obviously do not care about any silly statements about legalities (they already were planning on ignoring the law).

      On PAM, do be careful how you set that up as that can be a problem. Apache actually has documented this mistake (after they were compromised.. they have typically given detailed analysis of breaches).

      And lastly, back to the subject of changing ports. I’m sorry to inform but unless this was a skilled attacker (I doubt it) then brute force tools do more than just use the standard port. I know this because there was a mistake on a server after an updated firewall (I seem to remember it was due to my IP block changing and the other administrator forgot to deny everyone else on forwarding, see next part) that made me see on an internal host brute force login attempts (as root and other users). The problem then is that if ssh itself was already bound to 22 on the main server, then if forwarding a port to ssh on the internal server (think: vm) then it cannot use port 22, can it? No, so it uses another port and forwards it to the internal server at the proper port. In other words the internal port 22 is only reachable by the _other_ external port (that is not 22). So once again, changing port has no value in normal circumstances. In the normal circumstances it actually makes things worse if you rely on that because you have a false sense of security (even if that is “one less thing to worry about” – sorry to inform you but that is NOT something you should not worry about).

  • Gaston Wagner Mar 19, 2014 @ 21:32

    md5 pass:
    echo “A great password” | md5sum

    generate random password:
    tr -cd [:alnum:][:punct:] < /dev/urandom | head -c 20 ; echo

  • Anonymous Jun 18, 2013 @ 20:50

    I too disagree with Bob, not only deny ssh as root, but the entire root account should be disabled and use sudo instead, this provides an audit trail that being root does not.

    For those that do not use sudo, still disable ssh as root will make it so if in the obscenely rare case you are attacked, said attacker now needs 2 passwords, normal user and root to gain root access.

    Limiting the su command to the wheel group is also a great idea.

    I alos suggest Bob get a spell checker.

    thanks

    • Cody Jun 18, 2013 @ 23:56

      How exactly do you suppose you’re going to disable root ? Do you mean disable it except on certain consoles (through /etc/securetty or /etc/login.defs) ? Or do you mean one cannot use ‘sudo su -‘ to change to root (which to me is not the same as disabling root; root is still enabled but you’re restricting who can become root). And if you mean by shell then that is easily defeated (again unless of course you are talking about sudo only where you can limit commands and arguments given). If root didn’t have a shell (say /sbin/nologin) then I would think that would have some real problems in certain cases too (been a while since I’ve looked at initscripts but there might be a problem for emergency logging in). Even if there is not a problem with emergency shell then you have to remember that if there’s physical access there is the possibility of editing the init part in the boot loader. Ah well, just some random thoughts.

      Based on how you worded the post I assume you mean don’t allow ‘su -‘ either by sudo or otherwise. But still root is not itself disabled.

      And you’re correct that two different passwords is better than one (though there’s also been debates over the years on this issue relating to strength of passwords). But since we’re talking ssh the better way is:

      a key with a passphrase attached to it and disallow password logins in ssh, period.

      wheel is indeed another option although su is not the only command with the execute suid bit (not that it’s the same thing but that doesn’t mean suid cannot be abused to escalate privileges).

      And I know I should resist the temptation since no one is perfect and this is not a typing class (or even anything that needs to be professionally proofread – this post is just as unprofessional as any other) but I have very little willpower with this type of thing: the same sentence you suggest Bob uses a spell checker has a typo: alos versus also. As for Bob’s claim that it was only because of unencrypted sessions I have the following to say:

      1) It was not only unencrypted sessions. Another consideration was you have an added layer of defence.
      2) telnet has had for many years encryption (option -x). Whether most servers or clients enable it is frankly irrelevant because it was not the only issue any way.

      As for keychain I don’t understand why the need these days. Why not just use ssh-add ? You can specify a time out, you can clear any sessions and is it really that bad to run it when you log in and just not specify a time out ? People who work on more than one machine surely are used to multiple passwords for multiple types of accounts (and services). And let’s not forget that it’s less of a hassle than, say, password ages (restricting recently used passwords even). That’s not even considering libpwquality (which is far more restrictive than the default password testing). Each to their own of course and maybe there’s other things I don’t remember from keychain (long time ago) that make it more appealing. (This is more a curiosity than anything. I don’t honestly care otherwise – everyone should use what works for themselves.)

  • rups Jun 17, 2013 @ 13:03

    Hi its a very nice tutorial.

    I was looking for the possible obstacles in implementation of SSH in the network? It would be great if somebody can provide answer.

    Thanks

  • Madhusudan Mar 25, 2013 @ 12:07

    Hi Guys,
    Need a help. Is there any ways you can log/track the operations [Like move,delete] done by a user in a RHEL server using by a WinSCP ??
    Currently I am able to see only login/logout logs in /var/log/sshd.log …
    Is there any ways I can see more logs what exact operations done by a user ??
    Current sshd_config setting for Logging is “LogLevel INFO”.

    Thanks inadvance
    Rao

  • krnkris Feb 6, 2013 @ 15:58

    ‘PermitRootLogin’
    If this option is set to “no”, root is not allowed to log in.

    Based on:
    http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config&sektion=5

  • Boyd Kelly Jan 19, 2013 @ 16:43

    I don’t really agree that Bob’s point about ‘PermitRootLogin no’ is ‘Excellent’. The root account is a known account with elevated privileges. If is is available to log in to remotely, it is also available for a brute force attack. There are other ways of preventing this, but the most simple requiring no resources, it simply to not allow root login remotely, but allow a user with a weird name and very secure password.

  • Kevin Dec 19, 2012 @ 0:50

    Ofcourse what measures you would put in place and to what level they could be called paranoid depends on the purpose of the machine and what you actually do to counteract attacks.
    My homeserver is connected to the internet on some ports, among which SSH.
    I have root disabled, Canonical does this by default (yay) and you need to actually undertake action to be able to use root, if root would be active i’d disable this even though the point of this from a security standpoint could be argued. On top of this i’ve got Fail2Ban running to, among other things, keep an eye on SSH and autoban anything that fails to login more then x-amount of time. Combine that with a custom login name and password of decent length and ofcourse keeping everything reasonbly up to date and having all other sane security configurations in place (like the firewall that allows only ports that are actually going to be used) I am confident all is fine for about 99% of the situations.
    You could do all sorts of fancy things with methods of authentication but to me thats just not worth the hassle.

  • Winston Weinert Oct 31, 2012 @ 16:41

    Another good option is to comment out the “auth” lines for “pam_unix.so” and “pam_opieaccess.so” on FreeBSD. This forces users to either key-based authentication or One Time Passwords. Note that using OTP doesn’t ensure your connection from the client machine is insecure, it’s just a good compromise if you don’t have access to a trusted machine with keys. Don’t do anything you wouldn’t do over telnet when using OTP on an insecure box.

  • Chase Venters Oct 23, 2012 @ 20:04

    The bash function for generating passwords is good, but another good option is the pwgen command available on most Linux distributions through your native repositories.

  • Nathan Oct 23, 2012 @ 19:51

    Disabling root is not simply about making the system more secure it creates a layer of accountability; if every admin has their own account and no one has the root password you can track activity to a specific user/account. Serve those accounts from a central directory service (e.g. LDAP) or use a configuration management tool (e.g. Chef or Puppet) and it becomes a very simple (and reliable) task to (dis|en)able a users access across your infrastructure. Running non-standard ports, while security through obscurity, does *marginally* increase the cost of finding a service that can be exploited by a zero day exploit. VPN’s and restricted IP’s would be preferable but, may not always be an option.

    • Cody Oct 23, 2012 @ 23:40

      On root: true that it makes it more secure and adds to accountability. Maybe I am not following you right on every admin having their own account (so forgive me if this is not what you mean) but: it would depend on what activity you’re referring to. Some you could track more easily but not everything is logged, either (and history can be cleared among other things). Maybe you mean sudo though and in that case it often is an option but not always.

      On the note of finding a a service: that depends on how you look at it, I would say. It does mean it takes more work for those who are very inexperienced and are using a tool that only checks a service by port. But of course there’s many other options out there. Naturally, if you combine changing the port with rate limiting connections per IP (in general) then it will take longer but it still can be done (as in, nmap and many other tools has plenty of potential to slow things down among other options). I think the issue is not “it should not be done because it is security through obscurity” so much as that some will take it as “if I do this that’s all I need to do”. Fine if you do everything else too, but it isn’t a security mechanism by itself and people unfortunately do not put that together. Combine that with the below and it is even worse : Years ago the r* services and telnet were common. Of course, to do remote log on or remote tasks via those (or even allow!) is insane but at one point that was the norm and the point there is the internet protocols weren’t designed with security in mind (so: to think changing a port is all you should do is of course a flaw. Not saying that everyone thinks it is all you need to do, but I am pretty sure some do think like that. That’s why as I mentioned in another post exploits being released to the public is actually good).

      You’re right that restricted IPs is not always an option. But when it is, of course it should be done. It indeed would depend on many circumstances. That’s unfortunate. But changing ports isn’t going to make that go away for anyone who knows how the service works (especially if they have the source to the exploit).

  • anon Oct 23, 2012 @ 16:32
    PasswordAuthentication no

    Please note that this is not enough to use key-only authentication. Depending on the server configuration (e.g., FreeBSD’s out-of-the-box one), you’ll also need to use —

    UsePAM no
    ChallengeResponseAuthentication no

    This is a requirement for any of our servers running sshd, external-facing or not.

  • Erik Oct 18, 2012 @ 23:29

    A couple of things about this:

    On the controversial root login topic:

    In a modern managed environment, it’s almost a requirement that key-based root SSH logins be enabled. There are simply far too many tools which rely on using that functionality. That said, there’s no real good reason to allow “normal” password root logins, so use the above ‘PermitRootLogin without-password’ and ‘PasswordAuthentication no’ – though, note that ALL users will be required to have SSH keys set up. Bastion hosts are a good idea here: create one with no root logins allowed via SSH, and all users have to password login. You can then set up key-based logins from that host to all the appropriate infrastructure. Admin Users can then log into other machines as themselves before ‘su’ or ‘sudo’ to root, AND you have left open root key’d SSHs for the automation. In addition, ‘sudo’ is NOT a complete replacement for ‘su’ – there are a number of cases I can quote you where running sudo will NOT work, while running after a ‘su – ‘ WILL. EVen when sudo options claim to DoTheRightThing. Sometimes, root just is better.

    DON’T play the “change SSHD port to something besides 22” game. It’s merely security through obscurity (which is practically worthless), and leads to a whole lot of extra configuration EVERYWHERE, which in turn leads to many more opportunities for mistakes. Leave it running on the default port. It’s a default, for a reason.

    For the same reasons, I’d avoid port knocking. It’s a huge hassle, and doesn’t add much security, and only adds complexity everywhere. Simplicity of configuration adds far more security than a complicated scheme.

    To the above poster on the authorized_keys filename: virtually all SSH (including modern OpenSSH) implementations never bothered to make the switch to requiring authorized_keys2 for Protocol2 keys. Nowdays, virtually all implementations use ONLY the authorized_keys file (and won’t look at authorized_keys2) and file all keys there, so the article should be kept as-is.

    Finally, to recommending a 4096 keylength: that’s excessive. 2048 is *very* sufficient for anytime in the future we care about, and there’s a non-trivial penalty to pay for that added keylength, particularly if you run a system that has very frequent SSH logins. A 4096-bit key is NOT twice as long as a 2048-bit key, it’s 2048-times as long, and can easily quadruple or more the time to do authentication. Modern factoring techniques can’t even approach a 2048-bit key, and unless there’s a algorithmic breakthrough, any hardware in our professional lifetime won’t either. Use 4096 bits only to satisfy some pedantic legality.

    • Cody Oct 20, 2012 @ 19:31

      True. Though I would say that security through obscurity isn’t practically worthless but instead it is more harmful and therefore completely worthless. The same applies to a badly configured firewall, even.

      Security through obscurity (and companies relying on it – especially companies that have products of their own with a security flaw) is a reason why people will make public flaws and even exploits for those flaws/holes. Some say releasing exploits is harmful and unethical and whatever else but I would rather ask them this:

      Would you prefer the company be FORCED to fix it or would rather prefer that it’s not made public and instead wait until someone with bad intentions finds it and abuses it ? Obscure does not mean it can’t be found. And what if it is a product YOU or your COMPANY uses ?

      Fact is companies do ignore these things and so it is good that people release the exploits. Microsoft has indeed ignored many things and that’s the least of it: they have even made claims that some backdoors (and probably other types of exploits/etc) were less serious than they seem. To that I say: 1) Do they care that little about their customers ? If a building inspector found a hole or crack in a ceiling in a building and ignored it and signed it off as OK, wouldn’t you be unhappy ? Should be: it’s a safety risk. A risk is a risk no matter how minor someone thinks it is. 2) Are they too lazy or incapable of fixing the problem and that is why they dismiss it as not an issue ?

      But of course they’re not the only ones in that. As for the Microsoft case I am thinking of the BackOrifice family of backdoors.

  • AdvancedBeginner Oct 15, 2012 @ 16:14

    I would not recommend showing a banner with explanation of “XYZ system you are accessing” as it gives more clues/confirmation to those wanting to breach into your network… if they are here, quite possibly they are here for reason…

    • Cody Feb 19, 2015 @ 1:33

      They likely already have the information from other places. Still, there is no need to include this information; they don’t care about your policy – if they’re there to root your server, they’re already disregarding the law, why would your warning make them rethink it ? The law is the law, right ? (I mean of course I’m neglecting those in authority .. the law is the law for citizens)

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.