Ejemplos de uso inteligente de plantillas SSH





Los certificados SSH son una herramienta muy poderosa . Inicialmente, en el centro de certificación, step-ca



implementamos solo un conjunto mínimo de funciones para la autenticación mediante certificados de usuario y de host. Luego agregamos plantillas de certificado X.509 , y en agosto del año pasado, y plantillas SSH, en la versión 0.15.2. Finalmente, hemos documentado esta característica y estamos listos para hablar sobre ella.



Las plantillas para certificados SSH funcionan de manera similar a las plantillas X.509: son archivos JSON escritos en Go text/template



. Se utilizan para configurar los certificados SSH que emite step-ca



. Echemos un vistazo a qué son estas plantillas y cómo puede usarlas.



De forma predeterminada, una plantilla de certificado SSH personalizada se ve así:



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
	"criticalOptions": {{ toJson .CriticalOptions }}
}
      
      





Y aquí está el certificado SSH emitido con este patrón:



$ step ssh inspect id_ct-cert.pub
id_ct-cert.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:iczSh1XiBBE36yfJcDidgp6fqY3qWx1RtEwFfAN9jDs
        Signing CA: ECDSA SHA256:MKwRQ/SDKk/pCJbbCk5bfhZACjSjv7uZXLyc5n4Wx6k
        Key ID: "carl@smallstep.com"
        Serial: 2831574724231262409
        Valid: from 2020-11-17T16:48:11 to 2020-11-18T08:49:11
        Principals:
                carl
                carl@smallstep.com
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
      
      





Permite al usuario carl



(o carl@smallstep.com



) autenticarse en cualquier host SSH que confíe en mi CA SSH. El certificado incluye algunas extensiones básicas:



  • permit-x11-forwarding



    : Habilita el reenvío X11 (con ssh -X



    ) para ejecutar programas X11 remotos en la pantalla local.

  • permit-agent-forwarding



    : Permite la redirección del agente (uso ssh -A



    ) para reenviar claves del agente SSH local al host remoto (para obtener más información sobre el agente SSH, consulte aquí ).

  • permit-port-forwarding



    : Permite el reenvío de puertos (tunelización) de local a puerto remoto ( ssh -L



    ) o de remoto a local ( ssh -R



    ).

  • permit-pty



    : Una extensión muy importante. Si desea abrir una sesión interactiva en la consola, el host debe asignarle un pty (pseudo-tty). De lo contrario, no se proporciona interactividad. Por ejemplo, para probar la autenticación SSH en GitHub, se puede ejecutar ssh -T git@github.com



    ( -T



    deshabilita la solicitud pty).

  • permit-user-rc



    : Ejecute un archivo RC personal después de conectarse (ubicado ~/.ssh/rc



    en el host remoto).


Los certificados de usuario y de host admiten extensiones y parámetros críticos, pero OpenSSH no define extensiones integradas ni parámetros críticos para los certificados de host. Así, todo lo más interesante sucede con los certificados de usuario, por lo que en este artículo solo los consideraremos.



Ejemplos de plantillas de certificado



Hagamos algunos cambios en la plantilla predeterminada.



Prohibir agentes y reenvío de puertos

Si los usuarios se conectan a hosts internos a través del host bastión , sería bueno desactivar el reenvío de puertos por razones de seguridad. No desea que los usuarios redirijan el tráfico desde el servidor de producción MySQL a su host local. De manera similar, la redirección de agentes conlleva un riesgo de seguridad . Aquí hay una plantilla que simplemente elimina estas dos extensiones de los certificados SSH:



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {
           "permit-x11-forwarding": "",
           "permit-pty": "",
           "permit-user-rc": ""
  },
	"criticalOptions": {{ toJson .CriticalOptions }}
}
      
      





Incorporación de la directiva force-command

ForceCommand



Es una directiva de configuración SSHD del lado del servidor que ejecuta un comando alternativo en el host en lugar de un terminal interactivo. Pero con el mismo efecto, puede incrustarlo force-command



directamente en el certificado, en la sección Critical Options:



. Puede ser útil para cuentas de servicio que necesitan ejecutar solo un comando, por ejemplo, iniciar una tarea en un sistema remoto.



Restringir conexiones por direcciones

Para restringir el alcance de un certificado, se puede incrustar una lista de direcciones IP permitidas (bloques CIDR).



Aquí hay una plantilla de certificado que usa tanto source-address



, como force-command



.



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
	"criticalOptions": {
		"force-command": "echo \"Hello World\"",
		"source-address": "10.20.30.0/24,1.1.1.1/32"
	}
}
      
      





Este es un ejemplo normal, pero aquí la lista de IP está rígidamente fija y no cambia. Y normalmente queremos usar diferentes listas de direcciones para diferentes usuarios. Intentemos…



Insertar diferentes valores para diferentes usuarios

Obviamente, los usuarios no pueden tener derecho a editar el rango de direcciones. Por lo tanto, los valores dinámicos deben provenir de una fuente confiable.



Para hacer esto, a step-ca



través del proveedor OpenID Connect (OIDC), puede configurar el proveedor OAuth para agregar reclamos personalizados al token que contiene los bloques de direcciones CIRD que queremos agregar al certificado de este usuario.



El proveedor OIDC es la forma perfecta de emitir certificados SSH a step-ca. En el artículo DIY Single Sign-On para SSH , cubrí cómo configurar una CA SSH para emitir certificados SSH a corto plazo utilizando tokens de identificación de un proveedor OAuth confiable. Si un step-ca



configurado como un cliente OAuth confiable, leerá el campo email



del token de ID y recuperará la lista de entidades principales de certificados SSH desde allí (por ejemplo, los carl@smallstep.com



certificados para carl



y serán generados por el campo carl@smallstep.com



).



Pero OIDC permite leer ID y otros campos desde tokens hasta plantillas . Aquí es donde comienza la verdadera magia. Por lo tanto, agregamos un campo separado al directorio de usuarios en el lado del proveedor de identidad source_address



y lo reflejamos en nuestro token de identificación. Luego, a través de la plantilla SSH, puede ingresar el valor del token en el certificado. Aquí está la plantilla:



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
{{ if .Token.source_address }}
	"criticalOptions": {
		"source-address": "{{ .Token.source_address }}"
	}
{{ else }}
	"criticalOptions": {{ toJson .CriticalOptions }}
{{ end }}
}
      
      





Autenticación de GitHub por certificado

Veamos otro ejemplo de reclamo personalizado. Con GitHub Enterprise Cloud o GitHub Enterprise Server, puede configurar GitHub para usar certificados SSH. Específicamente, GitHub confiará en su autoridad de certificación SSH . Pero para que todo funcione, debe crear un certificado SSH separado para cada usuario con una extensión login@github.com



que especifique el nombre de usuario en GitHub. Con esta extensión, el certificado autentica al usuario en GitHub Enterprise. Y es genial: el mismo certificado le permite conectarse a su servidor a través de SSH y enviar el código a GitHub.



Aquí hay una plantilla de certificado con soporte personalizado para extensiones de GitHub:



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"criticalOptions": {{ toJson .CriticalOptions }},
{{ if .Token.ghu }}
	"extensions": {
	  "login@github.com": {{ toJson .Token.ghu }}
	}
{{ else }}
	"extensions": {{ toJson .Extensions }}
{{ end }}
}
      
      





Para usar la plantilla, debe agregar un requisito individual ghu



("Nombre de usuario de GitHub") a los tokens de identificación de OIDC . Echemos un vistazo más de cerca a cómo crear este reclamo personalizado con su proveedor de OAuth.



Registro de una aplicación con un proveedor de identidad

No todos los proveedores de identidad admiten requisitos individuales, pero si lo hacen, el proceso es bastante similar. Así es como se hace con Okta:



  1. Añadir a la aplicación de OAuth Okta y confiar en ella con el proveedor de PeDIP en step-ca



    como se describe en el bricolaje SSO para SSH artículo .





  2. Agregue un nuevo campo a su directorio de usuarios de Okta (por ejemplo GitHub Username



    )

  3. Agregue un requisito individual al token OIDC , por ejemplo, con un nombre cortoghu





  4. Ahora completamos el campo para el usuario de prueba y verificamos el requisito. Okta tiene una herramienta de prueba de tokens de identificación. O se puede utilizar step



    para validar todo el flujo de OAuth:



    OIDC_ENDPOINT="https://[your organization].okta.com/oauth2/default/.well-known/openid-configuration"
    CLIENT_ID="[your OAuth client ID]"
    CLIENT_SECRET="[your OAuth client secret]"
    step oauth --oidc --provider $OIDC_ENDPOINT \
        --client-id $CLIENT_ID --client-secret $CLIENT_SECRET \
        --listen=":10000" --bare |
    step crypto jwt inspect --insecure
          
          





  5. Finalmente, step-ca



    para usar este patrón. La configuración del proveedor debe hacer referencia al archivo de plantilla:



    {
      "provisioners": [
        {
          "type": "OIDC",
          "name": "Okta",
          "clientID": "[your OAuth client ID]",
          "clientSecret": "[your OAuth client secret]",
          "configurationEndpoint": "https://[your organization].okta.com/oauth2/default/.well-known/openid-configuration",
          "listenAddress": ":10000",
          "options": {
            "ssh": {
                "templateFile": "templates/certs/ssh/github.tpl"
            }
          }
        },
          ...
      ]
    }
          
          





Que sigue



Hemos agregado una sección sobre Plantillas SSH a la documentación que entra en más detalles sobre todos los parámetros y variables.



Si tiene alguna pregunta, no dude en preguntar .



All Articles