The iptables software is a user space application for configuring packet filtering in the Linux kernel. iptables is used to set rules for packets that travel through a host’s network stack and at certain points, called hooks, the iptables rules are evaluated and actions, such as dropping a packet, can be executed. In this post I will draft a script to setup the iptables’ rules for a firewall and then set that script to be executed at boot time.Read More
Using Public Key Cryptography and SSH Tools for Smooth Log In
To log in to an SSH server without the needing to enter a password each time can be done in different ways. One way is to to configure your server to allow certain users (or certain users from certain hosts/networks/ip addresses [or ranges]) but another preferred method I am going to demonstrate involves encryption keys and the Diffi-Helmen Key Exchange.
(See also PKI)
Primarily one needs an encryption key to verify his or her identity. There are different algorithms that exist by which a key can be created (I won’t go into them here), but a popular and often recommended one is the RSA algorithm which I will use in my example.
On a POSIX (Unix/Unix Like) system with an SSH server in a typical configuration, this is the process to create an rsa encryption key:
> ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_rsa. Your public key has been saved in /home/user/.ssh/id_rsa.pub. The key fingerprint is: a9:9d:f8:df:63:64:68:11:00:13:f1:bb:2d:76:5d:5b user@gnu-linux
Once our key has been created (client side), we need to copy our public key into the proper directory on the SSH server. DO NOT DISTRIBUTE YOUR PRIVATE KEY, KEEP IT SAFE! When performing public key authentication, by default the server checks in the users home directory (
$HOME) for a directory named ‘.ssh’. Inside that directory the server is looking for a file named ‘authorized_keys’. This file is where we place a copy of our public key, on a single new line.
The public key can be distributed automatically with the
> ssh-copy-id Usage: /usr/bin/ssh-copy-id [-h|-?|-n] [-i [identity_file]] [-p port] [[-o
] ...] [user@]hostname > > ssh-copy-id firstname.lastname@example.org
To do it manually:
---In the home directory on the client machine--- > cat .ssh/id_rsa.pub > pubkey > scp pubkey email@example.com: ---output omitted--- > ssh firstname.lastname@example.org ---output omitted--- ---On server in home directory--- > cat pubkey >> .ssh/authorized_keys > exit
Okay. This takes care of half of the puzzle. This will allow our server to use our rsa key to verify our identity, but (assuming a passphrase was entered when prompted above) we will still need to enter the passphrase for this key each time we attempt to log into the server. What we can do to get around this is utilize the
ssh-agent which is part of the SSH client.
Our key can be added to the ssh-agent one time and future requests for access to SSH servers will be handled by the agent. When our rsa key was created, we opted to store it in the default location. The ssh-agent will likewise by default look in the default storage location for our encryption keys. So all one needs to do to load their key into the ssh-agent is issue the
ssh-add command – Windows users can setup a profile in Putty to accomplish the same result.
> ssh-add Enter passphrase for /home/user/.ssh/id_rsa: Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)
Now with our key loaded into the ssh-agent, we can access any SSH server where our public key is authorized without needing to enter our passphrase.
Upon connecting to an OpenSSH server, the server sends its public key to the
client so that the user on the client side can verify that the server they
are trying to connect to is indeed the server they expect it to be (and not an
attacker spoofing the desired SSH server). Once initially verified, the server’s
key is then stored in the
$HOME/.ssh/known_hosts file. Proper use
of this system mitigates SSH Spoofing attacks, but by default it also
presents a data leak that could be utilized by someone who has cracked your system.
When securing a system, we would like to believe our efforts will thwart any
any such attempts at penetration; but any good security plan should consider how
to minimize damage in the event that an intruder does gain access. By default
the keys in
known_hosts are referenced in plain text:
$ cat $HOME/known_hosts $ magellanic.zapto.org,18.104.22.168 ssh-rsa AAAAB3NzaC1yz2EAAAADAQABAAABAQC/TLO38IPrLW18kgKx4BQmPGmOXaIKRyTGTFtOT4tCph9ORyb7Mh0SlIe1bowqOFcNI6LUNcrloiTFd9wvAljTHriZJASEOy6uCBf1cKcwX/TpjtiA2uJ7mzosmeoB0PFAxCmKvb2xGXGIsjFOHYWSOitKqxj9r9JUAAURgzb5teml9/bcsMz05qZtkS4EmvYAFXXSaqLNiT+Q3UCjj2GD3mSGqyuy4ad+pEENXNf10D/hMxQBiedH4jNhUJSqTCtJtfVf7532OP7qvQ4PISbh3itEmrFBelkDxlC+3mxFFOzk/SyYWf16Roc9xsnR5HK7mGYG4N4YcxYaioCV1Nd9
The problem here is that if an attacker found a vulnerability in your security
and gained access to a single machine, all they would need to do is run the above
command and they would have a list of hosts on the network that possibly have
the same vulerability. This is a type of an Island Hopping attack, in
which an attacker gains access to a ‘weak link’ in the network and then ‘hops’
around from system to system. We can prevent this type of attack by hashing the
hostnames in our
Hashing will take our human readable hostname (and ip address) and transform
it into something like
Which is virtually useless to an attacker, but OpenSSH will have no problem
utilizing. To configure our server to hash hostnames automatically, set the
following directive in
To hash existing entries in your
This command will copy your
$HOME/.ssh/known_hosts file to
$HOME/known_hosts.old with all the plain text hostnames and replace
known_host file with hashed hostnames. It would be wise to verify
this replacement file will allow you to connect to remote hosts before removing
To defend against SSH server spoofing – where an attacker sets up an SSH server and masquerades as another in order to capture users’ login credentials – every SSH server has a unique public key that can be utilized to verify that servers identity. This key is located in the
/etc/ssh/ directory, and is used by clients to encrypt communications with the server. In turn, the server must use its private key to decrypt these communications.
The key is a rather long string of random characters and not very useful for humans, but a fingerprint of the key can be produced which is more compatible with the operating system of the mind. The first time an SSH client connects to an SSH server, this fingerprint is displayed.
The authenticity of host 'host.example.org (22.214.171.124)' can't be established. ECDSA key fingerprint is 03:ed:6d:1f:ff:56:9d:5f:f3:65:20:b5:ad:55:55:87. Are you sure you want to continue connecting (yes/no)?
This prompt is asking the user to verify the offered fingerprint (the fingerprint of the server) against a known good fingerprint under their control. But how is this done? At the time the SSH server is installed and the public/private key pairs are generated, the SSH server administrator can fingerprint the server and distribute this fingerprint to users who will access the server. One can do such fingerprinting with the
ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub 256 03:ed:6d:1f:ff:56:9d:5f:f3:65:20:b5:ad:55:55:87 host (ECDSA)
-l option instructs the program to show the fingerprint, and
f for a key file. Simply direct the output the above command to a file and distribute that file to users who will be connecting to the server.
ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub > server_fingerprint.txt
To get a look at the server’s public key fingerprint before attempting a connection, one can utilize the
ssh-keyscan -t ecdsa host.example.org > tmp ssh-keygen -lf tmp 256 03:ed:6d:1f:ff:56:9d:5f:f3:65:20:b5:ad:55:55:87 host.example.org (ECDSA)
-t is for type of key to be scanned (which can be rsa1 for protocol version 1, dsa, ecdsa, ed25519, or rsa for protocol version 2). The output is redirected to a temporary file named
tmp, then the file is checked with the
Once client has verified the fingerprint, it will store a copy of the server’s public key in
$HOME/.ssh/known_hosts and will check the stored key on subsequent connections to that host. If the server has changed its keys, or another machine is attempting to spoof the real server, the client will notice and will not allow connections to that host.