Site is accessible on the IP address when not following th install guide

For security, I think it would be better if by default Discourse forums aren’t visible when navigating directly to the IP address in a browser.

A couple of reasons:

  • Allows use of site without HTTPs, for users and also the initial configuration by the admin.
  • Leaks origin server address, which is bad if you’re using cloudflare or similar to protect your origin IP from ddos attacks or server hacking attempts, if the hackers deem the server to be of high value. There are people out there running bots scanning all IP ranges owned by webhosts.

Also, the discourse installer now confirms that the domain/subdomain is configured properly or it won’t continue with the install.

All that needs to be added to the very bottom of the /etc/nginx/conf.d/discourse.conf file (inside the docker container) is:

server {
    listen 80;
    server_tokens off;
    return 404;

Where is your server’s public IP address. There is probably a more elegant way to include the IP address than hard coding it. I tried a couple but couldn’t get them working.

Works well for me (including with cloudflare proxying), I can’t think of many cases where allowing web access directly on the IP would be useful or necessary. It seems like fairly common practice to disallow this. Happy to hear any reasons not to do this though!

1 Like

Why do any change when our default guide leaves you with a working HTTPS-only site?

People with special needs can go and hack around, but our default will stay as it is, defaulting to working domain name and HTTPS.


Thank you very much!

1 Like

Speaking objectively, this isn’t accurate. It’s not https only, as you can access the site directly via the IP address that isn’t https.

The difference is disallowing connecting insecurely without https and exposing the server origin IP. I’m unaware of any benefits to that.

If you DNS look up the top 50 sites in the world, it looks like none of them are accessible insecurely directly via the IP. I don’t think it is unreasonable to assume that the top 50 sites in the world are using best practices.

Here is a quite accurate top list:

Here is a DNS lookup tool:

Out of the box, trying to access via IP will return with a 301 Redirect to the correct domain:

$ curl -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.1
Date: Mon, 29 Jun 2020 20:24:41 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive


Is your proposal to change from a 301 to a 404?


8 out of 8 installs, installed using the digital ocean image, discoursehosting installed (then migrated) as well as manually using this guide discourse/ at master · discourse/discourse · GitHub all are accessible insecurely via IP by default. Two of them were installed in the last week (using the github guide above.).

Is there maybe an extra step for that I’m missing? I’d say a 404 is better than a 301, seeing probably most people snooping around the IP addresses aren’t up to any good. But a 301 is better than insecure access.

No repro… correctly redirects me to


Hmmm, maybe it’s the cloudflare template. That’s probably the only consistent difference to a totally vanilla install between all of them.

1 Like

If you’re taken steps which aren’t listed in the cloud install it isn’t by definition a “vanilla install”.

The Cloudflare template doesn’t do anything obvious to interfere with a redirect:

  - file:
      path: /tmp/add-cloudflare-ips
      chmod: +x
      contents: |
        #!/bin/bash -e
        # Download list of CloudFlare ips
        wget -O - > /tmp/cloudflare-ips
        wget -O - >> /tmp/cloudflare-ips
        # Make into nginx commands and escape for inclusion into sed append command
        CONTENTS=$(</tmp/cloudflare-ips sed 's/^/set_real_ip_from /' | sed 's/$/;/' | tr '\n' '\\' | sed 's/\\/\\n/g')
        echo CloudFlare IPs:
        echo $(echo | sed "/^/a $CONTENTS")
        # Insert into discourse.conf
        sed -i "/sendfile on;/a $CONTENTS\nreal_ip_header CF-Connecting-IP;" /etc/nginx/conf.d/discourse.conf
        # Clean up
        rm /tmp/cloudflare-ips

  - exec: "/tmp/add-cloudflare-ips"
  - exec: "rm /tmp/add-cloudflare-ips"

It grabs the IP ranges, stored temporarily as cloudflare-ips and adds support for CF-Connecting-IP


Right. I didn’t claim them to be “vanilla installs”.

So I tested removing the official cloudflare template on one of them then rebuilding, unfortunately didn’t make a difference. Still accessible insecurely via IP.

Can’t really think of anything else out of the ordinary between those installs. The only plugins on that instance were the default included docker manager and the official ad plugin. It’s on the stable branch, but the other sites that also behave the same are on a mix of stable, beta and tests-passed.

Not specific to any configuration, or cloudflare, just another datapoint and viewpoint:

We can set up a proxy to redirect a “naked IP address on port 80” (as an example) to any other FQDN a number of ways with both apache2 and nginx.

There are many ways to do this (rewrite and redirect, virtual host and redirect, etc).

For example, we can create a virtual host on a reverse proxy with the reverse proxy listening on the IP address on port 80, and redirect all those requests to any FQDN (or IP address) we choose.

We can also do this with a reverse proxy using mod_rewrite in Apache2 and rewrite rules with ngnix.

For all of our Discourse setups (in operations), we have a reverse proxy in front of Discourse (some apache2, some nginx) and it’s easy to mitigate these kinds of problems (as they arise) by configuring the reverse proxy to handle these kinds of issues and special cases.

Having said that, I don’t use the special case of cloudflare as a proxy, but it would seem that any proxy would be configurable to manage these types of issues, just like any reverse proxy can be configured to redirect “just about anything to any other thing”.

Taking this a step further, if I was a commercial proxy user (like cloudflare) and had a particular IP address of domain name I wanted redirected (or blackholed), I would configure (or request) the proxy (in this case cloudflare) to redirect the "naked IP address on port 80) to the FQDN (or where ever) I choose.

This is the kind of thing proxies are designed to handle (by design); and as mentioned, this type of redirect is easy to do with apache2 or nginx, so I assume (not behing a cloudfare user) a commercial service like cloudfare can manage this type of trivial redirection with ease.


I use this for a site to direct the bots hitting it by raw IP to a special page:

server {
        listen 80;
        # listen [::]:80;

        server_name ~^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+;

        root /var/www/ip-address;
        default_type text/plain;
        index nothing.doing;
        location / {
                try_files $uri /nothing.doing;

BUT I’m with the others in saying I can’t reproduce access by IP for my private forum either. I get the redirect. And mine’s got no special configuration, no cloudflare, and is literally running a $0 per month virtual server that gives me no frills.


Bur if you think about it you might realize that they all have load balanced setups on an infrastructure costing (tens of) millions of dollars. So they’re not representative either.

Migrating does not copy any nginx settings so in fact that’s just a new install.


Great, thanks for sharing that snippet @elijah, appreciate it! I’ll swap out the hardcoded IP with your regex, or use the full snippet. :slight_smile:


Yes, that further eludes to those sites most likely not being usable on web via any direct IP. Anyhow, no one seems to be in support of allowing insecure direct IP access on web.

Yes, you’re right.

1 Like

I just tested launching 2 Discourse instances on Digital Ocean using their market place app to quickly launch them.

I wanted to test this with virtually zero custom configuration, just editing smtp, dev email and discourse_hostname with bogus details (to allow the rebuild).

The installer stops due to the bogus domain/subdomain I set not passing the domain validation step (and recommends editing the app.yml file manually then rebuilding).

After editing the app.yml and rebuilding (smtp, dev email, discourse_hostname only), the site is available insecurely on the IP address without any involvement of Cloudflare. It doesn’t redirect to the set discourse_hostname.

Most of my installs didn’t use the Digital Ocean market place app to set up, but were done manually using the standard docker install guide.

Note that, the installer stopping due to not being able to validate the domain also happened on two recent installs I did that used Cloudflare, probably because of the proxying. The other installs were done before there was a domain validation step in the installer.

edit: Note that only 2 of the 8 Discourse installs had any domain verification issue during the initial install (not including the two testing instances made above). The Discourse set up script suggests the user to edit the app.yml manually and rebuild on domain verification error. No problem if this isn’t useful though, this wasn’t a solution for myself.

edit: Generally using Cloudflare flexible SSL, not letsescrypt (which would be better). Thanks @neounix.

FYI @markersocial

All of our Discourse installs redirect the http://the.ip.add.res to the https://FQDN configured by enabled LETSENCRYPT in the .yml Discourse container file.

For all this to work property and for the LETSENCRYPT certs to work, you need a completely working SSL configuration (normally with LETSENCRYPT), as you surely know already.

Just a reminder… hope this helps.


Vanilla is having a valid domain and using the discourse setup script.

If you do neither, it is not unexpected for the result to be different.

This topic has no actionable information and we can’t repro if the instructions are followed.