Crivaledaz / Mattermost-LDAP

This module provides an external LDAP authentication in Mattermost for the Team Edition (free).
MIT License
357 stars 71 forks source link

Missing Configurations table #95

Closed gottobre closed 1 year ago

gottobre commented 1 year ago

Hi, I just noticed that my Mattermost database (mysql) is missing the Configurations table. I'm running Mattermost 6.5.0 and until now I had no issues using my instance; also, i've been using Gitlab Authentication with no problems at all. But now, how can I fix the URLs as described in your guide if i miss that table? At this moment, if I click on the Gitlab button I'm redirected to http://mysite/oauth/access_token with error "The requested URL was not found on this server". Could it be related to my missing table? Unfortunately, changing URLs in GitlabSettings section of my config.json file didn't solve my issue. I would really appreciate your help, thanks and have a good day

Crivaledaz commented 1 year ago

Hi,

Are you talking about the Mattermost DB or the Oauth/Mattermost-LDAP DB ?

For Mattermost, it depends on your settings. The configuration could be stored in database if enabled, or it will only be kept on the config.json file. You can refer to my answers in #84 for more information about this.

If you are talking about the Oauth database, if you have a bare-metal installation, you need to run the db_init/init_mysql.sh script, which should create the Oauth table for you. Adapt parameters to fit your environment by copying the db_init/config_init.sh.example file to db_init/config_init.sh, before to run it. If you use the container deployment, it should be done automatically during starting time.

If Oauth database and tables already exist, you can change the redirect_url with the following SQL command, as described in the documentation :

UPDATE oauth_clients SET redirect_uri = 'https://mattermost.company.com/signup/gitlab/complete' WHERE client_id = '1234567890';

Besides, regarding your issue, it seems your Oauth server is not reachable, and that is why you get the error : The requested URL was not found on this server. Maybe your request is not redirected as expected, or the web server is down, or your request is blocked by a security policy ... Which HTTP server do you use (httpd/Apache or Nginx) ? Have you configured the redirection ?

Normally, when you click on the GitLab button you should be redirected to http://<your domain>/oauth/authorize.php then, if you are not already logged, you are redirected to http://<your domain>/oauth/index.php in order to authenticate. Since you are redirected on the access_token page, verify you have not reversed some GitLab URLs in the Mattermost configuration.

Can you check if you can browse the Oauth login page, independently of Mattermost ? For that, go to http://<your domain>/oauth/index.php. You should have a login form, and if you Oauth is well configured, try to connect with your LDAP credentials, you should access to a page which confirms the authentication as succeeded.

I hope these elements give you some points to debug your installation. Let me know.

Regards,

gottobre commented 1 year ago

Hi and thanks for your quick reply, I'm referring to the Mattermost DB. I checked your answers in #84 and now I understood that I'm missing that table just because I have a bare metal installation. I suppose I had no problem with the db_init/init_mysql.sh part because the output of the script was fine as you can see from the following output: MariaDB [oauth_db]> select * from oauth_clients; +------------------------------------------------------------------+------------------------------------------------------------------+-----------------------------------------------------+--------------------+-------+---------+ | client_id | client_secret | redirect_uri | grant_types | scope | user_id | +------------------------------------------------------------------+------------------------------------------------------------------+-----------------------------------------------------+--------------------+-------+---------+ | 0d9984fe77fb17e5a217e095e98c5e2ca3418037ca891303afdc405bd0293ec5 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | https://my_mattermost_server_url/signup/gitlab/complete | authorization_code | api | | +------------------------------------------------------------------+------------------------------------------------------------------+-----------------------------------------------------+--------------------+-------+---------+

