Skip to content

Commit

Permalink
Check if we are on ipv4, ipv6 or dualStack when doing tailscale
Browse files Browse the repository at this point in the history
Signed-off-by: Manuel Buil <mbuil@suse.com>
  • Loading branch information
manuelbuil committed Jul 3, 2023
1 parent 2215870 commit f21a014
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 21 deletions.
15 changes: 12 additions & 3 deletions pkg/agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,15 +390,24 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
if err != nil {
return nil, err
}
if len(vpnInfo.IPs) != 0 {
logrus.Infof("Node-ip changed to %v due to VPN", vpnInfo.IPs)

var vpnIPs []net.IP
if vpnInfo.IPv4Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv4Address)
}
if vpnInfo.IPv6Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv6Address)
}

if len(vpnIPs) != 0 {
logrus.Infof("Node-ip changed to %v due to VPN", vpnIPs)
if len(envInfo.NodeIP) != 0 {
logrus.Warn("VPN provider overrides configured node-ip parameter")
}
if len(envInfo.NodeExternalIP) != 0 {
logrus.Warn("VPN provider overrides node-external-ip parameter")
}
nodeIPs = vpnInfo.IPs
nodeIPs = vpnIPs
flannelIface, err = net.InterfaceByName(vpnInfo.VPNInterface)
if err != nil {
return nil, errors.Wrapf(err, "unable to find vpn interface: %s", vpnInfo.VPNInterface)
Expand Down
25 changes: 20 additions & 5 deletions pkg/cli/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,27 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
if err != nil {
return err
}
if len(vpnInfo.IPs) != 0 {
logrus.Infof("Advertise-address changed to %v due to VPN", vpnInfo.IPs)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
// If we are in ipv6-only mode, we should pass the ipv6 address. Otherwise, ipv4
if utilsnet.IsIPv6CIDRString(util.JoinIPNets(serverConfig.ControlConfig.ClusterIPRanges)) {
if vpnInfo.IPv6Address != nil {
logrus.Infof("Advertise-address changed to %v due to VPN", vpnInfo.IPv6Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
serverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv6Address.String()
} else {
return errors.New("tailscale does not provide an ipv6 address")
}
} else {
if vpnInfo.IPv4Address != nil {
logrus.Infof("Advertise-address changed to %v due to VPN", vpnInfo.IPv4Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
serverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv4Address.String()
} else {
return errors.New("tailscale does not provide an ipv4 address")
}
serverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPs[0].String()
}
logrus.Warn("Etcd IP (PrivateIP) remains the local IP. Running etcd traffic over VPN is not recommended due to performance issues")
} else {
Expand Down
13 changes: 6 additions & 7 deletions pkg/util/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
apinet "k8s.io/apimachinery/pkg/util/net"
netutils "k8s.io/utils/net"
)

// JoinIPs stringifies and joins a list of IP addresses with commas.
Expand Down Expand Up @@ -85,10 +86,9 @@ func JoinIP4Nets(elems []*net.IPNet) string {
// If no IPv6 addresses are found, an error is raised.
func GetFirst6(elems []net.IP) (net.IP, error) {
for _, elem := range elems {
if elem == nil || elem.To16() == nil {
continue
if elem != nil && netutils.IsIPv6(elem) {
return elem, nil
}
return elem, nil
}
return nil, errors.New("no IPv6 address found")
}
Expand All @@ -97,10 +97,9 @@ func GetFirst6(elems []net.IP) (net.IP, error) {
// If no IPv6 addresses are found, an error is raised.
func GetFirst6Net(elems []*net.IPNet) (*net.IPNet, error) {
for _, elem := range elems {
if elem == nil || elem.IP.To16() == nil {
continue
if elem != nil && netutils.IsIPv6(elem.IP) {
return elem, nil
}
return elem, nil
}
return nil, errors.New("no IPv6 CIDRs found")
}
Expand All @@ -125,7 +124,7 @@ func GetFirst6String(elems []string) (string, error) {
func JoinIP6Nets(elems []*net.IPNet) string {
var strs []string
for _, elem := range elems {
if elem != nil && elem.IP.To4() == nil {
if elem != nil && netutils.IsIPv6(elem.IP) {
strs = append(strs, elem.String())
}
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/vpn/vpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ type TailscaleOutput struct {

// VPNInfo includes node information of the VPN. It is a general struct in case we want to add more vpn integrations
type VPNInfo struct {
IPs []net.IP
IPv4Address net.IP
IPv6Address net.IP
NodeID string
ProviderName string
VPNInterface string
Expand Down Expand Up @@ -112,15 +113,14 @@ func getTailscaleInfo() (VPNInfo, error) {
logrus.Debugf("Output from tailscale status --json: %v", output)

var tailscaleOutput TailscaleOutput
var internalIPs []net.IP
err = json.Unmarshal([]byte(output), &tailscaleOutput)
if err != nil {
return VPNInfo{}, fmt.Errorf("failed to unmarshal tailscale output: %v", err)
}

for _, address := range tailscaleOutput.TailscaleIPs {
internalIPs = append(internalIPs, net.ParseIP(address))
}
// Errors are ignored because the interface might not have ipv4 or ipv6 addresses (that's the only possible error)
ipv4Address, _ := util.GetFirst4String(tailscaleOutput.TailscaleIPs)
ipv6Address, _ := util.GetFirst6String(tailscaleOutput.TailscaleIPs)

return VPNInfo{IPs: internalIPs, NodeID: "", ProviderName: "tailscale", VPNInterface: tailscaleIf}, nil
return VPNInfo{IPv4Address: net.ParseIP(ipv4Address), IPv6Address: net.ParseIP(ipv6Address), NodeID: "", ProviderName: "tailscale", VPNInterface: tailscaleIf}, nil
}

0 comments on commit f21a014

Please sign in to comment.