Configuring Mutual Transport Layer Security (mTLS)

In traditional Transport Layer Security (TLS), only the server authenticates to the client by presenting its certificate. With mutual Transport Layer Security (mTLS), both the server and the client present their certificates so that they are mutually authenticated.

The SSL_CLIENT_AUTHENTICATION parameter controls whether the client certificate needs to be authenticated. This doesn’t authenticate or authorize the end user. It authenticates that the certificates used by both the server and client are valid and signed by a known certificate authority (CA). Configuring PKI Certificate Authentication goes into detail about end-user authentication using PKI certificates.

The default for SSL_CLIENT_AUTHENTICATION is TRUE for the database server, listener, and client, which will require mTLS (mutual TLS requiring a client certificate in a client wallet). Settings are as follows:

Create the Server and Listener Wallet

To get a certificate signed by a publicly signed certificate authority, you must create the database server and listener wallet and export a certificate signing request (CSR).

  1. Login to the host where the database is installed.

  2. Create the wallet.

    orapki wallet create -wallet <wallet location> -pwd <wallet password> -auto_login
  3. Add the trusted root certificate to the wallet (get this from your certificate administrator).

    orapki wallet add -wallet <wallet location> -trusted_cert -cert <trusted root certificate location>/rootCA.crt -pwd <wallet password>
  4. Create a private key and certificate request in the wallet.

    orapki wallet add -wallet <wallet location> -keysize 2048 -dn <certificate_dn> -pwd <wallet password>
  5. Export the certificate request to get it signed.

    orapki wallet export -wallet <wallet location> -dn <certificate_dn> -request <certificate signing request location>/<file_name>.csr -pwd <wallet password>
  6. Display the contents of the wallet.

    orapki wallet display -wallet <wallet_location>

    There will be an entry under Requested Certificates.

  7. View the contents of the CSR (certificate signing request) file.

    cat <certificate_signing_request_location>/<file_name>.csr
  8. Send the CSR file to your certificate administrator to have it signed by the root certificate authority (CA) or an intermediate CA.

  9. Import the signed database server user certificate into the database wallet.

    orapki wallet add -wallet <wallet location> -user_cert -cert <signed certificate location>/<file_name_signed>.crt -pwd <wallet password>
  10. Display the contents of the wallet:

    orapki wallet display -wallet <wallet location>
  11. Ensure that the database server user certificate is now displayed under User Certificates.

    The wallet you will use for the database server and listener is now ready to be deployed for use.

Set WALLET_ROOT and deploy the database server wallet

  1. Check to see if WALLET_ROOT already exists. Login as a user with privileges to check system parameters and run:

    SHOW PARAMETER WALLET_ROOT

    If WALLET_ROOT is not already setup, run the next command to create WALLET_ROOT.

  2. Create WALLET_ROOT, a system parameter. Run the following SQL command:

    alter system set wallet_root = '<wallet_root_directory>' scope=spfile;
  3. Reboot the database.

  4. Show the modified wallet_root parameter. Run the following SQL command:

    show parameter wallet_root;
  5. If the TLS directory does not yet exist under WALLET_ROOT, create a directory for TLS under your WALLET_ROOT PDB directory in the operating system.

    mkdir -p -v <wallet_root_directory>/<PDB GUID>/tls

    You can find the PDB GUID for your PDB by running the following SQL command:

    select guid from v$containers;
  6. Change ownership of the directory.

    sudo chown oracle:oinstall -R -v <wallet_root_directory>/<PDB GUID>/tls
  7. Copy the database server ewallet.p12 and the cwallet.sso files to this new tls directory.

    Perform this command from the same directory where the wallets were created:

    cp ./ewallet.p12 ./cwallet.sso <wallet_root_directory>/<PDB GUID>/tls

Database server configuration for mTLS

  1. Log in to the server where the Oracle database resides.

  2. Check that SSL_CLIENT_AUTHENTICATION in the sqlnet.ora file is set to TRUE as this enables mTLS:

    By default, the sqlnet.ora file is located in the $ORACLE_HOME/network/admin directory or in the location set by the TNS_ADMIN environment variable.

    SSL_CLIENT_AUTHENTICATION=TRUE

    You may set this to OPTIONAL instead which enables both TLS and mTLS and is dependent on whether the client sends the client user certificate.

