はじめに
こんにちは、Putraです。
プライバシーを守りながら自由にコミュニケーションができる「自前チャットサーバー」、憧れますよね。今回は、AWSの CloudFormation を活用して、分散型チャット基盤 Matrix Synapse を構築する方法を解説します。
「コストを抑えつつセキュリティも妥協しない」ノポウハウをぎゅっと凝縮してお届けします!
Matrix Synapse とは?
Matrixは、特定のサービス(SlackやLINEなど)の枠を超えて、「誰もが自由につながり、自分のデータを自分で管理できる」新しいチャットの仕組みです。
使い方は一般的なチャットと変わりませんが、サーバーを自分たちで持てるため、データの保存場所や運用ルールを自分で決められるのが特徴です。
外部サービスに依存せず、安心して長く使えるチャット基盤を構築できます。
- つながる自由: 自分のサーバーを立てても、他のサーバーにいる人とスムーズにやり取りができます。
- 圧倒的な安心感: 通信は常に暗号化されるため、プライバシー保護も万全です。
- Synapse(シナプス): Matrixという仕組みを動かすための「心臓部」にあたるソフトウェアのことです。
Matrix公式サイト:https://matrix.org
今回の構築戦略:ここがポイント!
ただ構築するだけでなく、運用を考えた3つのこだわりを詰め込みました。
- コスト最適化 (NAT Gatewayレス): 高額なNAT Gatewayを使わず、EC2をパブリックサブネットに配置。通信費を賢く抑えます。
- 多層防御 (Security Group Chaining): DB(RDS)へのアクセスをEC2からだけに制限。インターネットから隔離された安全な環境を作ります。
- 自動化 (CloudFormation & Docker): インフラ構築からDockerのインストールまでを自動化し、作業ミスを防ぎます。
構築前のチェックリスト
デプロイを始める前に、以下の3点だけは必ず確認してください!ここを忘れるとエラーの原因になります。
- ACM証明書:
matrix.[your-domain]の証明書が「発行済み」ですか? - DBパスワード: 英数字のみ(半角英字+数字)で準備しましたか?(記号はNG!)
- リージョン: 全てのリソースを同じリージョンに揃えていますか?
CloudFormationテンプレート作成
自分で一つずつ設定するのは大変ですが、AWSの CloudFormation を使えば、ボタン一つで環境が整います。
このテンプレートでは、チャットに必要な「ネットワーク(VPC)」「データベース(RDS)」「画像保存場所(S3)」、そして「サーバー本体(EC2)」をまとめて作成します。
AWSTemplateFormatVersion: "2010-09-09"
Description: Infrastructure setup for Matrix Synapse (Manual IAM Setup Version).
# ==========================================
# 1. PARAMETERS
# ==========================================
Parameters:
KeyPairName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair in the TARGET REGION.
DBPassword:
Type: String
NoEcho: true
Description: Master password for RDS (Alphanumeric ONLY).
MinLength: 8
CertificateArn:
Type: String
Description: ARN of the ACM Certificate for HTTPS (Must be ISSUED in Target Region).
ImageId:
Type: String
Description: AMI ID for Amazon Linux 2023 (Must match Target Region).
SynapseServerName:
Type: String
Default: matrix.xxxxx.com # ドメイン情報を伏せています
Description: The domain name for the Matrix Server.
# ==========================================
# 2. RESOURCES
# ==========================================
Resources:
# --- A. NETWORKING ---
# VPC, Internet Gateway, dan Subnet dibuat secara otomatis
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags: [{Key: Name, Value: Matrix-VPC}]
InternetGateway:
Type: AWS::EC2::InternetGateway
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# (Public Subnet untuk EC2 dan ALB, Private Subnet untuk RDS)
# ... (Detail Networking sesuai dokumentasi) ...
# --- B. SECURITY GROUPS ---
# 必要なポートのみを開放し、セキュリティを確保します
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTPS to ALB
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
SynapseSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow traffic from ALB
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8008
ToPort: 8008
SourceSecurityGroupId: !Ref ALBSecurityGroup
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
RDSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow traffic from EC2 only
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref SynapseSecurityGroup
# --- C. STORAGE (S3 & RDS) ---
# データベースとファイル保存用のバケットを作成
MatrixMediaBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
RDSInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: matrix-db-verify
Engine: postgres
EngineVersion: "14"
DBInstanceClass: db.t3.micro
AllocatedStorage: 20
DBName: matrixsynapse
MasterUsername: matrixadmin
MasterUserPassword: !Ref DBPassword
VPCSecurityGroups: [!Ref RDSSecurityGroup]
PubliclyAccessible: false
# --- D. APPLICATION (EC2) ---
# サーバー本体。起動時にDockerを自動インストールします
SynapseEC2Instance:
Type: AWS::EC2::Instance
DependsOn: RDSInstance
Properties:
InstanceType: t3.small
ImageId: !Ref ImageId
KeyName: !Ref KeyPairName
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: "0"
GroupSet: [!Ref SynapseSecurityGroup]
SubnetId: !Ref PublicSubnet1
UserData:
Fn::Base64: !Sub |
#!/bin/bash
dnf update -y
dnf install -y docker
systemctl start docker
systemctl enable docker
usermod -a -G docker ec2-user
sleep 30
docker run -d \
--name matrix_synapse \
--restart unless-stopped \
-p 8008:8008 \
-e SERVER_NAME=${SynapseServerName} \
-e REPORT_STATS=no \
-e DATABASE_URL="postgresql://matrixadmin:${DBPassword}@${RDSInstance.Endpoint.Address}:5432/matrixsynapse" \
matrixdotorg/synapse:latest
# --- E. LOAD BALANCER (ALB) ---
# HTTPS通信を受け付け、サーバーに転送します
MatrixALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: matrix-alb-verify
Subnets: [!Ref PublicSubnet1, !Ref PublicSubnet2]
SecurityGroups: [!Ref ALBSecurityGroup]
Scheme: internet-facing
# ... (Listener & Target Group detail) ...
構築の手順 (立ち上げの流れ)
- 事前準備(情報の収集)
スタックを作成する前に、以下の2つの情報をメモしておきましょう。
- CertificateArn: [ACM] で作成したドメイン用の証明書のARN(
arn:aws:acm:...)をコピーします。 - ImageId (AMI): [EC2コンソール] のAMIカタログから、Amazon Linux 2023 のAMI ID(
ami-xxxx...)をコピーします。
- スタックの作成 (Create Stack)
いよいよCloudFormationを実行します!
- 開始: CloudFormation 画面で「スタックの作成」>「新しいリソースを使用」を選択。
- アップロード: 用意した
matrix-synapse-stack.yamlをアップロードします。 - パラメータ入力: * Stack name: 好きな名前を入力。
- DBPassword: 安全なパスワードを決めて入力。
- KeyPairName: 自分のキーペアを選択。
- その他: ステップ1で控えた ARN と AMI ID を貼り付けます。
- デプロイ: 最後にレビュー画面で「IAM リソースが作成される場合があることを承認」にチェックを入れて「送信」をクリック!
- 作成されたリソースの確認
作成完了(CREATE_COMPLETE)まで約10分ほど待ちます。完了したら「出力 (Outputs)」タブを確認しましょう。
詳細な設定情報
構築に必要な情報を整理しました。設定ファイルを編集する際に、この表を見ながら進めるとスムーズです。
| カテゴリ | 項目 | 設定値 / 確認方法 |
| サーバー | OS / ユーザー | Amazon Linux 2023 / ec2-user |
| 設定パス | /home/ec2-user/synapse_data/homeserver.yaml | |
| コンテナ名 | matrix_synapse | |
| データベース | エンジン | PostgreSQL |
| ユーザー名 | matrixadmin | |
| エンドポイント | [ステップ3の出力結果を確認] | |
| ストレージ | S3バケット名 | [ステップ3の出力結果を確認] |
| IAMロール | MatrixS3AccessRole | |
| アクセス | 管理者ユーザー | admin |
インフラが立ち上がったら、最後に「接続の設定」と「セキュリティの設定」を行います。
RDSの接続情報をコピーする
Dockerを動かすために、データベース(RDS)の住所=エンドポイントが必要です。
- RDSコンソールの「データベース」から、作成したインスタンスをクリックします。
- 「接続とセキュリティ」タブにあるエンドポイントの文字列をコピーして、メモ帳などに控えておきましょう。
例:matrix-db-verify.xxxxx.ap-xxxxxxxxx.rds.amazonaws.com
DNS設定(Route 53)でドメインを紐付ける
ロードバランサー(ALB)と、用意したドメインを合体させます。
- Route 53コンソールで対象のドメインを選択し、「レコードを作成」をクリック。
- 以下のように設定します:
- レコード名:
matrix - レコードタイプ:
Aレコード - エイリアス:
ONにする - トラフィックのルーティング先: 「Application and Classic Load Balancer」を選択し、先ほどCloudFormationで作ったALBを選びます。
- レコード名:
これで、ブラウザから自分のドメインでアクセスできるようになります!
セキュリティの要!IAMロールの作成
ここは最重要ステップです。サーバー(EC2)に**「デジタル身分証(IAMロール)」**を持たせます。
💡 なぜこれが必要なの?
普通、サーバーがS3(画像保存場所)にアクセスするにはパスワードが必要ですが、設定ファイルにパスワードを書き込むのは盗まれるリスクがあり危険です。 代わりに「身分証」をサーバーに持たせることで、パスワードなしで安全にS3を使えるようになります。これがAWSにおける最高レベルのセキュリティ対策です。
ロールの作成手順
- IAMコンソール > 「ロールを作成」をクリック。
- 信頼されたエンティティで「EC2」を選択して次へ。
- 許可ポリシーで以下の2つを検索してチェックを入れます。
AmazonS3FullAccessAmazonSSMManagedInstanceCore
- 名前を
MatrixS3AccessRoleとして作成します。
サーバーへのアタッチ
作成した「身分証」をサーバーに渡します。
- EC2コンソールで、Matrixサーバーのインスタンスにチェックを入れます。
- 「アクション」 > 「セキュリティ」 > 「IAMロールを変更」 をクリック。
- 先ほど作った
MatrixS3AccessRoleを選んで保存すれば完了です!
サーバー構築とS3連携 (最終設定)
いよいよ仕上げです。Session Managerでサーバーに接続して、設定を完了させましょう。
事前準備:パラメータの確認
作業をスムーズに進めるため、以下の値を手元に用意してください。
- S3バケット名 / RDSエンドポイント (ステップ3でメモしたもの)
- DBパスワード (自分で決めたもの)
- ドメイン名 (例:
matrix.xxxxx.com)
環境の初期化と設定ファイルの生成
まずは作業ディレクトリを作成し、初期設定ファイルを自動生成します。
# 1. 環境のリセットとディレクトリ作成
sudo docker rm -f matrix_synapse
mkdir -p /home/ec2-user/synapse_data
# 2. 初期設定ファイルの生成
sudo docker run -it --rm \
-v /home/ec2-user/synapse_data:/data \
-e SYNAPSE_SERVER_NAME=[サーバー名] \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
homeserver.yaml の編集
エディタ(nanoなど)で設定ファイルを開き、データベースとS3の連携設定を書き換えます。
sudo nano /home/ec2-user/synapse_data/homeserver.yaml
- データベース設定 (PostgreSQLへの変更)
デフォルトの sqlite3 の記述を削除し、以下に書き換えます。
database:
name: psycopg2
args:
user: matrixadmin
password: [DBパスワード]
database: matrixsynapse
host: [RDSエンドポイント]
cp_min: 5
cp_max: 10
- ストレージ設定
ファイルの一番最後に、以下の設定を追記してください。 (IAMロールを使っているため、アクセスキーの記載は不要です!)
media_storage_providers:
- module: s3_storage_provider.S3StorageProviderBackend
store_local: true
store_remote: true
store_direct: true
config:
bucket: [S3バケット名]
region_name: [リージョン名]
コンテナの起動と管理者作成
設定が完了したので、本番用コンテナを起動します。
# 1. コンテナの本番起動
sudo docker run -d \
--name matrix_synapse \
--restart unless-stopped \
-p 8008:8008 \
-v /home/ec2-user/synapse_data:/data \
matrixdotorg/synapse:latest
# 2. 管理者ユーザーの作成
sudo docker exec -it matrix_synapse register_new_matrix_user \
-c /data/homeserver.yaml http://localhost:8008 \
--admin --user admin --password [管理者用パスワード]
最終動作確認
すべてが正しく動いているかチェックしましょう!
- ブラウザ確認: http://app.element.io/ にアクセスして、JSONメッセージが表示されればOKです。
- アプリ(Element)でログイン:
- 「ホームサーバー」を自分のドメインに変更してログイン。
- 画像を送信してみて、AWSコンソールの S3バケット 内にファイルが保存されていれば構築成功です!
まとめ
今回は、AWS CloudFormationを活用して、コストを抑えつつセキュアに Matrix Synapseサーバーを立ち上げる方法 をご紹介しました。
最初は難しそうに見える手順も、一つひとつ整理していけば確実に構築できます。自分たちだけのコミュニケーション基盤を持つことで、運用の自由度もセキュリティも格段に向上します。
今後もMatrix関連の情報をお届けしていく予定ですので、次回もお楽しみに!
