Conversation
…e verification Closes #16. Three bugs fixed during validation against a real DO droplet (coturn 4.6, Ubuntu 24.04): 1. IPv4 detection — curl was following the system's preferred address family and returning the v6 address on dual-stack droplets. Fixed with curl -4. 2. log-file path — coturn 4.5/4.6 with no log-file directive detects non-TTY stdout (the tee pipe) and writes only to PID-named files (/var/log/turn_<pid>_<date>.log), so the bare-path file the script greps stays at 0 bytes. log-file=stdout in the conf forces stdout emission; tee captures it as a flat file. 3. CHANGE_REQUEST grep wording — script was matching coturn 4.10's text ("STUN CHANGE_REQUEST not supported: only one IP") which doesn't match coturn 4.6's ("cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided"). Match the stable substring "only one IP" instead. Combined with bug 2's fix, verification is now real on both coturn versions. Verified: on a single-public-IP droplet the script now correctly exits 1 with a printed FAIL line + log tail. On a multi-IP setup (Reserved IP aliased to eth0 — see #15) the script exits 0 and natcheck reports the expected filtering classification.
Closes #15. v0.1.2.1 shipped `external-ip=PUBLIC/PRIVATE` as the universal fix. That form only works on AWS/GCP-style topology where the public IP is NAT'd to a separate private NIC IP — the two values differ naturally. On single-public-IP providers (DO basic droplet, Linode Nanode, Hetzner single-IP), eth0's IP IS the public IP; `external-ip=A/A` doesn't satisfy coturn's "two distinct IPs" requirement and coturn refuses to participate in §4.4. Conf now uses two `listening-ip` + two `external-ip` pairs explicitly. Docs add a per-provider topology table with the worked DO Reserved IP example (alias second IP to eth0 with `ip addr add`, reference both as listening-ip + as external-ip pairs). Verification step + automated path (validate-coturn.sh) cross-referenced. Verified: with two distinct routable IPs configured per the new conf shape, coturn 4.6 emits no "only one IP" warning and natcheck reports the canonical filtering verdict end-to-end.
…logies
Single-public-IP providers (DO basic, Linode Nanode, Hetzner single-IP)
need a second routable IP attached and aliased to eth0 before coturn can
honor §4.4. Script now accepts SECOND_IP env var: aliases the IP to the
default-route NIC if not already present, writes the conf in multi-IP
form (two listening-ip + two external-ip pairs).
Behaviour matrix:
- SECOND_IP set → multi-IP form, aliases the IP, writes both pairs
- public != private → AWS/GCP-style, uses both directly
- public == private → writes degenerate single-IP conf that will fail
verification, so user gets the FAIL line and a
pointer to docs/coturn-setup.md instead of
silently producing filtering: untested samples
Top-of-file usage block now shows both the no-env (AWS/GCP) and
SECOND_IP=... (single-public-IP) invocation forms.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bundles #15 and #16. v0.1.2.2 patch tag; no code or JSON schema delta.
What this changes
examples/coturn-natcheck.confexternal-ip=PUBLIC/PRIVATE(only works on AWS/GCP-style topology where the two IPs differ) with explicit two-listening-ip+ two-external-ip-pair form. Honest about the topology requirement.docs/coturn-setup.mdip addr add; verification step references the two specific coturn warning lines; cross-references the script.scripts/validate-coturn.shcurl -4), log-file path (log-file=stdoutso tee captures real content), CHANGE_REQUEST grep wording portable across coturn 4.5/4.6/4.10. NewSECOND_IPenv var: aliases the IP to the NIC, writes the multi-IP conf form. Honest failure on misconfigured single-IP droplets.CHANGELOG.md[0.1.2.2]entry.Why two issues bundled
#16's script fix is correct standalone (false-positive verification was a real bug), but merging it alone leaves users following
docs/coturn-setup.mdon a basic single-IP droplet in a worse state than today: the script correctly fails closed, but they have no path forward. #15 provides the path. Shipping both as v0.1.2.2 ships one user-visible message ("coturn validation now works end-to-end across more provider topologies") with a single tag.Verification (Jordan)
Both behavioural branches confirmed against a real DO basic droplet (coturn 4.6, Ubuntu 24.04, primary public IP
168.144.121.96, Reserved IP168.144.1.58):Script aliases the Reserved IP, writes multi-IP conf, coturn starts clean (no warning), exits 0. natcheck reports the canonical filtering verdict end-to-end:
{ "nat_type": "ADM", "filtering": {"behavior": "address-and-port-dependent", "tested_against": "168.144.121.96:3478"}, "webrtc_forecast": {"direct_p2p": "unlikely", "turn_required": true} }Verdict reproduces across runs (mapped ports + RTTs vary as expected; classification + warnings + exit code stable).
Out of scope
--serveris IPv4 literal, natcheck's classifier compares mapped endpoints across families and produces wrong ADM verdicts. Larger surface (Go code change + new schema warning + tests). v0.1.3.docs/samples/filtering.txt): blocks behind classifier: cross-address-family mapped endpoints produce wrong ADM verdict #14 so the documented invocation is the natural form (--server stun.l.google.com:19302 --server stun.cloudflare.com:3478 --server <coturn>:3478), not the IPv4-literal workaround we used today.Linus disposition
4 files, 136 insertions / 65 deletions. Each commit is one concern (conf+docs / script / changelog). No drive-by refactors. No new dependencies. No code touched.
Test plan
make test(race, count=1) — green (no code change but sanity)make lint— 0 issuesgofmt -l .— cleangh release create v0.1.2.2brew upgrade natchecklands the correctedexamples/anddocs/and the newscripts/)