mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
fix(relay): XDP_PASS DNS replies (#10330)
DNS replies are UDP packets often arriving to our ephemeral range. As such, these get dropped because we attempt to look up a channel map for them and fail to find anything. To fix this, we assume all UDP packets arriving with a source port of 53 are DNS packets, and pass them up the stack. There are likely other types of UDP traffic this could be problematic for (QUIC comes to mind), but this fixes the immediate issue at hand for now, as detecting STUN probes is somewhat complex. Fixes #10329
This commit is contained in:
@@ -28,6 +28,7 @@ pub fn handle_turn(ctx: aya_ebpf::programs::XdpContext) -> u32 {
|
||||
Err(Error::NotIp | Error::NotUdp) => xdp_action::XDP_PASS,
|
||||
Err(
|
||||
e @ (Error::PacketTooShort
|
||||
| Error::DnsPacket
|
||||
| Error::NotTurn
|
||||
| Error::NotAChannelDataMessage
|
||||
| Error::UdpChecksumMissing
|
||||
|
||||
@@ -38,6 +38,8 @@ const UPPER_PORT: u16 = 65535;
|
||||
const CHAN_START: u16 = 0x4000;
|
||||
/// Channel number end
|
||||
const CHAN_END: u16 = 0x7FFF;
|
||||
/// DNS port
|
||||
const DNS_PORT: u16 = 53;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn try_handle_turn(ctx: &XdpContext) -> Result<(), Error> {
|
||||
@@ -72,6 +74,11 @@ fn try_handle_turn_ipv4(ctx: &XdpContext) -> Result<u16, Error> {
|
||||
let udp = unsafe { ref_mut_at::<UdpHdr>(ctx, EthHdr::LEN + Ipv4Hdr::LEN)? };
|
||||
let udp_payload_len = udp.len() - UdpHdr::LEN as u16;
|
||||
|
||||
// We do not want to handle DNS packets
|
||||
if udp.source() == DNS_PORT {
|
||||
return Err(Error::DnsPacket);
|
||||
}
|
||||
|
||||
if (LOWER_PORT..=UPPER_PORT).contains(&udp.dest()) {
|
||||
try_handle_from_ipv4_udp(ctx)?;
|
||||
|
||||
@@ -100,6 +107,11 @@ fn try_handle_turn_ipv6(ctx: &XdpContext) -> Result<u16, Error> {
|
||||
let udp = unsafe { ref_mut_at::<UdpHdr>(ctx, EthHdr::LEN + Ipv6Hdr::LEN)? };
|
||||
let udp_payload_len = udp.len() - UdpHdr::LEN as u16;
|
||||
|
||||
// We do not want to handle DNS packets
|
||||
if udp.source() == DNS_PORT {
|
||||
return Err(Error::DnsPacket);
|
||||
}
|
||||
|
||||
if (LOWER_PORT..=UPPER_PORT).contains(&udp.dest()) {
|
||||
try_handle_from_ipv6_udp(ctx)?;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pub enum Error {
|
||||
UdpChecksumMissing,
|
||||
PacketTooShort,
|
||||
NotUdp,
|
||||
DnsPacket,
|
||||
NotTurn,
|
||||
NotIp,
|
||||
Ipv4PacketWithOptions,
|
||||
@@ -34,6 +35,7 @@ impl aya_log_ebpf::WriteToBuf for Error {
|
||||
Error::UdpChecksumMissing => "UDP checksum is missing",
|
||||
Error::PacketTooShort => "Packet is too short",
|
||||
Error::NotUdp => "Not a UDP packet",
|
||||
Error::DnsPacket => "DNS packet",
|
||||
Error::NotTurn => "Not TURN traffic",
|
||||
Error::NotIp => "Not an IP packet",
|
||||
Error::Ipv4PacketWithOptions => "IPv4 packet has options",
|
||||
|
||||
Reference in New Issue
Block a user