Compare commits

...

3 Commits

Author SHA1 Message Date
Quentin McGaw
42caa64743 fix(httpproxy): redirect from http to https 2023-05-29 09:40:37 +00:00
Quentin McGaw
6d48f9c2ba fix(routing): net.IPNet to netip.Prefix conversion 2023-05-22 05:56:27 +00:00
Quentin McGaw
f712d77642 fix(firewall): prevent IP family mix in acceptOutputFromIPToSubnet 2023-05-21 18:06:18 +00:00
4 changed files with 70 additions and 3 deletions

View File

@@ -157,6 +157,13 @@ func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context, func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
intf string, sourceIP netip.Addr, destinationSubnet netip.Prefix, remove bool) error { intf string, sourceIP netip.Addr, destinationSubnet netip.Prefix, remove bool) error {
doIPv4 := sourceIP.Is4() && destinationSubnet.Addr().Is4() doIPv4 := sourceIP.Is4() && destinationSubnet.Addr().Is4()
doIPv6 := sourceIP.Is6() && destinationSubnet.Addr().Is6()
if !doIPv4 && !doIPv6 {
c.logger.Debug(fmt.Sprintf(
"source IP address %s and destination subnet %s are not of the same IP family, skipping...",
sourceIP, destinationSubnet))
return nil
}
interfaceFlag := "-o " + intf interfaceFlag := "-o " + intf
if intf == "*" { // all interfaces if intf == "*" { // all interfaces

View File

@@ -2,7 +2,6 @@ package httpproxy
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"sync" "sync"
"time" "time"
@@ -66,5 +65,8 @@ var hopHeaders = [...]string{ //nolint:gochecknoglobals
// Do not follow redirect, but directly return the redirect response. // Do not follow redirect, but directly return the redirect response.
func returnRedirect(*http.Request, []*http.Request) error { func returnRedirect(*http.Request, []*http.Request) error {
return fmt.Errorf("%w", http.ErrUseLastResponse) // WARNING: do not wrap this error!
// The standard library code checking against it does not use
// Go 1.13 `errors.Is` but `==`, so we cannot wrap it.
return http.ErrUseLastResponse
} }

View File

@@ -21,7 +21,17 @@ func NetipPrefixToIPNet(prefix *netip.Prefix) (ipNet *net.IPNet) {
} }
func netIPNetToNetipPrefix(ipNet net.IPNet) (prefix netip.Prefix) { func netIPNetToNetipPrefix(ipNet net.IPNet) (prefix netip.Prefix) {
return netip.MustParsePrefix(ipNet.String()) if len(ipNet.IP) != net.IPv4len && len(ipNet.IP) != net.IPv6len {
return prefix
}
var ip netip.Addr
if ipv4 := ipNet.IP.To4(); ipv4 != nil {
ip = netip.AddrFrom4([4]byte(ipv4))
} else {
ip = netip.AddrFrom16([16]byte(ipNet.IP))
}
bits, _ := ipNet.Mask.Size()
return netip.PrefixFrom(ip, bits)
} }
func netIPToNetipAddress(ip net.IP) (address netip.Addr) { func netIPToNetipAddress(ip net.IP) (address netip.Addr) {

View File

@@ -8,6 +8,54 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_netIPNetToNetipPrefix(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
ipNet net.IPNet
prefix netip.Prefix
}{
"empty ipnet": {},
"custom sized IP in ipnet": {
ipNet: net.IPNet{
IP: net.IP{1},
},
},
"IPv4 ipnet": {
ipNet: net.IPNet{
IP: net.IP{1, 2, 3, 4},
Mask: net.IPMask{255, 255, 255, 0},
},
prefix: netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
},
"IPv4-in-IPv6 ipnet": {
ipNet: net.IPNet{
IP: net.IPv4(1, 2, 3, 4),
Mask: net.IPMask{255, 255, 255, 0},
},
prefix: netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
},
"IPv6 ipnet": {
ipNet: net.IPNet{
IP: net.IPv6loopback,
Mask: net.IPMask{0xff},
},
prefix: netip.PrefixFrom(netip.IPv6Loopback(), 8),
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
prefix := netIPNetToNetipPrefix(testCase.ipNet)
assert.Equal(t, testCase.prefix, prefix)
})
}
}
func Test_netIPToNetipAddress(t *testing.T) { func Test_netIPToNetipAddress(t *testing.T) {
t.Parallel() t.Parallel()