SSH
The secure shell (ssh) is a powerful tool. It allows you to connect
to a remote machine and issue commands on a terminal like you would be
there. It actually works without much configuration if you have server
already running ssh as a daemon. If you haven’t installed it yet, you do
apt-get install openssh-client
on the machine from which you want
to connect and apt-get install openssh-server
on the machine you want
to connect to.
Keys, Fingerprints, and Connecting
To connect in a secure manner you need to know the fingerprint of the key used by the server. If it is not your machine, your administrator has probably supplied you with it somehow or somewhere. Talking about own machines you determine the fingerprints of keys of your server like this:
root@server:~# ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key
256 7a:17:9d:42:e7:cf:28:ba:af:29:a4:a1:2f:ad:4b:1a /etc/ssh/ssh_host_ecdsa_key.pub (ECDSA)
It’s plural, because at the moment you will probably have different kinds
of keys there (dsa, rsa, ecdsa). Those are encryption algorithms btw.
I am going to use ecdsa in the following, that’s why examples show these.
You can do this with keys of the other type by just switching the names where
appripriate. Which key your server will use is agreed between client and
server btw. For more info on ssh-keygen refer to man ssh-keygen
.
Now when you connect to the machine for the first time ssh will give you as message like this:
user@host:~# ssh server
The authenticity of host 'server ([192.0.2.3])' can't be established.
ECDSA key fingerprint is 7a:17:9d:42:e7:cf:28:ba:af:29:a4:a1:2f:ad:4b:1a.
Are you sure you want to continue connecting (yes/no)?
This is the point at which you once have to verify that this is the key the server is supposed to respond with. Verify it against the key from above and only continue if you are sure they match. ssh will store this information and will not ask you again as long as neither the involved name/ip nor the keys used are altered. Otherwise you will get an according question again.
Oh, this all is assuming everything else works and you got no firewalls
inbetween. Default port for ssh is 22 btw.
if you should need forwarding or to open a port in a firewall. This is
also the simplest form of invoking ssh. If you want to connect to a
different user-account on the remote machine, prepend the username to the
severname like in ssh user@server
. I’ll get to some more options
later, but let’s visit key-generation first.
Generating Keys
You can generate new keys interactively by issueing ssh-keygen
. If
you need to generate lots of keys for unattended tasks, you might prefer
a non-interactive way. Here it comes …
To generate a new ssh-key in the file specified at the end with no
passphrase, the given email-address as a comment, and a 4096-bit key-length:
user@host:~$ ssh-keygen -b 4096 -t rsa -N "" -C user@host.local -f ./new_id_rsa
Your identification has been saved in ./new_id_rsa.
Your public key has been saved in ./new_id_rsa.pub.
The key fingerprint is:
e5:68:34:13:54:be:4b:ea:24:06:8c:fa:5d:eb:15:e0 user@host
The key's randomart image is:
+---[RSA 4096]----+
| .o.. |
| o |
| . + o |
| o . o * . |
| . o E S + |
| . . . + . |
|. + + . |
| . . o * |
| . ..o . |
+-----------------+
If you do not specify a destination-file ssh-keygen will assume a default (but prompt to you for it). The fingerprint shown here is important if you generate server-keys. Then, those will be shown for verification when connecting to the server for the first time.
The keys used by the server when responding to incoming ssh connections
are kept in /etc/ssh
. If you want to replace them you need to replace
the files there. Keys for users are kept in ~/.ssh
. This folder does
not exist before you start using ssh. So if you haven’t done so, go
ahead and create a key for yourself. Use ssh-keygen
without option to
do so, and it will generate the directory on the way.
Copying Keys
Ssh-keys are often used to access remote machines without having to
enter a password. That allows to use such connections by programs as well. Ssh will
look for a file named ~/.ssh/authorized_keys
and will allow logins for those keys. I
started by copying those manually with scp. But there is an easier
way resulting in less typing …
To copy a key (the public part of it) to a remote server you can use
the tool ssh-copy-id
. In
its simple form you invoke it like this to copy your (the current users)
ssh-key to the remote users authorized_keys file:
user@host:~$ ssh-copy-id user@server
That would copy the public key of the current user to the homedirectory
of the specified user on the server. You will be asked for fingerprint and
password as approriate.
If the key in question is not that of your current user, you can specify
a key with the -i
option like this:
user@host:~$ ssh-copy-id -i ./new_id_rsa.pub user@remotehost.local
Now after that’s done, connect to your server again and notice how it will not ask you for a password anymore. If your key is protected by a password, you will have to enter that though, if the key is not yet otherwise unlocked.
Key Management and SSH-Agent
If you have to manage many different keys, entering the passphrase for those can become annoyingly unconvenient. However your keys should have a passphrase, if you cannot make sure that nobody will ever have access to them. If the keys are stolen as files, they are still worthless without the passphrase. If there is no passphrase on the keys, anyone in posession of the files can log onto machines prepped as described above without any further obstacles. So consider when to use ssh-keys without passphrase. There are measures to restrict a keys usage, but more on that later.
So if you do not want to unlock your keys so often, you can use ssh-agent for this. If running Gnome this should happen automatically and you get a password dialogue in the window manager instead of the shell. If you have wondered what that is, that’s ssh-agent. In the dialogue you can chose to have the key unlocked every time you log-in. Do that, and you will not be asked. Note that it is rather easy to forget passphrases this way.
Using this chain, you can now log-in to your remote machines without
entering a further password after you have logged into your workplace.
A really convenient way to work with remote machines for sure. You can use
ssh-agent on desktop-less systems as well. Refer to man ssh-agent
and man ssh-add
.
If you use many different machines you can also start seperating where
the known fingerprints for target servers are saved. Usually these are all
in ~/.ssh/known_hosts
, but you can provide ssh with the option
-o UserKnownHostsFile="~/.ssh/known_hosts.server1"
to use a different
file. For example handy if you want to distribute them and prepare clients
for a seamless access.
X- and Port-Forwarding, copying with SSH
Knowing how to access machines with ssh is just the beginning though. Let’s explore how to use this besides typing commands.
-
X-Forwarding
One thing you may encounter is that you would like to start a graphical application on the remote machine. Without any further measures this will either show you an error or start the application and diplay it on the remote machine. Now if you actually want the application to be displayed on your X server, just pass the options
-XY
to your ssh. Try again and you get the window on your local machine. Neat stuff … -
Port-Forwarding
You can use ssh to easily access any ports on or from the remote machine. This is very powerful. You can use
-D 42000
in your ssh command and you get a SOCKS proxy on your local port 42000. Any requests you send there will be forwarded through the tunnel and send on from there. You can also use-L 42000:target:8080
to build a tunnel from your local port 42000 over the ssh connection to the server and from there to target on port 8000. -
File-Copies, Mounting
Editing files is fine and copy & paste works good, but what with large binary files? How does one get those to the server? Easy. Secure Copy (scp) is a variant of ssh specialised for this. It’s actually like FTP over SSH or something, but you don’t need to know. Just do a
scp ./localfile.zip user@host:/home/user/
and it’s done. Works as well the other way round btw. to copy from the server to your local machine. Can do recursive and more, seeman scp
. If you need to browse files or copy many selected files, you can also go one step further and use sshfs. For this you will need to install first withapt-get install sshfs
. Create a folder you want to use as a mountpoint (I will use /mnt/ssh here) and dosshfs user@server:/home/user /mnt/ssh
. Voila, your home-directory of the remote server is mounted.
Secure Shell on I2P
Infrastructure to manage IT is often build around using ssh. If you are good with using ssh and the command-line, you can start administering any of your machine from anywhere. You do have a problem though if machines are changing IPs, for example because the provider requires so. Now here comes the thing, it is pretty easy to start using ssh over I2P, which is not dependend on the IP. I just came to think of it and ended up trying out.
On your server (the machine you want to access), you create a hidden service. Go to the Hidden Service Manager (url is /i2ptunnelmgr) and look for the section with “I2P Hidden Services” (in contrast to the “I2P Client Tunnels” below that). At the bottom of that section you will find a Create Button with a dropdown aside. I chose “Standard” from the dropdown and pressed Create. I then chose a name and description and entered 127.0.0.1 with port 22 as the target. In the advanced options I chose “interactive connection” as the profile and pressed save. I then started the tunnel as I chose to not have it start automatically for now. After the tunnel was running I clicked on it (like to edit it) and copied the Local destination, the I2P address that has been generated for it.
On my home-network I then went to the router console and also to the Hidden Service Manager, but this time to the lower “I2P Client Tunnels” section. That also has a dropdown with button at its end, I again chose “Standard” in the dropdown and pressed create. And again a name and a description. As access point I chose a port-number (like 42000) and reachability from 0.0.0.0 as I wanted my whole LAN to have access to it. At tunnel destination I entered the destination as copied from the server setup above. Under Advanced Options I again chose “interactive connection”. Create, start.
I didn’t even verify anything, but directly went and attempted to connect. I used my usual setup with an ssh-key to connect and just changed the host and port to match that of my local i2p router and the tunnel-port as chosen right before. ssh then asked about the server-fingerprint, as it hasn’t connected to my i2p router on that port ever before. It can’t know it’s the same server I usually connect under its ClearNet name. So I verified that fingerprint, and voila, connected. It’s not fast, you do notice the delay with every keystroke. But it seems to work pretty reliably and is usable.