2024-09-07 13:46:59 +00:00
|
|
|
package children
|
2021-04-20 21:31:37 +00:00
|
|
|
|
|
|
|
import (
|
2022-10-20 19:59:46 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
2023-08-05 21:53:17 +00:00
|
|
|
"isle/bootstrap"
|
2024-09-07 13:11:04 +00:00
|
|
|
"isle/daemon/daecommon"
|
2023-08-05 21:53:17 +00:00
|
|
|
"isle/yamlutil"
|
2021-04-20 21:31:37 +00:00
|
|
|
"net"
|
|
|
|
"path/filepath"
|
|
|
|
|
2023-07-06 15:51:38 +00:00
|
|
|
"code.betamike.com/micropelago/pmux/pmuxlib"
|
2024-07-06 13:36:48 +00:00
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
2024-06-15 21:02:24 +00:00
|
|
|
"github.com/slackhq/nebula/cert"
|
2021-04-20 21:31:37 +00:00
|
|
|
)
|
|
|
|
|
2022-10-20 19:59:46 +00:00
|
|
|
// waitForNebula waits for the nebula interface to have been started up. It does
|
|
|
|
// this by attempting to create a UDP connection which has the nebula IP set as
|
|
|
|
// its source. If this succeeds we can assume that at the very least the nebula
|
|
|
|
// interface has been initialized.
|
2024-06-17 18:51:02 +00:00
|
|
|
func waitForNebula(
|
2024-07-06 13:36:48 +00:00
|
|
|
ctx context.Context, logger *mlog.Logger, hostBootstrap bootstrap.Bootstrap,
|
2024-06-17 18:51:02 +00:00
|
|
|
) error {
|
2024-07-06 13:36:48 +00:00
|
|
|
var (
|
2024-07-13 14:08:13 +00:00
|
|
|
ip = net.IP(hostBootstrap.ThisHost().IP().AsSlice())
|
2024-07-06 13:36:48 +00:00
|
|
|
lUDPAddr = &net.UDPAddr{IP: ip, Port: 0}
|
|
|
|
rUDPAddr = &net.UDPAddr{IP: ip, Port: 45535}
|
|
|
|
)
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2024-07-06 13:36:48 +00:00
|
|
|
ctx = mctx.Annotate(ctx, "lUDPAddr", lUDPAddr, "rUDPAddr", rUDPAddr)
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2024-07-06 13:36:48 +00:00
|
|
|
until(
|
|
|
|
ctx,
|
|
|
|
logger,
|
|
|
|
"Creating UDP socket from nebula addr",
|
|
|
|
func(context.Context) error {
|
|
|
|
conn, err := net.DialUDP("udp", lUDPAddr, rUDPAddr)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
conn.Close()
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
)
|
2022-10-20 19:59:46 +00:00
|
|
|
|
2024-07-06 13:36:48 +00:00
|
|
|
return ctx.Err()
|
2022-10-20 19:59:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-19 18:49:04 +00:00
|
|
|
func nebulaConfig(
|
2024-09-10 20:51:33 +00:00
|
|
|
networkConfig daecommon.NetworkConfig,
|
2024-07-06 13:36:48 +00:00
|
|
|
hostBootstrap bootstrap.Bootstrap,
|
2022-10-26 21:21:31 +00:00
|
|
|
) (
|
2024-07-19 18:49:04 +00:00
|
|
|
map[string]any, error,
|
2022-10-26 21:21:31 +00:00
|
|
|
) {
|
2021-04-20 21:31:37 +00:00
|
|
|
var (
|
|
|
|
lighthouseHostIPs []string
|
|
|
|
staticHostMap = map[string][]string{}
|
|
|
|
)
|
|
|
|
|
2022-10-26 22:23:39 +00:00
|
|
|
for _, host := range hostBootstrap.Hosts {
|
2021-04-20 21:31:37 +00:00
|
|
|
|
|
|
|
if host.Nebula.PublicAddr == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-10-29 19:11:40 +00:00
|
|
|
ip := host.IP().String()
|
|
|
|
lighthouseHostIPs = append(lighthouseHostIPs, ip)
|
|
|
|
staticHostMap[ip] = []string{host.Nebula.PublicAddr}
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2024-06-23 12:37:10 +00:00
|
|
|
caCertPEM, err := hostBootstrap.CAPublicCredentials.Cert.Unwrap().MarshalToPEM()
|
2024-06-15 21:02:24 +00:00
|
|
|
if err != nil {
|
2024-07-19 18:49:04 +00:00
|
|
|
return nil, fmt.Errorf("marshaling CA cert to PEM: :%w", err)
|
2024-06-15 21:02:24 +00:00
|
|
|
}
|
|
|
|
|
2024-06-23 12:37:10 +00:00
|
|
|
hostCertPEM, err := hostBootstrap.PublicCredentials.Cert.Unwrap().MarshalToPEM()
|
2024-06-15 21:02:24 +00:00
|
|
|
if err != nil {
|
2024-07-19 18:49:04 +00:00
|
|
|
return nil, fmt.Errorf("marshaling host cert to PEM: :%w", err)
|
2024-06-15 21:02:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hostKeyPEM := cert.MarshalX25519PrivateKey(
|
|
|
|
hostBootstrap.PrivateCredentials.EncryptingPrivateKey.Bytes(),
|
|
|
|
)
|
|
|
|
|
2024-07-19 18:49:04 +00:00
|
|
|
config := map[string]any{
|
2021-04-20 21:31:37 +00:00
|
|
|
"pki": map[string]string{
|
2024-06-15 21:02:24 +00:00
|
|
|
"ca": string(caCertPEM),
|
|
|
|
"cert": string(hostCertPEM),
|
|
|
|
"key": string(hostKeyPEM),
|
2021-04-20 21:31:37 +00:00
|
|
|
},
|
|
|
|
"static_host_map": staticHostMap,
|
|
|
|
"punchy": map[string]bool{
|
|
|
|
"punch": true,
|
|
|
|
"respond": true,
|
|
|
|
},
|
2024-07-19 18:49:04 +00:00
|
|
|
"tun": map[string]any{
|
2024-09-10 20:51:33 +00:00
|
|
|
"dev": networkConfig.VPN.Tun.Device,
|
2021-04-20 21:31:37 +00:00
|
|
|
},
|
2024-09-10 20:51:33 +00:00
|
|
|
"firewall": networkConfig.VPN.Firewall,
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 20:51:33 +00:00
|
|
|
if publicAddr := networkConfig.VPN.PublicAddr; publicAddr == "" {
|
2021-04-20 21:31:37 +00:00
|
|
|
|
|
|
|
config["listen"] = map[string]string{
|
|
|
|
"host": "0.0.0.0",
|
|
|
|
"port": "0",
|
|
|
|
}
|
|
|
|
|
2024-07-19 18:49:04 +00:00
|
|
|
config["lighthouse"] = map[string]any{
|
2021-04-20 21:31:37 +00:00
|
|
|
"hosts": lighthouseHostIPs,
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
_, port, err := net.SplitHostPort(publicAddr)
|
|
|
|
|
|
|
|
if err != nil {
|
2024-07-19 18:49:04 +00:00
|
|
|
return nil, fmt.Errorf(
|
|
|
|
"parsing public address %q: %w", publicAddr, err,
|
|
|
|
)
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
config["listen"] = map[string]string{
|
|
|
|
"host": "0.0.0.0",
|
|
|
|
"port": port,
|
|
|
|
}
|
|
|
|
|
2024-07-19 18:49:04 +00:00
|
|
|
config["lighthouse"] = map[string]any{
|
2021-04-20 21:31:37 +00:00
|
|
|
"hosts": []string{},
|
|
|
|
"am_lighthouse": true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-19 18:49:04 +00:00
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func nebulaWriteConfig(
|
|
|
|
runtimeDirPath string,
|
2024-09-10 20:51:33 +00:00
|
|
|
networkConfig daecommon.NetworkConfig,
|
2024-07-19 18:49:04 +00:00
|
|
|
hostBootstrap bootstrap.Bootstrap,
|
|
|
|
) (
|
|
|
|
string, error,
|
|
|
|
) {
|
2024-09-10 20:51:33 +00:00
|
|
|
config, err := nebulaConfig(networkConfig, hostBootstrap)
|
2024-07-19 18:49:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("creating nebula config: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-06-17 18:51:02 +00:00
|
|
|
nebulaYmlPath := filepath.Join(runtimeDirPath, "nebula.yml")
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2024-07-14 13:50:24 +00:00
|
|
|
if err := yamlutil.WriteYamlFile(config, nebulaYmlPath, 0600); err != nil {
|
2024-07-19 18:49:04 +00:00
|
|
|
return "", fmt.Errorf("writing nebula.yml to %q: %w", nebulaYmlPath, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nebulaYmlPath, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func nebulaPmuxProcConfig(
|
|
|
|
runtimeDirPath, binDirPath string,
|
2024-09-10 20:51:33 +00:00
|
|
|
networkConfig daecommon.NetworkConfig,
|
2024-07-19 18:49:04 +00:00
|
|
|
hostBootstrap bootstrap.Bootstrap,
|
|
|
|
) (
|
|
|
|
pmuxlib.ProcessConfig, error,
|
|
|
|
) {
|
2024-09-10 20:51:33 +00:00
|
|
|
config, err := nebulaConfig(networkConfig, hostBootstrap)
|
2024-07-19 18:49:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return pmuxlib.ProcessConfig{}, fmt.Errorf(
|
|
|
|
"creating nebula config: %w", err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
nebulaYmlPath := filepath.Join(runtimeDirPath, "nebula.yml")
|
|
|
|
if err := yamlutil.WriteYamlFile(config, nebulaYmlPath, 0600); err != nil {
|
|
|
|
return pmuxlib.ProcessConfig{}, fmt.Errorf(
|
|
|
|
"writing nebula.yml to %q: %w", nebulaYmlPath, err,
|
|
|
|
)
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2022-10-20 19:59:46 +00:00
|
|
|
return pmuxlib.ProcessConfig{
|
2024-07-19 14:50:20 +00:00
|
|
|
Cmd: filepath.Join(binDirPath, "nebula"),
|
|
|
|
Args: []string{"-config", nebulaYmlPath},
|
|
|
|
Group: -1, // Make sure nebula is shut down last.
|
2022-10-20 19:59:46 +00:00
|
|
|
}, nil
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|