diff options
Diffstat (limited to 'doc/s6-fdholderd.html')
-rw-r--r-- | doc/s6-fdholderd.html | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/doc/s6-fdholderd.html b/doc/s6-fdholderd.html new file mode 100644 index 0000000..0977101 --- /dev/null +++ b/doc/s6-fdholderd.html @@ -0,0 +1,318 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6: the s6-fdholderd program</title> + <meta name="Description" content="s6: the s6-fdholderd program" /> + <meta name="Keywords" content="s6 s6-fdholderd fd-holding fd-holder fd unix socket activation server daemon" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6-fdholderd</tt> program </h1> + +<p> +<tt>s6-fdholderd</tt> is the serving part of the +<a href="s6-fdholder-daemon.html">s6-fdholder-daemon</a> +fd-holding server. +It assumes that its stdin is a bound and listening Unix +domain socket, and +it accepts connections from clients connecting to it, and stores and +retrieves file descriptors on their behalf. +</p> + +<h2> Interface </h2> + +<pre> + s6-fdholderd [ -1 ] [ -v verbosity ] [ -c <em>maxconn</em> ] [ -n <em>maxfds</em> ] [ -i <em>rulesdir</em> | -x <em>rulesfile</em> ] +</pre> + +<ul> + <li> s6-fdholderd accepts connections from clients to an already +bound and listening SOCK_STREAM Unix domain socket which is its +standard input. </li> + <li> Depending on the verbosity level, it logs what it does to stderr. </li> + <li> It runs until killed by a signal. Depending on the received +signal, it may kill its children before exiting. </li> + <li> Client connections are short-lived. Clients generally perform +one operation, then disconnect. </li> + <li> Possible operations include: + <ul> + <li> <a href="s6-fdholder-storec.html">Storing a file descriptor</a> </li> + <li> <a href="s6-fdholder-retrievec.html">Retrieving a file descriptor</a> </li> + <li> <a href="s6-fdholder-deletec.html">Deleting a file descriptor</a> </li> + <li> <a href="s6-fdholder-listc.html">Listing stored file descriptor +identifiers</a> </li> + <li> <a href="s6-fdholder-getdumpc.html">Getting the whole server state</a> </li> + <li> <a href="s6-fdholder-setdumpc.html">Setting the whole server state</a>, +or more accurately adding a set of file descriptors to the already existing +state </li> + </ul> </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-1</tt> : write a newline to stdout, and close stdout, +right before entering the client-accepting loop. +If stdout is suitably redirected, this can be used by monitoring +programs to check when the server is accepting connections. +The <a href="s6-notifywhenup.html">s6-notifywhenup</a> +program can be used before the s6-ipcserver +invocation to notify listeners when the server is ready. </li> + <li> <tt>-v <em>verbosity</em></tt> : be more or less +verbose. <em>verbosity</em> can be 0 (quiet), 1 (normal), or 2 or more +(verbose). </li> + <li> <tt>-c <em>maxconn</em></tt> : accept at most +<em>maxconn</em> concurrent connections. Default is 16. It is +impossible to set it higher than the value of the S6_FDHOLDER_MAX macro, +i.e. 256. Client connections to this server are short-lived, so this +number needs not be too high. Every client connection eats up +one available file descriptor, so it is best for <em>maxconn</em> to be +as small as possible. </li> + <li> <tt>-n <em>maxfds</em></tt> : store at most +<em>maxfds</em> file descriptors. Default is 1000. +It is impossible to set it higher than the number of files that can +be opened by the s6-fdholderd process, minus a few descriptors +needed for correct operation. Before running s6-fdholderd, make sure to +<a href="s6-softlimit.html">properly adjust</a> the +<a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_resource.h.html">number +of openable files</a> of the current process. </li> + <li> <tt>-t <em>clienttimeout</em></tt> : disconnect a client +if it's in the middle of an operation and it has not written or read any +data in <em>clienttimeout</em> milliseconds. By default, <em>clienttimeout</em> +is 0, which means infinite. </li> + <li> <tt>-T <em>lameducktimeout</em></tt> : give clients +<em>lameducktimeout</em> milliseconds to finish their current operation +before exiting after receiving a SIGTERM. By default, <em>lameducktimeout</em> +is 0, which means infinite. </li> + <li> <tt>-x <em>rulesfile</em></tt> : read access rights +configuration from +<a href="http://en.wikipedia.org/wiki/Cdb_%28software%29">CDB</a> +file <em>rulesfile</em>. </li> + <li> <tt>-i <em>rulesdir</em></tt> : read access rights +configuration from the filesystem in directory <em>rulesdir</em>. </li> +</ul> + +<h2> Signals </h2> + +<ul> + <li> SIGTERM: enter lameduck mode, then exit when no more operation +is pending. </li> + <li> SIGHUP: reopen <em>rulesfile</em>, if s6-fdholderd has been run +with the <tt>-x</tt> option. It is not necessary to send s6-fdholderd +a SIGHUP when the <tt>-i</tt> option is used instead: configuration +changes in the filesystem are automatically picked up. </li> +</ul> + +<h2> Identifiers </h2> + +<ul> + <li> Every file descriptor is stored in the s6-fdholderd daemon via the +<a href="s6-fdholder-storec.html">s6-fdholder-storec</a> program, with +an <em>identifier</em>. That identifier is a zero-terminated character +string, containing 1 to 255 characters. </li> + <li> Any non-null character can be used in an identifier. Non-printable or +special characters will be quoted when printed by +<a href="s6-fdholder-listc.html">s6-fdholder-listc</a>. However, it is +recommended to only use reasonable characters in identifiers: clients +should be able to know at a glance what file descriptor is represented by +an identifier. Identifiers have no special meaning to the server. </li> + <li> A good convention is to use <tt>unix:/<em>path</em>/<em>to</em>/<em>socket</em></tt> for +Unix domain sockets and <tt><em>protocol</em>:<em>ip</em>:</em><em>port</em></tt> +for INET domain sockets. </li> + <li> An identifier is chosen by the storing client, within the limits of +what the server authorizes it to use. </li> + <li> The retrieving client must know the exact identifier corresponding to +a descriptor to be able to retrieve that descriptor. It must also be +authorized by the server. </li> + <li> When an identifier is in use, it cannot be used again to store another +descriptor. However, once the descriptor has been deleted or has expired, +it is possible to reuse the same identifier. </li> +</ul> + +<a name="configuration"> +<h2> Configuration </h2> +</a> + +<p> + Before running s6-fdholderd (or its wrapper +<a href="s6-fdholder-daemon.html">s6-fdholder-daemon</a>), it is necessary +to configure it. This is done by a series of rules, or <em>ruleset</em>, +stored in either a <em>rulesfile</em> in the +<a href="http://en.wikipedia.org/wiki/Cdb_%28software%29">CDB</a> format, +or in a <em>rulesdir</em>, i.e. a directory in the filesystem following a +certain format. s6-fdholderd will refuse to run if neither the <tt>-i</tt> +nor the <tt>-x</tt> option have been provided. +</p> + +<p> + Rulesets can be converted between the <em>rulesdir</em> and +<em>rulesfile</em> formats with the +<a href="s6-accessrules-cdb-from-fs.html">s6-accessrules-cdb-from-fs</a> and +<a href="s6-accessrules-fs-from-cdb.html">s6-accessrules-fs-from-cdb</a> +conversion tools. +</p> + +<h3> Rules format </h3> + +<p> + The rules file, or rules directory, follows the +<a href="libs6/accessrules.html">s6 accessrules format</a> for uid and +gid checking. For every connecting client, s6-fdholderd matches the uid +and gid of the client against the provided ruleset, and determines what +the client is authorized to do. +</p> + +<p> + By default, no client is allowed to do anything - not even +connect to the server. Even <tt>root</tt>, the super-user, will be denied +access. That's why +it is essential to create a sensible ruleset prior to running the server +in order to do anything useful. +</p> + +<p> + The various rights that a client can have are the following (using a +rulesdir as an example, but a rulesfile works the same way): +</p> + +<ul> + <li> Connect to the server. This is a prerequisite for +doing anything. It will allow a client to perform "public" operations, +ones that do not require specific access rights other than connecting: +for instance, listing all identifiers. This right is given if an +<tt>allow</tt> file is found in one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. +For instance, to allow everyone to connect, touch +<tt><em>rulesdir</em>/uid/default/allow</tt>. </li> +</ul> + +<p> + The other rights are defined in the "environment" part of the ruleset: +</p> + +<ul> + <li> File descriptor storage rights. This will be checked for storage and +deletion of individual file descriptors. This right is given if a non-empty +file named <tt>S6_FDHOLDER_STORE_REGEX</tt> is found is the <tt>env/</tt> +subdirectory of one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. +This file should contain a single line, which will be interpreted as an +<a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended +regular expression</a> by s6-fdholderd; the regular expression describes the +set of identifiers that the client is allowed to use to store file +descriptors. For instance, <tt>^unix:/tmp/</tt> indicates that a client +that matches this rule will be allowed to store or delete file descriptors +using any identifier starting with <tt>unix:/tmp/</tt>. </li> + <li> File descriptor retrieval rights. This will be checked for retrieval +of individual file descriptors. This right is given if a non-empty +file named <tt>S6_FDHOLDER_RETRIEVE_REGEX</tt> is found is the <tt>env/</tt> +subdirectory of one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. +This file should contain a single line, which will be interpreted as an +<a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended +regular expression</a> by s6-fdholderd; the regular expression describes the +set of identifiers that the client is allowed to use to retrieve file +descriptors. For instance, <tt>^unix:/tmp/</tt> indicates that a client +that matches this rule will be allowed to retrieve file descriptors that are +identified by strings starting with <tt>unix:/tmp/</tt>. </li> + <li> Dump reading rights. This will be checked for clients wanting to +copy the whole state of the server. This right is given if a non-empty +file named <tt>S6_FDHOLDER_GETDUMP</tt> is found is the <tt>env/</tt> +subdirectory of one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. +This is very powerful: you should only give this right to <tt>root</tt>, +or to a dedicated uid that is only used to perform dump transfers. </li> + <li> Dump writing rights. This will be checked for clients wanting to +copy an entire set of file descriptors into the server. +This right is given if a non-empty +file named <tt>S6_FDHOLDER_SETDUMP</tt> is found is the <tt>env/</tt> +subdirectory of one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. +This is very powerful: you should only give this right to <tt>root</tt>, or +to a dedicated uid that is only used to perform dump transfers. </li> +</ul> + +<h3> Configuration examples </h3> + +<p> + Assuming you want to run a s6-fdholderd daemon in the +<tt>/service/fdholder</tt> directory with the <tt>-i rules</tt> option, +you should: +</p> + +<ul> + <li> Prepare the rules directory: <tt>mkdir /service/fdholder/rules ; +cd /service/fdholder/rules ; mkdir uid gid</tt> </li> + <li> Allow a few users, or everyone, to connect. To allow root to +connect: <tt>mkdir uid/0 ; touch uid/0/allow</tt>. To allow everyone +to connect: <tt>mkdir uid/default ; touch uid/default/allow</tt>. </li> +</ul> + +<p> + Depending on your policy, you should now give certain rights to +certain users or groups. For instance: +</p> + +<ul> + <li> To allow user number 50 to perform dump transfers from and to +this server: <tt>mkdir -p uid/50/env ; touch uid/50/allow ; +echo > uid/50/env/S6_FDHOLDER_GETDUMP ; echo > +uid/50/env/S6_FDHOLDER_SETDUMP</tt> </li> + <li> To allow user number 72 to store a descriptor under the name +<tt>foobar</tt> and <em>only</em> this name: <tt>mkdir -p uid/72/env ; +touch uid/72/allow ; echo '^foobar$' > +uid/72/env/S6_FDHOLDER_STORE_REGEX</tt> </li> + <li> To allow users having 23 as their primary group number to retrieve file +descriptors with an identifier containing <tt>foo</tt>, then one +character, then <tt>bar</tt>: +<tt>mkdir -p gid/23/env ; touch gid/23/allow ; echo foo.bar > +gid/23/env/S6_FDHOLDER_RETRIEVE_REGEX</tt> </li> + <li> To allow everyone to dump entire states into the server: +<tt>mkdir -p uid/default/env ; touch uid/default/allow ; +echo > uid/default/env/S6_FDHOLDER_SETDUMP</tt>. +<strong>Never do this!</strong> </li> +</ul> + +<h2> Notes </h2> + +<ul> + <li> s6-fdholderd is meant to be execve'd into by a program that gets +the listening socket. That program is normally +<a href="s6-ipcserver-socketbinder.html">s6-ipcserver-socketbinder</a>, +which creates the socket itself; but it can be a different one if the +socket is to be obtained by another means, for instance if it has +been retrieved from another fd-holding daemon. </li> + <li> s6-fdholderd will store any open file descriptor, without +discriminating on its type. However, it makes more sense to store certain +file descriptor types than others: for instance, Unix domain or INET domain +sockets, or named pipes, are good candidates for fd-holding. On the other +hand, it makes little sense to fd-hold regular files, and if done anyway, +the results can be surprising, because the read/write file offset is +stored with the descriptor, and no automatic rewind is performed by the +daemon. </li> + <li> Anyone that is allowed to connect is allowed to read the whole list +of identifiers. This is intentional: identifiers should be public and +well-known, and the security of the system should not depend on a client +not knowing what identifier a certain descriptor is stored under. If you +need to hold descriptors that only a few programs are supposed to access, +you can always run a separate s6-fdholderd instance in a private directory +with a configuration tailored to your needs +- and you can even make the name of the listening socket private. +s6-fdholderd is lightweight, you can start as many instances as you need, +and you can run them as long as you need then kill them with SIGTERM. + <li> s6-fdholderd pre-allocates its storage at start, in the stack. It +uses a small amount of heap memory for communication with a client, but frees +it as soon as the client disconnects. It should never run out of memory in +normal usage, even if used intensively. </li> +</ul> + +</body> +</html> |