From 04f46615ffde82bbf28b74643c58b70a43b88c31 Mon Sep 17 00:00:00 2001 From: Denis CLAVIER Date: Fri, 10 Dec 2021 18:57:03 +0100 Subject: [PATCH] Migrate from Apache to Nginx - Add HTTPS support - fix #80 --- .gitignore | 2 + Container.md | 123 ++++++++++--------------------- Docker/mattermostldap/Dockerfile | 26 ------- README.md | 6 +- docker-compose.yaml | 75 ++++++++++--------- env.example | 88 ---------------------- oauth.conf | 46 ++++++++++++ 7 files changed, 130 insertions(+), 236 deletions(-) delete mode 100644 Docker/mattermostldap/Dockerfile delete mode 100644 env.example create mode 100644 oauth.conf diff --git a/.gitignore b/.gitignore index 86e46b4..ef624d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ config_init.sh config_ldap.php config_db.php +data +certs diff --git a/Container.md b/Container.md index 4a41f19..b16584e 100644 --- a/Container.md +++ b/Container.md @@ -3,9 +3,9 @@ Install using containers - Docker/Podman The easiest way to setup Mattermost-LDAP is using the docker-compose implementation. -For production use, you must use the `docker-copose.yaml` file available at the root of this repository. Unlike the Demo, this docker-compose file only setup Mattermost-LDAP with an Apache server and a PostgreSQL database. +For production use, you must use the [`docker-compose.yaml`](https://github.com/Crivaledaz/Mattermost-LDAP/blob/master/docker-compose.yaml) file available at the root of this repository. Unlike the Demo, this docker-compose file only setup Mattermost-LDAP with an Nginx server linked to a PHP engine and a PostgreSQL database. -This implementation uses an embedded Oauth server, which can be configured by environment variables. +This implementation uses the repository Oauth server, which can be configured by environment variables. ## Requirements @@ -17,42 +17,33 @@ For more information about Podman installation, see official documentation : htt ## Preparation -First, you need to clone (or download and extract) this repository on your server : +First, you need to clone (or download and extract) this repository on your server with: ```bash git clone https://github.com/Crivaledaz/Mattermost-LDAP cd Mattermost-LDAP ``` -Then, before running the docker-compose file, you need to adapt LDAP and DB parameters. All parameters are gathered in the `env.example` file and they are passed to Postgres and Oauth server by environment variables. +Then, before running the docker-compose file, you need to adapt LDAP and DB parameters. All parameters are gathered in `environment` sections in the [`docker-compose.yaml`](https://github.com/Crivaledaz/Mattermost-LDAP/blob/master/docker-compose.yaml) file and they are passed to Postgres and Oauth server by environment variables. -Copy the `env.example` file to `.env` and edit it to change with your values. +You must edit the docker-compose file to adapt parameters with your values. **Warning** : Postgres root password and database Oauth password must be changed. Client and secret tokens must be generated randomly, using `openssl rand -hex 32`. For more information about available parameters, refer to the [configuration section](https://github.com/Crivaledaz/Mattermost-LDAP#configuration) of the repository README. Otherwise, for production, you need to create a directory to store PostgreSQL data. This directory will contain the Oauth database and allows data persistence, even if containers are stopped or restarted. By default, this Mattermost-LDAP implementation uses folder `data/` next to the `docker-compose.yaml` file to store data. This folder need to be created before running Docker compose : + ```bash mkdir data ``` -To use Mattermost-LDAP with your own Mattermost server, you need to configure your Mattermost instance as described in section "Configure Mattermost". +To use Mattermost-LDAP with your own Mattermost server, you need to configure your Mattermost instance as described in section "Configure Mattermost" below. ## Configure Mattermost -Active Gitlab authentication in `System Console > Gitlab` (or `config.json`) and fill application id and secret with the two tokens got during install section. For the next fields use this : - -``` -User API Endpoint : http://HOSTNAME/oauth/resource.php -Auth Endpoint: http://HOSTNAME/oauth/authorize.php -Token Endpoint: http://HOSTNAME/oauth/token.php -``` - -Change `HOSTNAME` by hostname or ip of the server where you have installed Mattermost-LDAP module. - -Since Mattermost 4.9, these fields are disabled in admin panel, so you need to edit directly section `GitLabSettings` in the Mattermost configuration file `config.json`. +Active Gitlab authentication in Mattermost configuration and fill GitLab parameters, with your values. To do this, you need to edit the `config.json` file or change parameters in Mattermost configuration table if you use configuration in the database. -In the `config.json` file, GitLab configuration is gathered in the section `GitLabSettings`. You have to enable it and to fill parameters with your values. Once completed, the section should look like : +In the `config.json` file, GitLab configuration is gathered in the section `GitLabSettings`. Adapt this section with your values, it should seems like this : ``` "GitLabSettings": { @@ -60,94 +51,54 @@ In the `config.json` file, GitLab configuration is gathered in the section `GitL "Secret": "fedcba987654321fedcba987654321", "Id": "123456789abcdef123456789abcdef", "Scope": "", - "AuthEndpoint": "http://localhost/oauth/authorize.php", - "TokenEndpoint": "http://localhost/oauth/token.php", - "UserApiEndpoint": "http://localhost/oauth/resource.php" + "AuthEndpoint": "https:///oauth/authorize.php", + "TokenEndpoint": "https:///oauth/token.php", + "UserApiEndpoint": "https:///oauth/resource.php" }, ``` -*Note* : You need to restart the Mattermost server to take into account the change. +Change `` by the hostname or ip of the server where you have installed Mattermost-LDAP module. The `Secret` and `Id` parameters should contain the tokens generated previously. -## Usage - -Once the `.env` file have been adapted, you can run the docker-compose file with the following commands : -```bash -# With Docker -docker-compose build -docker-compose up -d +**Note** : You need to restart the Mattermost server to take into account the change. -# With Podman -podman-compose build -podman-compose up -d -``` +## HTTPS configuration -The build command allows Docker compose to build necessary image. Images use are available in the [Docker/](Docker) directory of this repository. The up command starts all services described in the Docker compose file. +Since Mattermost-LDAP version 2.1, HTTPS is enable by default to protect sensitive data exchanged between users and Mattermost-LDAP (LDAP username and password). -Once all services are started, go to Mattermost server and click on GitLab button to login with LDAP credential on Mattermost-LDAP. Then, if you login successfully and authorize Mattermost-LDAP to transmit your data to Mattermost, you should be log on Mattermost. +You need to provide a pair of TLS certificates and to store these in a directory named `certs`. To generate self-signed certificates you can use the following command : -To stop Mattermost server and Mattermost-LDAP, use the following command : ```bash -# With Docker -docker-compose down - -# With Podman -podman-compose down +mkdir certs +openssl req -x509 -newkey rsa:4096 -sha256 -days 364 -nodes -keyout certs/key.pem -out certs/cert.pem -subj '/CN=' -extensions san -config <( echo '[req]'; echo 'distinguished_name=req'; echo '[san]'; echo 'subjectAltName=DNS:localhost,') ``` -## Extension - -### Additional information for usage with nginx-proxy, nginx-proxy-letsencrypt - -In case you want to use `nginx-proxy`, `nginx-proxy-letsencrypt`, and (for example) `openldap`, it is possible to use subdomains for your services. Following this approach you could have mattermost running on on `https://chat.example.com` and authenticate via this container from `https://oauth.example.com`. This container will then have its own letsencypt certificate. +Replace `` by the hostname serving the Oauth server (ie: the server where you have installed Mattermost-LDAP). -You can add the following settings to your configuration files for this type of setup. +**Remark** : By default, Mattermost does not trust self-signed certificate. To remediate you need to add the certificate to the Mattermost server certificate bundle or change the parameter `EnableInsecureOutgoingConnection` to true in the Mattermost configuration (`config.json`). -In `docker-compose.yaml` : -```yaml -version: '3' +Alternatively, you can use your own certificates and place them in the `certs` directory. This directory will be consumed by the Nginx container as a volume. -[...] +*Note* : Your certificates should be in PEM format and must be named `cert.pem` and `key.pem`, to match the Nginx configuration. -services: - mattermost-ldap: - - [...] - - expose: - - 80 - - 443 - - environment: - [...] - - VIRTUAL_HOST=oauth.example.com,www.oauth.example.com - - LETSENCRYPT_HOST=oauth.example.com,www.oauth.example.com - -[...] -``` +## Usage -In `.env`: +Once you have adapted environement paramters in the docker-compose file, you can run Mattermost-LDAP with the following commands (from the root of the repository) : ```bash -[...] - -redirect_uri = "https://chat.example.com/signup/gitlab/complete" - -ldap_filter = "(&(objectClass=inetOrgPerson)(memberof=cn=chat,ou=groups,dc=example,dc=com))" +# With Docker +docker-compose up -d -[...] +# With Podman +podman-compose up -d ``` +The previous command starts all services described in the Docker compose file. The `-d` argument allows to start all container in background, in a detached mode. -This filter will additionally allow you to filter based on group affiliation within your LDAP server. +Once all services are started, go to Mattermost server and click on GitLab button to login with LDAP credential on Mattermost-LDAP. Then, if you login successfully and authorize Mattermost-LDAP to transmit your data to Mattermost, you should be log on Mattermost. -Finally, add the following to your mattermost `config.json` to ensure the correct redirect. +To stop Mattermost-LDAP, use the following command : +```bash +# With Docker +docker-compose down -```json - "GitLabSettings": { - "Enable": true, - "Secret": "XXX", - "Id": "YYY", - "Scope": "", - "AuthEndpoint": "https://oauth.example.com/oauth/authorize.php", - "TokenEndpoint": "https://oauth.example.com/oauth/token.php", - "UserApiEndpoint": "https://oauth.example.com/oauth/resource.php" - }, +# With Podman +podman-compose down ``` diff --git a/Docker/mattermostldap/Dockerfile b/Docker/mattermostldap/Dockerfile deleted file mode 100644 index 71329b9..0000000 --- a/Docker/mattermostldap/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# Image mattermostldap -FROM php:apache - -RUN set -x \ - && apt-get update \ - && apt-get install -y libpq-dev libldap2-dev git\ - && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure pgsql --with-pgsql=/usr/local/pgsql \ - && docker-php-ext-install pdo pdo_pgsql pgsql \ - && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ - && docker-php-ext-install ldap - -# Enable development php.ini config (Solve empty answer from token.php) -RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini - -# Get Mattermost-LDAP project -RUN git clone https://github.com/crivaledaz/Mattermost-LDAP.git /opt/Mattermost-LDAP/ - -# Install server Oauth -RUN cp -r /opt/Mattermost-LDAP/oauth/ /var/www/html/ - -# Get config file -RUN cp /var/www/html/oauth/config_db.php.example /var/www/html/oauth/config_db.php; cp /var/www/html/oauth/LDAP/config_ldap.php.example /var/www/html/oauth/LDAP/config_ldap.php - -# Open and expose port 80 for Apache server -EXPOSE 80 diff --git a/README.md b/README.md index b60c255..0f7e14e 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ See Limitation section for more information. ## Quick Start - Demonstration -To test and try Mattermost-LDAP, you can use the demonstration available in the `Demo/` folder. This demonstration is based on a docker-compose implementation describe in the `Demo/docker-compose.yaml` file. +To test and try Mattermost-LDAP, you can use the demonstration available in the `Demo/` folder. This demonstration is based on a docker-compose implementation describe in the [`Demo/docker-compose.yaml` file](https://github.com/Crivaledaz/Mattermost-LDAP/blob/master/Demo/docker-compose.yaml). This docker-compose file instantiate a Mattermost Server from the official preview image provides by Mattermost, a Mattemrost-LDAP pre-configured server with a PostgreSQL database and an OpenLDAP server with a test user : John DOE. @@ -64,7 +64,7 @@ docker-compose up -d podman-compose up -d ``` -The up command starts all services described in the Docker compose file. The `-d` argument allow to start all container in background, in a detach mode. +The up command starts all services described in the Docker compose file. The `-d` argument allows to start all container in background, in a detach mode. Once all services are started, go to Mattermost server. Mattermost should be available after a few seconds on localhost : http://localhost. @@ -104,7 +104,7 @@ Configuration files are provided with examples and default values. Each config f You can find a detailed description of each parameters available below. -**Note** : For container, these variables are overload by environment variables define in `.env` file or `docker-compose.yaml` file. +**Note** : For container, these variables are overload by environment variables define in the [`docker-compose.yaml`](https://github.com/Crivaledaz/Mattermost-LDAP/blob/master/docker-compose.yaml) file. ### Init script parameters diff --git a/docker-compose.yaml b/docker-compose.yaml index 6efd37d..70b3d45 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,29 +1,38 @@ version: '3' services: - mattermost-ldap: - build: Docker/mattermostldap - image: mattermostldap + nginx: + image: nginx restart: always ports: - 80:80 - 443:443 + volumes: + - ./oauth:/var/www/html/oauth + - ./oauth.conf:/etc/nginx/conf.d/oauth.conf:ro + - ./certs:/etc/nginx/certs + links: + - "php:php" + php: + build: ./Docker/php-ldap-pgsql + image: php-ldap-pgsql + volumes: + - ./oauth:/var/www/html/oauth environment: - - ldap_host - - ldap_port - - ldap_version - - ldap_start_tls - - ldap_search_attribute - - ldap_base_dn - - ldap_filter - - ldap_bind_dn - - ldap_bind_pass - - db_host - - db_port - - db_type - - db_name - - db_user - - db_pass - + ldap_host: ldap://ldap.company.com:389/ + ldap_port: 389 + ldap_version: 3 + ldap_start_tls: 0 + ldap_search_attribute: uid + ldap_base_dn: "ou=People,o=Company" + ldap_filter: "(objectClass=*)" + ldap_bind_dn: "" + ldap_bind_pass: "" + db_host: "127.0.0.1" + db_port: "5432" + db_type: "pgsql" + db_name: "oauth_db" + db_user: "oauth" + db_pass: "oauth_secure-pass" db: image: postgres:alpine restart: always @@ -32,17 +41,17 @@ services: - ./db_init/config_init.sh.example:/docker-entrypoint-initdb.d/config_init.sh - ./data/:/var/lib/postgresql/data/ environment: - - POSTGRES_USER - - POSTGRES_PASSWORD - - POSTGRES_HOST_AUTH_METHOD - - client_id - - client_secret - - redirect_uri - - grant_types - - scope - - user_id - - db_user - - db_pass - - db_name - - db_host - - db_port + POSTGRES_USER: postgres + POSTGRES_PASSWORD: rootroot + POSTGRES_HOST_AUTH_METHOD: trust + client_id: 123456789abcdef123456789abcdef + client_secret: fedcba987654321fedcba987654321 + redirect_uri: "https://mattermost.company.com/signup/gitlab/complete" + grant_types: "authorization_code" + scope: "api" + user_id: "" + db_user: "oauth" + db_pass: "oauth_secure-pass" + db_name: "oauth_db" + db_host: "127.0.0.1" + db_port: "5432" diff --git a/env.example b/env.example deleted file mode 100644 index e3572d0..0000000 --- a/env.example +++ /dev/null @@ -1,88 +0,0 @@ -# Docker compose parameters for Mattermost-LDAP -# -# Adapt these parameters to match with your configuration. -# More information available in section "Configuration" in README.md - -# -# Oauth client configuration -# - -# Client ID token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token. -client_id = "123456789abcdef123456789abcdef" - -# Client Secret token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token. -client_secret = "fedcba987654321fedcba987654321" - -# Redirect URI use by Oauth server to redirect user after authentifictaion process. Must be the same than as Mattermost give to Oauth server. -redirect_uri = "http://localhost/signup/gitlab/complete" - -# Grant types method uses by Oauth server -grant_types = "authorization_code" - -# Scope of the client in the Oauth server -scope = "api" - -# Non important parameter. Could be used as a commentary field -user_id = "" - -# -# Database configuration -# - -# Username for the PostgreSQL administrator account -POSTGRES_USER = "postgres" - -# Password for PostgreSQL administrator account -POSTGRES_PASSWORD = "rootroot" - -# Method to use for connection to database -POSTGRES_HOST_AUTH_METHOD = "trust" - -# Oauth user to connect the database -db_user = "oauth" - -# Oauth password to connect the database -db_pass = "oauth_secure-pass" - -# Oauth database name -db_name = "oauth_db" - -# PostgreSQL database host -db_host = "127.0.0.1" - -# PostgreSQL database port -db_port = "5432" - -# Database type. Docker compose implementation for Mattermost-LDAP uses PostgreSQL. -db_type = "pgsql" - -# -# LDAP configuration -# - -# LDAP host or IP -ldap_host = "ldap://ldap.company.com:389/" - -# LDAP port -ldap_port = "389" - -# LDAP protocol version -ldap_version = "3" - -# LDAP STARTTLS -ldap_start_tls = "1" - -# Unique identifier for entry in LDAP -ldap_search_attribute = "uid" - -# Base DN to search from in LDAP -ldap_base_dn = "ou=People,o=Company" - -# Additional filter for LDAP search -ldap_filter = "(objectClass=*)" - -# Service account to bind LDAP server -ldap_bind_dn = "" - -# Password for service account to bind LDAP server -ldap_bind_pass = "" diff --git a/oauth.conf b/oauth.conf new file mode 100644 index 0000000..9e193e0 --- /dev/null +++ b/oauth.conf @@ -0,0 +1,46 @@ +server { + listen *:443; + server_name localhost; + root /var/www/html; + index index.php index.html index.htm; + + ssl on; + ssl_certificate ./certs/cert.pem; + ssl_certificate_key ./certs/key.pem; + + 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 php:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location / { + try_files $uri $uri/ =404; + } + +} + +server { +listen 80 default_server; +server_name localhost; +index index.php index.html index.htm; +return 301 https://$host$request_uri; +}