Listener configuration for mTLS

  1. Check the PROTOCOL parameter in the listener.ora file to ensure TLS is specified.

    By default, listener.ora is located in the $ORACLE_HOME/network/admin directory.

    The parameter PROTOCOL=tcps tells the listener to only use TLS (or mTLS) for database connections.

    For example:

    LISTENER = (ADDRESS=(PROTOCOL=tcps)(HOST=<host_name>)(PORT=1522))
  2. Ensure that the listener wallet exists in the location of the WALLET_LOCATION parameter in the listener.ora file. Use the same wallet as you did for the database server.

    WALLET_LOCATION=
        (SOURCE=
            (METHOD=file)
            (METHOD_DATA=
                (DIRECTORY=$WALLET_DIR/<pdb guid>/tls)))

    If the listener is on the same server as the database server and the server TLS wallet is in the default location, set the listener WALLET_LOCATION to the same location. Alternatively, the server wallet can be copied to a different location for the listener.

    If you set the SSL_SERVER_DN_MATCH parameter to TRUE for DN matching (partial or full DN match), then the hostname or DN check will happen against both the listener certificate and the server certificate. They don’t have to be the same certificate, but matching will be done with both certificates.

  3. Ensure the SSL_CLIENT_AUTHENTICATION parameter is set to TRUE in listener.ora file to enable mutual TLS.

    SSL_CLIENT_AUTHENTICATION=TRUE

Client Configuration for mTLS

  1. Log in to the client for the Oracle database.

  2. Set SSL_CLIENT_AUTHENTICATION in the sqlnet.ora and tnsnames.ora files to TRUE.

    A setting of TRUE, will send a client side user certificate to the server. Because this applies to every connection, you can change the SSL_CLIENT_AUTHENTICATION parameter in the tnsnames.ora connection string using the same parameter setting which will take precedence over the sqlnet.ora setting.

    SSL_CLIENT_AUTHENTICATION=TRUE

Tip: While the default value for this parameter is true, setting it explicitly to true will make troubleshooting connection problems easier.

  1. If you connect to multiple databases and some require mTLS and the other TLS connections don’t need a wallet, then you have two options for setting different connections depending if you have a common wallet to connect with the different databases or if each mTLS connection requires a different wallet:
    • With a Common Client Wallet
      1. Specify a common mTLS client wallet by setting WALLET_LOCATION in sqlnet.ora.

        This will result in every mTLS connection using the same client wallet to connect with their database.

      2. In the connection string for one-way TLS connections,

        1. Set SSL_CLIENT_AUTHENTICATION = FALSE to override the mTLS client wallet setting.

        2. Set WALLET_LOCATION = SYSTEM to specify the system default certificate store.

    • Without a Common Client Wallet

      This can be used if you need to use a different client wallet for each database connection.

      1. Set WALLET_LOCATION = SYSTEM in sqlnet.ora to allow the TLS connections to connect without using a wallet.

      2. Set the WALLET_LOCATION for every mTLS connection to specify the unique wallet location for each connection.

Related Topics

Connect to the database

Connect to the database using the connection name with the tcps protocol.

sqlplus <user_name>@<PDB_name>

Server Certificate DN Matching

Oracle recommends using Server certificate DN matching, similar to using server DN matching with one-way TLS, to ensure the client is connecting to the intended server.

Configure full DN matching by setting the SSL_SERVER_CERT_DN parameter connection string in the tnsnames.ora file:

Note:

If you can’t set the host value in tnsnames.ora or sqlnet.ora to the value of the certificate common name (CN) or one of the entries in the SAN field, then consider using full DN matching.

Both the listener and server certificate will be checked with both partial and full DN matching. When using full DN matching, while the server and listener certificate can be different, their DN must be the same for the connection to succeed.

The tnsnames.ora file will look similar to:

finance=
(DESCRIPTION=
    (ADDRESS_LIST=
        (ADDRESS=(PROTOCOL = tcps)(HOST = finance)
        (PORT = 1575)))
    (CONNECT_DATA=
        (SERVICE_NAME= finance.us.example.com))
    (SECURITY=
        (SSL_SERVER_DN_MATCH = TRUE)
        (SSL_SERVER_CERT_DN="cn=finance,cn=OracleContext,c=us,o=example")))