Open alexispurslane opened 9 months ago
I've tried pinging various things from inside docker compose exec protonwire bash
and ping can never reach anything either, it just hangs forever. Even though, sometimes, before protonwire restarts itself (and gets a different log color), the docker container behind it can access the internet!
Same here. Usually have to go in and 'docker compose protonwire restart' to reset the entire stack but definitely looking for a fix here.
Curl exit code 6 is DNS error. From the logs I can see that metadata endpoints are indeed reachable, So I guess the problem is with https://protonwire-api.vercel.app/v1/client/ip
which redirects to https://icanhazip.com
Can you try to resolve protonwire-api.vercel.app
and icanhazip.com
from both inside and outside the container?
container has bind-tools
so host command should work, Can you try the following commands and post the output
(Please redact your public IP).
host -t A protonwire-api.vercel.app
host -t A icanhazip.com
curl -Lv https://protonwire-api.vercel.app/v1/client/ip
If they do not work, try setting IPCHECK_URL
to https://protonwire-api.vercel.app/api/client/exp/clientip
and check if resolves the issue. This API endpoint is experimental do not spam it.
ping may be a different issue as it typically requires additional caps (CAP_NET_RAW
or tweaking sysctl net.ipv4.ping_group_range
.
@tprasadtp excellent, thank you, I'll give these commands a shot and see what I get! I don't know if changing the API endpoint will work, since I already attempted to do that as noted in my bug report, but it's worth a shot too.
Alright I ran the suggested commands inside the protonwire container and here's what I got:
protonwire-api.vercel.app has address 76.76.21.61
protonwire-api.vercel.app has address 76.76.21.93
icanhazip.com has address 104.18.115.97
icanhazip.com has address 104.18.114.97
* Trying 76.76.21.61:443...
* Connected to protonwire-api.vercel.app (76.76.21.61) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.vercel.app
* start date: Sep 25 03:14:47 2023 GMT
* expire date: Dec 24 03:14:46 2023 GMT
* subjectAltName: host "protonwire-api.vercel.app" matched cert's "*.vercel.app"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /v1/client/ip]
* h2h3 [:scheme: https]
* h2h3 [:authority: protonwire-api.vercel.app]
* h2h3 [user-agent: curl/8.0.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x7fc30856faf0)
> GET /v1/client/ip HTTP/2
> Host: protonwire-api.vercel.app
> user-agent: curl/8.0.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 308
< cache-control: public, max-age=0, must-revalidate
< content-type: text/plain
< date: Fri, 29 Sep 2023 17:42:42 GMT
< location: https://icanhazip.com/
< refresh: 0;url=https://icanhazip.com/
< server: Vercel
< strict-transport-security: max-age=63072000; includeSubDomains; preload
< x-vercel-cache: MISS
< x-vercel-id: iad1::cj79f-1696009362684-a013ed042279
<
* Ignoring the response-body
* Connection #0 to host protonwire-api.vercel.app left intact
* Issue another request to this URL: 'https://icanhazip.com/'
* Trying 104.18.114.97:443...
* Connected to icanhazip.com (104.18.114.97) port 443 (#1)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=sni.cloudflaressl.com
* start date: Apr 7 00:00:00 2023 GMT
* expire date: Apr 6 23:59:59 2024 GMT
* subjectAltName: host "icanhazip.com" matched cert's "icanhazip.com"
* issuer: C=US; O=Cloudflare, Inc.; CN=Cloudflare Inc ECC CA-3
* SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: icanhazip.com]
* h2h3 [user-agent: curl/8.0.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x7fc30856faf0)
> GET / HTTP/2
> Host: icanhazip.com
> user-agent: curl/8.0.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 200
< date: Fri, 29 Sep 2023 17:42:42 GMT
< content-type: text/plain
< content-length: 13
< access-control-allow-origin: *
< access-control-allow-methods: GET
< set-cookie: __cf_bm=1EoYCZIBioCXpjESzk8BewS1FTnGiAfzvq0VjCVat1M-1696009362-0-AQr9fCq43QrcroeorxGZmw3zuYdXTWFrxrSfIW6Q9uYLQq8uybFhGBTbpaF0rb6jQgvEdqpibuugjryTptIv2Xc=; path=/; expires=Fri, 29-Sep-23 18:12:42 GMT; domain=.icanhazip.com; HttpOnly; Secure; SameSite=None
< server: cloudflare
< cf-ray: 80e60636395782fc-IAD
< alt-svc: h3=":443"; ma=86400
<
[MY IP ADDRESS REDACTED]
* Connection #1 to host icanhazip.com left intact
It also appeared that I can ping both IP addresses and URLs, and even curl icanhazip.com, from inside the protonwire client, but the docker container behind it still couldn't access the internet (perhaps because protonwire had restarted so many times it finally became stable, but the other docker couldn't talk to the newly started processes) . This was presenting differently than it had been when I made the bug report, so I restarted the docker compose in order to see if I could do your commands while it was having the problems I initially described, for better diagnostics. Instead, now the problem is gone! The connection can be verified the first time, so protonwire doesn't need to restart, which means the container behind it can access the internet. I'm worried this will happen again though.
It might be that server you selected was offline for a while, which obviously results in connection errors. Because DNS is kinda circular dependency it may result in DNS errors when wireguard client is up. (DNS is 10.2.0.1 which is only accessible if VPN is connected). Can you provide logs with timestamps and exact server name?
How are you running containers behind the VPN? There also might be a race condition which can lead to networking being broken inside them.
I restarted my computer and I'm running into the exact same problems again, with basically the exact same logs, despite choosing a completely different server so I highly doubt that it's the server randomly being offline. Also as you can see in the docker composed that I put in the original issue post I have the docker container that's behind proton wire set up to depend on proton wire so there is no race condition there.
Here is the current output of the three commands you listed above, now that protonwire is failing again:
;; communications error to 10.2.0.1#53: timed out
;; communications error to 10.2.0.1#53: timed out
;; no servers could be reached
;; communications error to 10.2.0.1#53: timed out
;; communications error to 10.2.0.1#53: timed out
;; no servers could be reached
10.2.0.1 is the protonvpn server which also handles DNS, so connection errors to server breaks everything.
Whats the output of wg show protonwire0
(inside the container)?
Can you curl an IP address? Try curl -vL https://1.1.1.1/ -o /dev/null
(This should bypass the DNS)
If it does not work, can you try to run with SKIP_DNS_CONFIG=1
? That should remove DNS from the variables.
output of wg show protonwire0
:
interface: protonwire0
public key: ...
private key: (hidden)
listening port: 41637
fwmark: 0xca6d
peer: [peer public key]
endpoint: 193.29.107.162:51820
allowed ips: 0.0.0.0/0, ::/0
latest handshake: 1 minute, 28 seconds ago
transfer: 801.47 KiB received, 327.49 KiB sent
persistent keepalive: every 25 seconds
output of curl -vL https://1.1.1.1/ -o /dev/null
:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 1.1.1.1:443...
* Connected to 1.1.1.1 (1.1.1.1) port 443 (#0)
* ALPN: offers h2,http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [15 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2598 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=cloudflare-dns.com
* start date: Jan 12 00:00:00 2023 GMT
* expire date: Jan 11 23:59:59 2024 GMT
* subjectAltName: host "1.1.1.1" matched cert's IP address!
* issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS Hybrid ECC SHA384 2020 CA1
* SSL certificate verify ok.
} [5 bytes data]
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: 1.1.1.1]
* h2h3 [user-agent: curl/8.0.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x7fb76c074af0)
} [5 bytes data]
> GET / HTTP/2
> Host: 1.1.1.1
> user-agent: curl/8.0.1
> accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
< HTTP/2 200
< date: Sun, 01 Oct 2023 18:24:18 GMT
< content-type: text/html
< report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=hQOLzC6oLrf%2BCOOcvO8Ufzoh8lfJ9zaZs10q04YXUaPkewo3Q0no7Hur4PZANhkR%2FQww5bKG%2FxCds53IKCVzWSTphfLmUi8%2FFEvpzr5%2BPqnla2EBY%2FCbe5A%3D"}],"group":"cf-nel","max_age":604800}
< nel: {"report_to":"cf-nel","max_age":604800}
< last-modified: Fri, 21 Jul 2023 21:11:33 GMT
< strict-transport-security: max-age=31536000
< served-in-seconds: 0.004
< cache-control: public, max-age=14400
< cf-cache-status: HIT
< age: 38
< expires: Sun, 01 Oct 2023 22:24:18 GMT
< accept-ranges: bytes
< set-cookie: __cf_bm=.DknbODlodCAZFfdM3vxVzfz8H5wIh7tb5q6Nu5yjok-1696184658-0-AaOU+Yqd+1WwWrpGEe0XMyKAQQgVfjX0y2ov5OQUw8ucL5vNKnmEtVhFxu/Pu4bi0CU1ehEz123geZ3OI3/1Nh8=; path=/; expires=Sun, 01-Oct-23 18:54:18 GMT; domain=.every1dns.com; HttpOnly; Secure; SameSite=None
< server: cloudflare
< cf-ray: 80f6bde35e542c52-FRA
< alt-svc: h3=":443"; ma=86400
<
{ [5 bytes data]
100 56597 0 56597 0 0 62328 0 --:--:-- --:--:-- --:--:-- 62331
* Connection #0 to host 1.1.1.1 left intact
So it looks like it can connect fine to the internet. Try this command and check if it returns your public IP. If yes then something is wrong with routing/wireguard tunnel if not its only the DNS which is borked and need to be fixed.
curl -vfL --resolve "protonwire-api.vercel.app:443:76.76.21.9" -H 'Host: protonwire-api.vercel.app' https://protonwire-api.vercel.app/api/client/exp/clientip
If you get protonVPN public IP from the above command, use SKIP_DNS_CONFIG=1
as a work around for now.
You can configure DoT on systemd resolved to protect DNS queries.
I ran that command, and I got the protonVPN endpoint IP address back, so it looks like it is just a DNS issue. I'm not using systemd-resolved though, and I'd rather not even slightly risk any data leaks (I have clinical anxiety and just don't want the mental space taken up by that lol) so I guess I'll just wait till a proper fix for the DNS is found.
Next time you encounter the issue can you try the following?
cat /etc/resolv.conf
cat /etc/resolv.conf.protonwire
ls -alh /etc/resolv.conf
ip route get 10.2.0.1
ip -4 --json rule | jq
ip -4 --json route show table 51821 | jq
ping 10.2.0.1
I cannot reproduce the issue locally. Did the issue occur after upgrade to 7.2 or later ?
Next time you encounter the issue can you try the following?
cat /etc/resolv.conf cat /etc/resolv.conf.protonwire ls -alh /etc/resolv.conf ip route get 10.2.0.1 ip -4 --json rule | jq ip -4 --json route show table 51821 | jq ping 10.2.0.1
Sure, no problem! I'll run them right now
I cannot reproduce the issue locally. Did the issue occur after upgrade to 7.2 or later ?
I'm not sure, but I think so — I'd had the container up for like two or more straight months, then I finally rebooted my server and restarted the container, and that's when the problems started, which implies it started when the image was rebuilt, I think,
@tprasadtp oh shit, I just realized, even though I thought I updated the container, it's still on version 7.0.3 according to docker inspect
... strange. Let me try to update it and see if that resolves the problem.
Interesting. Now that I've updated, it works fine... for now, at least.
Edit (later): nope, it's broken again
I think change to updating the resolv.conf logic might be the issue. But openresolv(used in 7.0.x) is also broken as it does not behave well with bind mounted /etc/resolv.conf.
cat /etc/resolv.conf
cat /etc/resolv.conf.protonwire
ls -alh /etc/resolv.conf
ip route get 10.2.0.1
ip -4 --json rule | jq
ip -4 --json route show table 51821 | jq
ping 10.2.0.1
Can you please try these and give their outputs? Also output of docker inspect of the container?
Alright. It started working again this morning when I restarted it (connection was able to be verified), but I'll wait until it fails again and run those commands. In the meantime, check out these logs, it's doing something new — verifying the connection is still failing, but then it's reconnecting to the server, which it wasn't doing before, and reconnnecting successfully too. It also says the server is online:
protonwire | [INFO ] Refresing server metadata (for ...)
protonwire | [SUCCESS ] Successfully refreshed server metadata
protonwire | [SUCCESS ] Server ... is online
protonwire | [SUCCESS ] Using PrivateKeyFile - /etc/protonwire/private-key
protonwire | [SUCCESS ] net.ipv4.conf.all.rp_filter is already set to 2
protonwire | [NOTICE ] Creating WireGuard Interface - protonwire0
protonwire | [INFO ] Setting WireGuard interface address - 10.2.0.2
protonwire | [INFO ] Setting WireGuard interface MTU to 1480
protonwire | [SUCCESS ] Configured WireGuard private key from /etc/protonwire/private-key
protonwire | [INFO ] WireGuard interface is configured with peer - ...
protonwire | [INFO ] Bringing WireGuard interface up
protonwire | [SUCCESS ] Configured fwmark on WireGuard interface to - 0xca6d
protonwire | [NOTICE ] Creating routes (IPv4)
protonwire | [SUCCESS ] DNS is is set to 10.2.0.1 via /etc/resolv.conf
protonwire | [SUCCESS ] Successfully configured DNS (resolvconf)
protonwire | [INFO ] Verifying connection
protonwire | [SUCCESS ] Connected to node-...
protonwire | [SUCCESS ] Connection verified!
protonwire | [INFO ] Checking status - every 120 seconds
protonwire | [ERROR ] Failed to resolve DNS domain (https://protonwire-api.vercel.app/v1/client/ip)
protonwire | [ERROR ] Failed to verify connection (1/5)
protonwire | [WARNING ] Attempting to re-connect to ...
protonwire | [SUCCESS ] Server ... is online
protonwire | [SUCCESS ] Using PrivateKeyFile - /etc/protonwire/private-key
protonwire | [SUCCESS ] net.ipv4.conf.all.rp_filter is already set to 2
protonwire | [NOTICE ] WireGuard interface 'protonwire0' already exists
protonwire | [SUCCESS ] WireGuard interface already has address - 10.2.0.2/32
protonwire | [SUCCESS ] WireGuard interface MTU is already set to - 1480
protonwire | [SUCCESS ] WireGuard interface already has private key configured
protonwire | [SUCCESS ] WireGuard interface already has peer - ...
protonwire | [SUCCESS ] WireGuard interface is already UP
protonwire | [SUCCESS ] WireGuard interface fwmark is already set to - 0xca6d
protonwire | [SUCCESS ] Routes are algrady configured (IPv4)
protonwire | [SUCCESS ] Routing policy rule is already configured (IPv4)
protonwire | [SUCCESS ] DNS is already set to 10.2.0.1 in /etc/resolv.conf
protonwire | [SUCCESS ] Successfully configured DNS (resolvconf)
protonwire | [SUCCESS ] Connected to node-dk-05.protonvpn.net (via 193.29.107.163)
protonwire | [NOTICE ] Successfully reconnected to ...
Here's the command output:
# This file is managed by protonwire. DO NOT EDIT.
# If you do not wish to use ProtonVPN DNS servers,
# disable it via one of the following.
# - Set 'SKIP_DNS_CONFIG' envirpnment variable to '1'.
# - Use '--skip-dns-config' CLI flag.
#
# Your old DNS configration has been backed up at /etc/resolv.conf.protonwire.
# protonvpn will automatically restore your previous DNS config upon disconnect.
#
nameserver 10.2.0.1
nameserver 127.0.0.11
options ndots:0
-rw-r--r-- 1 root root 420 Oct 2 13:51 /etc/resolv.conf
10.2.0.1 dev protonwire0 table 51821 src 10.2.0.2 uid 0
cache
[
{
"priority": 0,
"src": "all",
"table": "local"
},
{
"priority": 32765,
"not": null,
"src": "all",
"fwmark": "0xca6d",
"table": "51821"
},
{
"priority": 32766,
"src": "all",
"table": "main"
},
{
"priority": 32767,
"src": "all",
"table": "default"
}
]
[
{
"dst": "0.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "8.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "10.2.0.1",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "11.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "12.0.0.0/6",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "16.0.0.0/4",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "32.0.0.0/3",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "64.0.0.0/3",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "96.0.0.0/6",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "100.0.0.0/10",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "100.128.0.0/9",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "101.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "102.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "104.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "112.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "120.0.0.0/6",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "124.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "126.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "128.0.0.0/3",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "160.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "168.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.0.0.0/9",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.128.0.0/10",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.192.0.0/11",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.224.0.0/12",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.240.0.0/13",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.248.0.0/14",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.252.0.0/15",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "169.255.0.0/16",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "170.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "172.0.0.0/12",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "172.32.0.0/11",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "172.64.0.0/10",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "172.128.0.0/9",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "173.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "174.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "176.0.0.0/4",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.0.0.0/9",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.128.0.0/11",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.160.0.0/13",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.169.0.0/16",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.170.0.0/15",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.172.0.0/14",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.176.0.0/12",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "192.192.0.0/10",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "193.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "194.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "196.0.0.0/6",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "200.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "208.0.0.0/4",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.1.0/24",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.2.0/23",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.4.0/22",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.8.0/21",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.16.0/20",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.32.0/19",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.64.0/18",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.0.128.0/17",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.1.0.0/16",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.2.0.0/15",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.4.0.0/14",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.8.0.0/13",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.16.0.0/12",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.32.0.0/11",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.64.0.0/10",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "224.128.0.0/9",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "225.0.0.0/8",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "226.0.0.0/7",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "228.0.0.0/6",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
},
{
"dst": "232.0.0.0/5",
"dev": "protonwire0",
"scope": "link",
"metric": 500,
"flags": []
}
]
PING 10.2.0.1 (10.2.0.1): 56 data bytes
64 bytes from 10.2.0.1: seq=0 ttl=64 time=107.875 ms
64 bytes from 10.2.0.1: seq=1 ttl=64 time=108.152 ms
64 bytes from 10.2.0.1: seq=2 ttl=64 time=113.538 ms
^C
--- 10.2.0.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 107.875/109.855/113.538 ms
here's the inspect output:
[
{
"Id": "...",
"Created": "2023-10-01T22:52:30.692743725Z",
"Path": "/usr/bin/protonwire",
"Args": [
"connect",
"--container"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 237751,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-10-02T13:51:31.637724376Z",
"FinishedAt": "2023-10-02T13:51:31.279691757Z"
},
"Image": "sha256:952d93f4bd6ae8144ff6692c9e3e864a0aa93d2cd0fbc5be6593d152faaf7887",
"ResolvConfPath": "/var/lib/docker/containers/952e79f5dfaa2e757e1c7ee199869ad538d3e1389459395b552ddd1ec32ddeed/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/952e79f5dfaa2e757e1c7ee199869ad538d3e1389459395b552ddd1ec32ddeed/hostname",
"HostsPath": "/var/lib/docker/containers/952e79f5dfaa2e757e1c7ee199869ad538d3e1389459395b552ddd1ec32ddeed/hosts",
"LogPath": "/var/lib/docker/containers/952e79f5dfaa2e757e1c7ee199869ad538d3e1389459395b552ddd1ec32ddeed/952e79f5dfaa2e757e1c7ee199869ad538d3e1389459395b552ddd1ec32ddeed-json.log",
"Name": "/protonwire",
"RestartCount": 85,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "projectname_default",
"PortBindings": {
"6881/tcp": [
{
"HostIp": "",
"HostPort": "6881"
}
],
"6881/udp": [
{
"HostIp": "",
"HostPort": "6881"
}
],
"6969/tcp": [
{
"HostIp": "",
"HostPort": "6969"
}
]
},
"RestartPolicy": {
"Name": "unless-stopped",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
0,
0
],
"CapAdd": [
"NET_ADMIN"
],
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": [],
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Sysctls": {
"net.ipv4.conf.all.rp_filter": "2",
"net.ipv6.conf.all.disable_ipv6": "1"
},
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": null,
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"Mounts": [
{
"Type": "tmpfs",
"Target": "/tmp"
},
{
"Type": "bind",
"Source": "/opt/docker/projectname/wg2-private.key",
"Target": "/etc/protonwire/private-key",
"ReadOnly": true
}
],
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
],
"Init": true
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/577524c738e4e67596b7c164e4351a831e437fec127c110856ba3770c51ca24e-init/diff:/var/lib/docker/overlay2/0d5bbbeed3e21b388eb547b5a36712277dbb681c2970a2ebde7e01d477d183b7/diff:/var/lib/docker/overlay2/9478a60b4dc66f264edb60b6975c158f9777ee78c7e92e9a7692d716e87da10e/diff:/var/lib/docker/overlay2/bab38cec549e0a06f842239d6642393e8aef4c23982ad6da53a38892ae1d0296/diff:/var/lib/docker/overlay2/a4a97968382108a583457cd6b5af0de13ed4ae96ed52292357fa6657d06699fe/diff",
"MergedDir": "/var/lib/docker/overlay2/577524c738e4e67596b7c164e4351a831e437fec127c110856ba3770c51ca24e/merged",
"UpperDir": "/var/lib/docker/overlay2/577524c738e4e67596b7c164e4351a831e437fec127c110856ba3770c51ca24e/diff",
"WorkDir": "/var/lib/docker/overlay2/577524c738e4e67596b7c164e4351a831e437fec127c110856ba3770c51ca24e/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "tmpfs",
"Source": "",
"Destination": "/tmp",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/opt/docker/projectname/wg2-private.key",
"Destination": "/etc/protonwire/private-key",
"Mode": "",
"RW": false,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "952e79f5dfaa",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"6881/tcp": {},
"6881/udp": {},
"6969/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PROTONVPN_SERVER=...",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/usr/bin/protonwire",
"connect",
"--container"
],
"Image": "ghcr.io/tprasadtp/protonwire:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"com.docker.compose.config-hash": "cfdc52264b86d28cbca5a42920dea92335e01d29f4840e732559510780f9c09b",
"com.docker.compose.container-number": "1",
"com.docker.compose.depends_on": "",
"com.docker.compose.image": "sha256:952d93f4bd6ae8144ff6692c9e3e864a0aa93d2cd0fbc5be6593d152faaf7887",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "projectname",
"com.docker.compose.project.config_files": "/opt/docker/projectname/docker-compose.yml",
"com.docker.compose.project.working_dir": "/opt/docker/projectname",
"com.docker.compose.service": "protonwire",
"com.docker.compose.version": "2.21.0",
"io.github.tprasadtp.metadata.git.branch": "HEAD",
"io.github.tprasadtp.metadata.git.commit": "3adea60a05cd076ee612f4f818dd886d21e8a430",
"io.github.tprasadtp.metadata.git.shortCommit": "3adea60",
"io.github.tprasadtp.metadata.git.tag": "7.2.3",
"io.github.tprasadtp.metadata.version.major": "7",
"io.github.tprasadtp.metadata.version.minor": "2",
"io.github.tprasadtp.metadata.version.patch": "3",
"io.github.tprasadtp.metadata.version.prerelease": "",
"io.github.tprasadtp.metadata.version.snapshot": "false",
"org.opencontainers.image.created": "2023-09-24T20:38:01Z",
"org.opencontainers.image.description": "\"ProtonVPN Wireguard Client for Linux\"",
"org.opencontainers.image.documentation": "https://tprasadtp.github.io/protonwire",
"org.opencontainers.image.licenses": "GPLv3",
"org.opencontainers.image.revision": "3adea60a05cd076ee612f4f818dd886d21e8a430",
"org.opencontainers.image.source": "\"https://github.com/tprasadtp/protonwire\"",
"org.opencontainers.image.title": "protonwire",
"org.opencontainers.image.url": "https://ghcr.io/tprasadtp/protonwire",
"org.opencontainers.image.vendor": "\"Prasad Tengse <tprasadtp@users.noreply.github.com>\"",
"org.opencontainers.image.version": "7.2.3"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "0ee1735cd5c84e0ea1201d9247dd6bf5fc8039d96539781fd7e8690f14dfe361",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"6881/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6881"
},
{
"HostIp": "::",
"HostPort": "6881"
}
],
"6881/udp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6881"
},
{
"HostIp": "::",
"HostPort": "6881"
}
],
"6969/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6969"
},
{
"HostIp": "::",
"HostPort": "6969"
}
]
},
"SandboxKey": "/var/run/docker/netns/0ee1735cd5c8",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"projectname_default": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"protonwire",
"protonwire",
"952e79f5dfaa"
],
"NetworkID": "f2e23327b187848d908ce53d5a1b76ca8ab8ac101a8f15d2dbdf6b9e36dca5f9",
"EndpointID": "48b152225ed5514aff6ea1d2df8d8461ef27a3a8a5204229926982be3cc2439c",
"Gateway": "172.21.0.1",
"IPAddress": "172.21.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:15:00:02",
"DriverOpts": null
}
}
}
}
]
Just to be clear this is output when connection fails, correct? Everything looks fine from routing table and routing priorities. Are you still able to resolve some random DNS from inside the container?
Just to be clear this is output when connection fails, correct?
Yeah
Everything looks fine from routing table and routing priorities. Are you still able to resolve some random DNS from inside the container?
I'll check in a bit
Yeah
Its really weird. You can ping to DNS server it routes via correct interface, but only DNS resolution fails? Really strange.
I'll check in a bit
Take your time.
I re-built the container image with debian as the base image ghcr.io/tprasadtp/protonwire:7.2.3-debug-alexis
. (It was built by github actions and is signed) try it and check if it helps? Another option is to run with a different container runtime.
Debian bookworm has podman can you try to run it with podman? Also rootless uses user-mode networking. I don't think its an issue but can you try to run container it in podman rootful mode?
Have you disabled Netshield in your protonvpn configuration?
Have you disabled Netshield in your protonvpn configuration?
Yes
Hmmm, This is really strange. Try it with debian image ghcr.io/tprasadtp/protonwire:7.2.3-debug-alexis
, and next time when connection errors, try to ping 10.2.0.1 and also try to resolve a well known dns name like github.com
inside the container and also verify DNS queries are being routed via wireguard. ip route get 10.2.0.1
I will try to reproduce this on bookworm and same docker version.
I can somewhat reproduce the issue, but it recovers on its own quickly.
docker run -it \
--name=protonwire-alexis-test-f8c2df2 \
--init \
--cap-add=CAP_NET_ADMIN \
--userns=host -p=8000:80 \
--mount type=bind,src=<key-file>,dst=/etc/protonwire/private-key,readonly \
--sysctl net.ipv4.conf.all.rp_filter=2 \
--tmpfs /tmp \
ghcr.io/tprasadtp/protonwire:7.3.0-alpha1 \
protonwire c nl-free-127.protonvpn.net --verbose --container --ks --check-interval 10
[•] Adding IP rule for Table 51821 (IPv4)
[•] Updating /etc/resolv.conf
[•] DNS is is set to 10.2.0.1 via /etc/resolv.conf
[•] Successfully configured DNS (resolvconf)
[•] Verifying connection
[•] WireGuard interface - protonwire0 is present
[•] Connected to peer - zFkaDAaf8Xt6c1FY82sp5Ncw/pN+GB9asDtGDOWClzo=
[•] Connected to server: NL-FREE#128127(nl-free-127.protonvpn.net)
[•] Not validating country
[•] Not validating if server supports P2P
[•] Not validating if server supports Stremaing
[•] Not validating if server supports Tor
[•] Not validating if server supports SecureCore
[•] Allowed ExitIPs - 185.107.56.76 185.107.56.78 185.107.56.80 185.107.56.83
[•] Checking client IP via https://protonwire-api.vercel.app/v1/client/ip
[•] (curl) % Total % Received % Xferd Average Speed Time Time Time Current
[•] (curl) Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Could not resolve host: protonwire-api.vercel.app
[•] (curl) * Closing connection 0
[•] (curl) curl: (6) Could not resolve host: protonwire-api.vercel.app
[•] Healthcheck curl exit code - 6
[•] Failed to resolve DNS domain (https://protonwire-api.vercel.app/v1/client/ip)
[•] Retry (1/5) after 2 seconds
But it happens sporadically but it recovers quickly. Only changes I have from your configuration is IPCHECK_INTERVAL=10
which might help if NAT gateway is forgetting connections too quickly and
KILL_SWITCH=1
.
I have pushed 7.3.0-alpha1
image which uses debian bookworm. Does the issue persist with that image as well?
Any output from
ip route get 10.2.0.1
ping 10.2.0.1
host -t A github.com
when the issue occurs might shed light on whats happening. If that too does not help, try to run with SKIP_DNS_CONFIG=1
. (You don't need any connected containers just run the protonwire and see if the issue re-appears). Also try with a custom name server like 1.1.1.1 (use --dns
flag or dns
option.)
Hmmm, This is really strange. Try it with debian image
ghcr.io/tprasadtp/protonwire:7.2.3-debug-alexis
, and next time when connection errors, try to ping 10.2.0.1 and also try to resolve a well known dns name likegithub.com
inside the container and also verify DNS queries are being routed via wireguard.ip route get 10.2.0.1
I will try to reproduce this on bookworm and same docker version.
When using this container image, ping isn't provided for some reason. I'll try the stuff in your most recent comment instead.
Okay, trying with the 7.3.0-alpha1 container image, and the different environment variables you mentioned, and I'm still getting the same failure to verify the connection because it can't resolve the DNS of the domain as before. Here's the output from the three commands you gave:
10.2.0.1 dev protonwire0 table 51821 src 10.2.0.2 uid 0
cache
bash: ping: command not found
;; communications error to 10.2.0.1#53: timed out
;; communications error to 10.2.0.1#53: timed out
;; no servers could be reached
I really appreciate your patience, you are being awesome! :tada:
bash: ping: command not found
Ahh my bad I missed iputils-ping (which was provided by busybox on alpine) 7.3.0-alpha2 should have it.
Lets narrow it down.
wg show
should spit out something like,interface: protonwire0
public key: xx
private key: (hidden)
listening port: 46403
fwmark: 0xca6d
peer: zFkaDAaf8Xt6c1FY82sp5Ncw/pN+GB9asDtGDOWClzo=
endpoint: 185.107.56.76:51820
allowed ips: 0.0.0.0/0, ::/0
latest handshake: 43 seconds ago
transfer: 44.56 KiB received, 18.46 KiB sent
persistent keepalive: every 25 seconds
grab endpoint
IP from above and try to ping it (remove port).
ping <endpoint>
ping 1.1.1.1
host -t A github.com 1.1.1.1
host -t A protonwire-api.vercel.app 1.1.1.1
SKIP_DNS_CONFIG=1
host -t A github.com
host -t A protonwire-api.vercel.app
Cool I'll go through this tomorrow if that's okay. We'll get to the bottom of this! 😄
I'm also having the same issue. Was working fine earlier today but no joy the past hour.
This fails from within the protonwire container but runs fine on the host machine.
host -t A protonwire-api.vercel.app 1.1.1.1 ;; communications error to 1.1.1.1#53: timed out ;; communications error to 1.1.1.1#53: timed out ;; no servers could be reached
Same result when using SKIP_DNS_CONFIG 1 too, but I get a different error from protonwire.
[INFO ] Skipping DNS configuration [INFO ] Verifying connection [ERROR ] curl command exited with 35 [ERROR ] Retry (1/5) after 2 seconds [ERROR ] curl command exited with 35 [ERROR ] Retry (2/5) after 2 seconds
UPDATE Just switched server and its working again. Would it be possible to provide a list of servers and keys to rotate around in-case of this?
Seems to have stopped working again shortly after.
figured out the issue on my end...i had multiple containers using the same wireguard private key...i created new keys for each instance and the issue went away.
For anyone else facing this issue.. make sure you are utilizing the PRIVATE KEY NOT the public key. IDK why it can present itself as a CURL issue, but hey, knowledge is power.
Version
7.2.3
Credential and Server Validation
nl-free-127.protonvpn.net
or server name likeNL#1
) as mentioned in the docs.System Architecture
x86_64
Kernel Version
6.1.0-12-amd64
Running on a NAS?
No
Runtime
Systemd (>244) Unit, docker-rootless
Version of Runtime
My configuration
Whitelisting API endpoints
I am not using ad-blocking DNS server or gateway
Troubleshooting & Runtime
Container/Pod/systemd log output with DEBUG=1 or
--debug
flagAny additional info
I've also tried changing the
IPCHECK_URL
to https://api.ipify.org/, but it didn't help. It still continues to fail to verify.Code of Conduct & PII Redaction