net/tstun: drop TSMP messages injected into TUN (#20511)
Enforce that TSMP messages are only accepted for transmission over the wireguard connection from within the client. Updates tailscale/corp#45059 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
@@ -761,6 +761,14 @@ func (t *Wrapper) filterPacketOutboundToWireGuard(p *packet.Parsed, pc *peerConf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TSMP traffic should only originate from tailscaled, not from the host
|
||||||
|
// itself.
|
||||||
|
if p.IPProto == ipproto.TSMP {
|
||||||
|
t.limitedLogf("[unexpected] received TSMP out packet over tstun; dropping")
|
||||||
|
metricPacketOutDropTSMP.Add(1)
|
||||||
|
return filter.DropSilently, gro
|
||||||
|
}
|
||||||
|
|
||||||
// Issue 1526 workaround: if we sent disco packets over
|
// Issue 1526 workaround: if we sent disco packets over
|
||||||
// Tailscale from ourselves, then drop them, as that shouldn't
|
// Tailscale from ourselves, then drop them, as that shouldn't
|
||||||
// happen unless a networking stack is confused, as it seems
|
// happen unless a networking stack is confused, as it seems
|
||||||
@@ -1507,6 +1515,7 @@ var (
|
|||||||
metricPacketOutDrop = clientmetric.NewCounter("tstun_out_to_wg_drop")
|
metricPacketOutDrop = clientmetric.NewCounter("tstun_out_to_wg_drop")
|
||||||
metricPacketOutDropFilter = clientmetric.NewCounter("tstun_out_to_wg_drop_filter")
|
metricPacketOutDropFilter = clientmetric.NewCounter("tstun_out_to_wg_drop_filter")
|
||||||
metricPacketOutDropSelfDisco = clientmetric.NewCounter("tstun_out_to_wg_drop_self_disco")
|
metricPacketOutDropSelfDisco = clientmetric.NewCounter("tstun_out_to_wg_drop_self_disco")
|
||||||
|
metricPacketOutDropTSMP = clientmetric.NewCounter("tstun_out_to_wg_drop_tsmp")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Wrapper) InstallCaptureHook(cb packet.CaptureCallback) {
|
func (t *Wrapper) InstallCaptureHook(cb packet.CaptureCallback) {
|
||||||
|
|||||||
@@ -1236,3 +1236,36 @@ func TestFilterDropEmptyTSMPDiscoAdvertInbound(t *testing.T) {
|
|||||||
t.Errorf("got %v; want DropSilently", got)
|
t.Errorf("got %v; want DropSilently", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop TSMP packets from ourselves.
|
||||||
|
func TestFilterDropTSMP(t *testing.T) {
|
||||||
|
var memLog tstest.MemLogger
|
||||||
|
tw := &Wrapper{logf: memLog.Logf, limitedLogf: memLog.Logf}
|
||||||
|
ipHdr := packet.IP4Header{
|
||||||
|
IPProto: ipproto.TSMP,
|
||||||
|
Src: netaddr.IPv4(1, 2, 3, 4),
|
||||||
|
Dst: netaddr.IPv4(5, 6, 7, 8),
|
||||||
|
}
|
||||||
|
tsmpPayload := make([]byte, 33)
|
||||||
|
tsmpPayload[0] = byte(packet.TSMPTypeDiscoAdvertisement)
|
||||||
|
pkt := make([]byte, ipHdr.Len()+len(tsmpPayload))
|
||||||
|
ipHdr.Marshal(pkt)
|
||||||
|
copy(pkt[ipHdr.Len():], tsmpPayload)
|
||||||
|
|
||||||
|
wantMetric := metricPacketOutDropTSMP.Value() + 1
|
||||||
|
|
||||||
|
pp := new(packet.Parsed)
|
||||||
|
pp.Decode(pkt)
|
||||||
|
got, _ := tw.filterPacketOutboundToWireGuard(pp, nil, nil)
|
||||||
|
if got != filter.DropSilently {
|
||||||
|
t.Errorf("got %v; want DropSilently", got)
|
||||||
|
}
|
||||||
|
if got, want := memLog.String(), "[unexpected] received TSMP out packet over tstun; dropping\n"; got != want {
|
||||||
|
t.Errorf("log output mismatch\n got: %q\nwant: %q\n", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if metricPacketOutDropTSMP.Value() != wantMetric {
|
||||||
|
t.Errorf("expected metric\n got: %d\nwant: %d\n",
|
||||||
|
metricPacketOutDropTSMP.Value(), wantMetric)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user