mirror of
https://github.com/mdlayher/homelab.git
synced 2024-12-14 11:47:32 +00:00
nixos/lib/vargen: fetch IPv6 /56 dynamically
Signed-off-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
parent
2b4b722e5b
commit
2c40c7faab
1 changed files with 65 additions and 42 deletions
|
@ -17,28 +17,39 @@ import (
|
||||||
|
|
||||||
//go:generate /usr/bin/env bash -c "go run main.go > ../vars.json"
|
//go:generate /usr/bin/env bash -c "go run main.go > ../vars.json"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// pdLen is the length of the IPv6 prefix delegated to my router by Charter.
|
||||||
|
pdLen = 56
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// Fetch IPv4 address and IPv6 prefix for use elsewhere.
|
||||||
|
var (
|
||||||
|
wan4 = wanIPv4()
|
||||||
|
gua6 = wanIPv6Prefix()
|
||||||
|
)
|
||||||
|
|
||||||
// The primary subnet: all servers and network infrastructure live here.
|
// The primary subnet: all servers and network infrastructure live here.
|
||||||
var (
|
var (
|
||||||
enp2s0 = newSubnet("enp2s0", 0)
|
enp2s0 = newSubnet("enp2s0", 0, gua6)
|
||||||
|
|
||||||
lan0 = newSubnet("lan0", 10)
|
lan0 = newSubnet("lan0", 10, gua6)
|
||||||
iot0 = newSubnet("iot0", 66)
|
iot0 = newSubnet("iot0", 66, gua6)
|
||||||
// TODO: eventually fix the switch VLAN as well.
|
// TODO: eventually fix the switch VLAN as well.
|
||||||
tengb0 = newSubnet("tengb0", 110)
|
tengb0 = newSubnet("tengb0", 110, gua6)
|
||||||
wg0 = newSubnet("wg0", 20)
|
wg0 = newSubnet("wg0", 20, gua6)
|
||||||
|
|
||||||
server = newHost(
|
server = newHost(
|
||||||
"servnerr-3",
|
"servnerr-3",
|
||||||
tengb0,
|
tengb0,
|
||||||
ip("192.168.110.5"),
|
netaddr.MustParseIP("192.168.110.5"),
|
||||||
mac("90:e2:ba:5b:99:80"),
|
mac("90:e2:ba:5b:99:80"),
|
||||||
)
|
)
|
||||||
|
|
||||||
desktop = newHost(
|
desktop = newHost(
|
||||||
"nerr-3",
|
"nerr-3",
|
||||||
tengb0,
|
tengb0,
|
||||||
ip("192.168.110.6"),
|
netaddr.MustParseIP("192.168.110.6"),
|
||||||
mac("90:e2:ba:23:1a:3a"),
|
mac("90:e2:ba:23:1a:3a"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -63,19 +74,19 @@ func main() {
|
||||||
newHost(
|
newHost(
|
||||||
"theatnerr-1",
|
"theatnerr-1",
|
||||||
lan0,
|
lan0,
|
||||||
ip("192.168.10.10"),
|
netaddr.MustParseIP("192.168.10.10"),
|
||||||
mac("94:de:80:6c:0e:ef"),
|
mac("94:de:80:6c:0e:ef"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"monitnerr-1",
|
"monitnerr-1",
|
||||||
lan0,
|
lan0,
|
||||||
ip("192.168.10.11"),
|
netaddr.MustParseIP("192.168.10.11"),
|
||||||
mac("dc:a6:32:1e:66:94"),
|
mac("dc:a6:32:1e:66:94"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"monitnerr-2",
|
"monitnerr-2",
|
||||||
lan0,
|
lan0,
|
||||||
ip("192.168.10.12"),
|
netaddr.MustParseIP("192.168.10.12"),
|
||||||
mac("dc:a6:32:7e:b6:fe"),
|
mac("dc:a6:32:7e:b6:fe"),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -83,31 +94,31 @@ func main() {
|
||||||
newHost(
|
newHost(
|
||||||
"switch-livingroom01",
|
"switch-livingroom01",
|
||||||
enp2s0,
|
enp2s0,
|
||||||
ip("192.168.1.2"),
|
netaddr.MustParseIP("192.168.1.2"),
|
||||||
mac("f0:9f:c2:0b:28:ca"),
|
mac("f0:9f:c2:0b:28:ca"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"switch-office01",
|
"switch-office01",
|
||||||
enp2s0,
|
enp2s0,
|
||||||
ip("192.168.1.3"),
|
netaddr.MustParseIP("192.168.1.3"),
|
||||||
mac("f0:9f:c2:ce:7e:e1"),
|
mac("f0:9f:c2:ce:7e:e1"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"switch-office02",
|
"switch-office02",
|
||||||
enp2s0,
|
enp2s0,
|
||||||
ip("192.168.1.4"),
|
netaddr.MustParseIP("192.168.1.4"),
|
||||||
mac("c4:ad:34:ba:40:82"),
|
mac("c4:ad:34:ba:40:82"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"ap-livingroom02",
|
"ap-livingroom02",
|
||||||
enp2s0,
|
enp2s0,
|
||||||
ip("192.168.1.5"),
|
netaddr.MustParseIP("192.168.1.5"),
|
||||||
mac("74:83:c2:7a:c6:15"),
|
mac("74:83:c2:7a:c6:15"),
|
||||||
),
|
),
|
||||||
newHost(
|
newHost(
|
||||||
"keylight",
|
"keylight",
|
||||||
iot0,
|
iot0,
|
||||||
ip("192.168.66.10"),
|
netaddr.MustParseIP("192.168.66.10"),
|
||||||
mac("3c:6a:9d:12:c4:dc"),
|
mac("3c:6a:9d:12:c4:dc"),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -118,9 +129,9 @@ func main() {
|
||||||
// Attach interface definitions from subnet definitions.
|
// Attach interface definitions from subnet definitions.
|
||||||
out.addInterface("enp2s0", enp2s0)
|
out.addInterface("enp2s0", enp2s0)
|
||||||
out.addInterface("lan0", lan0)
|
out.addInterface("lan0", lan0)
|
||||||
out.addInterface("guest0", newSubnet("guest0", 9))
|
out.addInterface("guest0", newSubnet("guest0", 9, gua6))
|
||||||
out.addInterface("iot0", iot0)
|
out.addInterface("iot0", iot0)
|
||||||
out.addInterface("lab0", newSubnet("lab0", 2))
|
out.addInterface("lab0", newSubnet("lab0", 2, gua6))
|
||||||
out.addInterface("tengb0", tengb0)
|
out.addInterface("tengb0", tengb0)
|
||||||
out.addInterface("wg0", wg0)
|
out.addInterface("wg0", wg0)
|
||||||
|
|
||||||
|
@ -128,7 +139,7 @@ func main() {
|
||||||
// section with different rules.
|
// section with different rules.
|
||||||
out.Interfaces["wan0"] = iface{
|
out.Interfaces["wan0"] = iface{
|
||||||
Name: "enp1s0",
|
Name: "enp1s0",
|
||||||
IPv4: wanIPv4(),
|
IPv4: wan4,
|
||||||
}
|
}
|
||||||
out.Interfaces["wwan0"] = iface{
|
out.Interfaces["wwan0"] = iface{
|
||||||
Name: "wwp0s19u1u3i12",
|
Name: "wwp0s19u1u3i12",
|
||||||
|
@ -154,7 +165,31 @@ func wanIPv4() netaddr.IP {
|
||||||
log.Fatalf("failed to read HTTP body: %v", err)
|
log.Fatalf("failed to read HTTP body: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip(strings.TrimSpace(string(b)))
|
return netaddr.MustParseIP(strings.TrimSpace(string(b)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func wanIPv6Prefix() netaddr.IPPrefix {
|
||||||
|
res, err := http.Get("https://ipv6.icanhazip.com")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to perform HTTP request: %v", err)
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to read HTTP body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to determine the WAN IPv6 prefix so we can use that elsewhere
|
||||||
|
// when the ISP decides to change it after some period of time. The prefix
|
||||||
|
// length is hardcoded so it can be used elsewhere.
|
||||||
|
ip := netaddr.MustParseIP(strings.TrimSpace(string(b)))
|
||||||
|
pfx, err := ip.Prefix(pdLen)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create prefix from IP: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pfx
|
||||||
}
|
}
|
||||||
|
|
||||||
type output struct {
|
type output struct {
|
||||||
|
@ -184,8 +219,14 @@ type ipv6Addresses struct {
|
||||||
LLA netaddr.IP `json:"lla"`
|
LLA netaddr.IP `json:"lla"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSubnet(iface string, vlan int) subnet {
|
func newSubnet(iface string, vlan int, gua netaddr.IPPrefix) subnet {
|
||||||
gua := prefix(fmt.Sprintf("2600:6c4a:787f:59%02x::/64", vlan))
|
// The GUA prefix passed is a larger prefix such as a /48 or /56 and must
|
||||||
|
// be combined with the VLAN identifier to create a single /64 subnet for
|
||||||
|
// use with machines.
|
||||||
|
sub6 := gua.IP.As16()
|
||||||
|
sub6[pdLen/8] = byte(vlan)
|
||||||
|
gua.IP = netaddr.IPFrom16(sub6)
|
||||||
|
gua.Bits = 64
|
||||||
|
|
||||||
// A hack to continue using 192.168.1.0/24 for the management network.
|
// A hack to continue using 192.168.1.0/24 for the management network.
|
||||||
v4Subnet := vlan
|
v4Subnet := vlan
|
||||||
|
@ -195,11 +236,11 @@ func newSubnet(iface string, vlan int) subnet {
|
||||||
|
|
||||||
return subnet{
|
return subnet{
|
||||||
Name: iface,
|
Name: iface,
|
||||||
IPv4: prefix(fmt.Sprintf("192.168.%d.0/24", v4Subnet)),
|
IPv4: netaddr.MustParseIPPrefix(fmt.Sprintf("192.168.%d.0/24", v4Subnet)),
|
||||||
IPv6: ipv6Prefixes{
|
IPv6: ipv6Prefixes{
|
||||||
GUA: gua,
|
GUA: gua,
|
||||||
LLA: prefix("fe80::/64"),
|
LLA: netaddr.MustParseIPPrefix("fe80::/64"),
|
||||||
ULA: prefix(fmt.Sprintf("fd9e:1a04:f01d:%d::/64", vlan)),
|
ULA: netaddr.MustParseIPPrefix(fmt.Sprintf("fd9e:1a04:f01d:%d::/64", vlan)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,24 +399,6 @@ func mac(s string) net.HardwareAddr {
|
||||||
return mac
|
return mac
|
||||||
}
|
}
|
||||||
|
|
||||||
func ip(s string) netaddr.IP {
|
|
||||||
ip, err := netaddr.ParseIP(s)
|
|
||||||
if err != nil {
|
|
||||||
panicf("failed to parse IP: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
|
|
||||||
func prefix(s string) netaddr.IPPrefix {
|
|
||||||
ip, err := netaddr.ParseIPPrefix(s)
|
|
||||||
if err != nil {
|
|
||||||
panicf("failed to parse IPPrefix: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
|
|
||||||
func panicf(format string, a ...interface{}) {
|
func panicf(format string, a ...interface{}) {
|
||||||
panic(fmt.Sprintf(format, a...))
|
panic(fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue