Discussion/Proposal: Default to 0.0.0.0 for listening IP range in Vapor 4

Currently in Vapor 3, the app boots up listening to connections on 127.0.0.1. Whilst this is fine for development locally, there are numerous Discord/Stackoverflow/forums posts about not being able to access it when deployed/from a phone when testing. The original reason for this was security to lock it down by default.

Whilst I agree with the intentions, I think this has made it harder to get started and proved a common stumbling block for new users of Vapor. In Vapor 4, I propose we default to 0.0.0.0 to allow connections for all IP addresses. There is a small security downside (though for a web server framework this is more of an edge case than the normal use case) and this should really be handled in security groups/firewalls instead.

Thoughts?

Agreed, think it'd be really helpful to avoid confusion, and even if you do know what/why it does, it'd save you the extra steps of setting the app to listen on 0.0.0.0 when needed.

+1. I'd love to find the original discussion. IIRC it was in a vapor/vapor issue, but I can't find it--it may have been lost to Slack's paywall. Either way, I think 0.0.0.0 makes sense as a default. It might be worth doing a bit of research first to see what other popular web frameworks do just to be sure.

Didn't we have something the saved all the messages automatically? Maybe it is somewhere in there?

Personally I think when it comes to security versus convenience, go with security. It's only a command line option away from making it listen on 0.0.0.0 and then you are knowingly opening the app in development up to anybody on the same network as you.

5 Likes

I think i'm with monagle on this one. However, this does seem like a great opportunity to improve the vapor docs by mentioning this feature (I didn't find it in the docs quickly skimming).

2 Likes

This isn't my project, so take this as the random drive-by that it is, but I agree with listening to 127.0.0.1 by default rather than 0.0.0.0. It is inevitable that some of your users will be server-side novices (or just poorly informed about security) and will not really understand this. I would strongly encourage you to have a webpage somewhere that explains why it's not good practice for most servers to listen to 0.0.0.0 and then talks about the best way to fix this, including points that you might consider higher-level, like how to lock down a server so that it only accepts connections from specific external IPs. You can then link that from Stack Overflow, Reddit, Twitter, blog posts, etc., so that when people Google their problem, they'll find your page.

13 Likes

Having publicly exposed services when not expected is bad, not giving an administrator the ability to bind to specific interfaces/networks is bad, but I've never been sure why (and have never seen justification why) running a service you are making available to the internet (like say http or imap) bind to IP_ANY.

For production, it's fine and good to expect an administrator to think about this for a few seconds when setting up the deployment. For devs, binding to localhost only is the right default so you don't end up with a half-baked debug build accepting public connections in a coffeeshop.

-1 along with the suggestion of having it documented how to expose Vapor apps if really wanted.

Defaulting to 0.0.0.0 is what caused major security issues with redis. They even had to introduced special mode to mitigate the issue. Note the first sentence that is the heart of the problem.

Protected mode

Unfortunately many users fail to protect Redis instances from being accessed from external networks. Many instances are simply left exposed on the internet with public IPs. For this reasons since version 3.2.0, when Redis is executed with the default configuration (binding all the interfaces) and without any password in order to access it, it enters a special mode called protected mode . In this mode Redis only replies to queries from the loopback interfaces, and reply to other clients connecting from other addresses with an error, explaining what is happening and how to configure Redis properly.

We expect protected mode to seriously decrease the security issues caused by unprotected Redis instances executed without proper administration, however the system administrator can still ignore the error given by Redis and just disable protected mode or manually bind all the interfaces.

2 Likes

I wouldn’t listen on 0.0.0.0 by default. People start dev servers all the time and then forget about them. And many of those will probably run with docker images without a dedicated user. Better not leave those doors open by default.

2 Likes

Stumbled across this thread. As 0xTim says in the beginning of the thread, I as a new user got stuck on this for a considerable amount of time.

Because I develop on RHEL and the binaries are not available for my OS, I am forced to use an Ubuntu container. Following the documentation gets me stuck at being unable to access the hello world page from the container host.

Personally I do not see the problem with defaulting to 0.0.0.0 because I do not open the assigned port on the firewall anyway and the app would be served to outside the network by a lighttpd web server reverse proxy.

A workstation and development environment on linux comes with at least a firewall. Access control is also tight with SELinux.

If 127.0.0.1 is kept default for the next versions it should be mentioned in the documentation at least, in order to reduce frustration to new users.

1 Like