Db2

Db2

Connect with Db2, Informix, Netezza, open source, and other data experts to gain value from your data, share insights, and solve problems.

 View Only

Db2 and TLS: Part 1 – TLS on the Db2 Server

By Cyrus Ng posted 2 hours ago

  

Setting up TLS in Db2 may seem like a daunting task but it doesn’t have to be. 

The use of Transport Layer Security (TLS), the industry standard for the encryption of data in transit, has exploded over the past decade. Db2 has supported TLS for a long time now, with TLS 1.2 and TLS 1.3 being the currently supported versions. All it takes are a few extra steps, and your database and applications will be securely talking on the network. 

In this first part of a series of blogs, we will break down common TLS scenarios you may encounter with Db2, potential mistakes that can be made, and how you as a database administrator can resolve them. While we will briefly summarize important TLS concepts throughout this series, some basic familiarity with these concepts is expected.  

Without further delay, let’s get right into setting up TLS on our server for the first time. 

Configuration of the Db2 server 


Configuring the Db2 server for TLS is done at the instance level using the database manager configuration (DBM cfg) and the DB2COMM registry variable. Specifically, the following DBM cfg parameters are relevant to the configuration: 

  • SSL_SVR_KEYDB: defines the path to the keystore used by the server to store the TLS certificate.  
  • SSL_SVR_STASH: defines the path to the stash file used for SSL setup. 
  • SSL_SVR_LABEL: defines the label for the SSL certificate in the keystore. 
  • SSL_SVCENAME: defines the SSL service name or port number. 

You may not be familiar with some of the key concepts such as keystores or stash files mentioned above, so let’s take a look at this before setting these parameters up.

Keystore and Stash Files 

TLS uses objects called certificates, which serve to represent the identity of your server during the TLS handshake.  The handshake is a negotiation process to establish a secure session between the client and the server. Certificates are stored in a keystore. TLS keystores for Db2 are usually created using GSKit, an IBM cryptographic and key management provider. To create a keystore, use the following command: 

gsk8capicmd_64 –keydb –create –db /home/db2inst1/server.p12 -pw <password> -stash 

This command will create a keystore at /home/db2inst1/server.p12. If a path is not given, the keystore is created in the current directory. The keystore needs to be in a location that is accessible by the instance owner and protected from unintended overwrites. For example, the instance owner’s home directory is a good place for this. In contrast, the instance directory is not a good place for this, since the instance directory is often recreated during an upgrade. Note the full path to your keystore for later.  

The format of the keystore depends on the extension you provided on the command, which will be “.p12” for a PKCS12 keystore, or “.kdb” for a KDB keystore. Alternatively, you can use the “-type” option to provide the keystore format. We recommend PKCS12 keystores – they're easier to work with and if you run into trouble, they are compatible with a wider variety of tools such as OpenSSL compared to KDB keystores, which is an IBM proprietary format. 

You may have noticed that we provided a “-stash” option in our command. This option creates a stash file for our keystore, which is a binary blob file that effectively represents our provided password. Db2 will use this file to automatically open the keystore. Otherwise, you’d have to provide the keystore’s password every single time the keystore is accessed... which can be a lot! In later commands to use and access the keystore, we will supply the “–stashed” option on subsequent gsk8capicmd_64 commands so we don’t have to type in our password. This file is created in the same directory as our keystore with the same name as our keystore, but with “.sth” as the file extension. In our case, our stash file would be at /home/db2inst1/server.sth. As before, note the full path to the stash file for later.  

Your keystore will contain the certificates used for TLS, so remember to back it up. Also remember your stash file whenever you back up your keystore! 

On Windows, Db2 supports using the native Microsoft Certificate Store. If you choose to use this, you will not have to create a keystore and stash file. You can refer to our documentation for further information about this option. 

There are two other things we need: the certificate that will represent our server and the port Db2 will listen on for TLS connections. Let’s start with TLS certificates. 

Certificates 

