How do I allow ICMP Redirect for static route?

IPfire seems to block all ICMP traffic except for ping.

I have a static route to a pi-like device that is connected trough a AP and routes trafic to a network-printer on the LAN port.

How can I enable ICMP redirect for the static route so that I can reach my network printer?

I don’t think so. If a device in the green zone is communicating with another device in the same zone, the traffic doesn’t have to go through the firewall to reach its destination. This is because the communication is within the same network, and the packets are simply directed by the switch or other networking device. This means that even if IPFire were to block ICMP traffic, it would only block it coming in and out of the green zone, not the traffic within the zone itself.

2 Likes

Did some research on the forum before posting and came across several posts which said that ICMP Redirect are ignored.

The assumption that traffic would be redirected by the switch would be true, but only if there was a static route on the device that is trying to connect, instead of having to ask the router for the route.

Take the laptop as an example, if there was a static route on the laptop specifying that 192.168.2.2 is via 172.16.1.2 then there is no issue, but as there is not static route it has to ask IPFire instead and get redirected by it.

Yes. you are right, in this case the traffic will have to go thorough the router. Let’s see.
There are no rules in IPTables concerning ICMP redirect:

[root@ipfire cfusco]# iptables -L -v | grep -i 'icmp --icmp-type redirect'
[root@ipfire cfusco]# 

therefore it has to be set directly in the kernel

[root@ipfire cfusco]# cat /proc/sys/net/ipv4/conf/all/accept_redirects
0

zero means that the system is not accepting any ICMP redirect messages.

What about send_redirect?

[root@ipfire cfusco]# cat /proc/sys/net/ipv4/conf/all/send_redirects
1

send_redirect set to 1 means that the system is currently set to send ICMP redirect messages.

Based on this observation, here’s how ICMP redirects SHOULD work in this setup:

  1. Let’s say a Wi-Fi device wants to send a print job to the printer. It sends the packet to its default gateway, which would be the IPFire router, since all IP addresses (I suppose) are served by IPFire.

  2. The IPFire router, having a static route, knows that the Raspberry Pi router is on the same network as the Wi-Fi device and can route packets to the printer.

  3. So the IPFire router sends the packet to the Raspberry Pi, which then sends the packet to the printer. But the IPFire router also sends an ICMP redirect message back to the Wi-Fi device saying, “Next time you want to send a packet to the printer, send it to the Raspberry Pi directly”.

  4. The Wi-Fi device receives this ICMP Redirect message and updates its routing table accordingly. So, the next time it sends a packet to the printer, it will send it directly to the Raspberry Pi, bypassing the IPFire router. This helps optimize network traffic by reducing unnecessary load on the IPFire router.

This behavior assumes that the Wi-Fi device and the IPFire router both accept and respect ICMP redirect messages. If the Wi-Fi device ignores these messages, it will continue to send packets to the printer via the IPFire router. Similarly, if the IPFire router is set not to send ICMP redirect messages (i.e., send_redirects is set to ‘0’), this whole mechanism will not take place. In my machine, being set to 1 your setup should work (in theory).

To change the kernel behavior you can use sysctl in firewall.local.

For example to set send_redirects to 0,

sysctl -w net.ipv4.conf.all.send_redirects=0

put eth0 instead of all to target only that interface. I would advice to be prudent in changing these kind of settings as you could have unintended consequences, especially for security concerns.

1 Like

Will try this out, and thank you for the analyses, very helpful!

Regarding send_redirects, wouldn’t accept_redirects need to be enable for it to work?

I also had a look at secure_redirects which is on and which I think might play an important role here.
If I understand secure_redirects correctly then it will only accept ICMP redirect messages to gateways listed by IPFire.

Interestingly i got send_redirects to work by adding a route on the CLI

ip route add 192.168.2.0/24 via 172.16.1.2

This confirms that secure_redirects is having an effect and will only allow for defined gateways.

But… this only works for my Linux laptop, but not for my Windows PC, Android or iOS devices.
Seems that accept_redirects is required for that?

A solution could maybe to enable accept_redirects on green interface and then block everything except the ip for the printer with iptables somehow.

Looking at the network diagram arises a question:

Which router?

The printer is connected to the Pi which has two NICs: 172.16.1.2 ( AP net, not IPFire GREEN ) 192.168.2.1 ( own ethernet network ). So the Pi must be a router of it’s own. Connection Laptop (172.16.1.10) <—> Printer ( 192.168.2.2 ) runs independent from IPFire ( only through AP and Orange pi ).

2 Likes

@bbitsch Do you agree with this sequence of events (written in the next paragraph)?

When the Wi-Fi client wants to send a packet to the printer, it will not find the printer’s IP in its routing table or ARP cache since it’s not part of the green network. So, it sends the packet to its default gateway, which should be the IPFire router, by finding the MAC address of the IPFire router using an ARP request if necessary.

The IPFire router, knowing that the destination IP (printer’s IP) is reachable through the Raspberry Pi router, forwards the packet to the Raspberry Pi router, which in turn delivers the packet to the printer.

On a separate note @septus, having only a Linux client working while all the other OS machines don’t, should NOT depend on the ICMP redirect functionality. This routing should always work as long as the clients are configured to have IPFire as the default gateway. The ICMP redirect is just an optimization, even if all redirect functions were disabled completely, the routing should still be functional, although not optimal as it will always go through IPFire.

+++

NOTE: here it follows a detailed breakdown of the chain of events summarized by GPT4 when I prompted it to explain each steps for both layer 2 and layer 3. This is only for my own benefits, but I thought it would be useful anyway.

GTP4 breakdown of the chain of events, from the laptop to the printer

