cloudflared
cloudflared copied to clipboard
🐛 Failed to request quick Tunnel may caused by program internal nameserver(detection?)
Describe the bug
(maybe i should ask this in termux...)
I use cloudflared on Termux, Android 12
when i run ./cloudflare tunnel --url ..., it logs
❯ ./cloudflared tunnel --url ssh://localhost:8022 --proxy-dns-address 0.0.0.0
2022-10-27T12:26:36Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
2022-10-27T12:26:36Z INF Requesting new quick Tunnel on trycloudflare.com...
failed to request quick Tunnel: Post "https://api.trycloudflare.com/tunnel": dial tcp: lookup api.trycloudflare.com on [::1]:53: read udp [::1]:58253->[::1]:53: read: connection refused
It seems like the cloudflared thinks nameserver is ::1, but $PREFIX/etc/resolv.conf contains:
nameserver 9.9.9.9
nameserver 114.114.114.114
nameserver 8.8.8.8
nameserver 8.8.4.4
And nslookup can get correct ip address of api.trycloudflare.com.
❯ nslookup api.trycloudflare.com
Server: 9.9.9.9
Address: 9.9.9.9#53
Non-authoritative answer:
Name: api.trycloudflare.com
Address: 104.17.124.55
Name: api.trycloudflare.com
Address: 104.17.123.55
To Reproduce Steps to reproduce the behavior:
- Run './cloudflared tunnel' (in termux v0.118.0)
- See error
If it's an issue with Cloudflare Tunnel: but not with account(I logined my account but I use tunnel without account) ~3. Tunnel ID :~ ~4. cloudflared config:~
Expected behavior The program can get api.trycloudflare.com's ip address then create my tunnel.
Environment and versions
- OS: [Termux 0.118.0 on Android 12(vivo Y77)]
- Architecture: [aarch64]
- Version: [0.118.0]
Logs and errors up there.
Additional context none
??
@zhangjing-GitHub-Code the way you access termux ssh through cloudflare tunnel is.
- have a
sshdrunning. - give a user password
passwd - check if it is working
ssh localhost -p 8022; default ssh port in termux is 8022. - install cloudflared in termux
pkg install cloudflared cloudflared logina url will be given, you login a cloudflare in your phone and go to that page again. click the domain you want to use.cloudflared tunnel create temp-tunnel-name- in termux go to
ls ~/.cloudflared/=> you should see cert.pem and uuid.json - copy that uuid string without json.
- create a new file on
~/.cloudflared/config.yaml
tunnel: uuid
credentials-file: absolute path of that uuid.json (try pwd while on ~/.cloudflared/ to find a pathname)
- run
cloudflared tunnel run - exit from that command
- you will see a new tunnel in cloudflared zero trust.
I encountered the same problem and, after some research, I found a solution. Essentially, many Linux distributions include a local resolver that listens on [::1]:53. This resolver is responsible for forwarding DNS queries to the actual DNS server and caching the responses. Cloudflared attempts to query its edge server's IP address by sending a DNS query to the local resolver. However, the Android system does not provide such a local resolver, resulting in a connection get refused when attempting to query DNS from [::1]:53.
To resolve this issue, we need to set up a DNS proxy that listens on port 53. You can do this by executing the following command with root privileges:
sudo cloudflared proxy-dns --port 53
Afterwards, open a new terminal and run the tunnel command:
cloudflared tunnel --url ...
These should resolve the problem. Note that setting up a DNS proxy on port 53 requires root privileges.
I encountered the same problem and, after some research, I found a solution. Essentially, many Linux distributions include a local resolver that listens on [::1]:53. This resolver is responsible for forwarding DNS queries to the actual DNS server and caching the responses. Cloudflared attempts to query its edge server's IP address by sending a DNS query to the local resolver. However, the Android system does not provide such a local resolver, resulting in a connection get refused when attempting to query DNS from [::1]:53.
To resolve this issue, we need to set up a DNS proxy that listens on port 53. You can do this by executing the following command with root privileges:
sudo cloudflared proxy-dns --port 53Afterwards, open a new terminal and run the tunnel command:
cloudflared tunnel --url ...These should resolve the problem. Note that setting up a DNS proxy on port 53 requires root privileges.
Making that local DNS server doesn't work on android with termux.
I encountered the same problem and, after some research, I found a solution. Essentially, many Linux distributions include a local resolver that listens on [::1]:53. This resolver is responsible for forwarding DNS queries to the actual DNS server and caching the responses. Cloudflared attempts to query its edge server's IP address by sending a DNS query to the local resolver. However, the Android system does not provide such a local resolver, resulting in a connection get refused when attempting to query DNS from [::1]:53. To resolve this issue, we need to set up a DNS proxy that listens on port 53. You can do this by executing the following command with root privileges:
sudo cloudflared proxy-dns --port 53Afterwards, open a new terminal and run the tunnel command:cloudflared tunnel --url ...These should resolve the problem. Note that setting up a DNS proxy on port 53 requires root privileges.Making that local DNS server doesn't work on android with termux.
Do you have root though?
I dont't have root, but are in the process of rooting with magisk.
I dont't have root, but are in the process of rooting with magisk.
Root/sudo is required to bind any port<1024. I am surprised termux team hasn't fix this dns issue by now.
I'm using root
Try this (no root previleges required), I assume pip is already installed.
pip install udocker
udocker run ikhwanperwira/ucloudflared:latest tunnel --hello-world
To use credential login and make it persistent synchronous between host and container, use -v volume flag. This will mapping ~ (home host) to /home/nonroot (home container)
udocker run -v ~:/home/nonroot ikhwanperwira/ucloudflared:latest tunnel --config=/home/nonroot/cf/config.yaml run
Don't forget update credentials path of config.yaml in credentials-file=/home/nonroot/.cloudflared/<tunnel_id>.json
============================
Explanation:
Inspired from @Liquorice10113 answer, linux cloudflared binary tries to read /etc/hosts for metric (localhost lookup) and /etc/resolv.conf to resolve DNS. It's not possible for non-rooted android to listen on port 53 generally port less than 1024. Therefore I isolate cloudflared with docker.
The image was built from this simple Dockerfile:
# Official Cloudflared image
FROM cloudflare/cloudflared:latest
# You can replace `resolv.conf` with `/data/data/com.termux/files/usr/etc/resolv.conf`
COPY resolv.conf /etc/resolv.conf
# You can replace 'hosts` with `/data/data/com.termux/files/usr/etc/hosts`
COPY hosts /etc/hosts
In my cases, resolv.conf using Google DNS
nameserver 8.8.8.8
And hosts:
127.0.0.1 localhost
Then I built the image into specific architecture (linux/arm64) since Android using arm64 with GCP.
docker build --platform linux/arm64 -t ikhwanperwira/ucloudflared:latest . && docker push ikhwanperwira/ucloudflared:latest