Linux-UNIX: Neo4J auditing configuration
Use a double proxy together with either K-TAP or PCAP to capture encrypted Neo4J traffic.
About this task
This procedure requires two proxies of either NGINX or HAProxy type. Both must both be located on the database.
The first proxy instance terminates the SSL and adds a proxy protocol to ports 7687 and 7473. The second proxy instance listens to the intermediate ports (17687 and 17473) and removes the proxy protocol. K-TAP or PCAP intercepts the traffic between the two proxy instances. Outgoing decrypted traffic from Proxy2 is sent to unecrypted Neo4j database ports (27687, 7474).
Procedure
-
Configure the database. Neo4J advertises the ports it uses. The ports need to be changed to avoid conflicting with the proxy ports: Neo4J needs to have its port configuration changed and the proxy entry point ports need to be configured for advertising (requires version 3.5.0 or newer). In the neo4j configuration file: /home/neo4j/neo4j/conf/neo4j.conf, add/edit these lines. In this example the DB server is rh7u3x64t-ktap.databaseserver.
dbms.connector.bolt.listen_address=127.0.0.1:27687 dbms.connector.bolt.advertised_address=rh7u3x64t-ktap:7687 dbms.connector.http.listen_address=127.0.0.1:7474 dbms.connector.https.listen_address=127.0.0.1:27473 dbms.connector.https.advertised_address=rh7u3x64t-ktap:7473
- Configure HAProxy. (Not required if you are using NGINX.) In the HAProxy configuration file /etc/haproxy/haproxy.cfg:
- Enable the Proxy Protocol in Proxy1(HAProxy1) by adding the send-proxy keyword to the backend.
- Strip the Proxy protocol in Proxy2(HAProxy2) by adding accept-proxy to the frontend.
frontend main bind *:7687 ssl crt /home/ne04j/neo4j/certificates/neo4j.pem mode tcp default_backend send_proxy_protocol backend send_proxy_protocol balance roundrobin server app1 127.0.0.1:17687 send-proxy frontend strip_proxy_protocol bind 127.0.0.1:17687 accept-proxy mode tcp default_backend neo4j backend neo4j balance roundrobin server app1 127.0.0.1:27687
- Configure NGINX. (Not required if you are using HAProxy.)
For a TCP stream, the PROXY protocol can be enabled for connections between NGINX and an upstream server. To enable the PROXY protocol in Proxy1(Nginx1), include the proxy_protocol directive in a server block at the stream{} level in /etc/nginx/nginx.conf. NGINX terminates HTTPS traffic (the ssl_certificate and ssl_certificate_key directives) and proxies the decrypted data to a backend server. In Proxy2(Nginx2), add listen with proxy_protocol to receive the client’s real IP forwarded with Proxy Protocol.
- Make sure that your NGINX installation includes the HTTP and Stream Real IP modules:
nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'
- In the file /etc/nginx/nginx.conf,
add:
stream { upstream neo4jweb { server localhost:7474; } upstream neo4jbolt { server localhost:27687; } server { listen 7473 ssl; proxy_pass localhost:17473; proxy_protocol on; ssl_certificate /home/ne04j/neo4j/certificates/neo4j.cert; ssl_certificate_key /home/ne04j/neo4j/certificates/neo4j.key; } server { listen 7687 ssl; proxy_pass localhost:17687; proxy_protocol on; ssl_certificate /home/ne04j/neo4j/certificates/neo4j.cert; ssl_certificate_key /home/ne04j/neo4j/certificates/neo4j.key; } server { listen 17473 proxy_protocol; proxy_pass neo4jweb; } server { listen 17687 proxy_protocol; proxy_pass neo4jbolt; } }
- Make sure that your NGINX installation includes the HTTP and Stream Real IP modules:
- Configure the network. Verify that all traffic from the client is sent to Proxy1. Any traffic that does not go from Proxy2 to DB is dropped. This requires IPTABLE setup. Use this script neo4j_firewall.sh to set up the IPTABLES:
#!/bin/sh # Remove any existing jumps to our custom chains iptables -D INPUT -j chain-neo4j-incoming iptables -D OUTPUT -j chain-neo4j-outgoing # Clean any existing custom chains iptables -F chain-neo4j-incoming iptables -F chain-neo4j-outgoing iptables -X chain-neo4j-incoming iptables -X chain-neo4j-outgoing iptables -N chain-neo4j-incoming iptables -N chain-neo4j-outgoing # Define external(proxy1), proxy2, ssl and no ssl ports no_ssl_port_prefix=2 proxy2_port_prefix=1 port_list=0 # Pass in all arguments, please see bottom usage. for i in "$@" ; do # set the port prefix if echo $i | grep '^-' > /dev/null; then if echo $i | grep '^-port_list$' > /dev/null; then port_list=999 fi elif [ "X${port_list}" = "X999" ]; then external_port=${i} proxy2_port=${proxy2_port_prefix}${i} no_ssl_port=${no_ssl_port_prefix}${i} if [ “${external_port}” = “7473” ]; then no_ssl_port=7474 fi #################################### # INCOMING RULES # Allow loopback access to intermediate ports so that proxy1 can # route traffic to proxy2 iptables -A chain-neo4j-incoming -i lo -p tcp --dport ${proxy2_port} -j ACCEPT # Disallow external access to proxy2 iptables -A chain-neo4j-incoming -p tcp --dport ${proxy2_port} -j REJECT # Allow loopback access to unencrypted ports so that proxy2 can # route traffic to DB iptables -A chain-neo4j-incoming -i lo -p tcp --dport ${no_ssl_port} -j ACCEPT # Disallow direct access to unencrypted ports iptables -A chain-neo4j-incoming -p tcp --dport ${no_ssl_port} -j REJECT # Allow access to proxy1 iptables -A chain-neo4j-incoming -p tcp --dport ${external_port} -j ACCEPT #################################### # OUTGOING RULES # Allow loopback access to unencrypted ports to allow routing from proxy2 to # DB (proxy2 runs under neo4j UID) iptables -A chain-neo4j-outgoing -o lo -p tcp --dport ${no_ssl_port} -m owner --uid neo4j -j ACCEPT # Allow loopback access to intermediate ports to allow routing from proxy1 to # proxy2 (proxy1 runs under neo4j UID) iptables -A chain-neo4j-outgoing -o lo -p tcp --dport ${proxy2_port} -m owner --uid neo4j -j ACCEPT # Disallow loopback access to unencrypted ports to prevent local clients from # skipping interception iptables -A chain-neo4j-outgoing -o lo -p tcp --dport ${no_ssl_port} -j REJECT fi done if [ "${port_list}" = "0" ]; then echo “usage: /root/set_firewall.sh -port_list [external port list]” echo “for example /root/set_firewall.sh -port_list 7473 7687” fi # Firewall chains need to return at the end iptables -A chain-neo4j-incoming -j RETURN iptables -A chain-neo4j-outgoing -j RETURN # Hook the main rules up to the chains iptables -A INPUT -j chain-neo4j-incoming iptables -A OUTPUT -j chain-neo4j-outgoing
- Configure the S-TAP®. When configuring the proxy instances, the first instance terminates the encryption and adds the proxy-protocol for Guardium to collect the traffic and be able to attribute the correct analyzed client IP. The second instance removes the proxy-protocol, to not break the connection to the database. Configure the inspection engine to collect the traffic between the two proxy instances. For example, if you are using the example configurations above, then the ports to collect for Neo4j are 17473, 17687.
- If you are using K-TAP, modify the
guard_tap.ini file:
- IE
parameters
[DB_0] db_type=NEO4J port_range_end=17473 port_range_start=17473 real_db_port=17473 networks=127.0.0.1/255.255.255.255,9.70.165.199/255.255.255.255 [DB_1] db_type=NEO4J port_range_end=17687 port_range_start=17687 real_db_port=17687 networks=127.0.0.1/255.255.255.255,9.70.165.199/255.255.255.255
- IE
parameters
- If you are using PCAP, modify the
guard_tap.ini file:
- TAP properties
devices=ens32,lo ktap_installed=0
- IE
parameters
[DB_0] db_type=NEO4J port_range_end=17473 port_range_start=17473 real_db_port=17473 [DB_1] db_type=NEO4J port_range_end=17687 port_range_start=17687 real_db_port=17687
- TAP properties
- If you are using K-TAP, modify the
guard_tap.ini file: