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> : 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 <em>verbosity</em></tt> : 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 <em>maxconn</em></tt> : 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 <em>maxfds</em></tt> : 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 <em>clienttimeout</em></tt> : 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 <em>lameducktimeout</em></tt> : 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 <em>rulesfile</em></tt> : 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 <em>rulesdir</em></tt> : 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 > uid/50/env/S6_FDHOLDER_GETDUMP ; echo > 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$' > 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 > 287 gid/23/env/S6_FDHOLDER_RETRIEVE_REGEX</tt> </li> 288 <li> To allow the same users to list all identifiers: 289 <tt>echo > 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 > 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>