Now that we have a keystore, we need to create a certificate to represent our server. This will be stored in our keystore and be accessed when  

Certificates and the infrastructure surrounding them are designed around a system of trust. A certificate can be trusted because there is someone/something else vouching for it. This someone/something is called a certificate authority (CA). CAs sign certificates indicating they vouch for the authenticity of the certificate. The chain that gets created when CAs vouch for each other and the endpoint certificate is called a certificate chain. When a certificate is signed by a CA, we call them CA-signed certificates. 

It is good to mention here that there is also something called a self-signed certificate which  are essentially certificates that vouch for themselves. However, in most cases, you will likely want to use a CA-signed certificate. For example, if you have multiple clients connecting to many different databases and instances, a single CA can enable the client to form a TLS session with all databases using the same CA. If a self-signed certificate was used instead, each individual certificate would need to be copied over to each client. However, a self-signed certificate may be appealing if it is in a test environment or if only one or a few instances and a limited number of clients are being used. 

Self-Signed certificate 

To create a self-signed certificate, run: 

gsk8capicmd_64 –cert –create –db /home/db2inst1/server.p12 -label mylabel-dn ‘cn=Test’ -stashed 

This will create a certificate with the label “mylabel” in the keystore “/home/db2inst1/server.p12”. The “-dn” option provides the distinct name of our certificate – the only required part of this name is “CN”. 

TLS certificates have a public key and a private key. This is important; the server must have both. You can check by listing the certificates in the keystore: 

gsk8capicmd_64 –cert –list –db path/to/server.p12 -stashed 

This will give output looking like this: 

Certificates found 

* default, - personal, ! trusted, # secret key 

-       mylabel 

 

Note the “-” beside our “mylabel”. This indicates that the certificate has both the public and private key in the keystore. 

CA-Signed Certificates 

Db2 supports using CA-signed as well. To do this, we need to create a Certificate Signing Request: 

gsk8capicmd_64 -certreq -create -label mylabel -db /home/db2inst1/server.p12 -stashed -file /path/to/mylabel.csr -dn 'CN=test' 

This creates a certificate request associated with the label “mylabel”. Send the resulting /path/to/mylabel.csr to your CA for signing. 

After receiving the signed certificate back from your CA, you need to add any root and intermediate certificates to your keystore. This is usually provided by your CA. If these certificates are in separate files, add each one using: 

gsk8capicmd_64 -cert -add -db /home/db2inst1/server.p12 -stashed -label root -file /path/to/root/certificate 

If the certificates are in a single Base64-encoded file, use: 

gsk8capicmd_64 -cert -add -db /home/db2inst1/server.p12 -stashed -file /path/to/certificates 

If the file is PKCS12-encoded, use: 

gsk8capicmd_64 -cert -import -target /home/db2inset1/server.p12 -target_stashed -db /path/to/certificates.p12 -stashed 

Now you can receive (not add!) the certificate into your keystore. Run: 

gsk8capicmd_64 -cert -receive -db /home/db2inst1/server.p12 -file /path/to/server.pem -stashed 

If you have added your certificate instead of receiving it, the certificate will not be associated with your certificate signing request and you may receive a GSKit 407 error when starting the Db2 server.  

At this point, your certificate should be imported into the keystore using the same label provided when you created the CSR. You can confirm using: 

$ gsk8capicmd_64 –cert –list –db /home/db2inst1/server.p12 -stashed 

Certificates found 

* default, - personal, ! trusted, # secret key 

!       root 

-       mylabel 

(note the “-” beside the server certificate) and: 

gsk8capicmd_64 -cert –details –db /home/db2inst1/server.p12 -stashed –label mylabel 

TLS Port 

Last but not least, let’s talk about the TLS Port.  

You can choose any port for Db2 to listen to provided it is not in use. Alternatively, you can use a service name, which is a human-friendly name that maps to a port number. On Linux/Unix systems, service names are defined in /etc/services while on Windows, it is C:\Windows\System32\drivers\etc\services. For our sample setup, we will choose 25100 as our TLS port. 

