Using the Proxy in a secure data store
Starting up the Proxy
Configuring and starting the Oracle NoSQL Database Proxy is part of the data store administration. The proxy can be started on a secure data store using the following steps.
- Before you start up the proxy, you need to create a user
(
proxy_user
) as the proxy needs an identity to connect to the secure data store. This proxy user identity (proxy_user
) is never used for actual data operations. It is only needed for the initial connection to the store.In SQL shell, the following command will create a bootstrap user for the proxy. See Developers Guide for getting started with SQL commands.
Create theproxy_user
as shown below:sql-> CREATE USER proxy_user IDENTIFIED BY "<proxyuser_password>"
- Create a new password file to store the credentials needed to login as the
database user (
proxy_user
).java -Xmx64m -Xms64m -jar lib/kvstore.jar securityconfig pwdfile \ create -file $KVROOT/security/login.passwd java -Xmx64m -Xms64m -jar lib/kvstore.jar securityconfig pwdfile \ secret -file $KVROOT/security/login.passwd -set -alias proxy_user
Note:
The secret value to store (that you enter in the above step) must match the value of <proxyuser_password>
that you have set in the previous step. - Create a login file
proxy.login
for the bootstrap user with the following information in it.
where,oracle.kv.auth.username=<proxy_user> oracle.kv.auth.pwdfile.file=login.passwd oracle.kv.transport=ssl oracle.kv.ssl.trustStore=client.trust
login.passwd
is the file to store the password value of theproxy_user
user.client.trust
is the certificate trust file obtained from the data store deployment.
- Self-signed certificates can be used to securely connect to the Oracle NoSQL
Database Proxy. Use the openSSL command to generate the self-signed certificate
and private key. When prompted, provide a secure passphrase of your choice for
the certificate file.
Convert the private key toopenssl req -x509 -days 365 -newkey rsa:4096 -keyout key.pem -out certificate.pem \ -subj "/C=US/ST=CA/L=San/CN=${HOSTNAME}/emailAddress=xxxx.xxxx@oracle.com"
PKCS#8
format. When prompted, first enter the passphrase that you set in the previous step and then provide a secure password of your choice for the encryption. You will use the encryption password that you set here in the step below while starting the proxy.
Additionally, aopenssl pkcs8 -topk8 -inform PEM -outform PEM -in key.pem \ -out key-pkcs8.pem -v1 PBE-SHA1-3DES
driver.trust
file is also required if you are using the Java driver. Thisdriver.trust
file is not required for other language drivers. To generate thedriver.trust
file, import the certificate to the Java keystore. When prompted, provide the keystore password.keytool -import -alias example -keystore driver.trust -file certificate.pem
- Use the following command to start up the proxy for a secure data
store:
where,java -jar lib/httpproxy.jar \ -storeName <kvstore_name> \ -helperHosts <kvstore_helper_host> \ [-hostname <proxy_host>] \ [-httpsPort <proxy_https_port>] \ -storeSecurityFile $KVROOT/security/proxy.login \ -sslCertificate certificate.pem \ -sslPrivateKey key-pkcs8.pem \ -sslPrivateKeyPass <privatekey_password> \ [-verbose true]
kvstore_name
is the data store name obtained from the data store deployment. See ping to obtain information about the runtime entities (Storage Nodes and Replication Nodes) of the data store..kvstore_helper_host
is the data store's helper host:port list obtained from the data store deployment. See Obtaining a KVStore Handle in the Java Direct Driver Developer's Guide.proxy_host
is the hostname of the machine running the proxy service. This parameter is optional and defaults tolocalhost
. You can also specify the complete hostname of the machine running the proxy.proxy_https_port
is the port on which the proxy is listening for requests. This is an optional parameter and defaults to 443.Note:
Using port 443 requires root privilege. You can use port 8443 if you do not have root privilege.proxy.login
is the security login file generated in the earlier step for accessing the secure kvstore.certificate.pem
is the certificate file generated in the previous step.key-pkcs8.pem
is the private key file generated in the previous step.privatekey_password
is the password for the encryptedkey-pkcs8.pem
file.
Note:
The proxy start-up only accepts private key file in PKCS#8 format. If your private key is already in PKCS#8 (start with -----BEGIN ENCRYPTED PRIVATE KEY----- or -----BEGIN PRIVATE KEY-----), you don't need any additional conversion. Otherwise, you can use OpenSSL to do the conversion.
Connecting an application to the secure data store
Description of the illustration proxy_arch.png
Oracle NoSQL Database drivers are available in various programming languages that are used in the client application. Currently, Java, Python, Go, Node.js, C# are supported. Oracle NoSQL Database Proxy is a server that accepts requests from the client application and processes them using the Oracle NoSQL Database.
Authentication:
Within a secure Oracle NoSQL Database, access to the database is limited to
authenticated users. You need to create a user for your application
(appln_user
) and pass the credentials of this user while
connecting to your data store through the proxy from your drivers. The user will be
authenticated using the credentials supplied( username/password) in the data
store.
In the driver configuration, the application user name and password are provided.
When the handle is created from the secure configuration the driver will send a
login request to the proxy. The proxy uses this identity
(appln_user/applnuser_password
) to log into the data store,
authenticating the user. This user identity (appln_user
) must
already exist in the store.
appln_user
) as shown below for your application to
access the secure data
store.sql-> CREATE USER <appln_user> IDENTIFIED BY "<applnuser_password>"
Authorization:
Oracle NoSQL Database provides role-based authorization which enables the user to assign kvstore roles to user accounts to define accessible data and allow database administrative operations for each user account. Users can acquire desired privileges by role-granting. Your application should be given a role based on the least privilege access, carefully balancing the needs of the application with security concerns. See Configuring privileges and roles for more details.
After successful authentication of the application user, every driver request from
the handle created sends the identity (appln_user
) which is used by
the proxy and data store to authorize any data operations such as table creation,
put, get, query, etc. The data store is the entity that does the authorization. The
authorization is based on the identity and operation, and the data store uses the
roles assigned to the appln_user
to make authorization
decisions.
- The driver sends the request to the proxy and the request contains the authenticated identity.
- The proxy uses the authenticated identity to send the request to the data store.
- The data store validates the identity and authorizes the identity for the desired operation (put, get, query, etc) using the privileges set in the data store for that identity.
The Oracle NoSQL Database Java Driver contains the jar files that enable an application to communicate with the Oracle NoSQL Database Proxy. You can connect to the proxy using the following steps.
- Create an application user (
appln_user
) to access the data store through the secure proxy as shown in the above section. - For secure access, create an instance of the
StoreAccessTokenProvider
class with the parameterized constructor. Provide the reference ofStoreAccessTokenProvider
class to theNoSQLHandleConfig
class to establish the appropriate connection. Install the Oracle NoSQL Database Java Driver in the application's classpath and use the following code to connect to the data store.
where,String endpoint = "https://<proxy_host>:<proxy_https_port>"; StoreAccessTokenProvider atProvider = new StoreAccessTokenProvider("<appln_user>","<applnuser_password>".toCharArray()); NoSQLHandleConfig config = new NoSQLHandleConfig(endpoint); config.setAuthorizationProvider(atProvider); NoSQLHandle handle = NoSQLHandleFactory.createNoSQLHandle(config);
proxy_host
is the hostname of the machine running the proxy service. This should match the proxy host you configured earlier.proxy_https_port
is the port on which the proxy is listening for requests. This should match the proxy https port configured earlier.appln_user
is the user created to connect to the secure store. This should match the user created in the above section.applnuser_password
is the password of theappln_user
.
- You can specify the details of the trust store containing the
SSL certificate for the proxy in one of the following two ways.
You can set it as part of your Java code as shown below:
/* the trust store containing SSL cert for the proxy */ System.setProperty("javax.net.ssl.trustStore", trustStore); if (trustStorePassword != null) { System.setProperty("javax.net.ssl.trustStorePassword",trustStorePassword); }
Alternatively, you can start-up the application program and set thedriver.trust
file's path to the Java trust store by using the following command. This is required as the proxy is already set up using thecertificate.pem
andkey-pkcs8.pem
files.java -Djavax.net.ssl.trustStore=driver.trust \ -Djavax.net.ssl.trustStorePassword=<password of driver.trust> \ -cp .:lib/nosqldriver.jar application_program
The
driver.trust
contains thecertificate.pem
orrootCA.crt
certificate. If the certificatecertificate.pem
is in a chain signed by a trusted CA that is listed inJAVA_HOME/jre/lib/security/cacerts
, then you don't need to append Java environment parameter-Djavax.net.ssl.trustStore
in the Java command.
- Create an application user (
appln_user
) to access the data store through the secure proxy as shown in the above section. - If running a secure store, a certificate path should be
specified through the
REQUESTS_CA_BUNDLE
environment variable:
or$ export REQUESTS_CA_BUNDLE= <fully_qualified_path_to_certificate>/certificate.pem:$REQUESTS_CA_BUNDLE
borneo.NoSQLHandleConfig.set_ssl_ca_certs()
. - Use the following code to connect to the
proxy.
where,from borneo import NoSQLHandle, NoSQLHandleConfig from borneo.kv import StoreAccessTokenProvider endpoint = 'https://<proxy_host>:<proxy_https_port>' # Create the AuthorizationProvider for a secure store: ap = StoreAccessTokenProvider('<appln_user>','<applnuser_password>') # create a configuration object config = NoSQLHandleConfig(endpoint).set_authorization_provider(ap) # set the certificate path if running a secure store config.set_ssl_ca_certs(<ca_certs>) # create a handle from the configuration object handle = NoSQLHandle(config)
proxy_host
is the hostname of the machine running the proxy service. This should match the proxy host you configured earlier.proxy_https_port
is the port on which the proxy is listening for requests. This should match the proxy https port configured earlier.appln_user
is the user created to connect to the secure store. This should match the user created in the above section.applnuser_password
is the password of theappln_user
.
- Create an application user (
appln_user
) to access the data store through the secure proxy as shown in the above section. - Use the following code to connect to the proxy. To connect
an application to a secure NoSQL database, you need to provide user
credentials used to authenticate with the server. If the Proxy server is
configured with a self-signed certificate or a certificate that is not
trusted by the default system CA, you also need to specifiy
CertPath and ServerName for the certificate path and
server name used to verify server's
certificate.
where,import ( "fmt" "github.com/oracle/nosql-go-sdk/nosqldb" "github.com/oracle/nosql-go-sdk/nosqldb/httputil" ) ...cfg:= nosqldb.Config{ Endpoint: "https://<proxy_host>:<proxy_https_port>", Mode: "onprem", Username: "<appln_user>", Password: "<applnuser_password>>", }, // Specify the CertPath and ServerName // ServerName is used to verify the hostname for self-signed certificates. // This field is set to the "CN" subject value from the certificate specified by CertPath. HTTPConfig: httputil.HTTPConfig{ CertPath: "<fully_qualified_path_to_cert>", ServerName: "<server_name>", }, } client, err:=nosqldb.NewClient(cfg) iferr!=nil { fmt.Printf("failed to create a NoSQL client: %v\n", err) return } deferclient.Close() // Perform database operations using client APIs. // ...
proxy_host
is the hostname of the machine running the proxy service. This should match the proxy host you configured earlier.proxy_https_port
is the port on which the proxy is listening for requests. This should match the proxy https port configured earlier.appln_user
is the user created to connect to the secure store. This should match the user created in the above section.applnuser_password
is the password of theappln_user
.
- Create an application user (
appln_user
) to access the data store through the secure proxy as shown in the above section. - In secure mode the proxy requires the SSL Certificate and
Private key. The proxy certificate was created when configuring the
proxy as explained here. If the root certificate authority (CA) for your proxy
certificate is not one of the trusted root CAs , the driver
needs the certificate chain file (e.g. certificates.pem) or a
root CA certificate file (e.g. rootCA.crt) in order to connect to
the proxy. If you are using self-signed certificate instead, the driver
will need the certificate file (e.g. certificate.pem) for the
self-signed certificate in order to connect.
To provide the certificate or certificate chain to the driver, you have two options , either specifying in the code or setting as environment variables.
You can specify the certificates throughhttpOpt
property while creating the NoSQL handle. InsidehttpOpt
you can useca
property to specify the CA as shown below.const client = new NoSQLClient({ ....., httpOpt: { ca: fs.readFileSync(<caCertFile>) },..... });
Note:
If a file path is supplied, the path can be absolute or relative to the current working directory of the application.Alternatively, before running your application, set the environment variableNODE_EXTRA_CA_CERTS
as shown below.
where driver.trust is either a certificate chain file (certificates.pem) for your CA, your root CA's certificate (rootCA.crt) or a self-signed certificate (certificate.pem).export NODE_EXTRA_CA_CERTS="<fully_qualified_path_to_driver.trust>"
- To connect to the proxy in secure mode, in addition to
communication endpoint, you need to specify user name and password of
the driver user. This information is passed in
Config#auth
object underkvstore
property and can be specified in one of 3 ways as described below.You may choose to specify user name and password directly:
where,const NoSQLClient = require('oracle-nosqldb').NoSQLClient; const client = new NoSQLClient({ endpoint: 'https://<proxy_host>:<proxy_https_port>', auth: { kvstore: { user: '<appln_user>', password: '<applnuser_password>' } } });
proxy_host
is the hostname of the machine running the proxy service. This should match the proxy host you configured earlier.proxy_https_port
is the port on which the proxy is listening for requests. This should match the proxy https port configured earlier.appln_user
is the user created to connect to the secure store. This should match the user created in the above section.applnuser_password
is the password of theappln_user
.
You may choose to store credentials in a separate file which is protected by file system permissions, thus making it more secure than previous option, because the credentials will not be stored in memory, but will be accessed from this file only when login is needed. Credentials file should have the following format:
Then you may reference this credentials file as following:{ "user": "<appln_user>", "password": "<applnuser_password>" }
const NoSQLClient = require('oracle-nosqldb').NoSQLClient; const client = new NoSQLClient({ endpoint: 'https://<proxy_host>:<proxy_https_port>', auth: { kvstore: { credentials: '<path/to/credentials.json>' } } });
You may also reference
credentials.json
in the configuration file that is used to createNoSQLClient
instance.Contents ofconfig.json
{ "endpoint": "https://<proxy_host>:<proxy_https_port>", "auth": { "kvstore": { "credentials": "<path/to/credentials.json>" } } }
const NoSQLClient = require('oracle-nosqldb').NoSQLClient; const client = new NoSQLClient('</path/to/config.json>');
Note:
If a file path is supplied, the path can be absolute or relative to the current working directory of the application.
- Create an application user (
appln_user
) to access the data store through the secure proxy as shown in the above section. - To connect to the proxy in secure mode, in addition to
communication endpoint, you need to specify the details of the user
connecting to the secure data store. This information is passed in the
instance of
KVStoreAuthorizationProvider
and can be specified in any of the ways as described below.You may choose to specify user name and password directly:
where,var client = new NoSQLClient( new NoSQLConfig { Endpoint = "https://<proxy_host>:<proxy_https_port>", AuthorizationProvider = new KVStoreAuthorizationProvider( <appln_user, // user name as string <applnuser_password>) // password as char[] });
proxy_host
is the hostname of the machine running the proxy service. This should match the proxy host you configured earlier.proxy_https_port
is the port on which the proxy is listening for requests. This should match the proxy https port configured earlier.appln_user
is the user created to connect to the secure store. This should match the user created in the above section.applnuser_password
is the password of theappln_user
.
NoSQLClient
instance. Note that the password is specified as char[] which allows you to erase it after you are finished using NoSQLClient.You may choose to store credentials in a separate file which is protected by file system permissions, thus making it more secure than the previous option, because the credentials will not be stored in memory, but will be accessed from this file only when the login to the store is required. Credentials file should have the following format:
Then you may use this credentials file as following:{ "UserName": "<appln_user>", "Password": "<applnuser_password>" }
Contents ofconfig.json
var client = new NoSQLClient( new NoSQLConfig { Endpoint: 'https://<proxy_host>:<proxy_https_port>', AuthorizationProvider = new KVStoreAuthorizationProvider( "<path/to/credentials.json>") });
You may also reference credentials.json in the JSON configuration file that is used to create
NoSQLClient
instance:Contents ofconfig.json
{ "Endpoint": "https://<proxy_host>:<proxy_https_port>", "AuthorizationProvider": { "AuthorizationType": "KVStore", "CredentialsFile": "<path/to/credentials.json>" } }
var client = new NoSQLClient("</path/to/config.json>");
Note:
If a file path is supplied, the path can be absolute or relative to the current working directory of the application.Note that in
config.json
the authorization provider is represented as a JSON object with the properties forKVStoreAuthorizationProvider
and an additional AuthorizationType property indicating the type of the authorization provider, which is KVStore for the secure on-premises store.You need to provide the trusted root certificate to the driver if the certificate chain for your proxy certificate is not rooted in one of the well known CAs. The provided certificate may be either your custom CA or self-signed proxy certificate. It must be specified using TrustedRootCertificateFile property, which sets a file path (absolute or relative to the current working directory) to a PEM file containing one or more trusted root certificates (multiple roots are allowed in this file). This property is specified as part of ConnectionOptions in NoSQLConfig.var client = new NoSQLClient( new NoSQLConfig { Endpoint: 'https://<proxy_host>:<proxy_https_port>', AuthorizationProvider = new KVStoreAuthorizationProvider( "<path/to/credentials.json>"), ConnectionOptions: { "TrustedRootCertificateFile": "<path/to/certificates.pem>" } });