From 8e9a5ee678c66da902b28ae935f805fffdc09994 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sat, 6 Jun 2015 11:30:38 +0200 Subject: [PATCH] Update README on Inetd services and cleanup TODO. Signed-off-by: Joachim Nilsson --- README.md | 78 +++++++++++++++++++--------- TODO.md | 151 ++---------------------------------------------------- 2 files changed, 59 insertions(+), 170 deletions(-) diff --git a/README.md b/README.md index 48e1f12a..b2a29a6e 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,16 @@ Features Start, monitor and restart processes (daemons) if they fail. + **Inetd** Finit comes with an `inetd` server built-in. No need to maintain a separate config file for services that you want to start on demand. +All inetd services started can be filtered per port and inbound +interface, reducing the need for a full blown firewall. + + **Runlevels** Runlevels are optional in Finit, but support for [SysV runlevels][5] is @@ -72,6 +77,7 @@ followed by the desired run-time runlevel. Runlevel S can be started in sequence by using `run [S] cmd`. Changing runlevels at runtime is done like any other init, e.g. init 4. + **Plugins** Finit plugins can be either *boot hooks* into different stages of the @@ -86,6 +92,7 @@ Plugin capabilities: * Task/Run callbacks -- a one-shot commands, executed in sequence * Hooks -- hook into the boot at predefined points to extend finit * I/O -- listen to external events and control finit behavior/services +* Inetd -- extend with internal inetd services Extensions and functionality not purely related to what an `/sbin/init` needs to start a system are available as a set of plugins that either @@ -151,6 +158,7 @@ Syntax: Launch daemon on demand when a client initiates a connection to `SVC`. Services (SVC) are specified in the standard UNIX `/etc/services` file. With optional filtering for `iface` and possible custom `port`. + The following example opens port 2323 and only allows inbound telnet connections from `eth0`: @@ -158,7 +166,7 @@ Syntax: The `inetd` directive can also have ` -- Optional Description`, only Finit does not output this text on the console when launching inetd - services. Instead this text is sent to syslog. + services. Instead this text is sent to syslog. More on inetd below. * `runparts ` @@ -167,8 +175,7 @@ Syntax: * `include ` - Include another configuration file. If the file is not an absolute - path ``/etc/finit.d`` is prepended. + Include another configuration file. Absolute path required. * `tty [LVLS] ` @@ -260,7 +267,7 @@ finit. Bootstrap --------- -1. Setup `/dev` +1. Populate `/dev` 2. Parse `/etc/finit.conf` 3. Load all `.so` plugins 4. Remount/Pivot `/` to get R+W @@ -270,8 +277,8 @@ Bootstrap 8. Enable SysV init signals 9. Call 2nd level hooks, `HOOK_BASEFS_UP` 10. Start all 'S' runlevel tasks and services -11. Setup `/etc/sysctl.conf` -12. Setup hostname and loopback +11. Load kernel parameters from `/etc/sysctl.conf` +12. Set hostname and bring up loopback interface 13. Call `network` script, if set in `/etc/finit.conf` 14. Call 3rd level hooks, `HOOK_NETWORK_UP` 15. Switch to active runlevel, as set in `/etc/finit.conf`, default 2. @@ -349,8 +356,8 @@ finit with more internal inetd services. The inetd support in finit is quite advanced. Not only does it launch services on demand, it can do so on custom ports and also filter inbound -traffic using a poor man's tcpwrappers. The syntax is very similar to -traditional `/etc/inetd.conf`, yet keeping with the style of Finit: +traffic using a poor man's [TCP wrappers]. The syntax is very similar to +the traditional `/etc/inetd.conf`, yet keeping with the style of Finit: # Launch SSH on demand, in runlevels 2-5 as root inetd ssh/tcp nowait [2345] @root:root /usr/sbin/sshd -i @@ -362,14 +369,14 @@ A more advanced example: inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i inetd ssh@eth1:22/tcp nowait [2345] /usr/sbin/sshd -i -If eth0 is your Internet interface you may want to avoid using the +If `eth0` is your Internet interface you may want to avoid using the default port. To run ssh on port 222, and all others on port 22: inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i inetd ssh/tcp nowait [2345] /usr/sbin/sshd -i -This actually adds a deny rule for eth0 on ssh/tcp, implicitly. You can -even list the services in the reverse order with the same result: +*This actually adds a deny rule for eth0 on ssh/tcp, implicitly.* You +can even list the services in reverse order with the same result: inetd ssh/tcp nowait [2345] /usr/sbin/sshd -i inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i @@ -377,7 +384,20 @@ even list the services in the reverse order with the same result: There is no specific deny syntax available yet, see the TODO file for more details on how this can be implemented. -The `time.so` inetd plugin setup as follows. Notice the keyword +**Internal Services** + +The original `inetd` had a few standard services built-in: + +- time +- echo +- chargen +- discard + +Finit only supports the `time` service. This is realized as a plugin to +provide a simple means of testing the inetd functionality stand-alone, +but also as a very rudimentary time server for rdate clients. + +The `time.so` inetd plugin is set up as follows. Notice the keyword `internal` which applies to all built-in inetd services: inetd time/tcp nowait [2345] internal @@ -394,6 +414,10 @@ used for testing or environments where NTP for some reason is blocked. Also, remember the UNIX year 2038 bug, or in the case of RFC 868 (and some NTP implementations), year 2036! +**Note:** There is currently no verification that the same port is used + more than once. So a standard http service will clash with an ssh + entry `ssh@*:80/tcp`. + Hooks, Callbacks & Plugins -------------------------- @@ -401,8 +425,11 @@ Hooks, Callbacks & Plugins Finit provides only the bare necessities for starting and supervising processes, with an emphasis on *bare* -- for your convenience it does however come with support for hooks, service callbacks and plugins that -can used to extend finit with. For your convenience a set of *optional* -plugins are available: +can used to extend finit with. + +**Plugins** + +For your convenience a set of *optional* plugins are available: * *alsa-utils.so*: Restore and save ALSA sound settings on startup/shutdown. @@ -414,9 +441,9 @@ plugins are available: * *hwclock.so*: Restore and save system clock from/to RTC on startup/shutdown. -* *initctl.so*: Extends finit with a traditional initctl functionality. +* *initctl.so*: Extends finit with a traditional `initctl` functionality. -* *resolvconf.so*: Setup necessary files for resolvconf at startup. +* *resolvconf.so*: Setup necessary files for `resolvconf` at startup. * *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's) to start/stop getty consoles on them on demand. Useful when plugging @@ -473,13 +500,17 @@ they are called I/O plugins and are called from the finit main loop when `poll()` detects an event. See the source code for `plugins/*.c` for more help and ideas. -Callback plugins are called by finit them right before a process is -started, or restarted if it exits. The callback receive a pointer to -the `svc_t` (defined in `svc.h`) of the service, with all command line -parameters free to modify if needed. All the callback needs to do is -respond with one of: `SVC_STOP (0)` tells finit to *not* start the -service, `SVC_START (1)` to start the service, or `SVC_RELOAD (2)` to -have finit signal the process with `SIGHUP`. +**Callbacks** + +Callback plugins are called by finit right before a process is started, +or restarted if it exits. The callback runs as a separate process and +receives a pointer to the `svc_t` of the service, with all command line +parameters free to modify as needed. + +All the callback needs to do is respond with one of: `SVC_STOP (0)` +tells finit to *not* start the service, `SVC_START (1)` to start the +service, or `SVC_RELOAD (2)` to have finit signal the process with +`SIGHUP`. Rebooting & Halting @@ -649,6 +680,7 @@ for bug fixes and proposed extensions. [8]: http://www.gentoo.org/proj/en/base/openrc/ [9]: https://github.com/troglobit/troglos [10]: ftp://troglobit.com/finit/finit-1.13.tar.xz +[TCP Wrappers]: https://en.wikipedia.org/wiki/TCP_Wrapper [run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts [original finit]: http://helllabs.org/finit/ [EeePC fastinit]: http://wiki.eeeuser.com/boot_process:the_boot_process diff --git a/TODO.md b/TODO.md index 92f6a425..80684f2d 100644 --- a/TODO.md +++ b/TODO.md @@ -26,6 +26,7 @@ General and `RELOAD` on `STDOUT` from a script ... call it for example `.monitor=` in `svc_t` ... the script named as the basename of the service it monitors + `.sh`. +* Add support for `/etc/sysctl.d` * Add compile-time supoprt for running `/bin/sh` instead of `getty` * Add support for `init ` and `SIGHUP` to have finit reload its `finit.conf`, but also @@ -53,153 +54,9 @@ to achieve compatibility would be to add a plugin to finit which reads Inetd ----- -Simple way of running Internet services on demand, like the old inetd: - - inetd PORT/PROTO [@USER[:GROUP]] /path/to/daemon args -- desc - -Examples: - - # Inetd services, launched on demand - inetd ssh/tcp nowait [2345] @root:root /usr/sbin/sshd -i -- SSH daemon - -In keeping with the finit tradition, an optional callback can be setup -to each inetd service. When a client connects the finit will call the -callback with a `struct in_pktinfo` argument which the callback then can -allowed or deny. - -Alternatively, borrowing slightly from TCP wrappers by Wietse Venema, a -set of `allow` and `deny` directives can be added to `finit.conf` to -control inetd services. It could be what IP addreses, networks or -interfaces are allowed to connect to the given inetd services. To start -with the easiest (and what we need for WeOS at Westermo) is allow/deny -per iface. - - # Disable access to SSH - deny ssh all - # Allow SSH connections originating from eth0 - allow ssh eth0 - -Another option, to further extend the Inetd capabilities, is a separate -`finetd.conf` to list services. This would be beneficial when running -an SSH service on different ports on different interfaces: - - # Run SSH on port 22 on all interfaces except upstream - tcp ssh { - listen = *, !wan0 - exec = dropbear -i - } - - # Run SSH on non-standard port 222 for upstream interface - tcp ssh { - port = 222 - listen = wan0 - exec = dropbear -i - wait = yes - } - - # Run TFTP service on all interfaces except upstream interface - udp tftp { - listen = *, !wan0 - exec = uftpd -i -t - user = root - } - -or, more concise - - # System has four interfaces: wan0, eth0, eth1, eth2 - # This runs SSH on only three, with various ports - tcp ssh { - listen = wan0:222 eth0:22 eth1:22 - exec = /usr/sbin/dropbear -i - wait = yes - } - -this would be equivalent - - tcp ssh { - listen = wan0:222 !eth2 - exec = /usr/sbin/dropbear -i - wait = yes - } - -Syntax similar to [xinetd](http://en.wikipedia.org/wiki/Xinetd) - -### Custom Inet Port for Common Services - -- How to do this, without an obtrusive syntax? - -Maybe like this? Then we can still refer to it as the time protocol, -and have multiple entries. - - inetd time:8037/udp wait [2345] @root:root internal - inetd time:3737/udp wait [2345] @root:root internal - -But what if we want to have different allow/deny rules per service? -Here's a proposal, similar to user/pass encoding in URI's. This variant -could potentially be a lot easier to implement and also to maintain for -users, compared to the above allow/deny/xinetd variants. - - inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i - inetd ssh@eth1:22/tcp nowait [2345] /usr/sbin/sshd -i - -or - - inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i - inetd ssh@*:22/tcp nowait [2345] /usr/sbin/sshd -i - -or - - inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i - inetd ssh/tcp nowait [2345] /usr/sbin/sshd -i - -All three versions would be equivalent, except for the first one when -there are more interfaces than just eth0 and eth1. The latter two would -however be equivalent. - -Multiple `inetd ssh` entries with the same port will not be unique, they -will reuse all settings of the first listed entry. However, an entry -with a unique port and interface will be registered as a unique service. - -**Note:** Also, there is currently no verification that the same port is - used more than once. So a standard http service will clash with an - ssh entry ssh@*:80/tcp ... why you would ever want that? - -Inetd callbacks are no different from other callbacks. They match to an -inetd line using the command. So multiple `/usr/bin/sshd` inetd lines -in `finit.conf` will all use the same callback. However, the callback -will be called with the Internet port and interface as arguments. Like -this: - - svc_cmd_t sshd_callback(svc_t *svc, int port, char *ifname) - { - if (!cfg_is_ssh_enabled(ifname, port)) - return SVC_STOP; - - return SVC_START; - } - -As usual, the callback is run in a separate process context and it is up -to the implementer to return `SVC_STOP` or `SVC_START` (`SVC_RELOAD` is -not applicable for inetd services). - - -### Internal inetd services - -There are a few standard services that inetd usually had built-in: - -- time -- echo -- chargen -- discard - -At least 'time' will be implemented in finit, as a plugin, to serve as a -simple means of testing inetd functionality stand-alone, but also as a -very rudimentary time server for rdate clients. - -Example: - - # Built-in inetd time service, launched on demand - inetd time/udp wait [2345] @root:root internal +Optimize interface filtering by using socket filter. The functions +`inet_*_peek()` and `inetd_is_allowed()` used for interace filtering +should be possible to rewrite as socket filters. Crond