While it’s easy enough to know whether my own connection to IBM i is secure—that is, encrypted—how can I tell whether all connections are encrypted?
By Carol Woodbury
Some organizations have a requirement that all connections to their IBM i be encrypted. I applaud those organizations and encourage everyone to adopt this practice. Most organizations encrypt outbound connections, but not everyone encrypts internal traffic. Encrypting all communication (including internal) ensures that no passwords or data are flowing anywhere in cleartext.
As I said, it’s easy to determine whether my connection to IBM i is encrypted. If I’m using Access Client Solutions (ACS) to establish a Telnet session, all I have to do is look in the lower right corner of the session to see the port used, an open or closed padlock, and encryption strength if the connection is secure. For ODBC, I simply look for the job name to be QZDASSINIT (SS meaning secure) rather than QZDZSOINIT (where SO is open or not encrypted). But if I’m an administrator and I want to prove to myself or am required to prove to an auditor that all connections are secure, how might I do that?
One way to look at all connections is to use the Work with TCP/IP Network Status (WRKTCPSTS) command. Choosing to look at the IPv4 and IPv6 connections will show you the established connections and which server they’re connected to. The server name will indicate whether the connection is secure, typically by adding either -s or -ssl to the end of the server name, e.g., Telnet-ssl. The port used is also an indication of whether the connection is secure. For example, if the Telnet session is using port 23, then it’s not secure. But if it’s coming in via port 992, the connection is encrypted. Here’s a list of the well-known ports. In addition, you’ll need the list of ports used by the ACS. By analyzing the output of NETSTAT, you can determine if there are currently any unsecured connections established to your IBM i. The problem with NETSTAT is that it’s a point in time; it’s accurate only for the time at which you ran the command. Other connections may be established in the middle of the night, for example.
The Audit Journal
If you need a complete analysis of your connections, you’ll need to utilize the audit journal. To analyze all TCP/IP connections, you’ll need to add two values to the QAUDCTL system value: *NETTELSVR to audit Telnet connections and *NETSCK to get all other IP connections. (If you want to analyze UDP connections, you’ll need to add *NETUDP.) Once you’ve added these two values, all connections will be logged. (Note that these values may generate a significant number of audit journal entries, so once your analysis is completed you may want to remove them.)
To analyze the connections, you’ll need to gather the SK audit journal entries. Here’s an example (you’ll need to fill in the appropriate start and end times and dates.)
CPYAUDJRNE ENTTYP(SK) JRNRCV(*CURCHAIN) FROMTIME(startdate starttime)
The Copy Audit Journal Entry (CPYAUDJRNE) command will, by default, produce a file in QTEMP called QAUDITxx, where xx is the two-letter audit journal entry type. So in this case, I now have a file in QTEMP called QAUDITSK that I can use for analysis.
There are many subtypes within the SK audit journal entry (for the full list, see the IBM i Security Reference manual, Chapter 9) but the subtype we’re looking for is ‘A’, meaning that the connection has been accepted. So right away, I’m going to use the following SQL statement to filter the SK entries to just look for the accepted connections
SELECT * FROM qtemp/qauditsk WHERE SKTYPE = 'A'
Even with this filter, you’re still likely to have a lot of entries. At this point, your next step depends on why you’re examining these entries. If you think you’ve gotten all connections secured, you may want to specifically look for connections coming in over unsecured ports. The following SQL lists the ports that the connections should be using; anything coming in over a different port will be listed. (Note: This is not a complete list of secure ports!)
SELECT * FROM qtemp/qauditsk WHERE SKTYPE = 'A' and SKLPRT not in ('22','443','992')
If you are just starting out with this project, you’ll probably want to be more selective in the entries. For example, if you want to ensure all Telnet sessions are encrypted, you can use an SQL that will only include cleartext Telnet sessions (that is, connections coming in over port 23).
SELECT * FROM qtemp/qauditsk WHERE SKTYPE = 'A' and SKLPRT = ‘23’
Now that you’ve selected the audit entries, how do you read/make sense of the information in the audit journal entry? For most audit journal entry types, I find the job name, user, and number helpful as well as the program and program library. But in this case, these fields are worthless. That’s because these entries are generated before the user’s job has started. Take a look at Figure 1 and you’ll understand what I mean.
Figure 1: These entries were generated before the user’s job started.
Likewise, the User profile field that typically contains the name of the current user is also worthless in this audit journal entry as it will always contain the value *NONE. So what is helpful about this entry? You’ll want to focus on these two fields:
- SKLPRT—Local port
- SKRADR—Remote IP address
To decipher where the connection is coming from, you’ll have to do a reverse DNS lookup using the remote IP address. You may also find the timestamp (SKTSTP) field helpful if the connections are coming from remote servers and you have to look through scheduled jobs to find the incoming task.
As you start to play around with the SK entries, you may be tempted to force a few entries to understand how to better read and understand what you’re seeing. (That’s what I always do when I start using an entry I’m not familiar with.) To force the entry, remember that SK entries log new connections; therefore, it’s not sufficient to simply log off your Telnet session and log back on. That will not generate an SK entry. You must close and reinitiate the session to get an SK entry generated.
In V7R3 IBM reworked the *NETCMN value such that it no longer logs accepts and connects. If you have *NETCMN specified in QAUDLVL and think you’re going to get the audit journal entries I’ve been describing, you won’t. As I said earlier, you must specify *NETTELSVR and *NETSCK (and NETUDP if you want to analyze your UDP connections) in the QAUDLVL system value.
As I said earlier, I encourage my clients to make sure all communications—external and internal—are encrypted. I hope this article will provide you with the information that you’ll need to either start this project or ensure it’s already been completed.