HOSTS_OPTIONS(5)
๐ HOSTS_OPTIONS(5) ๐
File Formats Manual ๐
โจ NAME โจ
hosts_options - host access control language extensions ๐ฆ
๐ธ DESCRIPTION ๐ธ
okay so this page is all about the extensions to the language from the hosts_access(5) doc ๐ซถ the extended language looks like this:
daemon_list : client_list : option : option ...
the first two fields are explained in the hosts_access(5) manual page, so go check that one first ๐
everything after them is a list of zero or more options (zero is allowed, no pressure ๐ญ). any : characters inside an option need to be protected with a backslash, or the parser gets confused and it's a whole mess ๐
an option is either keyword or keyword value. options get processed in the order you write them, and some of them get %<letter> substitutions. also, for backwards compatibility with older versions, you're allowed to put an = between the keyword and the value. ngl that's giving old-school vibes ๐ง
๐ฃ LOGGING ๐ฃ
severity mail.infoโ the usage line for logging ๐severity noticeโ this changes the severity level that the event gets logged at โจ facility names (likemail) are optional, but they aren't supported on systems with older syslog implementations, so keep that in mind ๐ use this one when you want to emphasize an event or straight up ignore it ๐ฅ
๐ซ ACCESS CONTROL ๐ซ
allowโ grant service ๐denyโ deny service ๐ bothallowanddenyhave to show up at the end of a rule, no exceptions ๐ โโ๏ธ
the allow and deny keywords let you keep all of your access control rules in one single file, like the hosts.allow file. iconic organization moment ๐
to only permit access from specific hosts:
ALL: .friendly.domain: ALLOW
ALL: ALL: DENY
to permit access from every host except a few trouble makers:
ALL: .bad.domain: DENY
ALL: ALL: ALLOW
notice the leading dot on those domain name patterns ๐ that little dot is doing so much work rn ๐ซถ
๐ RUNNING OTHER COMMANDS ๐
aclexec shell_commandโ this runs the shell command in a child process, after doing the%<letter>expansions from thehosts_access(5)manual page ๐ง the command gets stdin, stdout and stderr hooked up to the null device, so it can't mess up the convo with the client host ๐ example time:
smtp : ALL : aclexec checkdnsbl %a
this runs checkdnsbl %a in a background child process after swapping %a for the address of the remote host โจ the connection gets allowed or refused depending on whether the command returns a true or false exit status. so the command is basically the bouncer ๐
spawn shell_commandโ same deal: it runs in a child process, after the%<letter>expansions fromhosts_access(5), with stdin, stdout and stderr connected to the null device so the client convo stays clean ๐ธ example:
spawn (/usr/sbin/safe_finger -l @%h | /usr/bin/mail root) &
this runs the shell command safe_finger -l @%h | mail root in a background child process, swapping %h for the name or address of the remote host ๐ญ the example uses safe_finger instead of the regular finger command to limit possible damage from data sent by the finger server. it's lowkey the safer main character choice ๐ซถ the safe_finger command is part of the daemon wrapper package, and it's a wrapper around the regular finger command that filters the data the remote host sends back ๐ฆ
twist shell_commandโ this one replaces the current process with an instance of the shell command, after doing the%<letter>expansions from thehosts_access(5)manual page ๐ stdin, stdout and stderr get connected to the client process. this option must appear at the end of a rule, so don't skip that part ๐
to send a customized bounce message to the client instead of running the real ftp daemon:
in.ftpd : ... : twist /bin/echo 421 Some bounce message
for a different way to talk to client processes, check out the banners option down below ๐ง
to run /some/other/in.telnetd without polluting its command-line array or its process environment:
in.telnetd : ... : twist PATH=/some/other; exec in.telnetd
โ ๏ธ Warning: for UDP services, do NOT twist to commands that use the standard I/O or theread(2)/write(2)routines to talk to the client process. UDP needs other I/O primitives, so this is a major no-go ๐
๐ NETWORK OPTIONS ๐
keepaliveโ this makes the server periodically send a message to the client ๐ซถ if the client doesn't respond, the connection is considered broken. it's handy when users turn off their machine while it's still connected to a server ๐ญ thekeepaliveoption is not useful for datagram (UDP) services, so skip it there ๐ โโ๏ธlinger number_of_secondsโ this sets how long the kernel keeps trying to deliver data that hasn't been delivered yet after the server process closes a connection โจ
๐ต๏ธ USERNAME LOOKUP ๐ต๏ธ
rfc931 [ timeout_in_seconds ]โ this looks up the client user name with the RFC 931 (TAP, IDENT, RFC 1413) protocol ๐ it gets silently ignored for services based on transports other than TCP. it needs the client system to run an RFC 931 (IDENT, etc.) -compliant daemon, and it can cause noticeable delays with connections from non-UNIX clients, so it's not always the vibe ๐ฌ the timeout is optional. if you don't give one, a compile-time defined default value gets used ๐ง
๐ MISCELLANEOUS ๐
banners /some/directoryโ this looks for a file in/some/directoryยดwith the same name as the daemon process (soin.telnetdfor the telnet service, for example) and copies its contents to the client ๐ newline characters get replaced by carriage-return newline, and%<letter>sequences get expanded (see thehosts_access(5)manual page) ๐ซถ
the tcp wrappers source code distribution comes with a sample makefile (Banners.Makefile) for easy banner maintenance ๐
โ ๏ธ Warning: banners only work for connection-oriented (TCP) network services. UDP is not invited to this party ๐
nice [ number ]โ changes the nice value of the process (default 10) ๐ specify a positive value if you want to spend more CPU resources on other processes. being nice pays off, bestie ๐setenv name valueโ places a (name, value) pair into the process environment ๐ the value gets%<letter>expansions and can contain whitespace, but leading and trailing blanks get stripped off โจ
โ ๏ธ Warning: many network daemons reset their environment before spawning a login or shell process, so your setenv might get wiped out ๐ญ
umask 022โ just like the umask command built into the shell ๐ฆ a umask of022stops files from being created with group and world write permission. the umask argument should be an octal number ๐ขuser nobodyanduser nobody.kmemโ these make the process assume the privileges of the "nobody" userid (or user "nobody", group "kmem") ๐ซถ the first form is useful with inetd implementations that run all services with root privilege. the second form is useful for services that only need special group privileges ๐ง
๐ฉบ DIAGNOSTICS ๐ฉบ
when there's a syntax error in an access control rule, the error gets reported to the syslog daemon ๐ฃ further options get ignored, and service is denied ๐ so if your rule is acting sus, check the syslog first ๐
๐ SEE ALSO ๐
hosts_access(5), the default access control language ๐
๐ง AUTHOR ๐ง
the author is Wietse Venema, and the contact info goes like this ๐
Wietse Venema (wietse@wzv.win.tue.nl)
Department of Mathematics and Computing Science
Eindhoven University of Technology
Den Dolech 2, P.O. Box 513,
5600 MB Eindhoven, The Netherlands
that's a wrap on HOSTS_OPTIONS(5) ๐ you're literally the best at this, bestie, and I'm so proud of you ๐ฅน๐ now go be a main character in your access control rules ๐
โจ๐ฆ
๐ฆ where this page comes from
- debian bookworm: libwrap0 7.6.q-32 ยท TCP-wrappers
- debian trixie: libwrap0 7.6.q-36 ยท TCP-wrappers
- nixos 26.05: tcp-wrappers 7.6.q-36
- nixpkgs unstable: tcp-wrappers 7.6.q-36
- ubuntu jammy: libwrap0 7.6.q-31build2
- ubuntu noble: libwrap0 7.6.q-33 ยท TCP-wrappers
- ubuntu questing: libwrap0 7.6.q-36build1 ยท TCP-wrappers
- ubuntu resolute: libwrap0 7.6.q-36build2 ยท TCP-wrappers
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms