================ PIV keys support ================ .. contents:: Introduction ============ The Bastion supports enabling a policy forcing accounts SSH ingress keys to originate from a known hardware token, ensuring that the private SSH key is only stored on this hardware token, and not on the filesystem. Currently, only Yubico keys implementing PIV can be verified this way. In that case, each individual hardware token has a builtin Certificate Authority, signed by a well-known Yubico certificate, hence proving that the hardware token is known and legit. This builtin CA, in turn, emits an attestation certificate each time a new PIV key is generated on the hardware token, hence proving that the bikey (private and public) has been generated by this individual hardware token. Other metadata is included in the attestation, such as the firmware version, the serial number of the token, the *TouchPolicy* and *PinPolicy*. Note that you may decide to overwrite the builtin CA by a one of your own, possibly signed by a CA of your company. This would ensure not only that the SSH key is provided by the device, but also that the device has been provided by your company. Please refer to the `Yubico PIV attestation page `_ and the `Yubico PIV tool page `_ for more information. Without a policy ================ If you want to support PIV keys without making those mandatory, you don't have anything to do: those keys are just regular RSA/ECDSA keys and they *just work* with The Bastion. In that case, after having properly configured your hardware token with a key in slot 9a, you can just use :doc:`/plugins/open/selfAddIngressKey` to add the key to your bastion account, and call it a day. As a quick guidance, on a Yubikey you can usually generate a key in the proper slot this way, after you've setup a management key: .. code-block:: shell :emphasize-lines: 1 yubico-piv-tool --key=YOUR_MGMT_KEY --action generate --pin-policy always --touch-policy never --slot 9a -o - Now, if you want the bastion to be aware that this key is from a hardware token, you shall use the ``--piv`` option to :doc:`/plugins/open/selfAddIngressKey`. This won't do anything special per-se, except storing the certificates information, and showing the details of the PIV key in command outputs such as :doc:`/plugins/open/selfListIngressKeys`. Note however that if in the future you enable the PIV enforcing policy either on your account or globally, this key will be considered valid, contrary to all the keys added without the ``--piv`` option, even if these keys happen to be PIV ones. To add a key with the ``--piv`` option, you'll need the SSH public key as usual, but also the attestation certificate and the key certificate. Step by step details on how to get those are out of the scope of this document, but again as a quick guidance, on a Yubikey you can usually get those this way: .. code-block:: shell :emphasize-lines: 1,2,3 yubico-piv-tool --action=read-certificate --slot=9a --key-format=SSH yubico-piv-tool --action=attest --slot=9a yubico-piv-tool --action=read-certificate --slot=f9 When you'll have added your key, you'll see a few more details than usual: .. code-block:: console :emphasize-lines: 1 bssh --osh selfAddIngressKey --piv Enter PIN for 'PIV Card Holder pin (PIV_II)': ---the-bastion.example.org--------------------------------the-bastion-3.01.03--- => add a new public key to your account -------------------------------------------------------------------------------- ~ Please paste the SSH key you want to add. This bastion supports the following algorithms: ~ ED25519: strongness[#####] speed[#####], use `ssh-keygen -t ed25519' to generate one ~ ECDSA : strongness[####.] speed[#####], use `ssh-keygen -t ecdsa -b 521' to generate one ~ RSA : strongness[###..] speed[#....], use `ssh-keygen -t rsa -b 4096' to generate one ~ ~ In any case, don't save it without a passphrase. ~ You can prepend your key with a from="IP1,IP2,..." as this bastion policy allows ingress keys "from" override by users ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyAMtxGT/RvzBZXiYlrCswZMruRtoBtONrVJTZ3Cj5ZpjaZyCRjQ/ETzZXXbvu9KiBsZyhVb/5H9F7CSGi+D5BlcRAKrT9P8MsT7BHWU14GhJddhHDy4rMnXapE93oxbnQIjQT34ozvTKlb0qOoR/SlT14LllvQS6ajaXB7Fm4bAJG/gYGXHEs2nmZn37Rll6vvpZ4ExM29UrqU3hAjYO0Ha+kL5G8Tr+fOhV/5ZmzNsYigdW7Ft7Co4Tpld9D0PqVhDPK7F1zHIFUXunFsewGtB3IQxLdLGDaCMzrRi11V6q/pBzN/75YsW6npRdOzJKjnwxG19lTtVCmCY3EPRFz ~ ~ You have requested to add a PIV-enabled SSH key. ~ Please paste the PIV attestation certificate of your hardware key in PEM format. ~ This snippet should start with '-----BEGIN CERTIFICATE-----' and end with '-----END CERTIFICATE-----': ~ -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIQAajpKeFbM+X1Yfk8GaH9dzANBgkqhkiG9w0BAQsFADAh MR8wHQYDVQQDDBZZdWJpY28gUElWIEF0dGVzdGF0aW9uMCAXDTE2MDMxNDAwMDAw MFoYDzIwNTIwNDE3MDAwMDAwWjAlMSMwIQYDVQQDDBpZdWJpS2V5IFBJViBBdHRl c3RhdGlvbiA5YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIAy3EZ P9G/MFleJiWsKzBkyu5G2gG042tUlNncKPlmmNpnIJGND8RPNlddu+70qIGxnKFV v/kf0XsJIaL4PkGVxEAqtP0/wyxPsEdZTXgaEl12EcPLisyddqkT3ejFudAiNBPf ijO9MqVvSo6hH9KVPXguWW9BLpqNpcHsWbhsAkb+BgZccSzaeZmfftGWXq++lngT Ezb1SupTeECNg7Qdr6QvkbxOv586FX/lmbM2xiKB1bsW3sKjhOmV30PQ+pWEM8rs XXMcgVRe6cWx7Aa0HchDEt0sYNoIzOtGLXVXqr+kHM3/vlixbqelF07MkqOfDEbX 2VO1UKYJjcQ9EXMCAwEAAaNOMEwwEQYKKwYBBAGCxAoDAwQDBQIEMBQGCisGAQQB gsQKAwcEBgIEALeG1jAQBgorBgEEAYLECgMIBAIDATAPBgorBgEEAYLECgMJBAEB MA0GCSqGSIb3DQEBCwUAA4IBAQAq9O6H02KRvSmBYsz23r6cNTNS/fr5lSPYMHz/ fX+D5B1thKKGstsfZVzoopwIjj86cIWpCYuNfEje+a5HrELL8ClV88JutJR2Nihs NxU3BbsSUqnwi2rQHcmtHJcC8rjfDzpYDlW1yR+SxVenbVxuRy0v8sbleHSPYaXG EhjupEAuhq7n0TjZMF1X7KElx9FZZM9HeuxUJvzV7XWiUgA4Zm05+4/zKW01n2kt +aMaQk7T1oiE0oOK51wJX6J80GzF51pM00oPlh4iDvnnNXYN2KvkNuNwPoceDDE/ 8K23ZfJyTN5nibk13UbxEWSHMUue1zcnFp0KdhqxbJYSS/9q -----END CERTIFICATE----- ~ ~ Thanks, now please paste the PIV key certificate of your generated key in PEM format. ~ This snippet should also start with '-----BEGIN CERTIFICATE-----' and end with '-----END CERTIFICATE-----': ~ -----BEGIN CERTIFICATE----- MIIC5jCCAc6gAwIBAgIJAKT/dqaxohbiMA0GCSqGSIb3DQEBCwUAMCsxKTAnBgNV BAMMIFl1YmljbyBQSVYgUm9vdCBDQSBTZXJpYWwgMjYzNzUxMCAXDTE2MDMxNDAw MDAwMFoYDzIwNTIwNDE3MDAwMDAwWjAhMR8wHQYDVQQDDBZZdWJpY28gUElWIEF0 dGVzdGF0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwDhP3YUI yLWSjseIKNzMscqCdicslrdkxPgMoK8Ocxu0err4yvFXiSZZL32BTZYLD8N7Y+d1 cww6VVsFYdwn01Kc6YLrwM5FIN/msXkGTPdPVhVeqNMHh4QyYrYixwWaTbDCGoQD axVlifVmPS02Mvm8NDjC17X3LhsV1OiS/wOScsI8HHGgQXQIQEDMnt6cwZ83QK73 7Wuu5uhSzT3jVOz28Rnij1p/8PcVWcGKWCPVYNbCmCdcm/sQeJB8y5aERDaePIIZ v9axnDT0DnUO7aDpzXA7i7XPbrkiSBEp7RCqXGs5cBqGCbq//xGh+/AGtCCV/sQM nTjl0d2k2Q8XTwIDAQABoxUwEzARBgorBgEEAYLECgMDBAMFAgQwDQYJKoZIhvcN AQELBQADggEBAHCnp3k5kQaBwYmR9nUHKGY1dgCvhJUlX2SAyY2fUeaMuURcRRlW BFw6CvLAjvSs5Dy3O6JWDmk+1WFZo0UMr15WZFiS5Fpy0M+GWvBCRP3YmbSw+J2t kyWypCIIu7cMtLpRYkL5SAlWmUCAz8dZPk5FLPpeqmxgQnRoSSe67IXiv3bNyPA1 3NoXI2xw0hWQU1+85tfTxoTxOiAzY8UpAT2GggtSmCwO3sHsHJUYXRyCf8e6jtJL OFBx/uz+VJoRH7hUVOY+sbP5JJ83dRrWZkS57Hf3q0LOtbn27vM+fmL0y7z4vgDo DedmrmsbPtsRc3t7RWoqCa80Iq1jPvdm5gw= -----END CERTIFICATE----- ~ ~ Public key successfully added: ~ info: ADDED_BY=jdoe USING=selfAddIngressKey UNIQID=2993de2bb014 TIMESTAMP=1609427402 DATETIME=2020-12-31T15:10:02 VERSION=3.01.03 ~ PIV: TouchPolicy=Never, PinPolicy=Always, SerialNo=12345678, Firmware=5.2.4 ~ fingerprint: SHA256:8B0T6174KUPL1iTSyC0UpnDOvuaCgyKpu8zo9rb2lco (RSA-2048) [2020/12/17] ------------------------------------------------------------ As you can see, we added the public key as usual but were also asked for the two certificates. On the bastion answer, right before the fingerprint of the key, we have a line starting with *PIV:*, with some metadata extracted from the certificate. Per-account policy ================== If you want to force several accounts to only use certified PIV keys, you can set the option per-account using the :doc:`/plugins/restricted/accountPIV` command, see its documentation page for all the possible options. The main takeaways are: - If you want an account to only have PIV keys, set the ``enforce`` policy for this account - If you want an account to never require PIV keys, even if the global policy would require it, set the ``never`` policy (useful for accounts used by automated workflows) Global policy ============= If you want to apply a policy bastion-wide, please refer to the :ref:`ingressRequirePIV` option. This policy can still be overridden per-account if needed, see above. Temporary grace period ====================== If you enable the PIV policy globally or on several accounts, you'll soon find out that sometimes people forget or lose their PIV-enabled hardware tokens, effectively locking them out of the bastion. There is a *temporary grace period* feature you can use to handle such cases nicely: .. code-block:: console :emphasize-lines: 1 bssh --osh accountPIV --account lechuck --policy grace --ttl 48h ---the-bastion.example.org--------------------------------the-bastion-3.01.03--- => modify the PIV policy of an account -------------------------------------------------------------------------------- ~ Changing account configuration... ~ PIV grace up to 2d+00:00:00 (Wed 2021-01-13 09:22:29 UTC) has been set for this account ~ Applying change to keys... ~ Non-PIV account's ingress keys, if any, have been restored ------------------------------------------------------------------- What happens here is that, for a duration of 48 hours, this account will behave as if no PIV policy was enforced: non-PIV keys are allowed again. If this account had non-PIV keys before its policy was set to enforce, those keys are even restored (can be viewed using :doc:`/plugins/open/selfListIngressKeys` as usual), so that they can easily connect again. However, after the grace period expires, their policy will go back to what it was previously, and all the non-PIV keys will be disabled again. This event is logged, so you can easily link this event from your SIEM to a potential ticket to your Helpdesk for a hardware key replacement, or such. This mechanism allows some flexibility (avoiding sending people back home just because they forgot their hardware key), while still enforcing a high-level security policy with the proper processes in place.