Softpanorama
(slightly skeptical) Open Source Software Educational Society

May the source be with you, but remember the KISS principle ;-)

Google   


TCP Wrappers

News

Lecture Notes Inetd Recommended Books Recommended Links xnetd Humor   Etc

Lecture Notes

Based on O'Reilly Practical Unix Security book

Intetd "superdaemon"

Originally, BSD Unix set a different server program running for every network service. As the number of services grew in the mid 1980s, Unix systems started having more and more server programs sleeping in the background, waiting for network connections. Although the servers were sleeping, they nevertheless consumed valuable system resources such as process table entries and swap space. Perhaps more importantly, configuring these servers was somewhat difficult, as each server was started up in a different way and had a different syntax for defining which port they should bind to and which UID they should use when running.

Today's Unix systems use the Internet daemon, inetd, to centralize the handling of lightweight Internet services. The Internet daemon listens and accepts connections on many network ports at the same time. When a connection is received, inetd automatically starts up the appropriate TCP-based or UDP-based server running under the appropriate UID. The Internet daemon also simplifies the writing of application-specific daemons themselves, as each daemon can be written so that it reads from the network on standard input and writes back to the network on standard output—no special calls from the Berkeley socket library are required.

Some Unix systems use an alternative Internet daemon called xinetd. Instead of locating all of its configuration in a single inetd.conf file, xinetd typically requires a separate configuration file for each service in the directory /etc/xinetd.d.

inetd uses the bind( ) call to attach itself to many network ports and then uses the select( ) call to determine which of these ports is the one that has received a connection.

The inetd daemon is run at boot time as part of the startup procedure. When inetd starts executing, it examines the contents of the /etc/inetd.conf file to determine which network services it is supposed to manage. The program will reread its configuration file if it is sent a HUP signal

A sample inetd.conf file
# Internet server configuration database
#
ftp       stream tcp nowait root    /usr/sbin/ftpd ftpd
#telnet   stream tcp nowait root    /usr/sbin/telnetd telnetd
#shell    stream tcp nowait root    /usr/sbin/rshd rshd
#login    stream tcp nowait root    /usr/sbin/rlogind rlogind
#exec     stream tcp nowait root    /usr/sbin/rexecd rexecd
#uucp     stream tcp nowait uucp    /usr/sbin/uucpd uucpd
#finger   stream tcp nowait nobody  /usr/sbin/fingerd fingerd
#tftp     dgram  udp wait   nobody  /usr/sbin/tftpd tftpd
#comsat   dgram  udp wait   root    /usr/sbin/comsat comsat
talk      dgram  udp wait   root    /usr/sbin/talkd talkd
ntalk     dgram  udp wait   root    /usr/sbin/ntalkd ntalkd
#echo     stream tcp nowait root    internal
#discard  stream tcp nowait root    internal
#chargen  stream tcp nowait root    internal
#daytime  stream tcp nowait root    internal
#time     stream tcp nowait root    internal
#echo     dgram  udp wait   root    internal
#discard  dgram  udp wait   root    internal
#chargen  dgram  udp wait   root    internal
#daytime  dgram  udp wait   root    internal
#time     dgram  udp wait   root    internal

Each line of the inetd.conf file contains at least six fields, separated by spaces or tabs:

Service name

Specifies the service name that appears in the /etc/services file. inetd uses this name to determine which port number it should listen to. If you are testing a new service or developing your own daemon, you may wish to put that daemon on a nonstandard port. Unfortunately, inetd requires that the service name be a symbolic value such as smtp, rather than a numeric value such as 25.

Socket type

Indicates whether the service expects to communicate via a stream or on a datagram basis.

Protocol type

Indicates whether the service expects to use TCP- or UDP-based communications. TCP is used with stream sockets, while UDP is used with dgram, or datagrams.

Wait/nowait

If the entry is "wait," the server is expected to process all subsequent connections received on the socket. If "nowait" is specified, inetd will fork( ) and exec( ) a new server process for each additional datagram or connection request received. Most UDP services are "wait," while most TCP services are "nowait," although this is not a firm rule. Although some manpages indicate that this field is used only with datagram sockets, the field is actually interpreted for all services.

User

Specifies the UID that the server process will be run as. This can be root (UID 0), daemon (UID 1), nobody (often UID -2 or 65534), or any other user of your system. This field allows server processes to be run with fewer permissions than root to minimize the damage that could be done if a security hole is discovered in a server program.

Command name and arguments

The remaining arguments specify the command name to execute and the arguments passed to the command, starting with argv[0].

Some services, like echo, time, and discard, are listed as "internal." These services are so trivial that they are handled internally by inetd rather than requiring a special program to be run. Although these services are useful for testing, they can also be used for denial of service attacks. You should therefore disable them.

You should routinely check the entries in the /etc/inetd.conf file and verify that you understand why each of the services in the file is being offered to the Internet. Sometimes, when attackers break into systems, they create new services to make future break-ins easier. If you cannot explain why a service is being offered at your site, you may wish to disable it until you know what purpose it serves. In many circumstances, it is better to disable a service that you are not sure about than it is to leave it enabled in an effort to find out who is using it at a later point in time: if somebody is using the service, they are sure to let you know! One easy way to list all of the services that are enabled is:

% grep -v "^#" /etc/inetd.conf
talk    dgram   udp     wait    root    /usr/sbin/tcpd  in.talkd
ntalk   dgram   udp     wait    root    /usr/sbin/tcpd  in.ntalkd
pop-3   stream  tcp     nowait  root    /usr/sbin/tcpd popper -c -C -p 2
auth    stream  tcp     nowait  nobody  /usr/sbin/tcpd identd -o -E -i

Because of the importance of the /etc/inetd.conf file, you may wish to track changes to this file using a source code control system such as RCS or CVS. You may also wish to use a consistency-checking tool such as Tripwire or detached PGP signatures to verify that all changes to the file are authorized and properly recorded.

The idea of TCP Wrappers as controlling layer for Inetd

TCP Wrappers is a package developed by Wietse Venema (who also wrote the SATAN security package) at the Eindhoven University of Technology as a countermeasure against attacks on their university systems. TCP_wrappers is an IP packet filtering and network access logging facility for inetd.  TCP_wrappers is usually configured to "wrap" itself around TCP-based services defined in inetd.conf.

