Certificates in the context of SSH is used to authenticate
users (clients) in a more systematic way than simply adding
public keys to a authorized_keys
file, which doesn't scale
and is a terrible security practice. They are pain to add when
more than one machine is involved, and equally difficult to
remove when a user no longer should have access to a device.
Using certificates avoids the need to distribute public keys, both user and host (server). For the user put the hosts public key in the ~/.ssh/known_hosts file, e.g.,
@cert-authority *.avassa.io ecdsa-sha2-nistp256 AAAAE2VjZHN...
and on each host (/etc/ssh/sshd_config) add the CA public key and the hosts private key and certificate, e.g.,
# Path to the CA public key for verifying user certificates
TrustedUserCAKeys /etc/ssh/ssh_user_key.pub
# Path to this host's private key and certificate
HostKey /etc/ssh/ssh_host_ecdsa_key
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
Client certificates should be short lived, typically only valid for a work day. That way access is automatically removed and there is no risk of users having access to machines long after they have quit. It is a good idea to use a sign in process where a user certificate for the day is generated.
However, it is also possible to have a list of revoked certificates, e.g., in the /etc/ssh/sshd_config
# File containing public keys of revoked certificates
RevokedKeys /etc/ssh/revoked_keys
See also https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys
An alternative SSH authentication scheme is to use OTPs. This service can be used to generate and validate OTPs as well as generating SSH certificates.
To setup SSH with OTPs first configure PAM to use an external program to authenticate, ie pam_exec.so, secondly configure ssh to use PAM and challenge-response authentication, e.g., in /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
UsePAM yes
PasswordAuthentication no
And in /etc/pam.d/sshd comment out common-auth and add call to custom callback
# Standard Un*x authentication.
#@include common-auth
auth requisite pam_exec.so quiet expose_authtok log=/var/log/otp-ssh.log /usr/local/bin/otp-validate.sh
auth optional pam_unix.so not_set_pass use_first_pass nodelay
The /usr/local/bin/otp-validate.sh should:
validate-otp
action with the OTPA few things to note.
Created
Bad Request
Unauthorized
Forbidden
Not Found
Conflict (instance exists)
Service Unavailable (strongbox sealed)
name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 distribute: to: none
fields | string Retrieve only requested fields from the resource See section fields |
validate | string <enumeration> Validate the request but do not actually perform the requested operation |
keys | string <enumeration> Retrieve only the keys for the list |
count | string <enumeration> Retrieve only the number of elements in the list |
OK
Bad Request
Unauthorized
Forbidden
Not Found
Precondition Failed
Service Unavailable (strongbox sealed)
- name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 distribute: to: none
No Content
Bad Request
Unauthorized
Forbidden
Not Found
Precondition Failed
Service Unavailable (strongbox sealed)
name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 distribute: to: none
Created
No Content
Bad Request
Unauthorized
Forbidden
Not Found
Precondition Failed
Service Unavailable (strongbox sealed)
name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 distribute: to: none
fields | string Retrieve only requested fields from the resource See section fields |
validate | string <enumeration> Validate the request but do not actually perform the requested operation |
OK
Bad Request
Unauthorized
Forbidden
Not Found
Precondition Failed
Service Unavailable (strongbox sealed)
name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 distribute: to: none
fields | string Retrieve only requested fields from the resource See section fields |
site | string Send the request to the specfifed site |
content | string <enumeration> Filter descendant nodes in the response |
keys | string <enumeration> Retrieve only the keys for the list |
count | string <enumeration> Retrieve only the number of elements in the list |
OK
Bad Request
Unauthorized
Forbidden
Not Found
Service Unavailable (strongbox sealed)
- name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 public-key64: | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHSLaSvbPs7OwB1E6eTvUlvKP+zt1K9GnuYtPvkmuaN/poh3AXcF2mx/213GEvwiUrn893Och8+izAXdo9NyNGc= strongbox serial: 0 distribute: to: none distribution-status: to: none
fields | string Retrieve only requested fields from the resource See section fields |
site | string Send the request to the specfifed site |
content | string <enumeration> Filter descendant nodes in the response |
OK
Bad Request
Unauthorized
Forbidden
Not Found
Service Unavailable (strongbox sealed)
name: ca-1 key-type: ecdsa key-curve: nistp256 key-size: 2048 public-key64: | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHSLaSvbPs7OwB1E6eTvUlvKP+zt1K9GnuYtPvkmuaN/poh3AXcF2mx/213GEvwiUrn893Och8+izAXdo9NyNGc= strongbox serial: 0 distribute: to: none distribution-status: to: none
OK
Bad Request
Unauthorized
Forbidden
Not Found
Service Unavailable (strongbox sealed)
public-key: | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzGm8UaHf1vbDr4J4OYMivONjA9GHjEw il8RER57cIrh2OIObGixCiKlqUUUrAdjqa7z1VUb0Xfsn3wu5+0VY5F/XNai7MvTNappSx QDN0vRzLzDMrdkFskscYVcw/Cfp/xo36nXl4IJLrOB/F6CZRsgP1Mq3YH3tEO7uU71uLTd 1kSYh7w/2g4ujJ4X10XMaLG3+UfTGPjWj/YXsSHKYtGctUDt0U+7AjmM9jz4Ult1XXHHvU 3rRm5fXaNbEsIZxEX/R7Gf090GmRNuJeKD7sCFT2trgepOOJqCYqUZZPbDNbO5ElM2VlK/ 1AAzDgWPSMuZmSw1ibg3OyZsQcoHTr jb@tio ttl: 12h valid-principals: - ubuntu cert-type: user key-id: admin-ssh critical-options: [] extensions: - permit-X11-forwarding - permit-pty
cert: | ecdsa-sha2-nistp521-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHA1MjEtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgX26CCgmZ1ZuH3WjnfKapLAdXkQvw3TL7YAqGZ0vKGzAAAAAIbmlzdHA1MjEAAACFBACkktLRt9W7CntAF0jAenkEdRswTyBy2lNSTA3z2iEeQsG/++vD6afN6j7ODOvbl95ykNXaC4st1DjpFmIcl4j0LQAKDle9X2DpPkOfKdmtUHu9kQODnq9Q8ByI8CXrVzSftTnnxI8ABnPI6PJzC7mzeCmtz9SyuHyAXOzaPQIY7nfVEwAAAAAAAAACAAAAAQAAABh1c2VycGFzcy1hZG1pbkB0ZWxjby5jb20AAAAKAAAABnVidW50dQAAAAAAAAAAAAAAAGHe1VIAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQR0i2kr2z7OzsAdROnk71Jbyj/s7dSvRp7mLT75Jrmjf6aIdwF3Bdpsf9tdxhL8IlK5/PdznIfPoswF3aPTcjRnAAAAZAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASQAAACAip89yj0Ba2NnDVi+5MyEyf4vHSnS1laEXoKU9ToHC9AAAACEA2aK07GT771qnINmS58xMSQJgHDbz13ihHFaqSTuigBU= userpass-admin@telco.com public-key: | ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACkktLRt9W7CntAF0jAenkEdRswTyBy2lNSTA3z2iEeQsG/++vD6afN6j7ODOvbl95ykNXaC4st1DjpFmIcl4j0LQAKDle9X2DpPkOfKdmtUHu9kQODnq9Q8ByI8CXrVzSftTnnxI8ABnPI6PJzC7mzeCmtz9SyuHyAXOzaPQIY7nfVEw== ubuntu private-key: | -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS 1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQApJLS0bfVuwp7QBdIwHp5BHUbME8g ctpTUkwN89ohHkLBv/vrw+mnzeo+zgzr25fecpDV2guLLdQ46RZiHJeI9C0ACg5XvV9g6T 5DnynZrVB7vZEDg56vUPAciPAl61c0n7U558SPAAZzyOjycwu5s3gprc/Usrh8gFzs2j0C GO531RMAAAEAD4hlXw+IZV8AAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ AAAIUEAKSS0tG31bsKe0AXSMB6eQR1GzBPIHLaU1JMDfPaIR5Cwb/768Ppp83qPs4M69uX 3nKQ1doLiy3UOOkWYhyXiPQtAAoOV71fYOk+Q58p2a1Qe72RA4Oer1DwHIjwJetXNJ+1Oe fEjwAGc8jo8nMLubN4Ka3P1LK4fIBc7No9Ahjud9UTAAAAQRixUumLl0HFS3r19GQQJmJl +ZyhYXUcG+B8C9zs6yM+BQ2fG3g3FHJM9fkQ/+/8QbHqD8pU3oWZwg3aitp0uZ+mAAAAAA ECAw== -----END OPENSSH PRIVATE KEY----- ca-public-key: | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHSLaSvbPs7OwB1E6eTvUlvKP+zt1K9GnuYtPvkmuaN/poh3AXcF2mx/213GEvwiUrn893Och8+izAXdo9NyNGc= strongbox serial: 2 expires: 2022-01-27T09:57:48.000000Z