mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
cmd{containerboot,k8s-operator},util/linuxfw: support ExternalName Services (#11802)
* cmd/containerboot,util/linuxfw: support proxy backends specified by DNS name Adds support for optionally configuring containerboot to proxy traffic to backends configured by passing TS_EXPERIMENTAL_DEST_DNS_NAME env var to containerboot. Containerboot will periodically (every 10 minutes) attempt to resolve the DNS name and ensure that all traffic sent to the node's tailnet IP gets forwarded to the resolved backend IP addresses. Currently: - if the firewall mode is iptables, traffic will be load balanced accross the backend IP addresses using round robin. There are no health checks for whether the IPs are reachable. - if the firewall mode is nftables traffic will only be forwarded to the first IP address in the list. This is to be improved. * cmd/k8s-operator: support ExternalName Services Adds support for exposing endpoints, accessible from within a cluster to the tailnet via DNS names using ExternalName Services. This can be done by annotating the ExternalName Service with tailscale.com/expose: "true" annotation. The operator will deploy a proxy configured to route tailnet traffic to the backend IPs that service.spec.externalName resolves to. The backend IPs must be reachable from the operator's namespace. Updates tailscale/tailscale#10606 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
@@ -373,6 +373,27 @@ func (i *iptablesRunner) DNATNonTailscaleTraffic(tun string, dst netip.Addr) err
|
||||
return table.Insert("nat", "PREROUTING", 1, "!", "-i", tun, "-j", "DNAT", "--to-destination", dst.String())
|
||||
}
|
||||
|
||||
// DNATWithLoadBalancer adds iptables rules to forward all traffic received for
|
||||
// originDst to the backend dsts. Traffic will be load balanced using round robin.
|
||||
func (i *iptablesRunner) DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error {
|
||||
table := i.getIPTByAddr(dsts[0])
|
||||
if err := table.ClearChain("nat", "PREROUTING"); err != nil && !isErrChainNotExist(err) {
|
||||
// If clearing the PREROUTING chain fails, fail the whole operation. This
|
||||
// rule is currently only used in Kubernetes containers where a
|
||||
// failed container gets restarted which should hopefully fix things.
|
||||
return fmt.Errorf("error clearing nat PREROUTING chain: %w", err)
|
||||
}
|
||||
// If dsts contain more than one address, for n := n in range(len(dsts)..2) route packets for every nth connection to dsts[n].
|
||||
for i := len(dsts); i >= 2; i-- {
|
||||
dst := dsts[i-1] // the order in which rules for addrs are installed does not matter
|
||||
if err := table.Append("nat", "PREROUTING", "--destination", origDst.String(), "-m", "statistic", "--mode", "nth", "--every", fmt.Sprint(i), "--packet", "0", "-j", "DNAT", "--to-destination", dst.String()); err != nil {
|
||||
return fmt.Errorf("error adding DNAT rule for %s: %w", dst.String(), err)
|
||||
}
|
||||
}
|
||||
// If the packet falls through to this rule, we route to the first destination in the list unconditionally.
|
||||
return table.Append("nat", "PREROUTING", "--destination", origDst.String(), "-j", "DNAT", "--to-destination", dsts[0].String())
|
||||
}
|
||||
|
||||
func (i *iptablesRunner) ClampMSSToPMTU(tun string, addr netip.Addr) error {
|
||||
table := i.getIPTByAddr(addr)
|
||||
return table.Append("mangle", "FORWARD", "-o", tun, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu")
|
||||
|
@@ -114,7 +114,6 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
|
||||
dadderLen = 16
|
||||
fam = unix.NFPROTO_IPV6
|
||||
}
|
||||
|
||||
dnatRule := &nftables.Rule{
|
||||
Table: nat,
|
||||
Chain: preroutingCh,
|
||||
@@ -145,6 +144,15 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
|
||||
return n.conn.Flush()
|
||||
}
|
||||
|
||||
// DNATWithLoadBalancer currently just forwards all traffic destined for origDst
|
||||
// to the first IP address from the backend targets.
|
||||
// TODO (irbekrm): instead of doing this load balance traffic evenly to all
|
||||
// backend destinations.
|
||||
// https://github.com/tailscale/tailscale/commit/d37f2f508509c6c35ad724fd75a27685b90b575b#diff-a3bcbcd1ca198799f4f768dc56fea913e1945a6b3ec9dbec89325a84a19a85e7R148-R232
|
||||
func (n *nftablesRunner) DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error {
|
||||
return n.AddDNATRule(origDst, dsts[0])
|
||||
}
|
||||
|
||||
func (n *nftablesRunner) DNATNonTailscaleTraffic(tunname string, dst netip.Addr) error {
|
||||
nat, preroutingCh, err := n.ensurePreroutingChain(dst)
|
||||
if err != nil {
|
||||
@@ -524,6 +532,14 @@ type NetfilterRunner interface {
|
||||
// to the provided destination, as used in the Kubernetes ingress proxies.
|
||||
AddDNATRule(origDst, dst netip.Addr) error
|
||||
|
||||
// DNATWithLoadBalancer adds a rule to the nat/PREROUTING chain to DNAT
|
||||
// traffic destined for the given original destination to the given new
|
||||
// destination(s) using round robin to load balance if more than one
|
||||
// destination is provided. This is used to forward all traffic destined
|
||||
// for the Tailscale interface to the provided destination(s), as used
|
||||
// in the Kubernetes ingress proxies.
|
||||
DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error
|
||||
|
||||
// AddSNATRuleForDst adds a rule to the nat/POSTROUTING chain to SNAT
|
||||
// traffic destined for dst to src.
|
||||
// This is used to forward traffic destined for the local machine over
|
||||
@@ -533,7 +549,7 @@ type NetfilterRunner interface {
|
||||
// DNATNonTailscaleTraffic adds a rule to the nat/PREROUTING chain to DNAT
|
||||
// all traffic inbound from any interface except exemptInterface to dst.
|
||||
// This is used to forward traffic destined for the local machine over
|
||||
// the Tailscale interface, as used in the Kubernetes egress proxies.//
|
||||
// the Tailscale interface, as used in the Kubernetes egress proxies.
|
||||
DNATNonTailscaleTraffic(exemptInterface string, dst netip.Addr) error
|
||||
|
||||
// ClampMSSToPMTU adds a rule to the mangle/FORWARD chain to clamp MSS for
|
||||
|
Reference in New Issue
Block a user