Tcp Wrappers is a single program called "tcpd". Unfortunately, it is distributed under the plural name of "TCP wrappers". It is a program and 2 configuration files. Paraphrased from the readme: With this package you can monitor and filter incoming requests for the SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK, and other network services. The package provides a tiny daemon wrapper program that can be installed without any changes to existing software or to existing configuration files. The wrapper reports the name of the client host and of the requested service; the wrapper does not exchange information with the client or server applications, and imposes no overhead on the actual conversation between the client and server applications. Optional features are: access control to restrict what systems can connect to what network daemons; client user name lookups with the RFC 931 etc. protocol; additional protection against hosts that pretend to have someone elses host name; additional protection against hosts that pretend to have someone else's host address.

The TCP Wrappers program can log incoming connections via syslog—whether or not the actual Internet daemon provides logging. TCP Wrappers also allows different server executables to be invoked for a given service depending on the source IP address of the incoming connection.

While TCP Wrappers can be run as a standalone program, today it is most commonly used as a library (libwrap) that is linked into the inetd program. By using a modern inetd program, your system will automatically honor the /etc/hosts.allow and /etc/hosts.deny files, which are described later.

 

Tcp_wrappers are designed to verify a remote hostname with its IP number before allowing a connection to be established. If a workstation's IP number and hostname do not match when checked against the domain tables maintained by the Internet Service Provider providing Internet connectivity for that workstation, tcp_wrappers will close the session before the user enters a username or password.  The original tcp_wrappers work in tandem with inetd can can control all programs launched by inetd like telnet and ftp using the hosts.allow & host.deny files. If you only want trusted networks/machine to be able to start telnet, you just add them into hosts.allow and turn off everyone else with hosts.deny.

TCP wrappers can monitor and filter incoming requests for telnet, ftp, rlogin, rsh, finger, talk, and just about anything else that run out of inetd.conf.

Original telnetd line in inetd.conf.

telnet stream tcp nowait root in.telnetd in.telnetd

With TCP wrappers installed:

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd

When a remote host accesses a "wrapped" service, the connection has to first go through the logging and access control mechanisms enforced by tcp_wrappers before it is allowed to proceed.

There are several reasons why tcp_wrappers is an excellent security tool:

The way to limit 'inetd' programs like telnet and ftp is with tcpwrappers using the hosts.allow & host.deny files. If you only want trusted networks/machine to be able to start telnet, you add them into hosts.allow and turn off everyone else with hosts.deny. Linux Journal had a good article in a security issue a year or so ago that I recommend. You can also limit users to ftp with the /etc/ftpusers file. As for the shut down, I usually set up a shutdown group and set up scripts to to call shutdown for the members.

The tcpd program can be set up to monitor incoming requests for telnet, finger, ftp, exec, rsh, rlogin, tftp, talk, comsat and other services that have a one-to-one mapping onto executable files.

Operation is as follows: whenever a request for service arrives, the inetd daemon is tricked into running the tcpd program instead of the normal server. tcpd logs the request and does some additional checks. When all is well, tcpd runs the appropriate server program and goes away.

Optional features include pattern-based access control, client username lookups with the RFC 931 protocol, protection against hosts that pretend to have someone else's host name, and protection against hosts that pretend to have someone else's network address.

Utilities (tcpdchk and tcpdmatch) are included to aid writing of /etc/hosts.allow and /etc/hosts.deny files. tcpdmatch does not understand '?' syntax in /etc/inet.conf, so it may generate spurious warnings noting that optional servers were not found.

What TCP Wrappers does

The TCP Wrappers system gives the system administrator a high degree of control over incoming TCP connections. The system is invoked after a remote host connects to your computer. It is invoked either through a subroutine library that is linked into the Internet server or through a standalone program started up through inetd. Once running, the TCP Wrappers system performs the following steps:

  1. It opens the /etc/hosts.allow file. This file contains access control rules and actions for each protocol.

  2. It scans through the file, line by line, until it finds a rule that matches the particular protocol and source host that has connected to the server.

  3. It executes the action(s) specified in the rule. If appropriate, control is then turned over to the network server.

  4. If no matching action is found, the file /etc/hosts.deny is opened and sequentially read line by line. If a matching line is found, access is denied and the corresponding action performed.

  5. If no match is found in either the /etc/hosts.allow or the /etc/hosts.deny file, then the connection is allowed by default.

If this seems overly complicated to you, you are right—it is. The reason for having two files, /etc/hosts.allow and /etc/hosts.deny, is to allow for backward compatibility with previous versions of TCP Wrapperss that did not provide for different kinds of actions on each line of the file. These earlier versions simply had a list of allowed hosts for each protocol in the file /etc/hosts.allow and a list of hosts to deny for each protocol in the file /etc/hosts.deny. These days, TCP Wrapperss is compiled with the -DPROCESS_OPTIONS option, which causes the advanced rules to be properly interpreted. Unfortunately, as is often the case, the complexity of having two incompatible modes of operation remains to allow for backward compatibility.

!

Your /etc/hosts.deny should contain only a single rule "ALL:ALL" to deny all access by default. Keeping all the rules in a single file simplifies maintenance. Using /etc/hosts.allow, which has priority over /etc/hosts.deny, ensures that if someone else accidentally modifies the wrong file, it won't override your rules.

The actions implemented by TCP Wrappers are quite sophisticated. Specifically, options can:

The TCP Wrappers system allows you to make up for many deficiencies in other network daemons. You can add logging to services that are not otherwise logged, add sophisticated and easily changeable access control lists, and even substitute different versions of a service daemon depending on the calling host. These are some of the reasons that the TCP Wrappers system has become standard on both free and commercial Unix offerings in recent years.

 The TCP Wrappers configuration language

The TCP Wrappers system has a simple but powerful language and a pair of configuration files that allow you to specify whether incoming connections should be accepted.

If TCP Wrappers is compiled with the -DPROCESS_OPTIONS flag, then each line of the /etc/hosts.allow and /etc/hosts.deny files have the following format:

daemon_list : client_host_list : option [ : option ...]

