Neo4j server security

So, till now we looked at how to configure a Neo4j server in order to obtain optimum performance. However, in a practical scenario, we also need to ensure that our database server is secure enough to handle confidential and critical data. In this section, we will look at some aspects of securing the Neo4j database server.

Port and remote connection security

When a Neo4j server is started, the default behavior is to bind the host to the localhost with the connection port as 7474. Hence only local requests from the same machine are serviced. You can configure this behavior in the conf/neo4j-server.properties file by uncommenting, adding, or modifying the following lines:

# 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

You can also restrict access to the database from only the machines(s) on which the application resides. So, only requests from this machine will be serviced. You can also provide open access (a security nightmare) by changing the incoming address to 0.0.0.0. The following setting is used for this:

org.neo4j.server.webserver.address=0.0.0.0

Support for HTTPS

There is built-in support for encrypted communication with SSL over HTTPS in a Neo4j server installation. A private key and a self-signed SSL certificate is generated when the server is initiated. In production scenarios, self-signed certificates are not reliable. Hence, you can configure your own certificates and keys. You can either replace the generated key and certificate with your own, or modify the conf/neo4j-server.properties file to change the location of the key and certificates:

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

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

You need to ensure that the key is encrypted and has the appropriate file permissions to enable read/write access for the server. There is also support for chained SSL certificates, where the certificates need to be merged in a single PEM file with the private key assuming the DER format. The option to enable/disable HTTPS support and define the port can be configured with these options:

# Support toggle for https: on/off
org.neo4j.server.webserver.https.enabled=true

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

Server authorization rules

Apart from restrictions at the IP level, more detailed security policies may be required for administrators. The authorization policies for the Neo4j server controls access to database aspects on the basis of user or application credentials. The security rules must first be registered with the server, making scenarios for external lookup and authentication on the basis of role possible. The detailed configuration for this is managed in the org.neo4j.server.rest.security.SecurityRule package.

Setup server authorization rules enforcement

Let us look at a scenario in which a security rule for failure is being registered for restriction of access to all the external URIs. This can be configured in the conf/neo4j-server.properties file:

org.neo4j.server.rest.security_rules=rule.CompleteRestrictionSecurityRule

The code for the CompleteRestrictionSecurityRule class can be defined in the following manner:

publicclassCompleteRestrictionSecurityRuleimplementsSecurityRule
{

publicstaticfinalStringMYREALM="MyApplication";

@Override
publicbooleanisAuthorized( HttpServletRequestrequest )
    {
returnfalse; // Forces failure always
// Logic for authorization coded here
    }

@Override
publicStringforUriPath()
    {
return"/*"; //For any incoming URI path
    }

@Override
publicStringwwwAuthenticateHeader()
    {
returnSecurityFilter.basicAuthenticationResponse(MYREALM);
    }
}

This rule restricts all types of access to the server from external locations. For a production scenario, you can configure the rule class to check for login credentials in order to authorize users to the application.

Sample request

POST http://localhost:7474/db/data/relationship/1
Accept:application/json; charset=UTF-8

Sample response

401:Unauthorized
WWW-Authenticate:Basic realm="MyApplication"

Security rules targeting with wildcards

Unlike the previous case, where all incoming requests are blocked, we can also target the restriction to some specific type of URIs with the use of wildcards. We need to register for this with a predefined wildcard URI path, with * specifying any section of the path. For example, /users* will block those requests that access the user root. In a similar fashion, the /users*type* expression refers to URIs accessing the type option for users like /users/mark/type/new.

You can use the defined CompleteRestrictionSecurityRule security rule class with a modification to the forUriPath method as follows:

publicStringforUriPath()
{
return"/secure/*";
}

This rule restricts only those requests that attempt to access the data under the /secure/ directory. So, with wildcards, you can flexibly control access to different parts of the server API.

Sample request

GET http://localhost:7474/secure/any/path/after/this/stuff
Accept:application/json; charset=UTF-8

Sample response

401:Unauthorized
WWW-Authenticate:Basic realm="MyApplication"

You can use multiple or a chain of wildcards in order to restrict a specific URI type or a pattern of URIs. Consider the case when the forUriPath() method is changed to take this form:

publicStringforUriPath()
    {
return"/protected/*/something/else/*/final/bit";
    }

The type of requests that this blocks are very specific and targeted in nature. An example of the type of request restricted is as follows:

Sample request

GET http://localhost:7474/protected/any/x/y/z/path/something/else/any/subpath/final/bit/anything
Accept:application/json; charset=UTF-8

Example response

401:Unauthorized
WWW-Authenticate:Basic realm="MyApplication"

Note

As a default behavior, the Neo4j server allows functionality for remote scripting, thereby allowing complete access to the underlying database instance from anywhere. This is better for development purposes. However, in production stages, allowing remote scripting is a potential high security risk, and you need to impose a sound security layer.

Other security options

Apart from the numerous security configurations discussed, for critical deployments it is wise to use an additional proxy similar to Apache's mod_proxy (http://httpd.apache.org/docs/2.2/mod/mod_proxy.html). This can provide access control to specific IPs, a range of IPs and even URI patterns. So you can essentially allow /db/data available to external clients while /db/admin/ can be made accessible from a specific IP. The configuration would look something like this:

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

The proxy server gives the same functionality as Neo4j's default SecurityRule feature and you can also use both together with proper non-conflicting configurations. However, admins often prefer Apache to the default Neo4j feature.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset