Multiple hostnames/domains with locally managed tunnels?

I'd like to locally manage tunnels programmatically via the CLI. I want it to be able to route requests from multiple domains and subdomains to different sites that are behind a Traefik router. When I cloudflared tunnel login, it asks me to select a zone/domain. Let's say that I select nick.com I can then create a tunnel with cloudflared tunnel create nick If i then run cloudflared tunnel list, it shows various tunnels that I've created previously - both via the dashboard and CLI. If I create a route cloudflared tunnel route dns nick 1.nick.com, i get the response Added CNAME 1.nick.com which will route to this tunnel tunnelID.... If I create a route cloudflared tunnel route dns nick 2, i get the response Added CNAME 2.nick.com which will route to this tunnel tunnelID.... So, the tunnel seems to very much be tied to a specific domain (nick.com). If I then run cloudflared tunnel route dns othertunnel 1.othertunnel.com, i get the response Added CNAME 1.othertunnel.nick.com which will route to this tunnel tunnelID.... So, it seems like when I am logged in via cloudflared CLI, even though you can see your account's different tunnels, you can only actually use one of them at a time. Moreover, even if you try to create a route on a different tunnel, it'll get created on the one you are currently logged-in to. Is this accurate? As far as I'm aware, if we use remote-managed tunnels, we can create routes with any of our domains. So, how are we supposed to do something similar with locally managed tunnels? I'm trying to make it all programmatic, so that I can integrate it into the fantastic open-source DDEV (https://ddev.com/) development environment, which is a wrapper around docker for developing with pretty much any PHP CMS or Framework I really don't want people to have to keep going to their dashboard to manually change things - it should just be a CLI command that magically does all the tunnel routing. Any suggestions? Thanks!
DDEV
DDEV
Local development environments in seconds. Customize, share, and extend with ease.
26 Replies
nickchomey
nickchomeyOP7mo ago
I just tried to install a new remote-managed tunnel, and got this message cloudflared service is already installed at /etc/systemd/system/cloudflared.service; if you are running a cloudflared tunnel, you can point it to multiple origins, avoiding the need to run more than one cloudflared service in the same machine that was expected. What wasn't expected (given what I wrote above) is that it says I can point the tunnel to multiple origins. Is it saying this because it is a remote managed tunnel? Or is it actually somehow possible to point a locally managed tunnel to multiple origins?
nickchomey
nickchomeyOP7mo ago
What is most confusing is that this doc on the Tunnel Configuration File - Origin Config shows different domains. But I can't seem to create a route for multiple domains via the CLI. https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/configuration-file/#origin-configuration
Cloudflare Docs
Configuration file · Cloudflare Zero Trust docs
Quick tunnels do not need a configuration file.
Erisa
Erisa7mo ago
The CLI command you're using to create multiple routes should be working fine so not 100% sure whats going on there, but honestly, they are just basic CNAME records. You can create them manually in the DNS tab using the tunnel ID: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/routing-to-tunnel/dns/ You can only use one tunnel at a time that is true (at least with a single cloudflared service), but a single tunnel can have multiple hostnames that go to different places on both local and remote managed
nickchomey
nickchomeyOP7mo ago
Thanks for clarifying that we can only use one tunnel at at time. That's fine, so long as we can have multiple different domain/hostnames. But I cant get that to work. In the example above, i'm using the Tunnel name (nick) rather than the UUID. The docs say that that should be fine cloudflared tunnel route dns <UUID or NAME> <hostname> so, why when I use a different domain/hostname, does it add it as a subdomain of the originally-linked domain when I did cloudflared tunnel login
Erisa
Erisa7mo ago
Oh I see
nickchomey
nickchomeyOP7mo ago
I just wiped out all tunnels and cnames, reinstalled cloudflared and am getting the same thing
Erisa
Erisa7mo ago
Yeah, that's a limitation of the route dns command, it links itself to a single zone for whatever reason. You need to create the DNS records manually instead (see the docs link above, its just a CNAME) I think this is an archeic holdover from when Tunnels used to be a domain-level product, that hasnt been the case for years now
nickchomey
nickchomeyOP7mo ago
bizarre. But thanks for the clarification. Can we create DNS records via the cli or api? I dont care what mechansim i use, so long as it is programmatic
Erisa
Erisa7mo ago
You can use the API: https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-create-dns-record The record will always be a CNAME with proxy enabled pointing to <tunnelid>.cfargotunnel.com
nickchomey
nickchomeyOP7mo ago
Thanks so much. I will figure out how to add CNAMEs via the API, with the tunnel_UUID.cfargotunnel.com. I see now in the dashboard that that's all that's actually happening
Erisa
Erisa7mo ago
Yeah the cli command is just a handy shortcut for that, unfortunate that it doesnt work too great
nickchomey
nickchomeyOP7mo ago
just one last clarification, if you dont mind. It shoudn't matter that the tunnel is originally linked with one domain? (or Zone, in Cf parlance)
Erisa
Erisa7mo ago
The tunnel itself runs at the account level, the zone-level part is legacy and only affects DNS record creation So it's fine If you were using a legacy tunnel it would be a problem but those were deprecated ages back so you won't be
nickchomey
nickchomeyOP7mo ago
ok great. I guess one last thing - could we create a tunnel in the dashboard and then just use its UUID when creating CNAME records? Because, if so, I'll probably instruct users to do that - create a tunnel in dashboard, then add the UUID and api key to an .env file
Erisa
Erisa7mo ago
If your tunnel is remote-managed when you create a hostname in the dash it will create the DNS record for you (that one works cross-zone unlike the cli, ha) I'm reasonably sure if you create a tunnel in the dashboard it has to be remote-managed and if you want a locally-managed tunnel you have to create it through the CLI, which would then give you a UUID that you can use for DNS records
nickchomey
nickchomeyOP7mo ago
Ok, i'll fiddle around with it and follow-up here with what i find
Erisa
Erisa7mo ago
Sure
nickchomey
nickchomeyOP7mo ago
Thanks so much. You're always very helpful I think you're correct about creating a remote-managed tunnel in the dashboard, and then manually adding CNAME records - it wont work. Sure, we get a UUID with the remote managed tunnel, but we still have to actually set the route that cloudflared uses on the server (eg. https://localhost:443). Normally you do that in the dashboard when you create a public hostname for the tunnel, but you cant when you just add a CNAME. So, I think I have no option (for the constraints/goals I have here) but to create a locally managed tunnel and then use the API to set the CNAMEs. I then assume that I can set the config.yaml to have different hostnames, such as in the docs (https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/configuration-file/#origin-configuration) e.g.
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
originRequest: # Top-level configuration
connectTimeout: 30s

ingress:
# The localhost:8000 service inherits all root-level configuration.
# In other words, it will use a connectTimeout of 30 seconds.
- hostname: example.com
service: localhost:8000
- hostname: example2.com
service: localhost:8001
# The localhost:8002 service overrides some root-level config.
- service: localhost:8002
originRequest:
connectTimeout: 10s
disableChunkedEncoding: true
# Some built-in services such as `http_status` do not use any configuration.
# The service below will simply respond with HTTP 404.
- service: http_status:404
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
originRequest: # Top-level configuration
connectTimeout: 30s

ingress:
# The localhost:8000 service inherits all root-level configuration.
# In other words, it will use a connectTimeout of 30 seconds.
- hostname: example.com
service: localhost:8000
- hostname: example2.com
service: localhost:8001
# The localhost:8002 service overrides some root-level config.
- service: localhost:8002
originRequest:
connectTimeout: 10s
disableChunkedEncoding: true
# Some built-in services such as `http_status` do not use any configuration.
# The service below will simply respond with HTTP 404.
- service: http_status:404
The crux is just creating the CNAMEs for each zone - subdomain / tunnel_UUID.cfargotunnel.com I suppose the only unknown for me right now is how "dynamic" this is... Im assuming that once I've created a CNAME via the API, if I simply edit the config.yaml to add another route, cloudflared probably wont recognize the change? I'd probably need to either restart the systemd service, or re-run cloudflared tunnel run {tunnel name} And, I suppose, a separate thought - should a Github Issue be created to at least track these legacy issues? Whether it ever gets fixed is another matter, but at least it would be somewhere
Erisa
Erisa7mo ago
You need to restart them, there was a few suggestions made to add hot reloads but they were always shot down with the recommendation to run cloudflared replicas and do a rolling restart https://github.com/cloudflare/cloudflared/issues/301#issuecomment-869925719 (if you manage to run the same tunnel with two different instances of cloudflared, which in itself requires some prodding with services, they will act as redundant replicas of each other) Remote managed tunnels will hot reload config changes but well :geblobshrug: that has its own issues An issue is a good idea if there isnt already one
nickchomey
nickchomeyOP7mo ago
Thanks. In this use-case, I think it shouldn't be an issue to restart the systemd service I'm not exactly sure what to put in a GH issue about this, but I'll try to summarize what has been discussed here and also share a link to this convo
nickchomey
nickchomeyOP7mo ago
Ugh, ive manually created some CNAMES, but am getting this error.
No description
nickchomey
nickchomeyOP7mo ago
yet, the tunnel shows as being connected
No description
Erisa
Erisa7mo ago
the dns is set to af579ef1-2a72-4c56-8752-45f44f190be0.cfargotunnel.com ? (i used ocr so that might not be right, check the id) and the zone is on the same account as the tunnel?
nickchomey
nickchomeyOP7mo ago
Actually, it might be an issue with my application i'm debugging now
Erisa
Erisa7mo ago
Alright
nickchomey
nickchomeyOP7mo ago
Ok, it was both application error, and I forgot to update the CNAMEs for a new tunnel that I created. I think its working now Thanks very much for your help. When I get this working with DDEV, I know that a lot of people will find it to be enormously useful. And I assume it'll end up bringing customers to CF FYI, I just realized cloudflared is written in Go, which I'm starting to learn and work in anyway. So, I think I'm going to take a crack at fixing the cloudflared tunnel route dns mechanism, such that it doesnt create the CNAME as a subdomain of whatever zone was originally linked with the tunnel. Or, at the very least, I'll try to identify where it is happening so I can provide a starting point in the GH Issue that I'll create
Want results from more Discord servers?
Add your server