I didn't apply the UPDATE oauth_clients SET redirect_uri just because redirect_uri was already ok in my opinion (let me know if I'm wrong). Before moving forward, I think it could be useful to share some informations about the infrastructure I'm working on: I have a bare-metal Mattermost server installation with Nginx on a separate vm, a mysql instance on another vm and a Haproxy vm. I'm using an external Gitlab server to authenticate which was working fine. I'm using Debian in all of them. In order to implement LDAP authentication, I created a separate Mattermost-LDAP (Debian) with Apache/2.4.38 , php5.6 (mod_php) and mysql Ver 15.1 Distrib 10.3.34-MariaDB . About the main issue I'm experiencing, the network seems to work fine since I'm able to telnet from my Mattermost server to my Mattermost-LDAP server port 80, and from my Mattermost-LDAP server to my external LDAP server port 636. The Mattermos-LDAP server is up and running and I also tested that php is working by phpinfo() . However, after reading your response I suppose I could have missed some Apache configuration; what kind of redirection should I configure? About possibly reversed Gitlab URLs, this is how my GitlabSetting section looks like in my config.json of my Mattermost server: "GitLabSettings": { "Enable": true, "Secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Id": "0d9984fe77fb17e5a217e095e98c5e2ca3418037ca891303afdc405bd0293ec5", "Scope": "api", "AuthEndpoint": "http://my_mattermost-ldap_server/oauth/authorize.php", "TokenEndpoint": "http://my_mattermost-ldap_server/oauth/token.php", "UserAPIEndpoint": "http://my_mattermost-ldap_server/oauth/resource.php", "DiscoveryEndpoint": "", "ButtonText": "", "ButtonColor": ""

I confirm I can browse http://my_mattermost-ldap_server/oauth/index.php but I'm getting "Authentication failed ... Check your username and password. If the error persists contact your administrator." This could be probably related to a bad oauth/LDAP/config_ldap.php configuration that i have to adjust. For now, just getting rid of that "the requested url was not found on this server" would be nice. Thanks for your time. Regards,

Crivaledaz commented 1 year ago

Hi,

The Oauth database seems good, except the redirect_uri is an HTTPS url and your Oauth server seems to use HTTP. It is not the problem for now but it may be your next problem. You can use HTTPS (and it is recommended), but you need to configure Apache accordingly. For more details about the redirect URL and how Mattermost build it, please read my answers in #30.

The GitlabSettings in Mattermost configuration are correct. So when you click on the GitLab button on Mattermost login page, you should be redirected to http://my_mattermost-ldap_server/oauth/authorize.php. Then if you are not already authenticated on Mattermost LDAP, you will be redirected to http://my_mattermost-ldap_server/oauth/index.php, where you have to enter your LDAP credentials to continue.

So it is strange you end on http://mysite/oauth/access_token since this URL is not involved in the authentication process on the client side. The process sequence is described on the picture below, where GitLab is replaced by Mattermost-LDAP :

Authentication Sequence

So, you need to find out why you are reaching the http://mysite/oauth/access_token instead of http://my_mattermost-ldap_server/oauth/authorize.php. Maybe you have some redirection somewhere on the NGINX server or Apache server. The error you get is normal since there is nothing on oauth/access_token. Try to trace the redirection process by looking in your web browser developer tools, or with Wireshark. You can look at the issue #33 for more information.

I am not confident with Apache configuration, but you can look at the Nginx configuration available here and adapt it. Else, I recommend to you to switch from Apache to Nginx, since you already are using Nginx on the Mattermost server. I think the use of 3 different web server (HAProxy, NGINX and Apache) can be complicated to managed, personally I prefer to homogenize the tool.

Concerning the Authentication failed error on the Oauth server, it's certainly because the LDAP configuration is wrong. You can use the ldap.php php script to debug it. Just adapt the parameters in the header and browse the file directly. Since your LDAP server is listening on port 636, I suppose you are using LDAPS, then you need to check that the hostname in parameters matches the 'CN' in the LDAP's SSL certificate.

Hope this will help you,

Regards

gottobre commented 1 year ago

Hi,
I took your advice and replaced apache with nginx, and I also simplified my environment a bit in order to avoid conflicts as much as possible. So now i have:

This is my /etc/nginx/sites-enabled/mattermost.conf:

