|
Related Reading
Linux Security Cookbook |
Editor's note: The authors of Linux Security Cookbook have selected a number of recipes from their book to present here. These recipes are organized into basic, intermediate, and advanced categories. This week's set consists of three recipes of a basic flavor. Over the next two weeks we'll present the intermediate and then advanced recipes. There'll be something for everyone here. Enjoy.
Author's note: SSH is a protocol for secure, remote logins and file copying; and OpenSSH, provided with most Linux distributions, is its most popular implementation. This recipe, selected from Chapter 6 on "Protecting Outgoing Network Connections," shows you how to use public-key authentication to prove your identity to a remote OpenSSH server, a technique more secure than using login passwords.
You want to set up public-key authentication between an OpenSSH client and an OpenSSH server.
Generate a key if necessary:
$ mkdir -p ~/.ssh If it doesn't already exist
$ chmod 700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t dsa
Copy the public key to the remote host:
$ scp -p id_dsa.pub remoteuser@remotehost:
Password: ********
Log into the remote host and install the public key:
$ ssh -l remoteuser remotehost
Password: ********
remotehost$ mkdir -p ~/.ssh If it doesn't already exist
remotehost$ chmod 700 ~/.ssh
remotehost$ cat id_dsa.pub >> ~/.ssh/authorized_keys (Appending)
remotehost$ chmod 600 ~/.ssh/authorized_keys
remotehost$ mv id_dsa.pub ~/.ssh Optional, just to be organized
remotehost$ logout
Log back in via public-key authentication:
$ ssh -l remoteuser remotehost
Enter passphrase for key '/home/smith/.ssh/id_dsa': ********
OpenSSH public keys go into the file ~/.ssh/authorized_keys. Older versions of OpenSSH, however, require SSH-2 protocol keys to be in ~/.ssh/authorized_keys2.
Public-key authentication lets you prove your identity to a remote host using a cryptographic key instead of a login password. SSH keys are more secure than passwords because keys are never transmitted over the network, whereas passwords are (albeit encrypted). Also, keys are stored encrypted, so if someone steals yours, it's useless without the passphrase for decrypting it. A stolen password, on the other hand, is immediately usable.
An SSH "key" is actually a matched pair of keys stored in two files. The private or secret key remains on the client machine, encrypted with a passphrase. The public key is copied to the remote (server) machine. When establishing a connection, the SSH client and server perform a complex negotiation based on the private and public key, and if they match (in a cryptographic sense), your identity is proven and the connection succeeds.
To set up public-key authentication, first create an OpenSSH key pair, if you don't already have one:
$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/smith/.ssh/id_dsa): <RETURN>
Enter passphrase (empty for no passphrase): *******
Enter same passphrase again: *******
Your identification has been saved in id_dsa
Your public key has been saved in id_dsa.pub.
The key fingerprint is: 76:00:b3:e8:99:1c:07:9b:84:af:67:69:b6:b4:12:17
smith@mymachine
Copy the public key to the remote host using password authentication:
$ scp ~/.ssh/id_dsa.pub remoteuser@remotehost:
Password: *********
id_dsa.pub 100% |*****************************| 736 00:03
Log into the remote host using password authentication:
$ ssh -l remoteuser remotehost
Password: ********
If your local and remote usernames are the same, you can omit the -l remoteuser part and just type ssh
remotehost.
On the remote host, create the ~/.ssh directory if it doesn't already exist and set its mode appropriately:
remotehost$ mkdir -p ~/.ssh
remotehost$ chmod 700 ~/.ssh
Then append the contents of id_dsa.pub to ~/.ssh/authorized_keys:
remotehost$ cat id_dsa.pub >> ~/.ssh/authorized_keys (Appending)
remotehost$ chmod 600 ~/.ssh/authorized_keys
Log out of the remote host and log back in. This time you'll be prompted for your key passphrase instead of your password:
$ ssh -l remoteuser remotehost
Enter passphrase for key '/home/smith/.ssh/id_dsa': *******
and you're done! If things aren't working, rerun ssh
with the -v option (verbose) to help diagnose the
problem.
The SSH server must be configured to permit public-key authentication, which is the default:
/etc/ssh/sshd_config:
PubkeyAuthentication yes If no, change it and restart sshd
For more convenience, you can eliminate the passphrase prompt using ssh-agent [Recipe 6.9] and create host
aliases in ~/.ssh/config. [Recipe 6.12]
ssh(1), scp(1), ssh-keygen(1).
SSH-2 Key File FormatsThe two major implementations of SSH—OpenSSH and SSH Secure Shell ("SSH2")—use different file formats for SSH-2 protocol keys. (Their SSH-1 protocol keys are compatible.) OpenSSH public keys for the SSH-2 protocol begin like this:
or:
SSH Secure Shell public keys for the SSH-2 protocol look like this:
These keys are installed differently too. For OpenSSH, you insert your public keys into the file ~/.ssh/authorized_keys. For SSH Secure Shell, you copy your public key files into the directory ~/.ssh2 and reference them in the file ~/.ssh2/authorization by name:
As for private keys, OpenSSH has no special requirements for installation, but SSH Secure Shell does. You must reference them in the file ~/.ssh2/identification by name: |
|
Author's note: If someone steals one of your backup tapes, your sensitive information could become compromised. This recipe, excerpted from Chapter 7 on "Protecting Files," illustrates how to encrypt the contents of a backup tape using GnuPG (gpg), a popular encryption program for Linux and other operating systems.
You want to create an encrypted backup.
Method 1: Pipe through gpg.
To write a tape:
$ tar cf - mydir | gpg -c | dd of=/dev/tape bs=10kTo read a tape:
$ dd if=/dev/tape bs=10k | gpg --decrypt | tar xf -
To write an encrypted backup of directory mydir onto a CD-ROM:
#!/bin/sh
mkdir destdir
tar cf - mydir | gpg -c > destdir/myfile.tar.gpg
mkisofs -R -l destdir | cdrecord speed=${SPEED} dev=${SCSIDEVICE} -
where SPEED and SCSIDEVICE
are specific to your system; see cdrecord(1).
Method 2: Encrypt files separately.
Make a new directory containing links to your original files:
$ cp -lr mydir newdir
In the new directory, encrypt each file, and remove the links to the unencrypted files:
$ find newdir -type f -exec gpg -e '{}' \; -exec rm '{}' \;
Back up the new directory with the encrypted data:
$ tar c newdirMethod 1 produces a backup that may be considered fragile: one big encrypted file. If part of the backup gets corrupted, you might be unable to decrypt any of it.
Method 2 avoids this problem. The cp -l option creates
hard links, which can only be used within a single filesystem.
If you want the encrypted files on a separate filesystem, use symbolic links instead:
$ cp -sr /full/path/to/mydir newdir
$ find newdir -type l -exec gpg -e '{}' \; -exec rm '{}' \;
Note that a full, absolute pathname must be used for the original directory in this case.
gpg does not preserve the owner, group, permissions, or
modification times of the files. To retain this information in your backups,
copy the attributes from the original files to the encrypted files, before the
links to the original files are deleted:
# find newdir -type f -exec gpg -e '{}' \; \
-exec chown --reference='{}' '{}.gpg' \;
-exec chmod --reference='{}' '{}.gpg' \;
-exec touch --reference='{}' '{}.gpg' \;
-exec rm '{}' \;
Method 2 and the CD-ROM variant of method 1 use disk space (at least temporarily) for the encrypted files.
gpg(1), tar(1), find(1), cdrecord(1).
|
Author's note: Each system log file in /var/log contains different information about your running Linux system. This recipe from Chapter 9 on "Testing and Monitoring" shows how to merge multiple log files, keeping the lines in sorted order by timestamp, which is trickier than you might think.
You want to merge a collection of log files into a single, chronological log file.
#!/bin/sh
perl -ne \
'print $last, /last message repeated \d+ times$/ ? "\0" : "\n" if $last;
chomp($last = $_);
if (eof) {
print;
undef $last;
}' "$@" | sort -s -k 1,1M -k 2,2n -k 3,3 | tr '\0' '\n'
The system logger automatically prepends a timestamp to each message, like this:
Feb 21 12:34:56 buster kernel: device eth0 entered promiscuous mode
To merge log files, sort each one by its timestamp entries, using the first three fields (month, date, and time) as keys.
A complication arises because the system logger inserts "repetition messages" to conserve log file space:
Feb 21 12:48:16 buster last message repeated 7923 times
The timestamp for the repetition message is often later than the last message. It would be terribly misleading if possibly unrelated messages from other log files were merged between the last message and its associated repetition message.
To avoid this, our Perl script glues together the last message with a subsequent repetition message (if present), inserting a null character between them: this is reliable because the system logger never writes null characters to log files. The script writes out the final line before the end of each file and then forgets the last line, to avoid any possibility of confusion if the next file happens to start with an unrelated repetition message.
The sort command sees these null-glued
combinations as single lines, and keeps them together as the files are merged.
The null characters are translated back to newlines after the files are sorted,
to split the combinations back into separate lines.
We use sort -s to avoid sorting entire lines if all of
the keys are equal: this preserves the original order of messages with the same
timestamp, at least within each original log file.
If you have configured the system logger to write messages to multiple log
files, then you may wish to remove duplicates as you merge. This can be done by
using sort -u instead of -s, and
adding an extra sort key -k 4 to compare the message
contents. There is a drawback, however: messages could be rearranged if they
have the same timestamp. All of the issues related to sort
-s and -u are consequences of the one-second resolution
of the timestamps used by the system logger.
We'll note a few other pitfalls related to timestamps. The system logger does not record the year, so if your log files cross a year boundary, then you will need to merge the log files for each year separately, and concatenate the results. Similarly, the system logger writes timestamps using the local time zone, so you should avoid merging log files that cross a daylight saving time boundary, when the timestamps can go backward. Again, split the log files on either side of the discontinuity, merge separately, and then concatenate.
If your system logger is configured to receive messages from other machines, note that the timestamps are generated on the machine where the log files are stored. This allows consistent sorting of messages even from machines in different time zones.
sort(1).
Be sure to check back here next week for recipes from Linux Security Cookbook on how to restrict access to network services by time of day, and on how to use sudo to permit read-only access to a shared file.
Return to Linux DevCenter.
Copyright © 2009 O'Reilly Media, Inc.