Linux, Unix, /etc

Danger Will Robinson! You are now entering a condescending Unix user zone!
Sponsored links (requires javascript):

A System Administrator's Introduction to TCP Wrappers

Introduction

TCP Wrappers is designed to filter incoming connections to network services. This article looks at how this package can be used to enhance the security of a networking system. The idea of the package is to provide wrapper daemons that can be installed without any changes to existing software. Most TCP/IP applications depend on the client/server model: that is, when a connection is requested by a client, a server process is started on the host to deal with this. TCP Wrappers works by interposing an additional layer, or wrapper, between client and server. In the basic service, the wrapper simply logs the name of the client host and of the requested service, then hands over to the real daemon, neither exchanging information with the client or server, nor imposing overhead on the actual conversation between the two. Optional features may be enabled, including: access control; client user name lookups; and additional protection against hostname spoofing.

Getting the Software

The current version of the software is 7.6. It can be obtained via ftp from ftp://ftp.porcupine.org/pub/security/

Compilation

Many different types of Unix system are supported; you should have no trouble building from source. There are a few decisions to make at compile-time. Features and can be turned on or off through definitions. Here is a list, with default values shown where appropriate:

STYLE = -DPROCESS_OPTIONS

Enable language extensions. This is disabled by default.

FACILITY=LOG_MAIL

Where do log records go? I prefer to set this to LOG_DAEMON, so that everything goes to /var/log/daemon. But you can do what you like!

SEVERITY= LOG_INFO

What level to give to the log message. The default, LOG_INFO, is fine.

HOSTS_ACCESS

When compiled with this option, the wrapper programs support a simple form of access control. Since this is the raison d'être of the suite, this is defined by default!

PARANOID

When compiled with -DPARANOID, the wrappers will always try to look up and double check the client host name, and will always refuse service in case of a discrepancy between hostname and IP address. This is a reasonable policy for most systems.

When compiled without -DPARANOID, the wrappers by default still perform hostname lookup, but hosts where such lookups give conflicting results for hostname and IP address are *not* automatically rejected. They can be matched with the PARANOID wildcard in the access files, and a decision made on whether to grant access.

DOT= -DAPPEND_DOT

This appends a dot to every domain name. For example, example.com becomes example.com.. This is done because on many Unix systems the resolver will append substrings of the local domain, and try to look up those hostnames, before trying to resolve the name it has actually been given. Use of the APPEND_DOT feature stops this waste of time and resources. It is off by default.

AUTH = -DALWAYS_RFC931

Always try to lookup the remote username. Note that for this to be of any use, the remote host must run a daemon that supports the finger protocol; and also, that such lookups are not possible for UDP-based connections. By default, this is turned off, and the wrappers look up the remote username only when the access control rules specify this behaviour.

RFC931_TIMEOUT = 10

Username lookup timeout.

-DDAEMON_UMASK=022

The is the default file permissions mask for processes run under control of the wrappers.

ACCESS = -DHOSTS_ACCESS

Host access control. Note that this can also be turned off at runtime by providing no, or empty, access control tables. Enabled by default.

TABLES = -DHOSTS_DENY=\"/etc/hosts.deny\" -DHOSTS_ALLOW=\"/etc/hosts.allow\"

The pathnames for the access control tables.

HOSTNAME= -DALWAYS_HOSTNAME

Always attempt to look up the client hostname. If this is disabled, the client hostname lookup is postponed until the name is required by an access control rule or by a %letter expansion. If this is what you want, note that paranoid mode must be disabled as well. This is on by default.

-DKILL_IP_OPTIONS

This is for protection against hosts that pretend they have someone else's host address — host address spoofing. this option is not needed on modern Unix systems that can stop source-routed traffic in the kernel e.g. Linux, Solaris 2.x, 4.4BSD and derivatives.

-DNETGROUP

Define if your system has NIS support. This is used only in conjunction with host access control, so if you're not using that, don't bother about this in any case. Off by default.

Some definitions are given that work around system bugs (just the basics here; see Makefile for details). The standard define is:

BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK

Having set the options to your requirements, type

make sys-type

Where sys-type is one of

generic (most bsd-ish systems with sys5 compatibility)
386bsd
aix
alpha
apollo
bsdos
convex-ultranet
dell-gcc
dgux
dgux543
dynix
epix
esix
freebsd
hpux
irix4
irix5
irix6
isc
iunix
linux
machten
mips(untested)
ncrsvr4
netbsd
next
osf
power_unix_211
ptx-2.x
ptx-generic
pyramid
sco
sco-nis
sco-od2
sco-os5
sinix
sunos4
sunos40
sunos5
sysv4
tandem
ultrix
unicos7
unicos8
unixware1
unixware2
uts215
uxp

If the unlikely event of none of these matching your system, then you will have to edit the system dependencies sections in the Makefile and do a 'make other'.

Installation

There are two ways to install the software, which we will call "easy" and "advanced".

Easy Installation

The "easy" recipe requires no changes to existing software or configuration files. Basically, you move the daemons that you want to protect to the directory specified in REAL_DAEMON_DIR in the Makefile, replacing them with copies of the tcpd program. For example, for telnet:

$ mkdir REAL_DAEMON_DIR
$ mv /sbin/in.telnetd REAL_DAEMON_DIR
$ cp tcpd /sbin/in.telnetd

