Wednesday, April 23, 2025

ODB Entra ID Integration Troubleshooting Guide

I've spent several weeks working through a wide variety of Oracle database integration use cases with Entra ID for the express purpose of methodically deriving all possible error codes that that a customer might encounter during an evaluation.  I will list each error followed by the one or more potential causes.

Before getting started with the errors, know that you can enable client and server side tracing to reveal underlying root causes of errors.

Client-side Trace for SQL*Plus
Either add the following to sqlnet.ora or set as environment variables the following before attempting to connect to the database server:
EVENT_25701=15
EVENT_25703=15
Note that 15 is for high level tracing and 14 for low level tracing.

Database Server Side Trace for non-autonomous databases
Set the following in the CDB:
SQL> ALTER SYSTEM SET EVENTS 'TRACE[TOKEN] DISK=HIGHEST'; 

Database Server Side Trace for autonomous databases
Review the alert log.  For example:
SQL> SELECT FROM V$DIAG_ALERT_EXT ORDER BY originating_timestamp desc;
SQL> SELECT * FROM UNIFIED audit_trail ORDER BY event_timestamp desc fetch first 100 rows only;
SQL> CREATE AUDIT POLICY ORA LOGON_SUCCESSES ACTIONS LOGON;
SQL> AUDIT POLICY ORA_LOGON_SUCCESSES WHENEVER SUCCESSFUL;

Error Number Documentation
Note that most errors provide additional help at the documentation page for the respective error code.
For example : https://docs.oracle.com/error-help/db/ora-<number>

Database Name Resolution
Database name resolution is typically provided by the explicit connect string, exclusively tnsnames.ora for JDBC-thin driver clients, a combination of sqlnet.ora and tnsnames.ora for JDBC-thick and OCI (C-based) client drivers, or LDAP-based name services.  Information on LDAP-based database name services are available at the following blog post: https://www.braddiggs.com/2023/10/oud-12cps4-use-case-oracle-database.html

Best Practice: Regardless of the name resolution repository, the best practice is to include all elements of connection in either the explicit connect string or TNS entry.

Here is a human friendly formatted TNS entry for database PDB1. The blue font items are required for the encrypted TCPS TLS connection. TLS connections between client and server are required for Entra ID integration.  The red font items are unique to Entra ID connections.

PDB1 = 
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=
      (SSL_SERVER_DN_MATCH=TRUE)
      (WALLET_LOCATION=SYSTEM)
      (TOKEN_AUTH=AZURE_INTERACTIVE)
      (TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)
      (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
      (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621)
    )
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )

Here is the equivalent explicit connect string being called with the connect SQL command:

SQL> connect (DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))(SECURITY=(SSL_SERVER_DN_MATCH=TRUE)(WALLET_LOCATION=SYSTEM)(TOKEN_AUTH=AZURE_INTERACTIVE)(TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)(CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)(AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=pdb1)))


Error Messages:

Here are the list of errors that I've encountered while troubleshooting Entra ID integration issues.

