Prev |  | Next

## 24.1. Securing access to the Neo4j Server

### 24.1.1. Secure the port and remote client connection accepts

By default, the Neo4j Server is bundled with a Web server that binds to host `localhost` on port `7474`, answering only requests from the local machine.

This is configured in the `conf/neo4j-server.properties` file:

    # http port (for all data, administrative, and UI access)
    org.neo4j.server.webserver.port=7474

    #let the webserver only listen on the specified IP. Default
    #is localhost (only accept local connections). Uncomment to allow
    #any connection.
    #org.neo4j.server.webserver.address=0.0.0.0

If you need to enable access from external hosts, configure the Web server in the `conf/neo4j-server.properties` by setting the property `org.neo4j.server.webserver.address=0.0.0.0` to enable access from any host.

### 24.1.2. Arbitrary code execution

By default, the Neo4j Server comes with some places where arbitrary code code execution can happen. These are the Section 18.18, “Gremlin Plugin” and the Section 18.13, “Traversals” REST endpoints. To secure these, either disable them completely by removing the offending plugins from the server classpath, or secure access to these URLs through proxies or Authorization Rules. Also, the Java Security Manager can be used to secure parts of the codebase.

### 24.1.3. HTTPS support

The Neo4j server includes built in support for SSL encrypted communication over HTTPS. The first time the server starts, it automatically generates a self-signed ssl certificate and a private key. Because the certificate is self signed, it is not safe to rely on for production use, instead, you should provide your own key and certificate for the server to use.

To provide your own key and certificate, replace the generated key and certificate, or change the neo4j-server.properties file to set the location of your certififacate and key:

    # Certificate location (auto generated if the file does not exist)
    org.neo4j.server.webserver.https.cert.location=ssl/snakeoil.cert

    # Private key location (auto generated if the file does not exist)
    org.neo4j.server.webserver.https.key.location=ssl/snakeoil.key

Note that the key should be unencrypted. Make sure you set correct permissions to the private key, so that only the neo4j server user can read/write it.

You can set what port the https connector should bind to in the same configuration file, as well as turn https off:

    # Turn https-support on/off
    org.neo4j.server.webserver.https.enabled=true

    # https port (for all data, administrative, and UI access)
    org.neo4j.server.webserver.https.port=443

### 24.1.4. Server Authorization Rules

Administrators may require more fine-grained security policies in addition to IP-level restrictions on the Web server. Neo4j server supports administrators in allowing or disallowing access the specific aspects of the database based on credentials that users or applications provide.

To facilitate domain-specific authorization policies in Neo4j Server, SecurityRules can be implemented and registered with the server. This makes scenarios like user and role based security and authentication against external lookup services possible.

#### Enforcing Server Authorization Rules

In this example, a (dummy) failing security rule is registered to deny access to all URIs to the server by listing the rules class in neo4j-server.properties:

    org.neo4j.server.rest.security_rules=my.rules.PermanentlyFailingSecurityRule

with the rule source code of:

    public class PermanentlyFailingSecurityRule implements SecurityRule
    {

        public static final String REALM = "WallyWorld"; // as per RFC2617 :-)

        @Override
        public boolean isAuthorized( HttpServletRequest request )
        {
            return false; // always fails - a production implementation performs
                          // deployment-specific authorization logic here
        }

        @Override
        public String forUriPath()
        {
            return "/*";
        }

        @Override
        public String wwwAuthenticateHeader()
        {
            return SecurityFilter.basicAuthenticationResponse(REALM);
        }
    }

With this rule registered, any access to the server will be denied. In a production-quality implementation the rule will likely lookup credentials/claims in a 3rd party directory service (e.g. LDAP) or in a local database of authorized users.

Example request

- `POST` `http://localhost:7474/db/data/node`
- `Accept:` `application/json`

Example response

- `401:` `Unauthorized`
- `WWW-Authenticate:` `Basic realm="WallyWorld"`

#### Using Wildcards to Target Security Rules

In this example, a (dummy) failing security rule is registered to deny access to all URIs to the server by listing the rule(s) class(es) in `neo4j-server.properties` In this case, the rule is registered using a wildcard URI path (where * characters can be used to signify any part of the path). For example `/users*` means the rule will be bound to any resources under the `/users` root path. Similarly `/users*type*` will bind the rule to resources matching the URIs like `/users/fred/type/premium`

    org.neo4j.server.rest.security_rules=my.rules.PermanentlyFailingSecurityRuleWithWildcardPath

with the rule source code of:

    public String forUriPath()
    {
        return "/protected/*";
    }

With this rule registered, any access to the server will be denied. Using wildcards allows flexible targeting of security rules to arbitrary parts of the server’s API, including any unmanaged extensions or managed plugins that have been registered.

Example request

- `GET` `http://localhost:7474/protected/wildcard_replacement/x/y/z/something/else/more_wildcard_replacement/a/b/c/final/bit/more/stuff`
- `Accept:` `text/plain`

Example response

- `401:` `Unauthorized`
- `WWW-Authenticate:` `Basic realm="WallyWorld"`

### 24.1.5. Hosted Scripting

| Important
The neo4j server exposes remote scripting functionality by default that allow full access to the underlying system. Exposing your server without implementing a security layer poses a substantial security vulnerability.

### 24.1.6. Security in Depth

Although the Neo4j server has a number of security features built-in (see the above chapters), for sensitive deployments it is often sensible to front against the outside world it with a proxy like Apache `mod_proxy` [3].

This provides a number of advantages:

- Control access to the Neo4j server to specific IP addresses, URL patterns and IP ranges. This can be used to make for instance only the `/db/data` namespace accessible to non-local clients, while the `/db/admin` URLs only respond to a specific IP address.

      <Proxy *>
        Order Deny,Allow
        Deny from all
        Allow from 192.168.0
      </Proxy>

While equivalent functionality can be implemented with Neo4j’s `SecurityRule` plugins (see above), for operations professionals configuring servers like Apache is often preferable to developing plugins. However it should be noted that where both approaches are used, they will work harmoniously providing the behavior is consistent across proxy server and `SecurityRule` plugins.

- Run Neo4j Server as a non-root user on a Linux/Unix system on a port < 1000 (e.g. port 80) using

      ProxyPass /neo4jdb/data http://localhost:7474/db/data
      ProxyPassReverse /neo4jdb/data http://localhost:7474/db/data

- Simple load balancing in a clustered environment to load-balance read load using the Apache `mod_proxy_balancer` [4] plugin

      <Proxy balancer://mycluster>
      BalancerMember http://192.168.1.50:80
      BalancerMember http://192.168.1.51:80
      </Proxy>
      ProxyPass /test balancer://mycluster

### 24.1.7. Rewriting URLs with a Proxy installation

When installing Neo4j Server behind proxies, you need to enable rewriting of the JSON calls, otherwise they will point back to the servers own base URL (normally http://localhost:7474).

To do this, you can use Apache mod_substitute

    ProxyPass / http://localhost:7474/
    ProxyPassReverse / http://localhost:7474/
    <Location />
        AddOutputFilterByType SUBSTITUTE application/json
        AddOutputFilterByType SUBSTITUTE text/html
        Substitute s/localhost:7474/myproxy.example.com/n
        Substitute s/http/https/n
    </Location>

[3] http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

[4] http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html

Copyright © 2012 Neo Technology

Prev | Up | Next
| Home |