Improved connector for Nginx proxy to Railo


Edit: This post is outdated. Please see this post https://kisdigital.wordpress.com/2013/03/04/my-final-nginxrailo-connector/

I have been working with Nginx quite a bit in the last week and I have had a little time to fine-tune my configuration a bit. Here is my stock Railo configuration. I have saved the settings to their own file and include the connector in each separate server configuration that requires Railo. This also remaps the standard Railo administrator to a more secure location and optionally sets basic authentication.

 # /etc/nginx/railo_connector.conf
 # Block default Railo admin
 if ($request_uri ~* ^/railo-context){
  return 404;
 }

 # Hide the Railo Administrator and optionally lock down with password
 location ~ ^/hardtoguesslocation/(.*)$ {
  #auth_basic $host;
  #auth_basic_user_file /path/to/htpasswd;
  if($request_uri ~^/railo-context/admin){
   return 404;
  }
  location ~^/hardtoguesslocation/{
   rewrite ^/hardtoguesslocation/(.*)$ /railo-context/admin/$1 last;
  }
 }

 # Main Railo proxy handler
 location ~ \.(cfm|cfml|cfc|jsp|cfr)(.*)$ {
  proxy_pass http://127.0.0.1:8888;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Real-IP $remote_addr;
 }

Also, Nginx allows you to use variables in your server configuration so it allows you to easily create a “catch all” virtual host. You can quickly add a new website just by adding it to your server.xml in Railo with no additional configuration required unless you require domain specific rewrites etc. Here is an example server configuration with a default virtual host and a separate domain configured:

server {
 #Catchall vhost
 listen    80; ## listen for ipv4
 server_name _;
 root /var/www/$host;
 index index.cfm;
 access_log  /var/logs/nginx/$host-access.log;
 # Do not log missing favicon.ico errors
 location = /favicon.ico { access_log off; log_not_found off; }
 # Do not serve any .hidden files
 location ~ /\. { access_log off; log_not_found off; deny all; }
 include /etc/nginx/railo_connector.conf;
# End of catch-all Server Configuration
}

server {
 #A domain with custom handling
 listen    80; ## listen for ipv4
 server_name mydomain.com www.mydomain.com;
 root /var/www/mydomain.com;
 index index.cfm;
 access_log  /var/logs/nginx/mydomain.com-access.log;
 # Do not log missing favicon.ico errors
 location = /favicon.ico { access_log off; log_not_found off; }
 # Do not serve any .hidden files
 location ~ /\. { access_log off; log_not_found off; deny all; }
 # Handle FW/1 style SES urls (i.e. http:/domain.com/main/default/key/value)
 location /{
  try_files $uri $uri/ @ses;
 }
 location @ses{
  rewrite ^/index.cfm/$uri last;
 }
 include /etc/nginx/railo_connector.conf;
# End of custom Server Configuration
}

If you want the X-Real-IP reported correctly on the Railo server you will also need to add the RemoteIP valve to your Tomcat configuration.

Overall Nginx makes a very nice front-end to Railo and as always I welcome any comments or suggestions to make it better.

Advertisements

11 thoughts on “Improved connector for Nginx proxy to Railo

  1. Good timing…I’m about to move my last cf applications off of an aging windows box to a linux vm. I’ve always wondered why the X-Real-IP didn’t seem to make any difference on my previous attempts at using it 🙂

  2. The SES rewrite isn’t that good. in general “if” conditions shouldn’t be used in nginx.
    So instead of this
    if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.cfm/$1 last;
    break;
    }

    I prefer this:
    # SES if file not exists
    location / {
    try_files $uri $uri/ @ses;
    }
    location @ses {
    rewrite ^ /index.cfm/$uri last;
    }

  3. Also blocking all request to “railo-context” isn’t really best practice 😉
    If you do that, the captcha image won’t be displayed. So i would block all request to “railo-context/admin” instead.

    This way you won’t block railos functionality.

    if ($request_uri ~ ^/railo-context/admin) {
    return 404;
    }
    location ~ ^/hardtoguess/ {
    rewrite ^/hardtoguess/(.*)$ /railo-context/admin/$1 last;
    }

  4. Where would the default catch all config go?

    Would I just create a standard mywebsite.com file in sites-available and use the catchall information in there?

  5. Interesting. I have done something like this:

    location /railo-context/admin {
    allow MYSERVERIP;
    deny all;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:8888;
    }

    I then set up an SSH tunnel to my server so my IP is the same as the one set there and access the railo-admin

  6. Thanks for this post.

    I like to include all the proxy_pass stuff rather than manage it per “server” block. This allows me to include it much easier in my re-write sections and railo-context/admin locations like below using something like

    #include proxy pass stuff to send request to TOMCAT
    include proxy_params;

    @stofke72 – I too prefer to setup a local SSH tunnel with with a virtual host that matches to up to an entry in my SERVER’s host file.

    For Example:

    server {
    listen 80;
    server_name mysite.com http://www.mysite.com mysite.railo;
    access_log /home/tim/sites/mysite.com/logs/access.log;
    error_log /home/tim/sites/mysitecom/logs/error.log;
    root /home/tim/sites/mysitecom/www;

    index index.cfm index.htm index.html index.cfml;

    …… more conf stuff here ….

    location /railo-context/admin/ {

    # include the external ip of the server or any other fixed ip
    # in order to prevent access to Railo Admin by others. Here it’s set
    # to server_ip so it can only be reached over with a connection over ssh
    # to the server.

    allow 127.0.0.1;
    deny all;

    # include all proxy related settings from the proxy_params file
    include proxy_params;
    }

    …. etc…

    }
    #end server block

    Then I make an entry like this on my server’s host file.

    ## RAILO ADMIN CONTEXT ACCESS ENTRIES
    127.0.0.1 mysite.railo

    This is so that when the SSH Tunnel passes the request to localhost:7822 or what not that gets sent over as mysite.railo to 127.0.0.1 address on the remote side. This in turn returns the web-context for this specific site. This is by far the best solution for securing the railo-context/admin directory that I have found.

    Now I can access: http://localhost:7822/railo-context/admin/web.cfm and manage my DSN’s and context settings as needed. Works great, but assumes you can make this hosts file entry on your own remote VPS.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s