SSH config, ssh via jumphost and autossh (ssh to Tor hidden service)

This will be a short post about the above mentioned parts, lets start right away.

SSH config

Every user can have a SSH client configuration file, it is located in ~/.ssh/config (where config ist the filename).
My SSH config file, I guess as many other users file, grew over time. Lets start with some things from my file.

There is the Host part, it usually contains the name you want to assign to the host to use it later on. Tipp, use some short and of course unique name.

Host myserver

The Host part can be wildcard, then the following parameters are valid for any Host. It then looks like this:

Host *
     ServerAliveInterval 15
     ControlMaster auto
     ControlPath /tmp/ssh-%r@%h:%p

ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. This option applies to protocol version 2 only.

This is copied from the man page of “ssh_config“.

In the case above it means the client will keep the connection alive by sending some packet every 15 seconds at least. The packet is send and the client will wait for a reply for 3 times the interval (2 packet can get lost) by default. I use this setting to be sure the connection is kept alive and it is still alive. I work on a mobile connection quite often.

ControlMaster auto
ControlPath /tmp/ssh-%r@%h:%p

These two options might be helpful in particular cases when you use multiple SSH connection to one host and want to save some time to build up the connection. The option is explained here and the options “/tmp/ssh-%r@%h:%p” are explained very well here. Basically it will use a socket to connect to the host and the socket will be in “/tmp/ssh-%r@%h:%p”, where “r” is the remote user name, “h” is the host name and “p” is the port number. The use of all this ensures that the socket name is unique.

Host myserver
	HostName example.org
	User username
        Port 22
#	IdentityFile ~/.ssh/id_rsa
	ForwardAgent yes
	Compression yes
	#CompressionLevel 9

HostName contains the remote IP or host name (domain name) you want to connect to, like in “ssh username@example.org” the example.org.

User contains the remote username.

This two are the minimum configuration parameters you want to use. When you want to connect to example.org via SSH you now just have to type the command “ssh myserver” and it will connect you as you are used to, but with much less typing.

Port is not needed if you want to use 22 (standard SSH port), so it is useless in the example above, but if you want to connect to some host that runs the SSH service on some non standard port, lets say 6022 you can use “Port 6022” to provide the port.

IdentityFile contains the identity file specific to the host. I commented this out some time ago because I now use a SSH-Agent, which you can do as well, there is “ssh-add” on any standard Linux system. So when I start a session I just do “ssh-add .ssh/id_rsa .ssh/id2_rsa” and so on to add all my needed ssh keys to the SSH-Agent.

With ForwardAgent your available keys from you local ssh-agent can be used on the remote host too, this is helpful when from the remote host you want to ssh to another server. I would suggest to use this option on any host, so you could move it to the “Host *” section.
Using this parameter will be handy if you want to rsync from one server to another.

You can use Compression if you are using a slow connection of if you transfer big amounts of data via SSH, it can be a bottle neck if your CPUs (local and remote) are not that fast. So it may be better to use Compression only in special cases or on really slow connections.
With CompressionLevel you can set the compression level, it is like with most other compressions and I came to the conclusion to comment it out with the #, so it is not used in my configuration anymore. Check the man page of gzip or similar to see the compression levels explanation from 1-9.

So if you want you can use the “Host *” section like this:

Host *
	ServerAliveInterval 15
	ControlMaster auto
	ControlPath /tmp/ssh-%r@%h:%p
    	ForwardAgent yes

Jump hosts

In some cases I want to connect to some host that is not reachable from the outside world (aka. the Internet), in this cases I use a jump host that is connected to that internal network.
I had to work some years the usual way, the usual way being to connect to the jump host by “ssh jumphost” and then open another ssh connection from its local command line interface. Instead you can add the following to your ssh configuration for the host in the internal network.

ssh -q -W %h:%p myserver

Explanation from explainshell.com:

ssh(1) -q -W %h:%p myserver

OpenSSH SSH client (remote login program)
-q Quiet mode. Causes most warning and diagnostic messages to be suppressed.
-W host:port Requests that standard input and output on the client be forwarded to host on port over the secure channel. Implies -N, -T, ExitOnForwardFailure and ClearAllForwardings and works with Protocol version 2 only.
ssh connects and logs into the specified hostname (with optional user name). The user must prove his/her identity to the remote machine using one of several methods depending on the protocol version used (see below). If command is specified, it is executed on the remote host instead of a login shell.

So when you add that to another Host configuration like this:

Host machine2
        HostName 192.168.0.42
        User username
        ssh -q -W %h:%p myserver

This would mean that your ssh connection to 192.168.0.42 as user username would be made via myserver and all data would be forwarded via myserver. This can also be used to connect via a particular server all the time if it is added to the “Host *” section of you ssh config.

SSH config for hidden Tor service SSH server

Something else I like to use ssh config for, is to connect to SSH via a tor Onion service, which I like to use for headless small computers (portable computer without a screen) like a Raspberry Pi that I connect to some network and want to SSH into them without knowing their IP address in the LAN. The setup of a Tor hidden service can be found online, the basic way it works is that your raspberry pi will tunnel to the Internet and be reachable via a hidden service.

Host raspberrypi
	HostName ap37csfkkmkksmkktllhjkcqd.onion 
        User Pi
        Port 22
        VerifyHostKeyDNS no
        ProxyCommand /bin/nc -xlocalhost:9050 -X5 %h %p

HostName now contains the .Onion domain of the hidden service.

I use VerifyHostKeyDNS to avoid warning about changed DNS for that host. I am not sure if it is actually needed, but at some point I added it.

The ProxyCommand parameter now is the important thing. I requires you to have Tor running as a client, this should be possible by “sudo apt-get install tor && sudo systemctl enable tor.service –now” Probably have to run it in two commands.
This uses netcat (nc) to forward all packets from ssh to nc to the local port 9050 (standard Tor Socks port).
I never noted what exactly the parameters for nc do. :-) if anyone know please let me know. I tried a quick search but it did not bring up any helpful results.

Port must contain the port the hidden service ssh is available at, this can be different from the clients ssh daemon/server but is defined by the hidden service configuration in the torrc config file.

Have a look in the manpage of ssh by typing “man ssh” in your command line or open the manpage online. The ssh_config manpage is also very helpful.

autossh

I lately started to use autossh in combination with remote screen sessions, screen is the tool to use if you work remotely and do something that you want to continue after a possible connection interruption. There is tmux as well, but I prefer screen. Please have a look at both and choose which you prefer and use it.

Quote from the manpage of autossh:

autossh is a program to start a copy of ssh and monitor it, restarting it as necessary should it die or stop passing traffic.

It basically improves the interruption resistivity of ssh by wrapping some other things around the connection and by using some special parameters. As I said I work remotely often and also I use mobile connections often on trains as well, I uses mosh (MObile SHell) before, but it is not working with screen that well, also it had some other downsides and to I ended up with autossh.

Let me know if there is any faults in this summary about my ssh use and setup.

Edit:
I figured something else out, I always wanted to keep my ssh config in sync between some computers. The problem was the synced folder is not ~/.ssh but ~/some/other/folder and in there I have a “ssh_config” file. So I tried to symlink that to my ~/.ssh which did not work (ln -s ~/some/other/folder/ssh_config ~/.ssh/config did not work) because auf some permission issue I think. Host in the file were just not found.
Today I figured out that I can include another file in my ~/.ssh/config by adding the following line in my ssh config file:

Include ~/some/other/folder/ssh_config

This now allows me to sync ~/some/other/folder/ssh_config between computers and include that file in my ssh config files on any computer I like to.