Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Charming Python: Using the xinetd program for system administration

A great substitute for the inetd program

Teodor Zlatanov (tzz@iglou.com), Programmer, Gold Software Systems
Teodor Zlatanov graduated with an M.S. in computer engineering from Boston University in 1999. He has worked as a programmer since 1992, using Perl, Java, C, and C++. His interests are in open source work on text parsing, 3-tier client-server database architectures, UNIX system administration, CORBA, and project management.

Summary:  Every UNIX administrator is familiar with inetd, the daemon that manages most incoming network connections through a centralized configuration file (inetd.conf). The xinetd daemon is a replacement for inetd that offers many improved or new features, and easier configuration. Ted explains the concepts behind inetd, and gives examples for setting up xinetd at your own site.

Date:  01 Nov 2001
Level:  Introductory
Also available in:   Japanese

Activity:  17585 views
Comments:  

The classic inetd daemon has been around for a long time. There are several ways to replace its functionality, but the most flexible and easiest way seems to be xinetd. Xinetd does all the things inetd can do, and a lot more. TCP wrapping, modular configuration, connection redirection, and load limits on incoming connections are just a few of the features that make xinetd a nice choice for system administrators.

This article is meant for the beginner to intermediate system administrator and the explanations and examples will try not to assume that you are already familiar with inetd. In this article we will look at some simple uses of xinetd, from installation to implementation of security policies.

Before starting

For the purposes of this article, ideally your system should be a recent (2000 or later) mainstream UNIX (Linux, Solaris, BSD) installation. The examples may work with earlier versions of Perl and UNIX, and other operating systems, but their failure to function should be considered an exercise for the reader to solve. The specific examples given are for Red Hat Linux, but they should work (with the exception of chkconfig) on other systems as well.


What's inetd anyway?

To a UNIX system administrator, inetd is as basic as the cp/rm/mv commands. It's always there, ready to handle incoming connections. But what is it, really? What does it do?

The answer begins with TCP/IP (it also includes UDP, but let's not worry about that for now). When you make a connection to a host, you are in fact creating a TCP/IP connection (a socket, usually) -- that's like a telephone call between you and the host. A TCP/IP connection is uniquely defined by the originating host and the receiving host, but there's another identifier. If we all connected to a server, how would it know to distinguish between webserver, telnet, SSH, FTP, and other connections? Sockets are also defined by the port used to make the connection. For instance, port 21 is incoming FTP, 22 is SSH, and 23 is TELNET (you can look in /etc/services on a UNIX system for most of the rest).

Once a connection is made, someone has picked up the phone on the other end. It can either be an operator or a direct line. The direct line means you are directly connected to the server, while the operator is the approach that involves inetd. The operator is really handling a bunch of incoming direct lines (ports on a host), and handing them off in person to the program (server) responsible.

UDP is a different connection method. Like TCP, it is basically a conversation with someone, but it's not guaranteed to be reliable. UDP, to continue the telephone analogy, is like throwing messages on a conveyor belt, and having the recipient stand on the other end of it. You can get a lot more messages through on the conveyor belt, but the recipient may miss a few if there are too many (network traffic is high) or he takes too long reading the messages (the server is busy).

With inetd, you are redirected to a specific server after some checks are performed. There's just one configuration file, inetd.conf, managing all the incoming connections. That makes life easier when adding, deleting, changing, or reviewing services on a system. For instance, ftp is defined as follows on a Solaris system with TCP wrappers:


Listing 1. inetd.conf definition of the FTP service

ftp     stream  tcp     nowait  root    /usr/sbin/tcpd          in.ftpd

These are all the necessary parameters for creating an FTP connection. In brief, we're using TCP/IP (tcp) in stream-oriented (stream) mode, allowing more than one FTP connection at a time (nowait), running as root, and invoking FTP (TCP wrappers, which will in turn invoke the FTP daemon).

Is this hard to parse at 1 AM? Absolutely. Is the complexity necessary? No. Xinetd took the inetd design and modularized it, meaning that each service can be in its own configuration file. Xinetd also added features like the TCP wrappers, making configuration easier.

Xinetd preserved the central configuration (operator) approach, storing all the configuration files in a single place, usually /etc/xinetd.conf and /etc/xinetd.d/* so that system administration gets easier. The modular configuration means that you can distribute a service to several machines by copying it to the xinetd.d directory, and you can remove it similarly. You can even specify extra include directories.

Finally, the xinetd FAQ (see Resources later in this article) states that RPC programs don't work too well with xinetd. No problem, use inetd for RPC and xinetd for everything else. It's like hiring two operators because one speaks Spanish and the other speaks everything else.


Introducing xinetd

So what is xinetd? It's just a program, that's all. There's nothing magical about handling incoming network connections. You could do it in Perl, Python, or Java. Xinetd was written in C, and it's just as fast as its predecessor, inetd, if not faster (for instance, the TCP wrappers don't have to be executed for each incoming connection; they are loaded into memory at startup).

Xinetd is a work in progress. (You may have an outdated version, so make sure you check the home page for the latest; see Resources.) Because it's a work in progress, security holes in xinetd are patched quickly, unlike inetd vulnerabilities, which usually take a lot longer to get patched. Of course, xinetd comes with the source code, so you can review it and see for yourself where vulnerabilities might exist.

How do you define services with xinetd? You write a service file that specifies the specific configuration in addition to the generic parameters specified in /etc/xinetd.conf. So, if /etc/xinetd.conf says:


Listing 2. Example xinetd.conf (standard Red Hat 7.1)

defaults
{
        instances               = 60
        log_type                = SYSLOG authpriv
        log_on_success          = HOST PID
        log_on_failure          = HOST
        cps                     = 25 30
}

service telnet
{
        flags           = REUSE
        socket_type     = stream        
        wait            = no
        user            = root
        server          = /usr/sbin/in.telnetd
        log_on_failure  += USERID
        disable         = yes
}

includedir /etc/xinetd.d

Every service file you place in /etc/xinetd.d will inherit those defaults, and specify its own parameters. The telnet service is defined at the top level here, instead of in the subdirectory. That's perfectly fine, and this modularity allows complex configurations.

To get xinetd to re-read the configuration file, you don't have to restart it. Simply send it the USR2 signal.

What do those parameters mean? Let's run through the whole list. You can also see the list with man xinetd.conf from the command line, if that man page was installed properly, but this summary will try to explain the parameters in simpler terms, without assuming you already know all about sockets and services. Some parameters (rpc_version, rpc_number) were skipped.

General parameters

id
The unique name for this service. A service name is already specified before the braces, but the ID makes it possible to have several protocols for a service that's logically the same. This is of limited use to the casual user. The NFS services, for instance, can run over the UDP or TCP transmission protocols. The time service, which is internal to xinetd, is provided in a TCP and a UDP version with Red Hat Linux 7.1 in /etc/xinetd.d/time and /etc/xinetd.d/time-udp.

type
This should actually be called "specialtype", because it only applies to special services. It can be a combination of "RPC" for RPC services (remote procedure calls, introduced by Sun, causes of many security issues, and best avoided); "INTERNAL" for services built into xinetd, such as the time service; and "UNLISTED" for nonstandard services you won't find in the system lists (/etc/services or /etc/rpc for RPC services).

flags
All the extra flags go here. The list is long and quite technical; the interesting flags are REUSE (for socket reuse, such as telnet), NAMEINARGS/NOLIBWRAP (if you want to invoke the TCP wrappers manually or you want to avoid the wrappers altogether), NODELAY/KEEPALIVE (for tuning TCP sockets), DISABLE (overrides the top-level "disable" parameter), and SENSOR (for detecting and thwarting some types of denial-of-service network attacks).

disable
You always want it set to "no" unless you want the service to be disabled. The Red Hat Linux chkconfig program will switch the "disable" parameter on or off for you; it is probably easier to enable and disable specific services with chkconfig under Red Hat than to do it manually. Note that chkconfig expects to find the service file in /etc/xinetd.d/SERVICE. So for the example in Listing 2 above, chkconfig will not turn telnet on/off when requested. This could be considered a bug or a feature, depending on your viewpoint.

socket_type
Usually you want this set to "stream" unless you are using UDP services, in which case set this to "dgram". There's also "raw" and "seqpacket", but those are pretty unusual.

protocol
This is the protocol to be used for the connection, usually "tcp" or "udp", though in theory you can use anything from /etc/protocols.

wait
If set to "no", xinetd will start a new handler for that service on every connection. If "yes", xinetd expects the handler to deal with all subsequent connections until it dies. In most cases, this is "no".

server, server_args
The program name for the handler, and the parameters it should get. The handler name should not be in the arguments, as is the case with inetd.

port
The port of the service. Usually unnecessary, since the port is mapped to the service by the /etc/services file.

redirect
Allows xinetd to send all traffic to the service to another host. Thus, firewalled hosts can accept secure traffic through a central xinetd forwarder, yet have no connections to the outside network. This feature can also be adopted, with some work, to do service failover between two hosts.

banner, banner_success, banner_fail
A custom block of text from a file to be printed upon any/a successful/an unsuccessful connection.

enabled
Supplements the "disabled" parameter and the DISABLE flag on a global level.

include, includedir
Tells xinetd to include a file or a directory.

Environment parameters

user, group, umask, groups
What UNIX attributes xinetd should impersonate when starting the service handler. This is mostly for insecure services.

nice
A UNIX priority level that determines how important this service is to the system. You can tune it for your system; take a look at the "nice" man page.

env
Environment variables for the service handler.

passenv
What environment variables from xinetd should be passed down to the service handler.

Resource management parameters

instances
Number of handlers that can be started at once. This can be tuned to prevent denial-of-service attacks. Set it to "UNLIMITED" if you want the default (no limits) behavior.

max_load
I: ) If the system is too loaded, stop accepting connections. The load numbers are system dependent, and should be tuned only if you really know what you are doing.

rlimit_as, rlmist_cpu, rlimit_data, rlimit_rss, rlimit_stack
The rlimit parameters specify resource limits (memory, CPU, and specific memory areas) for service handlers.

Security-specific parameters

only_from, no_access
Supplementary to the TCP wrappers, this is a way to block hosts making connections to us. Note that the default is to allow access to everyone, unless the TCP wrappers (whose rules are usually in /etc/hosts.allow) say otherwise.

access_times
The times of day that a service is available. For instance, "6:00-23:00" means the service will be available from 6 AM to 11:01 PM.

log_type, log_on_success, log_on_failure
Various logging options. The USERID flag in particular can be troublesome, because it slows things down to interrogate the connecting machine about the user connecting to us. Avoid USERID if possible.

bind
Allows a service to be specific to an interface, usually in the interest of security. For instance, the FTP service on the inside network would be just FTP, while outside FTP connections would generate intruder alerts. The "id" parameter would be useful here.

per_source
Specifies the maximum instances of a service from a source IP. Useful for handling single-source denial-of-service attacks or buggy programs making too many connections.

cps
Maximum connections per second allowed, and the number of seconds before the service is enabled again. "30 45" would mean "30 incoming connections per second, and wait 45 seconds if that limit is exceeded". For counteracting denial-of-service attacks, mostly.

deny_time
How long service will be denied to someone who sets off a SENSOR flag.


Replacing TCP wrappers

The classic TCP wrappers package is a very useful tool. Through a centralized file, usually /etc/hosts.allow and /etc/hosts.deny, access can be allowed or denied to any hosts necessary, per service. Unfortunately, the TCP wrapper library does not know much about system loads, resource limits, multiple attacks, and so on. Xinetd incorporates the TCP wrapper functionality (through the libwrap library), so you can move to xinetd smoothly and keep using the same configuration files from before.

That's pretty much all there is to the migration. Keep your old hosts.deny and hosts.allow files, and xinetd will happily follow them. Keep in mind, however, that xinetd has many options for control of connections that improve on the TCP wrappers. For instance, limiting connections per second, or connections when the load is too high, can be an invaluable aid to server management.

Make sure you compile xinetd with the libwrap option, or it will not know about the TCP wrappers. If xinetd comes from an RPM on Red Hat Linux, make sure you test that the TCP wrapper files work properly BEFORE you put the machine out in the open.


Advanced usage: failover

Although there are many ways in which xinetd could be used, the redirect parameter gives us the most interesting avenues. Failover, we all know, is pretty hard to do, and hardware failover is expensive. The approach described here is cheap and effective, through simple software. It does have a single point of failure -- the redirecting station, so you should consider whether that's acceptable. If it's not, well, hardware failover is expensive for a reason.

First, decide on a way to pick an "active" machine out of two or more. Let's assume you do it through a script, set_active.pl (we are going to do this for the telnet service, but it will work for any other service that can be switched to an alternate server with no ill effects). The script will take a machine name, which we will use to set the new failover, and a service name, which will give us the right /etc/xinetd.d/SERVICE file to edit. Feel free to customize the script to edit a different file, or take different parameters. The job could be done with a one-liner "perl -p -i -e" script, but this way you can expand a lot more in the future, and error-check your parameters.

This is simple enough. Now you just have to decide on a procedure to invoke this script - either manually, through a cron job, or triggered by another program. It becomes an architecture decision at this point. Don't forget to send the USR2 signal to xinetd at this point, or just restart it if you wish. Automating signals can be done with "pkill -USR2 xinetd" on Red Hat Linux, and restarting xinetd is just "/etc/rc.d/init.d/xinetd restart" on Linux or something similar on most UNIX systems.

This sort of failover will NOT work for database connectivity without a lot of extra work on the database side. You are best advised to use it for protocols such as rsync, ssh, ftp, and telnet, where the failover machines don't depend on each other.


Conclusion

Clearly, the plethora of features xinetd offers is a good reason to use it. Don't forget, however, the other benefits of xinetd: bugs are fixed as soon as they are reported, the source code is freely available, and migrating the existing inetd configuration (when you use the itox helper program that comes with xinetd) is a snap.

Why not use xinetd? Backward compatibility would be your best reason, followed closely by incompatibility with your specific platform. The xinetd software is most popular on Solaris and Linux servers, so your particular platform may have issues that are unresolved.


Resources

About the author

Teodor Zlatanov graduated with an M.S. in computer engineering from Boston University in 1999. He has worked as a programmer since 1992, using Perl, Java, C, and C++. His interests are in open source work on text parsing, 3-tier client-server database architectures, UNIX system administration, CORBA, and project management.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux, Open source
ArticleID=11174
ArticleTitle=Charming Python: Using the xinetd program for system administration
publish-date=11012001
author1-email=tzz@iglou.com
author1-email-cc=