Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS error #25

Closed
ManojKiranA opened this issue Jun 17, 2020 · 42 comments
Closed

DNS error #25

ManojKiranA opened this issue Jun 17, 2020 · 42 comments

Comments

@ManojKiranA
Copy link

while running expose share

this the error i am getting
Could not connect to the server.
Connection to sharedwithexpose.com:443 failed during DNS lookup: DNS error

@drbyte
Copy link
Contributor

drbyte commented Jun 18, 2020

sharedwithexpose.com seems to be responding fine for me.
Perhaps it was a temporary DNS sync issue.

@mpociot
Copy link
Member

mpociot commented Jun 18, 2020

I think this has something to do with how ReactPHP resolves the dns, as this is implemented in PHP as well.

@clue
Copy link

clue commented Jun 21, 2020

I agree that this error message is somewhat confusing and doesn't provide the necessary information. That's why I've filed reactphp/socket#230 a few weeks ago in the underlying component to improve error reporting. I'm planning to release this in the next couple of days if everything goes according to plan. This should give us much better insights to see what's going on.

In the meantime, you can also try installing this component from dev-master to see if the exception includes any more details 👍

@mpociot
Copy link
Member

mpociot commented Jun 22, 2020

@clue I just sent a test build with dev-master to someone that can reproduce the problem.

Here's the result:

Could not connect to the server.
Connection to sharedwithexpose.com:443 failed during DNS lookup: DNS query for sharedwithexpose.com failed: Unable to connect to DNS server (No route to host)

But pinging the host works just fine for him:

ping sharedwithexpose.com 
PING sharedwithexpose.com (142.93.106.246): 56 data bytes
64 bytes from 142.93.106.246: icmp_seq=0 ttl=49 time=143.324 ms
64 bytes from 142.93.106.246: icmp_seq=1 ttl=49 time=118.773 ms
64 bytes from 142.93.106.246: icmp_seq=2 ttl=49 time=116.059 ms

@clue
Copy link

clue commented Jun 22, 2020

@mpociot Thanks, this makes it much easier to debug:

DNS query for sharedwithexpose.com failed: Unable to connect to DNS server (No route to host)

This means the client side can't connect to the DNS server, so this is likely a system configuration or firewall issue. Perhaps you can try running one of the included DNS examples here: https://github.com/reactphp/dns/tree/master/examples

This is very close to what's being used internally by the socket component. We're not aware of any issues in our DNS component and these examples should work out of the box.

If it doesn't work on your system, you can also try checking the $config to see if it matches your expected system settings and/or manually specify another DNS server address (1.1.1.1 or 8.8.8.8) to see if this helps. A dump of $config and /etc/resolv.conf might be useful for further diagnosis.

@ian-patel
Copy link

dig +trace sharedwithexpose.com can't find records. ping looks fine.

image

@peteleco
Copy link

@clue Thanks, adding 1.1.1.1 dns works for me. Then i remove this dns let only google's dns and still works. I'm in Brazil, maybe was some slow dns propagation.

@themsaid
Copy link

Running the first example from https://github.com/reactphp/dns/tree/master/examples returns this:

RuntimeException: DNS query for www.google.com failed: Unable to connect to DNS server (No route to host) in /Users/mac/sites/dns/src/Query/UdpTransportExecutor.php:132
Stack trace:
#0 /Users/mac/sites/dns/src/Query/TimeoutExecutor.php(23): React\Dns\Query\UdpTransportExecutor->query(Object(React\Dns\Query\Query))
#1 /Users/mac/sites/dns/src/Query/RetryExecutor.php(79): React\Dns\Query\TimeoutExecutor->query(Object(React\Dns\Query\Query))
#2 /Users/mac/sites/dns/src/Query/RetryExecutor.php(22): React\Dns\Query\RetryExecutor->tryQuery(Object(React\Dns\Query\Query), 2)
#3 /Users/mac/sites/dns/src/Query/SelectiveTransportExecutor.php(67): React\Dns\Query\RetryExecutor->query(Object(React\Dns\Query\Query))
#4 /Users/mac/sites/dns/src/Query/CoopExecutor.php(58): React\Dns\Query\SelectiveTransportExecutor->query(Object(React\Dns\Query\Query))
#5 /Users/mac/sites/dns/src/Query/HostsFileExecutor.php(64): React\Dns\Query\CoopExecutor->query(Object(React\Dns\Query\Query))
#6 /Users/mac/sites/dns/src/Resolver/Resolver.php(35): React\Dns\Query\HostsFileExecutor->query(Object(React\Dns\Query\Query))
#7 /Users/mac/sites/dns/src/Resolver/Resolver.php(24): React\Dns\Resolver\Resolver->resolveAll('www.google.com', 1)
#8 /Users/mac/sites/dns/examples/01-one.php(18): React\Dns\Resolver\Resolver->resolve('www.google.com')
#9 {main}%    

