Installed?

Most modern distributions should come with TCP Wrappers installed and ready to go. Is your server daemon linked to TCP Wrappers? Check:

$ ldd /usr/sbin/sshd | grep libwrap
        libwrap.so.0 => /lib64/libwrap.so.0 (0x00002b2f57e20000)

Also have a look here:

man hosts.deny

Configuration

TCP Wrappers uses the files /etc/hosts.allow and /etc/hosts.deny to control what connections can be made to wrapped servers.

Note
No daemons need to be restarted because changes to hosts.allow and hosts.deny file take effect immediately.

If these files don’t exist, TCP Wrappers is not being used. Create them as root.

Rules

There can only be one rule per network service in hosts.allow and hosts.deny. In the case of conflicting rules in hosts.allow and hosts.deny the allow rule takes precedent. If there are no matching rules in the hosts.allow or hosts.deny files, then the connection is unrestricted (as if TCP Wappers wasn’t installed).

The rules take this form:

daemon:client [:option1:option2:...]

daemons

Examples of valid daemons
  • ALL is a special daemon specifier that applies to any service.

  • sshd Probably the most important one.

  • in.tftpd

  • in.telnetd

  • in.ftpd

  • slapd

  • portmap????

clients

  • specific.example.com will match just this host. Separate multiples with spaces or commas.

  • .example.com (note leading dot) will match all hosts ending in example.com.

  • .xed.ch EXCEPT test.xed.ch matches anything from xed.ch with the exception of test.xed.ch.

  • /etc/troublemakers matches anything in this file. It’s interpreted as a file if it has a leading /.

  • ALL is a special client designation that means match all hosts.

  • LOCAL matches any host that contains no dot (e.g. localhost).

  • UNKNOWN matches any user that is unknown. Also matches unknown hosts and unknown addresses. This could be useful if you definitely do not want to entertain attempts from users that do not exist in your passwd file or hosts that are not explicitly listed in your /etc/hosts file.

  • KNOWN is the inverse of UNKNOWN.

  • PARANOID matches host names that don’t match the address.

options

See man host_options.

  • :allow This (and deny) makes it possible to keep all rules in a single file.

  • :deny

  • :spawn (/some/shell/command

Example of the spawn option
sshd : hmm.xed.ch :spawn ( /bin/echo `date` "%h tried to use %d" >> login.log ) &
  • :deny

  • :twist replaces the actual request with one set by the server admin. Handy for honeypots and menacing rejection messages.

Example of the twist option
sshd : bad.xed.ch : twist /bin/echo "Go away!" : deny
  • :keepalive Server occasionally pings client until client stops responding.

  • :nice Change the niceness level for this process.

  • :setenv VAR VALUE Modify the process environment.

  • :user nobody Makes the UID kind of safe.

Examples

SSH Login Control

TCP Wrappers is often used to cut down the clutter of brute force ssh login attempts. Note that DenyHosts uses TCP Wrappers. If there’s a real problem with ssh attacks, might think about that. Or fail2ban which can use iptables too.

Very Simple Example

Coop’s minimal configuration suggestion.

echo "sshd : ALL" >> /etc/hosts.deny
echo "sshd : .xed.ch" >> /etc/hosts.allow

Another Very Simple Example

Here’s an even simpler way to block ssh access from every host but the special privileged one. Note that it only uses hosts.deny. A hosts.allow does not need to exist for this to work.

echo "sshd : ALL EXCEPT admin.xed.ch planb.xed.ch" >> /etc/hosts.deny