Running Neo4J Admin Console Behind a Reverse Proxy

Out of the box the Neo4J administration console is not secured, aside from the fact it only accepts connections from localhost by default. So if you are going to release your application into the wild you will need some way to secure it, and accept connections from other machines.

The ironically named 28.1.6. Security in Depth from the Neo4J reference manual is a little light on details, especially if you are not overly familiar with Apache.

Below I will describe how to set up an Apache reverse proxy with basic security to serve both your main application and the Neo4J admin console. Also I’ll discuss a work around for an outstanding bug with the admin console returning localhost:7474 in a JSON response that causes a problem when reverse proxying.

The following is for Apache 2.2 on Ubuntu, but should be easy enough to follow on different flavours or OS.

Complete Gist: https://gist.github.com/SmiddyPence/6499394

1) Install Apache.

a) See if Apache is already on your server. dpkg --get-selections | grep apache

b) If not update your repositories. apt-get update

c) Then install Apache. apt-get install apache2 apache2-utils

2) Enable proxy mod

a) Apache comes with the proxy mod by default, but it is not enabled. In your Apache install location ensure mods-available/proxy.conf looks like this:

<IfModule mod_proxy.c>  
    ProxyRequests Off
    <Proxy *>
        AddDefaultCharset off Order deny,allow Allow from all
    </Proxy>
    ProxyVia On
</IfModule>  

b) Enable both the proxy and proxyhttp modules. a2enmod proxy and a2enmod proxyhttp

c) Restart/Start the Apache service. service apache2 restart

3) Configure main web site VirtualHost entry.

a) Navigate to the sites-available folder in your apache install

b) Now create a file with the same name as your domain e.g. mydomain.com with the following content:

<VirtualHost *:80>  
    ServerName mydomain.com
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
    ErrorLog /var/www/mydomain.com/logs/error.log
</VirtualHost>  

There are a few things going on here, so lets just go over them:

The "*.80" means that this is the virtual host entry that is going to apply to the default http port.

The ServerName directive should be the name of your website.

The ProxyPass directive is indicating all requests "/" (appose to describing a sub folder) will map to the URL "http:localhost:8080/". This should be the context root of the application server that serves your main application.

The ProxyPassReverse directive rewrites request HTTP headers to return mydomain.com in place of the proxied servers localhost:8080.

The ErrorLog directive is pretty self explanatory, just make sure the path exists prior to restarting the server.

c) Add the following lines to your ports.conf if it is not already there.

NameVirtualHost *:80  
Listen 80  

d) Now enable your new site. a2ensite mydomain.com

e) Now apache reload

Checkpoint 1. Setting up hosting records with your registrar is beyond what I wanted to cover here, but assuming you have all that in place http://yourdomain.com; should now be serving your application server via apache. If it isn't, you should backtrack over the set up, before moving on to setting up access to the administration console (See additional guide section if necessary).

4) Configure Neo4J Admin Console VirtualHost entry.

a) Open up the mydomain.com site file again and create a second VirtualHost entry:

<VirtualHost *:7474>  
    ServerName mydomain.com
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass / http://localhost:7474/
    ProxyPassReverse / http://localhost:7474/
    ErrorLog /var/www/mydomain.com/logs/error.log
</VirtualHost>  

This is largely the same format as what we have seen before except we are now listening for requests on port 7474 and passing them onto localhost:7474. This is the default Neo4J Admin Console port, change it to your own configuration. If you want to restrict access to specific IPs change the "Allow from all".

b) Add the following lines to your ports.conf if it is not already there.

NameVirtualHost *:7474  
Listen *:7474  

c) Now "apache reload"

Checkpoint 2. Ok, so if we visit http://mydomain.com:7474 we should now see our administration console. There are two immediate problems: a) This is unsecure, b) if you click about it doesn't really work. So safety first, lets put some basic security it.

5) Applying Basic HTTP Security to the administration console.

a) Assuming you paid attention in step one you have already installed apache2-utils. If not do so now. apt-get install apache2-utils

b) Now we need to create a password file. htpasswd -cs /srv/auth/.htpasswd admin

"admin" is the username you want to authenticate with. (Omit -c if you already have a htpasswd file, -s uses SHA encryption; see documentation for others)

c) Enter passwords as prompted by htpasswd.

d) Add the following to the to the directive of the VirtualHost Entry for your admin console.

<Proxy *>  
    ...
    AuthType Basic
    AuthUserFile /srv/auth/.htpasswd
    AuthName "Login:"
    Require valid-user
    ...
</Proxy>  

e) "apache2 reload"

Those four lines are pretty self explanatory. Make sure if you chose a different path or file name for your password file it is updated accordingly. AuthName, just indicates what to display in the modal dialogue.

Checkpoint 3. Now if we visit our admin console URL, we should have a rudimentary modal login.

Although we have configured a reverse proxy that takes care of HTTP header information. The Neo4J console also returns URL information in JSON responses. Therefore you have probably noticed, clicking on the tabs does not work. If you’re a curious sort, enable FireBug and you will see one of the responses from the Server e.g. "/?_=1382426716662" has the body:

{
  "management" : "http://localhost:7474/db/manage/",
  "data" : "http://localhost:7474/db/data/"
}

This is no good to us any more, so we are going to use the Apache Substitute mod to rewrite this also.

6) Work around for Neo4J Admin Console behind reverse proxy.

a) Check your Apache mods-enabled and if substitute is not mentioned, enable it. a2enmod substitute

b) Add the following to the to the element of the VirtualHost Entry for your admin console.

<Proxy *>  
    ...
    AddOutputFilterByType SUBSTITUTE application/json
    Substitute "s|http://localhost:7474/db/manage|http://mydomain.com:7474/db/manage|i"
    Substitute "s|http://localhost:7474/db/data|http://mydomain.com:7474/db/data|i"
    ...
</Proxy>  

So the first line, is apply the rule to responses with the MIME type application/json. Then there are two separate rules that look for the first URL and replace it with the second.

c) "apache reload"

Done. You should now be able to use you admin console. Some of the images like the search magnifying glass will still be missing; but this should get you through to a patch.

Additional guides:

Installing Apache, Apache Proxy Module, Configuring Multiple Virtual Hosts, Connecting to tomcat using it's AJP protocal, Configure Authentication Module, Configure Substitution Module

Miscellaneous Shenanigans

Set file access limits, FileSystemPreference Bug, Exception for Web Admin static files

comments powered by Disqus