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

About Robert Zehnder

Web application developer specializing in ColdFusion/Railo and Open Source development.

Posted on August 22, 2011, in FW/1, nginx, Railo and tagged , , . Bookmark the permalink. 11 Comments.

  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.

  7. akismet-17d074bbbc883b7e7ca066a7be8b6582

    do you think a similar setup would work with Coldfusion?

  1. Pingback: Nginx connector for Railo/ACF part deux « KISDigital Blog

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

%d bloggers like this: