| 1 |
sez |
171 |
[[!meta title="DEP-9: inet-superserver configuration by maintainer scripts"]] |
| 2 |
sez |
170 |
|
| 3 |
|
|
Title: inet-superserver configuration by maintainer scripts |
| 4 |
sez |
171 |
DEP: 9 |
| 5 |
sez |
170 |
State: DRAFT |
| 6 |
sez |
263 |
Date: 2012-02-05 |
| 7 |
sez |
170 |
Drivers: Serafeim Zanikolas <sez@debian.org> |
| 8 |
sez |
172 |
URL: http://dep.debian.net/deps/dep9 |
| 9 |
sez |
170 |
License: http://www.jclark.com/xml/copying.txt |
| 10 |
|
|
Abstract: |
| 11 |
|
|
Motivation, requirements and functional overview of a successor |
| 12 |
|
|
configuration tool for inetd superservers. |
| 13 |
|
|
|
| 14 |
|
|
[[!toc ]] |
| 15 |
|
|
|
| 16 |
|
|
# Introduction |
| 17 |
|
|
|
| 18 |
|
|
The inet-superserver facility (typically provided by the openbsd-inetd |
| 19 |
|
|
package) listens to certain sockets and invokes the right server upon the |
| 20 |
|
|
arrival of an incoming request. Servers that are meant to be invoked by inetd |
| 21 |
|
|
must add a service entry to /etc/inetd.conf upon package installation (and |
| 22 |
|
|
remove the entry upon package purge). Maintainer scripts that modify |
| 23 |
|
|
inetd.conf must currently do so using a utility called update-inetd, as per |
| 24 |
|
|
Policy 11.2. |
| 25 |
|
|
|
| 26 |
|
|
However, update-inetd has a problematic interface that leads to several kinds |
| 27 |
|
|
of bugs, including cross-package ones. Fixing update-inetd is largely a matter |
| 28 |
|
|
of fixing its interface, which would break backwards-compatibility. With that |
| 29 |
|
|
cost as a given (ie. the cost of revising all maintainer scripts of |
| 30 |
|
|
update-inetd's reverse-depends), one might as well create a successor tool |
| 31 |
|
|
with a cleaner interface. |
| 32 |
|
|
|
| 33 |
|
|
This DEP proposes such a successor inetd configuration tool, hereafter called |
| 34 |
|
|
reconf-inetd. reconf-inetd, in addition to providing the existing functionality, |
| 35 |
|
|
must meet the following requirements: |
| 36 |
|
|
|
| 37 |
|
|
* the standard configuration files of inetd and xinetd must remain the |
| 38 |
|
|
authoritative files; |
| 39 |
|
|
* the solution must not change the way system administrators configure inetd, |
| 40 |
|
|
and must have no impact on maintainers of "Provides: inet-superserver" |
| 41 |
|
|
packages; |
| 42 |
|
|
* reconf-inetd must be capable of co-existing with update-inetd, so as |
| 43 |
|
|
to allow a gradual transition. |
| 44 |
|
|
|
| 45 |
|
|
Note that the first requirement above implies that inetd.conf entries that |
| 46 |
|
|
have been (i) added by reconf-inetd and (ii) were subsequently modified by the |
| 47 |
|
|
user, shall not be removed even on package purge. |
| 48 |
|
|
|
| 49 |
|
|
# Motivation |
| 50 |
|
|
|
| 51 |
|
|
The main problem of update-inetd is that the service entry to be enabled, |
| 52 |
|
|
disabled or removed, is selected in terms of a service name, such as "ftp". |
| 53 |
|
|
This limitation typically leads to cross-package bugs because of the |
| 54 |
|
|
difficulty to distinguish between independent implementations (eg. ftpd-ssl |
| 55 |
|
|
versus proftpd), or an ipv4 versus an ipv6 implementation of the same kind of |
| 56 |
|
|
service. As an example, in #168847, ftpd-ssl's invocation of update-inetd |
| 57 |
|
|
enables the service entry of (the previously uninstalled) proftpd because both |
| 58 |
|
|
packages' entries have an "ftp" service name. |
| 59 |
|
|
|
| 60 |
|
|
As of now, one can try to avoid the above problem as follows. A maintainer |
| 61 |
|
|
script may (i) further specify the acted-upon service entry in terms of a |
| 62 |
|
|
regular expression (which is matched against the whole service entry, instead |
| 63 |
|
|
of just the service name); (ii) override the default comment-prefix |
| 64 |
|
|
("#<off># "), to distinguish service entries of different packages that provide |
| 65 |
|
|
the same kind of service (eg. "#<off-ftpd-ssl-ipv4># " vs |
| 66 |
|
|
"#<off-proftpd-ipv4># "). These features work when used correctly, but at the |
| 67 |
|
|
cost of fragile logic in maintainer scripts. |
| 68 |
|
|
|
| 69 |
|
|
To summarise, the interface of update-inetd is inadequate in that it does not |
| 70 |
|
|
require that the following three elements are specified to select an entry: |
| 71 |
|
|
service name, protocol type, and path to server program. |
| 72 |
|
|
|
| 73 |
|
|
A secondary issue, but nevertheless one that would be nice to solve, is |
| 74 |
|
|
support for configuration updates of xinetd (#8927). xinetd has a relatively |
| 75 |
sez |
242 |
low popcon but one could argue that may be the case because it is not well |
| 76 |
|
|
integrated in Debian. |
| 77 |
sez |
170 |
|
| 78 |
|
|
|
| 79 |
|
|
# Outline of reconf-inetd operation |
| 80 |
|
|
|
| 81 |
|
|
reconf-inetd will operate similarly to update-inetd, ie. add, remove, enable and |
| 82 |
|
|
disable service entries in /etc/inetd.conf. The main difference is that where |
| 83 |
|
|
update-inetd uses command-line arguments, reconf-inetd will use xinetd.conf(5) |
| 84 |
|
|
configuration fragments under /usr/share/reconf-inetd (hereafter called |
| 85 |
|
|
reconf-inetd fragments, for brevity). Moreover, reconf-inetd will be invoked via a |
| 86 |
|
|
dpkg trigger, as opposed to from maintainer scripts. |
| 87 |
|
|
|
| 88 |
|
|
With reconf-inetd, inet-superserver configuration will occur as follows: |
| 89 |
|
|
|
| 90 |
|
|
* reconf-inetd will provide the directory /usr/share/reconf-inetd, and declare a |
| 91 |
|
|
dpkg trigger for that directory |
| 92 |
|
|
* server packages that can use inetd, will depend on reconf-inetd and install |
| 93 |
|
|
a reconf-inetd fragment in /usr/share/reconf-inetd |
| 94 |
|
|
* reconf-inetd will be invoked via a dpkg trigger to update /etc/inetd.conf |
| 95 |
|
|
using the fragments in /usr/share/reconf-inetd |
| 96 |
|
|
|
| 97 |
|
|
An inetd.conf service entry will be considered to be "matching" a reconf-inetd |
| 98 |
|
|
fragment when the following fields are equal: service name, protocol, and |
| 99 |
|
|
server program. In reconf-inetd fragments with "flags = NAMEINARGS" (eg. a tcpd |
| 100 |
|
|
service entry), the actual server path will be extracted from the server_args |
| 101 |
|
|
field, as per xinetd.conf(5). |
| 102 |
|
|
|
| 103 |
|
|
Upon adding an entry to inetd.conf, reconf-inetd will make a shadow copy of the |
| 104 |
|
|
related reconf-inetd fragment under /var/lib/reconf-inetd. This would allow to |
| 105 |
|
|
determine the following after the uninstallation of the related package: |
| 106 |
|
|
|
| 107 |
|
|
* to identify inetd.conf entries that have been added by reconf-inetd (as |
| 108 |
|
|
opposed to update-inetd or a user) |
| 109 |
|
|
* to determine whether an inetd.conf entry, that has been previously added by |
| 110 |
|
|
reconf-inetd, is intact or has had local modifications |
| 111 |
|
|
|
| 112 |
|
|
All reconf-inetd fragments will be considered enabled, regardless of the value |
| 113 |
|
|
of the "disable" field, if such field exists. Servers that support inetd mode |
| 114 |
|
|
but default to standalone operation must therefore not install a reconf-inetd |
| 115 |
|
|
fragment (and should instead provide a sample inetd.conf entry that the user |
| 116 |
|
|
has to add manually to /etc/inetd.conf). |
| 117 |
|
|
|
| 118 |
|
|
/etc/inetd.conf (and /etc/xinetd.d) will remain the authoritative |
| 119 |
|
|
configuration file for inetd (and xinetd). reconf-inetd fragments are only meant |
| 120 |
|
|
for updating the standard configuration files. |
| 121 |
|
|
|
| 122 |
|
|
An invocation of reconf-inetd (because of a fragment being installed or removed |
| 123 |
|
|
from /usr/share/reconf-inetd) may result in a modification of /etc/inetd.conf |
| 124 |
|
|
as summarised in the table below. |
| 125 |
|
|
|
| 126 |
|
|
<pre> |
| 127 |
|
|
|
| 128 |
|
|
| server | status of | matching | shadow | reconf-inetd |
| 129 |
|
|
| program | inetd.conf | reconf-inetd | fragment | action |
| 130 |
|
|
| exists | entry | fragment | status | |
| 131 |
|
|
---+---------+------------+--------------+------------+----------- |
| 132 |
|
|
0| no | disabled | no | identical | remove |
| 133 |
|
|
1| no | enabled | no | identical | remove |
| 134 |
|
|
---+---------+------------+--------------+------------+----------- |
| 135 |
|
|
2| yes | disabled | yes | different | enable |
| 136 |
|
|
3| yes | disabled | yes | identical | enable |
| 137 |
|
|
---+---------+------------+--------------+------------+----------- |
| 138 |
|
|
4| yes | missing | yes | n/a | add |
| 139 |
|
|
---+---------+------------+--------------+------------+----------- |
| 140 |
|
|
5| commented-out inetd.conf entry | none |
| 141 |
|
|
---+---------+------------+--------------+------------+----------- |
| 142 |
|
|
6| any other combination | none |
| 143 |
|
|
|
| 144 |
|
|
</pre> |
| 145 |
|
|
|
| 146 |
|
|
An inetd.conf entry is considered disabled when it starts with "#<off># ", |
| 147 |
|
|
and disabled by a user when commented-out simply with '#'. |
| 148 |
|
|
|
| 149 |
|
|
A shadow fragment status (ie. the fragment under /var/lib/reconf-inetd) is |
| 150 |
|
|
considered identical to a matching inetd.conf entry, by comparing the |
| 151 |
|
|
server arguments, if any. |
| 152 |
|
|
|
| 153 |
|
|
Follows a detailed description of the aforementioned scenarios. |
| 154 |
|
|
|
| 155 |
|
|
* an non-commented-out inetd.conf entry will be removed, regardless of whether |
| 156 |
|
|
it is enabled or disabled, when it: |
| 157 |
|
|
- refers to a non-existing server file |
| 158 |
|
|
- has no matching reconf-inetd fragment |
| 159 |
|
|
- is identical to a matching shadow fragment |
| 160 |
|
|
|
| 161 |
|
|
* a disabled inetd.conf entry will be enabled when it |
| 162 |
|
|
- refers to an existing server file |
| 163 |
|
|
- it has a matching reconf-inetd fragment |
| 164 |
|
|
- and a matching shadow fragment (identical or not) |
| 165 |
|
|
|
| 166 |
sez |
243 |
* a new inetd.conf entry will be added when there exists a reconf-inetd fragment |
| 167 |
sez |
170 |
that: |
| 168 |
|
|
- refers to an existing server file |
| 169 |
|
|
- has no matching (enabled, disabled, commented-out or not) inetd.conf |
| 170 |
|
|
entry |
| 171 |
|
|
- has a matching reconf-inetd fragment |
| 172 |
|
|
|
| 173 |
sez |
262 |
Meaning of the above listed actions: |
| 174 |
sez |
170 |
|
| 175 |
sez |
262 |
- add: add inetd.conf entry and a matching shadow fragment |
| 176 |
|
|
- remove: remove inetd.conf entry and matching shadow fragment |
| 177 |
|
|
- enable: enable inetd.conf entry |
| 178 |
|
|
|
| 179 |
sez |
277 |
# Configuration of new server packages |
| 180 |
|
|
|
| 181 |
|
|
Packages that have never used update-inetd must do the following: |
| 182 |
|
|
|
| 183 |
|
|
* depend on reconf-inetd |
| 184 |
|
|
* install a reconf-inetd fragment in /usr/share/reconf-inetd, as a regular |
| 185 |
|
|
file (ie. not as a conffile); |
| 186 |
|
|
|
| 187 |
sez |
170 |
# Transition of "Depends: update-inetd" packages |
| 188 |
|
|
|
| 189 |
|
|
A time-limited transition is not a strict requirement, since reconf-inetd and |
| 190 |
|
|
update-inetd can co-exist without problems. |
| 191 |
|
|
|
| 192 |
sez |
277 |
reconf-inetd will not touch any entries that have not been added by itself, |
| 193 |
|
|
including entries added by update-inetd. Thus, a server package that is meant |
| 194 |
|
|
to transition from update-inetd to reconf-inetd, must remove any entries that |
| 195 |
|
|
it previously added using update-inetd. |
| 196 |
|
|
|
| 197 |
sez |
170 |
Server packages that depend on update-inetd can be converted as follows: |
| 198 |
|
|
|
| 199 |
sez |
277 |
0) in the first stable Debian release in which reconf-inetd is used by the |
| 200 |
|
|
package: |
| 201 |
|
|
|
| 202 |
|
|
* depend on both update-inetd and reconf-inetd |
| 203 |
sez |
170 |
* install a reconf-inetd fragment in /usr/share/reconf-inetd, as a regular |
| 204 |
sez |
271 |
file (ie. not as a conffile); |
| 205 |
sez |
277 |
* drop any references to update-inetd in postrm, and modify postinst to remove |
| 206 |
|
|
any inetd.conf entries for that package that were previously added using |
| 207 |
|
|
update-inetd |
| 208 |
sez |
170 |
|
| 209 |
sez |
277 |
Below is an example postinst snippet for the ftpd-ssl server package (assuming |
| 210 |
|
|
it ships /usr/share/reconf-inetc/ftpd-ssl.xinetd): |
| 211 |
sez |
170 |
|
| 212 |
sez |
266 |
<pre> |
| 213 |
sez |
264 |
case $1 in |
| 214 |
|
|
configure) |
| 215 |
sez |
277 |
if ! -e /var/lib/reconf-inetd/ftpd-ssl.xinetd; then |
| 216 |
sez |
264 |
if which update-inetd; then |
| 217 |
|
|
update-inetd --remove ftp |
| 218 |
|
|
fi |
| 219 |
|
|
fi |
| 220 |
|
|
;; |
| 221 |
|
|
esac |
| 222 |
sez |
266 |
</pre> |
| 223 |
sez |
264 |
|
| 224 |
sez |
277 |
1) in later stable Debian releases, simply drop update-inetd all together |
| 225 |
|
|
(dependency and postinst snippet) |
| 226 |
|
|
|
| 227 |
sez |
265 |
# Requirements for xinetd/reconf-inetd fragments |
| 228 |
sez |
264 |
|
| 229 |
sez |
265 |
According to xinetd.conf(5), xinetd fragments must have the following fields: |
| 230 |
|
|
|
| 231 |
sez |
266 |
<pre> |
| 232 |
sez |
265 |
socket_type (mandatory) |
| 233 |
|
|
wait (mandatory) |
| 234 |
|
|
user (non-internal services only) |
| 235 |
|
|
server (non-internal services only) |
| 236 |
|
|
protocol (RPC and unlisted services only) |
| 237 |
|
|
port (unlisted non-RPC services only) |
| 238 |
sez |
266 |
</pre> |
| 239 |
sez |
265 |
|
| 240 |
|
|
If the protocol field is omitted and the service is listed, reconf-inetd will |
| 241 |
|
|
assume the protocol of the first matching entry from /etc/services. That will |
| 242 |
|
|
be tcp or udp, which currently implies IPv4, so if the intention is IPv6, then |
| 243 |
|
|
tcp6 or udp6 should be explicitly specified in the protocol field. |
| 244 |
|
|
|
| 245 |
sez |
271 |
Unlike, regular xinetd fragment files, reconf-inetd fragment files must have |
| 246 |
|
|
only one service per file. If your package provides more than one service, |
| 247 |
|
|
please install a separate fragment file for each service. This is the case to |
| 248 |
|
|
allow for removal of individual services, by simply removing the related file. |
| 249 |
sez |
265 |
|
| 250 |
sez |
276 |
The disable field in reconf-inetd fragments is completely ignored. |
| 251 |
|
|
reconf-inetd has no notion of maintainer-disabled inetd.conf entries |
| 252 |
|
|
|
| 253 |
sez |
170 |
# xinetd support |
| 254 |
|
|
|
| 255 |
|
|
xinetd configuration with reconf-inetd will become trivial because server |
| 256 |
|
|
packages will have to ship reconf-inetd (ie. xinetd.conf(5) compatible) |
| 257 |
|
|
fragments anyway. |
| 258 |
|
|
|
| 259 |
|
|
Synchronisation between inetd.conf and reconf-inetd fragments is outside this DEP's |
| 260 |
|
|
scope. The fact that inetd.conf (and /etc/xinetd.d) remains the authoritative |
| 261 |
|
|
configuration file implies that any synchronisation requires a user-initiated |
| 262 |
|
|
action, and is thus best implemented as a separate tool. |
| 263 |
|
|
|
| 264 |
sez |
264 |
# Clarification of behaviour on package removal versus package purge |
| 265 |
sez |
170 |
|
| 266 |
|
|
According to rules 0 and 1 in the previously listed table, reconf-inetd does |
| 267 |
|
|
not distinguish between package removal and purge. In other words, |
| 268 |
|
|
/etc/inetd.conf entries that were added by reconf-inetd will be removed upon |
| 269 |
sez |
264 |
package removal, as long as they have not been locally modified. Similarly, a |
| 270 |
|
|
locally-modified inetd.conf entry will not be removed even if the associated |
| 271 |
|
|
package is purged. This is in line with Debian policy, on the basis that |
| 272 |
|
|
inetd.conf is a configuration file, but not a conffile. |
| 273 |
sez |
170 |
|
| 274 |
sez |
264 |
# Current status |
| 275 |
sez |
241 |
|
| 276 |
sez |
264 |
20120206: upload of reconf-inetd to experimental |
| 277 |
|
|
|
| 278 |
sez |
241 |
# Source code repo |
| 279 |
|
|
|
| 280 |
|
|
http://git.debian.org/?p=collab-maint/reconf-inetd.git;a=summary |