Putting it all together 

We have everything we need to enable TLS on the server! We just need to tell Db2 about all our certificates. You can use the following command to update the DBM cfg based on the examples we used above: 

db2 update dbm cfg using SSL_SVR_KEYDB /home/db2inst1/server.p12 SSL_SVR_STASH /home/db2inst1/server.sth SSL_SVR_LABEL mylabel SSL_SVCENAME 25100 

Only thing left is to actually enable TLS: 

db2set DB2COMM=SSL 

That’s it! Now (re)start the Db2 server and it is ready to receive TLS connections! 

Note: I didn’t mention the other TLS parameters SSL_VERSIONS and SSL_CIPHERSPECS. These two parameters are optional, and Db2 automatically picks the most recently supported TLS version and the strongest supported cipher for the session. There are further intricacies when using these two TLS features, so I will save that for another blog post. 

Troubleshooting


You followed all the steps above, but TLS is still not working. What is going on? We’ll try to cover some of the common error scenarios you may have run into and how you can resolve them. 

For starters, the primary indicator that something went wrong when TLS is starting up is a SQL5043N when starting up your server: 

$ db2start 

SQL5043N  Support for one or more communications protocols specified in the DB2COMM environment variable failed to start successfully. However, core database manager functionality started successfully. 

Uh-oh! Something went wrong! First thing to check is the db2diag.log. Sometimes, the message is straightforward: 

2025-09-05-09.57.32.482363-240 E11590E469            LEVEL: Error  

PID : 3400479                  TID : 140340157736512 PROC : db2sysc  

INSTANCE: cyrusng              NODE : 000  

HOSTNAME: CyrusNg-857tb-x86  

EDUID : 1                      EDUNAME: db2sysc  

FUNCTION: DB2 UDB, common communication, sqlccLoadSSLLibrary, probe:2  

MESSAGE : ADM7012E The SSL_SVR_KEYDB DBM configuration parameter was not  

          configured. Update the SSL_SVR_KEYDB configuration parameter. 

In this case, I didn’t set the SSL_SVR_KEYDB DBM cfg parameter. But other errors may not be as obvious, and I will detail them below. 

GSKit Error 407 

You may encounter the following in the db2diag.log: 

2025-09-05-11.19.51.739672-240 I13213E613            LEVEL: Error 

PID : 3403116                  TID : 140157348996672 PROC : db2sysc 

INSTANCE: cyrusng              NODE : 000 

HOSTNAME: CyrusNg-857tb-x86 

EDUID : 1                      EDUNAME: db2sysc 

FUNCTION: DB2 UDB, common communication, sqlccMapSSLErrorToDB2Error, probe:6552 

MESSAGE : DIA3604E The SSL function "sqlccSSLValidateCertificate" failed with 

          the return code "407" in "sqlccEnvironmentInitCommon". 

DATA #1 : String, 27 bytes 

GSK_ERROR_BAD_KEYFILE_LABEL 

DATA #2 : String, 54 bytes 

The specified label in the key file could not be found 

Check that the certificate name you provided to SSL_SVR_LABEL is correct. You can do this by running: 

db2 get dbm cfg 

Correlate this with the certificates in your keystore by doing: 

gsk8capicmd_64 –cert –list –db path/to/server.p12 -stashed 

This will give output looking like this: 

Certificates found 

* default, - personal, ! trusted, # secret key 

-       mylabel 

If the certificate label matches what you provided to SSL_SVR_LABEL, then also check that this is a personal certificate (note the “-” beside the certificate). If this isn’t the case, then you will need to recreate or re-import the certificate into the keystore. 

Errors with CA-signed certificates 

You may encounter errors in the db2diag.log that look something like this: 

2025-09-05-12.04.49.796323-240 I11138E2456           LEVEL: Error  

PID : 3403630                  TID : 140280183383616 PROC : db2sysc  

INSTANCE: cyrusng              NODE : 000  

