전송 암호화 구성#

plans-img Enterprise 플랜 에서 사용 가능

deployment-img self-hosted 배포

Mattermost 설정의 구성 요소는 사용된 전송 암호화를 포함하여 다음 다이어그램에 표시됩니다. Mattermost 클러스터의 노드 간 암호화를 제외하고 모든 전송은 TLS 암호화에 의존합니다.

참고

애플리케이션 서버 간 전송은 기본적으로 사용되지 않으며 추가 설정 단계가 필요합니다. 클러스터 노드 간 자동 암호화를 포함하도록 핵심 제품을 개선하는 작업이 진행 중이며 향후 릴리스에서 계획되어 있습니다.

모든 전송이 TLS 암호화에 의존하는 Mattermost 설정의 구성 요소.

프록시에서 Mattermost로의 전송 암호화 구성#

plans-img Enterprise 플랜 에서 사용 가능

deployment-img self-hosted 배포

Mattermost는 TLS를 사용하여 프록시와 애플리케이션 서버 간의 트래픽을 암호화할 수 있습니다.

사전 요구사항#

  • 운영 중인 Mattermost 서버 또는 클러스터.

  • 애플리케이션 서버의 Mattermost 사용자 인증 정보.

예제 환경#

이 시나리오에는 Ubuntu 20.04를 실행하는 Mattermost 애플리케이션 서버와 NGINX 서버가 각각 하나씩 있으며, 다음과 같은 IP를 사용합니다:

  • transport-encryption-mattermost1: 10.10.250.146

  • transport-encryption-nginx: 10.10.250.107

NGINX 구성#

NGINX 서버에서 sudo 또는 root 사용자로 두 서버에 연결합니다. Mattermost 프록시 구성을 열고 다음 줄을 두 번 검색합니다:

proxy_pass http://backend;

프로토콜을 http``에서 ``https 로 변경합니다:

proxy_pass https://backend;

서비스 중단 시간을 최소화하기 위해 아직 NGINX 서버를 다시 로드하지 마세요.

Mattermost 구성#

Mattermost 서버에서 Mattermost의 config 디렉토리로 이동하여 프록시 서버와 애플리케이션 서버 간의 트래픽을 암호화하는 데 사용할 자체 서명 인증서를 생성합니다.

참고: 대안으로 회사의 CA에서 인증서를 서명할 수 있습니다.

cd /opt/mattermost/config
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
chown root:mattermost *.pem
chmod 640 *.pem

완료되면 config.json 파일을 열고 ServiceSettings 섹션에서 ConnectionSecurity, TLSCertFile, TLSKeyFile 값을 수정합니다.

이전

{
    "ServiceSettings": {
        "SiteURL": "https://transport-encryption.dev.example.com",
        "WebsocketURL": "",
        "LicenseFileLocation": "",
        "ListenAddress": ":8065",
        "ConnectionSecurity": "",
        "TLSCertFile": "",
        "TLSKeyFile": "",
        "...":"..."
    },
    "...":"..."
}

이후

{
    "ServiceSettings": {
        "SiteURL": "https://transport-encryption.dev.example.com",
        "WebsocketURL": "",
        "LicenseFileLocation": "",
        "ListenAddress": ":8065",
        "ConnectionSecurity": "TLS",
        "TLSCertFile": "/opt/mattermost/config/cert.pem",
        "TLSKeyFile": "/opt/mattermost/config/key.pem",
        "...":"..."
    },
    "...":"..."
}

Mattermost 서버를 재시작하고 정상적으로 실행 중인지 확인합니다:

sudo systemctl restart mattermost
systemctl status mattermost
● mattermost.service - Mattermost
   Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled)
   Active: active (running) since Mon 2019-10-28 16:45:29 UTC; 1h 15min ago
   [...]

마지막으로 NGINX 서버 에서 요청이 HTTPS로 전송되도록 구성을 다시 로드합니다:

sudo systemctl reload nginx

데이터베이스 전송 암호화 구성#

plans-img Enterprise 플랜 에서 사용 가능

deployment-img self-hosted 배포

Mattermost는 TLS를 사용하여 데이터베이스와 애플리케이션 간의 트래픽을 암호화할 수 있습니다. 이 가이드는 단일 독립 MySQL 서버에 대한 설정 단계를 설명합니다.

사전 요구사항#

  • 운영 중인 Mattermost 서버 또는 클러스터.

  • 운영 중인 MySQL 서버.

  • Mattermost와 MySQL 서버 간의 연결이 확인되었습니다.

  • MySQL 서버의 Mattermost 사용자 인증 정보.

예제 환경#

