openziti / ziti

The parent project for OpenZiti. Here you will find the executables for a fully zero trust, application embedded, programmable network @OpenZiti
https://openziti.io
Apache License 2.0
2.69k stars 153 forks source link

error: tunnel failed - proxy port is not in allowed port ranges #1015

Closed qrkourier closed 1 year ago

qrkourier commented 1 year ago

I noticed something unexpected when I was testing the Go ziti tunnel proxy. The problem was that the specified proxy port didn't match the allowed ports in the client config, but that constraint doesn't really make sense for an opaque proxy port. It still makes sense for a transparent proxy. For example, the allowed port was 80/tcp, and I tried to bind port 8080 and the client proxy always emitted an error.

I expected to be able to bind an arbitrary TCP port to map to any named Ziti service the identity is authorized to dial. I found the dialing tunneler enforced a constraint that seems to have been intended for transparent proxies to ensure that only the expected traffic maps to the expected Ziti service.

The difference seems to be whether the mapping of port-to-service is expressed in the edge client config or as runtime configuration of the client itself. The explicit client-side config should have higher precedence.

Command to reproduce uses a ZEDS identity to dial the HTTPBin service on an illegal port

$ docker run --rm --name ziti-proxy --publish 8080:8080 --env ZITI_IDENTITY_JSON="$(</tmp/test4.json)" --env PFXLOG_NO_JSON=true --workdir /netfoundry openziti/ziti-tunnel proxy zedsDemoHttpHttpbin:8080  

WARN: the identities directory is only available inside this container because /netfoundry is not a mounted volume. Be careful to not publish this image with identity inside or lose access to the identity by removing the image prematurely.
DEBUG: waiting 1s for /netfoundry/ziti_id.json (or token) to appear
INFO: found identity file /netfoundry/ziti_id.json
DEBUG: evaluating positionals: proxy zedsDemoHttpHttpbin:8080
INFO: running "ziti tunnel proxy --identity /netfoundry/ziti_id.json zedsDemoHttpHttpbin:8080"
[   0.000] WARNING edge/tunnel/dns.flushDnsCaches: {error=[exec: "resolvectl": executable file not found in $PATH]} unable to find systemd-resolve or resolvectl in path, consider adding a dns flush to your restart process
[   0.512]    INFO edge/tunnel/intercept.SetDnsInterceptIpRange: dns intercept IP range: 100.64.0.1 - 100.127.255.254
[   0.512]    INFO ziti/ziti/tunnel.startIdentity: loading identity: /netfoundry/ziti_id.json
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[Http-Zeds-Demo-whatismyip]} adding service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[0-rmwO1qx] serviceName=[Http-Zeds-Demo-whatismyip]} starting tunnel for newly available service Http-Zeds-Demo-whatismyip
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[service1 webhookz1 Z29vZ2xlLW9hdXRoMnwxMTYwMTQzMjA2MDgwNTM4ODkyOTQ=]} adding service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[3XWj21jKfRbsKUcqImy43o] serviceName=[service1 webhookz1 Z29vZ2xlLW9hdXRoMnwxMTYwMTQzMjA2MDgwNTM4ODkyOTQ=]} starting tunnel for newly available service service1 webhookz1 Z29vZ2xlLW9hdXRoMnwxMTYwMTQzMjA2MDgwNTM4ODkyOTQ=
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[3XWj21jKfRbsKUcqImy43o] serviceName=[service1 webhookz1 Z29vZ2xlLW9hdXRoMnwxMTYwMTQzMjA2MDgwNTM4ODkyOTQ=]} Hosting newly available service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[http-myipaddress]} adding service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[9fHowE1qXR] serviceName=[http-myipaddress]} starting tunnel for newly available service http-myipaddress
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpHelloWorld]} adding service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[B.v.O7JfXR] serviceName=[zedsDemoHttpHelloWorld]} starting tunnel for newly available service zedsDemoHttpHelloWorld
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpHttpbin]} adding service
[   0.686]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[PvrVQBJfX] serviceName=[zedsDemoHttpHttpbin]} starting tunnel for newly available service zedsDemoHttpHttpbin
[   0.709]    INFO edge/tunnel.(*contextProvider).accept: {service=[service1 webhookz1 Z29vZ2xlLW9hdXRoMnwxMTYwMTQzMjA2MDgwNTM4ODkyOTQ=]} hosting service, waiting for connections
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[https-myip-routerhosted]} adding service
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[Re-5yZVqxR] serviceName=[https-myip-routerhosted]} starting tunnel for newly available service https-myip-routerhosted
[   0.734]    INFO edge/tunnel/intercept/proxy.(*interceptor).handleTCP: {service=[zedsDemoHttpHttpbin] addr=[0.0.0.0:8080]} service is listening
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpFireworks]} adding service
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[RkxoZ-VfX] serviceName=[zedsDemoHttpFireworks]} starting tunnel for newly available service zedsDemoHttpFireworks
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpsHttpbin]} adding service
[   0.734]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceName=[zedsDemoHttpsHttpbin] serviceId=[jwMlPbkqXR]} starting tunnel for newly available service zedsDemoHttpsHttpbin
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpWhatIsMyIp]} adding service
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[owB2Rn.fXR] serviceName=[zedsDemoHttpWhatIsMyIp]} starting tunnel for newly available service zedsDemoHttpWhatIsMyIp
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[https-whatismyip]} adding service
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[r9lqikJfX] serviceName=[https-whatismyip]} starting tunnel for newly available service https-whatismyip
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).HandleServicesChange: {service=[zedsDemoHttpsWhatIsMyIP]} adding service
[   0.735]    INFO edge/tunnel/intercept.(*ServiceListener).addService: {serviceId=[v0bIRQoqxR] serviceName=[zedsDemoHttpsWhatIsMyIP]} starting tunnel for newly available service zedsDemoHttpsWhatIsMyIP
[   8.966]   ERROR edge/tunnel.DialAndRun: {error=[unable to dial service 'zedsDemoHttpHttpbin': dial failed: exceeded maximum [2] retries creating circuit [c/jJEuHqi5oQ]: error creating route for [s/jJEuHqi5oQ] on [r/d6evgSoqXR] (error creating route for [c/jJEuHqi5oQ]: port 8080 is not in allowed port ranges)] service=[zedsDemoHttpHttpbin]} tunnel failed
dovholuknf commented 1 year ago

Closing. I don't think we should invest in this any more. We should favor the linked issue you refer to. If you think this really needs to be completed, we can reopen this issue

scareything commented 1 year ago

This is actually a configuration issue. The tunneler is working as expected/intended.

Looking at the host.v1 configuration for the zedsDemoHttpHttpbin service:

{
    "allowedPortRanges": [ { "high": 80, "low": 80} ].
    "allowedProtocols": [ "tcp" ],
    "forwardPort": true,
    "forwardProtocol": true,
    "address": "172.17.0.1"
}

forwardPort is enabled, and port 80 is the only port in the whitelist. The zedsDemoHttpHttpbin would be usable by more clients if it set the server port to a specific value instead of attempting to forward the port that was intercepted by the client tunneler. e.g. a host.v1 config like this:

{
    "protocol": "tcp",
    "address": "172.17.0.1",
    "port": 80
}