1. Disallow remote root logins
  2. use a port other than 22/TCP
  3. Deploy one of the SSH brute force prevention tools: fail2ban or denyHosts
  4. Use AllowGroups, AllowUsers, DenyUsers to limit access to a specific group of users
  5. If you must use passwords, ensure that they are complex
  6. Limit the IP ranges that can connect to SSH via tcpwrappers(hosts.deny)
  7. alzare il firewall di notte
  8. Set PasswordAuthentication to "no" and use keys

no root remote login

adduser $user
gpasswd -a $user sudo
nano /etc/ssh/sshd_config
PermitRootLogin no
# only $user can login with ssh
AllowUsers $user
service ssh restart
# additionaly, enforce IP whitelist/blacklist via hosts.deny
secure passwords
PermitEmptyPasswords no

also, ssh users and specially root, should have 16 char alphanum passwords

port number

and restart the SSH service:

Port 22

Idle Log Out Timeout

idle timeout to avoid unattended ssh session

ClientAliveInterval 300
ClientAliveCountMax 0

Allow only SSH protocol 2

Using SSH protocol 2 only is much more secure

Protocol 2

Default Config Files and SSH Port

/etc/ssh/sshd_config - OpenSSH server configuration file.
/etc/ssh/ssh_config - OpenSSH client configuration file.
~/.ssh/ - Users ssh configuration directory.
~/.ssh/authorized_keys or ~/.ssh/authorized_keys - Lists the public keys (RSA or DSA) that can be used to log into the user's account
/etc/nologin - If this file exists, sshd refuses to let anyone except root log in.
/etc/hosts.allow and /etc/hosts.deny : Access controls lists that should be enforced by tcp-wrappers are defined here.
SSH default port : TCP 22

no obvious user

no root

create a dummy local user with no rights, use that user to login, put it in the wheel group, so that you can sudo

PermitRootLogin no
AllowUsers aa bb cc
AllowUsers deploy@(your-ip) deploy@(another-ip-if-any)
no system user

be careful system users(ftpd, apache, www ...)

allow only specific users:

AllowUsers user1 user2
AllowUsers deploy@(your-ip) deploy@(another-ip-if-any)

deny sys users

DenyUsers  user1 user2

list user that can potentially access the system:

cat /etc/passwd | grep /bin/sh
cat /etc/passwd | grep -v nologin | grep -v /bin/false

oppure cambiare la shell in /bin/false

Disable .rhosts files, Disable Host-Based Authentication Don't read the user's ~/.rhosts and ~/.shosts files

IgnoreRhosts yes
HostbasedAuthentication no

SSH time-lock tricks

You can also use different iptables parameters to limit connections to the SSH service for specific time periods. You can use the /second, /minute, /hour, or /day switch in any of the following examples.

In the first example, if a user enters the wrong password, access to the SSH service is blocked for one minute, and the user gets only one login try per minute from that moment on:

iptables -A INPUT -p tcp -m state --syn --state NEW --dport 22 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
iptables -A INPUT -p tcp -m state --syn --state NEW --dport 22 -j DROP

In a second example, iptables are set to allow only host 193.180.177.13 to connect to the SSH service. After three failed login tries, iptables allows the host only one login try per minute:

iptables -A INPUT -p tcp -s 193.180.177.13 -m state --syn --state NEW --dport 22 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
iptables -A INPUT -p tcp -s 193.180.177.13 -m state --syn --state NEW --dport 22 -j DROP
#SSH anti brute force
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 5 --rttl --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

only trusted IP

accept connection only from 192.168.1.0/24 and 202.54.1.5/29,

via firewall:

nano /etc/sysconfig/iptables (Redhat)
-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 ACC

via tcpwrappers hosts.allow hosts.deny:

nano /etc/hosts.allow
sshd: 192.168.1.2
nano /etc/hosts.deny
sshd: 192.168.1.2
ALL: 74.52.109.

Rate-limit Incoming Port # 22 Connections

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

#!/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

Use Log Analyzer

to use logwatch, make sure LogLevel is set to INFO or DEBUG in sshd_config

LogLevel INFO

hide openssh version

at the moment you need to update source code and compile openssh again

Stunnel proxy

adds SSL encription("secure tunnel") support to unencripted protocols.

apt-get install stunnel4 -y
nano /etc/stunnel/stunnel.conf
client = no
[squid]
accept = 8888
connect = 127.0.0.1:3128
cert = /etc/stunnel/stunnel.pem

Remote Command Call

ssh user@host 'ls -l; ps -aux; whoami'