3

I know how to use /etc/services but if I change it and the inetd package is later updated via apt-get to a new default one, my changes are gone (happened to me on a apt-get dist-upgrade from Debian Wheezy to Jessie). They are saved in a backup, but I still have to re-integrate my changes or alternartivley miss out on the new defaults from the package manager (by skipping the install of the new default version).

Is there a way to have a user-generated system wide "extension" to /etc/services that gets loaded as well and contains only my changes so that the configuration does not get destroyed with a package update?

I'm working on Debian Jessie, if relevant.

Foo Bar
  • 3,562

3 Answers3

3

This seems to come up in various bugtrackers from time to time: Debian #46049, Debian #711001, RH #133683. But none of these seem to be implemented.

To recap: the Name Service Switch reads /etc/nsswitch.conf where to look for e.g. services information:

$ strace -f -e open,stat getent services > /dev/null
[...]
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/x86_64-linux-gnu/libdb-5.3.so", O_RDONLY|O_CLOEXEC) = 3
open("/var/lib/misc/DB_CONFIG", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/var/lib/misc/services.db", 0x7ffd79d77060) = -1 ENOENT (No such file or directory)
open("/etc/services", O_RDONLY|O_CLOEXEC) = 3
+++ exited with 0 +++

This libnss_db.so.2 could only be found because I installed libnss-db earlier. So, if one manages to create a Berkeley DB database in /var/lib/misc/services.db with additional service names, this could work.

Update: with libnss-db (Debian/unstable here), this is indeed possible:

$ grep ^[A-Z] /etc/default/libnss-db 
ETC = /etc/local
DBS = services
VAR_DB = /var/lib/misc
AWK = awk
MAKEDB = makedb --quiet

$ cat /etc/local/services
# Local services
foobar          1234/tcp                        # Foo
barbaz          4321/udp

$ make
services... done.

$ getent services | wc -l
559

$ getent services foobar barbaz
foobar                1234/tcp
barbaz                4321/udp

And since /etc/local is not a registered configuration directory, it should not be touched by any upgrade process

Otherwise, these pathnames seem to be hardcoded and can only be changed/extended in a recompile, hence the wishlist tickets mentioned above.

$ strings /lib/x86_64-linux-gnu/libnss_files.so.2 | grep services
/etc/services

Note: there's also an libnss-extrausers package, which seems to provide additional files for NSS, but only for passwd, shadow and group information.

fra-san
  • 10,205
  • 2
  • 22
  • 43
ckujau
  • 1,403
3

/etc/services is a conffile, so if you modify it locally and a new package version is installed with a modified version, dpkg will ask you whether to keep your version or install the new one. Unfortunately, it won't give you an easy way to merge your changes.

You can divert the package-provided /etc/services and provide your own.

dpkg-divert --add --local --rename --divert /etc/services.debian /etc/services

If you want to concatenate your own entries or otherwise transform the Debian file, you can run a hook script when APT finishes its job. Declare the script in /etc/apt/apt.conf.d/local-etc-merge

DPkg::Post-Invoke {"cat /etc/services.local /etc/services.debian >/etc/services"}

Alternatively, you can make /etc/services invoke a command when read (that's overkill unless you modify /etc/services.local very often).

  • Post-Invoke seems pretty good. In /etc/services is there a way to say "include services.locale" so that I only have to change one file between package updates and only need to cat > the include command? – Foo Bar Apr 21 '15 at 06:00
  • @FooBar There's no include directive. But with my solution you don't need to change any file on a package update, you only need to do this one-time setup and to re-run cat /etc/services.local /etc/services.debian >/etc/services when you change /etc/services.local. – Gilles 'SO- stop being evil' Apr 21 '15 at 07:54
  • I accepted this answer, because this provides an actual workaround. But the other answers also got a +1, because they teached me nice things. – Foo Bar Jun 27 '15 at 08:50
1

Unfortunately there is no way of doing this. One option would be to "Hold" the netbase package so that it doesn't get updated automatically.

echo "netbase hold" | dpkg --set-selections

Another option might be to declare an /etc/services.local and submit a patch to the netbase maintainer that merged this file and its own /etc/services. I don't see that this would be too difficult except that a modified sort/merge would be required to understand # comment lines.

Chris Davies
  • 116,213
  • 16
  • 160
  • 287