Wednesday, November 4, 2015

[NoSQL] How to secure an Oracle NoSQL database

Hi,

In this post, i will talk about security on oracle NoSQL database and how to add security to an existing topology . After we enable security, pinging or connecting the NoSQL database need credentials.


First let see how can we login our NoSQL database without security.

$java -jar $KVHOME/lib/kvstore.jar runadmin -host localhost -port 5000 
Logged in admin as root
kv->

It is so simple, and you can see the config like this:

$ cd $KVROOT
$ cat config.xml 
<config version="2">
  <component name="params" type="bootstrapParams" validate="true">
    <property name="forceBootstrapAdmin" value="false" type="BOOLEAN"/>
    <property name="storageNodeId" value="1" type="INT"/>
    <property name="adminHttpPort" value="5001" type="INT"/>
    <property name="numCPUs" value="72" type="INT"/>
    <property name="haPortRange" value="5010,5030" type="STRING"/>
    <property name="rootDir" value="/opt/oracle/kvroot" type="STRING"/>
    <property name="mgmtClass" value="oracle.kv.impl.mgmt.jmx.JmxAgent" type="STRING"/>
    <property name="capacity" value="12" type="INT"/>
    <property name="memoryMB" value="120000" type="INT"/>
    <property name="hostname" value="#HOST#" type="STRING"/>
    <property name="hostingAdmin" value="true" type="BOOLEAN"/>
    <property name="storeName" value="#KVSTORE#" type="STRING"/>
    <property name="registryPort" value="5000" type="INT"/>
    <property name="softwareVersion" value="12.1.3.2.5" type="STRING"/>
  </component>
  <component name="mountPoints" type="bootstrapParams" validate="false">
    <property name="/u05/kvdata" value="" type="STRING"/>
    <property name="/u04/kvdata" value="" type="STRING"/>
    <property name="/u06/kvdata" value="" type="STRING"/>
    <property name="/u12/kvdata" value="" type="STRING"/>
    <property name="/u10/kvdata" value="" type="STRING"/>
    <property name="/u11/kvdata" value="" type="STRING"/>
    <property name="/u01/kvdata" value="" type="STRING"/>
    <property name="/u02/kvdata" value="" type="STRING"/>
    <property name="/u07/kvdata" value="" type="STRING"/>
    <property name="/u09/kvdata" value="" type="STRING"/>
    <property name="/u08/kvdata" value="" type="STRING"/>
    <property name="/u03/kvdata" value="" type="STRING"/>
  </component>
</config>

Note that: config.xml file exists on every storage node in topology. You can see that there is no entry about security.

So, lets start adding security. For this purpose, we should create encryption. In order to enable security, you can use wallet or password file. In this post, i will use password files, because you need EE (Enterprise Edition) licence to use wallet.

First, stop NoSQL database instances: (run on every storage node)

$ java  -Xmx256m -Xms256m -jar $KVHOME/lib/kvstore.jar stop -root $KVROOT -config config.xml

After that, you can config security in one of nodes.

$java  -Xmx256m -Xms256m -jar $KVHOME/lib/kvstore.jar securityconfig
security-> config create
Missing required argument (-root) for command: create
Usage: config create -root <secroot> 
        [-secdir <security dir>] [-pwdmgr {pwdfile | wallet | <class-name>}] 
        [-kspwd <password>] [-param <param=value>]*
        Creates a new security configuration.

You can see syntax of config command like above.

Create security files with command below:

security-> config create -pwdmgr pwdfile -root $KVROOT
Enter a password for the Java KeyStore:
Re-enter the KeyStore password for verification:
Created files
    /opt/oracle/kvroot/security/store.trust
    /opt/oracle/kvroot/security/security.xml
    /opt/oracle/kvroot/security/client.security
    /opt/oracle/kvroot/security/store.keys
    /opt/oracle/kvroot/security/client.trust
    /opt/oracle/kvroot/security/store.passwd
Created
security-> 

The password you entered above is saved into store.passwd file. Dont worry for remembering. :)

Important ! After that copy all the files created above to the other storage nodes.

you can do this with scp like this:

