nbdkit-ip-filter(1)

πŸ’– nbdkit-ip-filter(1) πŸ’–

okay so bestie, this is straight out of the NBDKIT manual section β€” it's the page for nbdkit-ip-filter(1) and it's literally the bouncer for your nbdkit party. pull up a chair, we're doing this πŸ’…


✨ NAME ✨

nbdkit-ip-filter β€” filter clients by IP address, process ID, user ID, group ID and more 🫢


πŸ“œ SYNOPSIS πŸ“œ

nbdkit --filter=ip PLUGIN [allow=addr[,addr...]]
                          [deny=addr[,addr...]]

🌸 DESCRIPTION 🌸

nbdkit-ip-filter is the vibe-check-at-the-door filter: it can allow or deny client connections based on their IP address. no cap.

ngl though, usually it's better to handle this outside nbdkit β€” like with TCP wrappers or a firewall β€” but this filter exists for when those aren't available. it's the backup plan that ate πŸ’…


πŸ’… EXAMPLES πŸ’…

🌈 Filter by IP address

nbdkit --filter=ip [...] allow=loopback deny=all

let clients connect over the loopback address (that's IPv4 or IPv6), and deny everybody else. periodt.

nbdkit --filter=ip [...] deny=8.0.0.0/8

allow any client except the ones coming from the IPv4 8.0.0.0/8 network. bye πŸ‘‹

nbdkit --filter=ip [...] allow=anyipv6 deny=all

let IPv6 clients connect from literally anywhere, deny all other sources. IPv6 stays winning ✨

πŸ¦‹ Filter by Unix domain socket peer

nbdkit -U $tmpdir/sock --filter=ip [...] allow=uid:`id -u` deny=all

only allow the current user (that's id -u) to connect over the socket. main character only.

want extra security on top? layer it by creating the socket inside a temporary directory that only that user can access. iconic.

nbdkit -U $tmpdir/sock --filter=ip [...] allow=gid:`id -g` deny=all

allow anyone in the same group as the current user to connect to the Unix domain socket.

and same as the previous one: layer extra security by creating the socket inside a temporary directory that only the group can access. πŸŽ€


πŸ”₯ RULES πŸ”₯

when a client connects, this filter checks its source address against the allow and deny lists, in this exact order:

  1. if the address matches anything in the allow list β†’ permission is granted βœ…
  2. if the address matches anything in the deny list β†’ permission is denied ❌
  3. otherwise β†’ permission is granted (yes really, default is yes) πŸ™ˆ

if either the allow or deny parameter isn't there, it's just treated as an empty list. and no, the order you type them on the command line does not matter β€” the allow list is always processed first, the deny list second. the filter has a system and it's sticking to it.

the allow and deny parameters each hold a comma-separated list of any of these:

  • all, any β€” these two keywords (same meaning, no diff) match any source.
  • allipv4, anyipv4 β€” match any IPv4 address.
  • allipv6, anyipv6 β€” match any IPv6 address.
  • allunix, anyunix β€” match any connection over a Unix domain socket.
  • allvsock, anyvsock β€” match any connection over an AF_VSOCK socket.
  • loopback β€” (nbdkit β‰₯ 1.48) any loopback address, both IPv4 or IPv6.
  • loopbackipv4, loopbackv4, loopback4 β€” (nbdkit β‰₯ 1.48) the IPv4 loopback address.
  • loopbackipv6, loopbackv6, loopback6 β€” (nbdkit β‰₯ 1.48) the IPv6 loopback address.
  • A.B.C.D β€” matches the single IPv4 address A.B.C.D, for example 192.168.2.0.
  • A.B.C.D/NN β€” matches the range of IPv4 addresses A.B.C.D/NN, for example 192.168.2.0/24 or 10.0.0.0/8.
  • A:B:... β€” matches the single IPv6 address A:B:.... the usual IPv6 address representations can be used (see RFC 5952).
  • A:B:.../NN β€” matches a range of IPv6 addresses A:B:.../NN.
  • dn:WILDCARD, issuer-dn:WILDCARD β€” (nbdkit β‰₯ 1.40, not Windows) matches the TLS Distinguished Name (DN) of the client certificate, or of the client certificate's issuer, against the WILDCARD. in the examples below the quotes are there to protect the wildcard from the shell β€” they are not part of the matching:
nbdkit --filter=ip allow=dn:"*,O=BigCo,*" [...]

nbdkit --filter=ip allow=issuer-dn:"CN=BigCo" [...]

check out nbdkit_peer_tls_dn(3), nbdkit_peer_tls_issuer_dn(3) and nbdkit-tls(1) for more on DNs.

heads up bestie: using this rule has important performance implications, see "Late filtering" below. 😭

comma splitting is not done inside parameters that start with dn: or issuer-dn:. see "Comma splitting" below.

  • pid:PID β€” (nbdkit β‰₯ 1.24, Linux only) matches the process ID PID, if the client connects over a Unix domain socket.
ngl, process IDs get recycled, so this alone is not secure enough to guarantee only one specific desired process can connect. but you could use it as an extra check. πŸ’€
  • security:LABEL β€” (nbdkit β‰₯ 1.36, not Windows) matches the security context of the client (usually the SELinux label, IPSEC label or NetLabel).
  • uid:UID β€” (nbdkit β‰₯ 1.24) matches the numeric user ID UID, if the client connects over a Unix domain socket.
  • gid:GID β€” (nbdkit β‰₯ 1.24) matches the numeric group ID GID, if the client connects over a Unix domain socket.
  • vsock-cid:CID, vsock-port:PORT β€” (nbdkit β‰₯ 1.24) these match the CID or port number for AF_VSOCK sockets.

πŸŽ€ PARAMETERS πŸŽ€

  • allow=addr[,...] β€” set the list of allow rules. this parameter is optional; if you omit it, the allow list is empty.
  • deny=addr[,...] β€” set the list of deny rules. this parameter is optional too; if you omit it, the deny list is empty.

🫢 NOTES 🫢

πŸŒ™ Not filtered

if you give neither the allow nor the deny parameter, the filter literally does nothing. it's just standing there, existing, serving no purpose. respect.

Unix domain sockets and AF_VSOCK sockets were always unfiltered in nbdkit ≀ 1.22. the ability to filter them got added in nbdkit β‰₯ 1.24. glow up ✨

in nbdkit ≀ 1.38, connections from non-IP, non-Unix, non-vsock sockets (whatever that would even be??) were allowed unfiltered. in nbdkit β‰₯ 1.40, unknown socket families are denied. stricter era, we love to see it.

πŸ’« Common patterns of usage

permit the known good connections and deny everything else:

nbdkit --filter=ip ... allow=good1,good2,... deny=all

block the troublemakers but let everything else through:

nbdkit --filter=ip ... deny=bad1,bad2,...

πŸ“ Comma splitting

you can supply each allow and deny parameter multiple times. the rules get concatenated.

also, each allow or deny parameter can contain multiple rules, split at commas (,).

these two sets of rules are equivalent:

nbdkit --filter=ip allow=good1 allow=good2,good3 deny=all

nbdkit --filter=ip allow=good1,good2 allow=good3 deny=all

because TLS Distinguished Names (DNs) contain commas, the filter has a special exception: if the first characters of the allow or deny parameter match dn: or issuer-dn:, then the whole parameter is not split. which means you can match on multiple DNs naturally:

nbdkit --filter=ip \
       allow=dn:"*,O=BigCo,*" \
       allow=issuer-dn:"CN=BigCo" [...]

🧚 Late filtering

normally this filter runs the filtering rules super early in the connection β€” right after nbdkit has received an open socket from the client. filtering happens in the .preconnect callback.

"Callback lifecycle" in nbdkit-plugin(3) explains the connection lifecycle in more detail, if you're curious.

however β€” if your allow or deny patterns contain any dn: or issuer-dn: rules, then all filtering has to happen later in the connection lifecycle, because we have to wait until TLS negotiation has finished. filtering happens in the .open or .list_exports callback instead.

in practice this makes filtering more expensive and potentially makes it easier to cause Denial of Service (DoS) attacks. 😭 so try to combine dn: and issuer-dn: rules with extra filtering outside nbdkit, like a firewall or VPN. stay safe out there bestie.

πŸ› DEBUG FLAGS πŸ›

  • -D ip.rules=1 β€” debug rules and rule matching. if clients are getting accepted or rejected when they shouldn't be, using -v -D ip.rules=1 can help you debug the problem. detective mode πŸ”

πŸ“ FILES πŸ“

  • $filterdir/nbdkit-ip-filter.so β€” the filter.

use nbdkit --dump-config to find the location of $filterdir. πŸ—ΊοΈ


⭐ VERSION ⭐

nbdkit-ip-filter first appeared in nbdkit 1.18. throwback era πŸ’«


πŸ‘€ SEE ALSO πŸ‘€

nbdkit(1), nbdkit-exitlast-filter(1), nbdkit-exitwhen-filter(1), nbdkit-limit-filter(1), nbdkit-time-limit-filter(1), nbdkit-filter(3), nbdkit_peer_name(3), nbdkit_peer_pid(3), nbdkit_peer_uid(3), nbdkit_peer_gid(3), nbdkit_peer_security_context(3), nbdkit_peer_tls_dn(3), nbdkit_peer_tls_issuer_dn(3), nbdkit-tls(1).


πŸ‘‘ AUTHORS πŸ‘‘

Richard W.M. Jones 🫑


Copyright Red Hat


πŸ“„ LICENSE πŸ“„

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Red Hat nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


and that's the whole page bestie, you're officially an IP-filtering expert πŸ’…βœ¨ this was nbdkit-1.48.1, dated 2026-08-29 β€” mwah, go slay πŸ«ΆπŸ’–πŸŒˆ

πŸ“¦ where this page comes from