tcprules(1)
β¨ tcprules(1) β the girl who compiles your rules π
okay bestie, gather round, because this is tcprules, and it's lowkey the bouncer-adjacent bestie of tcpserver(1). she compiles rules for tcpserver(1). that's the whole vibe. let's get into it π
π SYNOPSIS
tcprules cdb tmp
like. two arguments. two. that's it. she's not complicated, she's just powerful π
πΈ DESCRIPTION
so tcpserver(1) optionally follows rules to decide whether a TCP connection is acceptable. optional! but if you're here, you're using them. for example, the rule
18.23.0.32:deny
prohibits connections from IP address 18.23.0.32. yes, that's the whole rule. iconic, honestly. no cap. π«
tcprules reads rules from its standard input and writes them into cdb in a binary format suited for quick access by tcpserver(1). fast reads, pretty source, we love a glow-up π
here's the part that's genuinely so smart: tcprules can be used while tcpserver(1) is running. she ensures that cdb is updated atomically. how? she does it by first writing the rules to tmp and then moving tmp on top of cdb. if tmp already exists, it is destroyed. π
okay important, don't skip this: the directories containingcdbandtmpmust be writable totcprules; they must also be on the same filesystem. fr fr, same filesystem, that's not optional.
if there is a problem with the input or with tmp, tcprules complains and leaves cdb alone. she's dramatic but she's careful π«Ά
and the binary cdb format is portable across machines. take it anywhere, bestie βοΈ
π RULE FORMAT
a rule is one line. one. single. line. periodt.
a file containing rules may also contain comments: lines beginning with # are ignored. π¬
each rule contains an address, a colon, and a list of instructions, with no extra spaces. (the no-extra-spaces thing is real, don't be cute with your whitespace here π) when tcpserver(1) receives a connection from that address, it follows the instructions.
π― ADDRESSES
tcpserver(1) looks for rules with various addresses, in this order:
$TCPREMOTEINFO@$TCPREMOTEIP, if$TCPREMOTEINFOis set;$TCPREMOTEINFO@=$TCPREMOTEHOST, if$TCPREMOTEINFOis set and$TCPREMOTEHOSTis set;$TCPREMOTEIP;=$TCPREMOTEHOST, if$TCPREMOTEHOSTis set;- shorter and shorter prefixes of
$TCPREMOTEIPending with a dot; - shorter and shorter suffixes of
$TCPREMOTEHOSTstarting with a dot, preceded by=, if$TCPREMOTEHOSTis set; =, if$TCPREMOTEHOSTis set; and finally- the empty string.
tcpserver(1) uses the first rule it finds. first match wins, no takebacks π
you should use the-poption totcpserver(1)if you rely on$TCPREMOTEHOSThere. that's a real caveat, not me being extra.
for example, here are some rules:
joe@127.0.0.1:first
18.23.0.32:second
:third
127.:fourth
if $TCPREMOTEIP is 10.119.75.38, tcpserver(1) will follow the third instructions.
if $TCPREMOTEIP is 18.23.0.32, tcpserver(1) will follow the second instructions.
if $TCPREMOTEIP is 127.0.0.1 and $TCPREMOTEINFO is bill, tcpserver(1) will follow the fourth instructions.
if $TCPREMOTEIP is 127.0.0.1 and $TCPREMOTEINFO is joe, tcpserver(1) will follow the first instructions.
you can use tcprulescheck(1) to see how tcpserver will interpret rules in cdb. that's your vibe check tool, use her π
π’ ADDRESS RANGES
tcprules treats 1.2.3.37-53:ins as an abbreviation for the rules 1.2.3.37:ins, 1.2.3.38:ins, and so on up through 1.2.3.53:ins. β¨
similarly, 10.2-3.:ins is an abbreviation for 10.2.:ins and 10.3.:ins.
she's doing the typing so you don't have to, and that's main character energy π
π INSTRUCTIONS
the instructions in a rule must begin with either allow or deny. deny tells tcpserver(1) to drop the connection without running anything. for example, the rule
:deny
tells tcpserver(1) to drop all connections that aren't handled by more specific rules. bye bye π
the instructions may continue with some environment variables, in the form var="x". tcpserver(1) adds an environment variable $var with value x. for example,
10.0.:allow,RELAYCLIENT="@fix.me"
adds an environment variable $RELAYCLIENT with value @fix.me. π
the quotes may be replaced by any repeated character:
10.0.:allow,RELAYCLIENT=/@fix.me/
any number of variables may be listed:
127.0.0.1:allow,RELAYCLIENT="",TCPLOCALHOST="movie.edu"
stack 'em, bestie. as many as you want π
π SEE ALSO
tcpserver(1)tcprulescheck(1)argv0(1)fixcrio(1)recordio(1)rblsmtpd(1)tcpclient(1)who@(1)date@(1)finger@(1)http@(1)tcpcat(1)mconnect(1)tcp-environ(5)
http://cr.yp.to/ucspi-tcp.html
and that's the whole page, bestie π this was tcprules(1) β yes, page one of the manual, section one, general commands manual, and she said what she said β from the ucspi-tcp world over at http://cr.yp.to/ucspi-tcp.html. go compile some rules and slay π¦βπ
π¦ where this page comes from
- debian bookworm: ucspi-tcp 1:0.88-7 Β· LicenseRef-public-domain
- debian trixie: ucspi-tcp 1:0.88-13 Β· LicenseRef-public-domain
- nixos 26.05: ucspi-tcp 0.88
- nixpkgs unstable: ucspi-tcp 0.88
- ubuntu jammy: ucspi-tcp 1:0.88-6 Β· LicenseRef-public-domain
- ubuntu noble: ucspi-tcp 1:0.88-8ubuntu1 Β· LicenseRef-public-domain
- ubuntu resolute: ucspi-tcp 1:0.88-13ubuntu1 Β· LicenseRef-public-domain
- ubuntu stonking: ucspi-tcp 1:0.88-13ubuntu1 Β· LicenseRef-public-domain
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms