Deactivate IPv6 integrations when no IPv6 stack is detected

This commit is contained in:
Daniel 2022-06-09 13:50:18 +02:00
parent 0439894efc
commit c442a7e51c
4 changed files with 89 additions and 43 deletions

View file

@ -10,8 +10,8 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/safing/portbase/log"
"github.com/safing/portbase/notifications"
"github.com/safing/portmaster/firewall/interception/nfq"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/network/packet"
)
@ -141,13 +141,10 @@ func activateNfqueueFirewall() error {
return err
}
if err := activateIPTables(iptables.ProtocolIPv6, v6rules, v6once, v6chains); err != nil {
notifications.NotifyError(
"interception:ipv6-possibly-disabled",
"Is IPv6 enabled?",
"The Portmaster succeeded with IPv4 network integration, but failed with IPv6 integration. Please make sure IPv6 is enabled on your device.",
)
return err
if netenv.IPv6Enabled() {
if err := activateIPTables(iptables.ProtocolIPv6, v6rules, v6once, v6chains); err != nil {
return err
}
}
return nil
@ -163,8 +160,10 @@ func DeactivateNfqueueFirewall() error {
}
// IPv6
if err := deactivateIPTables(iptables.ProtocolIPv6, v6once, v6chains); err != nil {
result = multierror.Append(result, err)
if netenv.IPv6Enabled() {
if err := deactivateIPTables(iptables.ProtocolIPv6, v6once, v6chains); err != nil {
result = multierror.Append(result, err)
}
}
return result.ErrorOrNil()
@ -264,15 +263,22 @@ func StartNfqueueInterception(packets chan<- packet.Packet) (err error) {
_ = Stop()
return fmt.Errorf("nfqueue(IPv4, in): %w", err)
}
out6Queue, err = nfq.New(17060, true)
if err != nil {
_ = Stop()
return fmt.Errorf("nfqueue(IPv6, out): %w", err)
}
in6Queue, err = nfq.New(17160, true)
if err != nil {
_ = Stop()
return fmt.Errorf("nfqueue(IPv6, in): %w", err)
if netenv.IPv6Enabled() {
out6Queue, err = nfq.New(17060, true)
if err != nil {
_ = Stop()
return fmt.Errorf("nfqueue(IPv6, out): %w", err)
}
in6Queue, err = nfq.New(17160, true)
if err != nil {
_ = Stop()
return fmt.Errorf("nfqueue(IPv6, in): %w", err)
}
} else {
log.Warningf("interception: no IPv6 stack detected, disabling IPv6 network integration")
out6Queue = &disabledNfQueue{}
in6Queue = &disabledNfQueue{}
}
go handleInterception(packets)
@ -327,3 +333,11 @@ func handleInterception(packets chan<- packet.Packet) {
}
}
}
type disabledNfQueue struct{}
func (dnfq *disabledNfQueue) PacketChannel() <-chan packet.Packet {
return nil
}
func (dnfq *disabledNfQueue) Destroy() {}

View file

@ -259,7 +259,11 @@ func getListenAddresses(listenAddress string) (ip1, ip2 net.IP, port uint16, err
// listen separately for IPv4 and IPv6.
if ipString == "localhost" {
ip1 = net.IPv4(127, 0, 0, 17)
ip2 = net.IPv6loopback
if netenv.IPv6Enabled() {
ip2 = net.IPv6loopback
} else {
log.Warningf("nameserver: no IPv6 stack detected, disabling IPv6 nameserver listener")
}
} else {
ip1 = net.ParseIP(ipString)
if ip1 == nil {

View file

@ -1,7 +1,9 @@
package netenv
import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/tevino/abool"
)
// Event Names.
@ -20,6 +22,8 @@ func init() {
}
func prep() error {
checkForIPv6Stack()
if err := registerAPIEndpoints(); err != nil {
return err
}
@ -46,3 +50,22 @@ func start() error {
return nil
}
var ipv6Enabled = abool.NewBool(true)
// IPv6Enabled returns whether the device has an active IPv6 stack.
// This is only checked once on startup in order to maintain consistency.
func IPv6Enabled() bool {
return ipv6Enabled.IsSet()
}
func checkForIPv6Stack() {
_, v6IPs, err := GetAssignedAddresses()
if err != nil {
log.Warningf("netenv: failed to get assigned addresses to check for ipv6 stack: %s", err)
return
}
// Set IPv6 as enabled if any IPv6 addresses are found.
ipv6Enabled.SetTo(len(v6IPs) > 0)
}

View file

@ -12,6 +12,7 @@ import (
"github.com/miekg/dns"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/network/netutils"
)
@ -91,19 +92,6 @@ func listenToMDNS(ctx context.Context) error {
}()
}
multicast6Conn, err = net.ListenMulticastUDP("udp6", nil, &net.UDPAddr{IP: net.IP([]byte{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}), Port: 5353})
if err != nil {
// TODO: retry after some time
log.Warningf("intel(mdns): failed to create udp6 listen multicast socket: %s", err)
} else {
module.StartServiceWorker("mdns udp6 multicast listener", 0, func(ctx context.Context) error {
return listenForDNSPackets(ctx, multicast6Conn, messages)
})
defer func() {
_ = multicast6Conn.Close()
}()
}
unicast4Conn, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
// TODO: retry after some time
@ -117,17 +105,34 @@ func listenToMDNS(ctx context.Context) error {
}()
}
unicast6Conn, err = net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
if err != nil {
// TODO: retry after some time
log.Warningf("intel(mdns): failed to create udp6 listen socket: %s", err)
if netenv.IPv6Enabled() {
multicast6Conn, err = net.ListenMulticastUDP("udp6", nil, &net.UDPAddr{IP: net.IP([]byte{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}), Port: 5353})
if err != nil {
// TODO: retry after some time
log.Warningf("intel(mdns): failed to create udp6 listen multicast socket: %s", err)
} else {
module.StartServiceWorker("mdns udp6 multicast listener", 0, func(ctx context.Context) error {
return listenForDNSPackets(ctx, multicast6Conn, messages)
})
defer func() {
_ = multicast6Conn.Close()
}()
}
unicast6Conn, err = net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
if err != nil {
// TODO: retry after some time
log.Warningf("intel(mdns): failed to create udp6 listen socket: %s", err)
} else {
module.StartServiceWorker("mdns udp6 unicast listener", 0, func(ctx context.Context) error {
return listenForDNSPackets(ctx, unicast6Conn, messages)
})
defer func() {
_ = unicast6Conn.Close()
}()
}
} else {
module.StartServiceWorker("mdns udp6 unicast listener", 0, func(ctx context.Context) error {
return listenForDNSPackets(ctx, unicast6Conn, messages)
})
defer func() {
_ = unicast6Conn.Close()
}()
log.Warningf("resolver: no IPv6 stack detected, disabling IPv6 mDNS resolver")
}
// start message handler