Learning advanced SSH configurations and tunnelling (2/2)

Parichay Barpanda
Aug 31, 2018 · 9 min read

This post expects that you have basic knowledge about what is SSH protocol and how to SSH into your remote machine from your client computer. If you are not sure about it, read the “About SSH” section from my previous post.

Server-Side Configuration Options:

You can many changes in the ssh server side by making changes to the configuration file which is located inside /etc/ssh/ as “sshd_config”. Here is a couple of examples.

Disabling Password Authentication

To disable password authentication in our remote server Type:

nano /etc/ssh/sshd_config

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

Press Ctrl +X and save it.

Changing the port on which the SSH Daemon listens on

You should change the default port that SSH runs on. This decreases the number of authentication attempts on your server by automated bots.
To change the port that the SSH daemon listens on, you will have to log into your remote server. Open the sshd_config file on the remote system with root privileges, either by logging in with that user or by using sudo:

sudo nano /etc/ssh/sshd_config

Once you are inside, you can change the port that SSH runs on by finding the Port 22 specification and changing it to your desired port. For example, to change the port to 8000, put this in your file:

#Port 22
Port 8000

Save and close the file when you are finished. To implement the changes, you must restart the SSH daemon.

To restart SSH Daemon:

sudo service ssh restart

Client-Side Configuration Options:

You can also configure some options how to connect to the remote server from the client side. The configurations should be stored in the ~/.ssh/config file, which is read by your SSH client each time it is called.

Defining Server-Specific Connection Information

Create or open this file in your text editor on your local computer:

nano ~/.ssh/config

Inside, you can define individual configuration options by introducing each with a Host keyword, followed by an alias. Beneath this and indented, you can define any of the directives found in the ssh_configman page:

man ssh_config

An example configuration would be:

Host test
HostName baymax
Port 8000
User parichay

You could then connect to baymax on port 8000 using the username "parichay" by simply typing:

ssh test

You can also use wildcards to match more than one host. Keep in mind that later matches can override earlier ones. Because of this, you should put your most general matches at the top. For instance, you could default all connections to not allow X forwarding, with an override for baymax by having this in your file:

Host *
ForwardX11 no
Host test
HostName baymax
ForwardX11 yes
Port 8000
User parichay

Save and close the file when you are finished.

Disabling Host Checking

By default, whenever you connect to a new server, you will be shown the remote SSH daemon’s host key fingerprint.

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

This is configured so that you can verify the authenticity of the host you are attempting to connect to and spot instances where a malicious user may be trying to masquerade as the remote host.

In certain circumstances, you may wish to disable this feature. Like when your ip address of your host keeps changing everytime you restart your router. Note: This can be a big security risk, so make sure you know what you are doing if you set your system up like this.

To make the change, the open the ~/.ssh/config file on your local computer:

nano ~/.ssh/config

If one does not already exist, at the top of the file, define a section that will match all hosts. Set the StrictHostKeyChecking directive to "no" to add new hosts automatically to the known_hosts file. Set the UserKnownHostsFile to /dev/null to not warn on new or changed hosts:

Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

You can enable the checking on a case-by-case basis by reversing those options for other hosts. The default for StrictHostKeyChecking is "ask":

Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host testhost
HostName baymax
StrictHostKeyChecking ask
UserKnownHostsFile /home/demo/.ssh/known_hosts

Setting Up SSH Tunnels:

Tunneling other traffic through a secure SSH tunnel is an excellent way to work around restrictive firewall settings. It is also a great way to encrypt otherwise unencrypted network traffic.

Configuring Local Tunneling to a Server

SSH connections can be used to tunnel traffic from ports on the local host to ports on a remote host.

In local tunnel, you access a network location from your local computer through your remote host. First, an SSH connection is established to your remote host. On the remote server, a connection is made to an external (or internal) network address provided by the user and traffic to this location is tunnelled to your local computer on a specified port.

This is often used to tunnel to a less restricted networking environment by bypassing a firewall. Another common use is to access a “localhost-only” web interface from a remote location.

To establish a local tunnel to your remote server, you need to use the -L parameter when connecting and you must supply three pieces of additional information:

  • The local port where you wish to access the tunneled connection.
  • The host that you want your remote host to connect to.
  • The port that you want your remote host to connect on.

These are given, in the order above (separated by colons), as arguments to the -L flag. We will also use the -f flag, which causes SSH to go into the background before executing and the -N flag, which does not open a shell or execute a program on the remote side.

For instance, to connect to baymax on port 80 on your remote host, making the connection available on your local machine on port 8888, you could type:

ssh -f -N -L 8888:baymax:80 username@remote_host

Now, if you point your local web browser to 127.0.0.1:8888, you should see whatever content is at baymax on port 80.

Here’s an example. Let’s say you reside behind a restrictive firewall which does not allow outgoing SMTP connections except to a designated mail server. You want to connect to a different mail server, mail.example.net, on port 25. You have an SSH account on a machine shell.example.org, which does not reside within the restrictive firewall and can thus access port 25 on mail.example.net.

With standard SSH port forwarding, you could enter the command:

ssh -L 2525:mail.example.net:25 shell.example.org

This will forward port 2525 on your machine to port 25 on mail.example.net, by way of shell.example.org. You will then need to configure your mailer to send mail to localhost, port 2525, and use the authentication information for your mail account on mail.example.net.

Configuring Remote Tunneling to a Server

In a remote tunnel, a connection is made to a remote host. The remote computer is made to access a host through your local computer.

