Mattermost, Inc.

Active Directory SSO through a reverse proxy's REMOTE_USER

tl;dr: I’m trying to get Mattermost to trust the reverse proxy’s REMOTE_USER setting for authentication

The idea here would be to use the reverse proxy’s modules for authentication. I’ve seen the LDAP/SSO feedback request, but this approach is different in that Mattermost would not have to duplicate the security logic.

I’ve gotten so far as to get Active Directory SSO to work with Apache2’s libapache2-mod-auth-kerb. At this point Mattermost could just trust the REMOTE_USER header, since it’s guaranteed to be set and purified by Apache2. Chrome and IE are operational, out of the box, Firefox users have to hop through a few loops.

I’ve gotten a very similar setup to work with other web applications, e.g., phpBB, graphite, etc, but I’m unsure on how to proceed with Mattermost’s Erlang + Go. Any ideas?

The prerequisites are a working Kerberos authentication so that kinit and klist work. I’m using Ubuntu 14.04(.3 LTS). Here are the relevant snippets to duplicate my setup:

sudo apt-get install apache2 gnutls-bin msktutil libapache2-mod-auth-kerb

kinit
klist
cd && msktutil --create --base OU=Testlab --service HTTP --keytab http_mmost01.krb5keytab --computer-name mmost01 --upn HTTP/mmost01.foo.bar
sudo chown www-data:www-data http_mmost01.krb5keytab
sudo chmod 0600 http_mmost01.krb5keytab
sudo cp http_mmost01.krb5tab /etc/apache2/

sudo a2enmod proxy_wstunnel proxy proxy_http ssl

/etc/apache2/sites-enabled$ cat 001-mattermost-ssl.conf
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
            ServerAdmin admin@foo.bar
            DocumentRoot /var/www/html
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined

            SSLEngine on
            SSLCertificateFile      /etc/apache2/ssl/cert.pem
            SSLCertificateKeyFile /etc/apache2/ssl/key.pem

            ProxyRequests Off
            ProxyPreserveHost On
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options
            Header always append X-Frame-Options SAMEORIGIN


            <Location "/">
                    AuthType Kerberos
                    KrbAuthRealms FOO.BAR
                    Krb5Keytab /etc/apache2/http_mmost01.krb5keytab
                    KrbMethodNegotiate On
                    KrbMethodK5Passwd Off  # set to On for Firefox
                    KrbLocalUserMapping On
                    require valid-user
		# http://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
                    ProxyPass ws://localhost:8065/ retry=0
            </Location>
    </VirtualHost>

Oh right, as Inspector Colombo often remarked, One More Thing:

With the reverse proxy REMOTE_USER probably has to be saved into a separate request header, so add something like

RequestHeader set X-Forwarded-User %{REMOTE_USER}s

into the Location block, and then use X-Forwarded-User in Mattermost.

Interesting idea. This would require a bunch of code changes. First you would need your instance to be a single team only, basically toggling the AllowTeamCreation to false after you created one team. The reason is a user is only unique within a team (think Slack SAAS model). If your proxy sets the header “X-Forward-User” you could do something similar to https://github.com/mattermost/platform/blob/master/api/context.go#L87 and https://github.com/mattermost/platform/blob/master/api/context.go#L125, but instead lookup the user and “fake” a session object since mattermost trusts the proxy. You would also probably need the ability to turn on/off from the admin console.

I would love to know if you have managed to have any progress on this. I think it would work well for my use case. It would also be great if one could also pass to Mattermost a header like X-Forwarded-Team to inform MM as to which team the user is a member.

I disagree. The quasi-standard REMOTE_USER which is supported by a lot of applications identifies a login. Don’t think of it to be something like the username inside a team: think of it as something equal to email+password. Just do not ask for username+password any more when REMOTE_USER is set.

username and REMOTE_USER could be different.

I did some research and I created a fork using this idea: https://github.com/mmuszkow/platform
It’s just a proof-of-concept, but clearly shows that this is possible. We are using apache + mod_auth_mellon to inject the headers, the configuration looks as follow: https://github.com/mmuszkow/platform/tree/master/httpd-conf
We are using similar setup (mellon, shibboleth in the past) for many of our services. Do you think that such change (when polished) has any chances of reaching the master branch?

We discussed the change internally and it would be difficult to nominate this for APR given the testing complexity and recurring cost.

It’s a really interesting approach, just not in scope for master.

We would like to integrate Mattermost into a SSO setup with Apache, Django and a couple of other tools that all authenticate by trusting REMOTE_USER.

We therefore also need the feature discussed in this topic. Does anybody find a solution or workaround that can be used in production?

Thanks and best regards,
on

1 Like