Skip to content

Support authentication using SSH Certificates

Related issue: gitlab#408474 (closed)

Gitlab Rails: Draft: Support uploading CA files to a group (gitlab!126741 - closed)

Functional flow:

The functional workflow is the following:

  • An admin adds CA.pub to a namespace
  • A user tries authenticating using a certificate signed by the CA
  • Gitlab Shell sends the fingerprint of the CA to /authorized_certs and returns the namespace, which is remembered on Gitlab Shell during an SSH connection. The CA is unique for an instance (unique index for the fingerprint). It means that it's not necessary to integrate a namespace into the certificate, a certificate and a namespace have 1 -> 1 relationship.
  • The namespace is sent every time /allowed is called. It means that we send project fullpath and the namespace in which a user is authenticated. If the project doesn't have the namespace in the list of its ancestors, the action is not allowed.
sequenceDiagram
    User->>+Gitlab Shell: Auth using SSH Certificate
    Gitlab Shell->>+Gitlab Rails: /authorized_certs?key=signing-key-of-certificate&user_identity=username-or-primary-email
    Gitlab Rails-->>-Gitlab Shell: responds with the namespace that configures the CA and username of the user
    Gitlab Shell-->>User: Authenticated successfully
    User->>+Gitlab Shell: Git command to a specific project
    Gitlab Shell->>+Gitlab Rails: /allowed [namespace=namespace]
    Gitlab Rails-->>-Gitlab Shell: responds that the project belongs to this namespace or its ancestor
    Gitlab Shell-->>User: success

Steps to verify

  1. Ensure your current working directory is your <GDK_ROOT>

  2. Generate CA (Certificate Authority). Creates 2 files CA and CA.pub:

    ssh-keygen -C CA -f CA
  3. Create a new SSH ECDSA based key:

    ssh-keygen -t ecdsa -f ~/.ssh/gitlab-shell-812-ecdsa
  4. Gitlab Rails switched to id-group-ssh-certificate branch

  5. Use the UX from Gitlab Rails MR to add CA.pub to a group

  6. Generate a certificate. CA is the name of the CA file from 1st step, admin@example.com is the primary email of the user (username can be used as well), -V +1d is the expiration date, setting a small one like -V +5s can be used to test that expired certificates are not accepted:

    ssh-keygen -s CA -I admin@example.com -V +1d ~/.ssh/gitlab-shell-812-ecdsa.pub
  7. Gitlab Shell switched to this current branch (make command can be run to be sure). gdk start to start the app, gdk tail sshd will show the Gitlab Shell logs.

  8. Remove any loaded SSH keys:

    ssh-add -D
  9. Explicitly set SSH key to CA and test. gdk.test is the host here, can be 127.0.0.1 as well, the other options are to ensure no other config / key is used:

    ssh -v -F /dev/null -o "IdentitiesOnly=yes" -i ~/.ssh/gitlab-shell-812-ecdsa git@gdk.test -p 2222

The SSH certificate is accepted. The output similar to the following is generated:

debug1: Will attempt key: GitLab ED25519 SHA256:nAbfYGWTQguxdZFPfo6a9anzCVQ/oO6lRUAxotkxEtQ agent
debug1: Will attempt key: /Users/igordrozdov/.ssh/id_ed25519 ED25519 SHA256:VwKSgBdqjbYZEzaK2DsXcKwa4AG5Rh/ABrNATjXpIVM explicit
debug1: Will attempt key: /Users/igordrozdov/.ssh/id_ed25519 ED25519-CERT SHA256:nAbfYGWTQguxdZFPfo6a9anzCVQ/oO6lRUAxotkxEtQ explicit
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-dss>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: GitLab ED25519 SHA256:nAbfYGWTQguxdZFPfo6a9anzCVQ/oO6lRUAxotkxEtQ agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: /Users/igordrozdov/.ssh/id_ed25519 ED25519 SHA256:VwKSgBdqjbYZEzaK2DsXcKwa4AG5Rh/ABrNATjXpIVM explicit
debug1: Authentications that can continue: publickey
debug1: Offering public key: /Users/igordrozdov/.ssh/id_ed25519 ED25519-CERT SHA256:nAbfYGWTQguxdZFPfo6a9anzCVQ/oO6lRUAxotkxEtQ explicit
debug1: Server accepts key: /Users/igordrozdov/.ssh/id_ed25519 ED25519-CERT SHA256:nAbfYGWTQguxdZFPfo6a9anzCVQ/oO6lRUAxotkxEtQ explicit
Authenticated to gdk.test ([127.0.0.1]:2222) using "publickey".

I have multiple SSH keys in ~/.ssh folder, but none of them are accepted (may require removing them from the user profile of your local instance). The certificate is accepted.

Edited by Ash McKenzie

Merge request reports

Loading