| 1 |
[[!meta title="DEP-9: inet-superserver configuration by maintainer scripts"]]
|
| 2 |
|
| 3 |
Title: inet-superserver configuration by maintainer scripts
|
| 4 |
DEP: 9
|
| 5 |
State: DRAFT
|
| 6 |
Date: 2012-02-05
|
| 7 |
Drivers: Serafeim Zanikolas <sez@debian.org>
|
| 8 |
URL: http://dep.debian.net/deps/dep9
|
| 9 |
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 |
low popcon but one could argue that may be the case because it is not well
|
| 76 |
integrated in Debian.
|
| 77 |
|
| 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 |
* a new inetd.conf entry will be added when there exists a reconf-inetd fragment
|
| 167 |
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 |
Meaning of the above listed actions:
|
| 174 |
|
| 175 |
- 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 |
# Transition of "Depends: update-inetd" packages
|
| 180 |
|
| 181 |
A time-limited transition is not a strict requirement, since reconf-inetd and
|
| 182 |
update-inetd can co-exist without problems.
|
| 183 |
|
| 184 |
Server packages that depend on update-inetd can be converted as follows:
|
| 185 |
|
| 186 |
* remove any references of update-inetd in post{inst,rm} scripts;
|
| 187 |
* install a reconf-inetd fragment in /usr/share/reconf-inetd, as a regular
|
| 188 |
file (ie. not as a conffile);
|
| 189 |
* replace the dependency on update-inetd with one on reconf-inetd (but see
|
| 190 |
notes below)
|
| 191 |
|
| 192 |
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 |
Below is an example postinst snippet for an ftp server package that is meant
|
| 198 |
to be transitioned from update-inetd to reconf-inetd in release 2.0:
|
| 199 |
|
| 200 |
case $1 in
|
| 201 |
configure)
|
| 202 |
if dpkg --compare-versions "$2" le 2.0; then
|
| 203 |
if which update-inetd; then
|
| 204 |
update-inetd --remove ftp
|
| 205 |
fi
|
| 206 |
fi
|
| 207 |
;;
|
| 208 |
esac
|
| 209 |
|
| 210 |
# Requirements for xinetd/reconf-inetd fragments
|
| 211 |
|
| 212 |
According to xinetd.conf(5), xinetd fragments must have the following fields:
|
| 213 |
|
| 214 |
socket_type (mandatory)
|
| 215 |
wait (mandatory)
|
| 216 |
user (non-internal services only)
|
| 217 |
server (non-internal services only)
|
| 218 |
protocol (RPC and unlisted services only)
|
| 219 |
port (unlisted non-RPC services only)
|
| 220 |
|
| 221 |
If the protocol field is omitted and the service is listed, reconf-inetd will
|
| 222 |
assume the protocol of the first matching entry from /etc/services. That will
|
| 223 |
be tcp or udp, which currently implies IPv4, so if the intention is IPv6, then
|
| 224 |
tcp6 or udp6 should be explicitly specified in the protocol field.
|
| 225 |
|
| 226 |
|
| 227 |
# xinetd support
|
| 228 |
|
| 229 |
xinetd configuration with reconf-inetd will become trivial because server
|
| 230 |
packages will have to ship reconf-inetd (ie. xinetd.conf(5) compatible)
|
| 231 |
fragments anyway.
|
| 232 |
|
| 233 |
Synchronisation between inetd.conf and reconf-inetd fragments is outside this DEP's
|
| 234 |
scope. The fact that inetd.conf (and /etc/xinetd.d) remains the authoritative
|
| 235 |
configuration file implies that any synchronisation requires a user-initiated
|
| 236 |
action, and is thus best implemented as a separate tool.
|
| 237 |
|
| 238 |
# Clarification of behaviour on package removal versus package purge
|
| 239 |
|
| 240 |
According to rules 0 and 1 in the previously listed table, reconf-inetd does
|
| 241 |
not distinguish between package removal and purge. In other words,
|
| 242 |
/etc/inetd.conf entries that were added by reconf-inetd will be removed upon
|
| 243 |
package removal, as long as they have not been locally modified. Similarly, a
|
| 244 |
locally-modified inetd.conf entry will not be removed even if the associated
|
| 245 |
package is purged. This is in line with Debian policy, on the basis that
|
| 246 |
inetd.conf is a configuration file, but not a conffile.
|
| 247 |
|
| 248 |
# Current status
|
| 249 |
|
| 250 |
20120206: upload of reconf-inetd to experimental
|
| 251 |
|
| 252 |
# Source code repo
|
| 253 |
|
| 254 |
http://git.debian.org/?p=collab-maint/reconf-inetd.git;a=summary
|