Error: ORA-01017: invalid username/password; logon denied
Potential reasons for this error:
  • Invalid username or password provided
  • The server side configuration of the target database of the client connection (CDB or PDB) may not yet be configured for Entra Integration including setting IDENTITY_PROVIDER_TYPE to AZURE_ID and applying Entra ID integration to IDENTITY_PROVIDER_CONFIG
  • The connection string or TNS entry of the client may not include all requisites for Entra ID integrated database


    Error: ORA-12154: Cannot connect to database. Cannot find alias <db> in
    <dir>\tnsnames.ora.
    Potential reasons for this error:
    • The tnsnames.ora file does not exist in <odb_client_base>\network\admin or that the specified database does. Note that you can specify TNS_ADMIN=\<path> to specify the folder path to the tnsnames.ora file
    • The requested database does not exist in the tnsnames.ora file.

    Error: ORA-12170: Cannot connect. - timeout of -s for host <ip_address> port <secure_port>.
    (CONNECTION_ID=<connection_id>)
    Potential reasons for this error:
    • The SQL*Plus command cannot connect to the host specified in the TNS or connect string entry
    • Check network firewall or host-based firewall ingress rules allow the host of the database client to connect to the host of the database server
    • Check the network firewall or host-based firewall egress rules do not allow the database client or server to connect to the database server's host


    ORA-12541: Cannot connect. No listener at host <ip> port <port>
    Potential reasons for this error:
    • Oracle database listener is not running or ingress firewall rules (network or host-based) are blocking access to the database port.

    Error: ORA-12545: Connect failed because target host or object does not exist
    Potential reasons for this error:
    • Can’t lookup specified connect string. Check name service resolution in tnsnames.ora or directory service
    • Make sure TNS_ADMIN is set to the directory where tnsnames.ora exists
    • You get the following Microsoft Entra ID error when you specify an invalid client ID.

      Error: ORA-12547: TNS:lost contact
      Potential reasons for this error:
      • Occurs if you specify PROTOCOL of TCP instead of TCPS in connect string or TNS entry

      Error: ORA-12514: Cannot connect to database. Service <service_name> is not registered with the
      listener at host <hostname_or_ip_address> port <tcps_tls_port>
      (CONNECTION_ID=Kittn+/2RPGXnZPxZAV9Hw==)
      Potential reasons for this error:
      • Occurs when incorrect SERVICE_NAME value is specified in connect string or TNS entry

        Error: ORA-18726: Failed to get a value from an OracleResourceProvider: No implementation of oracle.jdbc.spi.AccessTokenProvider with name: "ojdbc-provider-azure-token" can be located. Implementations of oracle.jdbc.spi.AccessTokenProvider that can be located have the following names : []
        Potential reasons for this error:
        • In the case of SQLDeveloper, this can occur if the SQLDeveloper product.conf configuration file does not have all of the requisite OJDBC extension libraries required for Entra ID integration. See this blog post (https://www.braddiggs.com/2025/04/entra-id-integration-for-sqldeveloper.html) for details on how to configure SQLDeveloper for EntraID integration
        • This can result from using a version of the SQL*Plus client earlier than 23.7.
        • Note that if the connect string or TNS entry specifies TOKEN_AUTH=AZURE_DEVICE_CODE , this may indicate that AZURE_DEVICE_CODE is not yet supported
        Here is the equivalent Entra ID error when logging in with SQLcl 25.1:
        To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ARSX62NBJ to authenticate.
        2025-04-16 09:20:46.198 SEVERE com.azure.core.util.logging.ClientLogger performDeferredLogging Azure Identity => ERROR in getToken() call for scopes [https://dbauthdemo.com/89746215-ea34-4a83-ac0e-46a68de97935/.default]: Failed to acquire token with device code.
        Connection failed
          USER          =
          URL           = jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))(SECURITY=(SSL_SERVER_DN_MATCH=TRUE)(WALLET_LOCATION=SYSTEM)(TOKEN_AUTH=AZURE_INTERACTIVE)(TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)(CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)(AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=pdb1)))


        Error: ORA-18951: NL exception was generated: TNS-04610: No literals left, reached end of NV pair
        Potential reasons for this error:
        • Occurs when attempting to connect via thin client with TOKEN_AUTH=AZURE_DEVICE_CODE and the previous authentication was successful but failed to get token (Error: ORA-18726)

        Error: ORA-25704: Token-based authentication requires client parameter SSL_SERVER_DN_MATCH=TRUE.
        Potential reasons for this error:
        • All Entra ID integration connections between Oracle database client require encrypted TLS connection with SSL_SERVER_DN_MATCH=TRUE

          Error: ORA-25714: invalid value of PASSWORD_AUTH or TOKEN_AUTH in the client configuration
          Potential reasons for this error:
          • OCI driver (e.g. sqlplus) or JDBC-thick driver version used is not supported. SQL*Plus 19.18 or newer is required
          • JDBC-thin driver appears to only work with 23.7 or newer

          Error: ORA-25718: Invalid value of CLIENT_ID in the client configuration
          Potential reasons for this error:
          • Occurs when CLIENT_ID is invalid format or bad value in connect string or TNS entry
          You may also see Entra ID Error message AADSTS90016:





          Error: ORA-25719: Invalid value of TENANT_ID in the client configuration
          Potential reasons for this error:
          • Occurs if the TENANT_ID is incomplete or invalid format in the connect string or TNS entry

          Error: ORA-25726: Invalid value of AZURE_CREDENTIALS in the client configuration
          Potential reasons for this error:
          • Occurs when no client credentials have been entered for TOKEN_AUTH=AZURE_SERVICE_PRINCIPAL

          Error: ORA-25724: Azure AD authentication timeout and Vendor Code: 25724
          Potential reasons for this error:
          • Occurs when pop-up browser connection to https://login.microsoftonline.com times out after 60 seconds
          • Test connection multiple times from your computer to Microsoft login with:
            • Linux: curl -ksL https://login.microsoftonline.com/
            • Windows Powershell: Invoke-WebRequest -Uri https://login.microsoftonline.com
          • Note that web connection test may require going through a web proxy if direct outbound connections are not permitted
          • If connection is successful some of the time, there may be a routing or firewall issue between your computer and Microsoft's login page
          • If connection fails every time, there is likely either a firewall constraint, routing issue or Microsoft login may be temporarily down

            Error: ORA-28547: connection to server failed, probable Oracle Net admin error
            Potential reasons for this error:
            • Combination ORA and Entra ID Error message AADSTS90009:

            or Entra ID Error message AADSTS90002:



              • This error occurs if you have not specified the correct TENANT_ID in the connect string or TNS entry
              • Entra ID authentication attempt either timed out or failed to authenticate properly
              • Occurs when incorrect CLIENT_ID value is specified in connect string or TNS entry

              Error: ORA-28759: failure to open file
              Potential reasons for this error:
              • WALLET_LOCATION of the connect string or TNS entry has specified a wallet path for which no wallet exists

                Error: ORA-28864: SSL connection closed gracefully
                Potential reasons for this error:
                • If you’ve specified the non-secure port number (Default: 1521) instead of the secure port number (Default: 2484) in the connect string or TNS entry
                • Note that the default autonomous database uses port 1521 for secure port

                Error: ORA-28865: SSL connection closed
                Potential reasons for this error:
                • The database server may have not yet set the wallet_root directory
                • Check to make sure that the wallet has been copied to the PDB GUID directory ($WALLET_ROOT/$pdbguid/tls) on the database server
                Set the database server wallet with:

                sqlplus / as sysdba
                SQL> alter system set wallet_root='/u01/app/oracle/19c/wallet_root' scope=spfile;
                SQL> shutdown immediate;
                SQL> quit;
                lsnrctl stop
                lsnrctl stop
                sqlplus / as sysdba
                SQL> startup;
                SQL> alter pluggable database all open;
                SQL> alter system register;
                SQL> quit;




                Error: ORA-29003: SSL transport detected mismatched server certificate.
                Potential reasons for this error:
                • Occurs the SSL_SERVER_CERT_DN value of the connect string or TNS entry does not match the certificate subject or subject alternative name (SAN) entries of the certificate
                • You can use the openssl command of a Linux host to ascertain the certificate and SAN entries of the database server with:

                $ echo | openssl s_client -connect hrdb.dbauthdemo.com:2484 2>&1 | openssl x509 -noout -text | egrep -i "DNS|subject"
                        Subject: CN=hrdb.dbauthdemo.com
                        Subject Public Key Info:
                            X509v3 Subject Alternative Name: 
                                DNS:hrdb.dbauthdemo.com, DNS:www.hrdb.dbauthdemo.com
                            X509v3 Subject Key Identifier:



                Error: ORA-29024: Certificate validation failure
                Potential reasons for this error:
                • This error can be caused by the signing certificate authority not being present in the client host certificate authority trust store
                • Use orapki on the database host to display the trusted certificate subject and confirm that this trusted certificate is in the client host
                  • orapki wallet display -complete  -wallet $WALLET_ROOT/tls  -pwd <wallet_password>
                • In Windows client, run mmc, add “Certificates” snap-in, look up “Trusted Root Certification Authorities” to see if the DN o the certificate authority matches the subject of the same certificate authority from orapki display
                • In Linux, return all of the CA certificate subjects with: openssl crl2pkcs7 -nocrl -certfile /etc/pki/tls/certs/ca-bundle.trust.crt | openssl pkcs7 -print_certs -noout





                   

                  Thursday, April 17, 2025

                  Entra ID Integration For SQL*Plus

                  SQL*Plus is the most commonly used command line tool for the Oracle database.  This tool uses the Oracle Call Interface (OCI) libraries and APIs to connect to the database.  The SQL*Plus comes in two distributions.  First, it is included with the full Oracle Database Server and full Oracle Database Client, which is available through Oracle Software Delivery Cloud. Second, SQL*Plus is an optional package of the Oracle instant client distribution that can be downloaded and installed along with the Oracle instant client. The Oracle instant client typically has a newer version of SQL*Plus that the full client.  However, two important things not included with the Oracle instant client include a JDK or the orapki command for certificate and wallet management. Fortunately, there are options for working around these limitations as my blog on the missing orapki tool reveals.

                  Install SQL*Plus Instant Client


                  2. Extract the Oracle Instant into your preferred path. In my lab, I extracted it into "C:\u01\app\instantclient_23_7"

                  3. Extract the SQL*Plus Package into the same path as the previous step


                  Install SQL*Plus Full Client


                  2. Extract the the full database client zip file (V1045016-01.zip for Windows) into the desired location. In my lab, I extracted the full database client into "C:\u01\app\fullcient_23.5"

                  3. Run the setup tool in the <odb_client_base> directory. In my case, "C:\u01\app\fullcient_23.5\setup.exe"

                  4. Complete the setup process plugging in your preferred location for the client installation.  Here are the screenshots from my setup where C:\u01\app is the Oracle base that I chose for my install.






                  Configure SQL*Plus Full Client For Entra ID Integration

                  1. Setup TLS client-side configuration for secure TLS encrypted connection to the Oracle database server.  This requires that the SQL*Plus have a trust store loaded with the self-signed, privately signed or publicly signed certificate of the Oracle database server.  If the Oracle database server certificate is signed by a public certificate authority, then your TNS entry or connect string for the oracle database server can use WALLET_LOCATION=SYSTEM because SQL*Plus is outsourcing the trust store to the trust store of the operating system of the host where SQL*Plus is running.  Otherwise, a wallet containing the self-signed or privately signed certificate will need to be setup on this host and WALLET_LOCATION will be set to the full path to that wallet folder.  For example, I use the following in my WALLET_LOCATION=C:\Users\DBClient\Desktop\tls.  Note that this wallet will need auto-enable setup on the wallet so that SQL*Plus won't be prompted for the wallet password every time that SQL*Plus uses that wallet.  Here is the sample invocation of orapki to enable auto_login on the wallet. 

                  orapki wallet create -wallet $WALLET_ROOT/tls -pwd Oracle123 -auto_login

                  More detailed instructions on how to create the client wallet for TLS communication are available on my One-way TLS ODB Client/Server With Self-signed Certificates In Wallets blog post.

                  2. Add TNS entries into the "<odb_client_base>\network\admin\tnsnames.ora" configuration file for the Entra ID entabled Oracle database servers.  The key distinction of Entra ID enabled entries are that they will have TLS configured requiring certificate DN matching and will include the Entra ID specific properties for identifying the SAML authentication flow, tenancy, client, and server IDs.

                  For both the instant and full clients, the tnsnames.ora is located in the <client_base>\network\admin folder.

                  In my case for instant client:

                  C:\u01\app\instantclient_23_7\network\admin\tnsnames.ora


                  In my case for full client:

                  C:\u01\app\fullclient_23.5\network\admin\tnsnames.ora


                  For your reference, here is a sample tnsname.ora entry to illustrate the requisite requirements for an Entra ID integrated connection string.

                  PDB1 = 
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
                      (SECURITY=
                        (SSL_SERVER_DN_MATCH=TRUE)
                        (WALLET_LOCATION=SYSTEM)
                        (TOKEN_AUTH=AZURE_INTERACTIVE)
                        (TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)
                        (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
                        (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621)
                      )
                      (CONNECT_DATA=
                        (SERVER=DEDICATED)
                        (SERVICE_NAME=pdb1)
                      )
                    )

                  The key differences to note from a normal service description are the requirement for encrypted (e.g. TLS based TCPS) connection and Entra ID configuration.

                  The TLS encryption is required between the database client and server to securely pass the access token between the client and server. These settings are highlighted in blue.

                  The Entra ID configuration is highlighted in red where:
                  • TOKEN_AUTH specifies the SAML authentication flow, which is interactive in this case
                  • TENANT_ID specifies the ID of the Azure/Entra ID tenancy
                  • CLIENT_ID specifies the registered Entra ID web application for the database client
                  • AZURE_DB_APP_ID_URI specifies the URI of the registered Entra ID web application of the database server
                  Note that WALLET_LOCATION is set to SYSTEM. This means that the database server's TLS certificate is signed by a public certificate authority for which the operating system already contains a copy of the certificate authorities certificate chain in the operating system trust store.  Therefore, a local wallet file containing the certificate authority's certificate chain or a self-signed certificate from the database server.
                  If the database server's certificate is self-signed or signed by a private certificate authority, then you will instead need to specify the path to the wallet that includes this information.  Here is an example of what the WALLET_LOCATION would look like in the TNS entry if you had to specify a path to the wallet folder:

                        (WALLET_LOCATION=C:\Users\DBClient\Desktop\tls)


                  Also, in addition to specifying that the TLS certificate subject or one of the subject alternative name entries (SAN) must match the HOST value of the service description (e.g. SSL_SERVER_DN_MATCH=TRUE), you can also specify the full DN of the certificate with the following where the value of SSL_SERVER_CERT_DN highlighed in red would need to exactly match the subject of the server's certificate:

                        (SSL_SERVER_CERT_DN="CN=hrdb.dbauthdemo.com")

                  If you are not certain what the value of the server's certificate is, you can determine it from a UNIX/Linux system with the openssl tool. Here is a sample invocation for your reference:

                  $ echo | openssl s_client -connect hrdb.dbauthdemo.com:2484 2>&1 | openssl x509 -noout -text | egrep -i "DNS|subject"
                          Subject: CN=hrdb.dbauthdemo.com
                          Subject Public Key Info:
                              X509v3 Subject Alternative Name: 
                                  DNS:hrdb.dbauthdemo.com, DNS:www.hrdb.dbauthdemo.com
                              X509v3 Subject Key Identifier:


                  Use SQL*Plus With Entra ID Integration

                  1. Connect to a database server through a SQL prompt or command invocation of SQL*Plus. For example:

                  cd C:\u01\app\instantclient_23_7
                  .\sqlplus /nolog
                  SQL> conn /@pdb1

                  or alternatively with a full command invocation for the instant client install:

                  cd C:\u01\app\instantclient_23_7
                  .\sqlplus /@pdb1

                  or alternatively with a full command invocation for the full client install:

                  cd C:\u01\app\fullclient_23.5
                  .\bin\sqlplus /@pdb1




                  2. A web browser window will open to the Microsoft login.  You select the desired account or add a new one.  If you don’t already have an authenticated session, it will prompt you for your password followed by entering in the code from the Microsoft authenticator application. 


                  3. Once successfully authenticated, the web browser window will indicate that authentication is complete and that you can close the web browser window.


                  At this point, the structure of database in SQL*Plus will be revealed in the Connections panel in accordance with the permissions granted to your user.

                  I hope you found this post helpful and informative.

                  Blessings!

                  Brad

                  Entra ID Integration For SQLDeveloper

                  SQLDeveloper has been one of the preferred Integrated Development Environment (IDE) for Oracle developers, database administrators and power users for decades. This powerful tool has been recently supplemented with the ability to centralize authentication, authorization, and user life cycle database management of Oracle database users through cloud native integration with Microsoft Entra ID.  This integration is made possible through the Azure (Entra ID) resource extensions available from the ojdbc-extensions libraries.  The setup of SQLDeveloper for Entra ID integration is straight forward.  Much of what you see in this blog post was a distillation and simplification of the work produced by Ty Stahl from his blog post of the same topic.

                  Setup SQLDeveloper For Entra ID Integration

                  1. The first step is to download SQLDeveloper and extract SQLDeveloper into your desired location.  In my lab, this is C:\Program Files\sqldeveloper.

                  2. The next step is to build ojdbc-extensions with Apache Maven or download them and place them in a subdirectory of <sqldeveloper_base> folder.  For example, I extracted the downloaded extensions into C:\Program Files\sqldeveloper such that the resulting ojdbc-extensions libraries are in the "C:\Program Files\sqldeveloper\sdks\jdbc-azure" folder.

                  3. Next, start and then stop SQLDeveloper in order to create the SQLDeveloper product.conf configuration file in <home>\AppData\Roaming\sqldeveloper\<version>.  

                  4. Update the "<home>\AppData\Roaming\sqldeveloper\<version>\product.conf" file with individual AddJavaLibFile reference for each of the ojdbc-extensions jar files.  In my case, here are the following entries added:

                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\accessors-smart-2.5.1.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\asm-9.6.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-core-1.54.1.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-core-http-netty-1.15.7.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-data-appconfiguration-1.7.3.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-identity-1.14.2.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-json-1.3.0.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-security-keyvault-secrets-4.9.1.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\azure-xml-1.1.0.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\content-type-2.3.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jackson-annotations-2.13.5.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jackson-core-2.13.5.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jackson-databind-2.13.5.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jackson-datatype-jsr310-2.15.2.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jackson-module-jaxb-annotations-2.12.2.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jcip-annotations-1.0-1.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jna-5.13.0.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\jna-platform-5.13.0.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\json-smart-2.5.1.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\lang-tag-1.7.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\msal4j-1.17.2.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\msal4j-persistence-extension-1.3.0.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-buffer-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-codec-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-codec-dns-4.1.112.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-codec-http-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-codec-http2-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-codec-socks-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-common-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-handler-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-handler-proxy-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-resolver-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-resolver-dns-4.1.112.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-resolver-dns-classes-macos-4.1.112.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-resolver-dns-native-macos-4.1.112.Final-osx-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.62.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.69.Final-linux-aarch_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.69.Final-linux-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.69.Final-osx-aarch_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.69.Final-osx-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-boringssl-static-2.0.69.Final-windows-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-tcnative-classes-2.0.69.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-classes-epoll-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-classes-kqueue-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-native-epoll-4.1.115.Final-linux-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-native-kqueue-4.1.115.Final-osx-x86_64.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\netty-transport-native-unix-common-4.1.115.Final.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\nimbus-jose-jwt-9.40.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\oauth2-oidc-sdk-11.18.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\ojdbc-provider-azure-1.0.4.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\ojdbc-provider-common-1.0.4.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\ojdbc8-23.4.0.24.05.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\reactive-streams-1.0.4.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\reactor-core-3.4.41.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\reactor-netty-core-1.0.48.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\reactor-netty-http-1.0.48.jar
                  AddJavaLibFile C:\Program Files\sqldeveloper\sdks\jdbc-azure\slf4j-api-1.7.36.jar


                  Use SQLDeveloper With Entra ID Integration

                  Once SQLDeveloper has been setup for Entra ID integration, the next step is to add Entra ID enabled Oracle databases to the configuration and use them.

                  1. Open SQLDeveloper

                  2. Add an Entra ID enabled database by clicking on the green plus symbol in the upper lefthand corner of the SQLDeveloper app and fill out the fields as follows:

                  Name: <datbase_name>
                  Database Type: Oracle
                  Authentication Type: OS
                  Connection Type: TNS
                  Network Alias: <TNS_Alias_Name>

                  Here is a sample screenshot from my lab environment:


                  3. Once the database has been added, double-click on the database in the "Connections" panel to initiate the authentication process. In my case, PDB1.



                  4. A web browser window will open to the Microsoft login.  You select the desired account or add a new one.  If you don’t already have an authenticated session, it will prompt you for your password followed by entering in the code from the Microsoft authenticator application. 


                  5. Once successfully authenticated, the web browser window will indicate that authentication is complete and that you can close the web browser window.


                  At this point, the structure of database in SQLDeveloper will be revealed in the Connections panel in accordance with the permissions granted to your user.



                  Troubleshooting

                  For your reference, here is a sample tnsname.ora entry to illustrate the requisite requirements for an Entra ID integrated connection string.

                  PDB1 = 
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
                      (SECURITY=
                        (SSL_SERVER_DN_MATCH=TRUE)
                        (WALLET_LOCATION=SYSTEM)
                        (TOKEN_AUTH=AZURE_INTERACTIVE)
                        (TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)
                        (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
                        (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621)
                      )
                      (CONNECT_DATA=
                        (SERVER=DEDICATED)
                        (SERVICE_NAME=pdb1)
                      )
                    )

                  The key differences to note from a normal service description are the requirement for encrypted (e.g. TLS based TCPS) connection and Entra ID configuration.

                  The TLS encryption is required between the database client and server to securely pass the access token between the client and server. These settings are highlighted in blue.

                  The Entra ID configuration is highlighted in red where:
                  • TOKEN_AUTH specifies the SAML authentication flow, which is interactive in this case
                  • TENANT_ID specifies the ID of the Azure/Entra ID tenancy
                  • CLIENT_ID specifies the registered Entra ID web application for the database client
                  • AZURE_DB_APP_ID_URI specifies the URI of the registered Entra ID web application of the database server
                  Note that WALLET_LOCATION is set to SYSTEM. This means that the database server's TLS certificate is signed by a public certificate authority for which the operating system already contains a copy of the certificate authorities certificate chain in the operating system trust store.  Therefore, a local wallet file containing the certificate authority's certificate chain or a self-signed certificate from the database server.
                  If the database server's certificate is self-signed or signed by a private certificate authority, then you will instead need to specify the path to the wallet that includes this information.  Here is an example of what the WALLET_LOCATION would look like in the TNS entry if you had to specify a path to the wallet folder:

                        (WALLET_LOCATION=C:\Users\DBClient\Desktop\tls)


                  Also, in addition to specifying that the TLS certificate subject or one of the subject alternative name entries (SAN) must match the HOST value of the service description (e.g. SSL_SERVER_DN_MATCH=TRUE), you can also specify the full DN of the certificate with the following where the value of SSL_SERVER_CERT_DN highlighed in red would need to exactly match the subject of the server's certificate:

                        (SSL_SERVER_CERT_DN="CN=hrdb.dbauthdemo.com")

                  If you are not certain what the value of the server's certificate is, you can determine it from a UNIX/Linux system with the openssl tool. Here is a sample invocation for your reference:

                  $ echo | openssl s_client -connect hrdb.dbauthdemo.com:2484 2>&1 | openssl x509 -noout -text | egrep -i "DNS|subject"
                          Subject: CN=hrdb.dbauthdemo.com
                          Subject Public Key Info:
                              X509v3 Subject Alternative Name: 
                                  DNS:hrdb.dbauthdemo.com, DNS:www.hrdb.dbauthdemo.com
                              X509v3 Subject Key Identifier:

                  I hope you found this post helpful and informative.

                  Blessings!

                  Brad

                  Entra ID Integration For SQLcl

                  SQLcl is a powerful java (jdbc) based tool from Oracle that is designed to be functionally equivalent to the SQLPlus command line tool. SQLcl was introduced in 2015 with version 4.1. Ten years later, SQLcl version 25.1 now supports cloud native integration with Microsoft Entra ID including multi-factor authentication for centralizing authentication, authorization, and user life cycle management of Oracle database users. 

                  Setup SQLcl For Entra ID Integration

                  The setup of SQLcl and it's Entra ID integration is incredibly simple.

                  1. The first step is to download SQLcl and extract the SQLcl zip file into your desired location. In my lab, that is in C:\u01\app where the resulting extracted path is C:\u01\app\sqlcl.

                  2. The next step is to start SQLcl with /nolog in the UNIX/Linux terminal or Windows command or powershell prompt of your choosing.  Note that the default invocation of SQLcl uses the jdbc thick driver. Therefore, we specify the -thin argument to use the jdbc thin driver.

                  C:\u01\app\sqlcl>.\bin\sql -thin /nolog


                  3. Download and install the jdbc-azure libraries from maven at the following SQLcl command prompt:

                  SQL> sdk install jdbc-azure


                  If there is an error or for some reason SQLcl cannot connect to the Maven repo to download the dependencies you can build the ojdbc-extensions yourself with Apache Maven or alternatively, you can download a bundled set of the version 1.0.4 ojdbc-extensions from here.

                  If you downloaded the bundled v1.0.4 set, you will extract them into the <sqlcl_base_directory>\lib directory. The resulting libraries should be located in <sqlcl_base_directory>\lib\sdks\jdbc-azure.


                  Use SQLcl With Entra ID Integration

                  Once SQLcl has been setup for Entra ID integration, the next step is to add Entra ID enabled Oracle databases to the configuration and use them.

                  0. If you want to specify a specific tnsnames.ora, set TNS_ADMIN to the folder of that file.

                  set TNS_ADMIN=SQLC:\u01\app\sqlcl\oracle\network\admin


                  1. Now that the requisite JDBC thin driver dependencies are satisfied, you can connect to a EntraID enabled database.  Connect to the database through SQL prompt

                  SQL> conn /@pdb1

                  or alternatively with a full command invocation:

                  C:\u01\app\sqlcl>.\bin\sql.exe -thin /@pdb1

                  2. A web browser window will open to the Microsoft login.  You select the desired account or add a new one.  If you don’t already have an authenticated session, it will prompt you for your password followed by entering in the code from the Microsoft authenticator application. 


                  3. Once successfully authenticated, the web browser window will indicate that authentication is complete and that you can close the web browser window.


                  At this point, the structure of database in SQLcl will be revealed in the Connections panel in accordance with the permissions granted to your user.

                  Troubleshooting

                  Note that the @pdb1 reads the service connection string from the tnsnames.ora from my system, which is located in my environment in C:\u01\app\oracle\network\admin.  If you specify a service name that cannot be determined from the tnsnames.ora file, you will see an error similar to the following:

                  Connection failed
                    USER          =
                    URL           = jdbc:oracle:thin:@pdb1
                    Error Message = ORA-12154: Cannot connect to database. Could not find alias pdb1 in C:\u01\app\oracle\network\admin/tnsnames.ora.
                  https://docs.oracle.com/error-help/db/ora-12154/

                  For your reference, here is a sample tnsname.ora entry to illustrate the requisite requirements for an Entra ID integrated connection string.

                  PDB1 = 
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
                      (SECURITY=
                        (SSL_SERVER_DN_MATCH=TRUE)
                        (WALLET_LOCATION=SYSTEM)
                        (TOKEN_AUTH=AZURE_INTERACTIVE)
                        (TENANT_ID=7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1)
                        (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
                        (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621)
                      )
                      (CONNECT_DATA=
                        (SERVER=DEDICATED)
                        (SERVICE_NAME=pdb1)
                      )
                    )

                  The key differences to note from a normal service description are the requirement for encrypted (e.g. TLS based TCPS) connection and Entra ID configuration.

                  The TLS encryption is required between the database client and server to securely pass the access token between the client and server. These settings are highlighted in blue.

                  The Entra ID configuration is highlighted in red where:
                  • TOKEN_AUTH specifies the SAML authentication flow, which is interactive in this case
                  • TENANT_ID specifies the ID of the Azure/Entra ID tenancy
                  • CLIENT_ID specifies the registered Entra ID web application for the database client
                  • AZURE_DB_APP_ID_URI specifies the URI of the registered Entra ID web application of the database server
                  Note that WALLET_LOCATION is set to SYSTEM. This means that the database server's TLS certificate is signed by a public certificate authority for which the operating system already contains a copy of the certificate authorities certificate chain in the operating system trust store.  Therefore, a local wallet file containing the certificate authority's certificate chain or a self-signed certificate from the database server.
                  If the database server's certificate is self-signed or signed by a private certificate authority, then you will instead need to specify the path to the wallet that includes this information.  Here is an example of what the WALLET_LOCATION would look like in the TNS entry if you had to specify a path to the wallet folder:

                        (WALLET_LOCATION=C:\Users\DBClient\Desktop\tls)


                  Also, in addition to specifying that the TLS certificate subject or one of the subject alternative name entries (SAN) must match the HOST value of the service description (e.g. SSL_SERVER_DN_MATCH=TRUE), you can also specify the full DN of the certificate with the following where the value of SSL_SERVER_CERT_DN highlighed in red would need to exactly match the subject of the server's certificate:

                        (SSL_SERVER_CERT_DN="CN=hrdb.dbauthdemo.com")

                  If you are not certain what the value of the server's certificate is, you can determine it from a UNIX/Linux system with the openssl tool. Here is a sample invocation for your reference:

                  $ echo | openssl s_client -connect hrdb.dbauthdemo.com:2484 2>&1 | openssl x509 -noout -text | egrep -i "DNS|subject"
                          Subject: CN=hrdb.dbauthdemo.com
                          Subject Public Key Info:
                              X509v3 Subject Alternative Name: 
                                  DNS:hrdb.dbauthdemo.com, DNS:www.hrdb.dbauthdemo.com
                              X509v3 Subject Key Identifier:


                  Earlier in this post, I mentioned using the thin jdbc driver.  It is also possible to use the thick driver as well. However, you first have to replace the <sqlcl_base>\lib\ojdbc11.jar library with the same file from an Oracle Database 23.5 client, which is located here <odb_client>\jdbc\lib\ojdbc11.jar.  This appears to be unique to the SQLcl 25.1 version that will hopefully be resolved with a future update.  Once the replacement of the ojdbc11.jar library file is complete, you can login with the thick version of the driver:

                  C:\u01\app\sqlcl>.\bin\sql.exe -thick /@pdb1

                  You will know that you need the ODB 23.5 client library if after running the above command, you see an error similar to the following:

                  Error Message = Incompatible version of libocijdbc[Jdbc:23702501, Jdbc-OCI:23502407


                  I hope you found this post helpful and informative.

                  Blessings!

                  Brad

                  Footnote:
                  Note from the JDBC downloads page that JDBC-OCI (a.k.a. JDBC thick driver) support will be deprecated starting with ODB 24ai. See MOS note 2953282.1 for Deprecation Notice.

                  Wednesday, April 9, 2025

                  orapki for Oracle instant client

                  DISCLAIMER: The following is not recommended or supported by Oracle. This is simply an illustration of a possible workaround to the absence of orapki in the instaclient. Oracle recommends that you install the full Oracle database client when orapki is required.

                  As part of a series targeted at enabling customers with Entra ID integration for centralizing Oracle database authentication, authorization and user life cycle management, I published several blog posts on setting up TLS between the Oracle database clients and servers.  One of the commands used for wallet and certificate management is orapki. The orapki tool is included with the full Oracle database client but not the instant client.

                  A customer asked how to manage wallets and certificates on the client side without the orapki tool.  The good news is that orapki is just a java wrapper script that calls the PKI (oracle.security.pki.textui.OraclePKITextUI) library.  Therefore, if you copy the requisite java libraries to the client host, you can use the java command to manage wallets and certificates. This blog post describes how to get the orapki functionality working on an instaclient deployment without installing the full Oracle database client.

                  First, you download the full Oracle client from eDelivery.  In this example, I downloaded the Oracle 23.5 full zip file (V1044259-01.zip) for linux and put it in a subdirectory named pkilib of my Oracle 23.7 instacient base directory.

                  $ cd /u01/app/oracle/instantclient_23_7
                  $ mkdir pkilib
                  $ cd pkilib

                  Next, I extract the requisite jar files from the Full Oracle client installer.

                  $ unzip -q /tmp/V1044259-01.zip  client/stage/Components/oracle.crypto.*
                  $ unzip -q client/stage/Components/oracle.crypto.pki/23.0.0.0.0/1/DataFiles/filegroup1.jar  jlib/oraclepki.jar
                  $ unzip -q client/stage/Components/oracle.crypto.rsa/23.0.0.0.0/1/DataFiles/filegroup1.jar  jlib/*
                  $ mv jlib/* .
                  $ rm -fr client


                  Next, set the JAVA_HOME and a short variable for the jar files.

                  $ export JAVA_HOME=/u01/sw/jdk-21.0.6
                  $ pl="/u01/app/oracle/instantclient_23_7/pkilib/oraclepki.jar:/u01/app/oracle/instantclient_23_7/pkilib/cryptojce.jar"

                  If FIPS 140 compliance is required, you'll also need to add cryptojcommon.jar and jcmFIPS.jar in the pkilib to the pl string as well.

                  Now you can use java to perform orapki functions.  For example, let's create a wallet with auto_login enabled.

                  $ $JAVA_HOME/bin/java -classpath "$pl" oracle.security.pki.textui.OraclePKITextUI wallet create -wallet wallet -pwd Oracle123 -auto_login
                  Oracle PKI Tool Release 23.0.0.0.0 - Production
                  Version 23.0.0.0.0
                  Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.

                  Operation is successfully completed.

                  Here is the command to display the wallet.

                  $ $JAVA_HOME/bin/java -classpath "$pl" oracle.security.pki.textui.OraclePKITextUI wallet display -wallet wallet -pwd Oracle123
                  Oracle PKI Tool Release 23.0.0.0.0 - Production
                  Version 23.0.0.0.0
                  Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.

                  Requested Certificates: 
                  User Certificates:
                  Trusted Certificates: 


                  Here's the Microsoft Windows equivalent using powershell.

                  cd \u01\app\instantclient_23_7

                  mkdir pkilib

                  cd pkilib

                  Expand-Archive -Path C:\u01\app\V1045016-01.zip -DestinationPath client

                  Move-Item -Path client\jlib\cryptojce.jar -Destination .

                  Move-Item -Path client\jlib\oraclepki.jar -Destination .

                  Remove-Item -Recurse -Force client

                  $env:JAVA_HOME="C:\Program Files\Java\jdk-17"

                  $env:PATH="$env:JAVA_HOME\bin;" + $env:Path

                  $env:pl="C:\u01\app\instantclient_23_7\pkilib\oraclepki.jar;C:\u01\app\instantclient_23_7\pkilib\cryptojce.jar"

                  java -classpath $env:pl oracle.security.pki.textui.OraclePKITextUI wallet create -wallet wallet -pwd Oracle123 -auto_login

                  java -classpath $env:pl oracle.security.pki.textui.OraclePKITextUI wallet display -wallet wallet -pwd Oracle123
                   




                  Thanks to the following to people that provided similar references to accomplish the same.

                  Thursday, March 13, 2025

                  Oracle Unified Directory 14c

                  Oracle Unified Directory (OUD) 14c along with the rest of the 14c Identity and Access Management suite is now available. Details at https://blogs.oracle.com/cloud-infrastructure/post/identity-and-access-management-14c.


                  You can download from https://edelivery.oracle.com.  Search on "Oracle Enterprise Identity Services Suite Plus 14.1.2.1.0 ( Oracle Directory Services Plus)"

                  The technology release for evaluation is also available at https://www.oracle.com/security/identity-management/technologies/downloads.

                  The OUD 14c version is designed to be easily upgraded from OUD 12c OUD 14c and now supports the JDK 17 and 21 and the current release of Berkeley Database Java Edition Upgrade. The security posture has continued to increase by enabling TLS v1.3 and deprecating TLS v1.1 by default and changed the default keystore from JKS to PKCS12.

                  Blessings!

                  Brad

                  Thursday, November 7, 2024

                  One-way TLS ODB Client/Server With CA-signed Certificates In OS Truststore

                  In recent months, I've helped many customers understand there options for centralizing Oracle Database authentication.  One of those options requires Transport Layer Security (TLS) connection between the database client and database server in order to securely pass an access token to the database server.  When customers want to evaluate this solution, one of their challenges is how to setup TLS between the database and server for a proof of concept or internal validation.  There are three approaches that customers can take for setting up TLS between client and server:

                  1. Self-signed private certs with wallets - For demonstrations and proofs of concept
                  2. Self-signed private certs with host trust store - Next step toward production
                  3. Publicly signed certs - For production

                  The focus of this blog post is on the third of the three.

                  Here's the streamlined workflow that I use for setting up one-way TLS between Oracle Database client and server where the client wallet is distributed to Oracle Database clients. This comes from the Oracle Database security guide at https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/configuring-transport-layer-security-encryption.html#GUID-03F216A2-76E0-47C9-9751-6F2D39BD75A1

                  As a side note, if you are not familiar with the WALLET_ROOT database parameter, please familiarize yourself with it at https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/WALLET_ROOT.html because it plays a large role in several security configuration options of the Oracle database including configuring TLS.

                  When specifying the SSL_CIPHER_SUITES in the database listener.ora and client tnsnames.ora, you will want to select the strongest cipher suites from the desired SSL_Version (1.3 or 1.2) that you want to support that all of the database clients support.  In this example, we will use version 1.2 and cipher suite TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384.

                  The full list of supported SSL_VERSION and SSL_CIPHER_SUITES values per database version are available here:



                  Step 1: Generate, sign and load database server certificate by public certificate authority

                  1.1 Setup the database server environment variables and make wallet directory

                  ssh opc@hrdb.example.com
                  export ORACLE_BASE="/u01/app/oracle/19c"
                  export ORACLE_HOME="$ORACLE_BASE/dbhome_1"
                  export WALLET_ROOT="$ORACLE_BASE/wallet_root"
                  PATH=$ORACLE_HOME/bin:$PATH
                  mkdir -p $WALLET_ROOT/tls

                  1.2 Create autologin wallet 

                  orapki wallet create -wallet $WALLET_ROOT/tls -pwd Oracle123 -auto_login


                  1.3 Download and load the trusted root certificate chain (sf_bundle-g2-g1.crt) from the certificate authority and load into the wallet 

                  orapki wallet add -wallet $WALLET_ROOT/tls -pwd Oracle123 -trusted_cert -cert $WALLET_ROOT/sf_bundle-g2-g1.crt


                  1.4 Create a private key for the database server using the fully qualified hostname for the distinguished name (DN). 

                  orapki wallet add -wallet $WALLET_ROOT/tls -pwd Oracle123 -keysize 2048 -dn CN=hrdb.example.com


                  1.5 Export a certificate request to be signed by the certificate authority 

                  orapki wallet export -wallet $WALLET_ROOT/tls -pwd Oracle123 -dn CN=hrdb.dbauthdemo.com -request hrdb.csr


                  1.6 Sign the certificate through the certificate authority and download the signed certificate


                  1.7 Load the signed certificate (31e303219bbcf898.crt) into the wallet

                  orapki wallet add -wallet $WALLET_ROOT/tls -pwd Oracle123 -user_cert -cert 31e303219bbcf898.crt


                  1.8 Show the contents of the wallet

                  orapki wallet display -complete  -wallet $WALLET_ROOT/tls -pwd Oracle123


                  Step 2: Create client wallet for 19c database clients that don't support WALLET_LOCATION=SYSTEM

                  2.1 Create client wallet
                  The purpose of the client wallet is to create a wallet that has the signing certificate authority's certificate (or certificate chain).

                  mkdir -p $WALLET_ROOT/client_wallet/tls
                  orapki wallet create -wallet $WALLET_ROOT/client_wallet/tls -pwd Oracle123 -auto_login
                  orapki wallet add -wallet $WALLET_ROOT/client_wallet/tls -pwd Oracle123 -trusted_cert -cert $WALLET_ROOT/sf_bundle-g2-g1.crt


                  2.1 Copy client wallet to 19c database client hosts

                  rsync -Have ssh $WALLET_ROOT/client_wallet/tls/. opc@clientdb:/u01/app/oracle/tls 



                  Step 3: Configure 19c database server

                  3.1 Setup the database server environment variables on the hrdb host.

                  export ORACLE_BASE="/u01/app/oracle/19c"
                  export ORACLE_HOME="$ORACLE_BASE/dbhome_1"
                  export ORACLE_SID="hrdb"
                  export TNS_ADMIN="$ORACLE_HOME/network/admin"

                  PATH=$ORACLE_HOME/bin:$PATH


                  3.2 Configure sqlnet.ora

                  cat $ORACLE_HOME/network/admin/sqlnet.ora
                  SQLNET.AUTHENTICATION_SERVICES = (TCPS,NTS,BEQ)
                  SSL_CLIENT_AUTHENTICATION = FALSE
                  SSL_VERSION = 1.2
                  SSL_CIPHER_SUITES = (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)


                  3.3 Configure listener.ora

                  cat $ORACLE_HOME/network/admin/listener.ora
                  SSL_CLIENT_AUTHENTICATION = FALSE

                  LISTENER =
                    (DESCRIPTION_LIST =
                      (DESCRIPTION =
                        (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.example.com)(PORT = 1521))
                        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
                        (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.example.com)(PORT = 2484))
                        (SECURITY=(WALLET_LOCATION=/u01/app/oracle/19c/wallet_root/tls))
                      )
                    )

                  ADR_BASE_LISTENER = /u01/app/oracle/19c

                  3.4 Set the wallet_root parameter and restart the database and listener

                  sqlplus / as sysdba
                  SQL> alter system set wallet_root='/u01/app/oracle/19c/wallet_root' scope=spfile;
                  SQL> shutdown immediate;
                  SQL> quit;
                  lsnrctl stop
                  lsnrctl stop
                  sqlplus / as sysdba
                  SQL> startup;
                  SQL> 
                  alter pluggable database all open;
                  SQL> alter system register;
                  SQL> quit;

                  3.5 Configure host firewall of database server to allow inboud (a.k.a. ingress) connections to non-secure port (1521) and secure port (2848)

                  sudo firewall-cmd --permanent --zone=public --add-port=1521/tcp
                  sudo firewall-cmd --permanent --zone=public --add-port=2484/tcp
                  sudo firewall-cmd --reload
                  sudo firewall-cmd --list-all


                  Step 4: Configure 19c database client

                  Instructions for downloading 19c database client at https://www.braddiggs.com/2024/11/setup-production-oracle-19c-database.html

                  4.1 Setup the database client environment variables

                  export ORACLE_BASE="/u01/app/oracle/19c"
                  export ORACLE_HOME="$ORACLE_BASE/client"
                  export LD_LIBRARY_PATH="$ORACLE_HOME/lib"
                  PATH=$ORACLE_HOME/bin:$PATH


                  4.2 Extract the 19c database client

                  mkdir -p $ORACLE_HOME
                  cd 
                  $ORACLE_HOME
                  unzip -qo /u01/bits/
                  V982065-01.zip


                  4.3 Add database configurations to tnsnames.ora setting the WALLET_LOCATION to SYSTEM to use the operating system trust store, which includes all major public certificate authorities.  Note that the HOST value should be the fully qualified hostname of the database server.

                  cat $ORACLE_HOME/network/admin/tnsnames.ora
                  HRDB =
                    (DESCRIPTION =
                      (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.example.com)(PORT = 1521))
                      (CONNECT_DATA =
                        (SERVER = DEDICATED)
                        (SERVICE_NAME = hrdb)
                      )
                    )

                  HRDB_SSL =
                    (DESCRIPTION =
                      (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.example.com)(PORT = 2484))
                      (SECURITY=(WALLET_LOCATION=SYSTEM))
                      (CONNECT_DATA =
                        (SERVER = DEDICATED)
                        (SERVICE_NAME = hrdb)
                      )
                    )

                  pdb1 =
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCP)(HOST=hrdb.example.com)(PORT=1521))
                      (CONNECT_DATA=
                        (SERVER = DEDICATED)
                        (SERVICE_NAME=pdb1)
                      )
                    )

                  pdb1_ssl =
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.example.com)(PORT=2484))
                      (SECURITY=(WALLET_LOCATION=SYSTEM))
                      (CONNECT_DATA=
                        (SERVER=dedicated)
                        (SERVICE_NAME=pdb1)
                      )
                    )


                  4.4 Configure sqlnet.ora

                  cat $ORACLE_HOME/network/admin/sqlnet.ora
                  WALLET_LOCATION=
                    (SOURCE=  
                      (METHOD=file)    
                      (METHOD_DATA=    
                        (DIRECTORY=/u01/app/oracle/tls)
                      )
                    )

                  SQLNET.AUTHENTICATION_SERVICES = (TCPS,NTS,BEQ)
                  SSL_CLIENT_AUTHENTICATION = FALSE
                  SSL_VERSION = 1.2
                  SSL_CIPHER_SUITES=(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)


                  Step 5: Test 19c client connections to the database

                  5.1 Setup the database client environment variables

                  export ORACLE_BASE="/u01/app/oracle/19c"
                  export ORACLE_HOME="$ORACLE_BASE/client"
                  export LD_LIBRARY_PATH="$ORACLE_HOME/lib"
                  PATH=$ORACLE_HOME/bin:$PATH


                  5.2 Test to the container database (CDB) hrdb_ssl

                  sqlplus system/Oracle123@hrdb_ssl


                  5.3 Test to the pluggable database (PDB) pdb1_ssl

                  sqlplus system/Oracle123@pdb1_ssl


                  Step 6: Configure 23ai database client

                  Instructions for downloading 23ai database client at https://www.braddiggs.com/2024/11/setup-production-oracle-23ai-database.html

                  6.1 Setup the database client environment variables

                  export ORACLE_BASE="/u01/app/oracle/23ai"
                  export ORACLE_HOME="$ORACLE_BASE/client"
                  export LD_LIBRARY_PATH="$ORACLE_HOME/lib"
                  PATH=$ORACLE_HOME/bin:$PATH


                  6.2 Extract the 23ai database client

                  mkdir -p $ORACLE_HOME
                  cd 
                  $ORACLE_HOME
                  unzip -qo /u01/bits/
                  V1044258-01.zip


                  6.3 Add database configurations to tnsnames.ora setting the WALLET_LOCATION to SYSTEM

                  cat $ORACLE_HOME/network/admin/tnsnames.ora
                  HRDB =
                    (DESCRIPTION =
                      (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.example.com)(PORT = 1521))
                      (CONNECT_DATA =
                        (SERVER = DEDICATED)
                        (SERVICE_NAME = hrdb)
                      )
                    )

                  HRDB_SSL =
                    (DESCRIPTION =
                      (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.example.com)(PORT = 2484))
                      (SECURITY=(WALLET_LOCATION=SYSTEM))
                      (CONNECT_DATA =
                        (SERVER = DEDICATED)
                        (SERVICE_NAME = hrdb)
                      )
                    )

                  pdb1 =
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCP)(HOST=hrdb.example.com)(PORT=1521))
                      (CONNECT_DATA=
                        (SERVER = DEDICATED)
                        (SERVICE_NAME=pdb1)
                      )
                    )

                  pdb1_ssl =
                    (DESCRIPTION=
                      (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.example.com)(PORT=2484))
                      (SECURITY=(WALLET_LOCATION=SYSTEM))
                      (CONNECT_DATA=
                        (SERVER=dedicated)
                        (SERVICE_NAME=pdb1)
                      )
                    )


                  6.4 Configure sqlnet.ora

                  cat $ORACLE_HOME/network/admin/sqlnet.ora
                  SQLNET.AUTHENTICATION_SERVICES = (TCPS,NTS,BEQ)
                  SSL_CLIENT_AUTHENTICATION = FALSE
                  SSL_VERSION = 1.2
                  SSL_CIPHER_SUITES = (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)


                  Step 7: Test 23ai client connections to the database

                  Instructions for downloading 23ai database client at https://www.braddiggs.com/2024/11/setup-production-oracle-23ai-database.html

                  7.1 Setup the database client environment variables

                  export ORACLE_BASE="/u01/app/oracle/23ai"
                  export ORACLE_HOME="$ORACLE_BASE/client"
                  export LD_LIBRARY_PATH="$ORACLE_HOME/lib"
                  PATH=$ORACLE_HOME/bin:$PATH


                  7.2 Test to the container database (CDB) hrdb_ssl

                  sqlplus system/Oracle123@hrdb_ssl


                  7.3 Test to the pluggable database (PDB) pdb1_ssl

                  sqlplus system/Oracle123@pdb1_ssl


                  For troubleshooting, see my blog post on Troubleshooting Oracle One-way TLS Connection Errors.