From d8223f711574577ea37dd53bf721953a82ca12bd Mon Sep 17 00:00:00 2001 From: FineComputer14451 Date: Mon, 7 Sep 2026 00:08:40 +0000 Subject: [PATCH] fix(termux-connect): allow Cloudflare tunnel Host headers FastMCP DNS-rebinding protection only allows 127.0.0.1/localhost, so requests via *.trycloudflare.com returned 421 Invalid Host and the Grok Bot connector failed_to_load. Disable that check by default (loopback bind + Bearer still gate access); optional TERMUX_CONNECT_ALLOWED_HOSTS re-enables an explicit allowlist. --- .../skills/termux-connect/scripts/server.py | 28 +++++++++++++++++++ skills/termux-connect/scripts/server.py | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/plugins/grokhunter-termux-connect/skills/termux-connect/scripts/server.py b/plugins/grokhunter-termux-connect/skills/termux-connect/scripts/server.py index 97c79dc..25c6ca5 100755 --- a/plugins/grokhunter-termux-connect/skills/termux-connect/scripts/server.py +++ b/plugins/grokhunter-termux-connect/skills/termux-connect/scripts/server.py @@ -140,6 +140,33 @@ def main() -> None: ) sys.exit(1) + # FastMCP defaults DNS-rebinding Host allowlist to 127.0.0.1/localhost only. + # Cloudflare quick tunnels send Host: *.trycloudflare.com → 421 Invalid Host. + # Bind stays loopback; Bearer auth remains the access gate. + from mcp.server.transport_security import TransportSecuritySettings + + transport_security = TransportSecuritySettings( + enable_dns_rebinding_protection=False, + ) + extra_hosts = [ + h.strip() + for h in os.environ.get("TERMUX_CONNECT_ALLOWED_HOSTS", "").split(",") + if h.strip() + ] + if extra_hosts: + transport_security = TransportSecuritySettings( + enable_dns_rebinding_protection=True, + allowed_hosts=[ + f"{HOST}:{PORT}", + HOST, + "localhost", + f"localhost:{PORT}", + "127.0.0.1:*", + "localhost:*", + *extra_hosts, + ], + ) + mcp = FastMCP( "grokhunter-termux-connect", instructions=( @@ -150,6 +177,7 @@ def main() -> None: port=PORT, streamable_http_path="/mcp", stateless_http=True, + transport_security=transport_security, ) @mcp.tool() diff --git a/skills/termux-connect/scripts/server.py b/skills/termux-connect/scripts/server.py index 97c79dc..25c6ca5 100755 --- a/skills/termux-connect/scripts/server.py +++ b/skills/termux-connect/scripts/server.py @@ -140,6 +140,33 @@ def main() -> None: ) sys.exit(1) + # FastMCP defaults DNS-rebinding Host allowlist to 127.0.0.1/localhost only. + # Cloudflare quick tunnels send Host: *.trycloudflare.com → 421 Invalid Host. + # Bind stays loopback; Bearer auth remains the access gate. + from mcp.server.transport_security import TransportSecuritySettings + + transport_security = TransportSecuritySettings( + enable_dns_rebinding_protection=False, + ) + extra_hosts = [ + h.strip() + for h in os.environ.get("TERMUX_CONNECT_ALLOWED_HOSTS", "").split(",") + if h.strip() + ] + if extra_hosts: + transport_security = TransportSecuritySettings( + enable_dns_rebinding_protection=True, + allowed_hosts=[ + f"{HOST}:{PORT}", + HOST, + "localhost", + f"localhost:{PORT}", + "127.0.0.1:*", + "localhost:*", + *extra_hosts, + ], + ) + mcp = FastMCP( "grokhunter-termux-connect", instructions=( @@ -150,6 +177,7 @@ def main() -> None: port=PORT, streamable_http_path="/mcp", stateless_http=True, + transport_security=transport_security, ) @mcp.tool()