android bsd linux unix & open-source world


SSH Security Tips – OpenSSH hardening security

WP Greet Box icon
Hello there! If you are new here, you might want to subscribe to the RSS feed or subscribe via E-mail for updates on this topic.

In this article I'll show you some tricks to help you securing your OpenSSH service. Here you will find useful information on how to secure sshd and prevent ssh dictionary attack.

1. SSH security by tweaking sshd_config

The OpenSSH server configuration file is located in /etc/ssh/sshd_config. You need to restart sshd after every change you make to that file in order for changes to take effect.

  • Change port number

Moving the SSH daemon off of port 22 protects you against automated attacks which assume that sshd is running on port 22.

Port 34912

  • Allow only SSH protocol 2

Only SSH protocol version 2 connections should be permitted. Version 1 of the protocol contains security vulnerabilities. The default setting shipped in the configuration file is correct, but it's important to check.

Protocol 2

  • Disable root logins via ssh

The root user should never be allowed to login directly over a network. This is critical because many systems are exploited by allowing a remote user to attempt to "brute force" the root password by trying passwords over and over again.

PermitRootLogin no

  • Allow only specific users/groups to log in via SSH

By default, the SSH configuration allows any user to access the system. In order to allow all users to login
via SSH but deny only a few users or groups, add the following lines:

DenyUsers USER1 USER2
DenyGroups GROUP1 GROUP2

Alternatively, if it is appropriate to allow only a few users or groups access to the system via SSH:

AllowUsers USER1 USER2@
AllowGroups GROUP1 GROUP2

  • Disable .rhosts Files

SSH can emulate the behavior of the obsolete rsh command in allowing users to enable insecure access to their
accounts via .rhosts files. It's highly recommended to disable this.

IgnoreRhosts yes

  • Disable Host-Based Authentication

SSH's cryptographic host-based authentication is slightly more secure than .rhosts authentication, since hosts
are cryptographically authenticated. However, it is not recommended that hosts unilaterally trust one another.

HostbasedAuthentication no

  • Enable rsa key only authentication and disable password authentication

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile     .ssh/authorized_keys

PasswordAuthentication no

NOTE 1: Make sure you already have a working ssh key authentication before disabling password authentication. To set up openssh key authentication use this tutorial.

NOTE 2: If you still use password authentication you should disallow remote login from accounts with empty passwords:

PermitEmptyPasswords no

2. SSH security using TCP Wrappers

TCP Wrapper is a host-based Networking ACL system, used to filter network access to Internet Protocol  servers on Unix-like operating systems such as Linux or BSD. It allows host or subnetwork IP addresses, names and/or ident query replies, to be used as tokens on which to filter for access control purposes.

Using TCP wrappers to allow only specific hosts to connect

This approach is useful if you would like to allow only specific hosts on a network to be able to connect to your SSH service, but you don't want to use your firewall configuration.

I'll make a rule to allow only hosts on my local subnet and remote host 195.181.x.y to connect to my SSH service.

By default TCP wrappers first look in the /etc/hosts.deny file to see what hosts are denied for what service. Next, TCP wrapper looks in /etc/hosts.allow file to see if there are any rules that would allow hosts to connect to a specific service.

I'll create a rule like this in /etc/hosts.deny:

sshd: ALL

This means that by default all hosts are forbidden to access the SSH service. This needs to be here, otherwise all hosts would have access to the SSH service, since TCP wrappers first looks into hosts.deny file and if there is no rule regarding blocking SSH service, any host can connect.

Next, create a rule in /etc/hosts.allow to allow only specific hosts to use the SSH service:

sshd: 192.168.1 195.181.x.y

Now only hosts from the network and the 195.181.x.y host can access the SSH service. All other hosts are disconnected with the following error:

ssh_exchange_identification: Connection closed by remote host

NOTE: Unlike other implementations of TCP Wrappers, the use of hosts.deny has been deprecated in FreeBSD. All configuration options should be placed in /etc/hosts.allow.

3. SSH security using a Firewall

A firewall is a part of a computer system or network that is designed to block unauthorized access while permitting authorized communications. It is a device or set of devices which is configured to permit or deny computer applications based upon a set of rules and other criteria.

  • Linux and iptables

- allow ssh connection only from a specified host ( in our case ):

iptables -A INPUT -p tcp -m state --state NEW --source --dport 34912 -j ACCEPT

- prevent dictionary attack by limiting ssh connection:

iptables -N SSH_RULE
iptables -A INPUT -p tcp --dport
34912 -m state --state NEW -j SSH_RULE
iptables -A SSH_RULE -m recent --set --name SSH
iptables -A SSH_RULE -m recent --update --seconds 30 --hitcount 4 --name SSH -j DROP

This will create a new chain SSH_RULE, and all incoming SSH connection will go into this chain to test the condition. Condition is, for any source IP address there cannot be more than 3 SSH connection attempts within a 30 seconds window. If condition has been met, then all packets from that source IP address will be dropped.
That source IP can only connect again if condition is cleared again, i.e. there has been 30 seconds of quiet time.

NOTE: You should replace 34912 with the port defined in sshd_config.

  • BSD and packet filter ( pf )

- allow ssh connection only from a specified host ( in our case ):

pass in on $ext_if inet proto tcp from to $ext_if port 34912 keep state

- prevent dictionary attack by limiting ssh connection:

pass in on $ext_if proto tcp to ($ext_if) port 34912 keep state (max 100, source-track rule, max-src-nodes 75, max-src-states 3)

NOTE: You should replace 34912 with the port defined in sshd_config and $ext_if with your external network card.

Print This Post Print This Post
Comments (3) Trackbacks (0)
  1. WOW cool article man. Keep posting stuff like this because I really enjoy them.

  2. I truly relished your article and now I’ve bookmarked it on my delicious, mr wong, stumble accounts.

  3. I want to quote your post in my blog. It can?
    And you et an account on Twitter?

Leave a comment


No trackbacks yet.