Using nfqueue on Linux as a novel, webserver-agnostic HTTP authenticator

Ah, I stared at the x00P, but didn't realise it was yet another encoding of 80 :stuck_out_tongue:

4 Likes

How long a server send FIN+ACK for their side when there receive FIN? I found without delay given ack sent too fast and ignored because acme server didn't sent their FIN yet. 10ms was enough even in high ping though for at least for local

3 Likes

:frowning: Uch, the newly required nft_queue.ko module gives me a "NULL pointer dereference" error when modprobing it :frowning: Although dmesg points to nf_tables_init_net, which is weird, 'cause that module is sitting in lsmod just fine?

OK, installing the newly build kernel (although it were merely modules that were build extra) and a reboot later and it seems to be working. :slight_smile:

3 Likes

The final ACK should only be sent in response to receiving a FIN from the server. Is the plugin sending an ACK out of turn?

To be honest, I'm not if both modules are actually required. They both seem to get autoloaded on my server as soon as the plugin does its business, even if I rmmod them before.

3 Likes

well, I lazied out and send ACK for will-be-send fin packet after 10ms instead of tracking connection :stuck_out_tongue:

3 Likes

@_az Note that NFPROTO_INET has only been added to pyroute2 in version 0.7.4. Gentoo has 0.7.3 as stable and 0.7.4 still in 'testing'. Not a big deal, but you might want to have the dependency on pyroute2 to be 0.7.4 or higher.

Hmm, Gentoo seems to have some trouble:

2023-02-26 14:40:50,578:INFO:certbot._internal.auth_handler:Performing the following challenges:
2023-02-26 14:40:50,579:INFO:certbot._internal.auth_handler:http-01 challenge for le-test.ml
2023-02-26 14:40:50,607:DEBUG:certbot._internal.error_handler:Encountered exception:
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/certbot/_internal/auth_handler.py", line 86, in handle_authorizations
    resps = self.auth.perform(achalls)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/certbot_standalone_nfq/auth.py", line 66, in perform
    set_nfqueue_enabled(True, self.http_port)
  File "/usr/lib/python3.11/site-packages/certbot_standalone_nfq/auth.py", line 239, in set_nfqueue_enabled
    nft.chain(
  File "/usr/lib/python3.11/site-packages/pyroute2/nftables/main.py", line 294, in chain
    return self._command(nft_chain_msg, commands, cmd, kwarg)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyroute2/netlink/nfnetlink/nftsocket.py", line 1298, in _command
    self.nlm_request_batch(messages, noraise=(flags & NLM_F_ACK) == 0)
  File "/usr/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 879, in nlm_request_batch
    return tuple(self._genlm_request_batch(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 1170, in nlm_request_batch
    for msg in self.get(msg_seq=seq, noraise=noraise):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 870, in get
    return tuple(self._genlm_get(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 547, in get
    raise msg['header']['error']
pyroute2.netlink.exceptions.NetlinkError: (95, 'Operation not supported')

Not sure why :thinking: Certbot is running as root. The required modules are loaded:

nft_queue              16384  0
nf_tables             229376  1 nft_queue
nfnetlink_queue        24576  0

Uch, pyroute2 is very poorly documented if I may say so.. pyroute2.nftables · PyPI links to pyroute2 modules usage · Discussion #796 · svinota/pyroute2 · GitHub for its usage, but in that discussion, nothing about nftables is mentioned? :thinking: :frowning_face:

I have no idea on how to debug this further I'm afraid. I've updated iproute2 to 6.1.0 to no avail.

3 Likes

Good to know. Can probably just use a constant value in its place.

Are you able to run the below script without hitting the error?

#!/usr/sbin/nft -f
add table inet certbot_standalone_nfq
add chain inet certbot_standalone_nfq acme_http_requests { type filter hook input priority 1 ; policy accept; }
add rule inet certbot_standalone_nfq acme_http_requests tcp dport 80 queue num 8555 bypass
delete table inet certbot_standalone_nfq
4 Likes

Unfortunately not:

erazer tmp # ./nft.sh 
./nft.sh:3:1-112: Error: Could not process rule: Operation not supported
add chain inet certbot_standalone_nfq acme_http_requests { type filter hook input priority 1 ; policy accept; }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
./nft.sh:4:38-55: Error: Could not process rule: No such file or directory
add rule inet certbot_standalone_nfq acme_http_requests tcp dport 80 queue num 8555 bypass
                                     ^^^^^^^^^^^^^^^^^^
./nft.sh:5:14-35: Error: No such file or directory; did you mean table ‘certbot_standalone_nfq’ in family inet?
delete table certbot_standalone_nfq
             ^^^^^^^^^^^^^^^^^^^^^^
erazer tmp # 

OK, fixed it.

It seems the kernel configuration option CONFIG_NF_TABLES_INET needed to be set. Not sure what that option does, as without it, the command nft add table inet certbot_standalone_nfq ran fine. It was just the chain part that was erroring out. The kernel configuration help says "This option enables support for a mixed IPv4/IPv6 "inet" table.".

Running add chain inet certbot_standalone_nfq acme_http_requests without the latter part ran fine, so add chain inet .. did work earlier. Probably the type filter or hook input part required CONFIG_NF_TABLES_INET maybe?

Well, anyway, I'll add CONFIG_NF_TABLES_INET to the list of kernel configuration options required for certbot-standalone-nfq in the Gentoo ebuild :stuck_out_tongue:

5 Likes

while messing with firewall rules I realized this:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 22713
certbot certonly standlone -d exemple.org --http-01-port 22713
iptables -D PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 22713

why not just steal port for a bit?
while this will break other listeners for a bit but it's just few seconds and most listenrs are 301 redirected to https anyway

3 Likes

I had a previous project which did something like that, but I wasn’t a fan of a temporary L7 proxy where source address and headers would be “wrong” during the issuance period. Leaving the unrelated traffic totally unchanged was the main goal here.

5 Likes

After discovering that (somehow) snap's namespacing doesn't screw up the functioning of the nftables bits, I've decided to publish and it's now available from pypi and snaps!

Because a couple of the dependencies were GPLv2 and I have no idea how to interpret the rules when it comes to Python dependencies, I've licensed the whole plugin GPLv2.

4 Likes

There seems to be some debate (see e.g. Can I license Python project under 3-clause BSD while it has GPL-based dependencies - Open Source Stack Exchange) so I can understand your hesitation for the MIT license. I'll edit the license in my ebuild :slight_smile: (And rebuild it so it'll use the PyPi package. I dunno why, but for some reason I prefer using PyPi for source code instead of Github... :roll_eyes:)

3 Likes

not sure which lib it tainted GPL from?
ah pyroute2 for setting nfqueue rule

EDIT: it was scapy to send packet

3 Likes

pyroute2 is also licensed by the Apache Software License according to its PyPi page? Is that compatible with MIT?

Nevermind, scapy is GPL-2 only..

4 Likes

Added certbot-standalone-nfq to my Gentoo third party Certbot plugins overlay :star_struck:

Messed up a git squash rebase it seems, but no idea how the Gentoo mirror handles forced pushes.. So I'm gonna leave it like this :stuck_out_tongue:

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

@_az do you think that this plugin is stable enough suggested in help thread here, like for some exotic webserver we don't really know or when it takes too long thread for us to make OP config their webserver?

4 Likes

I wish I had seen this thread before, because it would have been a cool April Fool's Day post to propose extending this to work with TLS-ALPN-01 as well. :joy_cat:

Very cool work, @_az!

3 Likes

Not a bad idea.

4 Likes