Blocking/redirecting port 3000 with Nginx and Ruby On Rails (thin server)

Cort3z asked:

I am setting up a server now that uses Ruby on Rails with the Thin server.

I have set up Nginx to redirect all of my http://mysite.com to https://mysite.com(with ssl). I want all network traffic to the page be SSL, no exceptions.

This works great, but what bothers me is that it is still possible to access my thin server without SSL if someone writes http://mysite.com:3000, which happens to be the port I am running my server on. (I actually got several servers on ports 3000, 3001…).

Is there a way to block this, or rewrite it to https://mysite.com like I do with port 80?

I tried duplicating what I do on port 80, but I get errors saying it is already in use.

This is my nginx config.

upstream mysite.com {
  server 127.0.0.1:3000;
  server 127.0.0.1:3001;
  server 127.0.0.1:3002;
}
##THIS WORKS:    
server {
      listen      80 default;
      server_name mysite.com *.mysite.com;
      ## redirect http to https ##
      return 301 https://mysite.com$request_uri;
}

##THIS FAILS with "Address already in use"
server {
      listen      3000;
      server_name mysite.com *.mysite.com;
      ## redirect http to https ##
      return 301 https://mysite.com$request_uri;
}
#This part works as expected
server {
  listen      443 ssl;
  server_name mysite.com www.mysite.com;

  ssl on;
  ssl_certificate     /home/sne/.ssl/server.crt;
  ssl_certificate_key /home/sne/.ssl/server.key;

  access_log /var/www/mysite.com/log/access.log;
  error_log  /var/www/mysite.com/log/error.log;
  root     /var/www/mysite.com;
  index    index.html;

  if ($host = 'www.mysite.com' ) {
    return 301 https://mysite.com$request_uri;
  }

  location / {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;
    proxy_set_header  X_FORWARDED_PROTO $scheme;
    proxy_redirect  off;
    try_files /system/maintenance.html $uri $uri/index.html $uri.html @ruby;
  }

  location @ruby {
    proxy_pass http://mysite.com;
  }
}

My answer:


Close port 3000 in your firewall.

Then make sure you start thin in such a way that it is bound only to the localhost. This absolutely prevents inbound connections not originating from the local machine itself.

For instance:

rails server -b ::1

Or the old IPv4 way:

rails server -b 127.0.0.1

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.