Re: NFQUEUE usage and interaction with later chain rules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 15, 2024 at 01:09:30PM +0100, Athanasius wrote:
>   1. The only practical verdicts the userspace helper can return are
>   ACCEPT or DROP.  Checking through some documentation, examples, and
>   kernel code I've come across 'STOLEN', 'QUEUE' and 'REPEAT', but I
>   cannot find any actual documentation on what these might achieve.
> 
>   2. There appears to be no way to have an NFQUEUE rule act in a manner
>   where the userspace verdict can cause subsequent rules in the chain to
>   be considered.

  Well, of course I had an epiphany after sending this.  I can make use
of packet marks to do what I want, together with a REPEAT verdict.

  1. Have the NFQUEUE rule check that the specific mark value is NOT
  set.

  2. On not-DROP the userspace helper sets the mark value and returns a
  verdict of REPEAT.  REPEAT sends the packet through the netfilter
  chains and rules again, at least the INPUT chain.  So now it doesn't
  match the NFQUEUE rule and evaluation continues after.

I'm being a little vague about 'REPEAT' there because I've still not
found any documentation telling me what it's *supposed* to do.  I had
already tried 'STOP' (going through the 'other' possible verdicts), and
couldn't discern what it was causing to (not) happen.

  For the interested, I'm actually doing this in Python, using the
`fnfqueue` module.  The `NetfilterQueue` module appeared to offer no way
to use a more 'custom' verdict, or even set that 'fail open' socket
option.
  I'm using `impacket` to decode the packets in order to extract the
source IP.  The relevant code ends up being:

```python
def process_fnfqueue_packet(pkt):
    payload = pkt.payload
    rip = ImpactDecoder.IPDecoder().decode(payload)
    src_ip = rip.get_ip_src()
    if ipcheck.check_ip(src_ip):
        logger.debug(f"{src_ip=} should be banned")
        pkt.drop()

    else:
        pkt.mark = 2
        pkt.verdict(fnfqueue.REPEAT, fnfqueue.MANGLE_MARK)

```

`pkt` is the packet as `fnfqueue` provides it.

`ImpactDecoder...` is from `impacket`.

`ipcheck.check_ip()` is my code doing the GeoIP lookup and returning
a boolean, `True` for 'should drop'.

  I'll try to remember to write up a web page detailing my findings in
the hope that it might then be found useful by others in the future.

  Oh and that 'fail open' option is still a little problematic.  Without
it, because the NFQUEUE rule will initially match, I would just DROP
packets if the NFQUEUE buffer filled.  With it I'll instead end up with
blind ACCEPT rather than any subsequent rules being evaluated.
  I assume there are architectural reasons why evaluation couldn't be
made to continue after the NFQUEUE rule (e.g. a verdict of
'NF_CONTINUE'), but it would sure be helpful if that was possible.

-- 
- Athanasius (he/him) = Athanasius(at)miggy.org / https://miggy.org/
                  GPG/PGP Key: https://miggy.org/gpg-key
	   "And it's me who is my enemy. Me who beats me up.
Me who makes the monsters. Me who strips my confidence." Paula Cole - ME




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux