Overview
========

The icmpreboot package consists of a serverside kld module icmpreboot.ko 
and a clientside program icmp_reboot_client. This package enables a server
to be rebooted through the use of icmp packets. An authentication method is
provided, authentication information is transmitted encrypted over the 
network.

Two reboot commands are currently implemented, a CTRL-ALT-DEL (nice) kind 
of reboot with killing of all processes and syncing of the disks before 
the reboot, and a hard reboot without sync, for those times you really 
need it. Other commands can easily be added to the source.

Supported platforms
-------------------
The icmpreboot kld module has been tested and found working on
 . FreeBSD 3.4
 . FreeBSD 3.5
 . FreeBSD 4.0
Other versions of FreeBSD might also work (at least FreeBSD 3.0 is needed,
older versions do not support the new kld module structure).


Protocol
========
The client first asks a Challenge from the server. The server replies a
newly generated (random) md5 string, the key is stored in a table in the
kernel. The client should now generate a key the following way:

	md5( concat( md5(Password), Challenge ) )

Here Password is the password given by the user and Challenge is the server
replied challenge key. The resulting key is send together with a command to
the server. The server now authenticates the key (looks it up and compares
it to the stored key) and if correct issues the command.

Note; an authentication key is valid only one time. The server stored key 
expires in 300 seconds. Only CHALL_TS (currently 4) clients can request a 
challenge from the server. A new client is allowed after an old key 
expires. The expired key and client ip address are replaced.


ICMP packet structure
=====================
The icmpreboot package uses icmp packets as the transmission medium. In 
order to differentiate the icmpreboot packets from any existing icmp 
packets icmp->icmp_type is set to 197 for client to server packets and 
198 for server to client packets. Every packet starts with a magic number 
for extra safety. Packets not having their icmp_type set to 197 or 198 or
without the magic number are handed over to the normal icmp_input kernel 
routine. The kernel module uses the standard icmp_reflect routine to send 
the packet back to the client.


Server kld module
=================

Building
--------
In order to customize the local build directory you must create a 
Makefile.local. In this Makefile you can set the make flags for the local 
system, for example:
CFLAGS+= -DDEBUG -DFREEBSD4

-DDEBUG    is a safety flag in order to safely test the module, without 
           loading any reboot code into the kernel.

-DFREEBSD4 is needed when compiling on FreeBSD 4.x

To build do the following:

 % cd kld
 % umask 077

(See the password issue below.)

 % make depend

You are asked for a password. This will be the password the server will 
respond to.

 % make

The module should have been compiled. Copy it to a safe place and chmod 700
it (the password can be read from the source and from the binary, see
below).

 % make clean

In order to load the module and activate it use the command kldload:

 % kldload ./icmpreboot.ko

To unload it from the kernel thus deactivating it use kldunload:

 % kldunload icmpreboot.ko

Any output the module is giving can be read from /var/log/messages.

Security
--------
The password as created by the makefile and is stored in password.h. The
password is translated to its MD5 form, however, it is still a plaintext
password (the server can be rebooted using this MD5 string!). For security
reasons it is best to chmod 700 the created module and make clean the 
build directory. The password, nor the MD5 password string is ever
transmitted in cleartext over the network.

 - TODO -
 . Public key (two way) encryption in order to send an encrypted password 
   to the server, there decrypt it and crypt() (one way) it again to 
   match it against the stored password (like the /etc/password way). In 
   this way there is no plaintext password stored anywhere.

 . The server should read the password string from a file. This is more 
   flexible and secure.
   Q: Is it possible to read in a file from the kernel? How to go about?

 . The lookup of the icmp_input slot in the inetsw table should be more
   failsafe. It should at least verify the correct location.

 . A port to other BSDs or even linux might be possible...


Client program
==============
The client program takes at least the server hostname as an argument. Two
commands are currently implemented in the server, Shutdown and
Reboot_NO_sync. Shutdown is the default when omitted.

Usage: icmp_reboot_client <hostname> [Shutdown|Reboot_NO_sync]
 . Shutdown       The cleanest way to reboot (default).
 . Reboot_NO_sync Very hard reboot, no sync of the disks. Your last resort!

Building
--------
Just type make.

 - TODO -
 . A port of the client to windows would be handy and pretty straightforward
   to do.


Author
======
Rob Kaandorp <rob@di.nl>
Digital Intelligence

Any patches and ideas are greatly welcomed on the above address.
