お一人様misskeyサーバを立てた個人的記録
2024年2月20日追記
情報が頻繁に変わって更新が追いつかず、本記事の方法でつまづく場合があります。そういう時は、まず公式サイトの最新ドキュメントを読んでください。
2023年4月21日
あくまで「個人的にこうしたら成功した」という記録です。質問されてもお答えできませんので悪しからず。
クローズドmisskeyサーバ「こづか山荘」の管理人、小束弓月です。初めてmisskeyサーバを立てた時の記録を記事に仕立てました。
目標
misskeyをUbuntuサーバにインストールしWeb公開する
現環境
misskey2024.2.0
2023.12.22023.9.3 13.11.3
リリースノート https://misskey-hub.net/docs/releases.htmlUbuntu22.04
自宅x64マシン(4コア・メモリ16GB)
Conoha VPS 2GプランCloudflareを利用
静的コンテンツをキャッシュさせてサーバーの負荷を低減させる
DNSプロキシを使うと、公開されるIPアドレスがCloudflareのv4・v6アドレスになる
サーバの真のIPアドレスが露出しにくくなりDoS攻撃などを緩和できる
80/443番ポートを開放できるのがIPv6のみの環境(IPoE IPv6光回線など)でも、IPv4からアクセス可能になる(自宅v6アドレス宛てに変換してくれる)
参考:
はじめの作業
ファイアウォール/ufw設定
IPv6も利用する設定。
Conohaの場合、VPSネットワーク設定でWebポートを開けると80・443の他に20・21も開くので、意図的に閉める。
セキュリティグループ機能で通信ポートを細かく制御できるようになりました。
https://www.conoha.jp/vps/function/port/
$ sudo ufw default deny
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
$ sudo ufw status
Status: active
To Action From
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
$ sudo systemctl enable ufw
$ sudo ufw reload
パッケージのインストール
メモリアロケータ「jemalloc2」含む
$ sudo apt install build-essential curl ffmpeg lsb_release gnupg2 ca-certificates ubuntu-keyring libjemalloc2
PostgreSQLインストール
PostgreSQL 15.x以上
$ wget https://salsa.debian.org/postgresql/postgresql-common/raw/master/pgdg/apt.postgresql.org.sh
$ chmod 764 ./apt.postgresql.org.sh
$ sudo sh apt.postgresql.org.sh -i -v 15
$ psql --version
psql (PostgreSQL) 15.2 (Ubuntu 15.2-1.pgdg22.04+1)
PostgreSQL のデータベースとユーザを作成する
$ sudo -u postgres psql
postgres=# CREATE ROLE misskey LOGIN CREATEDB PASSWORD '<yourpassword>';
postgres=# CREATE DATABASE mk1 OWNER misskey;
postgres=# exit
Node.jsインストール
Node.js 20.10.x以上(misskey 2023.12.0以降) Node.js 20.x以上
$ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
$ NODE_MAJOR=20; echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
$ sudo apt update
$ sudo apt install nodejs
$ node -v
v20.10.0
$ sudo corepack enable
Redisインストール
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.2 LTS
Release: 22.04
Codename: jammy
$ curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb jammy main
$ sudo apt update
$ sudo apt install redis
$ redis-server -v
Redis server v=7.2.4 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=xxxxxxxxxxxxxxxx
$ sudo systemctl enable redis-server
$ sudo systemctl start redis-server
nginxインストール
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
> | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid nginx signing key <signing-key@nginx.com>
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
> http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
> | sudo tee /etc/apt/sources.list.d/nginx.list
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu jammy nginx
$ echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
> | sudo tee /etc/apt/preferences.d/99nginx
Package: *
Pin: origin nginx.org
Pin: release o=nginx
Pin-Priority: 900
$ sudo apt update
$ sudo apt install nginx
systemctlで状態を確認
$ sudo systemctl status nginx
もしactiveでなければ起動+自動起動を有効化。
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
動作を確認
$ curl http://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
・・・・・
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Let's Encrypt SSL証明書
<<~>>内にCloudflareに登録したメールアドレスとAPI Keyを書く。
$ sudo apt install certbot python3-certbot-dns-cloudflare
$ sudo mkdir /etc/cloudflare
$ sudo vi /etc/cloudflare/cloudflare.ini
dns_cloudflare_email = <<yourmail@example.tld>>
dns_cloudflare_api_key = <<your key>>
$ sudo chmod 600 /etc/cloudflare/cloudflare.ini
$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare/cloudflare.ini --dns-cloudflare-propagation-seconds 60 --server https://acme-v02.api.letsencrypt.org/directory -d <<yourdomain.tld>> -d <<*.yourdomain.tld>>
misskeyのインストール
misskey専用ユーザ作成
$ sudo adduser --disabled-password --disabled-login misskey
$ sudo su - misskey
Misskeyのインストール
$ git clone -b master https://github.com/misskey-dev/misskey.git --recurse-submodules
$ cd misskey
$ git checkout master
pnpmで必要なnpmパッケージをインストール。
$ NODE_ENV=production pnpm install --frozen-lockfile
設定ファイルの作成をする。example.ymlをコピーして作成して編集。
$ cp .config/example.yml .config/default.yml
$ vi .config/default.yml
【default.yml】<<~>>内が変更点
# Misskey configuration
# https://github.com/misskey-dev/misskey/blob/develop/.config/example.yml
url: <<https://yourdomain.example.tld/>>
port: 3000
db:
host: localhost
port: 5432
db: <<mk1>>
user: <<misskey>>
pass: <<yourdbpassword>>
dbReplications: false
redis:
host: localhost
port: 6379
id: 'aid'
proxyBypassHosts:
- api.deepl.com
- api-free.deepl.com
- www.recaptcha.net
- hcaptcha.com
- challenges.cloudflare.com
proxyRemoteFiles: true
signToActivityPubGet: true
そしてビルド。成功したらユーザ「misskey」からログアウト。
$ NODE_ENV=production pnpm run build
$ pnpm run init
$ exit
nginxの設定
$ sudo vi /etc/nginx/conf.d/misskey.conf
【misskey.conf】<<~>>内が変更点
# For WebSocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off;
server {
listen 80;
listen [::]:80;
server_name <<yourdomain.example.tld>>;
# For SSL domain validation
root /var/www/html;
location /.well-known/acme-challenge/ { allow all; }
location /.well-known/pki-validation/ { allow all; }
location / { return 301 https://$server_name$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name <<yourdomain.example.tld>>;
ssl_session_timeout 1d;
ssl_session_cache shared:ssl_session_cache:10m;
ssl_session_tickets off;
# To use Let's Encrypt certificate
ssl_certificate /etc/letsencrypt/live/<<example.tld>>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<<example.tld>>/privkey.pem;
# To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
# SSL protocol settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
# Change to your upload limit
client_max_body_size 80m;
# Proxy to Node
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_redirect off;
# If it's behind another reverse proxy or CDN, remove the following.
# 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 https;
# For WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Cache settings
proxy_cache cache1;
proxy_cache_lock on;
proxy_cache_use_stale updating;
proxy_force_ranges on;
add_header X-Cache $upstream_cache_status;
}
}
設定をテストして再起動
sudo nginx -t
$ sudo systemctl restart nginx
misskeyを起動
$ sudo su - misskey
$ cd misskey
$ NODE_ENV=production pnpm run start
Now listening on port 3000 on http://<your url>
と表示されたらブラウザからURLにアクセスする。Misskeyのウェルカムページが表示される。
Misskeyのデーモンを作成(自動起動)
いったんCtrl+Cでプロセスをキルし、ユーザ「misskey」から退出。
$ exit
「/etc/systemd/system/misskey.service」を作成する。
$ sudo vi /etc/systemd/system/misskey.service
次の内容を貼り付け、保存する。
うまくいかない場合は、npmの絶対パスをwhichコマンドなどで調べる(/usr/local/bin/npmなど)。
[Unit]
Description=Misskey daemon
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
Environment="LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
TimeoutSec=60
StandardOutput=journal
StandardError=journal
SyslogIdentifier=misskey
Restart=always
[Install]
WantedBy=multi-user.target
systemdを設定し、misskeyデーモンを開始。
$ sudo systemctl daemon-reload
$ sudo systemctl enable misskey
$ sudo systemctl start misskey
systemctlでデーモンの状態を確認。起動に少し時間がかかる場合も。
$ systemctl status misskey
activeならOK。
追加の設定
プッシュ通知の設定
npx web-push generate-vapid-keys
Summaly Proxyについて
2024.3.1
Summalyとはmisskeyサーバの機能の一つで、URLのプレビューに必要なサムネ画像などの情報を取得してクライアント(ブラウザやPWAアプリ)に渡す。
ただし、この時サーバの本当のIPアドレスが通信相手のログに残ってしまう。悪意のある相手にIPアドレスが知れた場合、DDoS攻撃などの標的になる可能性がある。
それを防ぐため、自ネットワーク外にあるサーバにSummalyを代行させて矢面に立ってもらいましょう、というのがSummaly Proxy。
(大手サーバなら負荷分散の意味もあるかも)
Summaly Proxyならmisskey.io提供の「summaly.arkjp.net」があるよという記述も多いが、こちら現在運用されていないとのこと。
https://github.com/misskey-dev/misskey/issues/12035
有志の方がSummaly proxyサーバを公開している。
もしくは自力でSummaly Proxyサーバを立てる。
サーバでリンク先の「Usage / Run the server」以下を実行すればひとまず動くので「http://localhost:3000/?url="プレビュー対象URL"」で動作を確認。運用するならmisskeyサーバと同様にnginxとLet's encryptを設定しhttps通信出来るように。
Proxyサーバ
外からの防御壁という意味では、汎用のproxyサーバを自前で立てるという手段もある。squidならドキュメントや事例紹介も豊富で、認証やファイアウォールを設定し自分専用に出来る。
default.ymlの「Other Configration」以下にproxyサーバの項目がある。
# Proxy for HTTP/HTTPS
# proxy: http://127.0.0.1:3128
上述の2行目をコメントアウトしてプロキシサーバのアドレス・ポートを指定しmisskeyをrestartすると、misskeyサーバから外部への通信がプロキシサーバを経由するようになる。
Cloudflare turnstile
BOTアクセスを防ぐCAPTCHA認証ツール。簡単に設定できて無料。
PostgreSQL
デフォルトのままではメモリ使用量が少なくパフォーマンスが低いので、サーバのメモリ搭載量に応じた設定にするとより快適になる。
ただし設定値を誤ると逆効果なので、よく調べて調整する。
misskeyのアップデート
サービスを停止しておく(作業中はmisskeyは利用できない)。
sudo systemctl stop misskey
sudo su - misskey
cd misskey
git checkout master
git pull
NODE_ENV=production pnpm install --frozen-lockfile
pnpm run clean
NODE_ENV=production pnpm run build
pnpm run migrate
exit
アップデートが終わり次第、Misskeyプロセスを再起動
sudo systemctl start misskey