Alternatively, if TCP Wrappers is compiled without the -DPROCESS_OPTIONS flag, then each line in the /etc/hosts.allow and /etc/hosts.deny files has the following format:[10]

daemon_list : client_host_list [: shell_command]

in which:

daemon_list

Specifies the command name (argv[0]) of a list of TCP daemons (e.g., telnetd). More than one daemon can be specified by separating them with blanks or commas. The reserved keyword "ALL" matches all daemons; "ALL EXCEPT" matches all daemons except for the specific one mentioned (e.g., "ALL EXCEPT in.ftpd").

client_host_list

Specifies the hostname or IP address of the incoming connection. More than one host can be specified by separating them with blanks or commas. Incomplete hostnames and IP addresses can be used for wildcarding . You can also use the format username@hostname to specify a particular user on a remote computer, although the remote computer must correctly implement the ident protocol. And as we noted in the discussion of ident, the identification returned is not something that can always be believed. The keyword ALL matches all clients; for a full list of keywords, see the table.

option [ : option ...]

Specifies one or more options that are executed for the particular service.

shell_command

Specifies a command that should be executed if the daemon_list and client_host_list are matched. A shell_command can be specified directly in the /etc/hosts.allow or /etc/hosts.deny file if TCP Wrappers is compiled without the -DPROCESS_OPTIONS flag. If TCP Wrappers is compiled with the -DPROCESS_OPTIONS flag, shell commands must be specified with the spawn option. A limited amount of token expansion is available within the shell command;

 Syntax for the "hosts" field in the tcpwrappers /etc/hosts.allow and /etc/hosts.deny files

Hostname as it appears in the /etc/hosts.allow or /etc/hosts.deny file

Has the following effect

ALL

Matches all hosts.

KNOWN

Matches any IP address that has a corresponding hostname; also matches usernames when the ident service is available.

LOCAL

Matches any host that does not have a period (.) in its name.

PARANOID

Matches any host for which double reverse-hostname/IP address translation does not match.

UNKNOWN

Matches any IP address that does not have a corresponding hostname; also matches usernames when the ident service is not available.

host.domainhost.subdomain

Matches the specific hostname.

.subdomain.domain

If the hostname begins with a period (.), the hostname will match any host whose hostname ends with the hostname (in this case, ".subdomain.domain").

111.222.333.444

Matches the specific IP address 111.222.333.444, for example 10.1.1.1

kkk.lll.mmm.

kkk.lll.

kkk.

If the hostname ends with a period (.), the hostname is interpreted as the beginning of an IP address. The string "18." will match any host with an IP address of 18.0.0.1 through 18.255.255.254. The string "192.168.1." will match any host with an IP address of 192.168.1.0 through 192.168.1.255.

a pattern EXCEPT another pattern

Matches any host that is matched by a pattern except those that also match another pattern.

The EXCEPT operator may also be used for specifying an Internet service.

 Options available for TCP Wrappers when compiled with -DPROCESS_OPTIONS

Option

Effect

allow

Allows the connection.

deny

Denies the connection.

Options for dealing with sub-shells

nice ±nn

Changes the priority of the process to ±nn. Use numbers such as +4 or +8 to reduce the amount of CPU time allocated to network services.

setenv name value

Sets the environment variable name to value for the daemon.

spawn shell_command

Runs the shell_command. The streams stdin, stdout, and stderr are connected to /dev/null to avoid conflict with any communications with the client.

twist shell_command

Runs the shell_command. The streams stdin, stdout, and stderr are connected to the remote client. This allows you to run a server process other than the one specified in the file /etc/inetd.conf. (Note: this will not work with most UDP services.)

umask nnn

Specifies the umask that should be used for sub-shells. Specify it in octal.

user username

Assumes the privileges of username. (Note: TCP Wrappers must be running as root for this option to work.)

user username.groupname

Assumes the privileges of username and sets the current group to be groupname.

Options for dealing with the network connection

banners /some/directory/

Specifies a directory that contains banner files. If a filename is found in the banner directory that has the same name as the network server (such as telnetd), the contents of the banner file are sent to the client before the TCP connection is turned over to the server. This process allows you to send clients messages—for example, informing them that unauthorized use of your computer is prohibited.

keepalive

Causes the Unix kernel to periodically send a message to a client process; if the message cannot be sent, the connection is automatically broken.

linger seconds

Specifies how long the Unix kernel should spend trying to send a message to the remote client after the server closes the connection.

rfc931 [timeout in seconds]

Specifies that the ident protocol should be used to attempt to determine the username of the person running the client program on the remote computer. The timeout, if specified, is the number of seconds that TCP Wrappers should spend waiting for this information.

 

Token expansion available for the TCP Wrappers shell command

Token

Mnemonic

Expands to

%a

Address

The IP address of the client

%A

Address

The IP address of the server (useful if the server system has more than one network interface)

%c

Client info

username@hostname (if username is available); otherwise, only hostname or IP address

%d

Daemon name

The name of the daemon (argv[0])

%h

Hostname

The hostname of the client (IP address if hostname is unavailable)

%H

Hostname

The hostname of the server (IP address if hostname is unavailable)

%p

Process

The process ID of the daemon process

%s

Server info

daemon@host

%u

User

The client username (or unknown)

%%

Percent

Expands to the "%" character

Theoretically the TCP Wrappers are vulnerable to IP spoofing because it uses IP addresses for authentication. In practice, this is not a significant concern, because TCP protocols as a rule require bidirectional communications to do anything useful. Furthermore, most TCP/IP implementations now use unpredictable sequence numbers, significantly reducing the chances of a successful spoofing attack.

TCP Wrappers also provides only limited support for UDP servers, because once the server is launched, it will continue to accept packets over the network, even if those packets come from "blocked" hosts, unless the UDP server is linked with the TCP Wrappers library and has been specially written to consult the TCP Wrappers access control lists after each new request is received.

Making sense of your TCP Wrappers configuration files

The configuration files we have shown so far are simple; unfortunately, sometimes things get more complicated. The TCP Wrappers system comes with a utility called tcpdchk that can scan through your configuration file and report on a wide variety of potential configuration errors. This is important because the TCP Wrappers system relies on many configuration files (/etc/services, /etc/inetd.conf, /etc/hosts.allow, and /etc/hosts.deny) and requires that the information between these files be consistent.

Here is an example of using the tcpdchk program; each line in this example represents a potential security problem:

% tcpdchk
warning: /etc/hosts.allow, line 24: ipop3d: no such process name in /etc/inetd.conf
warning: /etc/hosts.allow, line 39: sshd: no such process name in /etc/inetd.conf


We'll explore these "warnings" one at a time.

The first line of output refers us to line 24 of the file /etc/hosts.allow, which is shown here:

ipop3d : ALL : ALLOW

To understand the error no such process name in /etc/inetd.conf, we need to now refer to the file /etc/inetd.conf. This file has a line for the ipop3d daemon, but as the warning from tcpdchk implies, the process is not named ipop3d—it is named popper:

# example entry for the optional pop3 server
#                                                                                        
------------------------------
pop3    stream  tcp  nowait root /usr/local/libexec/ipop3d       popper

We must either change line 24 to refer to the process name popper, or change the entry in /etc/inetd.conf to use the name ipop3d. We'll change the file /etc/hosts.allow and rerun the tcpdchk program. Here is the new line 24:

popper : ALL : ALLOW

Now let's rerun the tcpdchk program:

r2# tcpdchk
warning: /etc/hosts.allow, line 24: popper: service possibly not wrapped
warning: /etc/hosts.allow, line 39: sshd: no such process name in /etc/inetd.conf
r2#

We are now told that the service is "possibly not wrapped." This is because tcpdchk is reading through the /etc/inetd.conf file and looking for "tcpd," the name of the TCP Wrappers executable. Because support for TCP Wrappers is compiled into the version of inetd that this computer is using, tcpd is not used, so tcpdchk reports a warning (which we ignore).

The second warning is that there is a rule in the /etc/hosts.allow file for the sshd service, but there is no matching daemon listed in the /etc/inetd.conf file. This is actually not an error: the sshd service is started up directly at boot time, not by inetd. Nevertheless, the program is linked with the TCP Wrappers library and honors the commands in the /etc/hosts.allow file.

The TCP Wrappers system comes with another utility program called tcpdmatch, which allows you to simulate an incoming connection and determine if the connection would be permitted or blocked with your current configuration files. In the following example, we will see if the user simsong@k1.vineyard.net is allowed to ssh into our machine:

r2# tcpdmatch
usage: tcpdmatch [-d] [-i inet_conf] daemon[@host] [user@]host
        -d: use allow/deny files in current directory
        -i: location of inetd.conf file
r2# tcpdmatch sshd simsong@k1.vineyard.net
warning: sshd: no such process name in /etc/inetd.conf
client:   hostname K1.VINEYARD.NET
client:   address  204.17.195.90
client:   username simsong
server:   process  sshd
matched:  /etc/hosts.allow line 39
option:   allow 
access:   granted
r2#

Ignoring the warning in the first line, we can see that permission would be granted by line 39 of the /etc/hosts.allow file. This line reads:

sshd : ALL : allow

Programs such as tcpdchk and tcpdmatch are excellent complements to the security program TCP Wrappers because they help you head off security problems before they happen. Wietse Venema should be complimented for writing and including them in his TCP Wrappers release; other programmers should follow his example.

Before answering this question, let's first provide a little background. TCP Wrappers has been around for many, many years. It is used to restrict access to TCP services based on host name, IP address, network address, etc. For more detailed on what TCP Wrappers is and how you can use it, see tcpd(1M). TCP Wrappers was integrated into Solaris starting in Solaris 9 where both Solaris Secure Shell and inetd-based (streams, nowait) services were wrapped. Bonus points are awarded to anyone who knows why UDP services are not wrapped by default.

TCP Wrappers support in Secure Shell was always enabled since Secure Shell always called the TCP Wrapper function host_access(3) to determine if a connection attempt should proceed. If TCP Wrappers was not configured on that system, access, by default, would be granted. Otherwise, the rules as defined in the hosts.allow and hosts.deny files would apply. For more information on these files, see hosts_access(4). Note that this and all of the TCP Wrappers manual pages a stored under /usr/sfw/man in Solaris 10. To view this manual page, you can use the following command:

$ man -M /usr/sfw/man -s 4 hosts_access

inetd-based services use TCP Wrappers in a different way. In Solaris 9, to enable TCP Wrappers for inetd-based services, you must edit the /etc/default/inetd file and set the ENABLE_TCPWRAPPERS parameter to YES. By default, TCP Wrappers was not enabled for inetd.
 

New usage of TCP Wrappers in Solaris 10

In Solaris 10, two new services were wrapped: sendmail and rpcbind.

To enable TCP Wrappers support for inetd-based services:

# inetadm -M tcp_wrappers=true
# svcadm refresh inetd


This will enable TCP Wrappers for inetd-based (streams, nowait) services like telnet, rlogin, and ftp (for example):

# inetadm -l telnet | grep tcp_wrappersdefault tcp_wrappers=TRUE

You can see that this setting has taken effect for inetd by running the following command:

# svcprop -p defaults inetd
defaults/tcp_wrappers boolean true


Note that you can also use the svccfg(1M) command to enable TCP Wrappers for inetd-based services.

# svccfg -s inetd setprop defaults/tcp_wrappers=true
# svcadm refresh inetd


Whether you use inetadm(1M) or svccfg is really a matter of preference. Note that you can also use inetadm or svccfg to enable TCP Wrappers on a per-service basis. For example, let's say that we wanted to enable TCP Wrappers for telnet but not for ftp. By default, both the global and per-service settings for TCP Wrappers are disabled:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
default tcp_wrappers=FALSE

# inetadm -l ftp | grep tcp_wrappers
default tcp_wrappers=FALSE


To enable TCP Wrappers for telnet, use the following command:

# inetadm -m telnet tcp_wrappers=TRUE

Let's check out settings again:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
tcp_wrappers=TRUE

# inetadm -l ftp | grep tcp_wrappers
default tcp_wrappers=FALSE


As you can see, TCP Wrappers has been enabled for telnet but none of the other inetd-based services. Pretty cool, eh?

You can enable TCP Wrappers support for rpcbind by running the following command:

# svccfg -s rpc/bind setprop config/enable_tcpwrappers=true
# svcadm refresh rpc/bind


