【Ubuntu】Mattermost をインストール

**この記事で解説すること：**

Amazon Lightsail で Ubuntu のインスタンスを立ち上げ、そこに Mattermost をインストールします。
構成は、Nginx + MySQL です。

また、独自ドメインを適用し、Let's Encrypt で SSL化も行います。


## サーバーの立ち上げ

### インスタンスの立ち上げ

Amazon Lightsail を利用します。

https://lightsail.aws.amazon.com/ls/docs/ja_jp/articles/how-to-create-amazon-lightsail-instance-virtual-private-server-vps

インスタンスを立ち上げる際の設定内容は以下です。

- プラットフォーム：Linux / Unix
- OSのみ：Ubuntu20.04 LTS
- インスタンスプラン：$10 プラン
※ メモリが2GBないと、SSHの際に重くて固まったりするので…
- SSHキーペア：デフォルトのまま
- 自動スナップショットの有効化：未チェック

作成後、状態が「保留中」から「実行中」になるまで待ちます。

料金は、Amazon EC2 と違い、実行中・停止中に関係なく課金されます。

### IPアドレスの固定

「ネットワーキング」タブから、静的IPアドレスを作成し、アタッチします。
料金は、アタッチしている間は無料です。

### ファイアウォールの設定

同じく「ネットワーキング」タブから、セキュリティルールを追加します。

Mattermost のポートはデフォルトで :8065 なので、そのポートを開けておきます。
その他に、80番ポート (HTTP) と 443番ポート (HTTPS) も開けておきます。

### SSH接続

「接続」タブから「SSHを使用して接続」で接続し、サーバー内にログインします。

他にもいくつか方法はありますが、このブラウザベースの接続が一番手軽で良いです。
以降の手順は、すべてサーバー内で作業します。


## Mattermost の設定

以下の公式の手順に沿って行います。

https://docs.mattermost.com/install/installing-ubuntu-2004-LTS.html

### 下準備

最新のセキュリティパッチが適用されていることを確認します。

```
$ sudo apt update
$ sudo apt upgrade

// 紫の画面では「keep the local version currently installed」を選択
```


### MySQL 

以下の順に実行します。

#### まずはインストール
```
$ sudo apt install mysql-server
```

#### root ユーザーのパスワードを設定
```
$ sudo mysql
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'hogehoge';
mysql> exit
```

※ 公式では最初に「sudo mysql_secure_installation」を実行していますが、この手順を踏んでおかないと以下のエラーが出ます。

```
Failed! Error: SET PASSWORD has no significance for user 'root'@'localhost' as the au
thentication method used doesn't store authentication data in the MySQL server. Please con
sider using ALTER USER instead if you want to change authentication parameters.
```

#### セキュリティ設定
```
$ sudo mysql_secure_installation  // 先程のパスワードでログイン
```

実行後、以下の質問だけ「No」で回答します。

- 「Would you like to setup VALIDATE PASSWORD component?」：No
- 「Change the password for root ?」：No


#### ログイン
```
$ mysql -u root -p  　// 先程のパスワードでログイン
```

#### ユーザー (mmuser) を作成
```
mysql> create user 'mmuser'@'%' identified by 'mmuserP@22w0rd';
mysql> show grants for 'mmuser'@'%';
```

#### DB作成
Mattermost のデータを保存するためのデータベースを作成します。

```
mysql> create database mattermost;
```

#### アクセス権限の付与
先ほど作成したユーザー (mmuser) が データベース (mattermost) にアクセスできるよう、権限を付与します。

```
mysql> grant all privileges on mattermost.* to 'mmuser'@'%';
mysql> show grants for 'mmuser'@'%';
mysql> exit
```

以上で、MySQL の設定は完了です。

### Mattermost

次に、Mattermost をインストールしていきます。

#### ダウンロード
```
$ wget https://releases.mattermost.com/7.2.0/mattermost-7.2.0-linux-amd64.tar.gz
```

latest ver. はこちらから確認できます。

https://mattermost.com/deploy/

#### 解凍
```
$ tar -xvzf mattermost*.gz
```

#### /opt ディレクトリに移動させ、dataディレクトリを作成
```
$ sudo mv mattermost /opt
$ sudo mkdir /opt/mattermost/data
```

#### システムユーザー及びグループの作成
mattermost 実行用のシステムユーザー及びグループ を作成し、権限を付与します。

```
$ sudo useradd --system --user-group mattermost
$ sudo chown -R mattermost:mattermost /opt/mattermost
$ sudo chmod -R g+w /opt/mattermost
```

#### 設定ファイルの編集
Mattermost の設定ファイル (config.json) について、必要な箇所を編集します。
```
$ sudo vim /opt/mattermost/config/config.json
```

編集内容は以下です。

```
"SiteURL" : "https://{example.com}"
```

※ {example.com} には、、Mattermost に紐付けたい独自ドメインを設定します。

※ ドメインをHPなどで利用している場合は、サブドメインなどを作成して割り当てるのがオススメです。

※ DNS の設定をしておきます。Aレコードの値には、インスタンスのパブリックIPを設定します。

```
"DriverName": "mysql"
```

```
"DataSource": "mmuser:<mmuser-password>@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s"
```

※ `<mmuser-password>`… 先ほどのMySQLで作成したユーザー (mmuser) に設定したパスワード

※ 「localhost」の部分について、公式では `<host-name-or-IP>` と書いてありますが、`"tcp(インスタンスのパブリックIP:3306)" )` とすると `Failed to ping DB` とエラーが出るため、localhost に設定しています。

```
"DefaultServerLocale": "ja"
"DefaultClientLocale": "ja"
```



#### Mattermost を起動できるか、一旦テスト
```
$ cd /opt/mattermost
$ sudo -u mattermost ./bin/mattermost
```

色々表示され、最後に `"Server is listening on :8065"` と表示されれば成功です。

#### systemd unit file の設定
systemd を使うため、systemd unit file を作成し、中身を設定します。

```
$ sudo vim /lib/systemd/system/mattermost.service
```

MySQLを使うので、公式を参考に 中身は以下のようにします。

```
[Unit]
Description=Mattermost
After=network.target
After=mysql.service
BindsTo=mysql.service

[Service]
Type=notify
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
KillMode=mixed
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
LimitNOFILE=49152

[Install]
  WantedBy=mysql.service
```


#### systemd をロードし、ちゃんとロードされたか確認
```
$ sudo systemctl daemon-reload
$ sudo systemctl status mattermost.service
```

以下のように表示されれば成功です。
```
● mattermost.service - Mattermost
Loaded: loaded (/lib/systemd/system/mattermost.service; disabled; vendor preset: enabled)
Active: inactive (dead)
```

#### Mattermost を起動
```
$ sudo systemctl start mattermost.service
```

以下を実行し、Matterhost の HTML が返ってくれば成功です。
```
$ curl http://localhost:8065
```

最後に、マシン起動時に、Mattermost が起動するように設定しておきます。
```
$ sudo systemctl enable mattermost.service
```

### NGINX

次に、ウェブサーバーを設定します。

#### まずはインストール
```
$ sudo apt update
$ sudo apt install nginx
$ curl http://localhost
```

#### 設定ファイルを作成
```
$ sudo vim /etc/nginx/sites-available/mattermost
```

中身は以下のようにします

※ {IPアドレス} は、インスタンスのパブリックIP です。
※ {example.com} は、Mattermost に紐付けたい独自ドメインを設定します。

```
upstream backend {
   server {IPアドレス}: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 {example.com};

   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_pass http://backend;
   }

   location / {
       client_max_body_size 50M;
       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;
   }
}
```

#### 既存の設定ファイルを削除
新しい設定ファイル (/etc/nginx/sites-available/mattermost) を作成したので、既存のファイルは削除しておきます。

```
$ sudo rm /etc/nginx/sites-available/default
```

#### 設定ファイルの有効化
先ほど作成した設定ファイル (`/etc/nginx/sites-available/mattermost`) のシンボリックリンクを `/etc/nginx/sites-enabled/` に張り、Nginx を起動します。

```
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/mattermost
$ sudo nginx -t
$ sudo systemctl start nginx
$ curl http://localhost
```

## SSL

次に、Let's Encrypt を利用し、サイトを SSL (TLS) 化します

https://letsencrypt.org/ja/

#### Certbot をインストール
Let's Encrypt で証明書を発行するには、Certbot という ACME クライアントを利用するので、その準備をします。

```
$ sudo snap install core; sudo snap refresh core
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
```

#### --dry-run で 一旦テスト
証明書を発行する前に、DNSが適切に構成されているかテストしておきます。

```
$ sudo certbot certonly --dry-run
// 1: Nginx Web Server plugin (nginx) を選択
```

※ 必ず 80番ポート (HTTP) を開けておいてください。開いていないと、エラーでチャレンジに失敗します。

#### 証明書を発行
```
$ sudo certbot
$ curl https://example.com
```

#### SSLセキュリティ設定
最後に、Nginx の設定ファイルを再度編集し、SSLセキュリティ設定を強化しておきます。

```
$ sudo vim /etc/nginx/site-availables/mattermost
```

編集内容は以下です。新しく追加する部分をコメントアウトしてあります。

```
upstream backend {
   server {IPアドレス}: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 {example.com};

    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 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;
    }
}

# ここから下をすべて追加
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/{ドメイン}/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/{ドメイン}/privkey.pem; # managed by Certbot
    # include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    ssl_session_timeout 1d;

    # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
    ssl_protocols TLSv1.2 TLSv1.3;

    # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
    # prevent replay attacks.
    #
    # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
    ssl_early_data on;

    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:50m;
    # HSTS (ngx_http_headers_module is required) (15768000 seconds = six months)
    add_header Strict-Transport-Security max-age=15768000;
    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
}


server {
    if ($host = {example.com}) {  // 忘れずに編集この行に独自ドメイン
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 default_server;
    server_name {example.com};   // 忘れずに編集
    return 404; # managed by Certbot

}
```

#### 反映
書き換えが終わったら、設定を反映させます。

```
$ sudo rm /etc/nginx/sites-enabled/mattermost
$ sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/mattermost
$ sudo nginx -t
$ sudo systemctl restart nginx
```

以下を実行し、Matterhost の HTML が返ってくれば成功です。
```
$ curl https://example.com
```

証明書の確認は、以下のサイトでドメインを検索することでも確認できます。

https://www.ssllabs.com/ssltest/index.html

ブラウザから https://example.com にアクセスした際、Nginxの初期ページが表示されたり、「この通信は保護されていません」と表示される場合は、再読み込みをしてください。キャッシュの問題である可能性があります。


以上で、Mattermost を立ち上げ & SSL化が完了しました。


今回は Amazon Lightsail のインスタンスを利用しましたが、同じ OS であれば、Amazon EC2 などでも問題ないかと思います。