Saturday, June 9, 2012

SSH fun - a poor man's VPN

Recently I saw an episode of HAK5 on SSH and using certificates to authenticate. I was thinking of implementing a VPN solution at home for when I am on the road but when I saw the show I liked the simplicity of it so I started and a couple of minutes of fun later I had an up and running poor man's VPN.

If you want a quick and easy solution to use an untrusted Internet connection, this might be a solution for you. Here is a description on how to implement it.

Setting up the server

Setting up your server can actually be any system that can run an openssh server. It can be a recent beefy thing but also an old desktop laying around. To install openssh server on a Ubuntu system, you do :

apt-get install openssh-server

Configure the firewall

Since we are about to hang this system to the Internet, a firewall is a must have. Ubuntu comes with ufw built in.

To configure the firewall for the openssh-server, you do:
ufw limit OpenSSH

To start the firewall run:
ufw enable

Configure your server

The configuration can be found in /etc/ssh/sshd_config. Change the following settings:

  • PermitRootLogin no
  • RSAAuthentication yes
  • PasswordAuthentication no
  • UsePAM no
SSH services connected to the Internet are constantly under attack. Since I want to use the attack data, I changed my log level to verbose.

Now that the server is configured, you got to restart the service. You do this with:

service ssh restart

Key generation

The basic idea is to create a key pair. One is a public key and will be installed on the server, the other one is your private key and is installed one the device you will connect with, your laptop or touchpad for example.

To generate the key you type on the laptop or touchpad:

ssh-keygen -t rsa

This will generate your generate your key pair. During the generation it will ask you where you want to store your keys and a password to protect it. The keys are by default stored in your home directory under the hidden directory ".ssh/". The private key is called id_rsa and the public key is called Another important file in the ssh directory is called known_hosts. You will get more information on known_hosts later in this post.

Getting the public key on the server
To get the public key to the server there are a couple of possibilities. 
  • the ssh-copy-id command
  • copy text from to the server to the file authorized_keys in the hidden .ssh directory under your profile.
Since ssh-copy-id is not available on every platform in the world, my preference goes out to the second option.

It is always a good idea to have a copy of your private key id_rsa stored at a secure place if something goes wrong with your system.

Opening up the gates

When your internet provides you with a DHCP address you can configure your system to use a dynamic dns. If you got a static IP you don't need the dynamic dns, you just need to know your IP.

Configure your router so that you allow incoming traffic on port 22.

Connecting to your server

A regular SSH session

To build just a regular SSH session you type on the command line:
ssh account@server

Surfing/Skyping/... over SSH session

You can use the SSH session as a SOCKS5 proxy. To do this, you do:
ssh -D port account@server

Then you need to configure your browser so that it uses a local (localhost or socks v5 proxy and of course the port you specified.


By default all logging will take place in /var/log/auth.log.

A regular connection looks like this:
timestamp server sshd[pid]: Connection from IP port port_number
timestamp server sshd[pid]: Found matching RSA key: key_in_hex
timestamp server sshd[pid]: Postponed publickey for user from IP port port_number ssh2 [preauth]

A disconnect looks like this:
timestamp server sshd[pid]: Received disconnect from IP ...

When somebody just does "ssh ip_address" it will show up like this: 
timestamp server sshd[pid]: Connection from IP port port_number
timestamp server sshd[pid]: Connection closed by IP [preauth]

Usually brute-force attacks are done like "ssh useraccount@IP" and since the attacker doesn't have the certificate it will show up like this:
timestamp server sshd[pid]: Connection from IP port port_number
timestamp server sshd[pid]: Invalid user useraccount from IP
timestamp server sshd[pid]: input_userauth_request: invalid user useraccount [preauth]
timestamp server sshd[pid]: Connection closed by IP [preauth]

Final thoughts on security considerations

If you want to slow down the attacks you can always implement a framework called Fail2Ban. This python framework reads out logs and uses iptables firewall to block brute-force attempts.


Erik Vanderhasselt said...

To have some fun with your logs:

This will get you the invalid log in attempts:
cat /var/log/auth.log | grep Invalid >> invalid

This will extract the offending IP addresses:
cat invalid | tr -s ' ' | cut -d ' ' -f 10 | sort -d -f | uniq -i >> offendingip

And the tested logins:
cat invalid | tr -s ' ' | cut -d ' ' -f 8 | sort -d -f | uniq -i >> invaliduserlist

My "friends" right now live in (geoip):
- Novosibrisk, Russia
- Beijing, China
- Guangdong, China
- Fujian, China
- Sichuan, China
- Shaanxi, China

Enjoy :)

Erik Vanderhasselt said...

Some interesting things to observe:

I got an interesting scan. They tried root on the default port first, they fail to login with root and then interestingly enough start trying random high ports.

After failing that test a dictionary attack was attempted but there must be a bug in their software since it tried the same login multiple times.

The complete test from some Chinese IP to my place was done in 14 minutes.

Another pattern I saw in my logs is alternating between trying with root for some random port and a dictionary test. This came from a Portuguese IP.

My Turkish friend only tried root for some random ports ... rather boring to look at.

Alan Wade said...

21SSH tunnels offer a method to bypass firewalls that command sure web services – farewell as a website permits outgoing connections. As an example, at workplace users is also blocked by some firewalls to access to social websites like facebook and youtube directly through eighty ports. However users might not would like to possess their internet traffic blocked by the firewalls and filters and want to be ready to unblock facebook and youtube. If users will hook up with AN external SSH server, they will produce AN SSH tunnel to forward a given port on their native machine to port eighty on an overseas internet server to bypass those firewalls and filters to unblock facebook and youtube.

Visit SSH VPN Website