AT-TLS Configuration for the Modern Mainframer

Pavel Jareš
Modern Mainframe
Published in
6 min readNov 16, 2021

AT-TLS for the Modern Mainframe Java Applications is where this story began as an overview of the AT-TLS layer of the z/OS Communication Server. To understand the need for the configuration that is going to be presented here, it is essential to read the original article beforehand.

The AT-TLS configuration uses a format similar to JSON but not exactly. For example, labels should be without spaces and the number sign (#) is used for comments. The configuration could be structured to allow the reuse of different parts. For detailed information, check the AT-TLS policy statements.

The first step to configure AT-TLS is defining a rule for the server-side, aka, the inbound call. This is where the network interface is specified via the local address setting. The `ALL` value can be used instead to listen on all interfaces and to specify only the port number, which can accept a fixed value or a range, e.g.: 12340–12345.

TTLSRule ServerRule
{
LocalAddr ALL
RemoteAddr ALL
LocalPortRange 12345
Direction Inbound
TTLSGroupActionRef ServerGroupAction
TTLSEnvironmentActionRef ServerEnvironmentAction
TTLSConnectionActionRef ServerConnectionAction
}

TTLSGroupAction could be used to define a setup according to the FIPS standards. In this case, for simplicity, it only enables the AT-TLS.

TTLSGroupAction ServerGroupAction
{
TTLSEnabled On
}

TTLSEnvironmentAction defines mainly the handshake parameters. Important thing is to set the role of the handshake and the certificate source, in this case, the rule `Keyring` as stated below.

TTLSEnvironmentAction ServerEnvironmentAction
{
HandshakeRole Server
EnvironmentUserInstance 0
TTLSEnvironmentAdvancedParmsRef EnvironmentAdvancedParms
TTLSKeyringParmsRef Keyring
}

TTLSKeyringParams specifies the keyring in use that contains a private key for TLS as well as public certificates to verify remote connections (especially relevant for the outbound communication). The keyring is identified by its ID and does not require the user ID for the account under which the application runs.

TTLSKeyringParms Keyring
{
Keyring RINGID
}

TTLSEnvironmentAdvancedParms is used to define the level of protocols. In the example below, TLS 1.3 and 1.2 are left active and older protocols are disabled. The protocols could also be controlled by the application via the ApplicationControlled parameter, i.e. AT-TLS control mode as described in the AT-TLS Overview article. All that is necessary to enable it is to set the value to `On` here and in the TTLSConnectionAdvancedParms. Aware mode is activated automatically once AT-TLS is configured.

TTLSEnvironmentAdvancedParms EnvironmentAdvancedParms
{
ApplicationControlled Off
Renegotiation Disabled
SSLv2 Off
SSLv3 Off
TLSv1 Off
TLSv1.1 Off
TLSv1.2 On
TLSv1.3 On
}

TTLSConnectionAction, in this case, is only used to collect the configuration defined as a separate block to be included in a `TTLSRule` rule.

TTLSConnectionAction ServerConnectionAction
{
HandshakeRole Server
TTLSCipherParmsRef CipherParms
TTLSConnectionAdvancedParmsRef ConnectionAdvancedParms
}

TTLSConnectionAdvancedParms is mainly used for certificates setup. The certificate label could be used to specify one, omitting it would select the default one in the keyring. It should be noted the ApplicationControlled value mentioned before and needed in case the controlling mode is desired.

TTLSConnectionAdvancedParms ConnectionAdvancedParms
{
ApplicationControlled Off
ServerCertificateLabel sercCert
SecondaryMap Off
}

TTLSCipherParms block can get a bit complicated as it is used to define ciphers to be used for communication. The list below is, by the time this article is published, TLS 1.3 compliant, however, this could change in the future. The full list of currently supported protocols can be found in the corresponding documentation. It is important to double-check the spelling of the configuration values as a typo would disable a cipher and result in the cipher no longer being in use.

TTLSCipherParms CipherParms
{
V3CipherSuites TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
V3CipherSuites TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
V3CipherSuites TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
V3CipherSuites TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
V3CipherSuites TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
V3CipherSuites TLS_AES_128_GCM_SHA256
V3CipherSuites TLS_AES_256_GCM_SHA384
V3CipherSuites TLS_CHACHA20_POLY1305_SHA256
}

To define an outbound configuration, many of the blocks described so far could be reused. It again could start with a TTLSRule very similar to the server rule with a difference being that it requires to indicate links to blocks with specific definitions and conditions to select a channel. A way to select an application on the server-side is ease — it is enough to only define the listening port. The outgoing calls, however, should be defined with better granularity. Specifying only the remote port or a range of ports may limit or alter the behavior of the client application as well. As an alternative, it might be more appropriate to define a job name instead or to use local ports.

TTLSRule ClientRule
{
RemotePortRange 12340-12345
Jobname MYJOB*
Direction Outbound
TTLSGroupActionRef ClientGroupAction
TTLSEnvironmentActionRef ClientEnvironmentAction
TTLSConnectionActionRef ClientConnectionAction
}

The rest of the outbound configuration is identical or very similar to the one for the inbound calls with one exception for the HandshakeRole value.

TTLSEnvironmentAction ClientEnvironmentAction
{
HandshakeRole Client
TTLSKeyringParmsRef Keyring
TTLSCipherParmsRef CipherParms
TTLSEnvironmentAdvancedParmsRef EnvironmentAdvancedParms
}

TTLSGroupAction ClientGroupAction
{
TTLSEnabled ON
}

TTLSConnectionAction ClientConnectionAction
{
HandshakeRole Client
TTLSCipherParmsRef CipherParms
TTLSConnectionAdvancedParmsRef ConnectionAdvancedParms
}

So far the base part of the AT-TLS configuration has been completed and is ready to be used. As an additional advanced setup, the configuration blocks could contain definitions of client certificates. Those could be defined separately for outbound and inbound calls. For the outbound calls, it is only necessary to define the CertificateLabel in the TTLSConnectionAdvancedParms block.

TTLSConnectionAdvancedParms ConnectionAdvancedParms
{
CertificateLabel clientCert
}

The server-side or inbound advanced parameters could be slightly more complicated as they require to define one block for the handshake types (the server needs to confirm if a client certificate is accepted) and then define the client authentication type. ClientAuthType could have the value Required or Full if client certificates are optional. AT-TLS offers two more handshake types — PassThru and SAFCheck. More information can be found in the official documentation from IBM.

TTLSEnvironmentAction ServerEnvironmentAction
{
HandshakeRole ServerWithClientAuth
}
TTLSEnvironmentAdvancedParms EnvironmentAdvancedParms
{
ClientAuthType Full
}
TTLSConnectionAction ServerConnectionAction
{
HandshakeRole ServerWithClientAuth
}

More rules could be defined to customize further the AT-TLS configuration and they could all be collected in a single USS file to then be set in a PAGENT. The location of configuration is then set by the TTLSConfig statement. For the updated configuration to take effect, the MVS command should be executed. The /F PAGENT,REFRESH could be used to check what has been changed since the last execution, and /F PAGENT,UPDATE could be used to reload all rules. Using the update is considered a best practice to ensure all configuration changes are applied correctly. Depending on the network settings of the operating system, a restart of the TCP stack may be required too.

After all, definitions are drafted, it is necessary to verify them for syntax errors and misconfigurations. As a starting point, issuing the command `pasearch -t` to find typos, invalid structures, and wrong configuration values. Once the syntax is corrected, studying the ‘Trace’ logs would be necessary for further troubleshooting. Log levels can be defined between 0 and 255 for each section of the AT-TLS setup — the higher the log level, the more detailed it would be. A value of 8 seems to enable enough traces for all possible configuration issues to be identified and it could be increased further for deeper troubleshooting. The errors with their specific error codes appear in the TCP IP and PAGENT logs. It is also good to know that the whole configuration could be done by z/OSMF, which is useful, especially when setting up only one system.

After following all the steps described above, the HTTP-enabled mainframe application would be accessible through the TLS protocol. This would be the first major milestone in this journey of leveraging the capabilities of AT-TLS, however, one should be cautious of the potential negative impact this environment could have on. For example, a simple misconfiguration or an accidental disabling of the AT-TLS would remove the security layer without warnings and would render all the network traffic plain and public. Of course, such situations have already been predicted and thought over with avoidance practices available that will be discussed in the next article of this series.

Co-authored by Boris Petkov

Attachment: example of AT-TLS configuration

Further reading: AT-TLS Aware Mode in a Mainframe Java Application

--

--