This can be useful if you need to allow access to an internal network that is locked down to external connections. If the firewall allows connections out of the network, this will allow you to connect out to a remote machine and tunnel traffic from that machine to a location on the internal network.

To establish a remote tunnel to your remote server, you need to use the -R parameter when connecting and you must supply three pieces of additional information:

  • The port where the remote host can access the tunneled connection.
  • The host that you want your local computer to connect to.
  • The port that you want your local computer to connect to.

These are given, in the order above (separated by colons), as arguments to the -R flag. We will also use the -f flag, which causes SSH to go into the background before executing and the -N flag, which does not open a shell or execute a program on the remote side.

For instance, to connect to baymax on port 80 on your remote host, making the connection available on your local machine on port 8888, you could type:

ssh -f -N -R 8888:baymax:80 username@remote_host

Configuring Dynamic Tunnelling to a Remote Server

A dynamic tunnel is similar to a local tunnel in that it allows the local computer to connect to other resources through a remote host. A dynamic tunnel does this by simply specifying a single local port. Applications that wish to take advantage of this port for tunneling must be able to communicate using the SOCKS protocol so that the packets can be correctly redirected at the other side of the tunnel.

Local tunnelling comes with a bunch of hassles like configuring your local computer so that it uses the forwarded port. To avoid all hassles, SSH supports dynamic port forwarding via SOCKS. SOCKS defines a standard mechanism for a client to connect to a server by way of a proxy. SSH can serve as the proxy, allowing you to connect to shell.example.org and make connections from there to an arbitrary server such as mail.example.net. Simply run:

ssh -D 1080 shell.example.org

to make the connection to shell.example.org and start a SOCKS proxy on localhost port 1080.

Traffic that is passed to this local port will be sent to the remote host. From there, the SOCKS protocol will be interpreted to establish a connection to the desired end location. This set up allows a SOCKS-capable application to connect to any number of locations through the remote server, without multiple static tunnels.

In order to make use of the SOCKS proxy, you can either use applications which can speak SOCKS natively, or you can use a socksifierprogram like tsocks. tsocks provides a library used with LD_PRELOAD, which replaces the standard sockets functions like socket, connect, and sendto with functions that make use of a designated SOCKS proxy. The tsocks script runs a program with this library loaded. The library will read /etc/tsocks.conf to find out what SOCKS proxy to use. To configure tsocks to work with an SSH SOCKS proxy on localhost, edit the default /etc/tsocks.conf, change the server variable to 127.0.0.1, and comment out the path example.

Using SSH Escape Codes to Control Connections

Even after establishing an SSH session, it is possible to exercise control over the connection from within the terminal. We can do this with something called SSH escape codes, which allow us to interact with our local SSH software from within a session. These commands can be executed starting with the ~ control character from within an SSH connection. Control commands will only be interpreted if they are the first thing that is typed after a newline, so always press ENTER one or two times prior to using one.

Forcing a Disconnect from the Client-Side

To close a connection from the client, use the control character (~), with a dot. If your connection is having problems, you will likely be in what appears to be a stuck terminal session. Type the commands despite the lack of feedback to perform a client-side disconnect:

[ENTER]
~.

The connection should immediately close, returning you to your local shell session.

Placing an SSH Session into the Background

To put an SSH session into the background, we need to supply the control character (~) and then execute the conventional keyboard shortcut to background a task (CTRL-z):

[ENTER]
~[CTRL-z]

This will place the connection into the background, returning you to your local shell session. To return to your SSH session, you can use the conventional job control mechanisms.

You can immediately re-activate your most recent backgrounded task by typing:

fg

If you have multiple backgrounded tasks, you can see the available jobs by typing:

jobs[1]+  Stopped                 ssh username@some_host
[2] Stopped ssh username@another_host

You can then bring any of the tasks to the foreground by using the index in the first column with a percentage sign:

fg %2

Changing Port Forwarding Options on an Existing SSH Connection

To alter the port forwarding configuration after the connection has already been established, we use the SSH command line interface, which can be accessed during a session by using the control character (~) and "C":

[ENTER]
~C
ssh>

You will be given an SSH command prompt, which has a very limited set of valid commands. To see the available options, you can type -h from this prompt. If nothing is returned, you may have to increase the verbosity of your SSH output by using ~v a few times:

[ENTER]
~v
~v
~v
~C
-h
Commands:
-L[bind_address:]port:host:hostport Request local forward
-R[bind_address:]port:host:hostport Request remote forward
-D[bind_address:]port Request dynamic forward
-KL[bind_address:]port Cancel local forward
-KR[bind_address:]port Cancel remote forward
-KD[bind_address:]port Cancel dynamic forward

As you can see, you can easily implement any of the forwarding options using the appropriate options (see the forwarding section for more information). You can also destroy a tunnel with the associated “kill” command specified with a “K” before the forwarding type letter. For instance, to kill a local forward (-L), you could use the -KL command. You will only need to provide the port for this.

So, to set up a local port forward, you may type:

[ENTER]
~C
-L 8888:127.0.0.1:80

Port 8888 on your local computer will now be able to communicate with the web server on the host you are connecting to. When you are finished, you can tear down that forward by typing:

[ENTER]
~C
-KL 8888

The information above mostly covers the day-to-day commands you need for SSH and tunnelling. You can read about SOCKS Server so that you can develop your application to make use of dynamic tunnelling. Also if you have some cool hacks to share, please let me know in the comments down below. Clap if you liked it,follow if you loved it. Thanks >

Parichay Barpanda

Written by

All about programming.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade