Question about loopback interface and FW rules

Started by Juhe, February 08, 2025, 10:38:52 PM

Previous topic - Next topic


Hi,

I have created an additional loopback interface lo1 which I am planning to use as the management interface for the OPNsense FW itself. I have assigned an address for the interface 10.10.10.10/32.

Now I have been experimenting with this management interface for a week. I changed the OPNsense GUI to only listen to this lo1 interface and I can access the GUI using the IP just fine. However when I tried to implement FW rules for the lo1 interface with the name MGMT_LO. I just could not get the rules working like I wanted. It seems like if I create any block rules (with logging enabled) they do not work for the loopback interface.

For example here are rules that should block all traffic --> that should be making the OPNsense GUI to not be reachable from any network. These rules were defined for the FW zone MGMT_LO:
INTERFACE    ACTION    DIRECTION    SRC    SRC PORT    DST    DST PORT    PROTOCOL
MGMT_LO    BLOCK    OUT            any    any            any    any            any
MGMT_LO    BLOCK    IN            any    any            any    any            any

But I am still able to ping the address 10.10.10.10 and also HTTP/S works just fine from other networks/interfaces. What am I missing here? I tried to read through OPNsense documentation but I found nothing special related to loopback interfaces/rules. Please help me out! I am going crazy here...

Something to note: I have also a network with interface called LAN where I have created a rule that allows egress traffic towards the loopback interface MGMT_LO. Without this rule I am not able to connect to the management address as I have a default rule to block all egress traffic that does not match a rule. But for some reason the rules defined in the MGMT_LO interface do not do anything at all....

Thank you all for your help and replies in advance!

February 09, 2025, 10:06:13 AM #1 Last Edit: February 09, 2025, 10:20:25 AM by Juhe
Hi,

I finally had time to to gather more information. And this is quite strange... Maybe I just do not understand loopback interfaces on BSD.

I first tried pinging the lo1 interface from my LAN device:

$ hostname -I
10.0.0.20

$ ping 10.10.10.10
PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data.
64 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=0.166 ms
64 bytes from 10.10.10.10: icmp_seq=2 ttl=64 time=0.099 ms
64 bytes from 10.10.10.10: icmp_seq=3 ttl=64 time=0.103 ms
64 bytes from 10.10.10.10: icmp_seq=4 ttl=64 time=0.114 ms

And while that ping was running I monitored tcpdump on the OPNsense server:
# tcpdump -ni lo0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo0, link-type NULL (BSD loopback), snapshot length 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

You might be thinking that why I am montioring the lo0 interface instead of the lo1. Well it seems that all of the loopback traffic will be going through lo0 based on fome BSD forum posts that I read throught.



Well then the second test. If I ping the lo1 interface within the OPNsense host I get quite different results...
$ ping -S 10.0.0.1 10.10.10.10
PING 10.10.10.10 (10.10.10.10) from 10.0.0.1: 56 data bytes
^C
--- 10.10.10.10 ping statistics ---
8 packets transmitted, 0 packets received, 100.0% packet loss

$ ping -S 10.0.1.1 10.10.10.10
PING 10.10.10.10 (10.10.10.10) from 10.0.1.1: 56 data bytes
^C
--- 10.10.10.10 ping statistics ---
5 packets transmitted, 0 packets received, 100.0% packet loss

$ ping -S localhost 10.10.10.10
PING 10.10.10.10 (10.10.10.10) from localhost: 56 data bytes
^C
--- 10.10.10.10 ping statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss

Here we can see that none of the pings were succesful. And I can see in the OPNsense FW live view that the default rule "Default deny / state violation rule" blocked these ping attempts.

And this is the tcpdump for the tests above:
# tcpdump -ni lo0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo0, link-type NULL (BSD loopback), snapshot length 262144 bytes
10:54:28.818141 IP 10.0.0.1 > 10.10.10.10: ICMP echo request, id 615, seq 4, length 64
10:54:29.826271 IP 10.0.0.1 > 10.10.10.10: ICMP echo request, id 615, seq 5, length 64
10:54:30.843957 IP 10.0.0.1 > 10.10.10.10: ICMP echo request, id 615, seq 6, length 64
10:54:31.906021 IP 10.0.0.1 > 10.10.10.10: ICMP echo request, id 615, seq 7, length 64
10:54:41.932158 IP 10.0.1.1 > 10.10.10.10: ICMP echo request, id 53280, seq 0, length 64
10:54:42.939043 IP 10.0.1.1 > 10.10.10.10: ICMP echo request, id 53280, seq 1, length 64
10:54:43.969763 IP 10.0.1.1 > 10.10.10.10: ICMP echo request, id 53280, seq 2, length 64
10:54:44.980103 IP 10.0.1.1 > 10.10.10.10: ICMP echo request, id 53280, seq 3, length 64
10:54:45.989744 IP 10.0.1.1 > 10.10.10.10: ICMP echo request, id 53280, seq 4, length 64
10:54:51.137569 IP 127.0.0.1 > 10.10.10.10: ICMP echo request, id 2606, seq 0, length 64
10:54:52.156885 IP 127.0.0.1 > 10.10.10.10: ICMP echo request, id 2606, seq 1, length 64
10:54:53.160118 IP 127.0.0.1 > 10.10.10.10: ICMP echo request, id 2606, seq 2, length 64
10:54:54.168148 IP 127.0.0.1 > 10.10.10.10: ICMP echo request, id 2606, seq 3, length 64
^C
13 packets captured
13 packets received by filter
0 packets dropped by kernel


So... What is happening here? I am planning to create multiple IPsec tunnels and using BGP to distribute the routes for the IPsec tunnels and if I can not use these loopback interfaces (and create rules) reliably I might have to use something else than OPNsense. Which sucks because I really like OPNsense so far!

I think what you're missing is the way filter rules work. Filtering happens when a packet initiating a connection/session either arrives at the firewall (inbound) or when it exits the firewall (outbound). Filter rules are usually applied inbound on the interface that receives the packet - i.e. an inbound rule on the LAN interface would apply to packets entering the firewall through the LAN interface. In the case of your ping from LAN, the packets are arriving at the firewall through the LAN interface (NOT the loopback interface), and they are handled locally (not routed somewhere else) so no outbound rules would be applied. Your filters on the loopback interface would not apply.

You probably could use a floating rule to block access to your management IP address (except from sources that you want to allow). The floating rule would apply inbound on all interfaces.

February 09, 2025, 11:15:46 AM #3 Last Edit: February 09, 2025, 11:17:47 AM by Juhe
Quote from: dseven on February 09, 2025, 10:44:52 AMI think what you're missing is the way filter rules work. Filtering happens when a packet initiating a connection/session either arrives at the firewall (inbound) or when it exits the firewall (outbound). Filter rules are usually applied inbound on the interface that receives the packet - i.e. an inbound rule on the LAN interface would apply to packets entering the firewall through the LAN interface. In the case of your ping from LAN, the packets are arriving at the firewall through the LAN interface (NOT the loopback interface), and they are handled locally (not routed somewhere else) so no outbound rules would be applied. Your filters on the loopback interface would not apply.

You probably could use a floating rule to block access to your management IP address (except from sources that you want to allow). The floating rule would apply inbound on all interfaces.

Thanks for replying! And thanks for suggesting a solution. I will probably do it like that.

Does this basically mean that any rules applied directly to any loopback interface would not make any difference? If so, it is quite confusing that you still can create these rules.

What is still confusing me is why the OPNsense internal pings did catch the rules (or rather the default rules) but not pings that came through LAN interface from a client connected to it.

Apparently inbound rules on loopback interfaces do catch packets coming from the firewall host itself. Filtering there probably wouldn't be very useful in general, but (at least in my observation) OPNsense is generally quite permissive, and doesn't seem to try too hard to prevent you from shooting yourself in the foot ;)

Quote from: dseven on February 09, 2025, 11:26:22 AMApparently inbound rules on loopback interfaces do catch packets coming from the firewall host itself. Filtering there probably wouldn't be very useful in general, but (at least in my observation) OPNsense is generally quite permissive, and doesn't seem to try too hard to prevent you from shooting yourself in the foot ;)

Yeah, apparently. Not a problem as you stated, that is not useful anyway. But strange and illogical IMO.

I am trying to implement a zero trust style network and OPNsense is not making it easy when it comes to the rules. I might try and see what VyOS is like. I do not like their rolling release model and from what I understood it is more of a router than FW. So that might not either be the best choice as I really want great FW with loads of features.

Just FYI lo0 gets skipped from processing. No PF rule on lo0 will influence any behavior.

https://github.com/opnsense/core/issues/8009
Hardware:
DEC740

Quote from: Monviech (Cedrik) on February 09, 2025, 02:10:47 PMJust FYI lo0 gets skipped from processing. No PF rule on lo0 will influence any behavior.

https://github.com/opnsense/core/issues/8009

Thanks! That is certainly good to know!

I wonder if this is also the case for other loopback interfaces since for some reason the traffic is coming into lo0 at least according to the tcpdump tests I ran before.

Are loopback interfaces not used that often with OPNsense? I mean it would not make any sense for me to tie the management(GUI,SSH) address to an actual interface. Or using an actual interface addrees for the local BGP peer IP. I am fairly new with networking but seems like on FWs such as cisco or fortigate they use loopback interfaces exactly for these purposes.


Quote from: Monviech (Cedrik) on February 09, 2025, 02:33:05 PMIf check the commit thats referenced by the issue you could see its explicitely lo0.

https://github.com/opnsense/core/commit/a0ee6288f62af0264a58037bc0f1cd82ffcca3b4

https://github.com/opnsense/core/blob/986dcb23245593df49c0dceb4fb1520c225bb694/src/etc/inc/filter.inc#L355

I read through the issue and looked at the commit. And I can confirm there is a skip rule for lo0 also on my instance.

I was just speculating if that also would have something to do with the rules not being processed for additional loopback interfaces like my tests could indicate in the main post and the first comment that I wrote.

I am going ahead and creating floating rules that will block egress connections to my lo1 interface. I still think this is silly. I would much rather liked to just block the ingress traffic on the lo1 interface rules. If someone can figure out a better way, I am very interested in hearing the ideas!

Quote from: Juhe on February 09, 2025, 05:35:14 PMI was just speculating if that also would have something to do with the rules not being processed for additional loopback interfaces like my tests could indicate in the main post and the first comment that I wrote.

I am going ahead and creating floating rules that will block egress connections to my lo1 interface. I still think this is silly. I would much rather liked to just block the ingress traffic on the lo1 interface rules. If someone can figure out a better way, I am very interested in hearing the ideas!

I've tried to explain how the filtering works, but apparently it hasn't sunk in yet. There is no "egress to loopback"! A ping from a LAN host enters the firewall through the LAN interface, therefore inbound firewall rules for the LAN interface are applied. Since the ping is not being forwarded on to some other destination, there is no egress, and so no outbound rule would apply.

The floating rule would catch the traffic destined for your management IP address inbound on *any* interface (or the ones that you specify)

Quote from: dseven on February 09, 2025, 05:40:41 PM
Quote from: Juhe on February 09, 2025, 05:35:14 PMI was just speculating if that also would have something to do with the rules not being processed for additional loopback interfaces like my tests could indicate in the main post and the first comment that I wrote.

I am going ahead and creating floating rules that will block egress connections to my lo1 interface. I still think this is silly. I would much rather liked to just block the ingress traffic on the lo1 interface rules. If someone can figure out a better way, I am very interested in hearing the ideas!

I've tried to explain how the filtering works, but apparently it hasn't sunk in yet. There is no "egress to loopback"! A ping from a LAN host enters the firewall through the LAN interface, therefore inbound firewall rules for the LAN interface are applied. Since the ping is not being forwarded on to some other destination, there is no egress, and so no outbound rule would apply.

The floating rule would catch the traffic destined for your management IP address inbound on *any* interface (or the ones that you specify)

Ok, thanks. I think I got it now! Do you happen to know where I could educate myself on the loopback interfaces? It is quite hard for me to understand how does it differ technically from a standard virtual interface (e.g. VLAN interface).

February 09, 2025, 08:26:52 PM #12 Last Edit: February 09, 2025, 08:29:03 PM by Patrick M. Hausen
It's not different. It's only the rule processing that is relevant here. Assuming that all rules are created wirh "quick" active, the first rule that matches is applied, a state is created for the connection (if appropriate) and no further rules are inspected.

So if you have an "allow in" rule on LAN, and you ping or connect with your browser, the first packet entering the LAN interface (from your PC to the loopback address - that goes *in* to LAN if you picture yourself as a tiny gnome sitting inside the firewall box) hits the "allow in" rule and no other rules are ever inspected for that connection.

Now ask yourself how should a packet/connection ever get to the loopback interface without entering the firewall box through some other interface first? Right, when you ping from the firewall itself. That's why your rule worked there. But every connection from an outside system will have entered the firewall via a different interface and one particular rule on that interface will have matched. End of rule processing.

HTH,
Patrick
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

Quote from: Juhe on February 09, 2025, 07:18:36 PMOk, thanks. I think I got it now! Do you happen to know where I could educate myself on the loopback interfaces? It is quite hard for me to understand how does it differ technically from a standard virtual interface (e.g. VLAN interface).

I don't know of anything specific. I could Google for something, but I'm sure you can do that too ;) I'll have a go at describing it a bit...

A loopback interface doesn't have any hardware associated with it, and doesn't communicate (over a layer 2 link) with any other hosts - rather anything that gets sent on the loopback interface "loops back" (inside the operating system kernel) and appears to be received by the same interface. It was traditionally used on Unix when processes running on the same host want to talk to eachother using TCP/IP without involving any physical network interface device. It can also be useful on hosts that act as routers, when you want to use an IP address that's not associated with any physical layer 2 network, because although it doesn't talk with any other hosts at layer 2, it can be routed to/from at layer 3.