The official llllloooooo blog

Monday, November 2, 2020

Getting IPv6 services working with xinetd on LFS

This is another post in the series of my trying to get Linux From Scratch working on a Raspberry Pi to my satisfaction.

If you are an IPv6 obsessive like me then you won't accept any tool or service that does not natively and easily support IPv6. xinetd doesn't really make it easy and obvious how to enable small services for IPv6 but it can probably be forgiven since development seems to have finished on it in about 2007. This post is the list of steps I went through to get xinetd working and working with IPv6.

xinetd is a more modern and secure replacement for the older inetd tool which can be used to start many small old school services such as telnet / echo / discard / chargen / daytime / systat etc. These are the kinds of tools that you can enable on a cisco router using the command "service tcp-small-servers" .

Even though the Linux From Scratch manuals do not encourage installing inetd or xinetd I still think it's useful to have these cool little services available. Anyone who knows about these tools already knows that they are not encrypted or secure. For that reason it makes sense to only make them available on your local trusted network segments. 

I managed to compile xinetd on the raspberry pi by first installing the tirpc library as per the instructions at

http://www.linuxfromscratch.org/blfs/downloads/stable/BLFS-BOOK-10.0-nochunks.html#libtirpc

Then I slightly modified the installed libtirpc include files so that they looked like the "old" rpc include files that xinetd depends on by using the following shell commands. This is required so that xinetd compiles rpc tools nicely.

# First change to the directory where the original 
#rpc include files (netdb.h) are
cd /usr/include/rpc

# Next move them all to the tirpc include directory
mv netdb.h ../tirpc/rpc

# Delete the old rpc directory and link it to the 
# more modern tirpc version
cd /usr/include
rm -rf rpc
ln -sfv tirpc/rpc rpc

To obtain xinetd follow the instructions as seen in an older version of Beyond LFS as seen at

http://www.linuxfromscratch.org/blfs/view/7.7/server/xinetd.html

And download the source gz file from

ftp://anduin.linuxfromscratch.org/BLFS/svn/x/xinetd-2.3.15.tar.gz

Decompress and compile as per the instructions seen in the link above but before you type "make" run the following command to tell the build to use the newly installed tirpc libraries.

export LDFLAGS="-ltirpc"

Now to IPv6. The secret is that you have to use the largely undocumented xinetd configuration file attribute v6only . This attribute isn't even mentioned in the xinetd.conf man page and good luck finding details on your favorite search engine. The only reason I knew about it was the thread I've linked below that talks about others trying to get IPv6 working with xinetd services

* xinetd doesn't listen on IPv6 by default
https://bugzilla.redhat.com/show_bug.cgi?id=195265

If you try to do this without using the secret v6only attribute then you might end up with error messages in your log file (/var/log/daemon.log on my system) that look something like

xinetd[123]: bind failed (Address already in use (errno = 98)). service = chargen-stream-v6
xinetd[123]: Service chargen-stream-v6 failed to start and is deactivated.

Basically what you have to do is when you define a service in your xinetd.conf files is to specify it twice. First the IPv4 version and then the IPv6 version. For example, for tcp chargen (port 19) I have the following in my config file

# IPv4 version of tcp chargen
service chargen
{
        disable         = no
        type            = internal
        id              = chargen-stream
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no
        flags           = IPV4
}

# IPv6 version of tcp chargen
service chargen
{
        disable         = no
        type            = internal
        id              = chargen-stream-v6
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no
        flags           = IPV6
        v6only          = yes
}


Technically you don't need the "flags = IPV4" statement in the first paragraph because xinetd will only create an IPv4 socket anyway even if you leave this statement out, but including this attribute makes the paragraphs a lot clearer in describing what they are doing.

So assuming you have xinetd services working for IPv4 you should be able to get them working for IPv6 by just copying each paragraph, changing the "id" slightly to make it unique, and then adding the "flags = IPV6" and "v6only = yes" attributes.

Good luck!

No comments: