Saturday, September 25, 2021

Setting Up Apache for Federated Identity

I was loading my environmental data up on a web server through Grafana.  I'd been running LDAP-based authentication for years, and wanted to be able to shut that service down because I was growing weary of updating SSL certificates.  I had Grafana running on it's own TCP port inside, but I desired to expose it (while protecting the data).  I finally broke down and did it.

I started out with two "tutorials" :

Both of these were lacking in information.  For example, there are no instructions on setting up the Google API, and there was a configuration option of "OIDCCryptoPassphrase" that was a variable and no one explained what it needed to be set to.  But, I wanted to get it done.

First, I went through Google.  I'd not set up google cloud for my domain before, so this was new.  First, log in to the https://console.cloud.google.com/apis/dashboard?pli=1 (it's the cloud platform).  Once in there, if you don't have a project already, create one.  This is done using the drop down at the top :

Click on "New Project" in the upper right hand corner :

Now, you can create a credential.  Click on "Credentials" on the left, and then "Create Credential" at the top :

 

Follow the set up guide.  The type will be what you need, in my case, I was doing Apache's HTTPd server, so I went with "Web Application".  The redirect URI setting must match what you use for your OAuth configuration (in the configuration file, actually).  Make sure you have your domains listed, etc.


At this point, copy the ID as well as the client secret.  These need to go into your configuration file for Apache's HTTPd.

You might need to create an "OAuth Consent Screen", too.  Those three configurations in Google are all you need.

Load up your editor you use to change the HTTPd configuration.  The basic lines you are going to need are :

    OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
    OIDCClientID CLIENT_ID_FROM_CONFIGURATION
    OIDCClientSecret CLIENT_SECRET_FROM_CONFIGURATION

    # OIDCRedirectURI is a vanity URL, and should not point to any actual content
    OIDCRedirectURI http://hostname.example.com/grafana/redirect_uri
    OIDCCryptoPassphrase PERSONALLY_CHOSEN_PASSPHRASE
    OIDCScope "openid email profile"
    OIDCRemoteUserClaim email

    <Location /grafana/>
        TemplateEnabled off
        AuthType openid-connect
        <RequireAny>
            # not just anyone signed in from google
            # Require valid-user

            # network
            Require ip 10.0.0.

            # signed in with domain
            Require claim hd:silverhawk.net

            # or, signed in with domain (e-mail fall through)
            Require claim "email~^(.*)@silverhawk.net$"

            # or Someone External
            Require claim "email~^username@gmail.com$"
        </RequireAny>

        ProxyPass http://localhost:3000/
        ProxyPassReverse http://localhost:3000/
        Order allow,deny
        Allow from all

        # grafana requires the username to be in a header
        RewriteEngine On
        RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER},NS]
        RequestHeader set X-WEBAUTH-USER "%{PROXY_USER}e"
    </Location>

The OIDCClientID and the OIDCClientSecret configuration items are where you stuff the respective items from your OAuth configuration we copied above.  The OIDCCryptoPassphrase is where I was getting lost - this is going to be something you choose, and is specific to the cluster (e.g. so that the cluster can keep state if you hit other servers).

I used a RequireAny to set up multiple options - so, if you are on the local network and sign in to google, you'll get in.  If your primary google address is a silverhawk.net domain, you can get in.  If your e-mail address is username@gmail.com, you can get in.

The rewrite directives are there specifically for Grafana so that Grafana can see the remote_user as the e-mail of the individual who just authenticated.  In your grafana.ini, locate your root_url, and make sure we've added the URI piece we are proxying, e.g. :

    root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/

Next, locate your "[users]" section, and set the following :

    allow_sign_up = false
    auto_assign_org = true

Next, locate the auth.proxy in your Grafana configuration.  Since we are rolling through HTTPd and it will be doing the authentication, we can let Grafana accept whatever HTTPd feeds to us.

    [auth.proxy]
    enabled = true
    header_name = X-WEBAUTH-USER
    header_property = username
    auto_sign_up = true

The header name should match what was in our rewrite rule, and the header property is the username that is going to get set up.  auto_sign_up needs to be set to true so that we can create accounts on the fly.

Now, restart any processes and give it a test!

No comments:

Post a Comment