Other uses for OpenSSH
Published: May 31, 2009Many people use OpenSSH to connect to a remote machine, but many don’t know that you can actually do other interesting things with it, other than just opening a remote login shell. In this article I’ll show you a few of them.
We will see how to:
-
Copy files from one machine to another securely.
-
Forward ports from your machine through the remote machine, creating a secure tunnel for your unsecured applications.
-
Increase the security of your OpenSSH communications.
Make sure the OpenSSH daemon is running.
OpenSSH is the most widely used implementation of SSH, and you’ll probably find it already installed in most UNIX like systems.
To be able to connect to the remote machine you’ll need to have the sshd
daemon running in it. If this remote machine is actually physically remote
then it must have it already running, otherwise how could you do anything
at all?.
But if your remote machine is sitting right next you, or you are running it as a virtual machine and you are experimenting with OpenSSH, then you can find out if the daemon is running by executing the following command:
$ ps -ef | grep sshd
You should see a line similar to this (the numbers will vary):
root 2859 1 0 13:29 ? 00:00:00 /usr/sbin/sshd
If it is not already running consult your distribution documentation to find out how to to start it. On an Slackware system you can do that by executing the following command as root:
# /etc/rc.d/rc.sshd start
To have the sshd
daemon run every time your Slackware system boots up,
you’ll have to chmod
the startup script so that it has execute
permission.
# chmod 755 /etc/rc.d/rc.sshd
On a Debian system you can start the daemon by executing the following command:
# /etc/init.d/ssh start
To find out how to make it start every time your Debian system boots up,
read the update-rc.d
man page to figure out how.
$ man update-rc.d
1. Copy files from one machine to another securely.
1.1. Using scp
for simple transfers.
You can easily copy files from one machine to another through an encrypted connection with OpenSSH, and this will prevent anyone else from spying what you are sending over. The basic form is:
mymachine:~$ scp somefile.tar gajon@remote.com:
That will copy the file somefile.tar
to the remote machine remote.com
at the home folder of the user gajon
(I’ll be using my own user name in
all the examples here, but of course you should use your own instead).
It is important to put a colon (:
) after the remote machine name,
otherwise scp
will just rename your local file as gajon@remote.com
in
the same local folder in your machine.
It’s also possible to specify the path and final name that you want the
file to have in the remote server. For example, this will copy the file to
the folder backups
that is located in the user’s home.
mymachine:~$ scp somefile.tar gajon@remote.com:backups/
This will copy the file to the same folder as the previous example, but will save the file with a different name.
mymachine:~$ scp somefile.tar gajon@remote.com:backups/back02.tar
You can also copy files from the remote machine to your local machine, you
just have to reverse the order of the arguments. For example, this will
copy the file myapp.log
that is located in the /var/log
folder of the
remote machine to your local machine, but with the name remote.log
instead.
mymachine:~$ scp gajon@remote.com:/var/log/myapp.log remote.log
If you wanted to preserve the original name you could have used the following command:
mymachine:~$ scp gajon@remote.com:/var/log/myapp.log .
Notice that the remote path after the colon starts with a slash, that indicates an absolute path. If you don’t start the path with a slash then it’s a relative path, relative to the home of the user in the remote machine.
1.2 Using sftp
for secure FTP transfers.
Many people know how to use FTP, but some may not realize that everything they transfer during an FTP session, including their user names and passwords, are sent unencrypted or protected in any form. This opens up the possibility that someone with ill intentions might capture that information.
sftp
solves that problem and it is used the same way as ftp
, so that
the user doesn’t need to learn anything new, and most graphical FTP
clients can also use sftp
– for example, FileZilla.
In this example we get the file back02.tar
from the remote machine and
save it in our local computer.
mymachine:~$ sftp gajon@remote.com
Connecting to remote.com...
gajon@remote.com's password:
sftp> cd backups
sftp> get back02.tar
sftp> bye
When you log on to a remote machine with the sftp
client the prompt will
change to sftp>
. The commands are almost the same as with a traditional
ftp
, you can enter ?
to see a list of available commands.
2. Forwarding ports.
2.1. From your local machine to a remote machine.
Port forwarding is useful for creating a secure data tunnel for an application that doesn’t support encryption or other form of secure communication out of the box. This is also useful to go through a firewall and skip any of its restrictions.
As an example, lets suppose you want to access a POP3 server. You can
redirect one of your local ports, lets say 9999
, to the port 110
(POP3) of the remote machine.
mymachine:~$ ssh -L 9999:localhost:110 gajon@remote.com
Next you need to configure your email client to use port 9999
. OpenSSH
will take all traffic on port 9999
in your local machine and send it
encrypted to the remote machine, where the data will continue through port
110
to its original destination.
Notice that the remote machine will send the data to the final destination
using port 110
, AND this data will NOT be encrypted anymore from
that point on. You must be aware of that, if your remote machine and the
destination machine (POP3 server) are the same then it’s OK, otherwise
there’s still a risk.
2.2. From the remote machine to your local machine.
It’s also possible to do a forwarding in the other direction, from the
remote machine to your local machine. An example of when this could be
useful is when you have a machine in your office that sits behind a
firewall that blocks all inbound connections, but permits all outbound
connections, and you want to be able to connect to your office machine
from your home and open an ssh
session.
From the office machine you can establish the tunnel to the home machine:
office:~$ ssh -R 2222:localhost:22 gajon@home
This tunnel will listen on port 2222
of the home machine and will
encrypt data and send it to port 22
of the machine at the office. Once
you are at home you can connect to the office machine from home with
OpenSSH, using this tunnel that you established from the office machine.
home:~$ ssh -p 2222 gajon@office
Notice that we are indicating to ssh
that we want to connect with the
port 2222
(-p
option), this is because that’s the port that your local
machine is listening to.
2.3. Dynamic port forwarding.
Dynamic port forwarding lets you forward any port on your local machine through a secure tunnel to a remote machine, by creating a SOCKS server.
Let’s say that you have a restrictive firewall at the office that blocks web pages that have not been authorized. Imagine you need to find a solution to a programming problem you are having but can’t do that because the firewall is blocking all websites that contain anything similar to a forum, and we all know that forums are where we always find solutions to a technical, undocumented problem.
Well, that has happened to me, and the solution is a SOCKS server that can proxy our data through a remote machine; and have it encrypted as an added bonus!.
You can establish a dynamic port forwarding tunnel as:
mymachine:~$ ssh -D 12345 gajon@remote.com
With that command, you establish a connection to the remote machine, but
OpenSSH will listen to any SOCKS communications on your local machine at
port 12345
.
To be able to use this tunnel, your application that needs to connect must
know how to use the SOCKS protocol (either SOCKS4 or SOCKS5). On Firefox
it’s easy to do that, we go to Preferences and in the Advanced group
select the Network tab, click on the Settings button and select
Manual proxy settings and in the SOCKS Server field put localhost
,
and port 12345
.
And that’s it, when Firefox needs to load a website, it will communicate
with the SOCKS server in your local machine with port 12345
; OpenSSH
will encrypt your data and send it through a secure channel to the remote
machine, where the data will continue its way to its destination and
original port.
But there are many applications that don’t implement a SOCKS protocol, one
example is Opera. There are tools that can wrap a non SOCKS application
and transparently send all its connections through a SOCKS server. One
such application that I have used is tsocks
.
3. Increase the security of your OpenSSH communications.
There are several things you can do to increase the security of your OpenSSH communications, and it’s a good idea to do them.
3.1. Disable root logins.
The most useful and easiest way to increase the security of your OpenSSH
server is to disable root
logins. To do this you must edit the
sshd_config
file in your server.
remote:~# vim /etc/ssh/sshd_config
Search for the PermitRootLogin
attribute and change it to no
. Then
restart your OpenSSH server. On Slackware you use the following line:
remote:~# /etc/rc.d/rc.ssh restart
On a Debian system you use the following line:
remote:~# /etc/init.d/sshd restart
3.2. Change the port where OpenSSH listens.
There are many people with bad intentions that use automated tools that try to breach OpenSSH servers. If you have a server on the Internet, you may have noticed in your logs that there are lots and lots of attempts to login to your server using many different user names. What they are trying to do is to get to one server by applying a so called dictionary attack, that is, attempting a huge combination of common user names and passwords, with the hope that one of those combinations will actually succeed.
A very easy way to stop that is to simply change the port of your OpenSSH
daemon. If the attacker cannot find a server at the default port 22
he
will probably just move to the next server that he can find. These kind of
attackers don’t bother checking every port of the machine, that would take
too much time, instead what they do is try all the ip addresses they can.
To change the port number of your server, edit the sshd_config
file
again and change the Port
attribute. For example:
Port 30234
Restart the OpenSSH daemon, and now to connect you have to specify the
port to use. You can use the -p
switch:
mymachine:~$ ssh -p 30234 gajon@remote.com
But having to type the -p
switch and the port is tedious, so instead of
that you can specify the port in a config
file that your ssh
client
can use. This config
file is usually found in the $HOME/.ssh/
folder.
Open up the $HOME/.ssh/config
file in your editor and put these lines
there:
Host remote.com
Port 30234
Make sure the Port
line below the Host
is indented.
This way you don’t have to specify the port on the command line.
mymachine:~$ ssh gajon@remote.com
You could also add the user name in the config
file:
Host remote.com
User gajon
Port 30234
And then you can just type:
mymachine:~$ ssh remote.com
3.3. Specify which groups can connect.
You can tell OpenSSH that only those users belonging to a certain group
can log in. For example, lets create a group sshers
, and add your user
to that group, you do that with root
. In this example I’ll be adding the
user gajon
to the group.
We have to do this on the remote server, and the first thing to do is create the group:
remote:~# groupadd sshers
Then check what groups the user is already a member of:
remote:~# groups gajon
gajon : users wheel audio video cdrom games
Then make it a member of the sshers
group:
remote:~# usermod -G wheel,audio,video,cdrom,games,sshers gajon
remote:~# groups gajon
gajon : users wheel audio video cdrom games sshers
Notice that the first group listed with groups gajon
is users
, that’s
the primary group of the user, the rest are the secondary groups. You
modify the list of secondary groups with usermod -G
, separating each
group name with a coma. See man usermod
for more details.
OK, now that you have your new group and your user is part of that group,
let’s configure the OpenSSH daemon so that only members of that group can
connect at the remote server. Edit the sshd_config
file in the server:
remote:~# vim /etc/ssh/sshd_config
And add the AllowGroups
property to to file:
# Only members of group sshers will be able to connect
AllowGroups sshers
And that’s it, any user that is not part of the sshers
group will not be
able to log in.
3.4. Use Public-Key Authentication.
It is not a good idea to type the password of your remote user while connecting to the remote machine. The problem is that if someones guesses your password, or looks over your shoulder while you are typing it, or somehow it is compromised, that person that has your password can easily connect to the remote machine from anywhere.
To avoid this danger, you could instead authenticate by setting up a so called “Public-Key Cryptography” authentication.
In Public-Key Cryptography, each party has a pair of keys, one key is known as the “private key” while the other is known as the “public key”. The idea is that when you want to communicate with another party you use their public key and only that who has the corresponding private key can decrypt the message.
This topic of Public-Key Cryptography is quite interesting, if you want to read more you can read the Wikipedia page about it.
The OpenSSH daemon can be configured to authenticate users with a Public-Key Cryptography method. The advantage of this scheme is that you will have your pair of keys, one public and one private, and if someone managed to obtain your user password it won’t matter, because no one will be able to log in to the remote system without the proper private key needed to establish the authentication.
Also, for an attacker to be able to log in into your system, not only he’ll need to get your private key, but also the password you use to decrypt your private key, which is only inside your head.
Let’s create your key pair in your local machine:
mymachine:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/gajon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/gajon/.ssh/id_rsa.
Your public key has been saved in /home/gajon/.ssh/id_rsa.pub.
The key fingerprint is:
fd:6b:f8:82:85:40:e2:8b:1b:31:47:c6:94:25:47:87 gajon@mymachine
Two keys have been generated, one private (id_rsa
), and the other public
(id_rsa.pub
). The password that you entered is used to encrypt your
private key.
Notice that the files were placed in your $HOME/.ssh/
folder in your
computer. Make sure that’s the case, you don’t want them scattered on your
file system.
Next you have to copy your public key to the $HOME/.ssh/authorized_keys
file in the remote server. The authorized_keys
file can contain the
information of several public keys, so to avoid overwriting an existing
authorized_keys
in your remote server, you are going to append the
contents of your public key to the authorized_keys
file. And if that
file did not exist, it will be created anyway.
mymachine:~$ cat .ssh/id_rsa.pub | ssh gajon@remote.com "cat >> .ssh/authorized_keys"
Now to connect to the remote machine using Public-Key Cryptography
authentication, you need to use the -i
switch and specify the
private key to use:
mymachine:~$ ssh -i ~/.ssh/id_rsa gajon@remote.com
Enter passphrase for key '/home/gajon/.ssh/id_rsa':
remote.com:~$
Notice that your ssh
client is asking you for your private key password,
which is NOT the same password for your system user, but the password you
entered when you created this pair of keys.
After you have seen that public key authentication works, it is a good
idea to disable simple password logins on your remote machine, so that the
only way of connecting to it is with the use of Public-Key Cryptography.
To do that you’ll need to set the PasswordAuthentication
property with
the value of no
, in the sshd_config
file.
remote.com:~# vim /etc/ssh/sshd_config
Disable tunnelled clear text passwords:
PasswordAuthentication no
Restart your sshd
daemon, and now you will only be able to log in to the
remote server if the user in the remote server has the public key info in
the .ssh/authorized_keys
file, AND you have the corresponding private
key in your own machine, and of course you know the password to that
private key.
BE VERY CAREFUL, after you make the above change and restart the daemon, do not log out of your session just yet, open up another terminal and try to make a second connection to your remote machine. If you can’t, try to figure it out in the other session that you still have open. I’m telling you this because if you disable password authentication, and the public key authentication fails, you could easily lock yourself out of the remote machine, which would be really bad.
Now, it is annoying having to specify the private key to use with the -i
switch every time you want to connect to the remote machine. So instead of
that, you can configure what private key to use in the $HOME/.ssh/config
file in your local machine.
Retaking the example we saw in section 3.2, you add the IdentityFile
setting which specifies a private key to use when connecting to the host.
Host remote.com
User gajon
IdentityFile ~/.ssh/id_rsa
Port 30234
This way it’s not necessary to specify the private key on the command
line, nor the user or the port (if it were different from the default
22
):
mymachine:~$ ssh remote.com
Enter passphrase for key '/home/gajon/.ssh/id_rsa':
remote.com:~$
A final note; you can name your keys any way you want. If you have more
than one remote machine you should give more meaningful names to your key
pairs, so that you can more easily manage them. For example, if we had
three servers, “breakpoint”, “lucretia” and “she-wolf”, we could
create a $HOME/.ssh/config
file with the following entries:
Host breakpoint
HostName 11.22.33.44
User gajon
IdentityFile ~/.ssh/id_rsa_breakpoint
Port 30234
Host lucretia
HostName lucretia.example.com
User johnny
IdentityFile ~/.ssh/id_rsa_lucretia
Host she-wolf.remote.com
User admin
IdentityFile ~/.ssh/id_rsa_shewolf
Notice that I added another setting, HostName
, which specifies the
actual host to connect to. It could be an IP address or a fully qualified
name of the server. That way the Host
setting is actually an alias that
you can freely define. With that example we can easily connect to the
“breakpoint” server, with an IP address of 11.22.33.44
.
mymachine:~$ ssh breakpoint
And that’s all for now.
I hope these tips are useful to you, but remember that we have just seen a few uses of OpenSSH, and that there are a lot more. For example, in a next article I’ll write how to use Public-Key authentication to easily issue commands to remote servers and automate tasks.