Sure, I’ll summarize the Layer 2 (Data Link) and Layer 3 (Network) events in this updated scenario of a laptop sending a print job to a printer, passing through an IPFire router, a Wireless Access Point, and then a Raspberry Pi router.

  1. Laptop (Layer 3): The laptop creates an IP packet with the source IP address as its own IP and the destination IP as the printer’s IP.

  2. Laptop (Layer 2): The laptop encapsulates this IP packet in an Ethernet frame (or equivalent for Wi-Fi, which is a 802.11 frame), using its own MAC address as the source MAC and the MAC address of its default gateway (IPFire router) as the destination MAC.

  3. Access Point (Layer 2): The Access Point receives the Wi-Fi frame from the laptop. It bridges this into an Ethernet frame and forwards it to the IPFire router via the Layer 2 switch.

  4. IPFire Router (Layer 3): The IPFire router receives the Ethernet frame, decapsulates it, and reads the destination IP address in the IP packet. Seeing that it’s destined for the printer, the router knows it needs to forward the packet to the Raspberry Pi.

  5. IPFire Router (Layer 2): The router encapsulates the IP packet in a new Ethernet frame, using its own MAC address as the source MAC and the MAC address of the Access Point as the destination MAC.

  6. Access Point (Layer 2): The Access Point receives the Ethernet frame from the Layer 2 switch. It bridges this into a Wi-Fi frame and forwards it to the Raspberry Pi.

  7. Raspberry Pi (Layer 3): The Raspberry Pi, functioning as a router, receives the Wi-Fi frame, decapsulates it, and reads the destination IP in the packet. Seeing that it’s destined for the printer, it knows it needs to forward the packet.

  8. Raspberry Pi (Layer 2): The Raspberry Pi encapsulates the IP packet in a new Ethernet frame, using its own MAC address as the source MAC and the MAC address of the printer as the destination MAC.

  9. Printer (Layer 2 & 3): The printer receives the Ethernet frame, decapsulates it to get the IP packet, and then processes the packet accordingly since it’s the intended recipient.

This is a simplified view, and it assumes that each device already knows the MAC addresses it needs (via previous ARP requests/responses). If a device doesn’t know a required MAC address, it would send an ARP request to find out. This description also omits the role of the layer 2 switch in forwarding the packets (which is described in the next paragraphs).

Here’s a simplified view of what happens when a packet travels through a switch:

  1. The switch receives an Ethernet frame on one of its ports.
  2. It examines the destination MAC address in the Ethernet frame’s header to determine the output port.
  3. If the switch already knows the output port (it maintains a MAC address table for this purpose), it forwards the frame to that port. If it doesn’t know, it floods the frame out of all its ports except for the port on which it received the frame.
  4. The frame is then received by the device connected to the output port, which matches the destination MAC address.

The switch does not need to decapsulate and re-encapsulate the Ethernet frames like a router. It simply reads the destination MAC address and forwards the frame based on that. The IP packet encapsulated within the Ethernet frame is not altered or even inspected by the switch under normal conditions.

Let’s put it this way. Your IPFire router is the commanding officer of your network. It will not be told what to do (modify its routing table), on the contrary it will tell everyone else what to do (modify their routing table) according to its decisions.

The send_redirects and accept_redirects settings in the Linux kernel control different behaviors:

  • send_redirects: This controls whether or not your machine will send ICMP redirect messages to other machines. It’s like the “commanding officer” giving orders (ICMP redirect messages) to others.
  • accept_redirects: This controls whether or not your machine will accept ICMP redirect messages from other machines and change its routing table accordingly. It’s like the “commanding officer” deciding whether or not to accept orders (ICMP redirect messages) from others.

So, these settings control the independent behaviors of sending and receiving ICMP redirect messages, respectively. They can be enabled or disabled independently of each other.

In the context of a network router like IPFire, it’s common to have send_redirects enabled and accept_redirects disabled. This allows the router to tell other machines on the network how to optimize their routes (sending ICMP redirects) without allowing other machines to alter the router’s own routing table (accepting ICMP redirects).

This provides a balance of network optimization and security. The security risk is preventing a third party from modifying the firewall routing table to create a man in the middle attack scenario.

IPFire 172.16.0.1 and Pi 172.16.1.2 are both IPFire GREEN, they share the same network 172.16.0.0/22.

1 Like

Thank you for the clarification.
Feels like I now have some leads in how this could be solved.

Will try to get back to this thread with a solution should I find it.

1 Like

So there must be a routing rule in IPFire for the 192.168.2.0/24

That is correct, there is a static path in the web interface for 192.168.2.0/24 via 172.16.1.2

Haven’t read the whole thread thoroughly, just a question:
What output gives
mtr 192.168.2.2 or
ping 192.168.2.2
from client 172.16.1.10?

Ping to 192.168.2.2 from green is working.

mtr from 172.16.1.10

  1. orangepizero.lan (172.16.1.2)
  2. 192.168.2.2

And mtr from a windows computer (on green)

  1. ice.mshome.net
  2. thewall.lan (172.16.0.1)
  3. orangepizero.lan (172.16.1.2)
  4. 192.168.2.2
2 Likes

If the devices in the GREEN zone get IP addresses from the DHCP IPFire server, you can use the DHCP static-routes option.

obraz

Best

1 Like

Many thanks, sending a static route trough DHCP will most definitely solve the problem.
Doing this once I get home.

1 Like

And it works on Windows and Linux, but not on Android and iOS.
Guess I’ll have to live with this until i flash my AP with OpenWRT.

Just for completeness:
Smartphone OSs like Android and iOS today use the unnecessary ( my opionion ) functionality of ‘random MACs’. This makes a DHCP server, which produces relations ( MAC, IP ) , useless.

1 Like