Search This Blog

Showing posts with label ssh. Show all posts
Showing posts with label ssh. Show all posts

Thursday, February 12, 2009

E-mail Alert on Root SSH Login

Want to be notified instantly when someone logs into your server as root? No problem, check out this nice tutorial on email notification for root logins. Keeping track of who logs into your server and when is very important, especially when you're dealing with the super user account. We recommend that you use an email address not hosted on the server your sending the alert from.

So lets get started!

  • Login to your server and su to root.
  • vim /root/.bashrc
  • Scroll to the end of the file then add the following:
echo 'ALERT - Root Shell Access (YourserverName) on:' `date` `who` | mail -s "Alert: Root Access from `who | cut -d'(' -f2 | cut -d')' -f1`" you@yourdomain.com
  • Replace YourServerName with the handle for your actual server
  • Replace you@yourdomain.com with your actual email address
  • Now logout of SSH, close the connection and log back in! You should receive an email address of the root login alert a few minutes afterwards.

Note: This is a great tool for servers that have multiple admins or if you give someone SSH access for whatever reason, although you should give out the root password to as few people as humanly possible and be sure to change it often.

This will not magically alert you when a hacker runs the latest kernel exploit on your server and logs into SSH because they will create their own SSH/telnet connection. You should keep your system up to date, install a firewall and follow the latest security releases.

Thursday, January 22, 2009

Defending against brute force ssh attacks

Defending against brute force ssh attacks

By Rainer Wichmann [support@la-samhna.de] (last update: Nov 21, 2008)

Introduction

During 2005, bute force attacks on the ssh (secure shell) service became pretty popular. These attacks are based on a rather simple idea: use an automated program for trying, one after the other, many combinations of standard or frequently used account names and likewise frequently used password (e.g.: guest/guest).

Defence methods

There are a number of methods to defend against such brute force attacks. The following list is intended to give an overview of them, and briefly mention their respective advantages and disadvantages.

Strong passwords

Neither in a dictionary, nor trivial variations of trivial passwords (guest1 is just as bad as guest). Using the initials of the words in some sentence is a simple method to have a strong password that is easy to remind (Peter, Paul, and Mary went to school yesterday = PPaMwtsy).

  • Advantage: Simple
  • Disadvantages:
    • Requires enforcement (regular checks of user passwords with tools like e.g. john ("John the Ripper").
    • Does not reduce the (network, sshd) load caused by the attacks.

RSA authentication

If you don't use passwords, but only RSA keys for authentication, a brute force search for a valid password will obviously be useless.

(1) Generate an RSA key with ssh-keygen -t rsa. This will create the files /home/username/.ssh/id_rsa (the private key) and /home/username/.ssh/id_rsa.pub (the public key).

sh$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
32-digit_hexadecimal_fingerprint username@hostname

(2) On each machine to which where you want to login, put /home/username/.ssh/id_rsa.pub into /home/username/.ssh/authorized_keys. This file can hold more than one key, so it may be wise to concatenate the freshly generated key.

sh$ cat /home/username/.ssh/id_rsa.pub >> /home/username/.ssh/authorized_keys

(3) On each machine from which you want to login, place the file /home/username/.ssh/id_rsa into the directory /home/username/.ssh/.

(4) Disable password-based login by setting 'PasswordAuthentication no' in /etc/ssh/sshd_config, and restart the sshd daemon with /etc/init.d/sshd restart

  • Advantage: Pretty secure, if done properly
  • Disadvantages:
    • Users may use private keys without setting a passphrase to protect them. This implies that getting access to the private key would allow to login to any machine where the corresponding public key is installed.
    • Non-tech users may need help to generate RSA key for themselves (and for using them).
    • It is neccessary to carry the private key along to login from another host.

Using 'iptables' to block the attack

It is possible to set up iptables rules to block ssh attacks. The following ruleset (seen in the blog of Andrew Pollock) will allow at most 3 connections per minute from any host, and will block the host for another minute if this rate is exceeded.

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set \
--name SSH -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --rttl \
--name SSH -j LOG --log-prefix "SSH_brute_force "
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 \
--hitcount 4 --rttl --name SSH -j DROP

For whitelisting, a possible variation (also described by Andrew Pollock) would be:

(1) Create a custom chain for whitelisting first:

iptables -N SSH_WHITELIST

(2) Whitelist any host(s) that you like:

iptables -A SSH_WHITELIST -s TRUSTED_HOST_IP -m recent --remove --name SSH -j ACCEPT

(3) Add the blocking rules:

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 -j SSH_WHITELIST
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 --rttl --name SSH -j ULOG --ulog-prefix SSH_brute_force
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 --rttl --name SSH -j DROP
  • Advantage: Transparent for users
  • Disadvantages:
    • Does not distinguish between successful logins and unsuccessful login attempts (i.e. three successful logins within one minute will trigger just like three unsuccessful login attempts).
    • As pointed out by one reader (L. Hamel), this method requires 'recent' (http://snowman.net/projects/ipt_recent/), an ipfilters patch that may not (yet) be in every distro's default kernel. So to use this technique with typical linux distros, you may have to patch the kernel.
    • R. McIntosh kindly notices that Debian/Ubuntu include this, but RHEL3/4/5 do not.

Using the sshd log to block attacks

It is possible to scan the syslog entries written by the sshd daemon for ongoing attacks, and block the attacker. There are several programs/scripts available that are specifically written for this purpose:

ssdfilter uses iptables for blocking (i.e. it dynamically adds custom firewall rules to block a specific attacker). You need to run sshdfilter instead of sshd. Sshdfilter will then start sshd and monitor its log.

Fail2Ban is a Python script which adds custom firewall rules to block an attacker. It can use the iptables, ipfwadm, or ipfw.

DenyHosts does not use firewall rules to block an attack. Rather, it writes blocking rules to /etc/hosts.deny. Thus, it requires an sshd daemon compiled with support for tcp_wrappers (default on most Linux distributions). Like Fail2Ban, DenyHosts is a Python script.

To find out whether your sshd daemon supports tcp_wrappers, you could use the command ldd /usr/sbin/sshd | grep libwrap. With tcp_wrappers supported you should get a line similar to libwrap.so.0 => /lib/libwrap.so.0 (0xb7f7e000) (numbers may be different). Without tcp_wrappers support, the output will be empty.

sh$ ldd /usr/sbin/sshd | grep libwrap
     libwrap.so.0 => /lib/libwrap.so.0 (0xb7f7e000)

Another method to test for tcp_wrappers support would be to add the line sshd: 127.0.0.1 to the file /etc/hosts.deny, and then try to connect to the local ssh server with the command ssh localhost. As you have just blocked localhost, this should fail with the error message ssh_exchange_identification: Connection closed by remote host:

sh$ ssh localhost
ssh_exchange_identification: Connection closed by remote host
  • Advantages:
    • Transparent for users
    • Can distinguish between unsuccessful login attempts (which are blocked) and successful logins (which are not blocked).
  • Disadvantages:
    • Many ssh attacks are fast and short (many connections in a short time). Thus, running a cron script to check the sshd logs for an ongoing attack may be pointless, as it may notice the attack only after it has finished (and the next attack will come from a different machine anyway).
    • Continuously monitoring the sshd log for an attack requires to run yet another daemon (in the case of sshdfilter, you have to run sshdfilter instead of sshd anyway).

Using tcp_wrappers to block attacks

In the preceding section the DenyHosts script was discussed, which scans the sshd logs to detect an attack, and then blocks it with a rule in /etc/hosts.deny. However, it is actually not necessary to scan the logs. It is possible to let the tcp wrapper library start a script whenever a connection is made, and let this script add rules to /etc/hosts.deny or /etc/hosts.allow, if the connecting host should be blocked.

(1) Download the sshblock.sh shell script (PGP signature), and copy it to /usr/local/bin/sshblock.sh (or wherever you like).

(2) Make it executable using the command chmod 755 /usr/local/bin/sshblock.sh

(3) Add the following three lines at the bottom of /etc/hosts.allow

#__START_SSHBLOCK__
#__END_SSHBLOCK__
sshd : ALL : spawn (/usr/local/bin/sshblock.sh %a)&

This will call the script /usr/local/bin/sshblock.sh for each ssh connection. The script will receive the remote IP address as the first and only argument. The script will write a temporary file /root/hosts.allow, and copy it to /etc/hosts.allow if it differs from that.

Requirements:

  • The sshd daemon must support tcp_wrappers (see preceding section on methods to test this).
  • The date command must support the '%s' format specifier to print seconds after the Epoch (use date +%s to test). Both GNU/Linux and FreeBSD date support this.

Configuration: at the top of the script, there are four variables that can be set: DONTBLOCK is the prefix of an address block that you do never want to be blocked (i.e. your own domain). The default is 192.168, which you can safely keep if you have no own domain, as this is a 'private' address block). At most (2) BURST_MAX connections from a host within BURST_TIM seconds are allowed (default: 5 within 60 sec), and blocks are removed after PURGE_TIM seconds (default: 3600 sec). In the script, this looks like:

# your own domain
DONTBLOCK=192.168

# block host if more than BURST_MAX connections within BURST_TIM seconds
BURST_MAX=5
BURST_TIM=60

# remove block after PURGE_TIM seconds
PURGE_TIM=3600
  • Advantage: Transparent for users
  • Disadvantages:
    • Does not distinguish between successful logins and unsuccessful login attempts (i.e. five successful logins within one minute will trigger just like five unsuccessful login attempts).
    • To remove a block, the script must run, which requires a connection from a non-blocked host (or follow a suggestion by Andreas Rizzi and install a cron job that calls the script with the parameter 127.0.0.0 once per hour).

Port knocking

As pointed out by Imre Veres, another solution to the problem is using knockd, which eliminates the need for having ssh listen on an open port.

Knockd watches predefined patterns in iptables' log, e.g. one hit to port 6356, one hit to port 9356 and two hits to port 3356. I.e. this is equivalent to knocking at a closed door with a "code" that is recognized by knockd. Knockd will then use iptables to open a predefined port (e.g. tcp/22 for sshd) for a predefined time (e.g. one minute). If a ssh session is opened within that time frame, it will remain open, though the ssh port will get closed by knockd after the predefined timeframe expires.

Kevin Hilton recommends fwknop on the grounds that "its much more sophisticated, very easy to set up (at least for ubuntu — probably other distributions as well), allows for encrypted communications, randomizes the source port, and is supported."

Michael Rash points out that fwkop supports Single Packet Authorization, which does not suffer from the traffic monitoring attack mentioned below under 'Disadvantages'.

  • Advantage: Fairly secure, as long as the attacker cannot monitor your traffic (since that could allow to determine and replay the portknock sequence)
  • Disadvantages:
    • Rather complicated scheme, not suitable for 'mere mortals'.
    • Requires a suitable program (e.g. knockd-client) for "port knocking" on the client (as well as knockd on the server)
    • As pointed out by Bond Masuda, it is pretty easy to detect the traffic pattern of 'portknocks followed by ssh connection', once an attacker can monitor your traffic. Thus simple portknocking provides no security against attackers who can spy on the local network. This problem is addressed by Single Packet Authorization in fwknop.

Tuesday, August 5, 2008

Howto Linux / UNIX setup SSH with DSA public key authentication (password less login)

Q. How do you set-up SSH with DSA public key authentication? I have Linux laptop called tom and remote Linux server called jerry. How do I setup DSA based authentication so I don’t have to type password?

A. DSA public key authentication can only be established on a per system / user basis only i.e. it is not system wide. You will be setting up ssh with DSA public key authentication for SSH version 2 on two machines:

#1 machine : your laptop called tom #2 machine : your remote server called jerry

Command to type on your laptop/desktop (local computer)

First login to local computer called tom and type the following command.

Step #1: Generate DSA Key Pair

Use ssh-keygen command as follows: $ ssh-keygen -t dsa Output:

Enter file in which to save the key (/home/vivek/.ssh/id_dsa):  Press [Enter] key
Enter passphrase (empty for no passphrase): myPassword
Enter same passphrase again: myPassword
Your identification has been saved in /home/vivek/.ssh/id_dsa.
Your public key has been saved in /home/vivek/.ssh/id_dsa.pub.
The key fingerprint is:
04:be:15:ca:1d:0a:1e:e2:a7:e5:de:98:4f:b1:a6:01 vivek@vivek-desktop

Caution: a) Please enter a passphrase different from your account password and confirm the same. b) The public key is written to /home/you/.ssh/id_dsa.pub. c) The private key is written to /home/you/.ssh/id_dsa. d) It is important you never-ever give out your private key.

Step #2: Set directory permission

Next make sure you have correct permission on .ssh directory: $ cd $ chmod 755 .ssh

Step #3: Copy public key

Now copy file ~/.ssh/id_dsa.pub on Machine #1 (tom) to remote server jerry as ~/.ssh/authorized_keys: $ scp ~/.ssh/id_dsa.pub user@jerry:.ssh/authorized_keys

Command to type on your remote server called jerry

Login to your remote server and make sure permissions are set correct: $ chmod 600 ~/.ssh/authorized_keys

Task: How do I login from client to server with DSA key?

Use scp or ssh as follows from your local computer: $ ssh user@jerry $ ssh user@remote-server.com $ scp file user@jerry:/tmp

You will still be asked for the passphrase for the DSA key file each time you connect to remote server called jerry, unless you either did not enter a passphrase when generating the DSA key pair.

Task: How do I login from client to server with DSA key but without typing a passhrase i.e. password-less login?

Type the following command at shell prompt: $ exec /usr/bin/ssh-agent $SHELL $ ssh-add Output:

Enter passphrase for /home/vivek/.ssh/id_dsa: myPassword
Identity added: /home/vivek/.ssh/id_dsa (/home/vivek/.ssh/id_dsa)

Type your passhrase once. Now, you should not be prompted for a password whenever you use ssh, scp, or sftp command.

If you are using GUI such as Gnome use the command: $ ssh-askpass OR $ /usr/lib/openssh/gnome-ssh-askpass

To save your passphrase during your GNOME session under Debian / Ubuntu, do as follows: a) Click on System b) Select Preferences c) Select Session d) Click on New e) Enter "OpenSSH Password Management" in the Name text area f) Enter /usr/lib/openssh/gnome-ssh-askpass in the command text area. g) Click on close to save the changes h) Log out and then log back into GNOME. After GNOME is started, a dialog box will appear prompting you for your passphrase. Enter the passphrase requested. From this point on, you should not be prompted for a password by ssh, scp, or sftp.