upstream backend {
   server 127.0.0.1:8065;
   keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
  listen 80 default_server;
  server_name   my_mattermost_server_name;
  root         /var/www/html;
  index index.php index.html index.htm;

  error_page 404 /404.html;
      location = /40x.html {
  } 

  error_page 500 502 503 504 /50x.html;
      location = /50x.html {
  }

  location /oauth/access_token {
    try_files $uri  /oauth/index.php;
  }

  location /oauth/authorize {
    try_files $uri /oauth/authorize.php$is_args$args;
  }

  location ~ /oauth/.*\.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }

   location ~ /api/v[0-9]+/(users/)?websocket$ {
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       client_max_body_size 50M;
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       client_body_timeout 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 90;
       proxy_send_timeout 300;
       proxy_read_timeout 90s;
       proxy_http_version 1.1;
       proxy_pass http://backend;
   }

   location / {
       client_max_body_size 50M;
       proxy_set_header X-Forwarded-Proto https;
       proxy_set_header X-Forwarded-Ssl on;
       proxy_set_header Connection "";
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       proxy_read_timeout 600s;
       proxy_cache mattermost_cache;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass http://backend;
   }
 }

These are GitlabSettings in config.json:

"GitLabSettings": {
    "Enable": true,
    "Secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Id": "0d9984fe77fb17e5a217e095e98c5e2ca3418037ca891303afdc405bd0293ec5",
    "Scope": "api",
    "AuthEndpoint": "https://my_mattermost_server_name/oauth/authorize.php",
    "TokenEndpoint": "https://my_mattermost_server_name/oauth/token.php",
    "UserAPIEndpoint": "https://my_mattermost_server_name/oauth/resource.php",
    "DiscoveryEndpoint": "",
    "ButtonText": "",
    "ButtonColor": ""

This is my /var/www/html/oauth/config_db.php (password is different from default but matches with the one belonging to oauth user in the mysql server):

<?php

$db_port      = intval(getenv('db_port')) ?: 3306;
$db_host      = getenv('db_host') ?: "10.17.11.23";
$db_name      = getenv('db_name') ?: "oauth_db";
$db_type      = getenv('db_type') ?: "mysql";
$db_user      = getenv('db_user') ?: "oauth";
$db_pass      = getenv('db_pass') ?: "oauth-secure_pass";
$dsn          = $db_type . ":dbname=" . $db_name . ";host=" . $db_host . ";port=" . $db_port;

/* Uncomment the line below to set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php)
 * If date.timezone is not defined in php.ini or with this function, Mattermost could return a bad token request error
*/
//date_default_timezone_set ('Europe/Paris');

This is /var/www/html/oauth/LDAP/config_ldap.php:

<?php
// LDAP parameters
$ldap_host = getenv('ldap_host') ?: "ldaps://10.10.10.12";
$ldap_port = intval(getenv('ldap_port')) ?: 636;
$ldap_version = intval(getenv('ldap_version')) ?: 2;
$ldap_start_tls = boolval(getenv('ldap_start_tls')) ?: false;

// Attribute use to identify user on LDAP - ex : uid, mail, sAMAccountName
$ldap_search_attribute = getenv('ldap_search_attribute') ?: "uid";

// variable use in resource.php
$ldap_base_dn = getenv('ldap_base_dn') ?: "dc=ns,dc=farm";
$ldap_filter = getenv('ldap_filter') ?: "(objectClass=*)";

// ldap service user to allow search in ldap
$ldap_bind_dn = getenv('ldap_bind_dn') ?: "";
$ldap_bind_pass = getenv('ldap_bind_pass') ?: "";

This is oauth_clients table on the mysql server:

select * from oauth_clients; 
| client_id | client_secret | redirect_uri | grant_types | scope | user_id | 
| 0d9984fe77fb17e5a217e095e98c5e2ca3418037ca891303afdc405bd0293ec5 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | https://my_mattermost_server_name/signup/gitlab/complete | authorization_code | api | no | 

So, when I click on the gitlab button I'm still redirected to https://my_mattermost_server_name/oauth/access_token . This is what i see from developer tools network tab:

name: login  status: 302  type: document / Redirect  Initiator: Other 
authorize.php?response_type=code&client_id=...  302  document / Redirect  gitlab/login 
access_token    200   document  authorize.php response_type=... 

Before installing php7.4-xml, access_token page was a 500 error "nginx can't fulfill the request at the moment"; after installing it, I see the ldap form page. Browsing https://my_mattermost_server_name/oauth/index.php directly, leads to the same ldap form page. LDAP Authentication is not currently working even if the values in config_ldap.php should be right. I also tried to insert my ldap user and pass in ldap_bind_dn and ldap_bind_pass but still no luck. This is nginx log I'm getting when i try to log in:

2022/09/23 15:36:07 [error] 168661#168661: *384 FastCGI sent in stderr: "PHP message: PHP Warning: ldap_search(): Search: Can't contact LDAP server in /var/www/html/oauth/LDAP/LDAP.php on line 118" while reading response header from upstream, client: 10.17.11.29, server: my_mattermost_server_name, request: "POST /oauth/index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "my_mattermost_server_name", referrer: "https://my_mattermost_server_name/oauth/access_token" 

Even if oauth/access_token somehow leads me to the ldap login page, of course I'd like to get there in the correct way. I'm almost sure my nginx configuration is wrong, do you have any idea about it? Thank you very much, have a good continuation

Crivaledaz commented 1 year ago

Hi,

You are now redirected to oauth/index.php page because in your Nginx configuration you have the following redirection block :

  location /oauth/access_token {
    try_files $uri  /oauth/index.php;
  }

So when your browser try to reach /oauth/access_token, Nginx redirect it to /oauth/index.php.

I made some test on my side, and contrary to what I said previously, it is normal Mattermost LDAP is redirecting you to oauth/access_token. I forgot I added this redirection to workaround the security of the Mattermost client desktop application. In fact, the desktop client has filters to restrict URLs which can be reached, as explained in #80.

So I think your Nginx configuration is good, I just have a doubt about the TLS configuration, but will see if we get an error about it later.

Now you need to solve the LDAP issue in order to complete the authentication process. So when you click on the GitLab button you are know redirected to the authentication form, then when you enter your credential and accept Mattermost LDAP to send your data to Mattermost, you should be redirected on Mattermost and hopefully logged in.

The error you get in PHP logs appears because the LDAP search request failed. Check the LDAP server is reachable from your VM. Else, it is possible you LDAP server cannot be searched anonymously and you have to configure the bind account in LDAP parameters.

Hope this will help you, let me know,

Regards

gottobre commented 1 year ago

Hi, I can finally use Mattermost-LDAP with no issues. Ldap auth was failing due to a certificate issue, I resolved with "TLS_REQCERT never" in /etc/openldap/ldap.conf file on the ldap server (I might as well have put the certificate into the Mattermost/Mattermost-LDAP vm i guess). Then, I went through "Token request failed" after typing ldap credentials in the form page, the mattermost log was:

{"timestamp":"2022-09-27 15:40:29.749 Z","level":"error","msg":"Token request failed.","caller":"web/context.go:105","path":"/signup/gitlab/complete","request_id":"xxxxxxxxxxxxxxxx","ip_addr":"127.0.0.1","user_id":"","method":"GET","err_where":"AuthorizeOAuthUser","http_code":500,"err_details":"Post \"https://my_mattermost_server_name/oauth/token.php\": dial tcp mattermost_public_ip:443: i/o timeout"}

I resolved this timeout problem by binding my_mattermost_server_name to the VIP of my Haproxy in /etc/hosts file of the Mattermost/Mattermost-LDAP vm. After that, i had no other issues. Of course I lost all my private channels, but i was able to restore them by changing the UserId in the ChannelMembers table of the mattermost database, replacing the old Gitlab Id with the new one belonging to the ldap user. Many thanks for all your help! Have a good continuation

Crivaledaz commented 1 year ago

Hi,

Thank you for your feedback. I am glad you manage to get a working Mattermost-LDAP.

I am not surprised for the LDAP certificate issue, and even if your patch is working, it disables certificate checking for all connections including other clients, which could lead to security issue. A better way would have been to add the client certificate to the trusted certificates in the LDAP server.

To associate previous account from GitLab with Mattermost-LDAP, I think the best way is to synchronize the users table in Mattermost-LDAP database by updating the id column with id from GitLab userId. This avoids altering the Mattermost database. However, editing Mattermost database work well too.

I closed this issue since you have a working Mattermost-LDAP instance, feel free to open a new issue if needed.

Regards