gateway-domain: tag:orchestrator is now allowed by the ACL too
A rule was added so the testing gateway may also reach nodes tagged tag:orchestrator, not only tag:notplants-test-server. Both tags now appear in the skill's table, and the tool's warning fires only when a node carries neither. Verified end to end from an orchestrator box (tag:orchestrator, tag:server) rather than assumed: - the gateway can open a TCP connection to it over the tailnet - a request to https://acltest.gtest.commoninternet.net/ returns the box's own self-signed certificate, subject and issuer both CN=acltest..., which is only possible if the gateway proxied the stream instead of terminating it - the payload came back and the box's listener logged the request The troubleshooting section gains the one-liner that isolates this from the gateway itself: open a TCP connection to your backend from the gateway.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: gateway-domain
|
||||
description: Give a tailnet box a real public HTTPS domain (<name>.gtest.commoninternet.net) by mapping it on the shared testing gateway. Use when an agent needs a publicly reachable URL for a box with no public IP — an OAuth callback, a webhook receiver, a demo link, an ACME challenge. Covers the add/remove tool, where the admin password lives, and the two things that silently break it: your box must carry the tag:notplants-test-server tailnet tag or the ACL blocks the gateway from reaching it, and your box serves the TLS cert rather than the gateway.
|
||||
description: Give a tailnet box a real public HTTPS domain (<name>.gtest.commoninternet.net) by mapping it on the shared testing gateway. Use when an agent needs a publicly reachable URL for a box with no public IP — an OAuth callback, a webhook receiver, a demo link, an ACME challenge. Covers the add/remove tool, where the admin password lives, and the two things that silently break it: your box must carry a tailnet tag the ACL allows (tag:notplants-test-server or tag:orchestrator) or the gateway cannot reach it, and your box serves the TLS cert rather than the gateway.
|
||||
---
|
||||
|
||||
# Giving your box a public domain
|
||||
@@ -18,20 +18,26 @@ python3 engine/tools/gateway-domain.py add myapp
|
||||
That is the whole happy path. The backend defaults to **this box's own tailscale IP**, so run
|
||||
it on the machine that will serve the domain.
|
||||
|
||||
## Your box must carry the `notplants-test-server` tag
|
||||
## Your box needs a tailnet tag the ACL allows
|
||||
|
||||
The tailnet ACL only permits the gateway to open connections to nodes tagged
|
||||
**`tag:notplants-test-server`**. Without it the gateway accepts your mapping and then simply
|
||||
never connects — which looks like a broken gateway and is not one. Check before you start:
|
||||
The gateway can only open connections to nodes the tailnet ACL lets it reach. Two tags qualify:
|
||||
|
||||
| tag | who |
|
||||
|---|---|
|
||||
| `tag:notplants-test-server` | test servers — the usual case |
|
||||
| `tag:orchestrator` | orchestrator boxes (added 2026-08-20, verified end to end) |
|
||||
|
||||
Without one of them the gateway accepts your mapping and then simply never connects — which
|
||||
looks like a broken gateway and is not one. Check before you start:
|
||||
|
||||
```bash
|
||||
tailscale status --json | jq -r '.Self.Tags[]?'
|
||||
```
|
||||
|
||||
If `tag:notplants-test-server` is not listed, add it to that node in the Tailscale admin (a
|
||||
node's tags are set when it is authenticated, so this may mean re-authenticating it), or map a
|
||||
backend that already has the tag. `gateway-domain.py` warns when the node it is about to map
|
||||
lacks the tag, but it cannot see the tags of a backend you name explicitly — that one is on you.
|
||||
If neither tag is listed, add one to that node in the Tailscale admin (a node's tags are set
|
||||
when it is authenticated, so this may mean re-authenticating it), or map a backend that already
|
||||
has one. `gateway-domain.py` warns when the node it is about to map carries neither, but it
|
||||
cannot see the tags of a backend you name explicitly — that one is on you.
|
||||
|
||||
The gateway itself is tagged `tag:testing-gateway`; that is the other half of the same ACL rule.
|
||||
|
||||
@@ -134,10 +140,12 @@ Check in this order — most failures are the last two.
|
||||
|
||||
1. `gateway-domain.py list` — is the mapping actually there?
|
||||
2. `getent hosts myapp.gtest.commoninternet.net` — should be `49.13.156.72`.
|
||||
3. **Is your node tagged `tag:notplants-test-server`?** (`tailscale status --json | jq -r
|
||||
'.Self.Tags[]?'`) This is the single most common cause. The gateway is `gateway-test-1`
|
||||
(`100.91.44.90`), tagged `tag:testing-gateway`; the ACL pairs those two tags, so an
|
||||
untagged backend is unreachable no matter how correct the mapping looks.
|
||||
3. **Does your node carry `tag:notplants-test-server` or `tag:orchestrator`?**
|
||||
(`tailscale status --json | jq -r '.Self.Tags[]?'`) This is the single most common cause.
|
||||
The gateway is `gateway-test-1` (`100.91.44.90`), tagged `tag:testing-gateway`; the ACL
|
||||
pairs that with the tags above, so a backend with neither is unreachable no matter how
|
||||
correct the mapping looks. Quick check from the gateway itself:
|
||||
`ssh root@49.13.156.72 'timeout 5 bash -c "echo > /dev/tcp/<your-tailnet-ip>/<port>"'`
|
||||
4. **Is your service actually serving TLS for that name on the backend port?** A backend that
|
||||
speaks plain HTTP on 443, or serves a cert for a different name, fails here and nowhere else.
|
||||
|
||||
|
||||
@@ -97,10 +97,10 @@ _ERR = re.compile(r'<p style="color:red">(.*?)</p>', re.S)
|
||||
# /var/lib/tunnel-gateway/tunnel_map.conf can clear. Refuse to create one.
|
||||
_BACKEND = re.compile(r"^(\d{1,3}(?:\.\d{1,3}){3})(?::(\d{1,5}))?$")
|
||||
|
||||
# The tailnet ACL only lets the gateway open connections to nodes carrying this tag.
|
||||
# The tailnet ACL only lets the gateway open connections to nodes carrying one of these.
|
||||
# A mapping to an untagged node is accepted by the gateway and then simply never
|
||||
# connects, which looks like a gateway fault and is not one.
|
||||
REQUIRED_TAG = "tag:notplants-test-server"
|
||||
ALLOWED_TAGS = ("tag:notplants-test-server", "tag:orchestrator")
|
||||
|
||||
|
||||
def _validate_backend(backend):
|
||||
@@ -144,9 +144,10 @@ def _warn_untagged(exe):
|
||||
tags = _self_tags(exe)
|
||||
if tags is None:
|
||||
return
|
||||
if REQUIRED_TAG not in tags:
|
||||
if not any(t in tags for t in ALLOWED_TAGS):
|
||||
print(
|
||||
f"warning: this node is not tagged {REQUIRED_TAG} (tags: {', '.join(tags) or 'none'}).\n"
|
||||
f"warning: this node carries none of {' / '.join(ALLOWED_TAGS)} "
|
||||
f"(tags: {', '.join(tags) or 'none'}).\n"
|
||||
" The gateway will accept the mapping but the tailnet ACL will not let it\n"
|
||||
" reach this box, so no traffic will flow. Add the tag in the Tailscale\n"
|
||||
" admin, or map a backend that already has it.",
|
||||
|
||||
Reference in New Issue
Block a user