Hi,

by accident I discovered this rather senseless redirect:

$ doas tcpdump -eptni vlan2 icmp 
tcpdump: listening on vlan2, link-type EN10MB
11:11:11:11:11:11 22:22:22:22:22 0800 98: 192.168.1.2 > 192.168.4.7: icmp: echo 
request
22:22:22:22:22 11:11:11:11:11:11 0800 98: 192.168.4.7 > 192.168.1.2: icmp: echo 
reply
11:11:11:11:11:11 22:22:22:22:22 0800 70: 192.168.4.1 > 192.168.4.7: icmp: 
redirect 192.168.1.2 to host 192.168.4.1
^C
110 packets received by filter
0 packets dropped by kernel


The routing table on 192.168.4.1 tells you why this redirect was sent.
Have a look at the second last route.

% doas ifconfig vlan2                                                           
                                                              
vlan2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500              
                                                                              
        lladdr 11:11:11:11:11:11
        index 7 priority 0 llprio 3
        encap: vnetid 2 parent em2
        status: active
        inet 192.168.4.1 netmask 0xfffffff0 broadcast 192.168.4.15
% doas route -n show -inet
Routing tables

Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
default            62.27.93.143       UGS        5    63324     -     8 pppoe0
224/4              127.0.0.1          URS        0        0 32768     8 lo0
62.27.93.143       85.212.225.8       UHh        1        1     -     8 pppoe0
85.212.225.8       85.212.225.8       UHl        0     1589     -     1 pppoe0
127/8              127.0.0.1          UGRS       0        0 32768     8 lo0
127.0.0.1          127.0.0.1          UHhl       9     1131 32768     1 lo0
192.168.0/22       192.168.4.1        UGS        0      314     -     8 vlan2   
  <- this is the culprit
192.168.4.0/28     192.168.4.1        UCn        2        0     -     4 vlan2


Network 192.268.0/22 is remote and connected via IPsec:
$ ipsecctl -s flow
flow esp in from 192.168.0.0/22 to 192.168.4.0/24 type use                      
                  
flow esp out from 192.168.224.0/24 to 192.168.0.0/17 type require               
                    

You'll note I manually (Flag S) added this rather senseless route to gateway
192.268.4.1 (Flag G), which is the very same machine.
Why did I do this?
To prevent leakage of packets which should be routed via IPsec. Without this
pseudo-route packets from localhost to 192.168.0/22 would be routed via default
route on pppoe0 and have a src IP of 85.212.225.8,
which would not be caught by the IPsec flow.

If I'm doing something wrong here and should have solved this an another way
please tell me.
Using a "flow esp in from 0.0.0.0/0" would work on the local side, but the
remote side would be required to accept packets from arbitrary IPs, too.

In any case I'd propose the following diff which will check whether the
redirect target is an address of the interface the forwarded packet came in on.


Christopher


Index: ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.322
diff -u -p -r1.322 ip_input.c
--- ip_input.c  7 Sep 2017 10:54:49 -0000       1.322
+++ ip_input.c  1 Dec 2017 18:00:53 -0000
@@ -1514,16 +1514,27 @@ ip_forward(struct mbuf *m, struct ifnet 
            (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
            satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
            ipsendredirects && !srcrt &&
-           !arpproxy(satosin(rt_key(rt))->sin_addr, m->m_pkthdr.ph_rtableid)) {
-               if ((ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) ==
-                   ifatoia(rt->rt_ifa)->ia_net) {
-                   if (rt->rt_flags & RTF_GATEWAY)
+           !arpproxy(satosin(rt_key(rt))->sin_addr, m->m_pkthdr.ph_rtableid) &&
+           (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) ==
+           ifatoia(rt->rt_ifa)->ia_net) {
+               struct ifaddr *ifa;
+
+               if (rt->rt_flags & RTF_GATEWAY)
                        dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
-                   else
+               else
                        dest = ip->ip_dst.s_addr;
-                   /* Router requirements says to only send host redirects */
-                   type = ICMP_REDIRECT;
-                   code = ICMP_REDIRECT_HOST;
+
+               /* don't redirect to the interface the packet came in on. */
+               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+                       if (ifa->ifa_addr->sa_family == AF_INET &&
+                           satosin(ifa->ifa_addr)->sin_addr.s_addr == dest)
+                               dest = 0;
+               }
+
+               /* Router requirements says to only send host redirects */
+               if (dest != 0) {
+                       type = ICMP_REDIRECT;
+                       code = ICMP_REDIRECT_HOST;
                }
        }

 
-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
2779 7F73 44FD 0736 B67A  C410 69EC 7922 34B4 2566

Attachment: pgpJ6ZS6cu6bn.pgp
Description: OpenPGP digital signature

Reply via email to