And that is all there is to it. Note that the wrapper, all files used by the wrapper, and all directories in the path leading to those files, should all have read only, or read and execute only, access; they must *not* be writable. So, use modes 755 or 555. There is no need for the wrapper to be set-uid.

Advanced Installation

The advanced installation method leaves your existing daemons alone, but involves simple modifications to the inetd configuration file, /etc/inetd.conf. This is the model I prefer. The changes to inetd.conf are straightforward. For each service to be protected by wrappers, tcpd should be executed in place of the original daemon, passing the original daemon pathname as an argument to tcpd. An example will make this clearer.

Here is a standard inetd.conf record for telnet service:

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

And here is the same record after modification to support TCP Wrappers:

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

Remember after editing this file to tell inetd to re-read it with kill -1.

Configuration

Access Control

The core idea behind TCP Wrappers is that of an access control policy. The policy rules are held in two files:

/etc/hosts.allow

and

/etc/hosts.deny

These are the default pathnames, which can be changed in the Makefile.

Access can be controlled per host, per service, or combinations thereof. Access control can also be used to connect clients to particular services, depending on the requested service, the origin of the request, and what host address the client connects to. For example, a www daemon might serve documents in the native language when contacted from within the country, otherwise in English.

The format of these files is described in detail by hosts_access(5). Basically, each file consists of a set of rules. these rules are searched in the order hosts.allow, hosts.deny, and the search stops at the first match. So, if a host is granted access in host.allow, it doesn't matter if it is then blocked in hosts.deny. Remember, first rule matched determines what action to take.

There are two basic keywords, allow and deny. These are used in conjuction with specific hostnames, or a wildcard from the list below.

A string beginning with . matches all hostnames that conclude with that string. For examle, .example.com would match dunne.example.com.

A string ending with . matches all hosts if whose IP addresses begin with that sequence. For example, 192.168 would match all addresses in the range 192.168.xxx.xxx.

A string beginning with @ is treated as an NIS netgroup name.

A string of the form n.n.n.n/m.m.m.m is treated as a netowrk/mask pair.

There are also some special shorthand names:

ALL

Always matches.

LOCAL

Matches any host whose name does not contain a dot character.

UNKNOWN

Matches a user whose name is unknown, and matches any hsot whose name or address are unknown.

KNOWN

Matches a user whose name is known, and matches any host whose name and address is known.

PARANOID

Matches any host whose name does not match its address.

There is also a set of symbolic names which expand to various information about the client and server. The full list of such expansions is:

%a	the client IP address
%c	client information: user@host, user@IP, etc
%d	argv[0] from the daemon process
%h	client host name or IP address
%n	client host name
%p	process id of the daemon
%s	server information
%u	client user name
%%	literal %

Examples

There are several typical forms of access control which provide examples of using the access control files. note that explicitly-authorised hosts are listed in hosts.allow; most other rules are put in hosts.deny.

To deny all access, leave hosts.allow blank, and put this in hosts.deny

/etc/hosts.deny:

ALL: ALL

To allow all acesss, simply leave both files blank.

To allow controlled access, add rules to hosts.allow and hosts.deny as appropriate. At it's simplest, this involves listing banned sites in hosts.deny.

/etc/hosts.deny:

evilcrackers.com: ALL

On the other hand, you can also deny access to all save selected sites:

/etc/hosts.allow:

example.com:ALL

/etc/hosts.deny:

ALL:ALL

Remember, first match is the important one — the ALL in hosts.deny won't block example.com

Booby Traps

A useful feature is the ability to trigger actions on the host based on attempted connections. For example, should we detect a remote site attempting to use our tftp server, the following rule in /etc/hosts.deny not only rejects the attempt, but notifies the sytem adminsistrator:

in.tftpd: ALL: finger -l @%h 2>&1 | mail -s remote tftp attempt' sysadm
'

Note that use of this feature relies on the PROCESS_OPTIONS option. This option also provides some other useful features.

spawn <shell_command>

Run the specified shell command as a child process.

twist <shell_command>

Replace the current process by the specified shell command.

banners <pathname>

Copy the contents of the file in <pathname> to the client. Useful for sites which are required to display a site policy banner to all users.

See the host_options(5) man page for full details of these and other options.

Logging

Log records are written to the syslog daemon, syslogd, with facility and level as specified in the Makefile at compile-time. What happens to them there is determined by the syslogd config. file, /etc/syslog.conf. If PROCESS_OPTIONS has been defined, the facility and level can be changed at run-time, using the keyword severity, e.g.

severity mail.info

Specifies logging with as facility mail at level info. An undotted argument is understood as a level.

Resources

A good set of man pages comes with the software.

A good account of the thinking which led to the creation of the TCP Wrappers is Venema's paper, TCP WRAPPER: Network monitoring, access control, and booby traps. It is available from his ftp site at ftp.porcupine.org/pub/security in a variety of formats— look for tcp_wrapper.<format>.Z.

Conclusion

In this article, we have shown how to install and configure TCP Wrappers to protect against many common attempts to compromise an Unix box connected to the Internet. Some of the advantages to using this software are: there is no need to modify existing daemons; only simple (and optional) changes to one existing configuration file are necessary; there is no impact on genuine users; it provides protection against a variety of cracking techniques; and there is the ability to install trip wires that notify of an attempted break-in.

[back to Linux, Unix, /etc]



Copyright © 1995-2007 Paul Dunne,

Sponsored links (requires javascript):