port 80 is accessible through localhost but the connection is refused externally

The domain name pointing to my droplet can’t be accessed at port 80, but 443 works: $ wget http://{my ip} –2016-02-22 23:33:51-- http://{my ip}/ Connecting to {my ip}… failed: Connection refused. $ wget https://{my ip} –2016-02-22 23:34:09-- https://{my ip}/ Connecting to {my ip}:443… connected.

In the droplet itself, I can access port 80 (where the web server redirects to 443) $ wget http://localhost –2016-02-23 02:35:29-- http://localhost/ Resolving localhost (localhost)… Connecting to localhost (localhost)||:80… connected. HTTP request sent, awaiting response… 301 Moved Permanently Location: https://localhost/ [following] –2016-02-23 02:35:29-- https://localhost/ Connecting to localhost (localhost)||:443… connected.

The server itself is a Play Framework server which listens on both port 80 and 443 using authbind, running as an unprivileged user. (both with IPv6) $ authbind --deep myserver -Dhttp.port=80 -Dhttps.port=443 … [info] - play.api.Play - Application started (Prod) [info] - play.core.server.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:80 [info] - play.core.server.NettyServer - Listening for HTTPS on port /0:0:0:0:0:0:0:0:443

It is basically a vanilla Ubuntu 15.10 x32 droplet. Is there some obvious place to look for configuration problems? I would just like to keep the networking simple and serve directly from port 80, and it’s hard to determine what is stopping me from doing so.


@gracenotes - OK, I think I understand the problem. Somewhere in your configuration, you are redirecting traffic to “localhost:443” instead of “yourIPorDomain:443”. You need to find where you define that.

One thing is what the program itself says it’s listening on. Another thing is what it’s actually listening on. Double check that you are actually bound to the correct interfaces by looking at netstat -nlp.

I’m going to guess that it’s just listening on port 80 for localhost, and that is why you’re not able to connect from the outside. Could be that the port was bound by another process or just an old authbind process that for some reason failed to shut down completely.

@gndo - ah, I see what you mean! There is HTTP -> HTTPS redirect, but I wrote it myself, and all it does it change the URL scheme and nothing else. It has to go through a routing file in my server (i.e. start a normal request/response cycle) before it aborts the request and adds the Location header in the response.

I did see that doing this inside the droplet did work: $ wget --verbose -S <domain>:80 Connecting to <domain> (<domain>)|<ip>|:80… connected. HTTP request sent, awaiting response… HTTP/1.1 301 Moved Permanently Location: https://<domain>/ … <subsequent successful fetch of page over HTTPS>

ifconfig shows that eth0 is bound to the resolved IP address, so the HTTP request doesn’t have to go very far to get that redirect response. Meanwhile, no requests initiated from my home network will produce any response at port 80, or actually any port except 443 or 22! (Except if I start the server at a high port, like port 9000, I can connect to it over plain HTTP.)

@gracenotes - no problem with the delay. The output “…: Connection refused.” confirms that there is an entity listening at external port 80. One possible reason for the rejection is that it is redirecting port 80 explicitly to “localhost:443” instead of “yourDomain:443”, which would explain why it works from your droplet but not externally.
Another possible reason for the rejection is that some security info is not being carried over to requests over port 80. A quick googling shows me a configuration value of “” would allow this security info to be stored in a session cookie for both ports. I didn’t recommend this since you were able to access both ports locally on your droplet.

@gndo: sorry for delay. The website is all set up (and running on HTTPS successfully for a week or so now), it seems like the port is just not going through/listening externally. $ wget --verbose <domain> –2016-03-06 21:13:53-- http://<domain>/ Resolving <domain>… <ip> Connecting to <domain>|<ip>|:80… failed: Connection refused.

This happens pretty much immediately.

@gracenotes - Ignore my last question, I am starting to see the problem now. Your http site is redirecting to your https site, and for some reason the security handshake is failing.

@gracenotes - when you ran wget with “–verbose”, did it hang (connection timeout) or did it say “connect” at some point and then a http response code that is not 200?

wget --verbose http://yourIPorDomain:80

@gndo: does not look like it at the moment, $ sudo ufw status verbose Status: inactive

@gracenotes - Do you have the firewall up?

ufw status verbose

Thanks for the help! Everything looks normal in netstat: Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp6 0 0 :::443 :::* LISTEN 11337/java
tcp6 0 0 :::80 :::* LISTEN 11337/java

And lsof matches as well: $ lsof -i :80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 11337 mgruen 136u IPv6 268554 0t0 TCP *:http (LISTEN)

Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

@gracenotes - On your server, try modifying and trying the following before starting your authbind command:

touch /etc/authbind/byaddr/${MYINET},80
chown ${PLAYUSERNAME} /etc/authbind/byaddr/${MYINET},80
chmod 755 /etc/authbind/byaddr/${MYINET},80