I looked into this because someone asked me about using the mail client on z/OS talking to a mail server somewhere in the internet.
My z/OS running on zPDT under Linux did not have a working connection to the outside world.
Configuring Linux to pass the z/OS traffic to the external network.
A ping to the server, got no response back.
Using Wireshark on the wireless connection, I could see my request from z/OS coming via Linux and going to the outside network. The source IP address was 10.1.1.1 – a “local only” address, and so the server could not send a response back to me.
The routing through Linux worked because I had a default route; ip route gave me
default via 192.168.xxx.xxx4 dev wlxd037450ab7ac proto dhcp metric 600 10.1.0.0/24 dev eno1 proto kernel scope link src 10.1.0.3 metric 100 10.1.0.0/24 via 10.1.0.3 dev eno1 proto static metric 100 10.1.1.0/24 dev tap0 proto kernel scope link src 10.1.1.1
To get the “right” IP address passed to the external network, was surprisingly easy. It was documented in the zPDT book.
I created a script
echo ‘Your firewall must be enabled for this command to be meaningful’ echo 1 > /proc/sys/net/ipv4/ip_forward iptables -F FORWARD iptables -P FORWARD ACCEPT iptables -t nat -A POSTROUTING -o wlxd037450ab7ac -j MASQUERADE # iptables -I INPUT -p tcp --dport 3270 -j ACCEPT
and used sudo to execute it.
I started the firewall
sudo ufw status
sudo ufw enable
I could then successfully ping the address
When I used Wireshark on the connection between Linux and z/OS, the source IP address was 10.1.1.2. When I used Wireshark on the wireless connection between Linux and the external network, the IP address was 192.168.xxx.xxx. This shows the effect of the iptables commands, it changed the 10.1.1.2 to a 192.168.xxx.xxx – and back again on the replies.
Getting the server’s certificate
I configured the AT-TLS definitions, for TLS support, specifying the choice of cipher specs I wanted to be used, and specified the keyring.
My z/OS client connected to the remote server. I could see the “client hello” flow, and the “server hello” response. In the server hello flow were the CA certificates the server supported. The client validates the certificates by checking the client’s key store.
I did not have the matching CA certificate in my keystore, and so my client failed to validate the certificate sent down, and the connection ended.
I could do it properly, and get the certificate from the official source for the server, but this was a test system, and I was happy to trust what was sent down in the handshake.
You can use wireshark or openssl to get the certificate
With openssl
openssl s_client -showcerts -tls1_2 -starttls smtp -connect smtp.gmail.com:587 | sed -ne ‘/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p’
You’ll need to interupt it (Ctrl-C) and paste the data into a file (google.pem)
You can display the contents of the certificate using
openssl x509 -in google.pem -text -noout|less
With Wireshark
display the certificates in the Server Hello flow.
right click on the certificate and use right click, export packet bytes. I created a file user.crt. This is a binary file.
The openssl command (on Linux)
openssl x509 -inform der -in user.crt -text > usercert.pem
displays the file in .pem format.
Put the certificate into the keyring
If you are using something that needs a keyring, you need to import the certificate into RACF and connect it to a keyring. If you are using something that uses openssl, such as Python, you need a .pem file in Unix Services.
I created a file on z/OS (VB) COLIN.USERCERT.PEM, and copied the .pem file into it (between and including the BEGIN CERTIFICATE and END CERTIFICATE lines).
I imported it, and connected it to my keyring using
//IBMRACF JOB 1,MSGCLASS=H //S1 EXEC PGM=IKJEFT01,REGION=0M //SYSPRINT DD SYSOUT=* //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * RACDCERT CHECKCERT('COLIN.USERCERT.PEM') RACDCERT DELETE (LABEL('USERTRUST.ORG')) CERTAUTH RACDCERT ADD('COLIN.USERCERT.PEM') - CERTAUTH WITHLABEL('USERTRUST.ORG') TRUST RACDCERT ID(START1) CONNECT(RING(TN3270) - CERTAUTH - LABEL('USERTRUST.ORG')) SETROPTS RACLIST(DIGTCERT,DIGTRING ) refresh RACDCERT LISTRING(TN3270) ID(START1) /*
Once I had refreshed my PAGENT job, and restarted my client code, I was able to establish a TLS session.
Client certificate
In the TLS handshake, the mail servers did not send down a request for the client certificate. As no certificate was requested, or sent up to the server, no certificate authentication was done. You need to check your mail server for it authentication process – it may just be userid and password. This information is sent once the TLS session has been established – so it flows encrypted.