HOSTNAME: CyrusNg-857tb-x86  

EDUID : 1                      EDUNAME: db2sysc  

FUNCTION: DB2 UDB, common communication, sqlccSSLValidateCertificate, probe:7602 MESSAGE : Certificate Validation Failed  

DATA #1 : String, 138 bytes  

message, certificate label, TLS 1.3 Status, public key OID, signature algorithm OID, key size,validity start, expiry, validation error log  

DATA #2 : String, 118 bytes Validation failure for certificate signedserver: GSKVAL_ERROR_NO_CHAIN_BUILT (575010) - No certificate chain was built  

DATA #3 : String, 12 bytes  

mylabel 

DATA #4 : Boolean, 4 bytes  

false  

DATA #5 : String, 0 bytes  

Object not dumped: Address: 0x00007F95867E5650 Size: 0 Reason: Zero-length data  

DATA #6 : String, 0 bytes  

Object not dumped: Address: 0x00007F95867E55E0 Size: 0 Reason: Zero-length data  

DATA #7 : unsigned integer, 8 bytes  

0  

DATA #8 : String, 0 bytes  

Object not dumped: Address: 0x00007F95867E5730 Size: 0 Reason: Zero-length data  

DATA #9 : String, 0 bytes  

Object not dumped: Address: 0x00007F95867E56C0 Size: 0 Reason: Zero-length data  

DATA #10: String with size, 391 bytes [Class=]GSKVALMethod::X509[Time=]2025:9:5:12:4:49.794[buildChain=][Error=]GSKVAL_ERR_NO_CHAIN_BUILT[Info=]CN=root[Cert=][Issuer=]CN=root[#=]0edd4386f8dc3646[Subject=]CN=test[=Cert][=buildChain]^M  

