0.0.0.0 is not a valid destination ip, but it is one of common variations used when binding a listening socket to "all/any addresses", aka INADDR_ANY, or addr strings like ":8080", etc..
> Yes, I ment to navigate to 0.0.0.0 to test the jekyll generated website.
> That's where jekyll points me to (console output says
> "Server address: http://0.0.0.0:4000/" It works just fine on all browsers but
> the latest Chrome.
Yeah, that's really misleading output from jekyll.
My own tool outputs [1] something like this:
serving, available at:
http://localhost:8080/index.html
http://10.0.0.10:8080/index.html
Which are the two IPs that are reachable when I do http.ListenAndServe(":8080") in Go, and they're copy-pasteable into a browser without needing it to recognize invalid IPs.
It's sad they're going to "fix" this. From the comments, it seems the only reason to support navigating to 0.0.0.0 is because some people got used to using that and they're getting confused or don't want to change their habits. This is the kind of accumulating crud that makes web browsers the ugly monsters they are, but it's not even of the important type like supporting non-standards-compliant websites. Imagine how the world would be a slightly better place if the Chrome guys asked Firefox etc to stop supporting 0.0.0.0 too, then people will stop blaming the browser and change their behavior.
This has nothing to do with "accumulating crud", it's a trivial thing, there's probably less code needed to not treat 0.0.0.0 differently. Also, the amount of people who have ever typed 0.0.0.0 into a browser is so small that it is virtually irrelevant what they do, and whether there is consistency between browsers.
But this is treating 0.0.0.0 differently. Did you not read the bug report, or the comments here, or anything? 0.0.0.0 is not a valid address. In fact, navigating to 127.0.0.1 when 0.0.0.0 is given in the URL is neither expected nor desirable.
Ha, I remember back when I first had Jekyll tell me to browse to http://0.0.0.0:NNNN/ and thinking "This can't possibly be correct, certainly that's invalid. Oh, it worked."
Glad I wasn't losing my mind, but this certainly is something people use, I guess it should probably be allowed.
That said, I think a local server that's listening on all interfaces/addresses should probably feel confident to say "please open http://localhost:NNNN" I've definitely seen neophytes to various tech get anxious about numbers appearing where they expect a name, and it's less clear what 0.0.0.0 is, if maybe it's something special and different from the "localhost" they're accustomed to (because it is... at least in theory).
Imagine you are developing inside a VM but use the browser on the host OS to check the results. If the bind address was localhost then you would need to tunnel your connection from host to guest to be able to reach your server.
By binding to 0.0.0.0:PORT the guest OS will make your service available on all enabled interfaces:PORT combinations which, hopefully will "just work" in most use cases.
The right way for a server to do this is to listen on 0.0.0.0 and then examine the socket to see what address(es) it is listening on, and report a real address to the user. It's just laziness (or ignorance) to print 0.0.0.0.
That would account for the case where my local machine doesn't have a host entry for "localhost" but would break if I don't have an IPV4 loopback (if, say, I only have a IPV6 one).
Both of those are pretty odd cases, so I'm not sure how much they're worth worrying about.
I could be wrong, because networking is Not My Thing At All, Oh God, Make The Pain Stop, Why Does The Routing Table Have Bees In It, but shouldn't 127.0.0.0/8 be able to find the IPv6 loopback if the IPv4 one does not exist? Or am I misunderstanding yet another part of networking?
So, the point of localhost resolving to 127.0.0.1, is that it gives you a layer 3 address to route to the layer-1 loopback interface.
So... what interface does 0.0.0.0 resolve to? Is the loopback interface the default if a routing pattern match falls off the end of the route table? I really wouldn't expect that, given that the default of "no special subnet used" should end up routed out to the WAN.
My understanding, and it could be wrong, is that 0.0.0.0 doesn't resolve to anything--no host, no interface. It's not valid at all. RFC 1122 clearly notes it as a MUST NOT address except as the source address when trying to figure out your own IP address; any behavior that such a resolution triggers is probably an undefined behavior of the network stack (unless it's explicitly and in a nonstandard way being handled, which feels odd to me).
Probably because of new developers. The last time I tried developing something in Django, it said it was running a webserver on 0.0.0.0:3000 or something similar. My classmate actually punched that into a browser, and it worked.
It's better if it doesn't work, so that they have to learn that it's very different from listening on the loopback. Accommodating the mistake encourages security holes.
I'd guess most applications that accept it replace it with 127.0.0.1 or resolve localhost. 0.0.0.0 is not a valid IP address and should be rejected by the network stack if passed in directly.
Incidentally, most browsers support decimal notation as well as dotted quad notation for IPv4 addresses. So http://1249764297/ works to reach Google for example. Once this regression is fixed you should be able to use http://0:*/ rather than http://0.0.0.0:*/
I say loopback address, you say 127.0.0.1. But did you know we dedicate the entire 127/8 Class A to it? That's a lot of loopback!
Another 'while I'm at it' question I've had for a while. Say you have a micro-service bound to local loopback, you don't want remote code touching it. E.g. I think the BitTorrent Sync WebUI will provide the private keys to any local loopback connection. It can't possibly be secure though, right?
No reason it should be insecure (aside from the fact it's giving out the private keys at all). No network stack worth its salt is going to forward packets to 127/8 from outside, and while I often say routing is no substitute for firewalling, in this case there's an implicit firewall in the standards. It doesn't seem inherently any more dangerous than using a unix domain socket (still a socket), or a named pipe, or shared memory.
Actually, thought: can javascript running on a web page make AJAX requests to 127.0.0.1 and access this bittorrent sync thing? I'd think CORS would prevent it, but that might be a danger.
There's a trick of using DNS rebinding to bypass CORS and gain Javascript access to services on 127.0.0.1. Just another reason to make sure you check the Host header!
Yep. It's rather useful too. If you're simultaneously testing multiple services that expect to exclusively bind to a socket, you can set application a to listen on 127.0.0.1, and application b to 127.127.127.127. Beats stopping and restarting by a long shot.
Offhand, the BitTorrent Sync WebUI thing has a rather bad smell to it. There are ways to protect that info from getting out, but it's definitely suspect.
it seems like it could of been decided a lot earlier
who, when entering "http://*" would expect a search, and when entering "http://*.*.*.*:*" would still expect a search?
after that, it should let the lower levels respond with any error messages if there are (it is not the fault of firefox or chrome that it can be used as a destination address)
Entering the address of 'all zeros' should probably transparently redirect to localhost. (If you're listening on all addresses, that should be the one; it should probably be treated as equivalent to a 302 redirect. (IE it should educate the user that the provided URI is being handled as localhost.))
I'd also like a shorter notation for 'this is not a search' I think ending a word in / is probably good enough for that?
I don't understand this line of thinking. 0.0.0.0 is not a valid routable IP address. It doesn't go anywhere. Why should it be magically redirected into the 127 /8? I would think we should disabuse people of their wrong notions rather than start juggling edge cases about our network routing.
I mean, I'm not saying it should go to Google Search, it should just go to a no-host-found page.
Making these kind of exceptions leads to more people doing illegal things, and then it's hard to know if you're doing something right because browsers won't help you figure out that you're breaking rules. Which makes everything more confusing.
Listening on 0.0.0.0 is not the same as trying to navigate there. 0.0.0.0 (and [::]) are addresses reserved for listening on all interfaces; they are not routable IPs.
And? Did you read the thread? The complaint centered on trying to navigate to URLs that certain tools (e.g., Jekyll) tell users to hit. I was adding another example. (Looking over it again, I see that SimpleHTTPServer was actually mentioned, so that's my bad, but still.)
When used as a TCP destination address (on Linux at least), 0.0.0.0 is equivalent to 127.0.0.1, and :: is equivalent to ::1. The resulting connections will even pick 127.0.0.1/::1 as their source address, or fail to complete if no IPv4/IPv6 loopback address is configured.
There's also ::ffff:0.0.0.0 and ::ffff:127.0.0.1, which behave like their corresponding IPv4 addresses if IPV6_V6ONLY isn't enabled on the socket.
In any case, if you have server code that only listens on 0.0.0.0 (or ::ffff:0.0.0.0, if you're crazy), it's obsolete now because it's unable to accept IPv6 connections. A modern server should either listen on :: with IPV6_V6ONLY=0, or set IPV6_V6ONLY=1 and create two sockets listening on :: and 0.0.0.0.
One annoying thing about the socket API is that binding to loopback always requires two sockets, one for 127.0.0.1 (or ::ffff:127.0.0.1) and another for ::1.
And if you ever create a listen API that accepts "localhost:8080" as input, but only creates one socket for one address, then a pox on your house.
That's only on Linux though, and I consider it a bug.
The RFCs are quite clear that 0.0.0.0 is unroutable and cannot be connected to. Windows gets this right.
My own tool outputs [1] something like this:
Which are the two IPs that are reachable when I do http.ListenAndServe(":8080") in Go, and they're copy-pasteable into a browser without needing it to recognize invalid IPs.[1] https://github.com/shurcooL/cmd/blob/8d16351d1f01caca2ac65b9...
Yeah, that's really misleading output from jekyll.