This change can be verified by running:

# svcprop -p config/enable_tcpwrappers rpc/bind
true


 

Old News ;-)

Glenn Brunette's Security Weblog Enabling TCP Wrappers on Solaris 10

Before answering this question, let's first provide a little background. TCP Wrappers has been around for many, many years. It is used to restrict access to TCP services based on host name, IP address, network address, etc. For more detailed on what TCP Wrappers is and how you can use it, see tcpd(1M). TCP Wrappers was integrated into Solaris starting in Solaris 9 where both Solaris Secure Shell and inetd-based (streams, nowait) services were wrapped. Bonus points are awarded to anyone who knows why UDP services are not wrapped by default.

TCP Wrappers support in Secure Shell was always enabled since Secure Shell always called the TCP Wrapper function host_access(3) to determine if a connection attempt should proceed. If TCP Wrappers was not configured on that system, access, by default, would be granted. Otherwise, the rules as defined in the hosts.allow and hosts.deny files would apply. For more information on these files, see hosts_access(4). Note that this and all of the TCP Wrappers manual pages a stored under /usr/sfw/man in Solaris 10. To view this manual page, you can use the following command:

$ man -M /usr/sfw/man -s 4 hosts_access

inetd-based services use TCP Wrappers in a different way. In Solaris 9, to enable TCP Wrappers for inetd-based services, you must edit the /etc/default/inetd file and set the ENABLE_TCPWRAPPERSparameter to YES. By default, TCP Wrappers was not enabled for inetd.

In Solaris 10, two new services were wrapped: sendmail and rpcbind. sendmail works in a way similar to Secure Shell. It always calls the host_access function and therefore TCP Wrappers support is always enabled. Nothing else needs to be done to enable TCP Wrappers support for that service. On the other hand, TCP Wrappers support for rpcbind must be enabled manually using the new Service Management Framework ("SMF"). Similarly, inetd was modified to use a SMF property to control whether TCP Wrappers is enabled for inetd-based services.

Let's look at how to enable TCP Wrappers for inetd and rpcbind...

To enable TCP Wrappers support for inetd-based services, you can simply use the following commands:

# inetadm -M tcp_wrappers=true
# svcadm refresh inetd

This will enable TCP Wrappers for inetd-based (streams, nowait) services like telnet, rlogin, and ftp (for example):

# inetadm -l telnet | grep tcp_wrappers
default  tcp_wrappers=TRUE

You can see that this setting has taken effect for inetd by running the following command:

# svcprop -p defaults inetd
defaults/tcp_wrappers boolean true

Note that you can also use the svccfg(1M) command to enable TCP Wrappers for inetd-based services.

# svccfg -s inetd setprop defaults/tcp_wrappers=true
# svcadm refresh inetd

Whether you use inetadm(1M) or svccfg is really a matter of preference. Note that you can also use inetadm or svccfg to enable TCP Wrappers on a per-service basis. For example, let's say that we wanted to enable TCP Wrappers for telnet but not for ftp. By default, both the global and per-service settings for TCP Wrappers are disabled:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
default  tcp_wrappers=FALSE

# inetadm -l ftp | grep tcp_wrappers
default  tcp_wrappers=FALSE

To enable TCP Wrappers for telnet, use the following command:

# inetadm -m telnet tcp_wrappers=TRUE

Let's check out settings again:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
         tcp_wrappers=TRUE

# inetadm -l ftp | grep tcp_wrappers
default  tcp_wrappers=FALSE

As you can see, TCP Wrappers has been enabled for telnet but none of the other inetd-based services. Pretty cool, eh?

You can enable TCP Wrappers support for rpcbind by running the following command:

# svccfg -s rpc/bind setprop config/enable_tcpwrappers=true
# svcadm refresh rpc/bind

This change can be verified by running:

# svcprop -p config/enable_tcpwrappers rpc/bind
true

That is all that there is to it! Quick, easy and painless! As always, let me know what you think!

Take care!

Technorati Tag:

Apr 06 2005, 04:30:38 PM EDT Permalink

Trackback URL: http://blogs.sun.com/roller/trackback/gbrunett/Weblog/tcp_wrappers_on_solaris_10
Comments:
Just wondering if using IP filter would not be a better way of blocking/allowing machines to connect to services? I used to use TCP Wrappers all the time, but find now, that I rarely use them in favor of using ipfilter? Is there some advantage to using both? Just curious....

Posted by Jason Grove on April 07, 2005 at 11:58 PM EDT #

Jason,

Thank you for your question. In my opinion, I agree with you - I too would rarely use TCP Wrappers in favor of IP Filter. The reasons for this are simple - IP Filter simply has a more rich feature set and offers greater flexibility for defining filtering policy. Further, if you use Solaris containers, keep in mind that the IP Filter policy is defined in the global zone (versus TCP Wrappers which is done per container). The benefit of configuring IP Filter from the global zone is that if a local zone is breached, an attacker (even with root privileges) will not be able to alter the firewall policy or touch the firewall logs since they are safely protected in the global zone.

That said, TCP Wrappers was designed to protect TCP services and it does that very well. Further it offers an easy to understand and use interface for configuring policy. The choice to use IP Filter or TCP Wrappers will likely depend on your experience and comfort level with these tools as well as on your filtering requirements. If you are looking for a more comprehensive host-based firewall solution however, I would certainly recommend IP Filter.

Thanks again!

Glenn

Posted by Glenn Brunette (192.18.128.12) on April 08, 2005 at 01:17 PM EDT
Website: http://blogs.sun.com/gbrunett/ #

Nice article. To answer the bonus question, the UDP services are not wrappered because they are stateless so there is no connection to manage. As the first comment said, IP filter can manage services, including UDP, because it is low enough in the protocol stack to cover both UDP and TCP.

Posted by Ben Strother on August 17, 2005 at 08:20 PM EDT
Website: http://www.livejournal.com/~wr4th/ #

Securing your network: An introduction to TCP wrappers  By Paul Dunne

Linux.com TCP Wrappers for Security  - May 27th, 1999  by Michael J. Wise

[****] Linux Security 101 Issue 14 By Kelley Spoon, mars@loeffel.txdirect.net -- very good discussion of tcpd

There's a daemon that's probably been installed on your machine that you don't know about. Or at least, you're not aware of what it can do. It's called tcpd, and it's how we shut off access to some of the basic services that the Bad Guys can use to get on our system.

Since tcpd can be pretty complex, I'm not going to go into all the details and tell you how to do the fancy stuff. The goal here is to keep the mischievous gibbons from knocking down what it took so long for use to set up.

tcpd is called into action from another daemon, inetd, whenever someone tries to access a service like in.telnetd, wu.ftpd, in.fingerd, in.rshd, etc. tcpd's job is to look at two files and determine if the person who is trying to access the service has permission or not.

The files are /etc/hosts.allow and /etc/hosts.deny. Here's how it all works:

  1. Someone tries to use a service that tcpd is monitoring.
  2. tcpd wakes up, and makes a note of the attempt to the syslog.
  3. tcpd then looks hosts.allow
    • if it finds a match, tcpd goes back to sleep and lets the user access the service.
  4. tcpd now takes a look at hosts.deny
    • if it finds a match, tcpd closes the user's connection
  5. If it can't find a match in either file, or if both files are empty, tcpd shrugs, guesses it's OK to let the user on, and goes back to sleep.

Now, there are a couple of things to note here. First, if you haven't edited hosts.allow or hosts.deny since you installed Linux, then tcpd assumes that you want to let everyone have access to your machine. The second thing to note is that if tcpd finds a match in hosts.allow, it stops looking. In other words, we can put an entry in hosts.deny and deny access to all services from all machines, and then list ``friendly'' machines in the hosts.allow file.

Let's take a look at the man page. You'll find the info you need by typing man 5 hosts_access (don't forget the 5 and the underscore).

       daemon_list : client_list

       daemon_list is a list of one or more daemon process  names
         or wildcards

       client_list  is  a  list  of  one or more host names, host
         addresses, patterns or wildcards  that will  be matched
         against the remote host name or address. 
       
       List elements should be separated by blanks and/or commas.

Now, if you go take a look at the man page, you'll notice that I didn't show you everything that was in there. The reason for that is because the extra option (the shell_command) can be used to do some neat stuff, but *most Linux distributions have not enabled the use of this option in their tcpd binaries*. We'll save how to do this for an article on tcpd itself.

If you absolutely have to have this option, get the source from here and recompile.

Back to business. What the above section from the hosts_access man page was trying to say is that the format of hosts.[allow|deny] is made up of a list of services and a list of host name patterns, separated by a ``:''

You'll find the name of the services you can use by looking in your /etc/inetd.conf...they'll be the ones with /usr/sbin/tcpd set as the server path.

The rules for determining host patterns are pretty simple, too:

And finally, there are some wildcards you can use:

Ok. Enough technical stuff. Let's get to some examples.

Let's pretend we have a home LAN, and a computer for each member of the family.

Our home network looks like this:

    linux.home.net      192.168.1.1
    dad.home.net	192.168.1.2
    mom.home.net	192.168.1.3
    sis.home.net	192.168.1.4
    bro.home.net        192.168.1.5

Now, since no one in the family is likely to try and ``hack root,'' we can assume they're all friendly. But....we're not so sure about the rest of the people on the Internet. Here's how we go about setting things up so people on home.net have full access to our machine, but no one else does. In /etc/hosts.allow:

# /etc/hosts.allow for linux.home.net

ALL: .home.net

And in /etc/hosts.deny

# /etc/hosts.deny for linux.home.net

ALL : ALL

Since tcpd looks at hosts.allow first, we can safely deny access to all services for everybody. If tcpd can't match the machine sending the request to ``*.home.net'', the connection gets refused.

Now, let's pretend that Mom has been reading up on how Unix stuff works, and she's started doing some unfriendly stuff on our machine. In order to deny her access to our machine, we simply change the line in hosts.allow to:

ALL: .home.net except mom.home.net

Now, let's pretend a friend from....uh....friend.com wants to get something off our ftp server. No problem, just edit hosts.allow again:

# /etc/hosts.allow for linux.home.net

ALL: .home.net except mom.home.net
wu.ftpd: .friend.com

Things are looking good. The only problem is that the name server for home.net is sometimes down, and the only way we can identify someone as being on home.net is through their IP address. Not a problem:

# /etc/hosts.allow for linux.home.net

ALL: .home.net except mom.home.net
ALL: 192.168.1. except 192.168.1.3
ALL: .friend.com

And so on....

I have found that's it's easier to deny everybody access, and list your friends in hosts.allow than it is to allow everybody access, and deny only the people who you know are RBG's. If you are running a private machine, this won't really be a problem, and you can rest easy.

However, if you're trying to run a public service (like an ftp archive of Tetris games for different OS's) and you can't afford to be this paranoid, then you need shouldn't put anything in hosts.allow, and just put all of the people you don't want touching your machine in hosts.deny

Recommended Links


In case of broken links please try to use Google search. If you find the page please notify us about new location
Google     

[Jun 4, 2006] Glenn Brunette's Security Weblog/ Enabling TCP Wrappers on Solaris 10

Tip of the Month: Enabling TCP Wrappers in Solaris 10

Before answering this question, let's first provide a little background. TCP Wrappers has been around for many, many years. It is used to restrict access to TCP services based on host name, IP address, network address, etc. For more detailed on what TCP Wrappers is and how you can use it, see tcpd(1M). TCP Wrappers was integrated into Solaris starting in Solaris 9 where both Solaris Secure Shell and inetd-based (streams, nowait) services were wrapped. Bonus points are awarded to anyone who knows why UDP services are not wrapped by default.

TCP Wrappers support in Secure Shell was always enabled since Secure Shell always called the TCP Wrapper function host_access(3) to determine if a connection attempt should proceed. If TCP Wrappers was not configured on that system, access, by default, would be granted. Otherwise, the rules as defined in the hosts.allow and hosts.deny files would apply. For more information on these files, see hosts_access(4). Note that this and all of the TCP Wrappers manual pages a stored under /usr/sfw/man in Solaris 10. To view this manual page, you can use the following command:

$ man -M /usr/sfw/man -s 4 hosts_access

inetd-based services use TCP Wrappers in a different way. In Solaris 9, to enable TCP Wrappers for inetd-based services, you must edit the /etc/default/inetd file and set the ENABLE_TCPWRAPPERSparameter to YES. By default, TCP Wrappers was not enabled for inetd.

In Solaris 10, two new services were wrapped: sendmail and rpcbind. sendmail works in a way similar to Secure Shell. It always calls the host_access function and therefore TCP Wrappers support is always enabled. Nothing else needs to be done to enable TCP Wrappers support for that service. On the other hand, TCP Wrappers support for rpcbind must be enabled manually using the new Service Management Framework ("SMF"). Similarly, inetd was modified to use a SMF property to control whether TCP Wrappers is enabled for inetd-based services.

Let's look at how to enable TCP Wrappers for inetd and rpcbind...

To enable TCP Wrappers support for inetd-based services, you can simply use the following commands:

# inetadm -M tcp_wrappers=true
# svcadm refresh inetd

This will enable TCP Wrappers for inetd-based (streams, nowait) services like telnet, rlogin, and ftp (for example):

# inetadm -l telnet | grep tcp_wrappers
default  tcp_wrappers=TRUE

You can see that this setting has taken effect for inetd by running

Note that you can also use the svccfg(1M) command to enable TCP Wrappers for inetd-based services.

# svccfg -s inetd setprop defaults/tcp_wrappers=true
# svcadm refresh inetd

Whether you use inetadm(1M) or svccfg is really a matter of preference. Note that you can also use inetadm or svccfg to enable TCP Wrappers on a per-service basis. For example, let's say that we wanted to enable TCP Wrappers for telnet but not for ftp. By default, both the global and per-service settings for TCP Wrappers are disabled:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
default  tcp_wrappers=FALSE

# inetadm -l ftp | grep tcp_wrappers
default  tcp_wrappers=FALSE

To enable TCP Wrappers for telnet, use the following command:

# inetadm -m telnet tcp_wrappers=TRUE

Let's check out settings again:

# inetadm -p | grep tcp_wrappers
tcp_wrappers=FALSE

# inetadm -l telnet | grep tcp_wrappers
         tcp_wrappers=TRUE

# inetadm -l ftp | grep tcp_wrappers
default  tcp_wrappers=FALSE

As you can see, TCP Wrappers has been enabled for telnet but none of the other inetd-based services. Pretty cool, eh?

You can enable TCP Wrappers support for rpcbind by running the following command:

# svccfg -s rpc/bind setprop config/enable_tcpwrappers=true
# svcadm refresh rpc/bind

This change can be verified by running:

# svcprop -p config/enable_tcpwrappers rpc/bind
true

That is all that there is to it! Quick, easy and painless! As always, let me know what you think!

Take care!

TCP Wrappers and xinetd

Controlling access to network services can be a challenge. Firewalls are useful for controlling access in and out of a particular network, but they can be difficult to configure. TCP wrappers and xinetd control access to services by hostname and IP addresses. In addition, these tools also include logging and utilization management capabilities that are easy to configure.

Purpose of TCP Wrappers

Many modern network services, such as SSH, Telnet, and FTP, make use of TCP wrappers, a program that is designed to stand between an incoming request and the requested service. TCP wrappers is installed by default with a server-class installation of Red Hat Linux, providing many advantages over running a variety of different services, each with their own access control methods.

The idea behind TCP wrappers is that, rather than allowing an incoming client connection to communicate directly with a network service daemon running as a separate process on a server system, the target of the request is "wrapped" by another program, allowing a greater degree of access control and logging of who is attempting to use the service.

The functionality behind TCP wrappers is provided by libwrap.a, a library that network services, such as xinetd, sshd, and portmap, are compiled against. Additional network services, even networking programs you may write, can be compiled again libwrap.a to provide this functionality. Red Hat Linux bundles the necessary TCP wrapper programs and library in the tcp_wrappers-<version> RPM file.

TCP Wrapper Advantages

When someone attempts to access a network service using TCP wrappers, a small wrapper program reports the name of the service requested and the client's host information. The wrapper program does not directly send any information back to the client, and after the access control directives are satisfied, the wrapper gets out of the way, not placing any additional overhead on the communication between the client and server.

TCP wrappers provide two basic advantages over other network service control techniques:

  • The connecting client is unaware that TCP wrappers are in use. Legitimate users will not notice anything different, and attackers never receive any additional information about why their attempted connections failed.
  • TCP wrappers operate in a manner that is separate from the applications the wrapper program protects. This allows many applications to share a common set of configuration files for simpler management.

Network monitoring, access control & booby traps using TCP Wrappers Part 1

By Trevor Warren <trevor@freeos.com>

This tool has been successfully used for shielding off systems and for detection of cracker activity. It has no impact on legal computer users, and does not require any change to existing systems software or configuration files. The tool has been installed world-wide on numerous UNIX systems without any source code change. Such is the beauty of TCP Wrappers.

Almost every application of the TCP/IP protocols is based on a client-server model. For example, when someone uses the telnet command to connect to a host, a telnet server process is started on the target host. The server process connects the user to a login process. A few examples are shown in table 1.

client server application
________________________________
telnet telnetd remote login
ftp ftpd file transfer
finger fingerd show users
systat systatd show users

Table 1. Examples of TCP/IP client-server pairs and
their applications.

The usual approach is to run one daemon process that waits for all kinds of incoming network connections. Whenever a connection is established this daemon (usually called inetd on our Linux boxes) runs the appropriate server program and goes back to sleep, waiting for other connections. See the example as illustrated below.

client server application
________________________________
telnet telnetd remote login
(foo1.bar) (foo2.bar)

We are on a client Linux box called foo1.bar and want to connect to a remote Linux box called foo2.bar which resides on a remote network. We then use the telnet client application from my box i.e foo1.bar to connect to the remote telnet server box foo2.bar. Have a look at the graphical illustrations as given below.
 

              -------------------      -----------------    -----------
foo1.bar---| client(ftp,telnet..) |---------| INETD server |--------| login |
            --------------------      -----------------    -----------

Figure 1. The inetd daemon process listens on the ftp,
telnet etc. network ports and waits for incoming con-
nections. The figure shows that a user has connected to
the ftp/telnet port.
 
            -----------------      -----------------    ---------
     user---| telnet client |--------| telnet server |--------| login |
            -----------------      -----------------    ---------
                   (foo1.bar)                           (foo2.bar) 

Figure 2. The inetd process has started a telnet
server process that connects the user to a login pro-
cess. Meanwhile, inetd waits for other incoming con-
nections. This illustrates an unprotected machine.

Fortunately, the author of TCP wrapper came up with a simple solution that did not require any change to existing software, and that turned out to work on all UNIX systems that were ever tried it on. The trick was to make a swap. Move the vendor-provided network server programs to another place, and install a trivial program in the original place of the network server programs. Whenever a connection was made, the trivial program would just record the name of the remote host, and then run the original network server program.

 

            -----------------      -----------------
     user---| telnet client |---------|  tcp wrapper  |----> logfile
            -----------------      -----------------
               (foo1.bar)                                (foo2.bar)

Figure 3. The original telnet server program has been
moved to some other place, and the tcp wrapper has tak-
en its place. The wrapper logs the name of the remote
host to a file. This illustrates a protected machine.

 

            -----------------      -----------------    ---------
     user---| telnet client |---------| telnet server |-------| login |
            -----------------      -----------------    ---------
                   (foo1.bar)                            (foo2.bar)

Figure 4. The tcp wrapper program has started the real
telnet server and no longer participates. The user can-
not notice any difference.

Lets look at the logs capable of being generated by our TCP wrapper application.

May 22 14:43:29 tuegate: systatd: connect from monk.rutgers.edu
May 22 15:08:30 tuegate: systatd: connect from monk.rutgers.edu
May 22 15:09:19 tuewse: fingerd: connect from monk.rutgers.edu
May 22 15:14:27 tuegate: telnetd: connect from cumbic.bmb.columbia.edu
May 22 15:23:06 tuegate: systatd: connect from cumbic.bmb.columbia.edu
May 22 15:23:56 tuewse: fingerd: connect from cumbic.bmb.columbia.edu

Some of the first cracker connections observed with the tcp wrapper program by the author. Each connection is recorded with: time stamp, the name of the local host, the name of the requested service (actually, the network server process name), and the name of the remote host.

Automatic reverse fingers had proven useful in the authors fight against the cracker, so he decided to integrate the "ad hoc" reverse finger tool with TCP Wrappers. To this end, the access control language was extended so that arbitrary shell commands could be specified.

/etc/hosts.allow:

in.tftpd: LOCAL, .foo.bar

/etc/hosts.deny:

in.tftpd: ALL: /usr/ucb/finger -l @%h 2>&1 | /usr/ucb/mail wswietse

This is an example of a booby trap on the tftp service. The entry in the first access control file says that tftp connections from hosts within its own domain are allowed. The entry in the second file causes the TCP Wrapper to perform a reverse finger in all other cases. The "%h" sequence is replaced by the actual remote host name. The result is sent to the administrator by email.

Our discussion till now gives only a limited illustration of the use of booby traps. Booby traps can be much more useful when installed on firewall systems, whose primary purpose is to separate an organizational network from the rest of the world. A typical firewall system provides only a limited collection of network services to the outer world. For example, telnet and smtp. By placing booby traps on the remaining network ports one can implement an effective early-warning system.

[Jan 7, 2005] BigAdmin - Submitted Tech Tip Enabling TCP Wrappers in the Solaris 10 Operating System Glenn Brunette, April, 2005

April, 2005 (BigAdmin)

First let's first provide a little background. TCP Wrappers has been around for many, many years (see Wietse Venema's FTP archive). It is used to restrict access to TCP services based on host name, IP address, network address, and so on. For more details on what TCP Wrappers is and how you can use it, see tcpd(1M). TCP Wrappers was integrated into the Solaris Operating System starting in the Solaris 9 release, where both Solaris Secure Shell and inetd-based (streams, nowait) services were wrapped. Bonus points are awarded to anyone who knows why UDP services are not wrapped by default.

TCP Wrappers support in Secure Shell was always enabled since Secure Shell always called the TCP Wrapper function host_access(3) to determine if a connection attempt should proceed. If TCP Wrappers was not configured on that system, access, by default, would be granted. Otherwise, the rules as defined in the hosts.allow and hosts.deny files would apply. For more information on these files, see hosts_access(4). Note that this and all of the TCP Wrappers manual pages are stored under /usr/sfw/man in the Solaris 10 OS. To view this manual page, you can use the following command:

$ man -M /usr/sfw/man -s 4 hosts_access

inetd-based services use TCP Wrappers in a different way. In the Solaris 9 OS, to enable TCP Wrappers for inetd-based services, you must edit the /etc/default/inetd file and set the ENABLE_TCPWRAPPERS parameter to YES. By default, TCP Wrappers was not enabled for inetd.

In the Solaris 10 OS, two new services were wrapped: sendmail and rpcbind. sendmail works in a way similar to Secure Shell. It always calls the host_access function and therefore TCP Wrappers support is always enabled. Nothing else needs to be done to enable TCP Wrappers support for that service. On the other hand, TCP Wrappers support for rpcbind must be enabled manually using the new Service Management Facility (SMF). Similarly, inetd was modified to use a SMF property to control whether TCP Wrappers is enabled for inetd-based services.

Installing, configuring, and using tcp wrapper to log unauthorized connection attempts on systems running Solaris 2.x

Installing TCP Wrappers on Solaris 7

[Sep 7, 2004 ] BigAdmin - Submitted Tech Tip Configuring TCP Wrappers for the Solaris Operating System

Solaris 9 SSH already has libwrap support compiled on. In S10 and later rpcbind is linked with libwrap so TCP Wrapper style controls are available for all RPC-based protocols (NIS, NFS etc)

Commentor: Casper Dik
Added: September 7, 2004
Comment:

It is rather pointless to install TCP wrappers for Solaris 9 and later as the version included in the OS is exactly the same as the one available on porcupine. That version has also been reved twice because of bugs we ran into. Solaris 9 SSH already has libwrap support compiled on. In S10 and later we also provide rpcbind linked with libwrap.


Copyright © 1996-2008 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

Standard disclaimer: The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: June 02, 2008