Thursday, May 19, 2022

Setup Gerrit server using HTTP authentication on Ubuntu

 I know there are quite some posts about how to do that, but decide to make this after I scratched to find solution for problem I faced.

For installing Gerrit server on Linux itself, it is pretty straight forward. Not going to talk about the simple way as it is pretty much just a local git. Will only discuss the Standalone Daemon installation as described here: https://gerrit-review.googlesource.com/Documentation/install.html

The instruction is very simple, adding gerrit as new user to your Linux, use gerrit account to install gerrit war file. And there is a note specifically mentioned you would need manually create the gerrit application folder if user gerrit does not have the privilege to create folder there. It also means there is no need of sudoer right for setting up gerrit server.

I picked most default setting during installation, as to be honestly, I don't know exactly what the option is for. But for authentication method, I'm sure I would want the 'http' option, as I want the users are manageable and there is no LDAP or ActiveDirectory at back end for small projects/small teams. But likely nowhere in the guide mentioned that you would need to setup the HTTP server (such as Apache) to make it working. Like many others, I have set the gerrit server on default port 8080, then I tried using web browser to open http://localhost:8080, and got the error: 

Configuration Error

Check the HTTP server's authentication settings.

The HTTP server did not provide the username in the Authorization header when it forwarded the request to Gerrit Code Review.

Some post like this one clarified that gerrit server is not expecting user to directly access the port reserved for Gerrit. Instead, Gerrit is expecting the http server to forward/redirect the access to the gerrit port. If user want to access Gerrit via a port other than the default http port 80, then a port different from the gerrit port would be need to setup with the http server. And, yes, a http server needs to be setup to make things working, especially, the http server also in charge of user authentication => this is not done by Gerrit server. Below setting is for user using http://gerrit_server_IP:8000 to access gerrit with web browser.

I installed the popular apache2 on Ubuntu: sudo apt install apache2

Then create /etc/apache2/sites-available/010-gerrit.conf with content:

<VirtualHost *:8000>
    ServerName localhost

    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
          Order deny,allow
          Allow from all
    </Proxy>
    <Location "/login/">
          AuthType Basic
          AuthName "Gerrit Code Review"
          AuthBasicProvider file
          AuthUserFile /etc/apache2/gerrit.htpasswd
          Require valid-user
    </Location>

    ProxyPass / http://localhost:8080/
</VirtualHost>

For highlighted, the port 8000 is the port for user to access Gerrit via web browser; The path for AuthUserFile is the file used to store authorized user accounts for the web access (not for the Linux host). The port 8080 is where the Gerrit server is listening to. And cannot add 'no-cannon' after that as many post said, as that will give me error (Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be in the form 'key=value') when I trying to restart Apache server. Also, need to add "Listen 8000" to /etc/apache2/ports.conf to make Apache accept access to the 8000 port. Then would need to enable the Gerrit config and restart Apache server with command:

sudo a2enmod proxy_http
sudo a2ensite 010-gerrit
sudo systemctl restart apache2

At this point, both Apache and Gerrit servers are up and running, but there is no valid user yet. To add the first user which would be the admin of Gerrit server, run this command to create user 'admin':

htpasswd -c /etc/apache2/gerrit.htpasswd admin

Note, usually the password file would be maintained by the web service account, so there is no need 'sudo' for running htpasswd command. Without 'sudo'. would need to run 'sudo chown' and 'sudo chgrp' against the password file to grant permission to the web service account, such as 'gerrit'.

Gerrit server is ready from now on. New user would need be added manually by gerrit account with command:

htpasswd /etc/apache2/gerrit.htpasswd new_user

Note: comparing above, no '-c' here. Otherwise it will overwrite the password file, and the previous added account (admin) would get removed.

There is many way to add a self register user service if that is desired.

Several other notes:

1) gerrit server won't automatically get started. Follow the instruction https://gerrit-review.googlesource.com/Documentation/install.html to make it automatically starts with OS boot.

And keep in mind, for manually starting gerrit, have to run gerrit.sh start with sudo as it needs root right. Make sure seeing 'Starting Gerrit Code Review: OK' after start gerrit.

2) Better update gerrit_application_directory/etc/gerrit.conf port setting of canonicalWebUrl, change to:

 canonicalWebUrl=http://gerrit_server_IP:8000/

i.e. the port number should be matched with Apache server setting for Gerrit. Otherwise, when user trying to logout or other operation, gerrit may direct the access to the Gerrit internal port 8080.

3) Keep in mind the user account for the host PC and Gerrit service are separated. 'gerrit' is account on the host PC, and above 'admin' account is gerrit user account. For gerrit operation via SSH, user would need to upload the SSH key for the Gerrit account first. Also note, with latest Git/OpenSSH, it may no longer accept RSA key, so you may generate ed25519 key pair for current host user account with this command:

ssh-keygen -t ed25519 -C 'some_comment'

Then you can run gerrit ssh command, such as this one for flush project_list:

ssh -p 29418 admin@gerrit_server_IP gerrit flush-caches --cache project_list

Note above command is using the Gerrit account name 'admin' for the SSH session, as the SSH service is provided by Gerrit.

4) Gerrit supports multiple plugin, such as gitiles for browse repo code. It's pretty easy to install plugins, just drop the jar file to gerrit_application_directory/plugins folder. And in fact, the gerrit installer war is coming with several common plugins, include giltes. User can install the plugin with init command (ref link), like this:

java -jar gerrit-3.5.1.war init -d /path/to/gerrit_app --install-plugin gitiles --install-plugin hooks --install-plugin plugin-manager --install-plugin singleusergroup ...

Or just do init with --install-all-plugins to have all default plugins installed.

5) If manually put a bare repo under gerrit git folder, it won't show up in gerrit web view. Running "gerrit flush-caches --cache project_list" won't help. User may explicitly make it visible with gerrit command: gerrit set-project the_hidden_git_name --project-state ACTIVE, or take other approach mentioned in the stackoverflow page: https://stackoverflow.com/questions/27817107/unhide-a-hidden-gerrit-project

And for local git, would need to set or update the remote URL like this:

git remote set-url origin ssh://gerrit_server_IP:29418/git_name 

6) As using HTTP authentication, we are not hooking up to company's LDAP server. The mail setting might be a headache, as it is not easy to setup using company's SMTP server. Even with mail service installed on the local Linux server, email exchange between the Linux and company's email server might be a nightmare. For example, I have Postfix installed on my Linux, and I'm getting 'Rejecting Unknown Local Recipients with Postfix'. Following this I can get the error resolved, the Linux mail system did say mail has been delivered, but I have never got the email from company email server. This would be a problem as user needs to register an email for submit code review: gerrit will send a verification email before adding user email address in record. To get around this, following https://gerrit-review.googlesource.com/Documentation/cmd-set-account.html, set the email address for new user using the admin account:

ssh -p 29418 admin@localhost gerrit set-account --add-email useremail_name@company.com gerrit_username

For gerrit management, there is plugins/admin-console (googlesource.com) which provides  information via SSH commands to Gerrit Administrators.

Note:  if planning to use LDAP and not using HTTP authentication, then no need to setup Apache as Gerrit has built-in web service, may just follow https://gerrit-review.googlesource.com/Documentation/config-gerrit.html#ldap, do not enable proxy-http, i.e. gerrit.config should have setting like:

[httpd]
        #listenUrl = proxy-http://*:8081/
        listenUrl = http://*:8080/