[Class=]GSKVALMethod::PKIX[Time=]2025:9:5:12:4:49.796[buildChain=][Error=]GSKVAL_ERR_NO_CHAIN_BUILT[Info=]CN=root[Cert=][Issuer=]CN=root[#=]0edd4386f8dc3646[Subject=]CN=test[=Cert][=buildChain]^M 

CALLSTCK: (Static functions may not be resolved correctly, as they are resolved to the nearest symbol) 

... 

2025-09-05-12.04.49.804738-240 I13595E583            LEVEL: Error  

PID : 3403630                  TID : 140280183383616 PROC : db2sysc  

INSTANCE: cyrusng              NODE : 000 

HOSTNAME: CyrusNg-857tb-x86  

EDUID : 1                      EDUNAME: db2sysc  

FUNCTION: DB2 UDB, common communication, sqlccMapSSLErrorToDB2Error, probe:6552 MESSAGE : DIA3604E The SSL function "sqlccSSLValidateCertificate" failed with  

          the return code "8" in "sqlccEnvironmentInitCommon".  

DATA #1 : String, 25 bytes  

GSK_ERROR_CERT_VALIDATION  

DATA #2 : String, 28 bytes  

Certificate validation error 

There may be a large variety of reasons for why a certificate failed validation, but one common reason is that you received the certificate correctly into the keystore but forgot to add the root and intermediate certificates. To check if this is the case, run: 

gsk8capicmd_64 -cert -validate -db /home/db2inst1/server.p12 -stashed -label mylabel 

If there are errors with the certificate chain, you will see something like this: 

CTGSK2146W An invalid certificate chain was found.  

Additional untranslated info:  

GSKKM_LAST_VALIDATION_ERROR: No certificate chain built  

GSKKM_VALIDATIONFAIL_SUBJECT: [Class=]GSKVALMethod::PKIX[Issuer=]CN=root[#=]0edd4386f8dc3646[Subject=]CN=test  

CTGSK2146W An invalid certificate chain was found. 

Make sure you have added all root and intermediate certificates to the keystore. These can be marked with a “!” when you list the certificates: 

Certificates found 

* default, - personal, ! trusted, # secret key 

!       root 

-       mylabel 

You may also see similar messages if your certificate does not meet the security requirements of your Db2 server. I hope to detail this in a later blog, but for now, I’ll refer you to our documentation about Db2’s security modes and the page about TLS 1.3 certificate restrictions   

If your certificate is using old insecure algorithms, you may see errors similar to the above. You can view the details of your certificate to check if these insecure algorithms are being used by running: 

gsk8capicmd_64 –cert –details –db /home/db2inst1/server.p12 -label mylabel 

GSKit Error 102 and 408 

In the db2diag.log, you may encounter: 

2025-09-05-11.01.48.637518-240 I11138E569            LEVEL: Error 

PID : 3402527                  TID : 139831086671424 PROC : db2sysc 

INSTANCE: cyrusng              NODE : 000 

HOSTNAME: CyrusNg-857tb-x86 

EDUID : 1                      EDUNAME: db2sysc 

FUNCTION: DB2 UDB, common communication, sqlccMapSSLErrorToDB2Error, probe:530 

MESSAGE : DIA3604E The SSL function "gsk_environment_init" failed with the 

          return code "102" in "sqlccEnvironmentInitCommon". 

DATA #1 : String, 20 bytes 

GSK_KEYFILE_IO_ERROR 

DATA #2 : String, 25 bytes 

I/O error reading keyfile 

or 

2025-09-05-10.24.38.250741-240 I57687E665            LEVEL: Error  

PID : 3402070                  TID : 139753546573376 PROC : db2sysc  

INSTANCE: cyrusng              NODE : 000  

HOSTNAME: CyrusNg-857tb-x86  

EDUID : 1                      EDUNAME: db2sysc  

FUNCTION: DB2 UDB, common communication, sqlccMapSSLErrorToDB2Error, probe:530  

MESSAGE : DIA3604E The SSL function "gsk_environment_init" failed with the  

          return code "408" in "sqlccEnvironmentInitCommon".  

DATA #1 : String, 30 bytes  

GSK_ERROR_BAD_KEYFILE_PASSWORD  

DATA #2 : String, 110 bytes  

The specified key file password is incorrect. The key file could not be used. The key file may also be corrupt 

The first thing to check is that you’ve specified the correct keystore and stash file pairing for SSL_SVR_STASH and SSL_SVR_KEYDB. You can check this by using: 

db2 get dbm cfg 

If you are sure that the DBM cfg is set correctly but are still getting these errors, check that the server can access the keystore and stash file. On Linux/Unix, these should be accessible by the instance owner. The permissions should be: 

$ ls -l server.p12 server.sth  

-rw------- 1 db2inst1 db2inst1 25599 Aug 14 10:52 server.p12 

-rw------- 1 db2inst1 db2inst1   193 Oct 24  2024 server.sth 

On Windows, these files should be accessible by the Db2 service account. You can find the account your Db2 service is running under by hitting Win+r and running services.msc. Search for the Db2 service and the account will be mentioned under the “Log On As” column.

Shows the Db2 service inside services.msc

Then, make sure your keystore is accessible by this account: 

Details of the Db2 service showing the permissions of the Administrator user

Remember to make sure the entire path is accessible to the instance owner/service account! If you have determined that the instance owner or Db2 service account can access the files, then double check the version of GSKit installed on your system. You can do this using:  

gsk8ver_64 

It should print out the version of each GSKit library in the GSKit installation: 

... 

libgsk8km2_64.so 

============ 

@(#)CompanyName:      IBM Corporation 

@(#)LegalTrademarks:  IBM 

@(#)FileDescription:  IBM Global Security Toolkit 

@(#)FileVersion:      8.0.60.1 

@(#)InternalName:     gskkm2 

@(#)LegalCopyright:   Licensed Materials - Property of IBM GSKit  

                      (C) Copyright IBM Corp.1995, 2024  

                      All Rights Reserved. US Government Users  

                      Restricted Rights - Use, duplication or disclosure 

                      restricted by GSA ADP Schedule Contract with IBM Corp. 

@(#)OriginalFilename: libgsk8km2_64.so 

@(#)ProductName:      gsk8l (GoldCoast Build 8.0.55) 240525_8.0.60.1 

@(#)ProductVersion:   8.0.60.1 

... 

Be careful! gsk8ver_64 will rely on LD_LIBRARY_PATH (Linux), LIBPATH (AIX), and PATH (Windows) to find the GSKit libraries, so if there are multiple GSKit installations on your system, make sure those variables point GSKit to the one used by the server. On Linux/Unix systems, use the export command. On Windows, you can use set or modify the system PATH

The GSKit version should match those found here for official Db2 releases and here for security special builds. If they don’t, then install the correct version of GSKit. If the GSKit version is older than 8.0.50.69, then you will need to recreate the keystore and stash file with a newer GSKit. 

You can also check that you can access the keystore using the stash file: 

gsk8capicmd_64 –cert –list –db /home/db2inst1/server.p12 -stashed 

If the command outputs a list of certificates, then we know the stash file is not corrupted. Otherwise, you will need to recreate the keystore and stash files by following the steps outlined in Keystore and Stash Files

Invalid TLS port 

If your chosen TLS port is in use by another process, you may see the following message in the db2diag.log

2025-09-05-11.10.29.502354-240 E62274E766            LEVEL: Error      

PID     : 3402800              TID : 139709405718080 PROC : db2sysc      

INSTANCE: cyrusng              NODE : 000      

HOSTNAME: CyrusNg-857tb-x86      

EDUID   : 1                    EDUNAME: db2sysc      

FUNCTION: DB2 UDB, common communication, sqlcctcpconnmgr, probe:46      

MESSAGE : ADM7007E  The SVCENAME DBM configuration parameter, "9083", is       

          configured with a port or a service name.  When it is configured with       

          a service name, the TCP/IP services files is used to map the service       

          name to a port number.  The port specified in this field is being       

          used by another process.  Resolve this problem by either deleting the       

          process using the port or use another port.   

This means another process is listening on the chosen TLS port. You will need to choose another port or terminate the process listening on that port. You can find out what ports are being used with: 

netstat –tulnp 

Some ports are restricted and are reserved for certain purposes by the OS. In these cases, you may see something like: 

2025-09-05-11.08.14.492921-240 I13762E385            LEVEL: Error      

PID     : 3402674              TID : 140084338746944 PROC : db2sysc      

INSTANCE: cyrusng              NODE : 000                              

HOSTNAME: CyrusNg-857tb-x86                                                                                                      

EDUID   : 1                    EDUNAME: db2sysc                         

FUNCTION: DB2 UDB, common communication, sqlcctcpconnmgr, probe:47           

MESSAGE : DIA3202C The TCP/IP call "bind" returned an errno="13". 

Conclusion


I hope this has been an informative read on how to set up the Db2 server to use TLS. Your server is now ready to communicate with clients in a secure manner. Now that we have our server set up, we will talk about setting up the client in the next blog. Until next time! 

Further Reading


About the Authors


Cyrus Ng is a Software Developer on the Db2 Security team at the IBM Toronto Lab with a Bachelor's in Computing from Queen’s University. He has worked with various security features in Db2, such as TLS 1.3 support, hostname validation, and audit. 

Greg Stager is the security architect for Db2 LUW at the IBM Toronto Lab. Greg has been a member of the Db2 security development team since 2000, where he has worked on all aspects of security within Db2, including authentication, authorization, auditing, and encryption.  Greg is a primary contributor to the Db2 LUW CIS Benchmark, and a Certified Information System Security Professional (CISSP). 

Nataliya Prokoshyna is a software development manager for Db2 LUW at the IBM Canada Lab. As a senior member of the Db2 security development team, Nataliya has worked on authentication, authorization, auditing and encryption, PSIRT, and other aspects of security within Db2. 

0 comments
10 views

Permalink