From 2716ac85a2b50e1fbaa48c443addde4d923e920d Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Thu, 18 Jul 2024 09:54:46 +0200 Subject: [PATCH] Drop icmp redirect on tun interfaces close #69 --- internal/iproute2/tun-iface.go | 42 ++++++++++++++++++++++++++++++---- internal/iproute2/utils.go | 28 +++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/internal/iproute2/tun-iface.go b/internal/iproute2/tun-iface.go index 39b2f82..4ea6495 100644 --- a/internal/iproute2/tun-iface.go +++ b/internal/iproute2/tun-iface.go @@ -38,12 +38,29 @@ func (t *TunIface) CreateAndUp() error { return fmt.Errorf("Unable to allocate TUN interface: %s", err) } t.iface = iface + if err := t.DropIcmpRedirect(); err != nil { + return err + } if err := runIP("link", "set", "dev", t.iface.Name(), "up"); err != nil { return err } return nil } +// Stop TunIface related goroutines and delete the interface +func (t *TunIface) Delete() error { + if t.iface == nil { + return nil + } + if err := runIP("link", "del", t.iface.Name()); err != nil { + return fmt.Errorf("Unable to delete interface %s: %s", t.iface.Name(), err) + } + if err := t.CancelDropIcmpRedirect(); err != nil { + return err + } + return nil +} + // MTU of the TunIface func (t *TunIface) MTU() (int64, error) { if strings.Contains(t.iface.Name(), "/") || strings.Contains(t.iface.Name(), ".") { @@ -88,13 +105,30 @@ func (t *TunIface) IPv4TTL() (uint8, error) { return uint8(ret), nil } -// Stop TunIface related goroutines and delete the interface -func (t *TunIface) Delete() error { +// Drop ICMP/ICMPv6 redirects on the interface +func (t *TunIface) DropIcmpRedirect() error { if t.iface == nil { return nil } - if err := runIP("link", "del", t.iface.Name()); err != nil { - return fmt.Errorf("Unable to delete interface %s: %s", t.iface.Name(), err) + if err := runIPTables("-A", "OUTPUT", "-o", t.iface.Name(), "-p", "icmp", "--icmp-type", "redirect", "-j", "DROP"); err != nil { + return fmt.Errorf("Unable to drop icmp redirect on interface %s: %s", t.iface.Name(), err) + } + if err := runIP6Tables("-A", "OUTPUT", "-o", t.iface.Name(), "-p", "icmpv6", "--icmpv6-type", "redirect", "-j", "DROP"); err != nil { + return fmt.Errorf("Unable to drop icmpv6 redirect on interface %s: %s", t.iface.Name(), err) + } + return nil +} + +// Cancel Drop ICMP/ICMPv6 redirects on the interface +func (t *TunIface) CancelDropIcmpRedirect() error { + if t.iface == nil { + return nil + } + if err := runIP6Tables("-D", "OUTPUT", "-o", t.iface.Name(), "-p", "icmpv6", "--icmpv6-type", "redirect", "-j", "DROP"); err != nil { + return fmt.Errorf("Unable to drop icmpv6 redirect on interface %s: %s", t.iface.Name(), err) + } + if err := runIPTables("-D", "OUTPUT", "-o", t.iface.Name(), "-p", "icmp", "--icmp-type", "redirect", "-j", "DROP"); err != nil { + return fmt.Errorf("Unable to drop icmp redirect on interface %s: %s", t.iface.Name(), err) } return nil } diff --git a/internal/iproute2/utils.go b/internal/iproute2/utils.go index 28a5afc..4d26d68 100644 --- a/internal/iproute2/utils.go +++ b/internal/iproute2/utils.go @@ -25,6 +25,34 @@ func runIP(args ...string) error { return nil } +// Run iptables command +func runIPTables(args ...string) error { + cmd := exec.Command("iptables", args...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + cmd.Stdin = os.Stdin + if err := cmd.Run(); err != nil { + errLog := fmt.Sprintf("Error running %s: %s", cmd.Args, err) + log.Println(errLog) + return err + } + return nil +} + +// Run ip6tables command +func runIP6Tables(args ...string) error { + cmd := exec.Command("ip6tables", args...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + cmd.Stdin = os.Stdin + if err := cmd.Run(); err != nil { + errLog := fmt.Sprintf("Error running %s: %s", cmd.Args, err) + log.Println(errLog) + return err + } + return nil +} + func IPSrSetSourceAddress(address string) error { return runIP("sr", "tunsrc", "set", address) }