This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / netguard / netguard.go
2.8 kB 82 lines
1// refuses outbound dials to special-purpose addresses, for anywhere 2// spindle fetches user-influenced urls (workflow caches, PDS blob 3// fetches) 4package netguard 5 6import ( 7 "fmt" 8 "net" 9 "syscall" 10) 11 12// https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml 13// https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml 14// https://datatracker.ietf.org/doc/rfc6890/ 15var BlockedRoutes = []string{ 16 "0.0.0.0/8", // unspecified / "this network" addresses 17 "10.0.0.0/8", // private network 18 "100.64.0.0/10", // shared carrier-grade nat space 19 "127.0.0.0/8", // loopback 20 "169.254.0.0/16", // link-local / autoconfiguration 21 "172.16.0.0/12", // private network 22 "192.0.0.0/24", // ietf protocol assignments 23 "192.0.2.0/24", // documentation / examples 24 "192.88.99.0/24", // deprecated 6to4 relay anycast 25 "192.168.0.0/16", // private network 26 "198.18.0.0/15", // benchmarking / testing 27 "198.51.100.0/24", // documentation / examples 28 "203.0.113.0/24", // documentation / examples 29 "224.0.0.0/4", // multicast 30 "240.0.0.0/4", // reserved / future use, includes limited broadcast 31 "::/128", // unspecified address 32 "::1/128", // loopback 33 "::ffff:0:0/96", // ipv4-mapped addresses 34 "64:ff9b::/96", // ipv4/ipv6 translation prefix 35 "100::/64", // discard-only prefix 36 "2001::/23", // ietf protocol assignments 37 "2001:db8::/32", // documentation / examples 38 "2002::/16", // deprecated 6to4 addressing 39 "fc00::/7", // unique local addresses 40 "fe80::/10", // link-local unicast 41 "ff00::/8", // multicast 42} 43 44var BlockedNets = func() []*net.IPNet { 45 nets := make([]*net.IPNet, 0, len(BlockedRoutes)) 46 for _, route := range BlockedRoutes { 47 _, ipnet, err := net.ParseCIDR(route) 48 if err != nil { 49 panic(fmt.Sprintf("parse blocked route %q: %v", route, err)) 50 } 51 nets = append(nets, ipnet) 52 } 53 return nets 54}() 55 56// net.Dialer Control func rejecting blocked special-purpose addresses. 57// this should run after dns resolution, so it should cover any rebinding tricks 58func RefuseSpecialPurposeAddrs(network, address string, _ syscall.RawConn) error { 59 host, _, err := net.SplitHostPort(address) 60 if err != nil { 61 return fmt.Errorf("split dial address %q: %w", address, err) 62 } 63 ip := net.ParseIP(host) 64 if ip == nil { 65 return fmt.Errorf("refusing to dial non-IP address %q", host) 66 } 67 bits := 128 68 if ip4 := ip.To4(); ip4 != nil { 69 ip = ip4 70 bits = 32 71 } 72 for _, ipnet := range BlockedNets { 73 _, blockedBits := ipnet.Mask.Size() 74 if blockedBits != bits { 75 continue 76 } 77 if ipnet.Contains(ip) { 78 return fmt.Errorf("refusing to dial %s: %s is blocked", ip, ipnet) 79 } 80 } 81 return nil 82}