Secure Logging Over a Network

Log system activities over a TCP network securely by interfacing the existing syslog dæmon with secure shell using simple Perl scripts.
Configuring ssh on Server and Client Side

Even if this should look like the easier step to accomplish, there are a few things you must pay attention to, so that an intruder, who has discovered the remote logging facility, won't be able to use it as a way to break in to the logger machine. First of all, you must generate your key pair on the network machine from which you're sending the logs by using the ssh-keygen utility. You do not have to set a password (just press return twice at the prompt) to this pair of keys (that should be used just for the logging program), so the script will not have to prompt you for it each time it starts.

With ssh2, you'll have to specify that you're going to use this newly created private key as a possible key to identify yourself. Add it to your ~/.ssh2/identification file by adding a new line with the IdKey statement, followed by the key name. (Alternatively, you could force this on the command line to ssh in the script.) Now, you'll have to transfer the public key to the system where you're going to store the logs, and add it to that user's authorized key file. (Usually ~/.ssh/authorized_keys in ssh1, where each line contains a key. In ssh2, copy the key to your ~/.ssh2 directory, then add an entry to your authorization file, ~/.ssh2/authorization by default, in the usual syntax Key key_filename.) This instructs sshd on that machine to authenticate anyone using the private key that couples with that public key without further checks.

Depending on the ssh configuration, you should normally have to log only once using this new generated key. At the first connection, ssh will have to add the key of the new host to your known_hosts files (by default, not an automatic task); it will prompt you to confirm that you would like to add the key. Pay attention to the authorization and key files permissions: they must be readable and writable only to the user—for security reasons first of all, but also because ssh will refuse to accept connections with such badly configured keys. Try logging in verbose mode if any problem occurs, since this will tell you exactly why the connection was not permitted.

A complete login over ssh could be done this way with that key. This would be very dangerous, so finally you must put some important restrictions on the use of the key. First, specify from which hosts this key could be used with the from= directive, so if someone were to steal the private key, he couldn't log on from any place other than the ones you specify. Second, inhibit the allocation of a pty with no-pty. Finally, limit the use of this key to just appending something to the logging file; that is, the command the Perl scripts execute on the remote machine. This is done using the command= directive and should be:

command="cat >>

At this point, you can be quite sure that nothing more than appending to the log file can be done, and you can use your normal account on some machine as a log storer, since this won't open you to any danger (other than having your space filled with logs), if the log key is correctly restricted by ssh. In ssh2, you'll have to add just the command restriction option, using the Command directive in your authorization file. Check out the man page for exact information on the syntax.

Since many sshd installations check the TCP wrappers files before allowing a connection, make sure the hosts from which you wish to connect are allowed to do so. As a user, be sure you don't have any .shosts or .rhosts files from the machine you are logging. If present, everything would seem to work (since authorizations would be done through these, if allowed by the dæmon), but the system would be very insecure.

Configuring syslogd

The first thing we have to do is create the named pipe needed for the communication between the syslogd and our script. This is easy; use the mkfifo command with the full path name of the named pipe as the parameter to create it. Now you must tell syslogd the kind of messages it should send to that pipe, using the standard syslogd syntax:

log_facility:    | /

It would be a good idea to send over the network the usual authorization tasks (auth.* and authpriv.*), critical messages (*.crit and *.emerg) and important kernel network-related messages (especially if you're filtering packets or something like that). It is very important to choose all the needed facilities to have a good overview of the system status. This changes, of course, from system to system (the facilities used could also be compilation, and thus distribution-dependent), so be sure to test it thoroughly.