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 [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 Digital Intelligence Any patches and ideas are greatly welcomed on the above address.