Tweets by @markusgattol |
The best order in which this page should be consumed/read is probably starting with the Overview section from below, followed by the Best Practices section which contains information about a basic SSH setup. The Best Practices section also contains information on the very important subject of PKA (Public Key Authentication) with SSH. After those, the reader might probably want to take a look at some of the more advanced SSH topics like for example multi-user ssh setup and last but not least, some nice to know bits and pieces on SSH. OverviewThis section is in place in order to provide some background information on SSH itself. HistoryWikipedia has an excellent article about SSH's history already. SSH Use CasesThis subsection lists some of the most common use cases for SSH:
TheoryGo here. OpenSSHThe OpenSSH suite includes the following tools:
Single User SSH SetupThis is when we set up an SSH environment without any central management instance which takes care of user management, access control, user credentials and things like that. Most people use this kind of setup which is perfectly fine for a single person or a small group of humans and a small group of remote machines which are entered via SSH. However, once the number of humans and/or machines exceeds a number of 3 or so, a single user setup does not scale anymore in which case a multi-user SSH setup should be used (this becomes even more true if the SSH environment is very dynamic in its nature i.e. users, account data, machines, access control, etc. changes very frequently). One remote Machine at a TimeThis is the most common use case of SSH — there is one SSH session established having single ends on both sides, the one originating at our local machine and the other one ending on the remote machine. Note that there can be of course several SSH sessions at a time in parallel. However, each one has just two ends. Whether we use a basic SSH setup using a user's password to authenticate ourselves or PKA (Public Key Authentication) is irrelevant. Server-Side ConfigurationFor this type of setup there is basically just one file
( Client Side ConfigurationOn the client side there are basically just three things we need to take care of:
I make heavy use of ~/.ssh/config and ssh-copy-id as can be seen further down. Two or more remote Machines at a TimeThis is what we are confronted with in case we (a single person actually) want/need to carry out the same action on several remote machines. Sure, we could log into remote machine 1, carry out the work, log out, log into remote machine 2, carry out the exact same work there, log out, log into remote machine 3, carry out the exact same... Clearly, in order to, for example, run The most commonly used tools to accomplish such thing are sa@wks:~$ type acs; acs ssh | egrep pssh\|clusterssh\|dsh acs is aliased to `apt-cache search' clusterssh - administer multiple ssh or rsh shells simultaneously dsh - dancer's shell, or distributed shell pssh - Parallel versions of SSH-based tools sa@wks:~$ I am very fond of ClusterSSH not just because it is probably the most capable tool, but especially because it allows for all the little things that, at the end of the day, make a difference. For example, it honors my ClusterSSHAfter installing Another configuration file which I use a lot is It contains a list of tag to server mappings. When any name is used on the command line it is checked to see if it is a known tag name. If it is, then the tag is replaced with the list of servers following this particular tag. The beauty of all of this is that it allows us to make the fine
grained specification of remote machines in 1 sa@wks:~$ cat /etc/clusters 2 all_my_testing_hosts testing testing_sec 3 sa@wks:~$ grep -A3 testing .ssh/config 4 # description: wks-ve2; testing 5 Host testing 6 HostName 192.168.1.101 7 Port 18689 8 User sa 9 -- 10 # description: wks-ve5; testing_sec 11 Host testing_sec 12 HostName 192.168.1.104 13 Port 18689 14 User sa 15 sa@wks:~$ cssh all_my_testing_hosts & 16 sa@wks:~$ tsw 17 18 19 [here the screenshot has been taken ...] 20 21 22 sa@wks:~$ testing session closed 23 testing_sec session closed 24 sa@wks:~$ Line 2 shows the contents of Those who are confused about the private IP addresses i.e. Also, I am only using two remote machines here to demonstrate things but then again, a real-world scenario could go in the thousands (I myself have used it for around 800 remote machines once were it worked perfectly fine). Anyway, in line 15 we use ClusterSSH with our current setup. I took a screenshot in line 16 which can be seen below. Note that for After issuing a few commands (on all remote machines simultaneously, using the little input window which can be seen in the middle) we exit this ClusterSSH session again which is shown by lines 22 and 23. If we ever run into timeout issues like Last but not least, I have a nice hint for GNU Emacs fans with regards to ClusterSSH... there is actually a ClusterSSH mode for GNU Emacs ;-] Multi-User SSH SetupIf we need/want to have a central management instance for all SSH related actions regarding one or more users then we are speaking of a multi-user SSH setup. Above I have already pointed out when such setup is a good idea respectively becomes mandatory. SSH Proxy
However, at the time I was evaluating a multi-user SSH setup, Monkeysphere was the more appropriate choice so I actually never took a deeper look at SSH proxy. MonkeysphereIn order to understand this subsection, knowledge about PKA (Public Key Authentication) is a mandatory prerequisite — I would advice the reader to read about PKA before proceeding and afterwards come back here.
What is Monkeysphere?Many people ask a certain question at first which is why I decided to answer it right away: No modifications to the OpenSSH software are required to use Monkeysphere. OpenSSH can be used as is — completely unpatched and out of the box. What does Monkeysphere do? Why do we need it? Well, let me answer this question with a counterquestion: What is the best procedure to establish trust with our PKA infrastructure? Especially, how can we be sure to trust SSH host keys? At the core of the problem/issue which can be eased with Monkeysphere-the-Software is the subject of trust, and the fact that humans have their Monkeysphere. There are certain approaches to this problem which more or less get the job done like for example, putting a remote machine's host key fingerprint online so we can validate it with the fingerprint that SSH shows us when we connect to this remote machine for the first time. sa@wks:~$ ssh sub The authenticity of host 'sub (192.168.1.3)' can't be established. RSA key fingerprint is ed:d3:29:bd:4d:e2:7d:a3:b0:15:96:26:d4:60:1e:22. Are you sure you want to continue connecting (yes/no)? no sa@wks:~$ Or, we could use Whatever we do, it certainly gets overly complex really soon plus most of those methods do not scale well and are way to inflexible in our dynamic environments as we have them nowadays. Monkeysphere provides a solution to all of the afore mentioned issues i.e. it provides us with a flexible and scalable framework to establish trust in both directions — from users to remote machines and vice versa. The Monkeysphere project's goal is to extend OpenPGP's web of trust to new areas of the Internet to help us securely identify each other while we work on-line. Specifically, Monkeysphere-the-Software currently offers a framework to leverage the OpenPGP web of trust for OpenSSH authentication, both ways — for users to verify the authenticity of the remote hosts they connect to and also, remote machines can verify the authenticity of its users. In other words, it allows us to use SSH as we normally do, but also to identify ourselves and the remote machines we administer or connect to with our OpenPGP keys. OpenPGP keys are tracked via GPG (GNU Privacy Guard), and Monkeysphere
manages the How does it work?Everyone who has used SSH before is familiar with the prompt given the first time we log into a new server, asking if we want to trust the remote machine's key by verifying the key fingerprint (see above). Unfortunately, unless we have access to the remote machine's key fingerprint through a secure out-of-band channel (e.g. the one used for remote management), there is no way to verify that the fingerprint we are presented with is in fact that of the remote machine we are really trying to connect to. Most of us also take advantage of PKA (Public Key Authentication) with OpenSSH's, rather than on relying on the exchange of a user account password. However, the public part of the key needs to be transmitted to the server through a secure out-of-band channel (usually via a separate password-based SSH connection or a (hopefully GPG (GNU Privacy Guard) signed) email to the system administrator) in order for this type of authentication to work. OpenSSH currently provides a functional way to manage the RSA and DSA keys required for these interactions through the ~/.ssh/known_hosts and ~/.ssh/authorized_keys files. However, it lacks any type of PKI (Public Key Infrastructure) that can verify that the keys being used really are the one required or expected. The basic idea of the Monkeysphere is to create a framework that uses GnuPG's capabilities and public keyserver communication to manage the keys that OpenSSH uses for authentication. The Monkeysphere provides an effective PKI for OpenSSH, including the possibility for key transition, transitive identification of keys, key revocation, and key expiration — it actively invites broader participation in the OpenPGP web of trust. With Monkeysphere, both parties to an OpenSSH connection (client and remote machine/server) explicitly designate who they trust to certify the identity of the other party.
These trust designations are explicitly indicated with traditional GPG
keyring trust models. Monkeysphere then manages the keys in the
No modification is made to the SSH protocol on the wire (it continues to be PKA i.e. use raw RSA public keys), and no modification is needed to the OpenSSH software itself. Benefits in a NutshellFor the user who connects to some remote machine using SSH
For the administrator of some remote machine
All of these added benefits are related to the additional notion of an PKI (Public Key Infrastructure) that Monkeysphere brings to SSH. A PKI at its core is a mechanism to provide answers to a few basic questions:
Given a clearly stated set of initial assumptions, functional cryptographic tools, and a PKI, these questions can be clearly answered in an automated fashion. We should not need to ask humans to do complicated, error-prone things like for example checking host key fingerprints — Monkeysphere can do this for us in a manner that is a lot faster, a lot more comfortable, a lot more secure as well as a lot more flexible and scalable. Remote Machine Setup / Host VerificationThis is about setting up and/or running a remote machine with Monkeysphere. In case the reader is just a user to some remote machine running Monkeysphere then here is what to do. As the administrator of some computer/gadget providing access via SSH, we can take advantage of Monkeysphere in two ways — these two are independent i.e. we can do one without the other:
PreparationsAt the very beginning each person about to setup Monkeysphere on a
remote machine is of course a user to Monkeysphere at this point as
well — this is optional but I recommend to make a little addition to
Ok, now we can really start setting up Monkeysphere on a remote machine... 1 sa@wks:~$ whoami 2 sa 3 sa@wks:~$ pwd 4 /home/sa 5 sa@wks:~$ hostname 6 wks 7 sa@wks:~$ ssh testing_sec 8 9 10 [skipping a lot of lines...] 11 12 13 sa@wks-ve5:~$ whoami 14 sa 15 sa@wks-ve5:~$ pwd 16 /home/sa 17 sa@wks-ve5:~$ hostname 18 wks-ve5 19 sa@wks-ve5:~$ su 20 Password: 21 wks-ve5:/home/sa# whoami 22 root 23 wks-ve5:/home/sa# dpl monkeysp* | grep ii 24 ii monkeysphere 0.24-1 use the OpenPGP web of trust to verify ssh connections Just a bit orientation in lines 1 to 24 — we started locally at my
workstation, then entered a remote machine (actually an OpenVZ VE
(Virtual Environment) running locally on my workstation) via SSH. The
remote machine What we need to do is to install the 25 wks-ve5:/home/sa# cd /etc/ssh/; type pi; pi ssh_host 26 pi is aliased to `ls -la | grep' 27 -rw------- 1 root root 668 2009-03-08 18:07 ssh_host_dsa_key 28 -rw-r--r-- 1 root root 602 2009-03-08 18:07 ssh_host_dsa_key.pub 29 -rw------- 1 root root 6363 2009-03-08 18:09 ssh_host_rsa_key 30 -rw-r--r-- 1 root root 1418 2009-03-08 18:09 ssh_host_rsa_key.pub 31 wks-ve5:/etc/ssh# dpl openssh-server | grep ii 32 ii openssh-server 1:5.1p1-5 secure shell server, an rshd replacement 33 wks-ve5:/etc/ssh# netstat -tulpe | grep ssh 34 tcp 0 0 *:18689 *:* LISTEN root 29916 300/sshd 35 tcp6 0 0 [::]:18689 [::]:* LISTEN root 29918 300/sshd As I mentioned above, we need to have a fully functional PKA setup in
place which includes the RSA host keys (lines 29 and 30), and a
running and well configured Where we start with Monkeysphere is right on top of a functioning PKA setup as I will now demonstrate below. Create and Publish an OpenPGP Certificate for a remote Machine36 wks-ve5:/etc/ssh# la /var/lib/monkeysphere/ 37 total 4 38 drwxr-xr-x 4 root root 49 2009-03-18 19:49 . 39 drwxr-xr-x 21 root root 4096 2009-03-18 19:49 .. 40 drwxr-x--- 5 root monkeysphere 40 2009-03-18 19:49 authentication 41 drwxr-xr-x 2 root root 6 2009-03-18 19:49 authorized_keys 42 wks-ve5:/var/lib/monkeysphere# monkeysphere-host import-key /etc/ssh/ssh_host_rsa_key foo.bar.com:18689 43 ms: host key imported: 44 pub 8192R/E00C6FA8 2009-03-22 45 Key fingerprint = 10A8 068F D530 ACBC 1392 1A05 027E 3BCD E00C 6FA8 46 uid ssh://foo.bar.com:18689 47 48 OpenPGP fingerprint: 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 49 ssh fingerprint: 8192 12:48:df:ad:b3:89:8c:d0:c8:09:49:8d:e6:b8:69:29 (RSA) 50 wks-ve5:/etc/ssh# la /var/lib/monkeysphere/ 51 total 8 52 drwxr-xr-x 5 root root 91 2009-03-22 20:29 . 53 drwxr-xr-x 21 root root 4096 2009-03-18 19:49 .. 54 drwxr-x--- 5 root monkeysphere 40 2009-03-18 19:49 authentication 55 drwxr-xr-x 2 root root 6 2009-03-18 19:49 authorized_keys 56 drwx------ 2 root root 79 2009-03-22 20:29 host 57 -rw-r--r-- 1 root root 3010 2009-03-22 20:29 ssh_host_rsa_key.pub.gpg We can see that after issuing line 42 in order to import the remote
machines host key, all that information ends up in
As mentioned earlier, having a pair of SSH host keys in place is a
prerequisite — those can also be created pretty easily. With the
command from line 42 we use the RSA private key in order to create the
OpenPGP certificate for the remote machine Also, we specify a FQDN (Fully Qualified Domain Name) and As we will see later, we can change the primary UID using
I already mentioned it above, installing and setting up Monkeysphere
does not require any changes to some running SSH setup except for a
one-line change to
Monkeysphere is after all just the cherry on top of SSH —
it is
possible to use standard PKA and Monkeysphere in parallel because,
as of now (March 2009), by default, Of course, we can turn that off if we do not want to allow PKA authentication in addition to Monkeysphere-style authentication. 58 wks-ve5:/etc/ssh# monkeysphere-host show-key 59 pub 8192R/E00C6FA8 2009-03-22 60 Key fingerprint = 10A8 068F D530 ACBC 1392 1A05 027E 3BCD E00C 6FA8 61 uid ssh://foo.bar.com:18689 62 63 OpenPGP fingerprint: 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 64 ssh fingerprint: 8192 12:48:df:ad:b3:89:8c:d0:c8:09:49:8d:e6:b8:69:29 (RSA) 65 wks-ve5:/etc/ssh# monkeysphere-host show-key | awk '/^OpenPGP fingerprint: /{print $3}' 66 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 67 wks-ve5:/etc/ssh# gpg --search --keyserver hkp://keys.gnupg.net 0x$(monkeysphere-host show-key | awk '/^OpenPGP fingerprint: /{print $3}') 68 gpg: searching for "10A8068FD530ACBC13921A05027E3BCDE00C6FA8" from hkp server keys.gnupg.net 69 gpg: key "10A8068FD530ACBC13921A05027E3BCDE00C6FA8" not found on keyserver 70 wks-ve5:/etc/ssh# monkeysphere-host publish-key 71 Really publish host key to pool.sks-keyservers.net? (Y/n) Y 72 gpg: sending key E00C6FA8 to hkp server pool.sks-keyservers.net With line 58 we take a look at the certificate we just created with line 42. I always opt to use the key ID instead of some UID on the key simply because the key ID is for sure unique. With line 65 we can see the command which can be used to get the key ID/fingerprint. As with the examples in the GPG (GNU Privacy Guard) section, we use such command to supply another one with a unique key ID as can be seen in line 67. Also notable about line 67 is the use of Anyway, the reason for line 67 is that I wanted to show there is no
key with key ID Note that it might take several minutes until the key/certificate has
been distributed across the entire key server network. Also note, that
all actions so far were carried out on our remote machine 73 wks-ve5:/etc/ssh# exit 74 exit 75 sa@wks-ve5:~$ exit 76 logout 77 Connection to 192.168.1.104 closed. 78 sa@wks:~$ gpg --search 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 79 gpg: searching for "10A8068FD530ACBC13921A05027E3BCDE00C6FA8" from hkp server keys.gnupg.net 80 gpg: key "10A8068FD530ACBC13921A05027E3BCDE00C6FA8" not found on keyserver 81 sa@wks:~$ gpg --search 0x10A8068FD530ACBC13921A05027E3BCDE00C6FA8 82 gpg: searching for "0x10A8068FD530ACBC13921A05027E3BCDE00C6FA8" from hkp server keys.gnupg.net 83 (1) ssh://foo.bar.com:18689 84 8192 bit RSA key E00C6FA8, created: 2009-03-22 85 Keys 1-1 of 1 for "0x10A8068FD530ACBC13921A05027E3BCDE00C6FA8". Enter number(s), N)ext, or Q)uit > 1 86 gpg: requesting key E00C6FA8 from hkp server keys.gnupg.net 87 gpg: key B58220DB: public key "ssh://foo.bar.com:18689" imported 88 gpg: Total number processed: 1 89 gpg: imported: 1 (RSA: 1) 90 sa@wks:~$ gpg --fingerprint foo.bar.com:18689 91 pub 8192R/E00C6FA8 2009-03-22 92 Key fingerprint = 10A8 068F D530 ACBC 1392 1A05 027E 3BCD E00C 6FA8 93 uid ssh://foo.bar.com:18689 94 Starting with line 73, we go back where we came from i.e. we leave the
remote machine and end up on my workstation in line 78. If we now
search for the former created and uploaded OpenPGP certificate for the
remote machine We choose to import the key/certificate into our local GPG keyring because we are going to sign it now. One important thing is to make sure to compare the key ID (also known
as fingerprint) of the retrieved certificate/key (e.g. line 92) with
the output from Sign the published Certificate95 sa@wks:~$ gpg --sign-key foo.bar.com:18689 96 97 pub 8192R/E00C6FA8 created: 2009-03-22 expires: never usage: CA 98 trust: unknown validity: unknown 99 [unknown] (1). ssh://foo.bar.com:18689 100 101 102 pub 8192R/E00C6FA8 created: 2009-03-22 expires: never usage: CA 103 trust: unknown validity: unknown 104 Primary key fingerprint: 10A8 068F D530 ACBC 1392 1A05 027E 3BCD E00C 6FA8 105 106 ssh://foo.bar.com:18689 107 108 Are you sure that you want to sign this key with your 109 key "Markus Gattol () <markus.gattol[at]foo.org>" (C0EC7E38) 110 111 Really sign? (y/N) y 112 113 You need a passphrase to unlock the secret key for 114 user: "Markus Gattol () <markus.gattol[at]foo.org>" 115 1024-bit DSA key, ID C0EC7E38, created 2009-02-06 116 117 118 sa@wks:~$ gpg --list-sig foo 119 pub 8192R/E00C6FA8 2009-03-22 120 uid ssh://foo.bar.com:18689 121 sig 3 E00C6FA8 2009-03-22 ssh://foo.bar.com:18689 122 sig C0EC7E38 2009-03-22 Markus Gattol () <markus.gattol[at]foo.org> 123 124 sa@wks:~$ gpg --send-key 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 125 gpg: sending key E00C6FA8 to hkp server keys.gnupg.net 126 sa@wks:~$ Nothing special in lines 95 to 117, just signing the host key/certificate for our remote machine. The result can be seen in line 122. After we are done, we publish the key/certificate into the WOT in line 124 and 125.
Now I know for sure, the just published key/certificate with the
key/certificate ID I know because it was me who set up the remote machine, also, I used
my own OpenPGP key with the key ID
Can the reader be sure to trust this key/certificate as well? Well,
there is a problem! Anyone could publish a simple self-signed
certificate to the WOT with any UID (e.g. Actually, that is what we should expect — as time goes by, any domain will probably have a dozen keys/certificates in the WOT simply because some idiots are going to create those and use our UID for those certificates as well. However, users to a monkeysphere-enabled remote machine are able to tell the difference between the right key/certificate and all the fakes ones by looking at the signatures. For example, if In reality though a user would not know about the validity of the host key/certificate as I just pointed it out i.e. with the key IDs above. In reality the validity for a key/certificate comes from the WOT because there will be host keys/certificates signed by folks the user does not know in person and thus he has to relying on the validity of this particular key/certificate. This is what Monkeysphere is/does... more on that below... Thoughts on signing the Host Key/CertificateThis subsection is meant to address the issue of signing OpenPGP-based SSH host keys/certificates. Computers are not people, so the circumstances under which we should sign a remote machines host key/certificate are different from those under which we should sign another person's public key. Why are signatures on an SSH host key/certificate important?In order for users to validate a host (also known as remote machine
respectively If the user has not signed the remote machine's key himself, then the remote machine's key can only be valid if other people that the user trusts have signed the key/certificate — standard WOT (Web of Trust) behavior that is... If only one person has signed the remote machine's key, then the user must fully trust this single person who has signed the host key/certificate. Full trust should be granted sparingly and with consideration — unless the users knows the server admin very well, they will in general not have full trust of this person. However, full trust of the host key/certificate can also be achieved if the remote machine's key has been signed by three or more people that the user has marginal trust of. In other words, three or more marginally trusted signatures equals one fully trusted signature — this however depends on the chosen trust model. It is much more common for users to have marginal trust of other users in the WOT than having full trust. For this reason, it is advisable to have as many people sign the remote machine's key/certificate as possible. What information we should have before signing a host key/certificate?Before signing the key of a person, we want to do two things:
For a server, we want to do basically the same thing:
However, verifying these things for a server is less intuitive than it is for a human. For example, what exactly does it means to verify the identity of a remote server on the Internet? The identity in this case is the FQDN (Fully Qualified Domain Name) of
the remote machine e.g. Verifying that a remote machine is in control of the key/certificate is, straightforward. If we manage to log into the remote machine in question, then that key/certificate exists on the remote machine. Further down I am going to show how we can do both, #1 and #2 in one shoot... If we are the person (or persons) that actually setup the remote machine from scratch and configured Monkeysphere and SSH on it, then we should sign the host key/certificate as part of that process. When the remote machine is first set up, the administrator(s) who set it up are the only ones who can actually vouch for the server key, so their signatures are necessary to get things going. Remember, that is exactly what I was taking about above... Their signatures are also necessary so that they can validate the host key themselves and log into the server via the monkeysphere-enabled SSH setup in the future. If we did not set up the server initially, we do not have an accumulated full trust of the person(s) who did, and we do not necessarily have console access to the server directly, it is hard to confidently verify the server identity and key ownership. We would like to be able to walk up to the server, log in at the console, and get the key ID (fingerprint) of the SSH host key/certificate directly — exactly that is usually impossible. However, it is still possible to verify the server identity and server ownership of the key, even in this case. 95 sa@wks:~$ gethostip foo.bar.com 96 foo.bar.com 64.34.161.100 4022A164 97 sa@wks:~$ grep foo /etc/hosts 98 sa@wks:~$ su 99 Password: 100 wks:/home/sa# echo "192.168.1.104 foo.bar.com" >> /etc/hosts 101 wks:/home/sa# exit 102 exit 103 sa@wks:~$ grep foo /etc/hosts 104 192.168.1.104 foo.bar.com 105 sa@wks:~$ gethostip foo.bar.com 106 foo.bar.com 192.168.1.104 C0A80168 Before we start verifying #1 and #2 from above we have to pull a
little stunt — I am doing this demonstration locally on my
workstation using an OpenVZ VE (Virtual Environment) for the remote
machine Because of that, we need to reroute queries that go to Line 96 shows the result when resolving the URL 107 sa@wks:~$ ssh-keygen -l -F [foo.bar.com]:18689 108 sa@wks:~$ grep -{A,B}2 foo.bar.com .ssh/config 109 # description: wks-ve5; testing_sec 110 Host testing_sec 111 HostName foo.bar.com 112 Port 18689 113 IdentityFile %d/.ssh/ssh_pka_key_wks-ve5 114 sa@wks:~$ export MONKEYSPHERE_LOG_LEVEL=DEBUG; ssh testing_sec 115 ms: checking path permission '/home/sa/.ssh/known_hosts'... 116 ms: checking path permission '/home/sa/.ssh'... 117 ms: checking path permission '/home/sa'... 118 ms: checking path permission '/home'... 119 ms: checking path permission '/'... 120 ms: path ok. 121 ms: lock created on '/home/sa/.ssh/known_hosts'. 122 ms: processing: foo.bar.com:18689 123 ms: primary key found: 027E3BCDE00C6FA8 124 ms: * acceptable primary key. 125 ms: * new key for foo.bar.com:18689 added to known_hosts file. 126 ms: lock touched on '/home/sa/.ssh/known_hosts'. 127 ms: lock removed on '/home/sa/.ssh/known_hosts'. 128 ms: known_hosts file updated. 129 130 131 [skipping a lot of lines...] 132 133 134 sa@wks-ve5:~$ whoami 135 sa 136 sa@wks-ve5:~$ pwd 137 /home/sa 138 sa@wks-ve5:~$ hostname 139 wks-ve5 140 sa@wks-ve5:~$ exit 141 logout 142 Connection to foo.bar.com closed. 143 sa@wks:~$ ssh-keygen -l -F [foo.bar.com]:18689 144 # Host [foo.bar.com]:18689 found: line 2 type RSA 145 8192 12:48:df:ad:b3:89:8c:d0:c8:09:49:8d:e6:b8:69:29 |1|FLHGJ1t+9RROV+ne/1SAjFBS4Ro=|LvzUJPJP8s1xjIsue1cl2CIdfU0= (RSA) In line 107 we take a look whether or not our Line 114 is interesting — I increased the log level so we have a more
verbose output when we try to establish contact to Lines 122 to 125 is where we verify #1 and #2 from above —
Monkeysphere finds the host key/certificate
The new key/certificate is then automatically added to our ~/.ssh/known_hosts file as we see in line 125 and as line 144 and 145 proof it. Note that the key ID from line 145 is of course the one from the remote machine's host keypair (from the public key to be more precise). It is also interesting to note that, although we connected to How to Revoke a Certificate for a remote MachineThis is important because we could eventually loose the private key used to sign the remote machine's OpenPGP key/certificate. Loosing here actually means stolen (someone else gets a hold of it; hopefully the original key owner was smart enough to protect the private key with a password) or a hardware failure could also cause loosing it. There are basically two subcommands to
146 sa@wks:~$ ssh testing_sec 147 148 / \ _-' 149 _/ \-''- _ / 150 __-' { \ 151 / \ 152 / "o. |o } 153 | \ ; YOU ARE BEING WATCHED! 154 ', 155 \_ __\ 156 ''-_ \./ 157 / '-____' 158 / 159 _' 160 _-' 161 162 163 This computer system is the private property of its owner, whether individual, corporate or government. It is 164 for authorized use only. Users (authorized or unauthorized) have no explicit or implicit expectation of 165 privacy. 166 167 Any or all uses of this system and all files on this system may be intercepted, monitored, recorded, copied, 168 audited, inspected, and disclosed to your employer, to authorized site, government, and law enforcement 169 personnel, as well as authorized officials of government agencies, both domestic and foreign. 170 171 By using this system, the user consents to such interception, monitoring, recording, copying, auditing, 172 inspection, and disclosure at the discretion of such personnel or officials. 173 174 175 UNAUTHORIZED OR IMPROPER USE OF THIS SYSTEM MAY RESULT 176 IN CIVIL AND CRIMINAL PENALTIES AND ADMINISTRATIVE OR 177 DISCIPLINARY ACTION, AS APPROPRIATE !! 178 179 180 By continuing to use this system you indicate your awareness of and consent to these terms and conditions of 181 use. LOG OFF IMMEDIATELY if you do not agree to the conditions stated in this warning. However, if you are 182 authorized personal with no bad intentions please continue. Have a nice day! :-) 183 184 sa@wks-ve5:~$ su 185 Password: 186 wks-ve5:/home/sa# export MONKEYSPHERE_DEBUG_LEVEL=DEBUG; monkeysphere-host add-revoker F6F78566432A78A90D39CDAE48E94AC6C0EC7E38 187 gpg: requesting key C0EC7E38 from hkp server pool.sks-keyservers.net 188 ms: key found: 189 pub 1024D/C0EC7E38 2009-02-06 190 Key fingerprint = F6F7 8566 432A 78A9 0D39 CDAE 48E9 4AC6 C0EC 7E38 191 uid Markus Gattol () <[email protected]> 192 uid Markus Gattol () <markus.gattol[at]foo.org> 193 sub 4096g/34233DEF 2009-02-06 194 195 Are you sure you want to add the above key as a revoker 196 of the host key? (Y/n) Y 197 ms: Revoker added. 198 wks-ve5:/home/sa# monkeysphere-host show-key 199 pub 8192R/E00C6FA8 2009-03-22 200 Key fingerprint = 10A8 068F D530 ACBC 1392 1A05 027E 3BCD E00C 6FA8 201 uid ssh://foo.bar.com:18689 202 203 The following keys are allowed to revoke this host key: 204 revoker: F6F78566432A78A90D39CDAE48E94AC6C0EC7E38 205 206 OpenPGP fingerprint: 10A8068FD530ACBC13921A05027E3BCDE00C6FA8 207 ssh fingerprint: 8192 12:48:df:ad:b3:89:8c:d0:c8:09:49:8d:e6:b8:69:29 (RSA) 208 wks-ve5:/home/sa# monkeysphere-host publish-key 209 Really publish host key to pool.sks-keyservers.net? (Y/n) Y 210 gpg: sending key E00C6FA8 to hkp server pool.sks-keyservers.net 211 wks-ve5:/home/sa# exit 212 exit 213 sa@wks-ve5:~$ exit 214 logout 215 Connection to foo.bar.com closed. In line 146 we issue our well-known command in order to enter After we became Increasing the log level in line 186 has only been done in order to make the following commands more verbose — usually, of course, increasing the log level is no necessity. Line 208 is interesting, not from a technical point of view but actually the motivation why we publish the host key/certificate again. We do so to make the just added revoker information public. Now, usually that is what we want. However, there might be cases when this might not be favorable to us which is if we wanted to hide our relationship (as administrative force) to that particular remote machine. Of course, in that case we would also not sign the host key/certificate in the first place. Being mentioned not just as somebody who has signed the host key/certificate but also as a revoker is an even stronger relationship than just having signed the key/certificate. Let us imagine a remote machine with 50 people (users of all different levels) who have signed its key/certificate but anyone who can revoke the host key is probably someone with a level of administrative access one way or another (or at least well-trusted by folks with administrative access). Bottom line is, if we do not want to hide our relationship with the remote machine (which is the default) then publishing the host key/certificate as we did in line 208 is perfectly fine. 216 sa@wks:~$ gpg --check-sigs E00C6FA8 217 pub 8192R/E00C6FA8 2009-03-22 218 uid ssh://foo.bar.com:18689 219 sig!3 E00C6FA8 2009-03-22 ssh://foo.bar.com:18689 220 sig! C0EC7E38 2009-03-22 Markus Gattol () <[email protected]> 221 222 sa@wks:~$ gpg --fixed-list-mode --with-colons --check-sigs E00C6FA8 223 tru::1:1237839982:0:3:1:5 224 pub:f:8192:1:027E3BCDE00C6FA8:1237730598:::m:::aA: 225 uid:f::::1237730598::CA020D08768F6C3244B3AE727F3034842C96988E::ssh\x3a//foo.bar.com\x3a18689: 226 sig:!::1:027E3BCDE00C6FA8:1237730598::::ssh\x3a//foo.bar.com\x3a18689:13x: 227 sig:!::17:48E94AC6C0EC7E38:1237732642::::Markus Gattol (http\x3a//www.markus-gattol.name) <[email protected]>:10x: 228 sa@wks:~$ gpg --export E00C6FA8 | gpg --list-packets 229 :public key packet: 230 version 4, algo 1, created 1237730598, expires 0 231 pkey[0]: [8192 bits] 232 pkey[1]: [6 bits] 233 :user ID packet: "ssh://foo.bar.com:18689" 234 :signature packet: algo 1, keyid 027E3BCDE00C6FA8 235 version 4, created 1237730598, md5len 0, sigclass 0x13 236 digest algo 2, begin of digest 25 14 237 hashed subpkt 2 len 4 (sig created 2009-03-22) 238 hashed subpkt 27 len 1 (key flags: 20) 239 hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2) 240 hashed subpkt 21 len 3 (pref-hash-algos: 2 8 3) 241 hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1) 242 hashed subpkt 30 len 1 (features: 01) 243 hashed subpkt 23 len 1 (key server preferences: 80) 244 subpkt 16 len 8 (issuer key ID 027E3BCDE00C6FA8) 245 data: [8191 bits] 246 :signature packet: algo 17, keyid 48E94AC6C0EC7E38 247 version 4, created 1237732642, md5len 0, sigclass 0x10 248 digest algo 2, begin of digest 0d e6 249 hashed subpkt 2 len 4 (sig created 2009-03-22) 250 subpkt 16 len 8 (issuer key ID 48E94AC6C0EC7E38) 251 data: [157 bits] 252 data: [160 bits] The commands from lines 216, 222 and 228 are the same as those in lines 263, 270 and 278. However, lines 216 to 252 show detailed information on our host key/certificate before we issued line 253 in order to update our local keyring with the former published host key/certificate (line 208). 253 sa@wks:~$ gpg --refresh-key gpg E00C6FA8 254 gpg: refreshing 1 key from hkp://keys.gnupg.net 255 gpg: requesting key E00C6FA8 from hkp server keys.gnupg.net 256 gpg: key E00C6FA8: direct key signature added 257 gpg: key E00C6FA8: "ssh://foo.bar.com:18689" 1 new signature 258 gpg: Total number processed: 1 259 gpg: new signatures: 1 260 gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model 261 gpg: depth: 0 valid: 2 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 2u 262 gpg: depth: 1 valid: 1 signed: 0 trust: 0-, 0q, 0n, 1m, 0f, 0u With line 253 we update the host key/certificate
263 sa@wks:~$ gpg --check-sigs E00C6FA8 264 pub 8192R/E00C6FA8 2009-03-22 265 sig! R E00C6FA8 2009-03-26 ssh://foo.bar.com:18689 266 uid ssh://foo.bar.com:18689 267 sig!3 E00C6FA8 2009-03-22 ssh://foo.bar.com:18689 268 sig! C0EC7E38 2009-03-22 Markus Gattol () <[email protected]> 269 270 sa@wks:~$ gpg --fixed-list-mode --with-colons --check-sigs E00C6FA8 271 tru::1:1238087182:0:3:1:5 272 pub:f:8192:1:027E3BCDE00C6FA8:1237730598:::m:::aA: 273 rvk:::17::::::F6F78566432A78A90D39CDAE48E94AC6C0EC7E38:80: 274 sig:!::1:027E3BCDE00C6FA8:1238070799::::ssh\x3a//foo.bar.com\x3a18689:1fx: 275 uid:f::::1237730598::CA020D08768F6C3244B3AE727F3034842C96988E::ssh\x3a//foo.bar.com\x3a18689: 276 sig:!::1:027E3BCDE00C6FA8:1237730598::::ssh\x3a//foo.bar.com\x3a18689:13x: 277 sig:!::17:48E94AC6C0EC7E38:1237732642::::Markus Gattol (http\x3a//www.markus-gattol.name) <[email protected]>:10x: 278 sa@wks:~$ gpg --export E00C6FA8 | gpg --list-packets 279 :public key packet: 280 version 4, algo 1, created 1237730598, expires 0 281 pkey[0]: [8192 bits] 282 pkey[1]: [6 bits] 283 :signature packet: algo 1, keyid 027E3BCDE00C6FA8 284 version 4, created 1238070799, md5len 0, sigclass 0x1f 285 digest algo 2, begin of digest 91 03 286 hashed subpkt 2 len 4 (sig created 2009-03-26) 287 hashed subpkt 12 len 22 (revocation key: c=80 a=17 f=F6F78566432A78A90D39CDAE48E94AC6C0EC7E38) 288 hashed subpkt 7 len 1 (not revocable) 289 subpkt 16 len 8 (issuer key ID 027E3BCDE00C6FA8) 290 data: [8190 bits] 291 :user ID packet: "ssh://foo.bar.com:18689" 292 :signature packet: algo 1, keyid 027E3BCDE00C6FA8 293 version 4, created 1237730598, md5len 0, sigclass 0x13 294 digest algo 2, begin of digest 25 14 295 hashed subpkt 2 len 4 (sig created 2009-03-22) 296 hashed subpkt 27 len 1 (key flags: 20) 297 hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2) 298 hashed subpkt 21 len 3 (pref-hash-algos: 2 8 3) 299 hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1) 300 hashed subpkt 30 len 1 (features: 01) 301 hashed subpkt 23 len 1 (key server preferences: 80) 302 subpkt 16 len 8 (issuer key ID 027E3BCDE00C6FA8) 303 data: [8191 bits] 304 :signature packet: algo 17, keyid 48E94AC6C0EC7E38 305 version 4, created 1237732642, md5len 0, sigclass 0x10 306 digest algo 2, begin of digest 0d e6 307 hashed subpkt 2 len 4 (sig created 2009-03-22) 308 subpkt 16 len 8 (issuer key ID 48E94AC6C0EC7E38) 309 data: [157 bits] 310 data: [160 bits] Line 265 is new because of updating our local version of the host key/certificate. Also, lines 273 and 274 are new. And last but not least, lines 283 to 290 are new as well. I will not go into detail here — what those lines in essence tell us
is that our host key/certificate got a revoker ID assigned to it.
Detailed information can be found by reading RFC (Request for
Comments) 4880, 311 sa@wks:~$ ssh testing_sec 312 313 314 [skipping a lot of lines...] 315 316 317 sa@wks-ve5:~$ su 318 Password: 319 wks-ve5:/home/sa# monkeysphere-host revoke-key 320 This will generate a revocation certificate for your host key 321 (fingerprint: 10A8068FD530ACBC13921A05027E3BCDE00C6FA8) and 322 dump the certificate to standard output. 323 324 It can also directly publish the new revocation certificate 325 to the public keyservers via pool.sks-keyservers.net if you want it to. 326 327 Publishing this certificate will IMMEDIATELY and PERMANENTLY revoke 328 your host key! 329 330 Publish the certificate after generation? (y/n/Q) n 331 332 sec 8192R/E00C6FA8 2009-03-22 ssh://foo.bar.com:18689 333 334 Create a revocation certificate for this key? (y/N) y 335 Please select the reason for the revocation: 336 0 = No reason specified 337 1 = Key has been compromised 338 2 = Key is superseded 339 3 = Key is no longer used 340 Q = Cancel 341 (Probably you want to select 1 here) 342 Your decision? 0 343 Enter an optional description; end it with an empty line: 344 > Creating a revocation certificate just in case... 345 > 346 Reason for revocation: No reason specified 347 Creating a revocation certificate just in case... 348 Is this okay? (y/N) y 349 NOTE: This key is not protected! 350 Revocation certificate created. 351 352 Please move it to a medium which you can hide away; if Mallory gets 353 access to this certificate he can use it to make your key unusable. 354 It is smart to print this certificate and store it away, just in case 355 your media become unreadable. But have some caution: The print system of 356 your machine might store the data and make it available to others! 357 -----BEGIN PGP PUBLIC KEY BLOCK----- 358 Version: GnuPG v1.4.9 (GNU/Linux) 359 Comment: A revocation certificate should follow 360 361 iQRRBCjBjgj7BQJJy8/cNB0jQ3JlYXRpbmcgYSBxxxxZvY2F0aW9uIGNlcnRpZml 362 YXRlIGp1c3QgaW4gY2FzZSjuLi4jCgkQjn47zejxxxxgwpCjjgTcvaLyt3ls0Yb9 363 qfPgC92IhWxxxxxxxjIljlh3iRoP21QHqx5BgkFxxxxlqlBMicPBCxJxy7r/TxRc 364 gLJpVusyTDxxxxxxx9QvjEljfPOmi7iyHERx8Tcxxxxi5c7IhIDh9T2nZiV0wulj 365 C/RMVef+ikxxxxxxxn0DKZ/0OhfK8yXisrg4CNXxxxxDj1TiQl4meTkNi0eshgbe 366 sCiXy1grN6xxxxxxxWTdgalE+MDZEcQjJjfcjMcxxxxPr8FTZPCMtYqRkv7j2z8M 367 cMRmfjiI2xxxxxxxxoxIMIQ5NDnWbX5v1r4sVMcxxxxB6XaugCbKJTh3nBbDjQZr 368 tSSZTBBIJVxxxxxxxG5uL39yJEEI7tymK4IWKIVxxxxkjvQ7WNox/M+0MY1nFEGb 369 mzGtvVmi/5xxxxxxxr3fC5CKIEpB9ISwtdMvrF0xxxxZCCXjbut2xIJ9rHCQKjVY 370 I4iK7mQoqcxxxxxxxyMp9f/zgaKhukyndXIvZ7TxxxxxOr12F3vNjryiYT1sGiii 371 yLZBOR4maoxxxxxxxDWSN5kEi4pGsiMiHRgV9WExxxxX5i3V8FiqpLi0HF78Lk1i 372 otqIIQl0OxxxxxxxxVaLuwS60XzdxingekoaExbxxxxGZg4SyHho/1iR2c+19dCm 373 DvNk3icD/bxxxxxxxrklBnubpvOfkZPWn79h4PfxxxxztoatPlwNTYoF3bBMiaTL 374 FHFfTPscKmxxxxxxxOxBexG3eF8RnI3pOLNBxnSxxxxIl26a6vja2iKQYNyVN9FE 375 FPNt5sN1JnxxxxxxxvQ92XY9eGHrh/iTvo6B2wnxxxxHY+T0cDKXVZPtS0wIw4dM 376 8jXtE+uJeexxxxxxxfiW5KSzCQio6Mi3PpOCx5dxxxxhhuBkjfeig4ol6BoC6qj6 377 inLvExJn5Kxxxxxxx4HOZYyWZkbcQ3KMvJkyuXnxxxxymETkFjQCghi9fs7MeXjG 378 obvaXXoBRLxxxxxxx5iPEYZ6Zrznuxftkwdwx+q0B+EzyYCI7xOivrO1TWfiBXo9 379 v+0lusPsljxxxxxxxTrodcSTj9faX0hvP7RyfMnQbtw9v2Mt8zinJCm2Ighjx7Ml 380 +o00XrL1j4gVsw5Dgqi/hBoDr7iFj6twZoP62CosWGFTxrmXxhFBM2m0dqDlj7lt 381 4zlkNCRJKor3rf3WjQoiLob3JwODuincTJemnGo0+zHaGXsG7o61baeE8ifguvxp 382 h9LsGjdRb797H6MTH7NqpupVl+vraRYBwhRE3idvrOjnYK4sSJrGRGsSxwSd7noQ 383 HCZneIOCG1uRtj2n+FGxDHkiynhXorZvsjkwINI0MY9wDF/zWfMvjBlh+4FC5F5R 384 WARL5A== 385 =vFm0 386 -----END PGP PUBLIC KEY BLOCK----- 387 wks-ve5:/home/sa# exit 388 exit 389 sa@wks-ve5:~$ exit 390 logout 391 Connection to foo.bar.com closed. In lines 311 to 391 we create a revocation certificate for our remote
machine using the subcommand The certificate is writen to stdout in lines 361 to 386 — I xed-out a
good portion of it and swapped a few characters using some GNU Emacs
magic like for example We should then grab that output and store it to some file which we keep somewhere save e.g. along with our revocation certificate(s) for our GPG keypair(s). Remote Machine Setup / User VerificationRemember, there are two angles how we can look at Monkeysphere... As the administrator of some computer/gadget providing access via SSH, we can take advantage of Monkeysphere in two ways — these two are orthogonal/independent i.e. we can do one without the other:
A monkeysphere-enabled remote machine can maintain SSH-style ~/.ssh/authorized_keys files automatically for its users. This frees us (the administrator(s)) from the task of manually checking/transmitting SSH keys, and it also enables users to do relatively painless key transitions, and to quickly and universally revoke access if they find that their SSH key has become compromised. We simply tell the monkeysphere-enabled system what person(s)
(identified by their OpenPGP UID) should have access to an account,
Monkeysphere takes care of generating the proper
392 sa@wks:~$ ssh testing_sec 393 394 / \ _-' 395 _/ \-''- _ / 396 __-' { \ 397 / \ 398 / "o. |o } 399 | \ ; YOU ARE BEING WATCHED! 400 ', 401 \_ __\ 402 ''-_ \.// 403 / '-____' 404 / 405 _' 406 _-' 407 408 409 This computer system is the private property of its owner, whether individual, corporate or government. It is 410 for authorized use only. Users (authorized or unauthorized) have no explicit or implicit expectation of 411 privacy. 412 413 Any or all uses of this system and all files on this system may be intercepted, monitored, recorded, copied, 414 audited, inspected, and disclosed to your employer, to authorized site, government, and law enforcement 415 personnel, as well as authorized officials of government agencies, both domestic and foreign. 416 417 By using this system, the user consents to such interception, monitoring, recording, copying, auditing, 418 inspection, and disclosure at the discretion of such personnel or officials. 419 420 421 UNAUTHORIZED OR IMPROPER USE OF THIS SYSTEM MAY RESULT 422 IN CIVIL AND CRIMINAL PENALTIES AND ADMINISTRATIVE OR 423 DISCIPLINARY ACTION, AS APPROPRIATE !! 424 425 426 By continuing to use this system you indicate your awareness of and consent to these terms and conditions of 427 use. LOG OFF IMMEDIATELY if you do not agree to the conditions stated in this warning. However, if you are 428 authorized personal with no bad intentions please continue. Have a nice day! :-) 429 430 sa@wks-ve5:~$ su 431 Password: 432 wks-ve5:/home/sa# monkeysphere-authentication list-id-certifiers 433 wks-ve5:/home/sa# monkeysphere-authentication add-id-certifier F6F78566432A78A90D39CDAE48E94AC6C0EC7E38 434 gpg: requesting key C0EC7E38 from hkp server pool.sks-keyservers.net 435 ms: key found: 436 pub 1024D/C0EC7E38 2009-02-06 437 Key fingerprint = F6F7 8566 432A 78A9 0D39 CDAE 48E9 4AC6 C0EC 7E38 438 uid [ unknown] Markus Gattol () <[email protected]> 439 uid [ unknown] Markus Gattol () <markus.gattol[at]foo.org> 440 sub 4096g/34233DEF 2009-02-06 441 442 Are you sure you want to add the above key as a certifier 443 of users on this system? (Y/n) Y 444 ms: Identity certifier added. 445 wks-ve5:/home/sa# monkeysphere-authentication list-id-certifiers 446 gpg: checking the trustdb 447 F6F78566432A78A90D39CDAE48E94AC6C0EC7E38: 448 :Markus Gattol (http\x3a//www.markus-gattol.name) <[email protected]>:1:120: 449 :Markus Gattol (http\x3a//www.markus-gattol.name) <markus.gattol[at]foo.org>:1:120: 450 wks-ve5:/home/sa# monkeysphere-authentication diagnostics 451 Checking for authentication directory... 452 Checking core GPG key... 453 454 Checking for Identity Certifiers... 455 456 Checking for Monkeysphere-enabled public-key authentication for users... 457 ! /etc/ssh/sshd_config does not point to monkeysphere authorized keys. 458 - Recommendation: add a line to /etc/ssh/sshd_config: 'AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u' 459 ! /etc/ssh/sshd_config refers to non-monkeysphere authorized_keys files: 460 AuthorizedKeysFile %h/.ssh/authorized_keys 461 - Recommendation: remove the above AuthorizedKeysFile lines from /etc/ssh/sshd_config 462 When the above 2 issues are resolved, please re-run: 463 monkeysphere-authentication diagnostics 464 465 466 [ here we use nano to edit sshd_config... ] 467 468 At first we need to specify who will be authorized to give users
access to our monkeysphere-enabled remote machine Line 432 shows how to list existing Identity Certifiers — there are
none yet which is why we issue line 433 with my key ID of
After we are done adding (and checking) our first identity certifier,
we run the As can be seen, and as I mentioned it before, we only have to make a tiny change to our existing PKA SSH setup — the only one necessary though... What we need to do is to modify our current /etc/ssh/sshd_config to
read We also disable the AllowUsers keyword directive simply because
Monkeysphere is now taking care of who can and who cannot enter our
remote machine
The last thing we change is Well, actually, this number might be different for the reader because
what happens is that all keys shown with The point here is, setting An even better option however, is to use More information on this matter can be found below — the main discussion on the matter can also be found below. ###_ main #AllowUsers sa@* #GSSAPIAuthentication no #GSSAPICleanupCredentials yes #IgnoreUserKnownHosts yes #KerberosAuthentication no #KerberosGetAFSToken no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #ListenAddress 0.0.0.0 #ListenAddress :: #UseLogin no AcceptEnv LANG LC_* AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u Banner /etc/issue.net ChallengeResponseAuthentication no ClientAliveCountMax 3 ClientAliveInterval 15 HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_rsa_key HostbasedAuthentication no IgnoreRhosts yes KeyRegenerationInterval 3600 LogLevel VERBOSE LoginGraceTime 20 MaxAuthTries 3 MaxSessions 5 MaxStartups 5:50:20 PasswordAuthentication no PermitEmptyPasswords no PermitRootLogin no Port 18689 PrintLastLog no PrintMotd no Protocol 2 PubkeyAuthentication yes RSAAuthentication no RhostsRSAAuthentication no ServerKeyBits 768 StrictModes yes Subsystem sftp /usr/lib/openssh/sftp-server SyslogFacility AUTH TCPKeepAlive yes UsePAM no UsePrivilegeSeparation yes X11DisplayOffset 10 X11Forwarding no ###_ emacs local variables # Local Variables: # mode: conf # allout-layout: (0 : 0) # End: 469 wks-ve5:/home/sa# monkeysphere-authentication diagnostics 470 Checking for authentication directory... 471 Checking core GPG key... 472 473 Checking for Identity Certifiers... 474 475 Checking for Monkeysphere-enabled public-key authentication for users... 476 Everything seems to be in order! 477 wks-ve5:/home/sa# mkdir .monkeysphere 478 wks-ve5:/home/sa# echo 'Markus Gattol () <markus.gattol[at]foo.org>' >> .monkeysphere/authorized_user_ids 479 wks-ve5:/home/sa# cat !echo:3 480 cat .monkeysphere/authorized_user_ids 481 Markus Gattol () <markus.gattol[at]foo.org> 482 wks-ve5:/home/sa# monkeysphere-authentication update-users 483 wks-ve5:/home/sa# type lat; lat /var/lib/monkeysphere/authorized_keys/ 484 lat is aliased to `ls -lath' 485 total 4.0K 486 drwxr-xr-x 2 root root 15 2009-03-27 14:44 . 487 -rw-r----- 1 root sa 1.5K 2009-03-27 14:44 sa 488 drwxr-xr-x 6 root root 141 2009-03-22 14:03 .. 489 wks-ve5:/home/sa# file /var/lib/monkeysphere/authorized_keys/sa 490 /var/lib/monkeysphere/authorized_keys/sa: ASCII text, with very long lines 491 wks-ve5:/home/sa# /etc/init.d/ssh reload 492 Reloading OpenBSD Secure Shell server's configuration: sshd. 493 wks-ve5:/home/sa# exit 494 exit 495 sa@wks-ve5:~$ exit 496 logout 497 Connection to foo.bar.com closed. After our change to The next thing we are going to do is to actually grant some user(s)
access to As can be seen, by issuing Finally, because of the change to A user is granted access to a monkeysphere-enabled remote machine if all of the following are true (logical AND):
As I have mentioned above, we can run Monkeysphere in parallel to some standard PKA (Public Key Authentication) setup which would allow folks to log in under the afore mentioned circumstances and/or if their public key where placed into ~/.ssh/authorized_keys. However, optionally we can disable standard PKA login so that
Monkeysphere remains the only way to authenticate against our remote
machine 498 sa@wks:~$ ssh testing_sec 499 500 501 [skipping a lot of lines...] 502 503 504 sa@wks-ve5:~$ su 505 Password: 506 wks-ve5:/home/sa# cd /var/lib/monkeysphere/authorized_keys/ 507 508 509 [ here we use nano to edit sshd_config/etc/monkeysphere/monkeysphere-authentication.conf... ] 510 511 512 wks-ve5:/var/lib/monkeysphere/authorized_keys# grep RAW /etc/monkeysphere/monkeysphere-authentication.conf 513 #RAW_AUTHORIZED_KEYS="%h/.ssh/authorized_keys" 514 RAW_AUTHORIZED_KEYS=none 515 wks-ve5:/var/lib/monkeysphere/authorized_keys# monkeysphere-authentication update-users 516 wks-ve5:/var/lib/monkeysphere/authorized_keys# type la 517 la is aliased to `ls -la' 518 wks-ve5:/var/lib/monkeysphere/authorized_keys# la 519 total 4 520 drwxr-xr-x 2 root root 15 Mar 28 13:33 . 521 drwxr-xr-x 6 root root 141 Mar 22 14:03 .. 522 -rw-r----- 1 root sa 811 Mar 28 13:33 sa 523 wks-ve5:/var/lib/monkeysphere/authorized_keys# exit 524 exit 525 sa@wks-ve5:~$ exit 526 logout 527 Connection to foo.bar.com closed. 528 sa@wks:~$ Line 509 indicates we used nano in order to put line 514 into place —
this is the reason why, from now on, standard It is then also important to update the monkeysphere-controlled, per user, authorized-keys file again as we do it in line 515. Being back on our local machine in line 528, it would now we necessary
to provide the authentication subkey to SSH-agent if we wanted to log
into User SetupHow to set up a remote machine with Monkeysphere and administer it is covered above. This subsection is about being a user to some monkeysphere-enabled SSH
setup i.e. a remote machine running an Any person who wants to access a monkeysphere-enabled remote machine needs to have a uniquely verifiable digital identity of himself. With regards to Monkeysphere, this is an OpenPGP UID in the WOT (Web of Trust). How to acquire such a digital identity is covered here. SSH ProxyCommandThe simplest way to identify remote machines with the help of the WOT
(Web of Trust) is to tell SSH to use Monkeysphere's This command will make sure the ~/.ssh/known_hosts file is up-to-date for the remote machine we are connecting to via SSH (Secure Shell). We can try this out when connecting to a remote machine which has
published its host key/certificate to the WOT with 1 sa@wks:~$ grep -A4 'Host \*' .ssh/config 2 Host * 3 User sa 4 ProxyCommand monkeysphere ssh-proxycommand %h %p 5 ControlMaster auto 6 ControlPath /tmp/ssh_connections_to_host(%h)_at_port(%p)_by_user(%r) 7 sa@wks:~$ Note that Monkeysphere will help us identify remote machines whose host key/certificate has been published to the WOT, and which are signed by people who we know and trust to correctly identify remote machines. If we are not connected to our administrator(s) through the WOT already, we should talk to them and establish that relationship e.g. by signing each others public key. If we have already established that relationship (directly by signing each others public key or indirectly via the WOT), but a remote machine's host key/certificate is not published to the WOT, we might suggest to our administrator(s) that they publish the host key/certificate in question so users of that remote machine can trust it. Authentication SubkeyAbove we have seen how to set up a remote machine for user authentication on the remote site. This is the part where we are going to look at the counterpart i.e. how to prepare the user's OpenPGP key so he can log into a monkeysphere-enabled remote machine. I already mentioned above that anyone who wants to use Monkeysphere as
a user needs to have an OpenPGP UID in the WOT. In order to log into a
monkeysphere-enabled remote machine we need to add an
authentication-capable subkey to our OpenPGP identity using
1 sa@wks:~$ echo $DISPLAY 2 :0.0 3 sa@wks:~$ DISPLAY=""; export MONKEYSPHERE_LOG_LEVEL=DEBUG; time monkeysphere gen-subkey --length 4096 $(gpg --fingerprint --with-colons markus.gattol | awk -F: '/fpr/ {print $10}') 4 ms: creating password fifo... 5 ms: generating subkey... 6 Please enter your passphrase for 48E94AC6C0EC7E38: 7 ............+++++ 8 ......+++++ 9 ...+++++ 10 ms: done. 11 12 real 1m45.554s 13 user 0m4.872s 14 sys 0m0.080s 15 sa@wks:~$ gpg --edit-key markus.gattol 16 Secret key is available. 17 18 pub 1024D/C0EC7E38 created: 2009-02-06 expires: never usage: SC 19 trust: ultimate validity: ultimate 20 sub 4096g/34233DEF created: 2009-02-06 expires: never usage: E 21 sub 4096R/C3650930 created: 2009-03-28 expires: never usage: A 22 [ultimate] (1). Markus Gattol () <[email protected]> 23 [ultimate] (2) Markus Gattol () <markus.gattol[at]foo.org> 24 25 Command> q 26 sa@wks:~$ gpg --send-key $(gpg --fingerprint --with-colons markus.gattol | awk -F: '/fpr/ {print $10}') 27 gpg: sending key C0EC7E38 to hkp server keys.gnupg.net 28 sa@wks:~$ echo $DISPLAY 29 30 sa@wks:~$ export DISPLAY=:0.0 31 sa@wks:~$ echo $DISPLAY 32 :0.0 Lines 1 to 3 are supposed to look different under normal circumstances
but I am having an issue with Line 3 is a bit heavy in this demonstration —
Line 6 prompts us for the password we specified when creating the
keypair in the first place. Lines 7 to 14 are indicators of collecting
enough entropy (see Line 21 shows us the just created subkey — note its Finally I reset Providing the Authentication Subkey to SSH-agent33 sa@wks:~$ ssh-add -l 34 8192 e9:44:87:72:db:27:c7:34:ff:81:a3:9d:5a:26:7c:d3 Public Key (RSA) 35 8192 61:42:af:ea:d9:bf:b7:b5:4b:24:ad:1a:ad:49:80:70 Public Key (RSA) 36 sa@wks:~$ DISPLAY=''; monkeysphere subkey-to-ssh-agent 37 Enter passphrase for key Markus Gattol (http\x3awww.markus-gattol.name) <[email protected]>: 38 gpg: about to export an unprotected subkey 39 We only support RSA keys (this key used algorithm 17). 40 Identity added: Markus Gattol (http\x3awww.markus-gattol.name) <[email protected]> (Markus Gattol (http\x3awww.markus-gattol.name) <[email protected]>) 41 sa@wks:~$ ssh-add -l 42 8192 e9:44:87:72:db:27:c7:34:ff:81:a3:9d:5a:26:7c:d3 Public Key (RSA) 43 8192 61:42:af:ea:d9:bf:b7:b5:4b:24:ad:1a:ad:49:80:70 Public Key (RSA) 44 4096 7d:08:51:13:9e:5a:26:64:c2:df:01:d1:1b:96:81:33 Public Key (RSA) 45 sa@wks:~$ export DISPLAY=:0.0 46 sa@wks:~$ ssh testing_sec 47 48 49 [skipping a lot of lines...] 50 51 52 sa@wks-ve5:~$ exit 53 logout 54 Connection to foo.bar.com closed. 55 sa@wks:~$ As before, I only altered In line 36 we issue In line 44 we can see that SSH-agent now knows about our monkeysphere-authentication subkey. The following test in lines 46 to 55 is successful. On the remote machine site, the setup at this point, was as can bee seen above where we got until line 528 or line 497 respectively. Keeping it up-to-dateWRITEME triggered by cron
triggered by incron
ObstaclesThere are a few obstacles one might run into when for example using
Monkeysphere in conjunction with clusterssh. One I run into was the
notorious More information about it can be found here. In short, making it go away only requires to increase the timeout from 10 seconds to for example 30 seconds sa@wks:~$ grep ssh_args .csshrc ssh_args= -x -o ConnectTimeout=30 sa@wks:~$ Best PracticesThere are a few things we can do in order to elevate security step by step. In more or less chronological order:
I have made very good experiences with the following
sa@wks:~$ cat /etc/ssh/sshd_config ###_ main #AuthorizedKeysFile %h/.ssh/authorized_keys #GSSAPIAuthentication no #GSSAPICleanupCredentials yes #IgnoreUserKnownHosts yes #KerberosAuthentication no #KerberosGetAFSToken no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #ListenAddress 0.0.0.0 #ListenAddress :: #UseLogin no AcceptEnv LANG LC_* AllowUsers sa@* Banner /etc/issue.net ChallengeResponseAuthentication no ClientAliveCountMax 3 ClientAliveInterval 15 HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_rsa_key HostbasedAuthentication no IgnoreRhosts yes KeyRegenerationInterval 3600 LogLevel VERBOSE LoginGraceTime 20 MaxAuthTries 2 MaxSessions 5 MaxStartups 5:50:20 PasswordAuthentication yes PermitEmptyPasswords no PermitRootLogin no Port 10874 PrintLastLog no PrintMotd no Protocol 2 PubkeyAuthentication no RSAAuthentication no RhostsRSAAuthentication no ServerKeyBits 768 StrictModes yes Subsystem sftp /usr/lib/openssh/sftp-server SyslogFacility AUTH TCPKeepAlive yes UsePAM yes UsePrivilegeSeparation yes X11DisplayOffset 10 X11Forwarding no ###_ emacs local variables # Local Variables: # mode: conf # allout-layout: (0 : 0) # End: sa@wks:~$ Note that The lines are alphabetically sorted (a single keystroke with GNU Emacs does the trick ;-] ) and I have made a few additions and sensible changes to Debian's standard installation. Most of the settings are now explained below as a remainder of this section. LoggingThe default settings enable sshd logging to the sa@rh0:~$ grep ^LogL /etc/ssh/sshd_config LogLevel VERBOSE sa@rh0:~$ Now all the details of successful SSH logins as well as potential
logins will be recorded into the Banner
No problem. The Enabling the Banner DirectiveAt first we need to uncomment the sa@rh0:~$ grep Bann /etc/ssh/sshd_config Banner /etc/issue.net sa@rh0:~$ Creating the pre-login MessageNow that the banner display is enabled in 1 sa@rh0:~$ cd /etc/ && type pi 2 pi is aliased to `ls -la | grep' 3 sa@rh0:/etc$ pi issue 4 -rw-r--r-- 1 root root 1535 2008-07-25 16:36 issue 5 lrwxrwxrwx 1 root root 10 2008-07-25 16:40 issue.net -> /etc/issue 6 -rw-r--r-- 1 root root 27 2008-07-25 16:37 issue.net_orig 7 -rw-r--r-- 1 root root 34 2008-07-25 16:35 issue_orig 8 sa@rh0:/etc$ The files sa@rh0:~$ su Password: rh0:/home/sa# /etc/init.d/ssh reload Reloading OpenBSD Secure Shell server's configuration: sshd. rh0:/home/sa# exit exit sa@rh0:~$ ,all login attempts will be met with the message from Getting the ResultThe result can be seen below. The content of sa@sub:~$ ssh rh0 / \ _-' _/ \-''- _ / __-' { \ / \ / "o. |o } | \ ; YOU ARE BEING WATCHED! ', \_ __\ ''-_ \.// / '-____' / _' _-' This computer system is the private property of its owner, whether individual, corporate or government. It is for authorized use only. Users (authorized or unauthorized) have no explicit or implicit expectation of privacy. Any or all uses of this system and all files on this system may be intercepted, monitored, recorded, copied, audited, inspected, and disclosed to your employer, to authorized site, government, and law enforcement personnel, as well as authorized officials of government agencies, both domestic and foreign. By using this system, the user consents to such interception, monitoring, recording, copying, auditing, inspection, and disclosure at the discretion of such personnel or officials. UNAUTHORIZED OR IMPROPER USE OF THIS SYSTEM MAY RESULT IN CIVIL AND CRIMINAL PENALTIES AND ADMINISTRATIVE OR DISCIPLINARY ACTION, AS APPROPRIATE !! By continuing to use this system you indicate your awareness of and consent to these terms and conditions of use. LOG OFF IMMEDIATELY if you do not agree to the conditions stated in this warning. However, if you are authorized personal with no bad intentions please continue. Have a nice day! :-) [email protected]'s password: Linux rh0 2.6.25-2-amd64 #1 SMP Mon Jul 14 11:05:23 UTC 2008 x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Fri Jul 25 15:39:30 2008 from xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx sa@rh0:~$ All local console logins will also display the message from
If this is not the behavior one desires, then he could place the
banner content into Strong PasswordsHere is some explanation what we consider a weak password. When we use
sa@sub:~$ type pwg pwg is aliased to `pwgen -sncB 55 1' sa@sub:~$ pwg usFAtwH3ou4NXkrheFjrFzNCRpVbTHfaXjiwmtNjWgcTRb9TwayYXjg sa@sub:~$ pwgen -sync 55 1 .:.2LRC=^h_LiJ^pBAeFLNTu`J3RO_:&\qCK)X`wEqipL2a_GD[=jzy sa@sub:~$ Well, although those are very strong passwords, typing this on a
regular is like cursing some user. A no-go simply put. Instead of
using the CLI (Command Line Interface) and A good idea is using something familiar. Something like
Another trivial change to actually elevate security a bit is to alter
the sa@rh0:~$ grep ^Login /etc/ssh/sshd_config LoginGraceTime 5 sa@rh0:~$ Now the sshd will only wait 5 seconds for a user to finish the login process before disconnecting the remote connection. This may aid in thwarting automated brute force attacks and denial of service style attacks against our SSH service.
Prohibit root loginWe do not want to allow SSH login for the user 1 sa@rh0:~$ grep PermitRootLogin /etc/ssh/sshd_config 2 PermitRootLogin no 3 sa@rh0:~$ Line 2 shows how it should look like, if it does not, we need to edit
[exiting the server; back on local machine...] 4 sa@sub:~$ ssh [email protected] 5 [email protected]'s password: 6 Permission denied, please try again. 7 sa@sub:~$ Allow Users / GroupsThe directive The example below shows that only the user sa@sub:~$ ssh rh0 grep AllowUsers /etc/ssh/sshd_config [email protected]'s password: AllowUsers sa sa@sub:~$
However, we can further tighten the security here by specifying not
only a username that can be permitted, but also the originating host
they can log in from by specifying a For example, if we specify My personal preference is to use sshd listening PortBy default sshd listens on port
Long story told short, since automated procedures in 99% of all cases
only look for an SSH service on port sa@sub:~$ ssh rh0 grep Port /etc/ssh/sshd_config [email protected]'s password: Port 17489 sa@sub:~$ is enough in order to avoid 99% percent of all automated procedures
targeted at the SSH service. After we added the line Specify particular listening Interface / AddressIf we are running SSH on a box within our LAN (Local Area Network) which is secured by a firewall from the insecure Internet then the following information is probably not needed. If however, we are running SSH on a firewall box or some kind of gateway with two or more network interfaces, then this section is quite interesting. Out of the box OpenSSH will bind to every available network address sub:/home/sa# netstat -tulpen | egrep ^Proto\|ssh Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp6 0 0 :::17489 :::* LISTEN 0 5797 2516/sshd sub:/home/sa# While convenient and suitable for most installations, this is far from
optimal. If our machine has two or more NICs (Network Interface Cards)
then the odds are that one is trusted (e.g. connected to our LAN) and
the other is untrusted (e.g. connected to the Internet). If this is
the case, and we do not need nor want SSH access coming in on the
untrusted interface, then we should configure OpenSSH to listen on a
specific interface (the trusted one that is) only. To have sshd only
bind to our internal interface with the IP address sa@sub:~$ ssh rh0 grep ListenAddress /etc/ssh/sshd_config [email protected]'s password: ListenAddress 10.0.4.56 sa@sub:~$ then we reload the configuration (see above) and we are done binding sshd to some specific listening interface. Public Key AuthenticationIt is very important that we control who has access to our servers — using SSH with PKA (Public Key Authentication) is one great method to get this job done. SSH with PKA can be used standalone or with a bunch of other methods like for example port knocking, tcp wrappers, ssh proxies, etc. Even if used standalone, PKA with SSH creates a practically not to overcome barrier for those (humans and software bots) who are not allowed to access our servers. This is just one reason, aside from its easy setup and maintenance, PKA is used a lot in practice. It is also the most recommended method to automate the authentication procedure to our servers in case it is needed for things like for example automated backups. In essence, PKA is working with a set of two keys:
The public key resides on our server, and a private key that corresponds with that public key resides on the user's computer. The private key is a secret file that matches with the public key in order to allow a connection to the remote server to be established — only those computers with the private key locally stored will be able to connect to the remote server via SSH. Private keys can be encrypted using a strength that varies (mostly from 1024 bit to 4096 bit) in length. The algorithm/method used is either RSA or DSA. These keys are so secure that it is believed, even supercomputers would take years to break the least encrypted (1024 bit) keys if not hundreds of years in case keys with a length of 4096 or more bits are used. In short, if set up correctly and used correctly, PKA makes it impossible for others to break into our server. Why does Public Key Authentication benefit me?PKA keeps our businesses IT infrastructures and therefore our livelihoods secure. Even if this seems not so important to most folks at first glance (those who want quick results no matter what), keeping things secure and under control is what everybody needs/wants in the long run. If we use PKA then no longer can our SSH password (the user password on the remote machine) be used to access a server, be guessed or cracked by hackers applying brute forcing and things like that. If we decide to access our remote server/machine using both, our private key and the password we choose to protect it (the one we used when creating the keypair; not to be confused with the user password on the remote machine used for password authentication), then even if someone knows the password for our private key, he still needs to obtain our private key in order to gain access to our server. It is the same the other way around i.e. if someone managed to get our private key, he still needs the password to unlock the private key in order to successfully access our server. If the reader is totally confused now, let me try again:
Using PKA with SSH not just increases security for the person/company who ultimately owns and/or administers the server but also for everyone else on the server i.e. with SSH PKA all user accounts are more secure which in turn reduces the risk of server-wide problems and keeps user accounts and therefore the whole server more secure from hostile activities. Things to note when enabling PKA:As with most things in life, there are advantages and disadvantages to enabling PKA (Public Key Authentication):
Setting up PKAAs of now we have a working SSH setup where we can login to our server (running the sshd) from our client (running an SSH client; preferably OpenSSH) via password authentication. Our plan now is to set up PKA, test it and only if it works do we disable password authentication — otherwise we might accidentally lockout ourselves from the server. Enabling PKAIn the example below, The user I work with is my standard user called As of now (March 2009) Debian ships with PKA enabled but that might be different depending on what local settings we have. So, just to be sure, we check the current status on PKA. 1 wks-ve5:/etc/ssh# egrep ^RSA\|^Pub\|^Protoc\|^Passwo\|AuthorizedKeysFile sshd_config 2 #AuthorizedKeysFile %h/.ssh/authorized_keys 3 PasswordAuthentication yes 4 Protocol 2 5 PubkeyAuthentication no 6 RSAAuthentication no 7 wks-ve5:/etc/ssh# egrep ^RSA\|^Pub\|^Protoc\|^Passwo\|AuthorizedKeysFile sshd_config 8 AuthorizedKeysFile %h/.ssh/authorized_keys 9 PasswordAuthentication yes 10 Protocol 2 11 PubkeyAuthentication yes 12 RSAAuthentication no As we can see in lines in lines 2, 5 and 6, PKA is currently disabled.
Although we also tested for Creating the KeypairAfter we configured the remote machine to allow for both, password
authenticated login using the user password for 13 wks-ve5:/etc/ssh# hostname 14 wks-ve5 15 wks-ve5:/etc/ssh# whoami 16 root 17 wks-ve5:/etc/ssh# exit 18 exit 19 sa@wks-ve5:~$ whoami 20 sa 21 sa@wks-ve5:~$ pwd 22 /home/sa 23 sa@wks-ve5:~$ type pi; pi ssh 24 pi is aliased to `ls -la | grep' 25 sa@wks-ve5:~$ exit 26 logout 27 Connection to 192.168.1.104 closed. 28 sa@wks:~$ whoami 29 sa 30 sa@wks:~$ hostname 31 wks 32 sa@wks:~$ pwd 33 /home/sa 34 sa@wks:~$ cd .ssh/ 35 sa@wks:~/.ssh$ pi Markus In lines 13 to 22 we just take a look around on the remote machine and ensure who we are and what machine/host this is — sometimes, when working with dozens of SSH sessions in parallel, this is necessary because only believing in the shell prompt may be fatal ;-] One important thing to note here is the result of line 23 — not the
fact that After logging out from the remote machine we change into 36 sa@wks:~/.ssh$ ssh-keygen -t rsa -b 8192 -f /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol -C 'PKA keypair for user Markus Gattol; reach me at [email protected]' 37 Generating public/private rsa key pair. 38 Enter passphrase (empty for no passphrase): 39 Enter same passphrase again: 40 Your identification has been saved in /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol. 41 Your public key has been saved in /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol.pub. 42 The key fingerprint is: 43 a6:2c:b6:3b:52:06:3c:7f:29:69:64:5f:c1:6d:ea:23 PKA keypair for user Markus Gattol; reach me at [email protected] 44 The key's randomart image is: 45 +--[ RSA 8192]----+ 46 | . . . | 47 | + o o | 48 | + . o . | 49 | + = . .| 50 | o =So . . | 51 | .. o+ . E ..| 52 | o.o. . .| 53 | ..o | 54 | oo | 55 +-----------------+ 56 sa@wks:~/.ssh$ pi Markus 57 -rw------- 1 sa sa 6431 2009-03-08 20:42 ssh_pka_key_for_user_Markus_Gattol 58 -rw-r--r-- 1 sa sa 1481 2009-03-08 20:42 ssh_pka_key_for_user_Markus_Gattol.pub The reason why we issued line 35 can be seen in line 36 — we create
the new keypair and name it appropriately ( The switches in line 36 are pretty much self-explanatory. I used Lines 38 and 39 are important. Remember what I said above about protecting the private key using a passphrase? Well, this is it. Lines 40 to 55 contain additional information like for example the keys fingerprint (a keys unique identifier) and the comment message we supplied in line 36. There is also a visual representation of the keys fingerprint which is... well, nice to have I guess ;-] The same command we issued in line 35, issued again in line 56 now
provides us with the keypair we just created — the private
( Note that this keypair mentions the user Also note that an SSH keypair has nothing to do with some GPG (GNU Privacy Guard) keypair. Transferring the Public Key to the remote MachineNext thing to do is to move the public key onto the remote machine so PKA can work. The Internet is full of documentation about this step including all
kinds of mystical magic like for example transferring the key with
59 sa@wks:~/.ssh$ ssh-copy-id -i /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol '-p 18689 [email protected]' 60 61 62 [skipping a lot of lines...] 63 64 65 [email protected]'s password: 66 Now try logging into the machine, with "ssh '-p 18689 [email protected]'", and check in: 67 68 .ssh/authorized_keys 69 70 to make sure we haven't added extra keys that you weren't expecting. 71 72 sa@wks:~$ ssh -p 18689 [email protected] 73 74 75 [skipping a lot of lines...] 76 77 78 [email protected]'s password: 79 Linux wks-ve2 2.6.26-1-openvz-amd64 #1 SMP Sat Jan 10 18:52:53 UTC 2009 x86_64 80 81 The programs included with the Debian GNU/Linux system are free software; 82 the exact distribution terms for each program are described in the 83 individual files in /usr/share/doc/*/copyright. 84 85 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 86 permitted by applicable law. 87 sa@wks-ve5:~$ su 88 Password: 89 wks-ve5:/home/sa# /etc/init.d/ssh reload 90 Reloading OpenBSD Secure Shell server's configuration: sshd. 91 wks-ve5:/home/sa# exit 92 exit 93 sa@wks-ve5:~$ exit 94 logout 95 Connection to 192.168.1.104 closed. In line 59 we use In line 65 we are still asked for the Lines 72 to 95 are just because we have not reloaded
At this point both, password as well as PKA login to the remote machine is enabled. The rationale here is simple — only after we made sure that PKA login works do we disable the standard user password login. If we would have disabled password login using the users
password for This is no problem with our current setup as Testing PKA enabled Login96 sa@wks:~$ ssh -i ~/.ssh/ssh_pka_key_for_user_Markus_Gattol -p 18689 [email protected] 97 98 99 [skipping a lot of lines...] 100 101 102 Enter passphrase for key '/home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol': 103 Linux wks-ve5 2.6.26-1-openvz-amd64 #1 SMP Sat Jan 10 18:52:53 UTC 2009 x86_64 104 105 The programs included with the Debian GNU/Linux system are free software; 106 the exact distribution terms for each program are described in the 107 individual files in /usr/share/doc/*/copyright. 108 109 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 110 permitted by applicable law. 111 sa@wks-ve5:~$ su 112 Password: In line 96 we specify the identity/keypair we would like to use for PKA login to our remote machine which is of course the one we created in lines 36 to 55. Line 99, as the others before, is just an indicator that I skipped the banner message. Line 102 is important as we are prompted for the password that protects our private key, the one we provided in lines 38 and 39. After providing the correct password, we are successfully logged into the remote machine, this time using PKA. This is the proof which we were looking for in order to turn of the standard password authentication using a user's password. Disable PAM and Password AuthenticationThis is optional but strongly recommended. After we set up PKA, we can disable PAM (Pluggable Authentication Modules) as well as password authentication because we do not need them anymore now that PKA works, besides, PKA is way more secure and comfortable than using password authentication. 113 wks-ve5:/home/sa# cd /etc/ssh/ 114 wks-ve5:/etc/ssh# egrep ^UsePAM\|^Password sshd_config 115 PasswordAuthentication yes 116 UsePAM yes 117 wks-ve5:/etc/ssh# nano sshd_config 118 119 120 [ here we use nano to edit sshd_config... ] 121 122 123 wks-ve5:/etc/ssh# egrep ^UsePAM\|^Password sshd_config 124 PasswordAuthentication no 125 UsePAM no 126 wks-ve5:/etc/ssh# /etc/init.d/ssh reload 127 Reloading OpenBSD Secure Shell server's configuration: sshd. 128 wks-ve5:/etc/ssh# exit 129 exit 130 sa@wks-ve5:~$ exit 131 logout 132 Connection to 192.168.1.104 closed. 133 sa@wks:~$ ssh -p 18689 [email protected] 134 135 136 [skipping a lot of lines...] 137 138 139 Permission denied (publickey). In order to so, we need to change lines 115 and 116 to 124 and 125 and
reload In line 133 we test if password authentication is still working — it is not as line 139 indicates but instead the remote machine requires us to use PKA from now on. We are done now setting up a rock-solid PKA (Public Key
Authentication) login environment in order to log into our remote
machine
We started with my standard ###_ main #GSSAPIAuthentication no #GSSAPICleanupCredentials yes #IgnoreUserKnownHosts yes #KerberosAuthentication no #KerberosGetAFSToken no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #ListenAddress 0.0.0.0 #ListenAddress :: #UseLogin no AcceptEnv LANG LC_* AllowUsers sa@* AuthorizedKeysFile %h/.ssh/authorized_keys Banner /etc/issue.net ChallengeResponseAuthentication no ClientAliveCountMax 3 ClientAliveInterval 15 HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_rsa_key HostbasedAuthentication no IgnoreRhosts yes KeyRegenerationInterval 3600 LogLevel VERBOSE LoginGraceTime 20 MaxAuthTries 1 MaxSessions 5 MaxStartups 5:50:20 PasswordAuthentication no PermitEmptyPasswords no PermitRootLogin no Port 18689 PrintLastLog no PrintMotd no Protocol 2 PubkeyAuthentication yes RSAAuthentication no RhostsRSAAuthentication no ServerKeyBits 768 StrictModes yes Subsystem sftp /usr/lib/openssh/sftp-server SyslogFacility AUTH TCPKeepAlive yes UsePAM no UsePrivilegeSeparation yes X11DisplayOffset 10 X11Forwarding no ###_ emacs local variables # Local Variables: # mode: conf # allout-layout: (0 : 0) # End: Automating the PKA LoginI already mentioned it above, we can use SSH-agent to bring a lot more comfort into our lives. In our current case we want to only provide the password used to unlock our private key once per session i.e. all subsequent PKA logins to the remote machine will not prompt us (the user) for the password anymore because the SSH-agent will intercept the call and provide the password for us. 140 sa@wks:~$ ssh-add /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol 141 Enter passphrase for /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol: 142 Identity added: /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol (/home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol) 143 sa@wks:~$ ssh -i /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol -p 18689 [email protected] 144 145 146 [skipping a lot of lines...] 147 148 First however we need to tell the SSH-agent about the particular
identity to use for logging into In line 143 we give it a try and as if it were magic, we are logged into the remote machine instantly without being required to type the password to unlock our private key as we had to in line 102 before. Let us recap: we have a working PKA SSH setup, password authentication as well as PAM is disabled and last but not least, the SSH-agent takes away the burden of providing the password to unlock the private key over and over again any time we want to log into the remote machine. This whole setup is very cool and good already but then, perfect is
what we want. The distinction between good and perfect in this regard
is if we could somehow wrap that overly complex line 143 into
something nice to remember like 149 sa@wks-ve5:~$ exit 150 logout 151 Connection to 192.168.1.104 closed. 152 sa@wks:~$ grep -A5 wks-ve5 .ssh/config 153 ###_ , wks-ve5 154 # description: remote host wks-ve5 155 Host wks-ve5 156 HostName 192.168.1.104 157 Port 18689 158 User sa 159 ###_ , sub 160 sa@wks:~$ ssh wks-ve5 161 162 163 [skipping a lot of lines...] 164 165 sa@wks-ve5:~$ exit 166 logout 167 Connection to 192.168.1.104 closed. 168 sa@wks:~$ We can get rid of the complex and tedious-to-type command sequence
from line 143 by putting all that information into Anyway, what I have in my We have now finished setting up a PKA (Public Key Authentication) setup which not just provides superior security to all of its users, all of the data stored onto a remote machine and all user accounts on this remote machine. Aside from superior security we have also created a super-comfortable way to log into a remote machine (line 160), so comfortable even that all sorts of daemons and programs might use it to, for example, carry out automated backups and things like that. TCP WrapperThis subsection can be found on another page. Port KnockingGo here. Proactive ApproachesWRITEME Iptables / Recent ModuleGo here. fail2banThis subject is covered on another page. SSHGuard
denyhosts
Nice to Know / HaveThis section covers things which are generally considered non-mandatory knowledge but which most people might find useful to know about. SSH AgentAlthough optional it is highly recommended to use SSH-agent because it
brings a great deal of comfort to the table we all want to enjoy.
SSH-agent is shipped with the sa@wks:~$ type afs; afs ssh-agent | grep bin afs is aliased to `apt-file search' openssh-client: /usr/bin/ssh-agent sa@wks:~$ So what is it that SSH-agent does? Well, in a nutshell, he remembers stuff for us and talks to a bunch of SSH related services on our behalf — it does all the repetitive and tedious talking for us. To be more precise, the SSH-agent is a program to hold private keys used for public key authentication — RSA and DSA that is. The idea is that SSH-agent is started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the SSH-agent program. Throughout this session, by using environment variables, the SSH-agent can be located and automatically used for authentication when logging into other machines using SSH. For example, if we use GIThub in order to manage source code or if we log into a remote machine using automatic PKA login then SSH-agent would provide the password to unlock the particular private key on our behalf so we are not bothered by it. However, for that to work we need to tell SSH-agent about our
identities/keypairs once per session — we do so using Once done, we can take a look at the identities currently known by the SSH-agent sa@wks:~$ ssh-add -l 8192 e9:88:82:22:fb:22:c2:38:ff:81:a3:9f:5a:26:2c:f3 Public Key (RSA) 8192 61:82:af:ea:f9:bf:b2:b5:8b:28:af:1a:af:89:80:20 Public Key (RSA) sa@wks:~$ As can be seen, I have currently two identities known by SSH-agent. From left to right, each line shows, length in bits, fingerprint in hexadecimal and key type. We could now use KeychainThe SSH-agent as well as GPG-agent keep information about our identities for as long as our current session period lasts — this information is kept in RAM (Random Access Memory) and is never written to the HDD (Hard Disk Drive). Once we end our current session e.g. by logging out, this information is lost as well and has to be provided again when we log on next time. This is bad for two reasons:
There is a tool called keychain which can ease this pain. Keychain is a manager for SSH-agent as well as GPG-agent. It allows our shells and cron jobs to share a single SSH-agent/GPG-agent process. In case of SSH, when keychain is run, it checks for a running
SSH-agent, otherwise it starts one. It saves the SSH-agent environment
variables to files like for example In addition, when keychain runs, it verifies that the key files specified on the command-line are known to SSH-agent (which is the case below), otherwise it loads them, prompting us for a password if necessary. 1 sa@wks:~$ ssh-keygen -l -f .ssh/ssh_pka_key_for_user_Markus_Gattol 2 8192 e9:44:87:72:db:27:c7:34:ff:81:a3:9d:5a:26:7c:d3 .ssh/ssh_pka_key_for_user_Markus_Gattol.pub (RSA) 3 sa@wks:~$ ssh-add -l 4 8192 e9:44:87:72:db:27:c7:34:ff:81:a3:9d:5a:26:7c:d3 Public Key (RSA) 5 sa@wks:~$ keychain 6 7 KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/ 8 Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL 9 10 * Inheriting ssh-agent (4601) 11 * Initializing /home/sa/.keychain/wks-sh file... 12 * Initializing /home/sa/.keychain/wks-csh file... 13 * Initializing /home/sa/.keychain/wks-fish file... 14 * Inheriting gpg-agent (4904) 15 * Initializing /home/sa/.keychain/wks-sh-gpg file... 16 * Initializing /home/sa/.keychain/wks-csh-gpg file... 17 * Initializing /home/sa/.keychain/wks-fish-gpg file... 18 19 sa@wks:~$ la .keychain/ 20 total 32 21 drwx------ 2 sa sa 102 2009-03-14 01:56 . 22 drwxr-xr-x 67 sa sa 4096 2009-03-14 01:56 .. 23 -rw------- 1 sa sa 73 2009-03-14 01:56 wks-csh 24 -rw------- 1 sa sa 58 2009-03-14 01:56 wks-csh-gpg 25 -rw------- 1 sa sa 129 2009-03-14 01:56 wks-fish 26 -rw------- 1 sa sa 87 2009-03-14 01:56 wks-fish-gpg 27 -rw------- 1 sa sa 103 2009-03-14 01:56 wks-sh 28 -rw------- 1 sa sa 74 2009-03-14 01:56 wks-sh-gpg 29 sa@wks:~$ keychain ssh_pka_key_for_user_Markus_Gattol 30 31 KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/ 32 Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL 33 34 * Found existing ssh-agent (4557) 35 * Found existing gpg-agent (4896) 36 * Known ssh key: /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol 37 In line 5 we start keychain, then we take a look at its files in lines
20 to 28. Now we want to tell it about one particular identity which
keychain should remember for us — we do so by manually issuing
Line 2 shows the fingerprint of this particular identity which is the same that SSH-agent currently knows about already — I had SSH-agent running already and the identity added to SSH-agent (lines 3 and 4) before I fired up keychain in line 5. If SSH-agent would not have known the identity specified in line 29, then keychain would ask us for the password at this point and take care SSH-agent stores it. 38 sa@wks:~$ grep keychain .bashrc 39 eval '/usr/bin/keychain /home/sa/.ssh/github_id_rsa /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol C0EC7E38' 40 sa@wks:~$ source ~/.bashrc 41 42 KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/ 43 Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL 44 45 * Found existing ssh-agent (4614) 46 * Found existing gpg-agent (9394) 47 * Known ssh key: /home/sa/.ssh/github_id_rsa 48 * Known ssh key: /home/sa/.ssh/ssh_pka_key_for_user_Markus_Gattol 49 * Adding 1 gpg key(s)... 50 51 sa@wks:~$ In lines 1 to 38 we triggered all actions with keychain manually.
Starting with line 39 however, we can automate things a little bit by
putting line 39 or something similar our The example above prompts us for the passwords of two SSH keys and one OpenPGP key automatically at startup/login in case the key is not already known to keychain from an earlier session. By default, the SSH-agent started by keychain is long-running and will
continue to run, even after we have logged out from the system. If we
want to change this behavior, i.e. make it more secure but less
uncomfortable then However, from my point of view, using keychain with However, using keychain with As mentioned above, keychain also supports GPG-agent in the same ways that SSH-agent is supported. By default keychain attempts to start all available agents but will fall back to only GPG-agent or only SSH-agent if either is unavailable. SSH Agent ForwardingThere is one thing about SSH-agent that is concerning with regards to security. When SSH-agent is running on a machine that cannot be trusted, someone with access to that system could extract the decrypted keys hold by SSH-agent at the time. Even though extracting the keys would be somewhat difficult, it is within the skills of professional crackers. And the mere fact that private key theft is possible means that we should take steps to guard against it happening in the first place. To formulate a strategy to protect our private SSH keys, we must first put the machines we access into one of two categories:
I have even stricter rules in this regard i.e. I consider any other hosts but my workstation and subnotebook untrusted hosts — even the various security enhanced OpenVZ VEs I use for various tasks like for example to drive my mail system. The fact that I am the only one with access to those remote machines does not change the fact that I consider them untrusted. The fact that they run on my own hardware does not change the fact that I consider them untrusted and neither does the fact that I am only using free software from Debian's official repositories. The mere fact that such hosts run software like for example an MTA (Mail Transfer Agent) which is directly connected to the Internet is enough to consider it an untrusted host. To guard our private SSH keys against extraction, SSH-agent (and thus keychain) should never be run on an untrusted host. That way, even if the system's security is compromised, there will be no SSH-agent around for the intruder to extract keys from in the first place. However, this creates a problem. If we cannot run SSH-agent on untrusted hosts, then how do we establish secure, passwordless (PKA that is) SSH connections from these systems? The answer is to only use SSH-agent and keychain on trusted hosts, and to use OpenSSH's authentication forwarding abilities to extend passwordless authentication to any untrusted hosts. In a nutshell, SSH-agent authentication forwarding works by allowing remote SSH sessions to contact an SSH-agent running on a trusted system. We will see a more example below: Advantages of SSH-agent Connection forwardingSSH-agent authentication forwarding offers a number of security advantages like for example:
The one drawback to relying on SSH-agent forwarding is that it does not solve the problem of allowing cron jobs to take advantage of PKA (RSA/DSA that is) authentication. A solution to this problem is to use keychain on our local and trusted machine and to set up all cron jobs that need PKA authentication so that they execute from our local trusted machine e.g. our workstation. If necessary, these cron jobs can use SSH to connect to remote systems to automate backups, synchronize files, and so on. Depicting SSH-agent forwardingUsually an SSH client converses with an SSH-agent on the same machine e.g. both running locally on my workstation for example. Now, by using SSH-agent forwarding, some remote SSH client can communicate with a local SSH-agent i.e. the SSH client and the SSH-agent are not running on the same machine. This is both a convenience feature, permitting our SSH clients on multiple machines to work with a single SSH-agent, and a means for enhancing security. Let us now take a look at an example in order to better understand what SSH-agent forwarding is and what it might be used for. Suppose we want to connect from our home computer (H), to a remote machine at work (W). Like many corporate computers, W is behind a network firewall and not directly accessible from the Internet, so we cannot create establish an SSH connection from H to W directly. Hmm... what can we do? We call technical support and for once, they
have good news. They say that our company maintains a gateway also
known as bastion host (B), which is accessible from the Internet and
runs an
This means we should be able to reach W by establishing an SSH connection from H to B, and then make another hop from B to W, since the firewall permits SSH traffic. Tech support gives us a user account on the bastion host B, and the problem seems to be solved... or is it? For security reasons, the company permits access to its computers only by PKA (Public Key Authentication). So, by using our private SSH key on our local home machine H, we successfully connect to bastion host B. And now we run into a roadblock — also for security reasons, the company prohibits users from storing their private SSH keys on the exposed bastion host B, since they can be stolen if B were compromised. That is bad news, since the SSH client on B needs a private SSH key to connect to our user account on W but our private key is with the SSH-agent at home on H. What now? Well, SSH-agent forwarding to the rescue we say...
SSH-agent forwarding allows a program (such as an SSH client) running on a remote machine, such as B, to access our SSH-agent on H transparently i.e. as if the SSH-agent were running on B itself. Thus, a remote SSH client running on B can now use the private keys stored held by the SSH-agent running on our local, trusted machine H as shown above. As a result, we can invoke an SSH session from B to our remote machine at work W, solving the problem. Setup SSH-agent forwardingThe prerequisite for SSH-agent forwarding to work is an up and running
PKA setup. Once this is done, we have to touch two files, namely
Before we start however, let us introduce the players on the field first:
Both, What we are going to do is to start out locally on my workstation
(
Disabled SSH-agent forwardingThis example shows Debian's default setting which is to disallow SSH-agent forwarding. 1 sa@wks:~$ echo $SSH_CONNECTION 2 3 sa@wks:~$ grep AllowAgentForwarding /etc/ssh/sshd_config 4 AllowAgentForwarding no 5 sa@wks:~$ grep ForwardAgent {/etc/ssh/ssh_,.ssh/}config 6 /etc/ssh/ssh_config:# ForwardAgent no 7 .ssh/config:ForwardAgent no 8 sa@wks:~$ ssh wks 9 Debian GNU/Linux squeeze/sid 10 11 sa@wks:~$ echo $SSH_CONNECTION 12 192.168.1.4 59506 192.168.1.4 1235 13 sa@wks:~$ ssh testing 14 15 Permission denied (publickey). 16 sa@wks:~$ exit 17 logout 18 Connection to 192.168.1.4 closed. In lines 2 and 12 we take a look at the current
SSH connection parameters — line 2 does not show anything because
there is no active SSH connection up and running. Line 12 on the other
hand shows that Lines 3 to 7 show the current settings with regards to SSH-agent
forwarding — note that those are local settings i.e. the ones active
on Line 4 is also worth a note — here we have explicitly set
Lines 6 and 7 show the settings that we would need to alter in case we
wanted to enable SSH-agent forwarding. As can be seen, I used the
per-user file to explicitly set The reason I set both explicitly even though the settings made are the same as their usual defaults is simply to provide a coherent example with all parts to the equation being present. What follows in lines 8 to 19 is exactly what we would expect — the second hop fails (line 15) because the (at that point; ssh wks) remote SSH client on ssh wks could not reach back to the SSH-agent on non-ssh wks because we prohibited it with our settings from lines 4 and 7 respectively. Enabled SSH-agent forwardingNow is the time to show what needs to be done in order to enable SSH-agent forwarding and also how it is done once all settings are made to enable it. 19 sa@wks:~$ grep AllowAgentForwarding /etc/ssh/sshd_config 20 AllowAgentForwarding yes 21 sa@wks:~$ echo $SSH_CONNECTION 22 23 sa@wks:~$ ssh wks 24 Debian GNU/Linux squeeze/sid 25 26 sa@wks:~$ pwd; whoami; hostname; echo $SSH_CONNECTION 27 /home/sa 28 sa 29 wks 30 192.168.1.4 34647 192.168.1.4 1235 31 sa@wks:~$ ssh testing 32 33 sa@wks-ve2:~$ pwd; whoami; hostname; echo $SSH_CONNECTION 34 /home/sa 35 sa 36 wks-ve2 37 192.168.1.4 34726 192.168.1.101 18689 38 sa@wks-ve2:~$ exit 39 logout 40 Connection to 192.168.1.101 closed. 41 sa@wks:~$ exit 42 logout 43 Connection to 192.168.1.4 closed. 44 sa@wks:~$ Line 20 shows the The settings for Whereas the second hop failed above (line 15) it is now working perfectly fine as can be seen from lines 31 to 37. It may be interesting to compare the SSH connection parameters to the settings in my ~/.ssh/config below which we can see, are a perfect match. For example, line 30 shows that the first hop really is just a loop on
SSH KeysThis subsection provides information with regards to SSH keys in general. Recreate SSH Keypairs for sshdThere are reasons when we want/need to recreate the SSH keypair used
by an This was one reasons, however, there may be other reasons like for example when we want a stronger (longer, more bits) keypair. Anyway, whatever the reason may be, how it is done is shown below. At first, a bit theory on SSH keys with The default is 1 wks-ve2:/home/sa# cd /etc/ssh 2 wks-ve2:/etc/ssh# la 3 total 156 4 drwxr-xr-x 2 root root 154 2009-03-08 00:24 . 5 drwxr-xr-x 54 root root 4096 2009-03-07 23:56 .. 6 -rw-r--r-- 1 root root 125749 2008-11-23 15:13 moduli 7 -rw-r--r-- 1 root root 1595 2008-11-23 15:13 ssh_config 8 -rw-r--r-- 1 root root 1895 2009-03-07 23:09 sshd_config 9 -rw------- 1 root root 668 2009-03-08 00:24 ssh_host_dsa_key 10 -rw-r--r-- 1 root root 602 2009-03-08 00:24 ssh_host_dsa_key.pub 11 -rw------- 1 root root 3239 2009-03-08 00:24 ssh_host_rsa_key 12 -rw-r--r-- 1 root root 734 2009-03-08 00:24 ssh_host_rsa_key.pub 13 wks-ve2:/etc/ssh# rm ssh_host_* 14 wks-ve2:/etc/ssh# ssh-keygen -b 4096 -t rsa -f /etc/ssh/ssh_host_rsa_key 15 Generating public/private rsa key pair. 16 Enter passphrase (empty for no passphrase): 17 Enter same passphrase again: 18 Your identification has been saved in /etc/ssh/ssh_host_rsa_key. 19 Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub. 20 The key fingerprint is: 21 3d:02:f4:54:f5:cf:bf:23:8f:3d:59:49:e2:f0:ec:12 root@wks-ve2 22 The key's randomart image is: 23 +--[ RSA 4096]----+ 24 | ... | 25 | . . | 26 | . . . | 27 | . . . +. . | 28 | . . S.=+ . o | 29 | . .Eo+ + | 30 | o.+ | 31 | o+. | 32 | o+=. | 33 +-----------------+ 34 wks-ve2:/etc/ssh# ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key 35 Generating public/private dsa key pair. 36 Enter passphrase (empty for no passphrase): 37 Enter same passphrase again: 38 Your identification has been saved in /etc/ssh/ssh_host_dsa_key. 39 Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub. 40 The key fingerprint is: 41 24:8b:25:3d:72:97:2b:11:2b:93:a7:22:57:d2:67:1e root@wks-ve2 42 The key's randomart image is: 43 +--[ DSA 1024]----+ 44 | | 45 | . | 46 | o o E | 47 | o * + o | 48 | B @ S . | 49 | . % * . | 50 | + o . | 51 | . . | 52 | | 53 +-----------------+ 54 wks-ve2:/etc/ssh# exit 55 exit 56 sa@wks-ve2:~$ As we can see from lines 9 to 12, those are the keypairs for protocol
version 2 which we are going to recreate/replace now. At first we
remove them in line 13, then we start creating the RSA keypair in line
14 and thereby specify to create a stronger keypair as is the current
default ( The same process is then repeated for the DSA keypair in lines 34
to 53. At this point we have successfully recreated the SSH keypairs
for In case we had already connected to some remote machine running this
Well, nothing bad or malicious happened — we just swapped the
machines identity by replacing its SSH keypairs used by SSH Host KeysIn order to authenticate (verify if some entity is who it claims to
be) a remote machine we use SSH keypairs as well. Each remote
machine's sa@wks:~$ ls -la /etc/ssh | grep ssh_host -rw------- 1 root root 668 2008-10-23 18:02 ssh_host_dsa_key -rw-r--r-- 1 root root 598 2008-10-23 18:02 ssh_host_dsa_key.pub -rw------- 1 root root 1675 2008-10-23 18:02 ssh_host_rsa_key -rw-r--r-- 1 root root 390 2008-10-23 18:02 ssh_host_rsa_key.pub sa@wks:~$ which are used to uniquely identify and authenticate each remote machine. Note that this is the reverse procedure to PKA — with PKA (Public Key Authentication) we make sure to authenticate the user who is about to connect to a remote machine. Once we connect to some remote machine for the first time, we get asked to check the host key fingerprint. However, how do we know if we can trust the remote machine's public host key to correctly identify the remote machine or in other words, how can we be sure the remote machine is the one it claims to be and not some machine used for an man-in-the-middle attack attempt? There are basically four choices we have, starting with the best one:
A few Hints with regards to SSH host Keys
Number of SSH Keypairs for PKAThe number of SSH keypairs that we have to administer should not be increasing with the number of remote hosts but rather with the number of users that can enter them. In other words, each user (and by user I mean person, not user account) should have one and only one public/private keypair and not one keypair for each remote host/account. If we recap, above we choose to name a keypair with regards to the person who would use it for PKA (Public Key Authentication). The ideal scenario is that every user has one particular SSH keypair
i.e. The user or the system administrator should place the user's unique public key in ~/.ssh/authorized_keys of all user accounts he should have access to. That way the user can log into all of his user accounts an remote machines by using PKA and the SSH-agent. He can also go from one account/machine to another without providing the password to unlock his private key. Some folks claim that they rather use one keypair for each remote machine instead of one keypair per person because it is more secure. Well, if done correctly then using one keypair per person for all of this accounts on possible many remote machines is not any less secure. I rather think/know because doing so (one keypair per person) we have a scalable principle at work whereas on the other hand, each person having different keys for each account/host does not scale and therefore is unmanageable which then becomes insecure. Let us do a mind game. Let us assume there is a project (cross-company or cross-agency to make it more fun) which has 600 servers and 20 persons with SSH access to those remote machines.
What mostly happens is something that can best be described as a mixture of #1 and #2 which makes it even worse because it tells us that whoever did this, has never ever spend a second thinking about that kind of thing... it just happened... In the end obeying #1 plus using a multi-user SSH setup on top or in addition to it certainly seems to be the best way to go... ~/.ssh/authorized_keysAlthough PKA is superior compared to authentication via a users password, both, in terms of comfort and in terms of security, there is one problem left we should deal with. PKA allows anyone in possession of the private key and the password to
unlock it, to establish any kind of SSH connection (login, remote
command execution, port forwarding, etc.) to the remote machine where
the However, there are a number of things that can be done with regards to
What Commands can be executed on the remote MachineWRITEME... just notes so far
Who has Access to our remote MachineAssuming the very unlikely case happens and someone manages to acquire not just the private key (what we posses) but also the password to unlock it (what we know), then usually that means that this person has access to all remote machines using this PKA keypair for SSH authentication. I leave it to the reader to imagine what the consequences of that might be... However, we can take measures to protect us from such thing simply by
using an options phrase preceding the particular public key within
If the options phrase at the beginning of a line contains the keyword
sa@wks:~$ head -n1 .ssh/authorized_keys from="*.sunoano.foo,!untrusted.sunoano.foo" ssh-rsa AAAAB [skipping a lot of characters...] k2NQ== PKA SSH keypair for user Markus Gattol; reach me at [email protected] sa@wks:~$ The hostname used will need to be the hostname reported when the IP
address of the connecting machine is looked up in the DNS (Domain Name
System). As usual, the For the example above, only if all three of the following are true
(logical AND) can we access the remote machine with this particular
public key in
The sole purpose of this phrase is to optionally increase security because, PKA by itself does not trust the network or name servers or anything but the keypair (Monkeysphere addresses this problem on a big scale). However, if somebody somehow steals the private key, the key permits an intruder to log in from anywhere in the world. This additional phrase makes using a stolen private key a lot more difficult because name servers and/or routers would have to be compromised too in order to gain access to our remote machine. More nifty OptionsAlthough sa@wks:~$ head -n1 .ssh/authorized_keys from="*.sunoano.foo,!untrusted.sunoano.foo",no-pty,no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-rsa AAAAB [skipping a lot of characters...] k2NQ== PKA SSH keypair for user Markus Gattol; reach me at [email protected] sa@wks:~$ I leave it to the reader to take a look at I would also like to note that with any SSH setup, some settings might
be redundant e.g. take for example In my opinion this kind of redundancy is acceptable/good since, what
happens if we copy the public key (with its preceding phrases) onto
some remote machine which might default to or have SSH ShortcutsI have already mentioned the use of client side configuration files above. We are now going to take a closer look at them. Before we do so, I would like to mention that I am usually not the emotional kind of person, but when it comes to SSH shortcuts, oh lord... ;-]
/etc/ssh/ssh_config respectively ~/.ssh/config
On some machines where I am part of a group of folks doing stuff
there, we keep common SSH shortcuts in So, let us take a nose dive right away and take a look at my
1 sa@wks:~$ cat .ssh/config 2 ###_ main 3 ###_. common settings 4 Host * 5 User sa 6 ControlMaster auto 7 ControlPath /tmp/ssh_connections_to_host(%h)_at_port(%p)_by_user(%r) 8 9 10 [skipping a lot of lines...] 11 12 13 ###_. local 14 15 16 [skipping a lot of lines...] 17 18 19 ###_ , wks-ve2 20 # description: wks-ve2; testing 21 Host testing 22 HostName 192.168.1.101 23 Port 18689 24 25 26 [skipping a lot of lines...] 27 28 29 ###_ , wks-ve5 30 # description: wks-ve5; testing_sec 31 Host testing_sec 32 HostName 192.168.1.104 33 Port 18689 34 IdentityFile %d/.ssh/ssh_pka_key_for_user_Markus_Gattol 35 ###_. remote 36 37 38 [skipping a lot of lines...] 39 40 41 ###_ emacs local variables 42 # Local Variables: 43 # mode: conf 44 # allout-layout: (0 : 0) 45 # End: In lines 4 to 7 we have those settings which are common for all
further host specifier blocks. This helps us with keeping a rather
small We might set sa@wks:/tmp$ type ll; ll | grep example ll is aliased to `ls -lh -I "*\.pyc"' srw------- 1 sa sa 0 Jun 8 09:32 [email protected]:15973 sa@wks:/tmp$ which is probably more intuitive as it follows the pattern of
Of course, we can override any of those settings i.e. if we choose to
put If we take a look at line 4 then we can see that I used AliasThe real benefit that comes with SSH shortcuts is that we can do the following: 46 sa@wks:~$ ssh -p 18689 [email protected] 47 48 49 [skipping a lot of lines...] 50 51 52 [email protected]'s password: 53 Linux wks-ve2 2.6.26-1-openvz-amd64 #1 SMP Sat Jan 10 18:52:53 UTC 2009 x86_64 54 55 The programs included with the Debian GNU/Linux system are free software; 56 the exact distribution terms for each program are described in the 57 individual files in /usr/share/doc/*/copyright. 58 59 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 60 permitted by applicable law. 61 sa@wks-ve2:~$ exit 62 logout 63 Connection to 192.168.1.101 closed. 64 sa@wks:~$ ssh testing 65 66 67 [skipping a lot of lines...] 68 69 70 [email protected]'s password: 71 72 73 [skipping a lot of lines...] 74 75 76 sa@wks-ve2:~$ exit 77 logout 78 Connection to 192.168.1.101 closed. 79 sa@wks:~$ Instead of issuing line 46, with all that information put into
Specifying IdentitiesWith Note that for it ( Shared Network ConnectionLast but not least, lines 6 and 7 show something that can be used to have more than one SSH sessions share a single network connection. How does that benefit us? Well, for example, if we use a basic SSH setup i.e. we authenticate ourselves using a user's password, we only have to provide the password once for several SSH sessions as long as the initially established network connection is still active — it gets closed as soon as we close the last remaining SSH session routed through that particular network connection/socket. In order to demonstrate that, I am going to log into the remote
machine 1: /dev/pts/4 sa@wks:/tmp$ tty 2: /dev/pts/4 /dev/pts/4 3: /dev/pts/4 sa@wks:/tmp$ pi ssh_connections 4: /dev/pts/4 sa@wks:/tmp$ ssh testing 5: /dev/pts/4 6: /dev/pts/4 / \ _-' 7: /dev/pts/4 _/ \-''- _ / 8: /dev/pts/4 __-' { \ 9: /dev/pts/4 / \ 10: /dev/pts/4 / "o. |o } 11: /dev/pts/4 | \ ; YOU ARE BEING WATCHED! 12: /dev/pts/4 ', 13: /dev/pts/4 \_ __\ 14: /dev/pts/4 ''-_ \.// 15: /dev/pts/4 / '-____' 16: /dev/pts/4 / 17: /dev/pts/4 _' 18: /dev/pts/4 _-' 19: /dev/pts/4 20: /dev/pts/4 21: /dev/pts/4 This computer system is the private property of its owner, whether individual, corporate or government. It is 22: /dev/pts/4 for authorized use only. Users (authorized or unauthorized) have no explicit or implicit expectation of 23: /dev/pts/4 privacy. 24: /dev/pts/4 25: /dev/pts/4 Any or all uses of this system and all files on this system may be intercepted, monitored, recorded, copied, 26: /dev/pts/4 audited, inspected, and disclosed to your employer, to authorized site, government, and law enforcement 27: /dev/pts/4 personnel, as well as authorized officials of government agencies, both domestic and foreign. 28: /dev/pts/4 29: /dev/pts/4 By using this system, the user consents to such interception, monitoring, recording, copying, auditing, 30: /dev/pts/4 inspection, and disclosure at the discretion of such personnel or officials. 31: /dev/pts/4 32: /dev/pts/4 33: /dev/pts/4 UNAUTHORIZED OR IMPROPER USE OF THIS SYSTEM MAY RESULT 34: /dev/pts/4 IN CIVIL AND CRIMINAL PENALTIES AND ADMINISTRATIVE OR 35: /dev/pts/4 DISCIPLINARY ACTION, AS APPROPRIATE !! 36: /dev/pts/4 37: /dev/pts/4 38: /dev/pts/4 By continuing to use this system you indicate your awareness of and consent to these terms and conditions of 39: /dev/pts/4 use. LOG OFF IMMEDIATELY if you do not agree to the conditions stated in this warning. However, if you are 40: /dev/pts/4 authorized personal with no bad intentions please continue. Have a nice day! :-) 41: /dev/pts/4 42: /dev/pts/4 [email protected]'s password: 43: /dev/pts/4 Linux wks-ve2 2.6.26-1-openvz-amd64 #1 SMP Sat Jan 10 18:52:53 UTC 2009 x86_64 44: /dev/pts/4 45: /dev/pts/4 The programs included with the Debian GNU/Linux system are free software; 46: /dev/pts/4 the exact distribution terms for each program are described in the 47: /dev/pts/4 individual files in /usr/share/doc/*/copyright. 48: /dev/pts/4 49: /dev/pts/4 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 50: /dev/pts/4 permitted by applicable law. 51: /dev/pts/4 sa@wks-ve2:~$ w 52: /dev/pts/4 19:49:28 up 4:40, 1 user, load average: 0.00, 0.00, 0.00 53: /dev/pts/4 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT 54: /dev/pts/4 sa pts/0 192.168.1.4 19:48 0.00s 0.00s 0.00s w 55: /dev/pts/4 sa@wks-ve2:~$ w 56: /dev/pts/4 19:50:03 up 4:40, 2 users, load average: 0.00, 0.00, 0.00 57: /dev/pts/4 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT 58: /dev/pts/4 sa pts/0 192.168.1.4 19:48 0.00s 0.04s 0.04s w 59: /dev/pts/4 sa pts/1 192.168.1.4 19:49 18.00s 0.00s 0.00s -sh 60: /dev/pts/4 sa@wks-ve2:~$ exit 61: /dev/pts/4 logout 62: /dev/pts/4 Connection to 192.168.1.101 closed. 63: /dev/pts/4 sa@wks:/tmp$ As can be seen, the screendump from Then we use There we use In other words, at this point in time, we have not even started using the second terminal (/dev/pts/2) in order to create another SSH session using the same network connection. Switching to /dev/pts/2 now... After issuing line 51: /dev/pts/4 we start using the second terminal
window. Line 4: /dev/pts/2 shows that there is a network socket in
place now — compare this line with line 7 from The real deal is with line 5: /dev/pts/2 — after hitting 1: /dev/pts/2 sa@wks:~$ tty 2: /dev/pts/2 /dev/pts/2 3: /dev/pts/2 sa@wks:~$ ls -l /tmp/ | grep ssh_con 4: /dev/pts/2 srw------- 1 sa sa 0 2009-03-11 20:48 ssh_connections_to_host(192.168.1.101)_at_port(18689)_by_user(sa) 5: /dev/pts/2 sa@wks:~$ ssh testing 6: /dev/pts/2 sa@wks-ve2:~$ w 7: /dev/pts/2 19:49:45 up 4:40, 2 users, load average: 0.00, 0.00, 0.00 8: /dev/pts/2 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT 9: /dev/pts/2 sa pts/0 192.168.1.4 19:48 10.00s 0.00s 0.00s -sh 10: /dev/pts/2 sa pts/1 192.168.1.4 19:49 0.00s 0.00s 0.00s w 11: /dev/pts/2 sa@wks-ve2:~$ exit 12: /dev/pts/2 logout 13: /dev/pts/2 Shared connection to 192.168.1.101 closed. 14: /dev/pts/2 sa@wks:~$ ls -l /tmp/ | grep ssh_con 15: /dev/pts/2 sa@wks:~$ Switching back to /dev/pts/4 now... Then we issued line 55: /dev/pts/4, same result as for line 6:
/dev/pts/2. Finally we exit from Switching back to /dev/pts/2 now... As we have exit Global Overrides and Global DefaultsThe For example, the The version of
1 sa@wks:~$ cat .ssh/config 2 ###_ main 3 ###_. global overrides 4 Host * 5 User sa 6 ProxyCommand monkeysphere ssh-proxycommand %h %p 7 ControlMaster auto 8 ControlPath /tmp/ssh_connections_to_host(%h)_at_port(%p)_by_user(%r) 9 ###_. local 10 11 12 [skipping a lot of lines...] 13 14 15 ###_ , wks 16 # description: workstation 17 Host wks 18 HostName 192.168.1.4 19 Port 1235 20 ForwardAgent yes 21 ###_ , wks-ve2 22 # description: wks-ve2; testing 23 Host testing 24 HostName 192.168.1.101 25 Port 18689 26 ###_ , wks-ve5 27 # description: wks-ve5; testing_sec 28 Host testing_sec 29 HostName foo.bar.com 30 Port 18689 31 IdentitiesOnly no 32 ###_. remote 33 34 35 [skipping a lot of lines...] 36 37 38 ###_. global defaults 39 Host * 40 ForwardAgent no 41 IdentitiesOnly yes 42 IdentityFile %d/.ssh/keypairs/ssh_pka_key_for_user_Markus_Gattol 43 ###_ emacs local variables 44 # Local Variables: 45 # mode: conf 46 # allout-layout: (0 : 0) 47 # End: 48 49 sa@wks:~$ What we can see in lines 2 to 47 is the current/final version of my
The rationale for those two stanzas is simple: The matching algorithm that applies to user client side configuration files is first-match i.e. any configuration value is only changed the first time it is set. Thus, global overrides should be at the beginning of the configuration file, followed by host-specific definitions and defaults at the end. Both global stanzas need to have a leading The opposite is the case for global defaults as we have a good example
with lines 20 and 40 — only for host Another pretty nice-to-have global default can be seen in line 42. This one saves us a lot troubles with the notorious MaxAuthTries keyword plus it makes actually a lot of sense to have one, and only one, default UID for PKA. ssh-argv0This one also allows for shortcut behavior. For it to work, we create
a symbolic link from our hostname to the binary 1 sa@wks:/tmp$ ln -s $(which ssh-argv0) testing_sec 2 sa@wks:/tmp$ pi testing 3 lrwxrwxrwx 1 sa sa 18 2009-03-12 14:01 testing_sec -> /usr/bin/ssh-argv0 4 sa@wks:/tmp$ ./testing_sec uptime 5 6 7 [skipping a lot of lines...] 8 9 10 13:02:46 up 21:53, 0 users, load average: 0.00, 0.00, 0.00 11 sa@wks:/tmp$ ssh testing_sec uptime 12 13 14 [skipping a lot of lines...] 15 16 17 13:03:00 up 21:53, 0 users, load average: 0.00, 0.00, 0.00 18 sa@wks:/tmp$ We use an alias in my Note that this is equal to line 11 where we use standard ssh syntax
with an alias from As a result, lines 10 and 17, both show the uptime on the remote
machine If our username is different on the remote SSH machine as compared to
the local machine, then we would use We are done. Last thing for me to say is that I mostly use
~/.ssh/config shortcuts instead of MiscellaneousThis section is used to drop anything SSH related here but which on its own does not deserve a section on its own. The subsections here must not necessarily have anything to do with each another, except for the fact that SSH may be the only thing they have in common. Check default ConfigurationWhat do we do if we want to know the default and/or current Reload vs RestartIf we make changes to the server-side configuration and want them to become active, there are two things we can do:
The latter is preferable since it keeps existing connections alive
e.g. if we mirror tons of data using Unison or rsync/scp. What happens
can be seen if we take a look at sa@wks:~$ grep -A4 -m1 reload /etc/init.d/ssh reload|force-reload) check_for_no_start check_config log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd" if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd; then sa@wks:~$ As we can see, By convention, programs/daemons are to be programmed so that if
received When we do not specify any signal in particular,
Figuring Source and Destination IP and PortSometimes we want to know the basic connection parameters for some established SSH connection: sa@rh0:~$ echo $SSH_CONNECTION 233.89.77.43 24456 126.32.55.45 35678 sa@rh0:~$
Getting rid of post-login MessagesThis is how it looks like by default when we login to some machine via SSH: 1 sa@sub:~$ ssh rh0 2 3 [email protected]'s password: 4 Linux rh0 2.6.25-2-amd64 #1 SMP Mon Jul 14 11:05:23 UTC 2008 x86_64 5 6 The programs included with the Debian GNU/Linux system are free software; 7 the exact distribution terms for each program are described in the 8 individual files in /usr/share/doc/*/copyright. 9 10 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 11 permitted by applicable law. 12 Last login: Mon Jul 28 09:41:59 2008 from xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 13 sa@rh0:~$ As can be seen in lines 4 to 11 we get the message from sa@rh0:~$ grep ^Print /etc/ssh/sshd_config PrintMotd no PrintLastLog no sa@rh0:~$ Non-interactive SSH Password AuthenticationThis is just mentioned for the sake of completeness. There is this
package called In short, making password authentication using a user's password somewhat work/look like PKA (Public Key Authentication) is what it does. While this works, it is not recommended... SSH has good reasons to make password based authentication interactive! Those who would like to have a non-interactive SSH setup should rather
use PKA instead of using Scan Network for sshd Versionssa@sub:~$ acs scanssh scanssh - get SSH server versions for an entire network sa@sub:~$ ScanSSH scans the given addresses and networks for running services. It mainly allows the detection of open proxies and Internet services. For known services, ScanSSH will query their version number and displays the results in a list. autosshautossh can be used to automatically restart SSH sessions and tunnels.
See sshmAnother, rather lightweight, shortcut thingy. See Securing SCP and SFTPThe packages What they do in a nutshell are basically restricting the commands available to SCP and SFTP users. For example what we can do, amongst other things, is providing access to remote users to both read and write local files but without providing them any remote execution privileges. SSHFSPlease go here for an example of how to use SSHFS (Secure SHell FileSystem). Note that SSHFS makes use of FUSE (Filesystem in User-space). SSH TunnelingWRITEME
SOCKS
TORWRITEME |