IBM Support

Converting non-z/OS SSH keys to certificates in RACF keyrings

How To


Summary

When combining z/OS and non-z/OS platforms, you may need additional instructions on setting up key rings for both Host and User Authentication.

These instructions are to be used as a guideline, and not a definitive set of steps, as there are many factors that affect what commands are available system - to - system, and which format is best.

Objective

The instructions are broken up into two sections:
1. Client is non-z/OS -- These instructions help you create a user-key certificate to then be distributed to z/OS server.
2. Server is non-z/OS -- These instructions help you create a host-key certificate to then be distributed to all z/OS clients that are to connect to this server.
Note: Each set of instructions assumes that the non-z/OS System has openssl Utilities available.

Steps

Client is non-z/OS:
Windows Client (PuTTY)
1) Generate PuTTY public/private key pair (id_rsa.ppk and id_rsa.pub).
2) Generate an OpenSSH private key from the PuTTY private key (id_rsa.openssh).  [Conversions --> Export OpenSSH key]
3) Copy the OpenSSH private key to Linux (or similar - where openssl utilities are available) and go to Linux Step 2

Linux (or similar)
1) Generate a user keypair on the linux/PC/etc client (id_rsa and id_rsa.pub).  (Note PEM format is ideal).  My id is "chuck" and my system name is "linux":
      chuck@linux:~$   ssh-keygen -t rsa -m PEM
2) Create an x509 certificate from the private key:
      chuck@linux:~/.ssh$  openssl req -new -x509 -key id_rsa -out sshcert.der -outform DER -days 90
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank.
For some fields there will be a default value,
If you enter '.', the field will be left blank.
 
Country Name (2 letter code) [AU]:<Enter Country>
State or Province Name (full name) [Some-State]:<Enter State>
Locality Name (eg, city) []:<Enter City>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<Enter Organization>
Organizational Unit Name (eg, section) []:<Enter Unit>
Common Name (eg, YOUR name) []:<Enter Name>
Email Address []:<Enter Email>
Note the "-days xx" option - this specifies the number of days to certify the certificate for. The default is typically 30 days.

3) copy (sftp) the newly created certificate (sshcert.der) from Linux to z/OS in binary.
 
     chuck@linux:~/.ssh$  sftp mega@mymainframe.com
      sftp> put sshcert.der
      Uploading sshcert.der to /sshcert.der
Remaining steps are performed on z/OS (where my userid is MEGA)
4) Copy the certificate to a data set:
      $ cp sshcert.der "//'MEGA.SSHCERT.DER'"
4a) This certificate can be validated using TSO command:   
RACDCERT CHECKCERT('DSN')

Example output:
racdcert checkcert('MEGA.SSHCERT.DER')            
 Certificate 1:                                        
   Start Date: 2020/01/30 16:32:46                     
   End Date:   2020/02/29 16:32:46                     
   Serial Number:                                      
        >751706B8737688AD5F513F6EE724918F00533F5A<     
   Issuer's Name:                                      
        >O=Internet Widgits Pty Ltd.SP=Some-State.C=AU<
   Subject's Name:                                     
        >O=Internet Widgits Pty Ltd.SP=Some-State.C=AU<
   Signing Algorithm: sha256RSA                        
   Key Type: RSA                                       
   Key Size: 3072                                      
 Chain information:                                    
   Chain contains 1 certificate(s), chain is complete  
 READY                                
5a) If this is the first time creating a certificate for this user you will need to define the key ring in TSO:
RACDCERT ID(MEGA) ADDRING(SSHAuthKeysRing)
       Then restrict access to this new ring:
RDEFINE RDATALIB MEGA.SSHAuthKeysRing.LST UACC(NONE)
PERMIT MEGA.SSHAuthKeysRing.LST CLASS(RDATALIB) ID(MEGA) ACCESS(READ)
SETROPTS RACLIST(RDATALIB) CLASSACT(RDATALIB)
SETROPTS RACLIST(RDATALIB) REFRESH

5b) If this is replacing an expired certificate for this user, delete the old/expired certificate.  Issue the following in TSO:
RACDCERT REMOVE(ID(MEGA) LABEL('cert-mega-ssh-rsa') RING(SSHAuthKeysRing)) ID(MEGA)
RACDCERT DELETE(LABEL('cert-mega-ssh-rsa')) ID(MEGA)

6) Add the new certificate to RACF using these TSO commands:
RACDCERT ADD('MEGA.SSHCERT.DER') ID(MEGA) WITHLABEL('cert-mega-ssh-rsa') TRUST
RACDCERT CONNECT(ID(MEGA) LABEL('cert-mega-ssh-rsa') RING(SSHAuthKeysRing) USAGE(PERSONAL)) ID(MEGA)
7) If this was a replacement for an expired certificate, the setup/update should now be complete.  If this is a first-time setup - add the following keyword to the user's authorized_keys file:
zos-key-ring-label="userID/SSHAuthKeysRing uniq-ssh-type"
   In my scenario I added the following to my ~/.ssh/authorized_keys
zos-key-ring-label="MEGA/SSHAuthKeysRing cert-mega-ssh-rsa"
Notes: 
  • There are likely other ways but the key is to use openssl to get the certificate in a standard format (DER) which z/OS can accept
  • A PEM format certificate works as well, the openssl command would use "-outform PEM" instead. However, this certificate format is text, and must be copied in a way where ASCII/EBCDIC conversions will occur.  
  • If using existing OpenSSH keys - the key may need to be placed into an openssl friendly format using "ssh-keygen -p -m PEM -f keyname" which will rebuild it (functionally it will be the same) into the proper PEM structure.  
  • This method will also work when SSHD is running in FIPSMODE with the following caveats - the server host key must also be in a key ring (per the regular FIPSMODE configuration).   
