Fundamental Security Part Six– Network Encryption

August 2023 – Oracle 19C

We have considered observability. Knowing where you may have a security problem. We now need to look at removing some of the main problems associated with Oracle databases. Lets start with Network Security.

By default, all data travelling over the network with Oracle is unencrypted. This means that anyone with something like Wireshark can inspect packets and read your data as it travels between the client/application and the database. This is not secure. You are going to want to encrypt this data.

There are 2 options when it comes to encryption; implement Transport Layer Security (TLS) using certificates or use Oracle Native Network Encryption and Integrity (note: these used to be part of the Advanced Security Option but is now free with all supported Oracle versions from Oracle 10 onwards)


Transport Layer Security (TLS)

This involves generating and signing a certificate, and putting it into an Oracle Wallet on the database server, and also including the same certificate on each Oracle client or application server needing to connect to the database. You then need to do the same on each client and add the certificate to the database server wallet. This can provide full standard TLS encryption, but at a cost of certificate management. Certificates must expire, and many companies require certificates to be signed by a Certificate Authority, which should impose a maximum lifespan of 1 year on the certificate. When the certificates expire, they need to be replaced. It is possible to link directly to a CA to assist with this, depending upon your setup, but that is beyond the scope of this blog post. Maybe later…

It’s a good idea to use certificate management software to perform this function, otherwise you probably have a never-ending task “like painting the Forth Bridge“.

WARNING! One of the commonest causes of system
outage in the IT industry is an expired certificate

For an example of implementing TLS, please check-out this blog post by Tim Hall

Note that TLS will require you to make both server-side and client-side changes (to every client which connects to the database).

To check if your session is running with encrypted TCPS (rather than TCP), you can issue the following command:

SELECT sys_context('USERENV', 'NETWORK_PROTOCOL') as network_protocol FROM dual;

NETWORK_PROTOCOL
----------------
tcps

As the following Twitter conversation shows, there are alternate ways to configure TLS. You could just generate your own signed certificate on each box, exchange it and hope nobody compromises it. You could just use a single signed and trusted root cert from your CA. It can be simpler, but there are inevitably trade-offs involved.


Oracle Native Network Encryption and Integrity (ONNEI or ANO)

The first thing you should look to do if you are not encrypting network traffic is to implement Oracle Native Network Encryption and Integrity (formerly Advanced Networking Option – ANO). Largely because it’s so simple, so easy to implement and will also show where you have older clients which need to be upgraded.

So what does the name mean? Encryption and Integrity. When you encrypt data you need good Encryption. You also need to ensure nobody has changed the data in transit. Integrity (or checksums). The industry standard algorithms at the moment are AES256 for encryption and SHA384 for crypto-checksumming.

Configuring ONNEI

One of the advantages of using the native encryption is that you can enable this server-side only. You may not need to make any changes at all to the clients, if the client or (JDBC) drivers are sufficiently up to date. Setup in REQUESTED mode to start with, so any non-compliant clients will still connect unencrypted.

Edit the sqlnet.ora file on the tns listener home on the database server(s) and add:

SQLNET.ENCRYPTION_SERVER = REQUESTED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256)
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUESTED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA384)

NOTE: the sqlnet.ora file is re-read dynamically every time there is a new database connection. Changing the file will immediately cause new connections to encrypt

Monitor connections to ensure they are encrypting:

SELECT sys_context('USERENV', 'NETWORK_PROTOCOL') as network_protocol FROM dual;

NETWORK_PROTOCOL
----------------
tcp

Ah! We are not using TLS so we aren’t encrypting as TCPS. The encryption is Oracle Native. The packets are not fully encrypted. Only the contents (your data!) are subject to encryption. We therefore need another method.

Looking at GV$SESSION_CONNECT_INFO, we can see 2 lines which would not normally be present, showing AES256 and SHA384 encryption. The SQL below restricts the output to your session. Remove the WHERE clause and you can see the encryption for every session. (You can sort-of use this view to see if the connection is using TCPS as the line “TCP/IP NT Protocol Adapter for Linux:…..” will not exist.)

Note that we are using REQUESTED and not REQUIRED at this stage, so some connections may have only 3 lines of output, some may have 5. Also, if you have note specified the level of encryption required, this is also reflected in the output (e.g. in 19C, the default is AES256 but the weak algorithm for checksumming, SHA1)

ONNEI

SELECT sys_context('USERENV', 'NETWORK_PROTOCOL') as network_protocol FROM dual;

NETWORK_PROTOCOL
----------------
tcp

SELECT network_service_banner FROM gv$session_connect_info 
      WHERE sid IN (SELECT DISTINCT sid FROM v$mystat) ORDER BY 1;

NETWORK_SERVICE_BANNER
----------------------------------------------------------------------------
AES256 Encryption service adapter for Linux: Version 19.0.0.0.0 - Production
Crypto-checksumming service for Linux: Version 19.0.0.0.0 - Production
Encryption service for Linux: Version 19.0.0.0.0 - Production
SHA384 Crypto-checksumming service adapter for Linux: Version 19.0.0.0.0 - P
TCP/IP NT Protocol Adapter for Linux: Version 19.0.0.0.0 - Production

TLS

SELECT sys_context('USERENV', 'NETWORK_PROTOCOL') as network_protocol FROM dual;

NETWORK_PROTOCOL
----------------
tcps

SELECT network_service_banner FROM gv$session_connect_info
WHERE sid IN (SELECT DISTINCT sid FROM v$mystat) ORDER BY 1;

NETWORK_SERVICE_BANNER
----------------------
Crypto-checksumming service for Linux: Version 19.0.0.0.0 - Production
Encryption service for Linux: Version 19.0.0.0.0 - Production

(if you are using both ONNEI and TLS, you may also get the SHA384 line)
One you are happy that all connections are encrypting successfully, change from REQUESTED to REQUIRED. This will reject any connection attempts which cannot encrypt.
SQLNET.ENCRYPTION_SERVER = REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256)
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA384)

All done. 1 or 2 changes to sqlnet.ora and you’re enforcing encryption over the network.

You can also confirm the protocol (tcp v tcps) used if you are auditing successful logons (you should be!)

SELECT dbusername,authentication_type FROM unified_audit_trail;

dbu  authentication_type
---  -------------------
TIM  (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.194)(PORT=63849))));
NEIL (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcps)(HOST=192.168.56.193)(PORT=44317))));

Performance Impact

All encryption comes with a CPU requirement. You will burn more CPU on the client and server encrypting and decrypting traffic. You also add a few milliseconds latency at connect time for the handshake (although for most databases systems using stable connection pools, this should not be noticeable)

Extra CPU is usually in the 1%-5% range for Oracle DB network encryption, although you do need to test as it will vary across applications. There is minimal difference between using TLS and ONNEI, although the TLSv1.3 handshake has been performance optimised over TLSv1.2, I have not re-tested for any performance difference at this point and if you are using connection pooling there will be no noticeable difference.

Conclusion – what should I use?

Both. One of the important things to remember about ONNEI is that it doesn’t use TLS, so it’s not using an “industry standard” protocol. Your security team may insist upon having TLSv1.2 or 1.3. However, it is encrypting/checksumming to the same standard so there is very little to choose between the 2 methods.

If you use pre-exchanged TLS certificates associated only with each server, you do have the advantage that you cannot fall foul of a man-in-the-middle attack. This is possible, although difficult, with ONNEI. Simple eavesdropping will not be possible.

However, you don’t need to choose to get started. You can set the sqlnet.ora parameter:

IGNORE_ANO_ENCRYPTION_FOR_TCPS=TRUE

This allows ONNEI to be used if the connection if not TLS encrypted, but ignores the ONNEI config for already encrypted connections.

So, setup ONNEI, monitor it for old client connections, then consider if you need to explicitly encrypt using TLS for some or all of your connections with the overhead that entails.

Next lets talk about Data Encryption At Rest

Running RAC in a Virtual Environment

I was in a discussion at an Oracle Meetup this week, and the subject of RAC in a virtualized environment – specifically Oracle Virtual Machine (OVM) – came up.
Here’s a couple of points which were discussed.

pingtarget

There was a lack of awareness of a common problem, which has a solution built-in to Oracle 12.1.0.2 Grid Infrastructure and later. In a virtualized environment, the network components are also virtualized. Sometimes, network failures on the host may not be raised up to the guests. As a result, the guest O/S commands can fail to detect the network failures and the Virtual NIC remains up. Grid Infrastructure (GI) will not perform a VIP fail-over as it can’t see the failure despite the network being unavailable.

To resolve this, Oracle has added an option of a “pingtarget” for each public network defined in GI. This will perform a keep-alive to a external device, usually something like the default gateway. This is just like the heartbeat on the cluster interconnect.

Before

srvctl config network

Network 1 exists

Subnet IPv4: 192.168.0.160/255.255.255.224/eth1, static
Subnet IPv6:
Ping Targets:
Network is enabled
Network is individually enabled on nodes:
Network is individually disabled on nodes:

The default gateway makes a good ping target. For this IP and subnet, it’s 192.168.0.161

srvctl modify network -k 1 -pingtarget 192.168.0.161

After

srvctl config network

Network 1 exists

Subnet IPv4: 192.168.0.160/255.255.255.224/eth1, static
Subnet IPv6:
Ping Targets: 192.168.0.161
Network is enabled
Network is individually enabled on nodes:
Network is individually disabled on nodes:

All safe!

Server Pools

A second item we discussed was the Server Pools in OVM. Each RAC guest should be on a different host, otherwise you have not eliminated that as a Single Point Of Failure. A second less obvious SPOF is the Server Pool disk.

A Server Pool is a filesystem LUN (and IP address prior to release 3.4) used to group a logical collection of servers with similar CPU models, within which we can create and migrate VM guests. For a RAC installation, each RAC node should be within a different server pool, as well as on different physical hardware.

ovs

In this image, RAC nodes within the same cluster should be created within each server pool. This configuration can safely support a 2 node cluster despite having 4 servers, with one node created in “OVS-Pool-2” on server “ovs02“. The second node should be in “OVS-Pool-1″ and can be on “ovs01“, “ovs11” or “ovs12“.

It is possible to live migrate guests between these 3 servers.