Tighter SSH Security with Two-Factor Authentication
We need to close a potential vulnerability before using this system in the wild.
Using ssh-agent and agent forwarding allows the remote SSH server to query the private key stored on your local computer. However, if you use this system to log in to multiple computers, an intruder on one machine can potentially highjack those keys to break in to another machine. In that case, this system could be more dangerous than one using static passwords.
To illustrate the problem, let's expand our example network from two to three nodes by adding machine3 to the mix. Create key pairs for both bob and root on machine3, as described in Examples 1 and 2, and add root's private key to ssh-agent on machine1.
Now, ssh to machine3 as bob using the agent-forwarding option -A. Run ssh-add -l, and you can see the public keys for both machine2 and machine3:
2048 fa:5c:4b:73:88:...: ... /media/usbdisk/key-rsa-root@machine2 (RSA) 2048 26:b6:e3:99:c1:...: ... /media/usbdisk/key-rsa-root@machine3 (RSA)
In this example, ssh-agent on machine1 caches the private keys for machine2 and machine3. This single agent allows us to log in as root on either computer. However, using the single agent also potentially allows an intruder on machine2 to log in as root on machine3 and vice versa. This is not good.
Fortunately, we can fix this problem by using the ssh-add -c option; we can add additional security by using individual ssh-agent instances to store one root key for each remote machine. The -c option tells ssh-agent to have the user confirm each use of a cached key. Devoting one ssh-agent instance per host prevents any as yet unknown ssh-agent vulnerability from exposing one machine's key to another.
Using the ssh-add confirm option is easy; simply set the -c option whenever adding a key to ssh-agent. Let's give it a try. Start two agents on machine1, specifiying predefined sockets:
ssh-add -c /media/usbdisk/key-rsa-root@machine2 ssh-add -c /media/usbdisk/key-rsa-root@machine3
You'll be asked to confirm use of the key when you ssh to machine2 and machine3.
You also can use separate ssh-agents to store each key. Let's give it a try; start two agents on machine1, specifying predefined sockets:
ssh-agent -a /tmp/ssh-agent-root@machine2 ssh-agent -a /tmp/ssh-agent-root@machine3
Once again, I'm using an arbitrary yet descriptive naming convention. Set the environmental variable, and add the key for machine2:
export SSH_AUTH_SOCK=/tmp/ssh-agent-root@machine2 ssh-add -c /media/usbdisk/key-rsa-root@machine2
Repeat this process for machine3, making the appropriate substitutions:
export SSH_AUTH_SOCK=/tmp/ssh-agent-root@machine3 ssh-add -c /media/usbdisk/key-rsa-root@machine3
Now, log in to machine3 (we'll go to machine3 at this point as we just set the SSH_AUTH_SOCK variable to point to machine3's agent):
ssh -A -i /media/usbdisk/key-rsa-bob@machine2 bob@machine3
Run the following command to see what keys you can query on machine1:
You see only the key for root on machine3.
Exit from machine3, change the environmental variable to the machine2 ssh-agent socket, and log in to machine2:
export SSH_AUTH_SOCK=/tmp/ssh-agent-root@machine2 ssh -A -i /media/usbdisk/key-rsa-bob@machine2 bob@machine2
Check your keys again:
Checking your keys on machine2 and machine3 reveals only the root key for that machine. In the previous example, by using a single ssh-agent, you would have seen the keys for both machine2 and machine3.
Using separate ssh-agent instances for each machine you log in to requires more work.
Resetting the SSH_AUTH_SOCK variable every time you want to log in to another machine is impractical. To simplify the process, I've written a simple script tfssh (two-factor ssh) to simplify the process. Its syntax is:
tfssh [username@]host [keydir]
The script [Listing 1 on the LJ FTP site at ftp.linuxjournal.com/pub/lj/listings/issue152/8957.tgz] starts ssh-agent when necessary, sets the environmental variable, adds the root keys to ssh-agent and logs in to the remote machine as the user. You also can tell tfssh to look in an arbitrary directory ([keydir]) for its keys and also set a key timeout for the key cache.
Practical Task Scheduling Deployment
One of the best things about the UNIX environment (aside from being stable and efficient) is the vast array of software tools available to help you do your job. Traditionally, a UNIX tool does only one thing, but does that one thing very well. For example, grep is very easy to use and can search vast amounts of data quickly. The find tool can find a particular file or files based on all kinds of criteria. It's pretty easy to string these tools together to build even more powerful tools, such as a tool that finds all of the .log files in the /home directory and searches each one for a particular entry. This erector-set mentality allows UNIX system administrators to seem to always have the right tool for the job.
Cron traditionally has been considered another such a tool for job scheduling, but is it enough? This webinar considers that very question. The first part builds on a previous Geek Guide, Beyond Cron, and briefly describes how to know when it might be time to consider upgrading your job scheduling infrastructure. The second part presents an actual planning and implementation framework.
Join Linux Journal's Mike Diehl and Pat Cameron of Help Systems.
Free to Linux Journal readers.View Now!
|The Firebird Project's Firebird Relational Database||Jul 29, 2016|
|Stunnel Security for Oracle||Jul 28, 2016|
|SUSE LLC's SUSE Manager||Jul 21, 2016|
|My +1 Sword of Productivity||Jul 20, 2016|
|Non-Linux FOSS: Caffeine!||Jul 19, 2016|
|Murat Yener and Onur Dundar's Expert Android Studio (Wrox)||Jul 18, 2016|
- Stunnel Security for Oracle
- The Firebird Project's Firebird Relational Database
- SUSE LLC's SUSE Manager
- Murat Yener and Onur Dundar's Expert Android Studio (Wrox)
- Managing Linux Using Puppet
- My +1 Sword of Productivity
- Non-Linux FOSS: Caffeine!
- Google's SwiftShader Released
- SuperTuxKart 0.9.2 Released
- Doing for User Space What We Did for Kernel Space