s6

Mirror/fork of https://skarnet.org/software/s6/
git clone https://ccx.te2000.cz/git/s6
Log | Files | Refs | README | LICENSE

s6-fdholderd.html (15674B)


      1 <html>
      2   <head>
      3     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      5     <meta http-equiv="Content-Language" content="en" />
      6     <title>s6: the s6-fdholderd program</title>
      7     <meta name="Description" content="s6: the s6-fdholderd program" />
      8     <meta name="Keywords" content="s6 s6-fdholderd fd-holding fd-holder fd unix socket activation server daemon" />
      9     <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
     10   </head>
     11 <body>
     12 
     13 <p>
     14 <a href="index.html">s6</a><br />
     15 <a href="//skarnet.org/software/">Software</a><br />
     16 <a href="//skarnet.org/">skarnet.org</a>
     17 </p>
     18 
     19 <h1> The <tt>s6-fdholderd</tt> program </h1>
     20 
     21 <p>
     22 <tt>s6-fdholderd</tt> is the serving part of the
     23 <a href="s6-fdholder-daemon.html">s6-fdholder-daemon</a>
     24 fd-holding server.
     25 It assumes that its stdin is a bound and listening Unix
     26 domain socket;
     27 it accepts connections from clients connecting to that socket,
     28 and stores and retrieves file descriptors on their behalf.
     29 </p>
     30 
     31 <h2> Interface </h2>
     32 
     33 <pre>
     34      s6-fdholderd [ -1 ] [ -v verbosity ] [ -c <em>maxconn</em> ] [ -n <em>maxfds</em> ] [ -t <em>clienttimeout</em> ] [ -T <em>lameducktimeout</em> ] [ -i <em>rulesdir</em> | -x <em>rulesfile</em> ]
     35 </pre>
     36 
     37 <ul>
     38  <li> s6-fdholderd accepts connections from clients to an already
     39 bound and listening SOCK_STREAM Unix domain socket which is its
     40 standard input. </li>
     41  <li> Depending on the verbosity level, it logs what it does to stderr. </li>
     42  <li> It runs until killed by a signal (normally SIGTERM).
     43 When s6-fdholderd is killed, all the fds it is currently holding are
     44 lost; if they need to be preserved, the admin should make sure to
     45 <a href="s6-fdholder-transferdump.html">transfer them</a> beforehand. </li>
     46  <li> Client connections are short-lived. Clients generally perform
     47 one operation, then disconnect. </li>
     48  <li> Possible operations include:
     49  <ul>
     50   <li> <a href="s6-fdholder-store.html">Storing a file descriptor</a> </li>
     51   <li> <a href="s6-fdholder-retrieve.html">Retrieving a file descriptor</a> </li>
     52   <li> <a href="s6-fdholder-delete.html">Deleting a file descriptor</a> </li>
     53   <li> <a href="s6-fdholder-list.html">Listing stored file descriptor
     54 identifiers</a> </li>
     55   <li> <a href="s6-fdholder-getdump.html">Getting the whole server state</a> </li>
     56   <li> <a href="s6-fdholder-setdump.html">Setting the whole server state</a>,
     57 or more accurately adding a set of file descriptors to the already existing
     58 state </li>
     59  </ul> </li>
     60 </ul>
     61 
     62 <h2> Options </h2>
     63 
     64 <ul>
     65  <li> <tt>-1</tt>&nbsp;: write a newline to stdout, and close stdout,
     66 right before entering the client-accepting loop.
     67 If stdout is suitably redirected, this can be used by monitoring
     68 programs to check when the server is accepting connections. See
     69 <a href="notifywhenup.html">this page</a> for more information on
     70 readiness notification. </li>
     71  <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp;: be more or less
     72 verbose. <em>verbosity</em> can be 0 (quiet), 1 (normal), or 2 or more
     73 (verbose). </li>
     74  <li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
     75 <em>maxconn</em> concurrent connections. Default is 16. It is
     76 impossible to set it higher than the value of the S6_FDHOLDER_MAX macro,
     77 i.e. 256. Client connections to this server are short-lived, so this
     78 number needs not be too high. Every client connection eats up
     79 one available file descriptor, so it is best for <em>maxconn</em> to be
     80 as small as possible. </li>
     81  <li> <tt>-n&nbsp;<em>maxfds</em></tt>&nbsp;: store at most
     82 <em>maxfds</em> file descriptors. Default is 1000.
     83 It is impossible to set it higher than the number of files that can
     84 be opened by the s6-fdholderd process, minus a few descriptors
     85 needed for correct operation. Before running s6-fdholderd, make sure to
     86 <a href="s6-softlimit.html">properly adjust</a> the
     87 <a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_resource.h.html">number
     88 of openable files</a> of the current process. </li>
     89  <li> <tt>-t&nbsp;<em>clienttimeout</em></tt>&nbsp;: disconnect a client
     90 if it's in the middle of an operation and it has not written or read any
     91 data in <em>clienttimeout</em> milliseconds. By default, <em>clienttimeout</em>
     92 is 0, which means infinite. </li>
     93  <li> <tt>-T&nbsp;<em>lameducktimeout</em></tt>&nbsp;: give clients
     94 <em>lameducktimeout</em> milliseconds to finish their current operation
     95 before exiting after receiving a SIGTERM. By default, <em>lameducktimeout</em>
     96 is 0, which means infinite. </li>
     97  <li> <tt>-x&nbsp;<em>rulesfile</em></tt>&nbsp;: read access rights
     98 configuration from
     99 <a href="https://en.wikipedia.org/wiki/Cdb_%28software%29">CDB</a>
    100 file <em>rulesfile</em>. </li>
    101  <li> <tt>-i&nbsp;<em>rulesdir</em></tt>&nbsp;: read access rights
    102 configuration from the filesystem in directory <em>rulesdir</em>. </li>
    103 </ul>
    104 
    105 <h2> Signals </h2>
    106 
    107 <ul>
    108  <li> SIGTERM: enter lameduck mode, then exit when no more operation
    109 is pending. </li>
    110  <li> SIGHUP: reopen <em>rulesfile</em>, if s6-fdholderd has been run
    111 with the <tt>-x</tt> option. It is not necessary to send s6-fdholderd
    112 a SIGHUP when the <tt>-i</tt> option is used instead: configuration
    113 changes in the filesystem are automatically picked up. </li>
    114 </ul>
    115 
    116 <h2> Identifiers </h2>
    117 
    118 <ul>
    119  <li> Every file descriptor is stored in the s6-fdholderd daemon via the
    120 <a href="s6-fdholder-store.html">s6-fdholder-store</a> program, with
    121 an <em>identifier</em>. That identifier is a zero-terminated character
    122 string, containing 1 to 255 characters. </li>
    123  <li> Any non-null character can be used in an identifier. Non-printable or
    124 special characters will be quoted when printed by
    125 <a href="s6-fdholder-list.html">s6-fdholder-list</a>. However, it is
    126 recommended to only use reasonable characters in identifiers: clients
    127 should be able to know at a glance what file descriptor is represented by
    128 an identifier. Identifiers have no special meaning to the server. </li>
    129  <li> A good convention is to use <tt>unix:<em>path</em>/<em>to</em>/<em>socket</em></tt> for
    130 Unix domain sockets and <tt><em>protocol</em>:<em>ip</em>:<em>port</em></tt>
    131 for INET domain sockets. </li>
    132  <li> An identifier is chosen by the storing client, within the limits of
    133 what the server authorizes it to use. </li>
    134  <li> The retrieving client must know the exact identifier corresponding to
    135 a descriptor to be able to retrieve that descriptor. It must also be
    136 authorized by the server. </li>
    137  <li> When an identifier is in use, it cannot be used again to store another
    138 descriptor. However, once the descriptor has been deleted or has expired,
    139 it is possible to reuse the same identifier. </li>
    140 </ul>
    141 
    142 <a name="configuration">
    143 <h2> Configuration </h2>
    144 </a>
    145 
    146 <p>
    147  Before running s6-fdholderd (or its wrapper
    148 <a href="s6-fdholder-daemon.html">s6-fdholder-daemon</a>), it is necessary
    149 to configure it. This is done by a series of rules, or <em>ruleset</em>,
    150 stored in either a <em>rulesfile</em> in the
    151 <a href="https://en.wikipedia.org/wiki/Cdb_%28software%29">CDB</a> format,
    152 or in a <em>rulesdir</em>, i.e. a directory in the filesystem following a
    153 certain format. s6-fdholderd will refuse to run if neither the <tt>-i</tt>
    154 nor the <tt>-x</tt> option has been provided.
    155 </p>
    156 
    157 <p>
    158  Rulesets can be converted between the <em>rulesdir</em> and
    159 <em>rulesfile</em> formats with the
    160 <a href="s6-accessrules-cdb-from-fs.html">s6-accessrules-cdb-from-fs</a> and
    161 <a href="s6-accessrules-fs-from-cdb.html">s6-accessrules-fs-from-cdb</a>
    162 conversion tools.
    163 </p>
    164 
    165 <h3> Rules format </h3>
    166 
    167 <p>
    168  The rules file, or rules directory, follows the
    169 <a href="libs6/accessrules.html">s6 accessrules format</a> for uid and
    170 gid checking. For every connecting client, s6-fdholderd matches the uid
    171 and gid of the client against the provided ruleset, and determines what
    172 the client is authorized to do.
    173 </p>
    174 
    175 <p>
    176  By default, no client is allowed to do anything - not even
    177 connect to the server. Even <tt>root</tt>, the super-user, will be denied
    178 access. That is why
    179 it is essential to create a sensible ruleset prior to running the server
    180 in order to do anything useful.
    181 </p>
    182 
    183 <p>
    184  The various rights that a client can have are the following (using a
    185 rulesdir as an example, but a rulesfile works the same way):
    186 </p>
    187 
    188 <ul>
    189  <li> Connect to the server. This is a prerequisite for
    190 doing anything. It will allow a client to perform "public" operations,
    191 ones that do not require specific access rights other than connecting.
    192 (There are no such operations for now, but it could change in the
    193 future; for now, when you allow a client to connect to the server,
    194 make sure to give him other rights too.)
    195  This right is given if an
    196 <tt>allow</tt> file is found in one of the subdirectories checked by
    197 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>.
    198 For instance, to allow everyone to connect, touch
    199 <tt><em>rulesdir</em>/uid/default/allow</tt>. </li>
    200 </ul>
    201 
    202 <p>
    203  The other rights are defined in the "environment" part of the ruleset:
    204 </p>
    205 
    206 <ul>
    207  <li> File descriptor storage rights. This will be checked for storage and
    208 deletion of individual file descriptors. This right is given if a non-empty
    209 file named <tt>S6_FDHOLDER_STORE_REGEX</tt> is found in the <tt>env/</tt>
    210 subdirectory of one of the subdirectories checked by
    211 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>.
    212 This file should contain a single line, which will be interpreted as an
    213 <a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">Extended
    214 Regular Expression</a> by s6-fdholderd; the regular expression describes the
    215 set of identifiers that the client is allowed to use to store file
    216 descriptors. For instance, <tt>^unix:/tmp/</tt> indicates that a client
    217 that matches this rule will be allowed to store or delete file descriptors
    218 using any identifier starting with <tt>unix:/tmp/</tt>. </li>
    219  <li> File descriptor retrieval rights. This will be checked for retrieval
    220 of individual file descriptors. This right is given if a non-empty
    221 file named <tt>S6_FDHOLDER_RETRIEVE_REGEX</tt> is found in the <tt>env/</tt>
    222 subdirectory of one of the subdirectories checked by
    223 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>.
    224 This file should contain a single line, which will be interpreted as an
    225 <a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">Extended
    226 Regular Expression</a> by s6-fdholderd; the regular expression describes the
    227 set of identifiers that the client is allowed to use to retrieve file
    228 descriptors. For instance, <tt>^unix:/tmp/</tt> indicates that a client
    229 that matches this rule will be allowed to retrieve file descriptors that are
    230 identified by strings starting with <tt>unix:/tmp/</tt>. </li>
    231  <li> Listing rights. This will be checked for clients wanting to list
    232 the identifiers of the descriptors currently stored in the server. This
    233 right is given if a non-empty file named <tt>S6_FDHOLDER_LIST</tt> is
    234 found in the <tt>env/</tt> subdirectory of one of the subdirectories checked by
    235 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. </li>
    236  <li> Dump reading rights. This will be checked for clients wanting to
    237 copy the whole state of the server. This right is given if a non-empty
    238 file named <tt>S6_FDHOLDER_GETDUMP</tt> is found is the <tt>env/</tt>
    239 subdirectory of one of the subdirectories checked by
    240 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>.
    241 This is very powerful: you should only give this right to <tt>root</tt>,
    242 or to a dedicated uid that is only used to perform dump transfers. </li>
    243  <li> Dump writing rights. This will be checked for clients wanting to
    244 copy an entire set of file descriptors into the server.
    245 This right is given if a non-empty
    246 file named <tt>S6_FDHOLDER_SETDUMP</tt> is found is the <tt>env/</tt>
    247 subdirectory of one of the subdirectories checked by
    248 <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>.
    249 This is very powerful: you should only give this right to <tt>root</tt>, or
    250 to a dedicated uid that is only used to perform dump transfers. </li>
    251 </ul>
    252 
    253 <h3> Configuration examples </h3>
    254 
    255 <p>
    256  Assuming you want to run an s6-fdholderd daemon in the
    257 <tt>/service/fdholder</tt> directory with the <tt>-i rules</tt> option,
    258 you should:
    259 </p>
    260 
    261 <ul>
    262  <li> Prepare the rules directory: <tt>mkdir /service/fdholder/rules ;
    263 cd /service/fdholder/rules ; mkdir uid gid</tt> </li>
    264  <li> Allow a few users, or everyone, to connect. To allow root to
    265 connect: <tt>mkdir uid/0 ; touch uid/0/allow</tt>. To allow everyone
    266 to connect: <tt>mkdir uid/default ; touch uid/default/allow</tt>. </li>
    267 </ul>
    268 
    269 <p>
    270  Depending on your policy, you should now give certain rights to
    271 certain users or groups. For instance:
    272 </p>
    273 
    274 <ul>
    275  <li> To allow user number 50 to perform dump transfers from and to
    276 this server: <tt>mkdir -p uid/50/env ; touch uid/50/allow ;
    277 echo &gt; uid/50/env/S6_FDHOLDER_GETDUMP ; echo &gt;
    278 uid/50/env/S6_FDHOLDER_SETDUMP</tt> </li>
    279  <li> To allow user number 72 to store a descriptor under the name
    280 <tt>foobar</tt> and <em>only</em> this name: <tt>mkdir -p uid/72/env ;
    281 touch uid/72/allow ; echo '^foobar$' &gt;
    282 uid/72/env/S6_FDHOLDER_STORE_REGEX</tt> </li>
    283  <li> To allow users having 23 as their primary group number to retrieve file
    284 descriptors with an identifier containing <tt>foo</tt>, then one
    285 character, then <tt>bar</tt>:
    286 <tt>mkdir -p gid/23/env ; touch gid/23/allow ; echo foo.bar &gt;
    287 gid/23/env/S6_FDHOLDER_RETRIEVE_REGEX</tt> </li>
    288  <li> To allow the same users to list all identifiers:
    289 <tt>echo &gt; gid/23/env/S6_FDHOLDER_LIST</tt> </li>
    290  <li> To allow everyone to dump entire states into the server
    291 (<strong>never do this!</strong> it's only an example): 
    292 <tt>mkdir -p uid/default/env ; touch uid/default/allow ;
    293 echo &gt; uid/default/env/S6_FDHOLDER_SETDUMP</tt>. </li>
    294 </ul>
    295 
    296 <h2> Notes </h2>
    297 
    298 <ul>
    299  <li> s6-fdholderd is meant to be execve'd into by a program that gets
    300 the listening socket. That program is normally
    301 <a href="s6-ipcserver-socketbinder.html">s6-ipcserver-socketbinder</a>,
    302 which creates the socket itself; but it can be a different one if the
    303 socket is to be obtained by another means, for instance if it has
    304 been retrieved from another fd-holding daemon. </li>
    305  <li> s6-fdholderd will store any open file descriptor, without
    306 discriminating on its type. However, it makes more sense to store certain
    307 file descriptor types than others: for instance, Unix domain or INET domain
    308 sockets, or named pipes, are good candidates for fd-holding. On the other
    309 hand, it makes little sense to fd-hold regular files, and if done anyway,
    310 the results can be surprising, because the read/write file offset is
    311 stored with the descriptor, and no automatic rewind is performed by the
    312 daemon. </li>
    313  <li> Despite there being access control for listing, the security of the
    314 system should not depend on a client
    315 not knowing what identifier a certain descriptor is stored under. If you
    316 need to hold descriptors that only a few programs are supposed to access,
    317 you can always run a separate s6-fdholderd instance in a private directory
    318 with a configuration tailored to your needs
    319 - and you can even make the name of the listening socket private.
    320 s6-fdholderd is lightweight, you can start as many instances as you need,
    321 and you can run them as long as you need then kill them with SIGTERM. </li>
    322  <li> s6-fdholderd pre-allocates its storage at start, in the stack. It
    323 uses a small amount of heap memory for communication with a client, but frees
    324 it as soon as the client disconnects. It should never run out of memory in
    325 normal usage, even if used intensively. </li>
    326 </ul>
    327 
    328 </body>
    329 </html>