@clue
Copy link

clue commented Jun 26, 2020

@themsaid Thanks for providing this exception trace. Can you file an issue in the upstream repo https://github.com/reactphp/dns with some details about your platform (PHP version, OS, /etc/resolv.conf and a dump of your $config object)?

We're not currently aware of any issues in our DNS component and people have been using this on a wide variety of platforms for years, so I'm really curious what could cause this issue. The only thing I have in mind might be if your system has a broken DNS configuration (primary DNS broken, but secondary DNS works), this is not currently implemented (reactphp/dns#6).

In the meantime, you should be able to work around this by explicitly defining another DNS server like given above. As an alternative, you can also temporarily add an entry to your /etc/hosts file like this (warning, may change in the future):

142.93.106.246 sharedwithexpose.com

Expose will also somehow use a Connector internally which accepts optional explicit DNS server configuration to override system defaults. This Connector can explicitly be configured like this:

$connector = new React\Socket\Connector($loop, array(
    'dns' => '127.0.1.1'
));

@mpociot
Copy link
Member

mpociot commented Jun 26, 2020

@clue I was talking with @themsaid about this today and he was able to fix this.
He was using 1.1.1.1 as his system configured DNS server - which resulted in the above error.
When manually setting the DNS server to 8.8.8.8 he was able to connect to the Expose server successfully.

I think the best way to fix this in the Expose codebase, is to give users the ability to manually override/configure the DNS server that should be used when connecting.

@clue
Copy link

clue commented Jun 26, 2020

@mpociot I don't agree that Expose should have explicit DNS configuration by default. Any application should take advantage of the system configuration and just work. If your ping command works, so should Expose. If your ping command works and Expose doesn't work, then something is broken (could be a missing feature in the underlying DNS component).

Adding explicit DNS configuration options could be useful in some more advanced scenarios, but this probably shouldn't be the default. In particular, Expose should not override the system settings by default because the system DNS configuration could configure a company-internal DNS server which resolves different addresses than a publicly available one such as Couldflare's or Google's (let alone possible privacy implications).

I'd really like to understand what's causing this problem as it clearly seems to affect multiple users. We just need some more information and a fix probably shouldn't be too hard 👍

@mpociot
Copy link
Member

mpociot commented Jun 26, 2020

Those are good points against having it configurable @clue :)

We will probably need some more input from @themsaid then.
All I know is that he is living in Egypt, where some internet censorship is in place, so this might be part of the problem.

@themsaid
Copy link

@themsaid I have no idea what's the causing the issue :) Could be the ISP indeed :)

@drbyte
Copy link
Contributor

drbyte commented Jun 26, 2020

In the cases where this problem is occurring ...
Is dnsmasq installed? (eg Laravel Valet uses it, as do other tooling systems)

If so, then sometimes explicitly configuring to use 127.0.0.1 as the primary DNS service is helpful.

dnsmasq does honor hosts files out-of-the-box, so that's still a suitable place to put custom servername entries.

But with dnsmasq I would suggest not editing resolv.conf but instead to edit the dnsmasq settings (with Valet you can put custom configs in ~/.config/valet/dnsmasq.d/; without Valet you can probably use /etc/dnsmasq.d/ if enabled or /etc/dnsmasq if you like tampering with default files)

@omitobi
Copy link

omitobi commented Jul 7, 2020

I also experienced this issue right now on expose

Could not connect to the server.
Connection to sharedwithexpose.com:443 failed during DNS lookup: fwrite(): send of 38 bytes failed with errno=65 No route to host

@clue
Copy link

clue commented Jul 7, 2020

This clearly seems to affect more people, so we need some help to track this down! 🪲

It looks like this is an error in the underlying DNS component rather than Expose itself. We're not aware of any issues in the underlying DNS component and so far we haven't been able to reproduce this in the underlying DNS component.

The error means the client side has issues communicating with the DNS server, so this is likely a system configuration or firewall issue. If this affects you, please try running one of the included DNS examples here: https://github.com/reactphp/dns/tree/master/examples

If you can reproduce this error in the DNS component, please report an issue upstream in https://github.com/reactphp/dns/issues so we can isolate and track this down. Please include details about your platform (PHP version, OS, /etc/resolv.conf and a dump of the $config object from the example).

@dakira
Copy link
Contributor

dakira commented Aug 18, 2020

I just had this problem and maybe my observations can help:

I'm in a corporate network that blocks anything but ports 80, 443 and 500 (for ipsec). So to be able to work I use a WireGuard VPN on port 500. The VPN works wonderfully, except for when I use expose. In those cases I simply deactivate the VPN and expose works as expected.

@clue
Copy link

clue commented Aug 18, 2020

If you can reproduce this problem locally, please show the output of the following commands:

$ php -v
$ php -r "require __DIR__.'/vendor/autoload.php';var_dump(React\Dns\Config\Config::loadSystemConfigBlocking());"
$ cat /etc/resolv.conf

The Config object should point to your DNS server address. You can try connecting to your DNS server like this (adjust IP accordingly):

$ php -r "var_dump(fsockopen('udp://127.0.0.1:53'));"

@clue
Copy link

clue commented Aug 18, 2020

I'm in a corporate network that blocks anything but ports 80, 443 and 500 (for ipsec). So to be able to work I use a WireGuard VPN on port 500. The VPN works wonderfully, except for when I use expose. In those cases I simply deactivate the VPN and expose works as expected.

@dakira This is an interesting one. It's my understanding this should also forward port 53 so you can connect to your DNS server. Can you run the above commands and see how this is different from the above observations?

@ls-dac-chartrand
Copy link

ls-dac-chartrand commented Aug 18, 2020

My error is:

"DNS query for X failed: too many retries"

Related to:

When I do cat /etc/resolv.conf I see:

nameserver 172.16.X.X
nameserver 9.9.9.9

Where X is redacted. If I change it (MacOS -> System Preferences -> Network -> Wifi -> Advanced -> DNS) to:

nameserver 9.9.9.9

The problem goes away.

I think this is because I'm working from home, 172.16.X.X is internal to the office which I am not connected to right now, expose is not doing a fallback to the second IP?

@dakira
Copy link
Contributor

dakira commented Aug 27, 2020

Hey @clue, sorry for the late reply. Your commands don't quite work because expose is bundling react/dns in its executable phar.

Anyway.. here are the results:

php -v
PHP 7.4.9 (cli) (built: Aug  7 2020 19:23:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
php -r ....
object(React\Dns\Config\Config)#2 (1) {
  ["nameservers"]=>
  array(3) {
    [0]=>
    string(10) "100.64.3.4"
    [1]=>
    string(7) "1.1.1.1"
    [2]=>
    string(7) "1.0.0.1"
  }
}

100.64.3.4 is an authorative nameserver for internal-only domains that does not do any recursion. This can be confirmed using dig.

dig @100.64.3.4 my.domain
; <<>> DiG 9.10.6 <<>> @100.64.3.4 my.domain
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 24660
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;my.domain.			IN	A

;; Query time: 23 msec
;; SERVER: 100.64.3.4#53(100.64.3.4)
;; WHEN: Thu Aug 27 15:59:09 CEST 2020
;; MSG SIZE  rcvd: 38