이 시나리오에는 Ubuntu 20.04를 실행하는 Mattermost 애플리케이션 서버와 MySQL 서버가 각각 하나씩 있으며, 다음과 같은 IP를 사용합니다:

  • transport-encryption-mattermost1: 10.10.250.146

  • transport-encryption-mysql1: 10.10.250.148

MySQL 구성#

첫 번째 단계로, sudo 또는 root 사용자로 두 서버에 연결합니다.

SSL 연결을 위해 서버를 준비하려면 다음 명령을 실행합니다:

sudo mysql_ssl_rsa_setup --uid=mysql

이렇게 하면 MySQL 서버가 연결을 암호화하는 데 사용하는 자체 서명 인증서가 /var/lib/mysql/ 에 생성됩니다. 회사 CA의 인증서를 사용하려면 MySQL 문서의 구성 단계를 따르세요.

참고: 선택적으로 모든 연결이 로컬 소켓 연결 또는 TLS를 통해 이루어져야 한다고 강제할 수 있습니다. 이를 위해 /etc/mysql/mysql.conf.d/mysqld.cnf 를 열고 다음 줄을 파일에 추가합니다:

require_secure_transport = ON

이제 MySQL 서버에 대한 모든 연결은 보안 전송을 활성화하여 이루어져야 합니다.

마지막으로, 서버를 재시작하고 정상적으로 실행 중인지 확인합니다:


systemctl restart mysql systemctl status mysql

● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-10-18 16:41:25 UTC; 2s ago
  Process: 8380 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
  Process: 8360 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 8382 (mysqld)
    Tasks: 27 (limit: 2361)
   CGroup: /system.slice/mysql.service
           └─8382 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid

Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Stopped MySQL Community Server.
Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Starting MySQL Community Server...
Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Started MySQL Community Server.

Mattermost 구성#

Mattermost 서버에서 config.json 파일을 열고 SqlSettings 섹션에서 DataSource 값을 찾습니다. 다음과 비슷하게 보일 것입니다:

"DataSource": "mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8\u0026writeTimeout=30s",

tls 플래그를 사용하여 TLS를 활성화하도록 구성할 수 있으며, 이 플래그는 다음 값을 지원합니다:

  • true (TLS 필요 + 신뢰할 수 있는 인증서)

  • false

  • skip-verify (TLS 필요 + 자체 서명 인증서 허용)

  • preferred (TLS 시도, 암호화되지 않은 연결로 대체)

자체 서명 인증서를 사용하므로 skip-verify 를 사용해야 합니다. 구성 설정은 다음과 같이 됩니다:

"DataSource": "mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8\u0026writeTimeout=30s&tls=skip-verify",

클러스터에서 Mattermost를 실행 중인 경우, 클러스터의 각 노드에서 값을 업데이트해야 합니다. 데이터베이스에서 구성을 사용하는 경우, systemd 유닛 파일을 업데이트하고 구성 저장소에 대해 TLS를 활성화해야 합니다.

완료되면 Mattermost 서버를 재시작하고 시스템이 정상 작동하는지 확인합니다:

sudo systemctl restart mattermost
systemctl status mattermost
● mattermost.service - Mattermost
   Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled)
   Active: active (running) since Fri 2019-10-18 16:47:08 UTC; 3s ago
  Process: 3424 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS)
 Main PID: 3443 (mattermost)
    Tasks: 20 (limit: 2361)
   CGroup: /system.slice/mattermost.service
           ├─3443 /opt/mattermost/bin/mattermost --config=mysql://mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s&tls=skip-verify
           └─3459 plugins/com.mattermost.nps/server/dist/plugin-linux-amd64

Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8637397,"caller":"scheduler/worker.go:36","msg":"Worker started","worker":"Plugins"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8639545,"caller":"jobs/jobs_watcher.go:38","msg":"Watcher Started"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"info","ts":1571417228.8641603,"caller":"jobs/schedulers.go:72","msg":"Starting schedulers."}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8645394,"caller":"app/web_hub.go:436","msg":"Hub for index 0 is starting with goroutine 3923"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8648505,"caller":"app/web_hub.go:436","msg":"Hub for index 1 is starting with goroutine 3924"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8656101,"caller":"web/static.go:31","msg":"Using client directory at /opt/mattermost/client"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"info","ts":1571417228.8681324,"caller":"commands/server.go:105","msg":"Sending systemd READY notification."}
Oct 18 16:47:08 transport-encryption-mattermost1 systemd[1]: Started Mattermost.
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.9003174,"caller":"jobs/schedulers.go:166","msg":"Next run time for scheduler","scheduler_name":"MigrationsSched
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.9025588,"caller":"jobs/schedulers.go:166","msg":"Next run time for scheduler","scheduler_name":"PluginsSchedule

클러스터 전송 암호화 구성#

plans-img Enterprise 플랜 에서 사용 가능

deployment-img self-hosted 배포

Mattermost는 SSH 터널링을 사용하여 배포 클러스터 내에서 전송되는 메시지를 암호화할 수 있습니다. 이 가이드는 Ubuntu 20.04에서 이 솔루션의 배포 과정을 설명하지만, 모든 Linux 운영 체제에 적용할 수 있습니다.

이 문서는 3노드 클러스터의 구성만 설명하지만, 이 수로 제한되지는 않습니다.

사전 요구사항#

  • 배포의 각 노드 간에 SSH 포트가 허용 목록에 등록되어 있어야 합니다.

  • 각 노드에서 ufw/iptables가 활성화되어 있어야 합니다.

  • 구성을 위해 각 노드의 root/sudo 사용자에 대한 접근 권한이 있어야 합니다.

  • 구성된 Mattermost 클러스터가 있어야 합니다.

  • 전용 서비스 사용자로 실행 중인 Mattermost가 있어야 합니다.

  • 각 클러스터 노드에서 Mattermost 서비스가 중지되어 있어야 합니다.

참고

애플리케이션 수준의 지원은 현재 개발 중이며, 사용 가능해지면 이 문서는 더 이상 사용되지 않을 것입니다.

예제 환경#

이 시나리오에서는 다음과 같은 호스트명/IP 매핑을 가진 3개의 애플리케이션 노드가 환경에 있습니다:

  • transport-encryption-mattermost1: 10.10.250.146

  • transport-encryption-mattermost2: 10.10.250.231

  • transport-encryption-mattermost3: 10.10.250.165

준비 사항#

  • sudo 또는 root 사용자로 각 Mattermost 서버에 연결합니다.

  • 내부 통신에 사용되는 각 클러스터 구성원의 IP를 기록해 둡니다.

  • 각 클러스터 노드의 /etc/ssh/sshd_config 에서 AllowTcpForwarding 이 활성화되어 있는지 확인합니다.

SSH 인증#

각 노드에서 서비스 계정용 SSH 키 쌍을 생성합니다. 이 시나리오에서는 이를 mattermost 라고 합니다:

sudo -u mattermost ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mattermost/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mattermost/.ssh/id_rsa.
Your public key has been saved in /home/mattermost/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:redacted mattermost@transport-encryption-mattermost1

회사 정책에서 다른 저장 위치 사용을 요구하는 경우 SSH 키 자체의 위치는 중요하지 않습니다.

다음으로, 각 노드의 SSH 공개 키가 클러스터의 다른 노드들의 authorized_keys 파일에 추가되었는지 확인합니다. 이를 위해 노드 2와 3의 /home/mattermost/.ssh/id_rsa.pub 내용을 복사하여 노드 1의 /home/mattermost/.ssh/authorized_keys 에 추가합니다.

클러스터의 각 노드에 대해 이 단계를 반복합니다. 결과적으로 각 노드는 클러스터의 다른 노드들과 SSH 연결을 설정할 수 있어야 합니다.

참고

이 서비스 계정은 Mattermost systemd 서비스 자체에 이미 사용 중인 서비스 계정과 별개일 수 있습니다. 이 서비스 계정이 포트 포워딩이 있는 SSH 터널을 생성할 수 있도록 허용되어야 하는 것이 중요하지만, 추가 권한은 필요하지 않습니다.

ufw 구성#

다음 단계로, 다른 멤버 노드들로부터의 SSH 접근을 허용합니다. 예:

  • mattermost1은 mattermost2와 mattermost3로부터의 접근을 허용

  • mattermost2는 mattermost1과 mattermost3로부터의 접근을 허용

  • mattermost3는 mattermost1과 mattermost2로부터의 접근을 허용

이를 위해 방화벽에 예외를 추가합니다. mattermost1 에 대한 명령어는 다음과 같습니다:

sudo ufw allow from 10.10.250.231/32 to any port ssh
sudo ufw allow from 10.10.250.165/32 to any port ssh
sudo ufw status
Rule added
Rule added
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       10.10.250.10
8065/tcp                   ALLOW       Anywhere
22/tcp                     ALLOW       10.10.250.231
22/tcp                     ALLOW       10.10.250.165

다른 노드들에서도 동일한 단계를 반복하되, IP를 다른 멤버 노드들의 IP로 교체합니다. 자기 자신을 제외한 각 멤버 노드에 대해 이 작업을 수행합니다.

다음으로, /etc/ufw/after.rules 를 열고 파일 하단에 다음 블록을 추가합니다:

*nat
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]

-A OUTPUT -p tcp -d 10.10.250.231 --dport 8075 -j DNAT --to-destination 127.0.0.1:18075
-A OUTPUT -p tcp -d 10.10.250.231 --dport 8074 -j DNAT --to-destination 127.0.0.1:18074
-A OUTPUT -p tcp -d 10.10.250.165 --dport 8075 -j DNAT --to-destination 127.0.0.1:28075
-A OUTPUT -p tcp -d 10.10.250.165 --dport 8074 -j DNAT --to-destination 127.0.0.1:28074

COMMIT

두 줄은 항상 단일 노드에 속하므로, 4개의 노드가 있는 배포에서는:

-A OUTPUT -p tcp -d ip_node_2 --dport 8075 -j DNAT --to-destination 127.0.0.1:18075
-A OUTPUT -p tcp -d ip_node_2 --dport 8074 -j DNAT --to-destination 127.0.0.1:18074
-A OUTPUT -p tcp -d ip_node_3 --dport 8075 -j DNAT --to-destination 127.0.0.1:28075
-A OUTPUT -p tcp -d ip_node_3 --dport 8074 -j DNAT --to-destination 127.0.0.1:28074
-A OUTPUT -p tcp -d ip_node_4 --dport 8075 -j DNAT --to-destination 127.0.0.1:38075
-A OUTPUT -p tcp -d ip_node_4 --dport 8074 -j DNAT --to-destination 127.0.0.1:38074

오른쪽의 포트는 고유해야 한다는 점에 유의하세요. 6개의 노드가 있는 클러스터의 경우, 8075와 8074 앞에 1부터 5까지의 숫자를 사용하세요. 클러스터가 더 큰 경우, 추가 포트를 사용해야 합니다.

다음 명령어를 사용하여 운영 체제에서 IP 포워딩이 활성화되어 있는지 확인합니다:

sysctl -w net.ipv4.ip_forward=1

그 후, ufw 규칙을 다시 로드하고 iptable 규칙이 성공적으로 생성되었는지 확인합니다:

iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  anywhere             10.10.250.231        tcp dpt:8075 to:127.0.0.1:18075
DNAT       tcp  --  anywhere             10.10.250.231        tcp dpt:8074 to:127.0.0.1:18074
DNAT       tcp  --  anywhere             10.10.250.165        tcp dpt:8075 to:127.0.0.1:28075
DNAT       tcp  --  anywhere             10.10.250.165        tcp dpt:8074 to:127.0.0.1:28074

클러스터의 모든 노드에 대해 이러한 단계를 반복합니다. 이 섹션의 끝에서 다음이 구성되어야 합니다:

  • 각 클러스터 노드에서 다른 노드로의 방화벽 SSH 접근이 활성화되어 있습니다.

  • 포트 8074와 8075에 대한 노드당 2개의 iptables 규칙이 있습니다.

  • IP 포워딩이 활성화되어 있습니다.

SSH 구성#

다음 단계로, SSH 터널이 Mattermost 서비스 시작의 일부로 생성되도록 합니다. 이를 위해 mattermost1/opt/mattermost/binpre_start.sh 라는 파일을 생성합니다:

#!/bin/bash
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 18075:10.10.250.231:8075 10.10.250.231 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 18074:10.10.250.231:8074 10.10.250.231 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 28075:10.10.250.165:8075 10.10.250.165 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 28074:10.10.250.165:8074 10.10.250.165 || true

참고

  • 터널이 이미 활성화된 경우 SSH 연결 자체의 오류를 무시합니다. 그렇지 않으면 Mattermost 서버가 시작되지 않을 것입니다.

  • 버전 업그레이드 시를 대비하여 이 스크립트를 백업해 두세요.

그 후, 셸 스크립트에 실행 권한을 설정합니다:

chmod +x /opt/mattermost/bin/pre_start.sh

Mattermost의 systemd 유닛 파일을 열고 Type=Notify 를 찾습니다. 그 후, Mattermost 자체가 시작되기 전에 실행될 ExecStartPre 스크립트를 입력합니다:

[Service]
Type=notify
ExecStartPre=/opt/mattermost/bin/pre_start.sh

그 후 systemd 데몬을 다시 로드합니다:

systemctl daemon-reload

각 멤버 노드에서 동일한 단계를 반복하고 환경에 맞게 노드 IP와 항목 수를 조정합니다.

클러스터 시작#

각 노드가 구성되면 각 클러스터에서 서비스를 다시 시작하고 아래 명령어를 사용하여 실행 중인지 확인합니다:

systemctl start mattermost
systemctl status mattermost.service
● mattermost.service - Mattermost
   Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled)
   Active: active (running) since Fri 2019-10-04 19:44:20 UTC; 5min ago
  Process: 16734 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS)

다음으로 Mattermost 시스템 콘솔을 열고 각 노드가 고가용성 섹션에서 성공적으로 보고되고 있는지 확인합니다.