HOSTS_OPTIONS(5)

๐Ÿ“ฆ
version 7.6.q ยท 4 versions
, in debian bookworm, debian trixie, nixos 26.05, nixpkgs unstable, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute

๐Ÿ’– 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 (like mail) 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 ๐Ÿ’€ both allow and deny have 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 the hosts_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 from hosts_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 the hosts_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 the read(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 ๐Ÿ˜ญ the keepalive option 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 (so in.telnetd for 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 the hosts_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 of 022 stops files from being created with group and world write permission. the umask argument should be an octal number ๐Ÿ”ข
  • user nobody and user 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 ๐Ÿ’…โœจ๐Ÿฆ‹