So react/dns only seems to try the first DNS and then stop. Changing the order of DNS servers in my WireGuard config and moving 100.64.3.4 to the end of the list solves the problem.

@clue
Copy link

clue commented Aug 31, 2020

@dakira Thanks for helping analyze this problem and confirming my previous assumptions! It does indeed look like the problem here is a misconfigured/unreachable primary DNS server plus the fact that ReactPHP does not currently try a secondary DNS server (reactphp/dns#6).

Fortunately, this means there are a number of work arounds that can be employed to avoid running into this problem:

  1. Make sure the primary DNS server is valid and reachable in your network. In many cases this means some manual system configuration, e.g. making sure 1.1.1.1 or some other public DNS server is your primary DNS.
  2. As per my above comment you can use your hosts file to (temporarily) create an explicit DNS entry which ReactPHP will use over any other DNS settings.

With the recent additions I've done in the DNS component, we've already achived some much better error reporting which helped pinpointing this issue. Now, the longer term goal here is definitely to add support for secondary DNS servers in ReactPHP as discussed in reactphp/dns#6. This is definitely on the roadmap, but at the moment I'm buried in work, so I won't be able to make any commitments for this at the moment. In other words, there are currently no immediate plans to build this from my end (no demand at the moment and more important outstanding issues currently), but I would be really happy to accept and/or help with any PRs 👍

If you need this for a commercial project and if you want to help sponsor this feature, feel free to reach out and send me an email. Perhaps we can also find a couple of new GitHub sponsors to allow me spending some time on this? 🤝 (sorry for the plug)

@dakira
Copy link
Contributor

dakira commented Sep 1, 2020

@mpociot I think this issue can be closed.

@chiribuc
Copy link

It seems that I have the same problem.

Could not connect to the server.
Connection to sharedwithexpose.com:443 failed during DNS lookup: DNS query for sharedwithexpose.com failed: Unable to connect to DNS server (php_network_getaddresses: gethostbyname failed. errno=0)

I read all the above comments but I cannot find a solution to this.
It was working just fine until today and nothing that I know changed...

@ejlocop
Copy link

ejlocop commented Nov 16, 2020

I'm not sure if this is a related issue or not.

image

@chiribuc
Copy link

I checked my /etc/resolv.conf and I remembered that i have IPV6 from my IPS.
If I change the order in the resolv.conf (set the IPV6 last) I don't receive an error anymore but the domain generated by expose it's not reachable from outside.

@chiribuc
Copy link

chiribuc commented Nov 16, 2020

@ejlocop

I'm not sure if this is a related issue or not.

image

I had this error when I tried to set 8.8.8.8 in my /etc/resolv.conf file

@chiribuc
Copy link

I checked my /etc/resolv.conf and I remembered that i have IPV6 from my IPS.
If I change the order in the resolv.conf (set the IPV6 last) I don't receive an error anymore but the domain generated by expose it's not reachable from outside.

Now its back with the error...

Could not connect to the server.
Connection to tls://sharedwithexpose.com:443 timed out after 20 seconds

@chiribuc
Copy link

Yes...IPv6 is the problem.
I disabled it from my router and it works now but I don't like it. :)

@michaeldyrynda
Copy link

Can confirm disabling IPv6 resolves this :(

@mpociot
Copy link
Member

mpociot commented Nov 17, 2020

Can someone help me reproduce this?

My /etc/resolv.conf looks like this:

nameserver 2001:4860:4860::8888

So it's using an IPv6 DNS, but I'm still able to connect to Expose.

It would be great if someone with this issue could try the following:

git clone git@github.com:beyondcode/expose.git

cd expose

composer update

./expose share my-local-site.test

This updates the internal ReactPHP component dependencies, so maybe this fixes it for you? As I can't verify the fix, I could use some help.

@chiribuc
Copy link

chiribuc commented Nov 17, 2020

Can someone help me reproduce this?

My /etc/resolv.conf looks like this:

nameserver 2001:4860:4860::8888

So it's using an IPv6 DNS, but I'm still able to connect to Expose.

It would be great if someone with this issue could try the following:

git clone git@github.com:beyondcode/expose.git

cd expose

composer update

./expose share my-local-site.test

This updates the internal ReactPHP component dependencies, so maybe this fixes it for you? As I can't verify the fix, I could use some help.

I tested but it gives me the same error:

Could not connect to the server.
Connection to sharedwithexpose.com:443 failed during DNS lookup: DNS query for sharedwithexpose.com failed: Unable to connect to DNS server (php_network_getaddresses: gethostbyname failed. errno=0)

@chiribuc
Copy link

chiribuc commented Nov 17, 2020

If I change the order of DNS and set the IPv6 to be the last in the /etc/resolv.conf than it works.
So from this:

nameserver IPv6
nameserver IPv6
nameserver IPv6

nameserver IPv4
nameserver IPv4
nameserver IPv4

to this:

nameserver IPv4
nameserver IPv4
nameserver IPv4

nameserver IPv6
nameserver IPv6
nameserver IPv6

@dakira
Copy link
Contributor

dakira commented Nov 24, 2020

@mpociot It's actually only not working when IPv6 or DNS over IPv6 is improperly configured, be it by the user or more probably the ISP. At that point the problem I discussed above with @clue kicks in. ReactPHP doesn't try a second DNS server if the first doesn't work (while the OS does and people don't notice their IPv6 DNS config is borked).

Just my wild guess after doing some testing on this..

@clue
Copy link

clue commented Dec 3, 2020

TLDR: Send a couple of sponsors my way (https://github.com/sponsors/clue) and I'm happy to solve this. 💸

This requires a feature addition in @reactphp which Expose builds on top of. Expose does not need any changes once this is built into @reactphp. :shipit:


Here's a recap of what's going on:

  • This only affects users that have multiple DNS servers and their primary DNS server is invalid (not reachable, not responsive etc.)
  • This happens irrespective of whether you're using IPv4 or IPv6 (either works just fine!)
  • Having multiple DNS servers is more common in dual stack setups, hence why this seems to be linked to IPv6
  • This can be easily worked around by making sure the very first nameserver entry in your /etc/resolv.conf is valid (see above: DNS error #25 (comment))
  • This can be easily reproduced by adding an invalid nameserver entry in your /etc/resolv.conf at the very top
  • An invalid nameserver entry should not cause this error when other nameserver entries are valid (this requires work, see below)

Here's what needs to be implemented in @reactphp to make sure this error no longer shows up even when people have invalid nameserver entries:

  • Done: The DNS component already supports parsing multiple nameserver entries into a Config object
  • The DNS component needs to accept multiple DNS servers (limited to one address at the moment, use Config instead of a string)
  • The DNS component needs a new "DNS executor" which accepts two executors and triggers the second one only if the first one fails
  • The DNS component needs to wire up a stack of fallback executors when more than one nameserver is given in the Config
  • The DNS component needs to be tagged in order for other component to depend on this new feature
  • Done: The Socket component already parses all nameserver entries into a Config object
  • The Socket component needs to pass the complete Config object instead of only its first nameserver entry to the DNS component (requires new DNS tag)
  • The Socket component needs to be tagged in order for other component to depend on this new feature
  • The Datagram component needs to pass the complete Config object instead of only its first nameserver entry to the DNS component (requires new DNS tag)
  • The Datagram component needs to be tagged in order for other component to depend on this new feature
  • Expose needs to be updated to require the new Socket component (requires new Socket tag), the DNS implementation is entirely opaque, no other changes whatsoever are required

As you can see, this is a non-trivial amount of work. I've layed out this plan to show this is very much actionable and could be solved in a couple of days.

As much as I'd love to work on this, I won't be able to commit to this right now: I'm rather busy working on a bunch of others projects at the moment.

Perhaps we can find a couple of new GitHub sponsors to allow me spending some time on this?

Put your money where your mouth is? 💸

@ondrejmirtes
Copy link

@clue BTW I had the same problem in PHPStan Pro and I solved it by hardcoding the DNS server to 1.1.1.1 for everyone. Can you think of any downside with this approach? Do you think that someone can have this server blocked by their corporate firewall or something?

@clue
Copy link

clue commented Dec 4, 2020

@ondrejmirtes Yes, this can be problematic. Hard-coding a public DNS server as the primary DNS server might be an option for some use cases (which is why this is indeed supported by @reactphp). This was briefly discussed in #25 (comment):

Adding explicit DNS configuration options could be useful in some more advanced scenarios, but this probably shouldn't be the default. In particular, Expose should not override the system settings by default because the system DNS configuration could configure a company-internal DNS server which resolves different addresses than a publicly available one such as Couldflare's or Google's (let alone possible privacy implications).

As per #25 (comment), some public DNS servers are also blocked in some more restrictive legislations (think country-wide blocks / firewalls implemented at the DNS level).

From a developer's perspective, I think this could perhaps be the more important reason why DNS fallback servers should be supported in ReactPHP itself:

@mpociot I don't agree that Expose should have explicit DNS configuration by default. Any application should take advantage of the system configuration and just work. If your ping command works, so should Expose. If your ping command works and Expose doesn't work, then something is broken (could be a missing feature in the underlying DNS component).

@ondrejmirtes
Copy link

@clue I see, it's funny how me and @mpociot had the same train of thought - I planned that if it turned out that 1.1.1.1 didn't work for everybody, I'd make the DNS configurable in PHPStan :D

I'm kind of used to that people's systems are broken in all kinds of ways, so it's better not to rely on it. For example in one instance the client crashed because the user had some non-sense in the memory_limit setting in php.ini, PHP silently ignores it, but some piece of code that tries to parse it throws an exception.

But I'll trust you on this one :)

@WyriHaximus
Copy link

WyriHaximus commented Dec 4, 2020

Here's what needs to be implemented in @reactphp to make sure this error no longer shows up even when people have invalid nameserver entries:

  • Done: The DNS component already supports parsing multiple nameserver entries into a Config object
  • The DNS component needs to accept multiple DNS servers (limited to one address at the moment, use Config instead of a string)
  • The DNS component needs a new "DNS executor" which accepts two executors and triggers the second one only if the first one fails
  • The DNS component needs to wire up a stack of fallback executors when more than one nameserver is given in the Config
  • The DNS component needs to be tagged in order for other component to depend on this new feature
  • Done: The Socket component already parses all nameserver entries into a Config object
  • The Socket component needs to pass the complete Config object instead of only its first nameserver entry to the DNS component (requires new DNS tag)
  • The Socket component needs to be tagged in order for other component to depend on this new feature
  • The Datagram component needs to pass the complete Config object instead of only its first nameserver entry to the DNS component (requires new DNS tag)
  • The Datagram component needs to be tagged in order for other component to depend on this new feature
  • Expose needs to be updated to require the new Socket component (requires new Socket tag), the DNS implementation is entirely opaque, no other changes whatsoever are required

@clue Do we have issues for all of this on the respected @reactphp repositories for tracking?

P.S. I'd be happy to pick those up, but it's not super high on my own priority list, like @clue says a one or more sponsors can help with that.

@simondavies
Copy link

I got the following error as others

Connection to sharedwithexpose.com:443 failed during DNS lookup:

Then looking through the above i did the following as others recommended @chiribuc thanks

edit my etc/resolv.conf and switched the IPv4 and IPv6 around.

nameserver 0000::0000:0000:0000:0000
nameserver 192.168.1.??

to

nameserver 192.168.1.??
nameserver 0000::0000:0000:0000:0000

and all run ok.

@fahmiegerton
Copy link

I have face similar issue. It was working before (weeks ago) but now it doesn't work. Am i doing something wrong?
image

@izshreyansh
Copy link

Using 1.1.1.1 definitely fix this issue.

@mpociot mpociot closed this as completed Jun 8, 2021
@beyondcode beyondcode locked and limited conversation to collaborators Jun 8, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests