299 lines
13 KiB
Markdown
299 lines
13 KiB
Markdown
---
|
|
date: 2019-10-15T00:00:00-05:00
|
|
title: "Installing Gerrit and Keycloak for GDB"
|
|
tags: [en_us, english, debian, free-software, planet-fedora, gerrit, keycloak, howto]
|
|
---
|
|
|
|
Back in September, we had
|
|
the [GNU Tools Cauldron](https://gcc.gnu.org/wiki/cauldron2019) in the
|
|
gorgeous city of Montréal (perhaps I should write a post specifically
|
|
about it...). One of the sessions we had was the **GDB BoF**, where
|
|
we discussed, among other things, how to improve our patch review
|
|
system.
|
|
|
|
I have my own personal opinions about the current review system we use
|
|
(mailing list-based, in a nutshell), and I haven't felt very confident
|
|
to express it during the discussion. Anyway, the outcome was that at
|
|
least 3 global maintainers have used or are currently using
|
|
the [Gerrit Code Review](https://www.gerritcodereview.com) system for
|
|
other projects, are happy with it, and that we should give it a try.
|
|
Then, when it was time to decide who wanted to configure and set
|
|
things up for the community, I volunteered. Hey, I'm already running
|
|
the Buildbot master for GDB, what is the problem to manage yet another
|
|
service? Oh, well.
|
|
|
|
Before we dive into the details involved in configuring and running
|
|
gerrit in a machine, let me first say that I don't totally support the
|
|
idea of migrating from mailing list to gerrit. I volunteered to set
|
|
things up because I felt the community (or at least the its most
|
|
active members) wanted to try it out. I don't necessarily agree with
|
|
the choice.
|
|
|
|
Ah, and I'm writing this post mostly because I want to be able to
|
|
close the 300+ tabs I had to open on my Firefox during these last
|
|
weeks, when I was searching how to solve the myriad of problems I
|
|
faced during the set up!
|
|
|
|
The initial plan
|
|
----------------
|
|
|
|
My very initial plan after I left the session room was to talk to
|
|
the [sourceware.org](https://sourceware.org) folks and ask them if it
|
|
would be possible to host our gerrit there. Surprisingly, they
|
|
already have a gerrit instance up and running. It's been set up back
|
|
in 2016, it's running an old version of gerrit, and is pretty much
|
|
abandoned. Actually, saying that it has been configured is an
|
|
overstatement: it doesn't support authentication, user registration,
|
|
barely supports projects, etc. It's basically what you get from a
|
|
pristine installation of the gerrit RPM package in RHEL 6.
|
|
|
|
I won't go into details here, but after some discussion it was clear
|
|
to me that the instance on sourceware would not be able to meet our
|
|
needs (or at least what I had in mind for us), and that it would be
|
|
really hard to bring it to the quality level I wanted. I decided to
|
|
go look for other options.
|
|
|
|
The OSCI folks
|
|
--------------
|
|
|
|
Have I mentioned the [OSCI project](https://osci.io/) before? They
|
|
are absolutely **awesome**. I really love working with them, because
|
|
so far they've been able to meet every request I made! So, kudos to
|
|
them! They're the folks that host
|
|
our [GDB Buildbot master](https://gdb-buildbot.osci.io). Their
|
|
infrastructure is quite reliable (I never had a single problem), and
|
|
Marc Dequénes (Duck) is very helpful, friendly and quick when replying
|
|
to my questions :-).
|
|
|
|
So, it shouldn't come as a surprise the fact that when I decided to
|
|
look for other another place to host gerrit, they were my first
|
|
choice. And again, they delivered :-).
|
|
|
|
Now, it was time to start thinking about the gerrit set up.
|
|
|
|
User registration?
|
|
------------------
|
|
|
|
Over the course of these past 4 weeks, I had the opportunity to learn
|
|
a bit more about how gerrit does things. One of the first things that
|
|
negatively impressed me was the fact that gerrit doesn't handle user
|
|
registration by itself. It is possible to have a very rudimentary
|
|
user registration "system", but it relies on the site administration
|
|
manually registering the users (via `htpasswd`) and managing
|
|
everything by him/herself.
|
|
|
|
It was quite obvious to me that we would need some kind of access
|
|
control (we're talking about a GNU project, with a copyright
|
|
assignment requirement in place, after all), and the best way to
|
|
implement it is by having registered users. And so my quest for the
|
|
best user registration system began...
|
|
|
|
Gerrit supports some user **authentication** schemes, such
|
|
as [OpenID](https://en.wikipedia.org/wiki/OpenID) (**not** OpenID
|
|
Connect!), [OAuth2](https://en.wikipedia.org/wiki/OAuth#OAuth_2.0)
|
|
(via plugin)
|
|
and
|
|
[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol).
|
|
I remembered hearing
|
|
about [FreeIPA](https://en.wikipedia.org/wiki/FreeIPA) a long time
|
|
ago, and thought it made sense using it. Unfortunately, the project's
|
|
community told me that installing FreeIPA on a Debian system is really
|
|
hard, and since our VM is running Debian, it quickly became obvious
|
|
that I should look somewhere else. I felt a bit sad at the beginning,
|
|
because I thought FreeIPA would really be our silver bullet here, but
|
|
then I noticed that it doesn't really offer a self-service user
|
|
registration.
|
|
|
|
After exchanging a few emails with Marc, he told me
|
|
about [Keycloak](https://en.wikipedia.org/wiki/Keycloak). It's a
|
|
full-fledged Identity Management and Access Management software,
|
|
supports OAuth2, LDAP, **and** provides a self-service user
|
|
registration system, which is exactly what we needed! However, upon
|
|
reading the description of the project, I noticed that it is written
|
|
in Java (JBOSS, to be more specific), and I was afraid that it was
|
|
going to be very demanding on our system (after all, gerrit is also a
|
|
Java program). So I decided to put it on hold and take a look at
|
|
using LDAP...
|
|
|
|
Oh, man. Where do I start? Actually, I think it's enough to say that
|
|
I just **tried**
|
|
installing [OpenLDAP](https://en.wikipedia.org/wiki/OpenLDAP), but
|
|
gave up because it was too cumbersome to configure. Have you ever
|
|
heard that LDAP is really complicated? I'm afraid this is true. I
|
|
just didn't feel like wasting a lot of time trying to understand how
|
|
it works, only to have to solve the "user registration" problem later
|
|
(because of course, OpenLDAP is just an LDAP server).
|
|
|
|
OK, so what now? Back to Keycloak it is. I decided that instead of
|
|
thinking that it was too big, I should actually install it and check
|
|
it for real. Best decision, by the way!
|
|
|
|
Setting up Keycloak
|
|
-------------------
|
|
|
|
It's pretty easy to set Keycloak up. The official website provides a
|
|
`.tar.gz` file which contains the whole directory tree for the
|
|
project, along with helper scripts, `.jar` files, configuration, etc.
|
|
From there, you just need to follow the documentation, edit the
|
|
configuration, and voilà.
|
|
|
|
For our specific setup I chose to use PostgreSQL instead of the
|
|
built-in database. This is a bit more complicated to configure,
|
|
because you need to download the JDBC driver, and install it in a
|
|
strange way (at least for me, who is used to just editing a
|
|
configuration file). I won't go into details on how to do this here,
|
|
because it's easy to find on the internet. Bear in mind, though, that
|
|
the official documentation is really incomplete when covering this
|
|
topic! [This](https://devopstales.github.io/sso/keycloak2/) is one of
|
|
the guides I used, along
|
|
with
|
|
[this other one](http://www.janua.fr/how-to-install-keycloak-with-mariadb/) (which
|
|
covers MariaDB, but can be adapted to PostgreSQL as well).
|
|
|
|
Another interesting thing to notice is that Keycloak expects to be
|
|
running on its own virtual domain, and not under a subdirectory (e.g,
|
|
`https://example.org` instead of `https://example.org/keycloak`). For
|
|
that reason, I chose to run our instance on another port. It is
|
|
supposedly possible to configure Keycloak to run under a subdirectory,
|
|
but it involves editing a lot of files, and I confess I couldn't make
|
|
it fully work.
|
|
|
|
A last thing worth mentioning: the official documentation says that
|
|
Keycloak needs Java 8 to run, but I've been using OpenJDK 11 without
|
|
problems so far.
|
|
|
|
Setting up Gerrit
|
|
-----------------
|
|
|
|
The fun begins now!
|
|
|
|
The gerrit project also offers a `.war` file ready to be deployed.
|
|
After you download it, you can execute it and initialize a gerrit
|
|
project (or application, as it's called). Gerrit will create a
|
|
directory full of interesting stuff; the most important for us is the
|
|
`etc/` subdirectory, which contains all of the configuration files for
|
|
the application.
|
|
|
|
After initializing everything, you can try starting gerrit to see if
|
|
it works. This is where I had my first trouble. Gerrit also requires
|
|
Java 8, but unlike Keycloak, it doesn't work out of the box with
|
|
OpenJDK 11. I had to make a small but important addition in the file
|
|
`etc/gerrit.config`:
|
|
|
|
[container]
|
|
...
|
|
javaOptions = "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED"
|
|
...
|
|
|
|
After that, I was able to start gerrit. And then I started trying to
|
|
set it up for OAuth2 authentication using Keycloak. This took a
|
|
**very long** time, unfortunately. I was having several problems with
|
|
Gerrit, and I wasn't sure how to solve them. I
|
|
tried
|
|
[asking for help](https://groups.google.com/forum/#!topic/repo-discuss/_n5Y2vDppX8) on
|
|
the official mailing list, and was able to make some progress, but in
|
|
the end I figured out what was missing: I had forgotten to add the
|
|
`AddEncodedSlashes On` in the Apache configuration file! This was
|
|
causing a very strange error on Gerrit (as you can see, a
|
|
`java.lang.StringIndexOutOfBoundsException`!), which didn't make
|
|
sense. In the end, my Apache config file looks like this:
|
|
|
|
<VirtualHost *:80>
|
|
ServerName gnutoolchain-gerrit.osci.io
|
|
|
|
RedirectPermanent / https://gnutoolchain-gerrit.osci.io/r/
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:443>
|
|
ServerName gnutoolchain-gerrit.osci.io
|
|
|
|
RedirectPermanent / /r/
|
|
|
|
SSLEngine On
|
|
SSLCertificateFile /path/to/cert.pem
|
|
SSLCertificateKeyFile /path/to/privkey.pem
|
|
SSLCertificateChainFile /path/to/chain.pem
|
|
|
|
# Good practices for SSL
|
|
# taken from: <https://mozilla.github.io/server-side-tls/ssl-config-generator/>
|
|
|
|
# intermediate configuration, tweak to your needs
|
|
SSLProtocol all -SSLv3
|
|
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
|
SSLHonorCipherOrder on
|
|
SSLCompression off
|
|
SSLSessionTickets off
|
|
|
|
# OCSP Stapling, only in httpd 2.3.3 and later
|
|
#SSLUseStapling on
|
|
#SSLStaplingResponderTimeout 5
|
|
#SSLStaplingReturnResponderErrors off
|
|
#SSLStaplingCache shmcb:/var/run/ocsp(128000)
|
|
|
|
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
|
|
Header always set Strict-Transport-Security "max-age=15768000"
|
|
|
|
ProxyRequests Off
|
|
ProxyVia Off
|
|
ProxyPreserveHost On
|
|
<Proxy *>
|
|
Require all granted
|
|
</Proxy>
|
|
|
|
AllowEncodedSlashes On
|
|
ProxyPass /r/ http://127.0.0.1:8081/ nocanon
|
|
#ProxyPassReverse /r/ http://127.0.0.1:8081/r/
|
|
</VirtualHost>
|
|
|
|
I confess I was almost giving up Keycloak when I finally found
|
|
the problem...
|
|
|
|
Anyway, after that things went more smoothly. I was finally able to
|
|
make the user authentication work, then I made sure Keycloak's user
|
|
registration feature also worked OK...
|
|
|
|
Ah, one interesting thing: the user logout wasn't really working as
|
|
expected. The user was able to logout from gerrit, but not from
|
|
Keycloak, so when the user clicked on "Sign in", Keycloak would tell
|
|
gerrit that the user was already logged in, and gerrit would
|
|
automatically log the user in again! I was able to solve this by
|
|
redirecting the user to Keycloak's logout page, like this:
|
|
|
|
[auth]
|
|
...
|
|
logoutUrl = https://keycloak-url:port/auth/realms/REALM/protocol/openid-connect/logout?redirect_uri=https://gerrit-url/
|
|
...
|
|
|
|
After that, it was already possible to start worrying about configure
|
|
gerrit itself. I don't know if I'll write a post about that, but let
|
|
me know if you want me to.
|
|
|
|
Conclusion
|
|
----------
|
|
|
|
If you ask me if I'm totally comfortable with the way things are set
|
|
up now, I can't say that I am 100%. I mean, the set up seems robust
|
|
enough that it won't cause problems in the long run, but what bothers
|
|
me is the fact that I'm using technologies that are alien to me. I'm
|
|
used to setting up things written in Python, C, C++, with very simple
|
|
yet powerful configuration mechanisms, and an easy to discover what's
|
|
wrong when something bad happens.
|
|
|
|
I am reasonably satisfied with the Keycloak logs things, but Gerrit
|
|
leaves a lot to be desired in that area. And both projects are
|
|
written in languages/frameworks that I am absolutely not comfortable
|
|
with. Like, it's really tough to debug something when you don't even
|
|
know where the code is or how to modify it!
|
|
|
|
All in all, I'm happy that this whole adventure has come to an end,
|
|
and now all that's left is to maintain it. I hope that the GDB
|
|
community can make good use of this new service, and I hope that we
|
|
can see a positive impact in the quality of the whole patch review
|
|
process.
|
|
|
|
My final take is that this is all worth as long as the Free Software
|
|
and the User Freedom are the ones who benefit.
|
|
|
|
P.S.: Before I forget, our gerrit instance is running
|
|
at
|
|
[https://gnutoolchain-gerrit.osci.io](https://gnutoolchain-gerrit.osci.io).
|