SSH User Certificates With Azure AD & Smallstep
As I work through evaluating better security for infrastructure within my team, one of the areas I saw an opportunity ripe for automation is implementing SSH certificates. SSH certificates can provide a smoother experience than simple RSA keys, but normally require some specific domain knowledge about PKI. Certificates and PKI can be complicated; sometimes they create more headaches than they solve.
Enter Smallstep – they have created a great tool called step-ca
for creating a really simple certificate authority and an excellent CLI called step
for interacting with it. If you configure step-ca
as a certificate authority for SSH, like so:
step-ca init -ssh
then it can issue both user and host certificates for use in your environment. Once you have a working CA, you can configure your ca.json
with a new provisioner. Provisioners are the backbone of step-ca
; they are how one is authorized to generate a certificate. Smallstep has built out an OIDC (OpenID Connect) provisioner which works with both Google and Azure AD.
[Note: Azure AD is the DaaS offering from Microsoft which is not the same as traditional Active Directory or ADFS.]
To set up an Azure AD provisioner, you'll need to first register Smallstep in your Azure AD tenant as an application. This can be done from the Azure CLI:
az ad app create --display-name "Smallstep SSH" --reply-urls https://garrettyamada.com:10000
[Replace "garrettyamada.com" with 127.0.0.1 here. My static site generator likes to replace any instance of it with my domain name (oops).]
The port 10000
is an example specific listening port when the step
CLI launches a web browser tab for sign-in. This can be set in our ca.json
, as we'll see in a moment. For specifics on the app registration and the credential details you need, see https://smallstep.com/docs/sso-ssh/azure-ad/.
After the app is registered, we'll add a provisioner to our step-ca
configuration's ca.json
.
{
"type": "OIDC",
"name": "AzureAD",
"clientID": "your-app-id",
"clientSecret": "your-client-secret",
"configurationEndpoint": "https://login.microsoftonline.com/your-tenant-id/v2.0/.well-known/openid-configuration",
"admins": [
"[email protected]"
],
"domains": [
"test.com"
],
"listenAddress": ":10000",
"claims": {
"maxTLSCertDuration": "8h0m0s",
"defaultTLSCertDuration": "2h0m0s",
"disableRenewal": true,
"enableSSHCA": true
}
}
Once ca.json
is updated, restart step-ca
. Then, from the client machine (assuming you have bootstrapped step
), run:
step ssh login [email protected] --provisioner "AzureAD"
This will launch a web browser tab, you'll sign in to Azure AD, which will return a token to step
. step
will use that token to request an SSH certificate from your CA, and if granted, add the certificate to your ssh-agent
.
That's all there is to it for setting up user certificates with the Azure AD provisioner. For more details, see the Smallstep documentation. Happy SSH-ing!