Server is non-z/OS:
1) On your Remote server, Windows/Linux, ensure openssl utilities are available.
2) Using the existing private host key, ensure it is in the proper PEM format (this command will restructure the private host key to an openssl friendly format - it will not change functionality):
ssh-keygen -p -m PEM -f keyname
For example:
ssh-keygen -p -m PEM -f /etc/ssh/ssh_host_rsa_key
3) Create a binary x509 DER certificate (based on the private key), note the "-days xx" option - this specifies the number of days to certify the certificate for. The default is typically 30 days.
openssl req -new -x509 -key keyname -out sshcert.der -outform DER -days 90
For example:
openssl req -new -x509 -key /etc/ssh/ssh_host_rsa_key -out sshcert.der -outform DER -days 90
*OR*
Create a text PEM certificate (based on the private key):
openssl req -new -x509 -key keyname -out sshcert.pem -outform PEM -days 90
For example:
openssl req -new -x509 -key /etc/ssh/ssh_host_rsa_key -out sshcert.pem -outform PEM -days 90
This produces a text certificate. You can validate this by browsing the output .pem file, it should appear like:
----BEGIN CERTIFICATE-----
MIIEazCCAtOgAwIBAgIUC/27Fd4dDAXZPn9kJ1odxOazL+AwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
G0FrnD9zWF8OfIaTFRTiGmLNvv8oyJ3tq21jqsT1MbekPO4qAImXW0gkpT2opVR2
9p+b4y2llPf62uZqfur+Aikji9TVQ1/rLYb6GgZbp4A4+oKe2vjF2N0hBIEkTpzm
KQkSWB/IxuXU+jOqtNXsu/fCNZEnfA1xMdmGasxbAw==
-----END CERTIFICATE-----
4) Copy the sshcert.der to z/OS in binary   or      sshcert.pem as text       (ftp/sftp/scp)
    Note:  It's critical to copy the file in the specified format or the certificate may become corrupted

Remaining steps to be performed on z/OS, in the examples cited my ID is "mega"
5) Copy the certificate to an MVS data set, (if using PEM, just use the respective file names):
cp sshcert.der "//'MEGA.SSHCERT.DER'"

6) Validate the certificate using TSO command:   
RACDCERT CHECKCERT('DSN')
For example:
racdcert checkcert('MEGA.SSHCERT.DER')            
 Certificate 1:                                        
   Start Date: 2020/01/30 16:32:46                     
   End Date:   2020/02/29 16:32:46                     
   Serial Number:                                      
        >751706B8737688AD5F513F6EE724918F00533F5A<     
   Issuer's Name:                                      
        >O=Internet Widgits Pty Ltd.SP=Some-State.C=AU<
   Subject's Name:                                     
        >O=Internet Widgits Pty Ltd.SP=Some-State.C=AU<
   Signing Algorithm: sha256RSA                        
   Key Type: RSA                                       
   Key Size: 3072                                      
 Chain information:                                    
   Chain contains 1 certificate(s), chain is complete  
 READY                                                 
Similar output would be produced for PEM.
7) If this is the first time creating a certificate for this system:
        In TSO - define the key ring:
RACDCERT ID(MEGA) ADDRING(SSHKnownHostsRing)

8) Add the new certificate to RACF using these TSO commands:
RACDCERT ADD('MEGA.SSHCERT.DER') ID(MEGA) WITHLABEL('host-ssh-type') TRUST
RACDCERT CONNECT(ID(MEGA) LABEL('host-ssh-type') RING(SSHKnownHostsRing)) ID(MEGA)
9) Permit user access to the known hosts key ring. All OpenSSH client users on this system must have the authority to read the public keys from this key ring.
RDEFINE RDATALIB MEGA.SSHKnownHostsRing.LST UACC(READ)
And if the RDATALIB class is not yet active and RACLISTed:
SETROPTS RACLIST(RDATALIB) CLASSACT(RDATALIB)

10) Edit /etc/ssh/ssh_known_hosts to add the label (note, you will need to make the proper replacements for "myhostname", userid, etc.:
myhostname zos-key-ring-label="MEGA/SSHKnownHostsRing myhost-ssh-rsa"
Notes:
  • These steps are documented in the OpenSSH User Guide under section "For system administrators", "Setting up the sshd daemon", "Steps for setting up server authentication when keys are stored in key rings" -- "Step 2: Distribute the public keys from the local host to the remote hosts".
  • If you collect a debug client trace (using the -vvv flags), upon successful connection, you'll see entries like this indicating the key ring was used successfully:
---
debug3: load_hostkeys: loading entries for host "myhost" from file "/etc/ssh/ssh_known_hosts"
debug1: zsshGetKeyFromKeyRing: key retrieval from key ring 'MEGA/SSHKnownHostsRing' label 'myhost-ssh-rsa' succeeded, key type is 'RSA'
debug3: load_hostkeys: found key type RSA in file /etc/ssh/ssh_known_hosts:31
---

Document Location

Worldwide

[{"Line of Business":{"code":"LOB56","label":"Z HW"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG90","label":"z\/OS"},"ARM Category":[{"code":"a8m0z0000000ALuAAM","label":"z\/OS-\u003EOpenSSH"}],"ARM Case Number":"","Platform":[{"code":"PF035","label":"z\/OS"}],"Version":"All Version(s)"}]

Document Information

Modified date:
14 February 2024

UID

ibm16124929