$ cd $KVROOT/security
$ scp  oracle@HOST:/opt/oracle/kvroot/security/* .

Lets continue to configure security.

security-> config add-security
Missing required argument (-root) for command: add-security
Usage: config add-security -root <kvroot> [-secdir <security dir>] [-config <config.xml>]
        Updates a Storage Node configuration to incorporate a security configuartion.

You see the parameters for adding security. Do the following:

security-> config add-security -root /opt/oracle/kvroot -secdir security -config config.xml
Configuration updated.
security-> 
security-> exit

Ok, we are done :) We added security to our topology, now start all services on all nodes with following:

$ nohup java  -Xmx256m -Xms256m -jar $KVHOME/lib/kvstore.jar start -root $KVROOT -config config.xml &

After all the services started, try to connect:

$java -jar /opt/oracle/kv-ce/lib/kvstore.jar runadmin -host localhost -port 5000
Cannot connect to admin at localhost:5000
kv-> 

As you see, after security enabled  you can not login to database. You can login database with generated client security file as follow:

$java -jar $KVHOME/lib/kvstore.jar runadmin -host localhost -port 5000  -security $KVROOT/security/client.security 
Logged in admin as anonymous
kv-> 

So lets create an admin user for example and see how it connects.

For this purpose we will create root user, for now we have no user such as root or other because we have no security, so no need for root account :) In order to do this, do :

kv-> plan create-user -name root -admin -wait
Enter the new password: 
Re-enter the new password: 
Executed plan 13, waiting for completion...
Plan 13 ended successfully
kv-> 
kv-> 

This command creates user root, to save passwords of users we will create a password file. As you remember we have option wallet or password file, i said at the beginning.

To create a password file

$java -jar $KVHOME/lib/kvstore.jar securityconfig pwdfile create -file $KVROOT/security/login.passwd 
Created
$

To add passwords to our password file:

$java -jar $KVHOME/lib/kvstore.jar securityconfig pwdfile secret -file $KVROOT/security/login.passwd -set -alias root
Enter the secret value to store: 
Re-enter the secret value for verification: 
Secret created
OK
$

Again no worry, passwords are stored on password file :)

Ok, one more step to finish :) . You dont need to enter your password when you login to NoSQL database, you have to use security file which contains your username and password. That file looks like client.security file with username and password information.

Add following lines to client.security file and save as adminlogin.txt

$cat client.security
#Security property settings for communication with KVStore servers
#Wed Nov 04 10:38:51 EET 2015
oracle.kv.ssl.trustStore=client.trust
oracle.kv.transport=ssl
oracle.kv.ssl.protocols=TLSv1.2,TLSv1.1,TLSv1
oracle.kv.ssl.hostnameVerifier=dnmatch(CN\=NoSQL)

$cat adminlogin.txt
oracle.kv.auth.username=root
oracle.kv.auth.pwdfile.file=/opt/oracle/kvroot/security/login.passwd
oracle.kv.ssl.trustStore=client.trust
oracle.kv.transport=ssl
oracle.kv.ssl.protocols=TLSv1.2,TLSv1.1,TLSv1
oracle.kv.ssl.hostnameVerifier=dnmatch(CN\=NoSQL)

After that we can use this file every time if we use a command need credentials in NoSQL database, like connecting to store. It is kind of annoying but you must do this :/

After those steps, you can not login anonymously to database:

$java -jar $KVHOME/lib/kvstore.jar runadmin -host localhost -port 5000  -security $KVROOT/security/client.security 
Could not login as anonymous: Authentication failed (12.1.3.2.5)
Login as:

But with adminlogin.txt you can connect succesfully:

$java -jar $KVHOME/lib/kvstore.jar runadmin -host localhost -port 5000  -security $KVROOT/security/adminlogin.txt 
Logged in admin as root
kv-> 


kv-> show users
user: id=u1 name=root

kv-> connect store -name #KVSTORE#
Error handling command connect store -name #KVSTORE#: Cannot connect to #KVSTORE# at localhost:5000
Warning: You are no longer connected to a store.


kv-> connect store -name #KVSTORE# -security /opt/oracle/kvroot/security/adminlogin.txt 
Connected to #KVSTORE#at localhost:5000.
kv-> 

I experienced that for connecting clients to NoSQL database or connecting from other storage nodes, you must provide login.passwd file and adminlogin.txt to client side.

Last step, lets check config.xml to see security option is active.

$ cd $KVROOT
$ $cat config.xml 
<config version="2">
  <component name="params" type="bootstrapParams" validate="true">
    <property name="forceBootstrapAdmin" value="false" type="BOOLEAN"/>
    <property name="storageNodeId" value="1" type="INT"/>
    <property name="adminHttpPort" value="5001" type="INT"/>
    <property name="numCPUs" value="72" type="INT"/>
    <property name="haPortRange" value="5010,5030" type="STRING"/>
    <property name="rootDir" value="/opt/oracle/kvroot" type="STRING"/>
    <property name="securityDir" value="security" type="STRING"/>
    <property name="mgmtClass" value="oracle.kv.impl.mgmt.jmx.JmxAgent" type="STRING"/>
    <property name="capacity" value="12" type="INT"/>
    <property name="memoryMB" value="120000" type="INT"/>
    <property name="hostname" value="#HOST#" type="STRING"/>
    <property name="hostingAdmin" value="true" type="BOOLEAN"/>
    <property name="storeName" value="#KVSTORE#" type="STRING"/>
    <property name="registryPort" value="5000" type="INT"/>
    <property name="softwareVersion" value="12.1.3.2.5" type="STRING"/>
  </component>
  <component name="mountPoints" type="bootstrapParams" validate="false">
    <property name="/u05/kvdata" value="" type="STRING"/>
    <property name="/u04/kvdata" value="" type="STRING"/>
    <property name="/u06/kvdata" value="" type="STRING"/>
    <property name="/u12/kvdata" value="" type="STRING"/>
    <property name="/u10/kvdata" value="" type="STRING"/>
    <property name="/u11/kvdata" value="" type="STRING"/>
    <property name="/u01/kvdata" value="" type="STRING"/>
    <property name="/u02/kvdata" value="" type="STRING"/>
    <property name="/u07/kvdata" value="" type="STRING"/>
    <property name="/u09/kvdata" value="" type="STRING"/>
    <property name="/u08/kvdata" value="" type="STRING"/>
    <property name="/u03/kvdata" value="" type="STRING"/>
  </component>
</config>

As you can see it shows default security directory under $KVROOT.


That's all.

Thanks for reading.

Enjoy & share.

Source:
http://oradb-srv.wlv.ac.uk:7777/nosql/SecurityGuide/secure_installation.html 

1 comment :

  1. Could I ask a question?
    I install a kvstore with parameter that "-secure-config disable"
    So can I set enable secure without reinstall?
    Thanks. Best.

    ReplyDelete