Never Ending Security

It starts all here

Tag Archives: SSH

Persistent reverse (NAT bypassing) SSH tunnel access with autossh

Situation: you are in a restricted network (company, hotel, hospital) where you have a “server” which you want to access from outside that network. You cannot forward ports to that machine, but you can ssh outside (to your own server). This tutorial solves this problem.

You need another server to which you setup a persistent ssh connection with a reverse tunnel. Then if you need to access the machine you ssh into the other server, and from there you ssh through the tunnel to the restriced machine.

Make sure you have permission to do this from the administrators. They generally don’t like holes in the firewall/security. They don’t block it for no reason.

Naming convention:

restricted machine: machine inside the restricted network middleman: machine to which the restricted machine sets up the tunnel, and from which you access the restricted server

Install the tools

We are going to use autossh. This is in the debian/ubuntu repositories. Make sure you also install openssh server.

Execute on: restricted machine.

sudo apt-get install autossh ssh

Create your ssh-key.

Execute on: restricted machine.

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): */root/.ssh/nopwd*
Enter passphrase (empty for no passphrase): *leave empty*
Enter same passphrase again: *leave empty*

Copy your key to the middleman machine

Execute on: restricted machine.

ssh-copy-id -i .ssh/ "-p 2222 remy@middleman"

(replace remy@middleman with your username and middleman ssh server. Also note how you can give a custom port in the ssh-copy-id.)

Test the connection with autossh

Execute on: restricted machine

autossh -M 10984 -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /root/.ssh/nopwd -R 6666:localhost:22 remy@middleman -p 2222

Explanation”of options:

  • -M 10984: autossh monitoring port.
  • -o “PubkeyAuthentication=yes”: authenticate with ssh-keys instead of password.
  • -o “PasswordAuthentication=no”: explicitly disable password authentication.
  • -i /root/.ssh/nopwd: the location of the ssh key to use.
  • -R 6666:localhost:22: reverse tunnel. forward all traffic on port 6666 on host middleman to port 22 on host restricted machine.
  • remy@middleman -p 2222: ssh user remy, ssh host middleman, ssh port 2222

If this all goes well you should be logged in to the middleman host without being asked for a password. You might get the question if you want to add the ssh key. Say yes to this.

If it does not go well, check the permissions on the ssh key (should be 600), and make sure you have the correct values in the autossh command.

SSH back in the restricted host

From another machine (outside the restricted network preferably) ssh into the middleman host.

Execute on: other machine

ssh -p 2222 remy@middleman

From the middleman, ssh into the restricted host via the reverse tunnel we created:

Execute on: middleman

ssh -p 6666 remy@

If all goes well, you should see a prompt to login to the restricted machine. Enter your password and go. If this goes well, you can continue. If this does not work, check the values in the command and the ssh configs. Also make sure you have executed the steps above correctly.

Enable the tunnel on boot

We are going to edit the /etc/rc.local file. This script normally does nothing, but gets executed at boot. If you make any errors in this script, your machine might not boot so make sure to do this correctly.

Execute on: restricted machine

sudo nano /etc/rc.local

Add (and change) the following line

autossh -M 10984 -N -f -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /root/.ssh/nopwd -R 6666:localhost:22 remy@middleman -p 2222 &

We have three new things in this command:

  • -N: Do not execute a command on the middleman machine
  • -f: drop in the background
  • &: Execute this command but do not wait for output or an exit code. If this is not added, your machine might hang at boot.

Save the file, and as make it executable:

Execute on: restricted machine

sudo chmod +x /etc/rc.local

And test it:

Execute on: restricted machine

sudo /etc/rc.local

If you get your regular promt back without any output you’ve done it correct.z

Forward a website, not ssh

You might want to forward a website on the restricted host. Follow the above tutorial, but change the autossh command:

autossh -M 10984 -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /root/.ssh/nopwd -R 8888:localhost:80 remy@middleman -p 2222
  • -R 8888:localhost:80: this forwards all traffic on host middleman to port 80 on host restrictedhost. (port 80 = website).

Other host inside restricted network

You can also forward ports from other restricted hosts in the network:

autossh -M 10984 -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /root/.ssh/nopwd -R 7777:host2.restrictednetwork:22 remy@middleman -p 2222

This will forward all traffic to port 7777 on host middleman, via host restrictedhost, to host host2.restrictednetwork port 22.

SSH Tunnels And Stuff Explained


SSH Tunnels

A SSH tunnel consists of an encrypted tunnel created through a SSH protocol connection. A SSH tunnel can be used to transfer unencrypted traffic over a network through an encrypted channel. For example we can use a ssh tunnel to securely transfer files between a FTP server and a client even though the FTP protocol itself is not encrypted. SSH tunnels also provide a means to bypass firewalls that prohibits or filter certain internet services. For example an organization will block certain sites using their proxy filter. But users may not wish to have their web traffic monitored or blocked by the organization proxy filter. If users can connect to an external SSH server, they can create a SSH tunnel to forward a given port on their local machine to port 80 on remote web-server via the external SSH server

Connecting to the internet from Wi-Fi hotspots, at work, or anywhere else away from home, exposes your data to unnecessary risks. You can easily configure your router to support a secure tunnel and shield your remote browser traffic

What is and Why Set Up a Secure Tunnel?

You might be curious why you would even want to set up a secure tunnel from your devices to your home router and what benefits you would reap from such a project. Let’s lay out a couple different scenarios that involve you using the internet to illustrate the benefits of secure tunneling.

Scenario one: You’re at a coffee shop using your laptop to browse the internet through their free Wi-Fi connection. Data leaves your Wi-Fi modem, travels through the air unencrypted to the Wi-Fi node in the coffee shop, and then is passed on to the greater internet. During the transmission from your computer to the greater internet your data is wide open. Anyone with a Wi-Fi device in the area can sniff your data. It’s so painfully easy that a motivated 12 year old with a laptop and a copy of Firesheep could snatch up your credentials for all manner of things. It’s as though you’re in a room filled with English-only speakers, talking into a phone speaking Mandarin Chinese. The moment somebody who speaks Mandarin Chinese comes in (the Wi-Fi sniffer) your pseudo-privacy is shattered.

Scenario two: You’re at a coffee shop using your laptop to browse the internet through their free Wi-Fi connection again. This time you’ve established an encrypted tunnel between your laptop and your home router using SSH. Your traffic is routed through this tunnel directly from your laptop to your home router which is functioning as a proxy server. This pipeline is impenetrable to Wi-Fi sniffers who would see nothing but a garbled stream of encrypted data. No matter how shifty the establishment, how insecure the Wi-Fi connection, your data stays in the encrypted tunnel and only leaves it once it has reached your home internet connection and exits to the greater internet.

In scenario one you’re surfing wide open; in scenario two you can login to your bank or other private web sites with the same confidence you would from your home computer.

Although we used Wi-Fi in our example you could use the SSH tunnel to secure a hardline connection to, say, launch a browser on a remote network and punch a hole through the firewall to surf as freely as you would on your home connection.

Sounds good doesn’t it? It’s incredibly easy to set up so there’s no time like the present—you can have your SSH tunnel up and running within the hour.

Down and Dirty

apt-get install openssh-server

Once you have installed an OpenSSH server, you will need to configure it by editing the sshd_config file in the /etc/ssh directory.

sshd_config is the configuration file for the OpenSSH server.
ssh_config is the configuration file for the OpenSSH client.

Make sure not to get them mixed up.

First, make a backup of your sshd_config file by copying it to your home directory, or by making a read-only copy in /etc/ssh by doing:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.factory-defaults
sudo chmod a-w /etc/ssh/sshd_config.factory-defaults

Creating a read-only backup in /etc/ssh means you’ll always be able to find a known-good configuration when you need it.

Once you’ve backed up your sshd_config file, you can make changes with any text editor (gksudo gedit /etc/ssh/sshd_config runs the standard text editor). Once you’ve made your changes, you can apply them by saving the file then doing:

sudo restart ssh

Configuring OpenSSH means striking a balance between security and ease-of-use. Ubuntu’s default configuration tries to be as secure as possible without making it impossible to use in common use cases.


Because a lot of people with SSH servers use weak passwords, many online attackers will look for an SSH server, then start guessing passwords at random. An attacker can try thousands of passwords in an hour, and guess even the strongest password given enough time. The recommended solution is to use SSH keys instead of passwords

If you disable password authentication, it will only be possible to connect from computers you have specifically approved. This massively improves your security, but makes it impossible for you to connect to your own computer from a friend’s PC without pre-approving the PC, or from your own laptop when you accidentally delete your key.

It’s recommended to disable password authentication unless you have a specific reason not to.

To disable password authentication, look for the following line in your sshd_config file:

#PasswordAuthentication yes

replace it with a line that looks like this:

PasswordAuthentication no

Once you have saved the file and restarted your SSH server, you shouldn’t even be asked for a password when you log in.

Key-Based SSH Logins

Key-based authentication is the most secure of several modes of authentication usable with OpenSSH, such as plain password (the default with Ubuntu) and Kerberos tickets. Key-based authentication has several advantages over password authentication, for example the key values are significantly more difficult to brute-force, or guess than plain passwords, provided an ample key length. Other authentication methods are only used in very specific situations.

SSH can use either “RSA” (Rivest-Shamir-Adleman) or “DSA” (“Digital Signature Algorithm”) keys. Both of these were considered state-of-the-art algorithms when SSH was invented, but DSA has come to be seen as less secure in recent years. RSA is the only recommended choice for new keys, so this guide uses “RSA key” and “SSH key” interchangeably.

Key-based authentication uses two keys, one “public” key that anyone is allowed to see, and another “private” key that only the owner is allowed to see. To securely communicate using key-based authentication, you need to create a public key for the computer you’re logging in from, and securely transmit it to the computer you’re logging in to. Wikipedia has a good explanation of the theory

Using key based logins with ssh is generally considered more secure than using plain password logins. This section of the guide will explain the process of generating a set of public/private RSA keys, and using them for logging into your Ubuntu computer(s) via OpenSSH.

Generating RSA Keys

The first step involves creating a set of RSA keys for use in authentication.

This should be done on the client.

To create your public and private SSH keys on the command-line:

mkdir ~/.ssh
chmod 700 ~/.ssh
ssh-keygen -t rsa

You will be prompted for a location to save the keys, and a passphrase for the keys. This passphrase will protect your private key while it’s stored on the hard drive and be required to use the keys every time you need to login to a key-based system:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/b/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/b/.ssh/id_rsa.
Your public key has been saved in /home/b/.ssh/

Your public key is now available as .ssh/ in your home folder.

Congratulations! You now have a set of keys. Now it’s time to make your systems allow you to login with them

Choosing a good passphrase

Just like with physical keys, you need to change all your locks if your RSA key is stolen. Otherwise, your thief will be able to get access to all your stuff.

An SSH key passphrase is a secondary form of security that gives you a little time when your keys are stolen. If your RSA key has a strong passphrase, it might take your attacker a few hours to guess by brute force. That extra time should be enough to log in to any computers you have an account on, delete your old key from the .ssh/authorized_keys file, and add a new key.

Your SSH key passphrase is only used to protect your private key from thieves. It’s never transmitted over the Internet, and the strength of your key has nothing to do with the strength of your passphrase.

You have to choose for yourself whether to use a passphrase with your RSA key. Ultimately, it’s a choice between cursing the difficulty every time you have to type it in, or cursing your glibness when someone logs in to all your accounts and changes your password so you can’t get in any more.

If you choose to use a passphrase, pick something strong and write it down on a piece of paper that you keep in a safe place. If you choose not to use a password, just press the return key without typing a password – you’ll never be asked for one again.

Key Encryption Level

Note: The default is a 2048 bit key. You can increase this to 4096 bits with the -b flag (Increasing the bits makes it harder to crack the key by brute force methods).

ssh-keygen -t rsa -b 4096

Password Authentication

The main problem with public key authentication is that you need a secure way of getting the public key onto a computer before you can log in with it. If you will only ever use an SSH key to log in to your own computer from a few other computers (such as logging in to your PC from your laptop), you should copy your SSH keys over on a memory stick, and disable password authentication altogether. If you would like to log in from other computers from time to time (such as a friend’s PC), make sure you have a strong password.

Transfer Client Key to Host

The key you need to transfer to the host is the public one. If you can log in to a computer over SSH using a password, you can transfer your RSA key by doing the following from your own computer:

ssh-copy-id <username>@<host>

Where <username> and <host> should be replaced by your username and the name of the computer you’re transferring your key to.

Due to this bug, you cannot specify a port other than the standard port 22. You can work around this by issuing the command like this: ssh-copy-id "<username>@<host> -p <port_nr>". If you are using the standard port 22, you can ignore this tip.

Another alternative is to copy the public key file to the server and concatenate it onto the authorized_keys file manually. It is wise to back that up first:

cp authorized_keys authorized_keys_Backup
cat >> authorized_keys

You can make sure this worked by doing:

ssh <username>@<host>

You should be prompted for the passphrase for your key:

Enter passphrase for key ‘/home/<user>/.ssh/id_rsa’:

Enter your passphrase, and provided host is configured to allow key-based logins, you should then be logged in as usual.


Encrypted Home Directory

If you have an encrypted home directory, SSH cannot access your authorized_keys file because it is inside your encrypted home directory and won’t be available until after you are authenticated. Therefore, SSH will default to password authentication.

To solve this, create a folder outside your home named /etc/ssh/<username> (replace “<username>” with your actual username). This directory should have 755 permissions and be owned by the user. Move the authorized_keys file into it. The authorized_keys file should have 644 permissions and be owned by the user.

Then edit your /etc/ssh/sshd_config and add:

AuthorizedKeysFile    /etc/ssh/%u/authorized_keys

Finally, restart ssh with:

sudo service ssh restart

The next time you connect with SSH you should not have to enter your password.

username@host’s password:

If you are not prompted for the passphrase, and instead get just the

username@host’s password:

prompt as usual with password logins, then read on. There are a few things which could prevent this from working as easily as demonstrated above. On default Ubuntu installs however, the above examples should work. If not, then check the following condition, as it is the most frequent cause:

On the host computer, ensure that the /etc/ssh/sshd_config contains the following lines, and that they are uncommented;

PubkeyAuthentication yes
RSAAuthentication yes

If not, add them, or uncomment them, restart OpenSSH, and try logging in again. If you get the passphrase prompt now, then congratulations, you’re logging in with a key!

Permission denied (publickey)

If you’re sure you’ve correctly configured sshd_config, copied your ID, and have your private key in the .ssh directory, and still getting this error:

Permission denied (publickey).

Chances are, your /home/<user> or ~/.ssh/authorized_keys permissions are too open by OpenSSH standards. You can get rid of this problem by issuing the following commands:

chmod go-w ~/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Error: Agent admitted failure to sign using the key.

This error occurs when the ssh-agent on the client is not yet managing the key. Issue the following commands to fix:


This command should be entered after you have copied your public key to the host computer.

Debugging and sorting out further problems

The permissions of files and folders is crucial to this working. You can get debugging information from both the client and server.

if you think you have set it up correctly , yet still get asked for the password, try starting the server with debugging output to the terminal.

sudo /usr/sbin/sshd -d

To connect and send information to the client terminal

ssh -v ( or -vv) username@host's

Where to From Here?

No matter how your public key was generated, you can add it to your Ubuntu system by opening the file .ssh/authorized_keys in your favourite text editor and adding the key to the bottom of the file. You can also limit the SSH features that the key can use, such as disallowing port-forwarding or only allowing a specific command to be run. This is done by adding “options” before the SSH key, on the same line in theauthorized_keys file. For example, if you maintain a CVS repository, you could add a line like this:

command="/usr/bin/cvs server",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-user-rc ssh-dss <string of nonsense>...

When the user with the specified key logged in, the server would automatically run /usr/bin/cvs server, ignoring any requests from the client to run another command such as a shell. For more information, see the sshd man page


Specify Which Accounts Can Use SSH

You can explicitly allow or deny access for certain users or groups. For example, if you have a family PC where most people have weak passwords, you might want to allow SSH access just for yourself.

Allowing or denying SSH access for specific users can significantly improve your security if users with poor security practices don’t need SSH access.

It’s recommended to specify which accounts can use SSH if only a few users want (not) to use SSH.

To allow only the users user1 and user2 to connect to your computer, add the following line to the bottom of the sshd_config file:

AllowUsers user1 user2

To allow everyone except the users user3 and user4 to connect to your computer, add the following line to the bottom of the sshd_configfile:

DenyUsers user3 user4

It’s possible to create very complex rules about who can use SSH – you can allow or deny specific groups of users, or users whose names match a specific pattern, or who are logging in from a specific location.

It is customary to switch:

PermitRootLogin no

Log More Information

By default, the OpenSSH server logs to the AUTH facility of syslog, at the INFO level. If you want to record more information – such as failed login attempts – you should increase the logging level to VERBOSE.

It’s recommended to log more information if you’re curious about malicious SSH traffic.

To increase the level, find the following line in your sshd_config:

LogLevel INFO

and change it to this:


Now all the details of ssh login attempts will be saved in your /var/log/auth.log file

Allow Forwarding

By default, you can tunnel network connections through an SSH session. For example, you could connect over the Internet to your PC, tunnel a remote desktop connection, and access your desktop. This is known as “port forwarding”.

By default, you can also tunnel specific graphical applications through an SSH session. For example, you could connect over the Internet to your PC and run nautilus "file://$HOME" to see your PC’s home folder. This is known as “X11 forwarding”.

AllowTcpForwarding yes
X11Forwarding yes

So, What is SSH Tunnelling ?

Port Forwarding

SSH tunnels can be created in several ways using different kinds of port forwarding mechanisms. Ports can be forwarded in three ways.

  1. Local port forwarding
  2. Remote port forwarding
  3. Dynamic port forwarding

Tunnelling with Local port forwarding

Let’s say that is being blocked using a proxy filter in the company. A SSH tunnel can be used to bypass this restriction. Let’s name my machine at the university as ‘work’ and a home machine as ‘home’. ‘home’ needs to have a public IP for this to work. And we are running a SSH server on the home machine. Following diagram illustrates the scenario.


To create the SSH tunnel execute following from ‘work’ machine.
ssh -L home

The ‘L’ switch indicates that a local port forward is need to be created. The switch syntax is as follows.

-L <local-port-to-listen>:<remote-host>:<remote-port>

Now the SSH client at ‘work’ will connect to SSH server running at ‘home’ (usually running at port 22) binding port 9001 of ‘work’ to listen for local requests thus creating a SSH tunnel between ‘home’ and ’work’. At the ‘home’ end it will create a connection to ‘’ at port 80. So ‘work’ doesn’t need to know how to connect to Only ‘home’ needs to worry about that. The channel between ‘work’ and ‘home’ will be encrypted while the connection between ‘home’ and ‘’ will be unencrypted.

Now it is possible to browse by visiting http://localhost:9001 in the web browser at ‘work’ computer. The ‘home’ computer will act as a gateway which would accept requests from ‘work’ machine and fetch data and tunnelling it back. So the syntax of the full command would be as follows.
ssh -L <local-port-to-listen>:<remote-host>:<remote-port> <gateway>
The image below describes the scenario.


Here the ‘host’ to ‘’ connection is only made when browser makes the request not at the tunnel setup time. It is also possible to specify a port in the ‘home’ computer itself instead of connecting to an external host. This is useful if I were to set up a VNC session between ‘work’ and ‘home’. Then the command line would be as follows.
ssh -L 5900:localhost:5900 home (Executed from 'work')

So here what does localhost refer to? Is it the ‘work’ since the command line is executed from ‘work’? Turns out that it is not. As explained earlier is relative not the machine from where the tunnel is initiated. So this will make a connection to port 5900 of the ‘home’ computer where the VNC client would be listening in.

The created tunnel can be used to transfer all kinds of data not limited to web browsing sessions. We can also tunnel SSH sessions from this as well. Let’s assume there is another computer (‘banned’) to which we need to SSH from work but the SSH access is being blocked. It is possible to tunnel a SSH session to this host using a local port forward. The setup would look like this.

As can be seen now the transferred data between ‘work’ and ‘banned’ are encrypted end to end. For this we need to create a local port forward as follows.
ssh -L 9001:banned:22 home

Now we need to create a SSH session to local port 9001 from where the session will get tunneled to ‘banned’ via ‘home’ computer.

ssh -p 9001 localhost

With that let’s move on to next type of SSH tunnelling method, reverse tunnelling.

Reverse Tunnelling with remote port forwarding

Let’s say it is required to connect to an internal work website from home.
The work firewall is blocking all incoming traffic. How can we connect from ‘home’ to internal network so that we can browse the internal site? A VPN setup is a good candidate here. However for this example let’s assume we don’t have this facility. Enter SSH reverse tunnelling..
As in the earlier case we will initiate the tunnel from ‘work’ computer behind the firewall. This is possible since only incoming traffic is blocked and outgoing traffic is allowed. However instead of the earlier case the client will now be at the ‘home’ computer. Instead of -L option we now define -R which specifies a reverse tunnel need to be created.
ssh -R home (Executed from 'work')

Once executed the SSH client at ‘work’ will connect to SSH server running at home creating a SSH channel. Then the server will bind port 9001 on ‘home’ machine to listen for incoming requests which would subsequently be routed through the created SSH channel between ‘home’ and ‘work’. Now it’s possible to browse the internal site by visiting http://localhost:9001 in ‘home’ web browser. The ‘work’ will then create a connection to intra-site and relay back the response to ‘home’ via the created SSH channel.

As nice all of these would be still you need to create another tunnel if you need to connect to another site in both cases. Wouldn’t it be nice if it is possible to proxy traffic to any site using the SSH channel created? That’s what dynamic port forwarding is all about.

Dynamic Port Forwarding

Dynamic port forwarding allows to configure one local port for tunnelling data to all remote destinations. However to utilize this the client application connecting to local port should send their traffic using the SOCKS protocol. At the client side of the tunnel a SOCKS proxy would be created and the application (eg. browser) uses the SOCKS protocol to specify where the traffic should be sent when it leaves the other end of the ssh tunnel.
ssh -D 9001 home (Executed from 'work')

Here SSH will create a SOCKS proxy listening in for connections at local port  9001 and upon receiving a request would route the traffic via SSH channel created between ‘work’ and ‘home’. For this it is required to configure the browser to point to the SOCKS proxy at port 9001 at localhost.


To setup Firefox to use this tunnel to navigate the internet, we go to Edit>Preferences>Advance in the Network tab, we click on the ‘Settings…’ button. There we select “Manual Proxy Configuration” and leave everything blank, except for the field “SOCKS Host”, where we write down the ‘’ and the port ‘9001’, that is the configuration of our tunnel. We select the SOCKS5 option and save our configuration.


As it stands, we now can use Firefox to navigate the web and our traffic will be forwarded through our tunnel, we can check that we are truly making use of our server, navigating a couple of pages and then kill our tunnel,  with will result in broken browser connection With the current settings, even though our traffic is encrypted, our DNS request are still not being sent through our tunnel, to change this in firefox, we write in the address bar about:config, look for the key network.proxy.socks_remote_dns and change it to true.

Our SSH Tunnel, can be use with any program that can use a SOCKS proxy, such as Skype, messengers, etc.

Another Interesting application would be using someting like SSHTunnel which will tunnel your phone browser while you are using are untrusted wireless network


At the end I’ll leave you with a command to test and figure out for yourself

  • ssh -c arcfour,blowfish-cbc -YCv user@host

Don’t forget to check man ssh

SSH Encryption and Connection Process


SSH Encryption and Connection Process


SSH, or secure shell, is a secure protocol and the most common way of safely administering remote servers. Using a number of encryption technologies, SSH provides a mechanism for establishing a cryptographically secured connection between two parties, authenticating each side to the other, and passing commands and output back and forth.

Symmetric Encryption, Asymmetric Encryption, and Hashes

In order to secure the transmission of information, SSH employs a number of different types of encryption at various points in the transaction. These include forms of symmetrical encryption, asymmetrical encryption, and hashing.

Symmetrical Encryption

The relationship of the components that encrypt and decrypt data determine whether an encryption scheme is symmetrical or asymmetrical.

Symmetrical encryption is a type of encryption where one key can be used to encrypt messages to the opposite party, and also to decrypt the messages received from the other participant. This means that anyone who holds the key can encrypt and decrypt messages to anyone else holding the key.

This type of encryption scheme is often called “shared secret” encryption, or “secret key” encryption. There is typically only a single key that is used for all operations, or a pair of keys where the relationship is easy to discover and it is trivial to derive the opposite key.

Symmetric keys are used by SSH in order to encrypt the entire connection. Contrary to what some users assume, public/private asymmetrical key pairs that can be created are only used for authentication, not the encrypting the connection. The symmetrical encryption allows even password authentication to be protected against snooping.

The client and server both contribute toward establishing this key, and the resulting secret is never known to outside parties. The secret key is created through a process known as a key exchange algorithm. This exchange results in the server and client both arriving at the same key independently by sharing certain pieces of public data and manipulating them with certain secret data. This process is explained in greater detail later on.

The symmetrical encryption key created by this procedure is session-based and constitutes the actual encryption for the data sent between server and client. Once this is established, the rest of the data must be encrypted with this shared secret. This is done prior to authenticating a client.

SSH can be configured to utilize a variety of different symmetrical cipher systems, including AES, Blowfish, 3DES, CAST128, and Arcfour. The server and client can both decide on a list of their supported ciphers, ordered by preference. The first option from the client’s list that is available on the server is used as the cipher algorithm in both directions.

On Ubuntu 14.04, both the client and the server are defaulted like this: aes128-ctraes192-ctr,,

This means that if two Ubuntu 14.04 machines are connecting to each other (without overriding the default ciphers through configuration options), they will always use the aes128-ctr cipher to encrypt their connection.

Asymmetrical Encryption

Asymmetrical encryption is different from symmetrical encryption in that to send data in a single direction, two associated keys are needed. One of these keys is known as the private key, while the other is called the public key.

The public key can be freely shared with any party. It is associated with its paired key, but the private key cannot be derived from the public key. The mathematical relationship between the public key and the private key allows the public key to encrypt messages that can only be decrypted by the private key. This is a one-way ability, meaning that the public key has no ability to decrypt the messages it writes, nor can it decrypt anything the private key may send it.

The private key should be kept entirely secret and should never be shared with another party. This is a key requirement for the public key paradigm to work. The private key is the only component capable of decrypting messages that were encrypted using the associated public key. By virtue of this fact, any entity capable decrypting these messages has demonstrated that they are in control of the private key.

SSH utilizes asymmetric encryption in a few different places. During the initial key exchange process used to set up the symmetrical encryption (used to encrypt the session), asymmetrical encryption is used. In this stage, both parties produce temporary key pairs and exchange the public key in order to produce the shared secret that will be used for symmetrical encryption.

The more well-discussed use of asymmetrical encryption with SSH comes from SSH key-based authentication. SSH key pairs can be used to authenticate a client to a server. The client creates a key pair and then uploads the public key to any remote server it wishes to access. This is placed in a file calledauthorized_keys within the ~/.ssh directory in the user account’s home directory on the remote server.

After the symmetrical encryption is established to secure communications between the server and client, the client must authenticate to be allowed access. The server can use the public key in this file to encrypt a challenge message to the client. If the client can prove that it was able to decrypt this message, it has demonstrated that it owns the associated private key. The server then can set up the environment for the client.


Another form of encryption that SSH takes advantage of is cryptographic hashing. Cryptographic hash functions are methods of creating a succinct “signature” or summary of a set of information. Their main distinguishing attributes are that they are never meant to be decrypted, they are virtually impossible to influence predictably, and they are practically unique.

Using the same hashing function and message should produce the same hash; modifying any portion of the data should produce an entirely different hash. A user should not be able to produce the original message from a given hash, but they should be able to tell if a given message produced a given hash.

Given these properties, hashes are mainly used for data integrity purposes and to verify the authenticity of communication. The main use in SSH is with HMAC, or hash-based message authentication codes. These are used to ensure that the received message text is intact and unmodified.

As part of the encryption negotiation, a message authentication code (MAC) algorithm is selected. The algorithm is chosen by working through the client’s list of acceptable MAC choices. The first one out of this list that the server supports will be used.

Each message that is sent after the encryption is negotiated must contain a MAC so that the other party can verify the packet integrity. The MAC is calculated from the symmetrical shared secret, the packet sequence number of the message, and the actual message content.

The MAC itself is sent outside of the symmetrically encrypted area as the final part of the packet. Researchers generally recommend this method of encrypting the data first, and then calculating the MAC.

How Does SSH Work?

You probably already have a basic understanding of how SSH works. The SSH protocol employs a client-server model to authenticate two parties and encrypt the data between them.

The server component listens on a designated port for connections. It is responsible for negotiating the secure connection, authenticating the connecting party, and spawning the correct environment if the credentials are accepted.

The client is responsible for beginning the initial TCP handshake with the server, negotiating the secure connection, verifying that the server’s identity matches previously recorded information, and providing credentials to authenticate.

An SSH session is established in two separate stages. The first is to agree upon and establish encryption to protect future communication. The second stage is to authenticate the user and discover whether access to the server should be granted.

Negotiating Encryption for the Session

When a TCP connection is made by a client, the server responds with the protocol versions it supports. If the client can match one of the acceptable protocol versions, the connection continues. The server also provides its public host key, which the client can use to check whether this was the intended host.

At this point, both parties negotiate a session key using a version of something called the Diffie-Hellman algorithm. This algorithm (and its variants) make it possible for each party to combine their own private data with public data from the other system to arrive at an identical secret session key.

The session key will used to encrypt the entire session. The public and private key pairs used for this part of the procedure are completely separate from the SSH keys used to authenticate a client to the server.

The basis of this procedure for classic Diffie-Hellman is:

  1. Both parties agree on a large prime number, which will serve as a seed value.
  2. Both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way.
  3. Independently, each party comes up with another prime number which is kept secret from the other party. This number is used as the private key for this interaction (different than the private SSH key used for authentication).
  4. The generated private key, the encryption generator, and the shared prime number are used to generate a public key that is derived from the private key, but which can be shared with the other party.
  5. Both participants then exchange their generated public keys.
  6. The receiving entity uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key. Although this is independently computed by each party, using opposite private and public keys, it will result in the same shared secret key.
  7. The shared secret is then used to encrypt all communication that follows.

The shared secret encryption that is used for the rest of the connection is called binary packet protocol. The above process allows each party to equally participate in generating the shared secret, which does not allow one end to control the secret. It also accomplishes the task of generating an identical shared secret without ever having to send that information over insecure channels.

The generated secret is a symmetric key, meaning that the same key used to encrypt a message can be used to decrypt it on the other side. The purpose of this is to wrap all further communication in an encrypted tunnel that cannot be deciphered by outsiders.

After the session encryption is established, the user authentication stage begins.

Authenticating the User’s Access to the Server

The next stage involves authenticating the user and deciding access. There are a few different methods that can be used for authentication, based on what the server accepts.

The simplest is probably password authentication, in which the server simply prompts the client for the password of the account they are attempting to login with. The password is sent through the negotiated encryption, so it is secure from outside parties.

Even though the password will be encrypted, this method is not generally recommended due to the limitations on the complexity of the password. Automated scripts can break passwords of normal lengths very easily compared to other authentication methods.

The most popular and recommended alternative is the use of SSH key pairs. SSH key pairs are asymmetric keys, meaning that the two associated keys serve different functions.

The public key is used to encrypt data that can only be decrypted with the private key. The public key can be freely shared, because, although it can encrypt for the private key, there is no method of deriving the private key from the public key.

Authentication using SSH key pairs begins after the symmetric encryption has been established as described in the last section. The procedure happens like this:

  1. The client begins by sending an ID for the key pair it would like to authenticate with to the server.
  2. The server check’s the authorized_keys file of the account that the client is attempting to log into for the key ID.
  3. If a public key with matching ID is found in the file, the server generates a random number and uses the public key to encrypt the number.
  4. The server sends the client this encrypted message.
  5. If the client actually has the associated private key, it will be able to decrypt the message using that key, revealing the original number.
  6. The client combines the decrypted number with the shared session key that is being used to encrypt the communication, and calculates the MD5 hash of this value.
  7. The client then sends this MD5 hash back to the server as an answer to the encrypted number message.
  8. The server uses the same shared session key and the original number that it sent to the client to calculate the MD5 value on its own. It compares its own calculation to the one that the client sent back. If these two values match, it proves that the client was in possession of the private key and the client is authenticated.

As you can see, the asymmetry of the keys allows the server to encrypt messages to the client using the public key. The client can then prove that it holds the private key by decrypting the message correctly. The two types of encryption that are used (symmetric shared secret, and asymmetric public-private keys) are each able to leverage their specific strengths in this model.

How To VNC Through SSH Tunnel on Linux


VNC, or “Virtual Network Computing”, is a connection system that allows you to use your keyboard and mouse to interact with a graphical desktop environment on a remote server. VNC makes managing files, software, and settings on a remote server easier for users who are not yet comfortable with working with the command line.

In this guide, we will be setting up VNC on an Ubuntu server and connecting to it securely through an SSH tunnel. The VNC server we will be using is TightVNC, a fast and lightweight remote control package. This choice will ensure that our VNC connection will be smooth and stable even on slower Internet connections.

How to VNC Through SSH Tunnel: Prerequisites

Before you begin with this guide, there are a few steps that need to be completed first.

You will need an Ubuntu server installed and configured with a non-root user that has sudo privileges.

Once you have your non-root user, you can use it to SSH into your Ubuntu server and continue with the installation of your VNC server.

Install Desktop Environment and VNC Server

By default, most Linux server installations will not come with a graphical desktop environment. If this is the case, we’ll need to begin by installing one that we can work with. In this example, we will install XFCE4, which is very lightweight while still being familiar to most users.

We can get the XFCE packages, along with the package for TightVNC, directly from Ubuntu’s software repositories using apt:

sudo apt-get update
sudo apt-get install xfce4 xfce4-goodies tightvncserver

To complete the VNC server’s initial configuration, use the vncserver command to set up a secure password:


(After you set up your access password, you will be asked if you would like to enter a view-only password. Users who log in with the view-only password will not be able to control the VNC instance with their mouse or keyboard. This is a helpful option if you want to demonstrate something to other people using your VNC server.)

vncserver completes the installation of VNC by creating default configuration files and connection information for our server to use. With these packages installed, you are ready to configure your VNC server and graphical desktop.

Configure VNC Server

First, we need to tell our VNC server what commands to perform when it starts up. These commands are located in a configuration file called xstartup. Our VNC server has an xstartup file preloaded already, but we need to use some different commands for our XFCE desktop.

When VNC is first set up, it launches a default server instance on port 5901. This port is called a display port, and is referred to by VNC as :1. VNC can launch multiple instances on other display ports, like:2, :3, etc. When working with VNC servers, remember that :X is a display port that refers to5900+X.

Since we are going to be changing how our VNC servers are configured, we’ll need to first stop the VNC server instance that is running on port 5901:

vncserver -kill :1

Before we begin configuring our new xstartup file, let’s back up the original in case we need it later:

mv ~/.vnc/xstartup ~/.vnc/xstartup.bak

Now we can open a new xstartup file with nano:

nano ~/.vnc/xstartup

Insert these commands into the file so that they are performed automatically whenever you start or restart your VNC server:

xrdb $HOME/.Xresources
startxfce4 &

The first command in the file, xrdb $HOME/.Xresources, tells VNC’s GUI framework to read the server user’s.Xresources file. .Xresources is where a user can make changes to certain settings of the graphical desktop, like terminal colors, cursor themes, and font rendering.

The second command simply tells the server to launch XFCE, which is where you will find all of the graphical software that you need to comfortably manage your server.

To ensure that the VNC server will be able to use this new startup file properly, we’ll need to grant executable privileges to it:

sudo chmod +x ~/.vnc/xstartup

Create a VNC Service File

To easily control our new VNC server, we should set it up as an Ubuntu service. This will allow us to start, stop, and restart our VNC server as needed.

First, open a new service file in /etc/init.d with nano:

sudo nano /etc/init.d/vncserver

The first block of data will be where we declare some common settings that VNC will be referring to a lot, like our username and the display resolution.

export USER="user"
OPTIONS="-depth ${DEPTH} -geometry ${GEOMETRY} :${DISPLAY} -localhost"
. /lib/lsb/init-functions

Be sure to replace user with the non-root user that you have set up, and change 1024x768 if you want to use another screen resolution for your virtual display.

Next, we can start inserting the command instructions that will allow us to manage the new service. The following block binds the command needed to start a VNC server, and feedback that it is being started, to the command keyword start.

case "$1" in
log_action_begin_msg "Starting vncserver for user '${USER}' on localhost:${DISPLAY}"
su ${USER} -c "/usr/bin/vncserver ${OPTIONS}"

The next block creates the command keyword stop, which will immediately kill an existing VNC server instance.

log_action_begin_msg "Stopping vncserver for user '${USER}' on localhost:${DISPLAY}"
su ${USER} -c "/usr/bin/vncserver -kill :${DISPLAY}"

The final block is for the command keyword restart, which is simply the two previous commands (stop andstart) combined into one command.

$0 stop
$0 start
exit 0

Once all of those blocks are in your service script, you can save and close that file. Make this service script executable, so that you can use the commands that you just set up:

sudo chmod +x /etc/init.d/vncserver

Now try using the service and command to start a new VNC server instance:

sudo service vncserver start

Connect to Your VNC Desktop

To test your VNC server, you’ll need to use a client that supports VNC connections over SSH tunnels. If you are using Windows, you could use TightVNC, RealVNC, or UltraVNC. Mac OS X users can use the built-in Screen Sharing, or can use a cross-platform app like RealVNC.

First, we need to create an SSH connection on your local computer that securely forwards to thelocalhostconnection for VNC. You can do this via the terminal on Linux or OS X via the following command:

(Remember to replace user and server_ip_address with the username and IP you used to connect to your server via SSH.)

ssh -L 5901: -N -f -l user server_ip_address

If you are using a graphical SSH client, like PuTTY, use server_ip_address as the connection IP, and setlocalhost:5901 as a new forwarded port in the program’s SSH tunnel settings.

Next, you can use your VNC viewer to connect to the VNC server at localhost:5901. Make sure you don’t forget that :5901 at the end, as that is the only port that the VNC instance is accessible from.

Once you are connected, you should see the default XFCE desktop ready for configuration and use! It should look something like this:


Once you have verified that the VNC connection is working, add your VNC service to the default services, so that it will automatically start whenever you boot your server:

sudo update-rc.d vncserver defaults

How to Decompress ZIP Archives With SSH

To save time on big file transfers, you can upload as a ZIP archive and decompress the file using SSH.

It could save you a lot of time.1

Here’s how to do it.

Tools and Setup

Before you begin, make sure you have shell access enabled for your domain. Not all web hosting companies provide this.

Secondly, you will need a SSH client. That’s the software you use to connect. On Windows, we recommend PuTTY, partly because it’s free. (If you using Mac or Unix, check out this info on how to start a SSH session).

Finally, you’ll need an FTP application like FileZilla.

Transfer and Decompress

Here’s how to do the rest. Replace all of the generic words we’ve used with your own details.

  1. FTP the ZIP file to the right directory on your host. It’s easier if you FTP the file to the folder where you want the unzipped files to appear.
  2. Open your SSH client or connect using your preferred application.
  3. Log in using your FTP password.
  4. At the [server]$ prompt, type ls to display a list of your directories.
  5. Type cd to change directory to the location of the zip file upload.
  6. Type ls again. You should see the name of the ZIP file you uploaded.
  7. Type unzip

Depending on how many files are in the zip, it might take a while to finish. But, when it does you will have all your files decompressed, exactly where you wanted them.

How to Decompress ZIP Archives With SSH

SSH Cheatsheet

SSH Client Usage

SSH Client Usage:

Install on Debian based distro(Usually installed by default):

sudo apt-get install openssh

Generate a SSH Key / Specify type:

ssh-keygen / ssh-keygen -t [key type]

Manually Copy SSH Key to Remote Server:

cat ~/.ssh/[name of key file] | ssh user@hostname “cat – >> ~/.ssh/authorized_keys”

Automatically Install Pub Key to Remote Server:


Connect to a remote machine:


Add a SSH Agent:


TCP Port Forwarding:

Port Forward a Local Port:

ssh -L [Local Port to connect to]:[Remote Host]:[Port to forward]

Reverse Port Forward to a Remote Machine:

ssh -R [Local Port to connect to]:localhost:[Port to Forward]

then from

ssh -p [Forwarded Port] username@localhost

Persistant Reverse Port Forward:

while true ; do ssh -R [Local Port to connect to]:localhost:[Port to Forward] ; sleep 60 ; done


ssh -D [Port to proxy traffic to]

Run a command and exit SSH Shell:

ssh [Command to run]

Forcing a command to run on each connect:

– Edit the ./ssh/authorized_keys file
– Before ssh-rsa type [variable name]=”[command to run]”

Use SCP to copy a file from Local machine to Remote Machine:

scp [/path/to/file.txt]

Use SCP to copy from remote machine to local machine:

scp[/path/to/file.txt] [name of file]


Use SCP to copy from a specific remote directory to specific local directory with different name:

scp ~/Documents/newfilename

Use SCP to recursively copy a directory:

scp -r [/path/to/dir][/path/to/save/dir]

Use SCP to copy but attempt to keep timestamps/permissions:

scp -rp [/path/to/dir][/path/to/save]

Set up Yubikey with PAM for OpenVPN, SSH and Squirrelmail

Yubikey and PAM for SSH:
If you’re using ArmHF or Armel you might experience a bug with the default libpam-yubikey packages:

If you have succesfully build the new package/fix and installed it, then it’s time to continue the setup for SSH:
1) you can create a global config or use a users own yubikey file, I choose the latter: mkdir /home/*username*/.yubico/ and create a file authorized_yubikeys
The context of this file should be:
username:*yubikey first 12 characters*:*next yubikey first 12 characters*
2) get an API key for the yubikey cloud solution to authenticate against:
3) remember the API key and add the following line to /etc/pam.d/sshd:
auth required id=*your API id number* key=*your API key* url=
4) comment /etc/ssh/sshd_config ChallengePassword no (so it says yes when you comment is!)
5) restart sshd: /etc/init.d/ssh restart or service sshd restart
6) test !

For OpenVPN with Yubikey and PAM:

1) Follow above steps for the correct yubikey pam module
2) Install OpenVPN with a default server.conf, ca.crt, server.crt etc following the 100 manuals on the net
3) Check if you have the OpenVPN AUTH module installed when you installed OpenVPN aka /usr/lib/openvpn/ – if you don’t have this file install the openvpn-pam module
4) add the following to the /etc/openvpn/server.conf:
### yubikey auth
plugin /usr/lib/openvpn/ openvpn #make sure the path is correct and end the line with the pam module name (openvpn – we’ll create this file manually later on)
5) create a file /etc/pam.d/openvpn with the following contents:
auth required authfile=/etc/yubikeyid id=16 debug
auth required use_first_pass
# first check the yubikey auth and then a succesful unix PAM auth
6) change the client openvpn config to add the following line: auth-user-pass
7) test!

Yubikey and Squirrelmail:
Read the howto here:

Don’t forget to install php-curl or similar package as php needs to do a curl
command/post against the Yubico API

How to setup and tunnel VNC over SSH trough the internet

Tunneling Your Way Out Of Corporate Networks with SSH + Socks and OpenVPN

Tunneling your way out of corporate networks Part 1: SSH + Socks:

The Proxytunnel tool, used in Part 1 can be downloaded from:

Tunneling your way out of corporate networks Part 2: OpenVPN:

NSA Documents: Attacks on VPN, SSL, TLS, SSH and Tor

Interesting talk about SSH and port forwarding + Some SSH Tools

The Black Magic Of SSH / SSH Can Do That?

Some additional background information about SSH and how it’s working:

Some SSH config examples:

20 Best SSH security practices:

Execute command over SSH:

Mosh (Mobile Shell) – Useful SSH program for GNU/Linux, BSD, OS X, Solaris and Android
More info: and