linuxfw

package
v0.0.0-...-8b68177 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 3, 2024 License: BSD-3-Clause Imports: 33 Imported by: 0

Documentation

Overview

Package linuxfw returns the kind of firewall being used by the kernel.

Index

Constants

View Source
const (
	// The mask for reading/writing the 'firewall mask' bits on a packet.
	// See the comment on the const block on why we only use the third byte.
	//
	// We claim bits 16:23 entirely. For now we only use the lower four
	// bits, leaving the higher 4 bits for future use.
	TailscaleFwmarkMask    = "0xff0000"
	TailscaleFwmarkMaskNum = 0xff0000

	// Packet is from Tailscale and to a subnet route destination, so
	// is allowed to be routed through this machine.
	TailscaleSubnetRouteMark    = "0x40000"
	TailscaleSubnetRouteMarkNum = 0x40000

	// Packet was originated by tailscaled itself, and must not be
	// routed over the Tailscale network.
	TailscaleBypassMark    = "0x80000"
	TailscaleBypassMarkNum = 0x80000
)

The following bits are added to packet marks for Tailscale use.

We tried to pick bits sufficiently out of the way that it's unlikely to collide with existing uses. We have 4 bytes of mark bits to play with. We leave the lower byte alone on the assumption that sysadmins would use those. Kubernetes uses a few bits in the second byte, so we steer clear of that too.

Empirically, most of the documentation on packet marks on the internet gives the impression that the marks are 16 bits wide. Based on this, we theorize that the upper two bytes are relatively unused in the wild, and so we consume bits 16:23 (the third byte).

The constants are in the iptables/iproute2 string format for matching and setting the bits, so they can be directly embedded in commands.

Variables

This section is empty.

Functions

func CheckIPRuleSupportsV6

func CheckIPRuleSupportsV6(logf logger.Logf) error

func CheckIPv6

func CheckIPv6(logf logger.Logf) error

checkIPv6 checks whether the system appears to have a working IPv6 network stack. It returns an error explaining what looks wrong or missing. It does not check that IPv6 is currently functional or that there's a global address, just that the system would support IPv6 if it were on an IPv6 network.

func DebugIptables

func DebugIptables(logf logger.Logf) error

DebugNetfilter prints debug information about iptables rules to the provided log function.

func DebugNetfilter

func DebugNetfilter(logf logger.Logf) error

DebugNetfilter prints debug information about netfilter rules to the provided log function.

func IPTablesCleanUp

func IPTablesCleanUp(logf logger.Logf)

IPTablesCleanUp removes all Tailscale added iptables rules. Any errors that occur are logged to the provided logf.

func NewFakeIPTablesRunner

func NewFakeIPTablesRunner() *iptablesRunner

func NfTablesCleanUp

func NfTablesCleanUp(logf logger.Logf)

NfTablesCleanUp removes all Tailscale added nftables rules. Any errors that occur are logged to the provided logf.

Types

type FWModeNotSupportedError

type FWModeNotSupportedError struct {
	Mode FirewallMode
	Err  error
}

func (FWModeNotSupportedError) Error

func (e FWModeNotSupportedError) Error() string

func (FWModeNotSupportedError) Is

func (e FWModeNotSupportedError) Is(target error) bool

func (FWModeNotSupportedError) Unwrap

func (e FWModeNotSupportedError) Unwrap() error

type FirewallMode

type FirewallMode string
const (
	FirewallModeIPTables FirewallMode = "iptables"
	FirewallModeNfTables FirewallMode = "nftables"
)

type MatchDecision

type MatchDecision int

MatchDecision is the decision made by the firewall for a packet matched by a rule. It is used to decide whether to accept or masquerade a packet in addMatchSubnetRouteMarkRule.

const (
	Accept MatchDecision = iota
	Masq
)

type NetfilterRunner

type NetfilterRunner interface {
	// AddLoopbackRule adds a rule to permit loopback traffic to addr. This rule
	// is added only if it does not already exist.
	AddLoopbackRule(addr netip.Addr) error

	// DelLoopbackRule removes the rule added by AddLoopbackRule.
	DelLoopbackRule(addr netip.Addr) error

	// AddHooks adds rules to conventional chains like "FORWARD", "INPUT" and
	// "POSTROUTING" to jump from those chains to tailscale chains.
	AddHooks() error

	// DelHooks deletes rules added by AddHooks.
	DelHooks(logf logger.Logf) error

	// AddChains creates custom Tailscale chains.
	AddChains() error

	// DelChains removes chains added by AddChains.
	DelChains() error

	// AddBase adds rules reused by different other rules.
	AddBase(tunname string) error

	// DelBase removes rules added by AddBase.
	DelBase() error

	// AddSNATRule adds the netfilter rule to SNAT incoming traffic over
	// the Tailscale interface destined for local subnets. An error is
	// returned if the rule already exists.
	AddSNATRule() error

	// DelSNATRule removes the rule added by AddSNATRule.
	DelSNATRule() error

	// AddStatefulRule adds a netfilter rule for stateful packet filtering
	// using conntrack.
	AddStatefulRule(tunname string) error

	// DelStatefulRule removes a netfilter rule for stateful packet filtering
	// using conntrack.
	DelStatefulRule(tunname string) error

	// HasIPV6 reports true if the system supports IPv6.
	HasIPV6() bool

	// HasIPV6NAT reports true if the system supports IPv6 NAT.
	HasIPV6NAT() bool

	// HasIPV6Filter reports true if the system supports IPv6 filter tables
	// This is only meaningful for iptables implementation, where hosts have
	// partial ipables support (i.e missing filter table). For nftables
	// implementation, this will default to the value of HasIPv6().
	HasIPV6Filter() bool

	// AddDNATRule adds a rule to the nat/PREROUTING chain to DNAT traffic
	// destined for the given original destination to the given new destination.
	// This is used to forward all traffic destined for the Tailscale 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

	// EnsureSNATForDst sets up firewall to mask the source for traffic destined for dst to src:
	// - creates a SNAT rule if it doesn't already exist
	// - deletes any pre-existing rules matching the destination
	// This is used to forward traffic destined for the local machine over
	// the Tailscale interface, as used in the Kubernetes egress proxies.
	EnsureSNATForDst(src, dst netip.Addr) error

	// 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.
	DNATNonTailscaleTraffic(exemptInterface string, dst netip.Addr) error

	EnsurePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error

	DeletePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error

	DeleteSvc(svc, tun string, targetIPs []netip.Addr, pm []PortMap) error

	// ClampMSSToPMTU adds a rule to the mangle/FORWARD chain to clamp MSS for
	// traffic destined for the provided tun interface.
	ClampMSSToPMTU(tun string, addr netip.Addr) error

	// AddMagicsockPortRule adds a rule to the ts-input chain to accept
	// incoming traffic on the specified port, to allow magicsock to
	// communicate.
	AddMagicsockPortRule(port uint16, network string) error

	// DelMagicsockPortRule removes the rule created by AddMagicsockPortRule,
	// if it exists.
	DelMagicsockPortRule(port uint16, network string) error
}

NetfilterRunner abstracts helpers to run netfilter commands. It is implemented by linuxfw.IPTablesRunner and linuxfw.NfTablesRunner.

func New

func New(logf logger.Logf, prefHint string) (NetfilterRunner, error)

New creates a NetfilterRunner, auto-detecting whether to use nftables or iptables. As nftables is still experimental, iptables will be used unless either the TS_DEBUG_FIREWALL_MODE environment variable, or the prefHint parameter, is set to one of "nftables" or "auto".

type PortMap

type PortMap struct {
	// MatchPort is the local port to which the rule should apply.
	MatchPort uint16
	// TargetPort is the port to which the traffic should be forwarded.
	TargetPort uint16
	// Protocol is the protocol to match packets on. Only TCP and UDP are
	// supported.
	Protocol string
}

// PortMap is the port mapping for a service rule.

Directories

Path Synopsis
Package linuxfwtest contains tests for the linuxfw package.
Package linuxfwtest contains tests for the linuxfw package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL