1

I want to drop all packets sent to a particular port. I first tried using firewalld/iptables-nft settings but that failed (maybe they're being processed by the kernel only?).

I succeeded in blocking all packets sent to localhost by using

tc qdisc add dev lo root netem loss 100%

But that's too heavy-handed as I just want to block packets sent to port 1884.

I continued using tc but am missing something.

The tc documentation that I have found isn't fantastic. This one from Arch Linux is pretty good but doesn't connect the dots enough for me. The man pages are probably the best I've found but they're a little disjoint so I'm having trouble understanding the whole picture.

From what I understand, I should be able to add an HTB class and then add a filter to that class that should only deliver packets that are not sent to dport 1884. Actually, there doesn't appear a way to do this (no logical NOT operation). Instead, you have to match dport and then use a policy to drop them. When I do that, it doesn't work.

Here's a more complex approach that I think should work:

tc qdisc del dev lo root # clear things out, just in case
tc qdisc add dev lo root handle 1: htb default 30
tc class add dev lo parent 1: classid 1:1 htb rate 1000mbit
tc class add dev lo parent 1:1 classid 1:10 htb rate 1000mbit
# drop anything with an mtu larger than 1
tc filter add dev lo protocol ip parent 1: prio 1 u32 match ip dport 1884 0xffff \
   action police mtu 1 drop flowid 1:10

I just want to drop all packets. Seems overly complex to do that (iptables works much more simply, IMO)

This looks like it should work and appeals to me since it's simple but it doesn't work

tc qdisc del dev lo ingress # clear things out, just in case
tc qdisc add dev lo ingress
tc filter add dev lo parent ffff: protocol ip prio 1 u32 match ip dport 1884 \
   0xffff action drop

Can someone point me to better documentation or help me understand what I'm doing wrong?

EDIT: Here's an example of a firewall-cmd I tried:

sudo firewall-cmd --add-rich-rule='rule family="ipv4" port port=1884 protocol=tcp drop log level="warning" prefix="DROP" limit value="1/s"' --permanent --zone=trusted

This one succeeds but fails to filter the traffic as I would like.

I also tried adding a direct iptables rule but something isn't right:

sudo firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -o lo -p tcp --dport 1884 -j DROP
Error: INVALID_IPV: 'ipv4' is not a valid backend or is unavailable

I tried a variety of quotes to make this command happy but couldn't get there.

2
  • What are the iptables / firewall-cmd commands you tried? Add them to the question. Commented Aug 23 at 5:03
  • @HaukeLaging Done. Commented Aug 25 at 18:36

2 Answers 2

3

The problem of

firewall-cmd --add-rich-rule='rule family="ipv4" port port=1884 protocol=tcp drop log \
level="warning" prefix="DROP" limit value="1/s"' --permanent --zone=trusted

seems to be the --zone=trusted. As

firewall-cmd --permanent --get-zone-of-interface=lo

shows you: The loopback interface is not part of that (or any) zone. So you need a loopback zone:

firewall-cmd --permanent --new-zone=loopback
firewall-cmd --permanent --zone=loopback --add-interface=lo
firewall-cmd --reload

Then change your command

firewall-cmd [...] --permanent --zone=trusted

to

firewall-cmd [...] --permanent --zone=loopback
3
  • My lo was assigned to a zone when I first started trying to configure this. I tried as you suggested without a change in behavior. Commented Aug 27 at 17:09
  • @MrMas Did you run firewall-cmd --reload afterwards? Commented Aug 27 at 19:12
  • Yes and I also made sure the settings were moved from runtime to permanent. Commented Sep 26 at 17:44
2

I'm puzzled why you've ended up going down a rabbit hole with tc. The usual approach would be to use the firewall to block traffic to the specified port and protocol. Here I've gone straight to iptables:

iptables -A INPUT -p tcp --dport 1884 -j REJECT

If you really do intend just to drop packets sent to localhost (127.0.0.1) then the command can be extended to include this. Here are two examples - one filters by interface and the other by IP address range:

iptables -A INPUT -i lo -p tcp --dport 1884 -j REJECT
iptables -A INPUT -p tcp --dst 127.0.0.0/8 --dport 1884 -j REJECT
6
  • 1
    That may well do what the OP wants but the title and the code example point to localhost only whereas your approach blocks packets from outside the system (network namespace), too. Commented Aug 26 at 4:20
  • @HaukeLaging like I say in my answer, I don't see the relevance of the OP using tc at all. And as for localhost I have chosen to assume that in the absence of anything else that it means the local host rather than the loopback interface Commented Aug 26 at 7:31
  • @ChrisDavies I guess I think of sending packets to localhost (127.0.0.1) and that happens to use the loopback interface. Commented Aug 27 at 15:48
  • @ChrisDavies On Fedora 42, I believe iptables-nft is used instead of iptables and I was getting warnings/errors trying to update iptables directly. Furthermore, adding the filtering didn't seem to do anything and I ran into some references (perhaps erroneous) that suggested that localhost/loopback resolution happens in the kernel and so iptables doesn't have the chance to touch it. Probably just misunderstanding some fundamentals there. Commented Aug 27 at 15:49
  • @MrMas thanks. You are trying to traffic from the local device talking to a local service? Commented Aug 27 at 22:14

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.