2021-01-03 14:25:43 +05:30
---
2022-07-16 23:28:13 +05:30
stage: Create
group: Source Code
2022-11-25 23:54:43 +05:30
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
2021-01-03 14:25:43 +05:30
---
2021-09-04 01:27:46 +05:30
# Fast lookup of authorized SSH keys in the database **(FREE SELF)**
2018-03-17 18:26:18 +05:30
2021-02-22 17:27:13 +05:30
NOTE:
2020-07-28 23:09:34 +05:30
This document describes a drop-in replacement for the
2023-04-23 21:23:45 +05:30
`authorized_keys` file. For standard (non-deploy key) users, consider using
2020-04-22 19:07:51 +05:30
[SSH certificates ](ssh_certificates.md ). They are even faster, but are not a
drop-in replacement.
2018-03-17 18:26:18 +05:30
Regular SSH operations become slow as the number of users grows because OpenSSH
searches for a key to authorize a user via a linear search. In the worst case,
2022-07-16 23:28:13 +05:30
such as when the user is not authorized to access GitLab, OpenSSH scans the
2018-03-17 18:26:18 +05:30
entire file to search for a key. This can take significant time and disk I/O,
2021-06-08 01:23:25 +05:30
which delays users attempting to push or pull to a repository. Making
2018-03-17 18:26:18 +05:30
matters worse, if users add or remove keys frequently, the operating system may
not be able to cache the `authorized_keys` file, which causes the disk to be
accessed repeatedly.
GitLab Shell solves this by providing a way to authorize SSH users via a fast,
indexed lookup in the GitLab database. This page describes how to enable the fast
lookup of authorized SSH keys.
2019-09-30 21:07:59 +05:30
## Fast lookup is required for Geo **(PREMIUM)**
2019-07-31 22:56:46 +05:30
2022-06-21 17:19:12 +05:30
Unlike [Cloud Native GitLab ](https://docs.gitlab.com/charts/ ), Omnibus GitLab by default
manages an `authorized_keys` file that is located in the
2022-07-16 23:28:13 +05:30
`git` user's home directory. For most installations, this file is located under
`/var/opt/gitlab/.ssh/authorized_keys` , but you can use the following command to
locate the `authorized_keys` on your system:
2021-09-04 01:27:46 +05:30
```shell
getent passwd git | cut -d: -f6 | awk '{print $1"/.ssh/authorized_keys"}'
```
The `authorized_keys` file contains all the public SSH keys for users allowed to access GitLab. However, to maintain a
2022-07-16 23:28:13 +05:30
single source of truth, [Geo ](../geo/index.md ) must be configured to perform SSH fingerprint
2019-07-31 22:56:46 +05:30
lookups via database lookup.
2020-11-24 15:15:51 +05:30
As part of [setting up Geo ](../geo/index.md#setup-instructions ),
2021-06-08 01:23:25 +05:30
you are required to follow the steps outlined below for both the primary and
2022-07-16 23:28:13 +05:30
secondary nodes, but **Write to "authorized keys" file**
must be unchecked only on the primary node, because it is reflected
2019-07-31 22:56:46 +05:30
automatically on the secondary if database replication is working.
2023-04-23 21:23:45 +05:30
## Set up fast lookup
2018-03-17 18:26:18 +05:30
GitLab Shell provides a way to authorize SSH users via a fast, indexed lookup
to the GitLab database. GitLab Shell uses the fingerprint of the SSH key to
check whether the user is authorized to access GitLab.
2023-04-23 21:23:45 +05:30
Fast lookup can be enabled with the following SSH servers:
- [`gitlab-sshd` ](gitlab_sshd.md )
- OpenSSH
You can run both services simultaneously by using separate ports for each service.
### With `gitlab-sshd`
To set up `gitlab-sshd` , see [the `gitlab-sshd` documentation ](gitlab_sshd.md ).
After `gitlab-sshd` is enabled, GitLab Shell and `gitlab-sshd` are configured
to use fast lookup automatically.
### With OpenSSH
WARNING:
OpenSSH version 6.9+ is required because `AuthorizedKeysCommand` must be
able to accept a fingerprint. Check the version of OpenSSH on your server with `sshd -V` .
2022-07-16 23:28:13 +05:30
Add the following to your `sshd_config` file. This file is usually located at
`/etc/ssh/sshd_config` , but it is at `/assets/sshd_config` if you're using
2018-03-17 18:26:18 +05:30
Omnibus Docker:
2020-03-13 15:44:24 +05:30
```plaintext
2020-04-08 14:13:33 +05:30
Match User git # Apply the AuthorizedKeysCommands to the git user only
AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k
AuthorizedKeysCommandUser git
Match all # End match, settings apply to all users again
2018-03-17 18:26:18 +05:30
```
Reload OpenSSH:
2020-03-13 15:44:24 +05:30
```shell
2018-03-17 18:26:18 +05:30
# Debian or Ubuntu installations
sudo service ssh reload
# CentOS installations
sudo service sshd reload
```
2020-07-28 23:09:34 +05:30
Confirm that SSH is working by commenting out your user's key in the `authorized_keys`
2022-03-02 08:16:31 +05:30
file (start the line with a `#` to comment it), and from your local machine, attempt to pull a repository or run:
2018-03-17 18:26:18 +05:30
2022-03-02 08:16:31 +05:30
```shell
ssh -T git@gitlab.example.com
```
2022-07-16 23:28:13 +05:30
A successful pull or [welcome message ](../../user/ssh.md#verify-that-you-can-connect )
means that GitLab was able to find the key in the database,
as it is not present in the file.
2019-07-31 22:56:46 +05:30
2021-02-22 17:27:13 +05:30
NOTE:
2020-07-28 23:09:34 +05:30
For Installations from source, the command would be located at
2020-05-24 23:13:21 +05:30
`/home/git/gitlab-shell/bin/gitlab-shell-authorized-keys-check` if [the install from source ](../../install/installation.md#install-gitlab-shell ) instructions were followed.
2022-07-16 23:28:13 +05:30
You might want to consider creating a wrapper script somewhere else, as this command must be
2020-05-24 23:13:21 +05:30
owned by `root` and not be writable by group or others. You could also consider changing the ownership of this command
as required, but that might require temporary ownership changes during `gitlab-shell` upgrades.
2021-02-22 17:27:13 +05:30
WARNING:
2020-07-28 23:09:34 +05:30
Do not disable writes until SSH is confirmed to be working
2021-06-08 01:23:25 +05:30
perfectly; otherwise, the file quickly becomes out-of-date.
2018-03-17 18:26:18 +05:30
2018-03-27 19:54:05 +05:30
In the case of lookup failures (which are common), the `authorized_keys`
2021-06-08 01:23:25 +05:30
file is still scanned. So Git SSH performance would still be slow for many
2018-03-17 18:26:18 +05:30
users as long as a large file exists.
2021-11-18 22:05:49 +05:30
To disable writes to the `authorized_keys` file:
2018-03-17 18:26:18 +05:30
2022-10-11 01:57:18 +05:30
1. On the top bar, select **Main menu > Admin** .
2021-09-04 01:27:46 +05:30
1. On the left sidebar, select **Settings > Network** .
1. Expand **Performance optimization** .
2021-11-18 22:05:49 +05:30
1. Clear the **Use authorized_keys file to authenticate SSH keys** checkbox.
2021-09-04 01:27:46 +05:30
1. Select **Save changes** .
2018-03-17 18:26:18 +05:30
Again, confirm that SSH is working by removing your user's SSH key in the UI,
2020-05-24 23:13:21 +05:30
adding a new one, and attempting to pull a repository.
2018-03-17 18:26:18 +05:30
Then you can backup and delete your `authorized_keys` file for best performance.
2020-07-28 23:09:34 +05:30
The current users' keys are already present in the database, so there is no need for migration
2022-03-02 08:16:31 +05:30
or for users to re-add their keys.
2018-03-17 18:26:18 +05:30
2023-04-23 21:23:45 +05:30
### How to go back to using the `authorized_keys` file
2018-03-17 18:26:18 +05:30
2022-07-16 23:28:13 +05:30
This overview is brief. Refer to the above instructions for more context.
2018-03-17 18:26:18 +05:30
2021-11-18 22:05:49 +05:30
1. [Rebuild the `authorized_keys` file ](../raketasks/maintenance.md#rebuild-authorized_keys-file ).
1. Enable writes to the `authorized_keys` file.
2022-10-11 01:57:18 +05:30
1. On the top bar, select **Main menu > Admin** .
2021-11-18 22:05:49 +05:30
1. On the left sidebar, select **Settings > Network** .
1. Expand **Performance optimization** .
1. Select the **Use authorized_keys file to authenticate SSH keys** checkbox.
2018-03-17 18:26:18 +05:30
1. Remove the `AuthorizedKeysCommand` lines from `/etc/ssh/sshd_config` or from `/assets/sshd_config` if you are using Omnibus Docker.
2021-11-18 22:05:49 +05:30
1. Reload `sshd` : `sudo service sshd reload` .
2018-03-17 18:26:18 +05:30
2020-07-28 23:09:34 +05:30
## SELinux support and limitations
GitLab supports `authorized_keys` database lookups with [SELinux ](https://en.wikipedia.org/wiki/Security-Enhanced_Linux ).
Because the SELinux policy is static, GitLab doesn't support the ability to change
2021-09-04 01:27:46 +05:30
internal webserver ports at the moment. Administrators would have to create a special `.te`
2022-07-16 23:28:13 +05:30
file for the environment, as it isn't generated dynamically.
### Additional documentation
2023-03-17 16:20:25 +05:30
Additional technical documentation for `gitlab-sshd` may be found in the
[GitLab Shell documentation ](../../development/gitlab_shell/index.md ).
2022-04-04 11:22:00 +05:30
## Troubleshooting
If your SSH traffic is [slow ](https://github.com/linux-pam/linux-pam/issues/270 )
2022-05-07 20:08:51 +05:30
or causing high CPU load, be sure to check the size of `/var/log/btmp` , and ensure it is rotated on a regular basis or after reaching a certain size.
2022-04-04 11:22:00 +05:30
If this file is very large, GitLab SSH fast lookup can cause the bottleneck to be hit more frequently, thus decreasing performance even further.
If you are able to, you may consider disabling [`UsePAM` in your `sshd_config` ](https://linux.die.net/man/5/sshd_config ) to avoid reading `/var/log/btmp` altogether.
2022-07-16 23:28:13 +05:30
Running `strace` and `lsof` on a running `sshd: git` process returns debugging information.
To get an `strace` on an in-progress Git over SSH connection for IP `x.x.x.x` , run:
2022-04-04 11:22:00 +05:30
```plaintext
sudo strace -s 10000 -p $(sudo netstat -tp | grep x.x.x.x | egrep 'ssh.*: git' | sed -e 's/.*ESTABLISHED *//' -e 's#/.* ##')
```
Or get an `lsof` for a running Git over SSH process:
```plaintext
sudo lsof -p $(sudo netstat -tp | egrep 'ssh.*: git' | head -1 | sed -e 's/.*ESTABLISHED *//' -e 's#/.* ##')
```