Implements STUN support feature requested in issue #71 by @willglynn#72
Implements STUN support feature requested in issue #71 by @willglynn#72
Conversation
|
All tests and checks have passed, merging to main |
| if attr_type == 0x0020 and attr_len >= 8: | ||
| family = attr[1] | ||
| if family == 0x01: # IPv4 only | ||
| x_port = struct.unpack('!H', attr[2:4])[0] ^ (self.stun_conf.MAGIC_COOKIE >> 16) | ||
| x_ip = struct.unpack('!I', attr[4:8])[0] ^ self.stun_conf.MAGIC_COOKIE | ||
| ip_address = socket.inet_ntoa(struct.pack('!I', x_ip)) | ||
| return ip_address, x_port | ||
| offset += 4 + attr_len |
There was a problem hiding this comment.
I feel sad looking at XOR-MAPPED-ADDRESS, but then I feel sadder thinking about everyone who had to deal with troubleshooting MAPPED-ADDRESS in the first place:
Note: XOR-MAPPED-ADDRESS and MAPPED-ADDRESS differ only in their
encoding of the transport address. The former encodes the transport
address by XOR'ing it with the magic cookie. The latter encodes it
directly in binary. RFC 3489 originally specified only MAPPED-
ADDRESS. However, deployment experience found that some NATs rewrite
the 32-bit binary payloads containing the NAT's public IP address,
such as STUN's MAPPED-ADDRESS attribute, in the well-meaning but
misguided attempt to provide a generic Application Layer Gateway
(ALG) function. Such behavior interferes with the operation of STUN
and also causes failure of STUN's message-integrity checking.
…which in turn reminds me of some Adam Langley blog posts:
- Unfortunate current practices for HTTP over TLS (04 Feb 2011)
Despite it being nearly twelve years since the publication of TLS 1.0
[RFC2246], around 3% of HTTPS servers will reject a valid TLS
"ClientHello". These rejections can take the form of immediately
closing the connection or a fatal alert. Intolerance to the
following has been observed:
Advertising version TLS 1.0.
Advertising a TLS version greater than TLS 1.0 (around 2% for 1.1
or 1.2, around 3% for greater than 1.2).
Advertising a version greater than 0x03ff (around 65% of servers)
The presence of any extensions (around 7% of servers)
The presence of specific extensions ("server_name" and
"status_request" intolerance has been observed, although in very
low numbers).
The presence of any advertised compression algorithms
- TLS 1.3 and Proxies (10 Mar 2018)
Sadly, it's precisely this sort of proxy misbehaviour that has delayed TLS 1.3 for over a year while my colleagues (David Benjamin and Steven Valdez) repeatedly deployed experiments and measured success rates of different serialisations. In the end we found that making TLS 1.3 look like a TLS 1.2 resumption solved a huge number of problems, suggesting that many proxies blindly pass through such connections. (Which should, again, make one wonder about what security properties they're providing.)
But, given all that, you might ponder why we bothered encrypting certificates? Partly it's one component of an effort to make browsing more private but, more concretely, it's because anything not encrypted suffers these problems. TLS 1.3 was difficult to deploy because TLS's handshake is, perforce, exposed to the network. The idea that we should make TLS a little more efficient by compressing certificates has been bouncing around for many years. But it's only with TLS 1.3 that we might make it happen because everyone expected to hit another swamp of proxy issues if we tried it without encrypting certificates first.
Anyway, good work! 👍
There was a problem hiding this comment.
Thank you for sharing such insightful info!
It really hits home given all the similar challenges we run into with protocol quirks and real-world networking!
One of the reasons for sticking with IPv4, too, was the unfortunate state of IPv6 adoption as well.
Milestone: STUN Support Added
The integration of STUN protocol in ESDDNS was made possible by a community feature request, marking a major milestone: it is the first time STUN-based public IP detection is available in this project.
STUN support was requested in issue #71 by willglynn, opened yesterday. This enhancement fulfills the need for a robust, modern method for NAT traversal and public IPv4 discovery—an essential capability for reliable dynamic DNS updates.
Session Traversal Utilities for NAT (STUN) is a standardized protocol for discovering the public IP address and port assigned to a device through NAT. Historically used in VoIP (e.g., SIP), STUN is now common in WebRTC, so many large tech providers operate public STUN infrastructure.
Recommended public STUN servers:
stun.l.google.com:19302(Google)stun.cloudflare.com:3478(Cloudflare)global.stun.twilio.com:3478(Twilio)This milestone reflects ESDDNS's commitment to open development, modern standards, and responsiveness to user feedback. Special thanks to willglynn and all contributors for driving this important feature forward.
STUN Protocol Integration
ESDDNS now supports STUN (Session Traversal Utilities for NAT) protocol as a first-priority WAN IP discovery method, with automatic fallback to HTTP services.
Features
Configuration
STUN + HTTP (Recommended)
Add
[STUNConfig]section todns.ini:Configuration Modes
Files Added
api/async_stun_discovery.py- Core STUN protocol implementationapi/get_ip_stun.py- STUN provider wrapperExpected Output
Note: Failed STUN servers (like
stun.verbo.bewithXOR-MAPPED-ADDRESS not found) returnNoneand are skipped - they don't affect validation.IP Validation
All IPs (from STUN and HTTP) are validated together in
wan_ip_state():Scenario 1: All Match (1 STUN + 2 HTTP)
Scenario 2: Single Source (STUN only)
Scenario 3: Mismatch (Different IPs)
Failed queries returning
Noneare filtered out and don't affect validation.Performance
Troubleshooting
No STUN output?
INFO STUN protocol enabled for IP discovery[STUNConfig]section exists indns.iniSTUN fails?
WARNING [stun] RETRY: Attempt #2...