Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with UDP Proxy #1107

Open
erroltuparker opened this issue Nov 13, 2024 · 7 comments
Open

Issue with UDP Proxy #1107

erroltuparker opened this issue Nov 13, 2024 · 7 comments

Comments

@erroltuparker
Copy link

I don't know when but there seems to have been some issue that happened when attempting to use the UDP Proxy option to reverse proxy the servers.

I note here that PROXY PROTOCOL should be working for UDP and works well for both TCP and HTTP.
#590

I'm quite confident that I had this setup and working when it first came out but I changed tools and then eventually came back because nothing else worked quite as well and had the features I wanted like Technitium. Since coming back, no matter what reverse proxy i use, traefik or caddy, or what protocol version, it is never able to respond to a request via the the UDP PROXY port configuration.

If im using proxy_protocol v2, i get that its missing the PROXY HEADER error

If I use v1, i get that it is unable to parse the address.

Currently, i'm able to proxy it to the native UDP port (53), but then I lose the ability to track where the requests are coming.

Any insights?

@ShreyasZare
Copy link
Member

Thanks for the post. Please share your reverse proxy config and screenshot of the DNS server Optional Protocols settings page so that I can understand your setup better.

@erroltuparker
Copy link
Author

Its very simple and nothing complex. i had crowdsec bouncer in before which is currently removed to reduce the any potential issues.

Caddy

{
	layer4 {
		tcp/:53 {
			@tdns dns
			route @tdns {
				proxy {
					upstream tcp/ext-dns:538
					proxy_protocol v2
				}
			}
		}
		udp/:53 {
			@udns dns
			route @udns {
				proxy {
					proxy_protocol v2
					upstream {
						dial udp/ext-dns:53
					}
				}
			}
		}
		udp/:853 {
			@quic quic sni dns.example.com
			route @quic {
				proxy {
					proxy_protocol v2
					upstream {
						dial udp/ext-dns:53
					}
				}
			}
		}
		tcp/:853 {
			@dot tls sni dns.example.com
			route @dot {
				tls
				proxy {
					upstream tcp/ext-dns:538
					proxy_protocol v2
				}
			}
		}
}

Traefik
routers.yml

tcp:
  routers:
    dns-tls:
      rule: "HostSNI(`dns.int.example.com`)"
      entryPoints:
        - dns-tls
      service: dns-tls
      tls: {}
    ext-dns:
      rule: "HostSNI(`*`)"
      entryPoints:
        - dns-tcp
      service: ext-dns
    ext-dns-tls:
      rule: "HostSNI(`dns.example.com`)"
      entryPoints:
        - dns-tls
      service: ext-dns-tls
      tls: {}

udp:
  routers:
    ext-dns:
      entryPoints:
        - dns
      service: ext-dns
    ext-dns-quic:
      entryPoints:
        - dns-quic
      service: ext-dns-quic

services.yml

tcp:
  services:
    dns-tls:
      loadBalancer:
        proxyProtocol:
          version: 2
        servers:
          - address: dns:538
    ext-dns:
      loadBalancer:
        proxyProtocol:
          version: 2
        servers:
          - address: ext-dns:538
    ext-dns-tls:
      loadBalancer:
        proxyProtocol:
          version: 2
        servers:
          - address: ext-dns:538

udp:
  services:
    ext-dns:
      loadBalancer:
        servers:
          - address: ext-dns:538
    ext-dns-quic:
      loadBalancer:
        servers:
          - address: ext-dns:538

@ShreyasZare
Copy link
Member

Please share the DNS server's Optional Protocols config screenshot too. Also, do you see any errors logged in the DNS logs? If yes then please share the error logs too.

@erroltuparker
Copy link
Author

This is when using proxy protocol v2

[2024-11-14 21:01:08 Local] [192.168.200.1:55995] [UDPPROXY] System.ArgumentNullException: Value cannot be null. (Parameter 'address')
   at System.ArgumentNullException.Throw(String paramName)
   at System.Net.IPEndPoint..ctor(IPAddress address, Int32 port)
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 410
[2024-11-14 21:01:08 Local] [192.168.200.1:55995] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:01:18 Local] [192.168.200.1:55995] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409

This is using v1

[2024-11-14 21:02:19 Local] [192.168.200.1:55188] [UDPPROXY] System.FormatException: An invalid IP address was specified.
 ---> System.Net.Sockets.SocketException (22): Invalid argument
   --- End of inner exception stack trace ---
   at System.Net.IPAddressParser.Parse(ReadOnlySpan`1 ipSpan, Boolean tryParse)
   at System.Net.IPAddress.Parse(String ipString)
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.ParseVersion1(String value) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 245
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 149
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:02:19 Local] [192.168.200.1:55188] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:02:19 Local] [192.168.200.1:39127] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:02:19 Local] [192.168.200.1:46580] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:02:20 Local] [192.168.200.1:49345] [UDPPROXY] System.FormatException: An invalid IP address was specified.
 ---> System.Net.Sockets.SocketException (22): Invalid argument
   --- End of inner exception stack trace ---
   at System.Net.IPAddressParser.Parse(ReadOnlySpan`1 ipSpan, Boolean tryParse)
   at System.Net.IPAddress.Parse(String ipString)
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.ParseVersion1(String value) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 245
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 149
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409
[2024-11-14 21:02:20 Local] [192.168.200.1:49345] [UDPPROXY] System.IO.InvalidDataException: The stream does not contain PROXY protocol header.
   at TechnitiumLibrary.Net.ProxyProtocol.ProxyProtocolStream.CreateAsServerAsync(Stream baseStream, CancellationToken cancellationToken) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\ProxyProtocol\ProxyProtocolStream.cs:line 138
   at DnsServerCore.Dns.DnsServer.ReadUdpRequestAsync(Socket udpListener, DnsTransportProtocol protocol) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 409

@ShreyasZare
Copy link
Member

Thanks for the details. I tested it in my setup with nginx as the reverse proxy and its working without any issues for both TCP and UDP proxy cases.

I would suggest that you run tcpdump -i any -w test.pcap command on the server that is running DNS and test it again. Share the test.pcap file over here or email it to support@technitium.com. This will allow debugging the issue better as it will be clear what data is being actually received by the DNS server.

@skedastically
Copy link

skedastically commented Nov 16, 2024

Hello,

In line 18 of your Caddyfile you're pointing to port 53 instead of 538. Is this intended? It seems to be pointing at the normal port, not UDP-PROXY.

						dial udp/ext-dns:53

With that said, I tried your Caddy-L4 setup with the :538/udp port and was able to reproduce the same errors on both v1 and v2.

With my nginx config working fine, I believe this is an issue with Caddy-L4 rather than Technitium. In fact, Nginx is the only reverse proxy I found to properly supporting PP on UDP so far.

@erroltuparker
Copy link
Author

Hi @ShreyasZare and @skedastically

Thanks for testing and confirming my issue with caddy, i've raised a issue on their side mholt/caddy-l4#269

I did also confirm that the work around did work as well, I just wish I could do a double proxy caddy -> nginx -> dns but as you have mentioned, the UDP proxying doesn't quite work properly and it seems that nginx only receives listen 53 proxy_protocol on tcp (could be wrong).

@skedastically yeah that was a work around I was using in the meanwhile to get it to respond, though because its not hitting the proxy port, it doesn't log it correctly and forgot to provide what the config should have been.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants