2021-01-03 14:25:43 +05:30
---
2022-07-23 23:45:48 +05:30
stage: Systems
2021-02-22 17:27:13 +05:30
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
2021-01-03 14:25:43 +05:30
---
2021-09-04 01:27:46 +05:30
# User lookup via OpenSSH's AuthorizedPrincipalsCommand **(FREE SELF)**
2018-11-18 11:00:15 +05:30
2021-11-11 11:23:49 +05:30
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19911) in GitLab 11.2.
2018-11-18 11:00:15 +05:30
2021-02-22 17:27:13 +05:30
The default SSH authentication for GitLab requires users to upload their SSH
2018-11-18 11:00:15 +05:30
public keys before they can use the SSH transport.
2021-02-22 17:27:13 +05:30
In centralized (for example, corporate) environments this can be a hassle
operationally, particularly if the SSH keys are temporary keys issued to the
user, including ones that expire 24 hours after issuing.
2018-11-18 11:00:15 +05:30
In such setups some external automated process is needed to constantly
upload the new keys to GitLab.
2021-02-22 17:27:13 +05:30
WARNING:
2021-12-11 22:18:48 +05:30
OpenSSH version 6.9+ is required because `AuthorizedKeysCommand` must be
able to accept a fingerprint. Check the version of OpenSSH on your server.
2018-11-18 11:00:15 +05:30
## Why use OpenSSH certificates?
By using OpenSSH certificates all the information about what user on
GitLab owns the key is encoded in the key itself, and OpenSSH itself
guarantees that users can't fake this, since they'd need to have
access to the private CA signing key.
When correctly set up, this does away with the requirement of
uploading user SSH keys to GitLab entirely.
## Setting up SSH certificate lookup via GitLab Shell
2018-12-05 23:21:45 +05:30
How to fully set up SSH certificates is outside the scope of this
2022-08-27 11:52:29 +05:30
document. See
[OpenSSH's`PROTOCOL.certkeys` ](https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD )
for how it works, for example
[RedHat's documentation about it ](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-using_openssh_certificate_authentication ).
2018-11-18 11:00:15 +05:30
We assume that you already have SSH certificates set up, and have
2021-09-30 23:02:18 +05:30
added the `TrustedUserCAKeys` of your CA to your `sshd_config` , for example:
2018-11-18 11:00:15 +05:30
2020-04-08 14:13:33 +05:30
```plaintext
2018-11-18 11:00:15 +05:30
TrustedUserCAKeys /etc/security/mycompany_user_ca.pub
```
Usually `TrustedUserCAKeys` would not be scoped under a `Match User
git` in such a setup, since it would also be used for system logins to
the GitLab server itself, but your setup may vary. If the CA is only
used for GitLab consider putting this in the `Match User git` section
(described below).
2022-07-23 23:45:48 +05:30
The SSH certificates being issued by that CA **must** have a "key ID"
2021-09-30 23:02:18 +05:30
corresponding to that user's username on GitLab, for example (some output
2018-11-18 11:00:15 +05:30
omitted for brevity):
2020-03-13 15:44:24 +05:30
```shell
2018-11-18 11:00:15 +05:30
$ ssh-add -L | grep cert | ssh-keygen -L -f -
2020-03-13 15:44:24 +05:30
2018-11-18 11:00:15 +05:30
(stdin):1:
Type: ssh-rsa-cert-v01@openssh.com user certificate
Public key: RSA-CERT SHA256:[...]
Signing CA: RSA SHA256:[...]
Key ID: "aearnfjord"
Serial: 8289829611021396489
Valid: from 2018-07-18T09:49:00 to 2018-07-19T09:50:34
Principals:
sshUsers
[...]
[...]
```
2021-09-30 23:02:18 +05:30
Technically that's not strictly true, for example, it could be
2018-11-18 11:00:15 +05:30
`prod-aearnfjord` if it's a SSH certificate you'd normally log in to
servers as the `prod-aearnfjord` user, but then you must specify your
own `AuthorizedPrincipalsCommand` to do that mapping instead of using
our provided default.
The important part is that the `AuthorizedPrincipalsCommand` must be
2020-05-24 23:13:21 +05:30
able to map from the "key ID" to a GitLab username in some way, the
2018-11-18 11:00:15 +05:30
default command we ship assumes there's a 1=1 mapping between the two,
since the whole point of this is to allow us to extract a GitLab
username from the key itself, instead of relying on something like the
default public key to username mapping.
Then, in your `sshd_config` set up `AuthorizedPrincipalsCommand` for
the `git` user. Hopefully you can use the default one shipped with
GitLab:
2020-04-08 14:13:33 +05:30
```plaintext
2018-11-18 11:00:15 +05:30
Match User git
AuthorizedPrincipalsCommandUser root
AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers
```
2022-08-13 15:12:31 +05:30
This command emits output that looks something like:
2018-11-18 11:00:15 +05:30
2020-04-08 14:13:33 +05:30
```shell
2018-11-18 11:00:15 +05:30
command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell username-{KEY_ID}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty {PRINCIPAL}
```
Where `{KEY_ID}` is the `%i` argument passed to the script
2021-09-30 23:02:18 +05:30
(for example, `aeanfjord` ), and `{PRINCIPAL}` is the principal passed to it
(for example, `sshUsers` ).
2018-11-18 11:00:15 +05:30
2021-06-08 01:23:25 +05:30
You need to customize the `sshUsers` part of that. It should be
2018-11-18 11:00:15 +05:30
some principal that's guaranteed to be part of the key for all users
who can log in to GitLab, or you must provide a list of principals,
2021-09-30 23:02:18 +05:30
one of which is present for the user, for example:
2018-11-18 11:00:15 +05:30
2020-04-08 14:13:33 +05:30
```plaintext
2018-11-18 11:00:15 +05:30
[...]
AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers windowsUsers
```
## Principals and security
2021-06-08 01:23:25 +05:30
You can supply as many principals as you want, these are turned
2018-11-18 11:00:15 +05:30
into multiple lines of `authorized_keys` output, as described in the
`AuthorizedPrincipalsFile` documentation in `sshd_config(5)` .
Normally when using the `AuthorizedKeysCommand` with OpenSSH the
principal is some "group" that's allowed to log into that
server. However with GitLab it's only used to appease OpenSSH's
2020-05-24 23:13:21 +05:30
requirement for it, we effectively only care about the "key ID" being
2021-06-08 01:23:25 +05:30
correct. Once that's extracted GitLab enforces its own ACLs for
2021-09-30 23:02:18 +05:30
that user (for example, what projects the user can access).
2018-11-18 11:00:15 +05:30
2021-11-18 22:05:49 +05:30
It's therefore fine to be overly generous in what you accept. For example, if the user has no access
to GitLab, an error is produced with a message about an invalid user.
2018-11-18 11:00:15 +05:30
message about this being an invalid user.
## Interaction with the `authorized_keys` file
SSH certificates can be used in conjunction with the `authorized_keys`
2021-06-08 01:23:25 +05:30
file, and if set up as configured above the `authorized_keys` file
still serves as a fallback.
2018-11-18 11:00:15 +05:30
This is because if the `AuthorizedPrincipalsCommand` can't
2021-06-08 01:23:25 +05:30
authenticate the user, OpenSSH falls back on
2018-11-18 11:00:15 +05:30
`~/.ssh/authorized_keys` (or the `AuthorizedKeysCommand` ).
2022-08-27 11:52:29 +05:30
Therefore there may still be a reason to use the [Fast lookup of authorized SSH keys in the database ](fast_ssh_key_lookup.md ) method
2021-06-08 01:23:25 +05:30
in conjunction with this. Since you are using SSH certificates for
2018-11-18 11:00:15 +05:30
all your normal users, and relying on the `~/.ssh/authorized_keys`
fallback for deploy keys, if you make use of those.
But you may find that there's no reason to do that, since all your
2021-06-08 01:23:25 +05:30
normal users use the fast `AuthorizedPrincipalsCommand` path, and
only automated deployment key access falls back on
2018-11-18 11:00:15 +05:30
`~/.ssh/authorized_keys` , or that you have a lot more keys for normal
users (especially if they're renewed) than you have deploy keys.
## Other security caveats
Users can still bypass SSH certificate authentication by manually
uploading an SSH public key to their profile, relying on the
`~/.ssh/authorized_keys` fallback to authenticate it. There's
2022-10-11 01:57:18 +05:30
currently no feature to prevent this,
2022-08-27 11:52:29 +05:30
[but there's an open request for adding it ](https://gitlab.com/gitlab-org/gitlab/-/issues/23260 ).
2018-11-18 11:00:15 +05:30
2021-06-08 01:23:25 +05:30
Such a restriction can currently be hacked in by, for example, providing a
2018-11-18 11:00:15 +05:30
custom `AuthorizedKeysCommand` which checks if the discovered key-ID
returned from `gitlab-shell-authorized-keys-check` is a deploy key or
not (all non-deploy keys should be refused).
2018-11-20 20:47:30 +05:30
## Disabling the global warning about users lacking SSH keys
2021-06-08 01:23:25 +05:30
By default GitLab shows a "You won't be able to pull or push
2018-11-20 20:47:30 +05:30
project code via SSH" warning to users who have not uploaded an SSH
key to their profile.
This is counterproductive when using SSH certificates, since users
aren't expected to upload their own keys.
To disable this warning globally, go to "Application settings ->
Account and limit settings" and disable the "Show user add SSH key
message" setting.
This setting was added specifically for use with SSH certificates, but
can be turned off without using them if you'd like to hide the warning
for some other reason.