fix: shoot ipv6 icmp redirects (#494)

This commit is contained in:
mzz 2024-04-08 19:35:17 +08:00 committed by GitHub
parent 3a83d98819
commit 7defd23ae9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 0 deletions

View File

@ -339,6 +339,38 @@ func (c *controlPlaneCore) _bindLan(ifname string) error {
}
return nil
})
filterEgress := &netlink.BpfFilter{
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_EGRESS,
Handle: netlink.MakeHandle(0x2023, 0b010+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
// Priority should be front of WAN's
Priority: 1,
},
Fd: c.bpf.bpfPrograms.TproxyLanEgress.FD(),
Name: consts.AppName + "_lan_egress",
DirectAction: true,
}
// Remove and add.
_ = netlink.FilterDel(filterEgress)
if !c.isReload {
// Clean up thoroughly.
filterEgressFlipped := deepcopy.Copy(filterEgress).(*netlink.BpfFilter)
filterEgressFlipped.FilterAttrs.Handle ^= 1
_ = netlink.FilterDel(filterEgressFlipped)
}
if err := netlink.FilterAdd(filterEgress); err != nil {
return fmt.Errorf("cannot attach ebpf object to filter egress: %w", err)
}
c.deferFuncs = append(c.deferFuncs, func() error {
if err := netlink.FilterDel(filterEgress); err != nil {
return fmt.Errorf("FilterDel(%v:%v): %w", ifname, filterEgress.Name, err)
}
return nil
})
return nil
}

View File

@ -76,6 +76,8 @@
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define NDP_REDIRECT 137
enum { BPF_F_CURRENT_NETNS = -1 };
enum {
@ -961,6 +963,37 @@ static __always_inline void prep_redirect_to_control_plane(
skb->cb[1] = l4proto;
}
SEC("tc/egress")
int tproxy_lan_egress(struct __sk_buff *skb)
{
if (skb->ingress_ifindex != NOWHERE_IFINDEX)
return TC_ACT_PIPE;
struct ethhdr ethh;
struct iphdr iph;
struct ipv6hdr ipv6h;
struct icmp6hdr icmp6h;
struct tcphdr tcph;
struct udphdr udph;
__u8 ihl;
__u8 l4proto;
__u32 link_h_len;
if (get_link_h_len(skb->ifindex, &link_h_len))
return TC_ACT_OK;
int ret = parse_transport(skb, link_h_len, &ethh, &iph, &ipv6h, &icmp6h,
&tcph, &udph, &ihl, &l4proto);
if (ret) {
bpf_printk("parse_transport: %d", ret);
return TC_ACT_OK;
}
if (l4proto == IPPROTO_ICMPV6 && icmp6h.icmp6_type == NDP_REDIRECT) {
// REDIRECT (NDP)
return TC_ACT_SHOT;
}
return TC_ACT_PIPE;
}
SEC("tc/ingress")
int tproxy_lan_ingress(struct __sk_buff *skb)
{