以前から
X や
買収や
そういった
Fediverse は、
ActivityPub を
これが
Fediverse を
かくして、
※ ↓ が
技術選定
ソフトウェアを 使うか
どのFediverse の
その上で、
ActivityPub を
他にも
サーバを 使うか
どのMastodon の
肝心の
Vultr は
Mastodon に
OS を 使うか
どのMastodon の
本来、
それにも
とは
料金
肝心のVultr で
画像等の
特に、
構築方 法
Mastodon の早速 Mastodon を
まずは
ssh root@123.456.78.90
Vultr から
passwd
次に、
exit
ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-copy-id -i ~/.ssh/id_ed25519_vultr.pub root@123.456.78.90
これで、
必要に.ssh/config
を
Host vultr Hostname 123.456.78.90 User root # 後で mastodon に変更する Port 22 IdentityFile ~/.ssh/id_ed25519_vultr
上記の
ssh vultr
Vultr の
まずは、
free
total used free shared buff/cache availableMem: 2013236 258740 1732296 828 162000 1754496Swap: 6451196 0 6451196
ありが
次に、
uname -r6.6.42-1-lts
pacman -Syu
reboot
uname -r6.6.45-1-lts
インスタンスの
インストール済みの
pacman -Q
acl 2.3.2-1archlinux-keyring 20240709-1argon2 20190702-6attr 2.5.2-1audit 4.0.1-3autoconf 2.72-1automake 1.17-1base 3-2base-devel 1-1bash 5.2.032-1bind 9.20.0-1binutils 2.43+r4+g7999dae6961-1bison 3.8.2-6brotli 1.1.0-2bzip2 1.0.8-6ca-certificates 20240618-1ca-certificates-mozilla 3.103-1ca-certificates-utils 20240618-1cdrtools 3.02a09-6cloud-guest-utils 0.33-2cloud-image-utils 0.33-2cloud-init 24.1-2cloud-utils 0.33-2coreutils 9.5-1cracklib 2.10.2-1cronie 1.7.2-1cryptsetup 2.7.4-1curl 8.9.1-2db5.3 5.3.28-5dbus 1.14.10-2dbus-broker 36-4dbus-broker-units 36-4dbus-units 36-4debugedit 5.0-6device-mapper 2.03.25-2dhclient 4.4.3.P1-3diffutils 3.10-1ding-libs 0.6.2-2dnssec-anchors 20190629-4duktape 2.7.0-7e2fsprogs 1.47.1-4efibootmgr 18-3efivar 39-1ethtool 1:6.9-1expat 2.6.2-1expect 5.45.4-5fakeroot 1.35-1file 5.45-1filesystem 2024.04.07-1findutils 4.10.0-1flex 2.6.4-5fuse-common 3.16.2-1fuse3 3.16.2-1gawk 5.3.0-1gc 8.2.6-1gcc 14.2.1+r32+geccf707e5ce-1gcc-libs 14.2.1+r32+geccf707e5ce-1gdbm 1.24-1gettext 0.22.5-1git 2.46.0-1glib2 2.80.4-1glibc 2.40+r16+gaa533d58ff-2gmp 6.3.0-2gnu-netcat 0.7.1-10gnupg 2.4.5-4gnutls 3.8.6-1gpgme 1.23.2-6gpm 1.20.7.r38.ge82d1a6-6gptfdisk 1.0.10-1grep 3.11-1groff 1.23.0-6grub 2:2.12-2gssproxy 0.9.2-1guile 3.0.10-1gzip 1.13-4hwdata 0.385-1iana-etc 20240612-1icu 75.1-1iotop 0.6-11iproute2 6.10.0-2iptables-nft 1:1.8.10-2iputils 20240117-1jansson 2.14-4jemalloc 1:5.3.0-4jq 1.7.1-2json-c 0.17-2kbd 2.6.4-1keyutils 1.6.3-3kmod 32-1krb5 1.21.3-1less 1:661-1libaio 0.3.113-3libarchive 3.7.4-1libassuan 3.0.0-1libbpf 1.4.3-1libcap 2.70-1libcap-ng 0.8.5-2libdaemon 0.14-6libedit 20240517_3.1-1libelf 0.191-4libevent 2.1.12-4libffi 3.4.6-1libgcrypt 1.11.0-2libgpg-error 1.50-1libidn2 2.3.7-1libisl 0.26-2libksba 1.6.7-1libldap 2.6.8-1libmaxminddb 1.10.0-1libmm-glib 1.22.0-1libmnl 1.0.5-2libmpc 1.3.1-2libndp 1.9-1libnetfilter_conntrack 1.0.9-2libnewt 0.52.24-2libnfnetlink 1.0.2-2libnftnl 1.2.7-1libnghttp2 1.62.1-1libnghttp3 1.4.0-1libnl 3.10.0-1libnm 1.48.8-1libnsl 2.0.1-1libp11-kit 0.25.5-1libpcap 1.10.4-1libpgm 5.3.128-3libpipeline 1.5.7-2libpsl 0.21.5-2libpwquality 1.4.5-5libsasl 2.1.28-4libseccomp 2.5.5-3libsecret 0.21.4-1libsodium 1.0.20-1libssh2 1.11.0-1libsysprof-capture 46.0-4libtasn1 4.19.0-2libteam 1.32-2libtirpc 1.3.5-1libtool 2.5.1-2libunistring 1.2-1liburcu 0.14.0-2liburing 2.6-2libusb 1.0.27-1libutempter 1.2.1-4libuv 1.48.0-2libverto 0.3.2-5libxcrypt 4.4.36-2libxml2 2.13.3-1libyaml 0.2.5-3licenses 20240728-1linux-api-headers 6.10-1linux-firmware 20240703.e94a2a3b-1linux-firmware-whence 20240703.e94a2a3b-1linux-lts 6.6.45-1linux-lts-headers 6.6.45-1lmdb 0.9.32-1lsof 4.99.3-2lvm2 2.03.25-2lz4 1:1.10.0-2m4 1.4.19-3make 4.4.1-2man-db 2.12.1-1mkinitcpio 39.2-2mkinitcpio-busybox 1.36.1-1mobile-broadband-provider-info 20240407-1mpdecimal 4.0.0-2mpfr 4.2.1-4nano 8.1-1ncurses 6.5-3net-tools 2.10-2nettle 3.10-1networkmanager 1.48.8-1nfs-utils 2.6.4-1nfsidmap 2.6.4-1nftables 1:1.1.0-2npth 1.7-1nspr 4.35-3nss 3.103-1numactl 2.0.18-1oniguruma 6.9.9-1openssh 9.8p1-1openssl 3.3.1-1p11-kit 0.25.5-1pacman 6.1.0-3pacman-mirrorlist 20240717-1pacutils 0.14.0-1pahole 1:1.27-2pam 1.6.1-2pambase 20230918-1parted 3.6-2patch 2.7.6-10pciutils 3.13.0-1pcre 8.45-4pcre2 10.44-1pcsclite 2.3.0-1perl 5.38.2-2perl-clone 0.46-3perl-data-dump 1.25-5perl-encode-locale 1.05-12perl-error 0.17029-6perl-file-listing 6.16-3perl-html-parser 3.82-1perl-html-tagset 3.24-1perl-http-cookiejar 0.014-2perl-http-cookies 6.11-1perl-http-daemon 6.16-3perl-http-date 6.06-2perl-http-message 6.46-1perl-http-negotiate 6.01-13perl-io-html 1.004-5perl-io-socket-ssl 2.085-1perl-json 4.10-2perl-libwww 6.77-1perl-log-message 0.08-10perl-log-message-simple 0.10-10perl-lwp-mediatypes 6.04-5perl-lwp-protocol-https 6.14-1perl-mailtools 2.21-8perl-net-http 6.23-3perl-net-ssleay 1.94-1perl-term-readline-gnu 1.46-3perl-term-ui 0.50-4perl-timedate 2.33-6perl-try-tiny 0.31-4perl-uri 5.28-1perl-www-robotrules 6.02-13pinentry 1.3.1-5pkgconf 2.1.1-1polkit 125-1popt 1.19-1procps-ng 4.0.4-3psmisc 23.7-1python 3.12.4-1python-attrs 23.2.0-3python-cffi 1.16.0-2python-charset-normalizer 3.3.2-2python-configobj 5.0.8-5python-cryptography 42.0.6-1python-filelock 3.13.3-2python-idna 3.7-1python-jinja 1:3.1.4-1python-jsonpatch 1.33-2python-jsonpointer 3.0.0-1python-jsonschema 4.23.0-1python-jsonschema-specifications 2023.12.1-2python-markupsafe 2.1.5-2python-netifaces 0.11.0-5python-oauthlib 3.2.2-3python-packaging 24.1-1python-pip 24.2-1python-pycparser 2.22-2python-pyrsistent 0.19.3-4python-pyserial 3.5-6python-referencing 0.35.1-1python-requests 2.32.3-1python-rpds-py 0.19.0-1python-six 1.16.0-9python-typing_extensions 4.12.2-1python-urllib3 1.26.19-1python-wheel 0.44.0-1python-yaml 6.0.1-4qemu-img 9.0.2-1readline 8.2.013-1reflector 2023-2rpcbind 1.2.7-1run-parts 5.17-1screen 4.9.1-2sed 4.9-3shadow 4.16.0-1slang 2.3.3-3sqlite 3.46.0-1sudo 1.9.15.p5-2systemd 256.4-1systemd-libs 256.4-1systemd-sysvcompat 256.4-1tar 1.35-2tcl 8.6.14-4texinfo 7.1-2thin-provisioning-tools 1.1.0-1tpm2-tss 4.0.1-1trizen 1:1.68-1tzdata 2024a-2ufw 0.36.2-4unzip 6.0-21util-linux 2.40.2-1util-linux-libs 2.40.2-1vim 9.1.0672-1vim-runtime 9.1.0672-1watchdog 5.16-2wget 1.24.5-3which 2.21-6wpa_supplicant 2:2.11-2xz 5.6.2-1zeromq 4.3.5-2zip 3.0-11zlib 1:1.3.1-2zstd 1.5.6-1
Arch Linux と
次に
デフォルトの
dateTue Aug 13 06:11:30 AM UTC 2024
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
dateTue Aug 13 03:12:01 PM JST 2024
次にen_US
がja_JP
が/etc/locale.gen
echo $LANGen_US.UTF-8
locale -aCC.utf8en_US.utf8POSIX
vim /etc/locale.gen
ja_JP.UTF-8 UTF-8
locale-gen
で
locale-gen
locale -aCC.utf8en_US.utf8ja_JP.utf8POSIX
locale -a
をja_JP
が
次に、/etc/locale.conf
を
vim /etc/locale.conf
# LANG=en_US.UTF-8LANG=ja_JP.UTF-8
最後に
reboot
一応、
echo $LANGja_JP.UTF-8
root に
systemd-homedと
useradd -mg wheel mastodon
passwd mastodon
wheel グループの/etc/sudoers
EDITOR=vim visudo
sudo
をsudo
コマンドを
# %wheel ALL=(ALL:ALL) NOPASSWD: ALL%wheel ALL=(ALL:ALL) NOPASSWD: ALL
次は
vim /etc/ssh/sshd_config
PermitRootLogin no
とPasswordAuthentication no
PermitRootLogin yesPermitRootLogin no
PasswordAuthentication yesPasswordAuthentication no
最後に
systemctl restart sshd
次に
pacman -S fail2ban
fail2ban のjail.conf
にjail.local
と
cp /etc/fail2ban/jail.{conf,local}
vim /etc/fail2ban/jail.local
以下の
[sshd]enabled = truemode = aggressive
以下の
systemctl enable --now fail2ban
現在 fail2ban が
fail2ban-client status
Status|- Number of jail: 1`- Jail list: sshd
SSH デーモンに
インスタンス作成から
fail2ban-client status sshd
Status for the jail: sshd|- Filter| |- Currently failed: 4| |- Total failed: 8110| - Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd- Actions |- Currently banned: 1 |- Total banned: 811 - Banned IP list: xxx.xxx.xxx.xxx
要点だけ確認すると、
IP アドレスが
fail2ban では
次に
Vultr で
nft list tables
table ip filtertable ip6 filter
iptables-nft は/etc/nftables.conf
を
vim /etc/nftables.conf
設定の
#!/usr/sbin/nft -f# vim:set ts=2 sw=2 et:
# 現在の全ルールセット(テーブル、チェーン、ルール)を削除flush ruleset
table inet filter { # 受信パケットに対して適用される設定 chain input { # 優先度は 0 であり、デフォルトのポリシーは drop # これは、受信パケットがこのチェーンに到達した場合、ルールに一致しない限り、全てのパケットを拒否することを意味する type filter hook input priority 0; policy drop;
# ループバックアドレスへのアクセスをローカルのループバックインターフェースからのものだけに制限し、それ以外のインターフェースからのアクセスを防ぐ iif "lo" accept ip daddr 127.0.0.0/8 iif != "lo" reject
# すでに確立されたコネクションや既存のコネクションに関連するパケットを許可する # これにより、正常な通信の流れが維持され、セッションが途切れたり中断されたりすることが防ぐ ct state established,related accept
# ウェブサーバが HTTP および HTTPS のリクエストを受け入れられるようにする tcp dport 80 accept tcp dport 443 accept
# 特定のアプリケーションやプロトコルが UDP ポート 443 を使用する場合にそのトラフィックを許可する udp dport 443 accept
# リモートからの SSH 接続要求を受け入れる tcp dport 22 ct state new accept
# ネットワーク接続の確認やトラブルシューティングのために、外部からの ping 要求を受け入れる icmp type echo-request accept
# ネットワーク上の障害やエラーを診断するのに役立つ情報を保存する # Allow destination unreachable messages, especially code 4 (fragmentation required) is required or PMTUD breaks icmp type destination-unreachable accept
# nftables でパケットがこのルールに一致した場合、nftables denied: というプレフィックス付きでログが記録され、1 分間に最大 5 回のログを生成する limit rate 5/minute log prefix "nftables denied: " level debug
# 上記で設定したルールに沿わない場合は接続を拒否する reject }
chain forward { type filter hook forward priority 0; policy drop; }
chain output { type filter hook output priority 0; policy accept; }}
以下の
systemctl enable --now nftables
nftables の
nft -c -f /etc/nftables.conf
問題なければ、
nft list ruleset
先ほど
次に
dmesg | grep "nftables denied:"
[631369.913820] nftables denied: IN=xxx OUT=xxx MAC=xxx SRC=xxx DST=xxx LEN=xxx TOS=xxx PREC=xxx TTL=xxx ID=xxx PROTO=xxx SPT=xxx DPT=xxx WINDOW=xxx RES=xxx SYN URGP=xxx
上記のような
これで
次に
pacman -S imagemagick ffmpeg postgresql postgresql-libs redis yaml-cpp libxml2 libxslt protobuf pkg-config jemalloc nginx certbot certbot-nginx libidn
以降の
su - mastodon
Arch Linux に
AUR の
git clone https://aur.archlinux.org/paru.git
cd paru
less PKGBUILD
makepkg -si
cd ..
rm -rf paru
sudo pacman -Rs rust
paru の
続いて、
paru -S rbenv ruby-build
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.2.3
rbenv init
echo 'eval "$(rbenv init - bash)"' >> ~/.bash_profile
source ~/.bash_profile
rbenv global 3.2.3
gem install bundler --no-document
Ruby の
次に
sudo -iu postgres
postgres ユーザに$LANG
にはja_JP.UTF-8
が
initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data'
続いて、
以下の
以下は
# DB Version: 16# OS Type: linux# DB Type: web# Total Memory (RAM): 2 GB# CPUs num: 1# Connections num: 100# Data Storage: ssd
max_connections = 100shared_buffers = 512MBeffective_cache_size = 1536MBmaintenance_work_mem = 128MBcheckpoint_completion_target = 0.9wal_buffers = 16MBdefault_statistics_target = 100random_page_cost = 1.1effective_io_concurrency = 200work_mem = 2621kBhuge_pages = offmin_wal_size = 1GBmax_wal_size = 4GB
これをpostgresql.conf
に
vim /var/lib/postgres/data/postgresql.conf
systemctl enable --now postgresql
su - postgres
psql
CREATE USER mastodon CREATEDB;
\q
PostgreSQL では、
これに
exit
systemctl enable --now redis
次に、
再度 mastodon ユーザに
もちろん、
su - mastodon
curl https://get.volta.sh | bash
source ~/.bashrc
volta install node
# 現在は yarn のバージョン 4 をインストールする必要がある点に注意volta install yarn@1
そして、
git clone https://github.com/mastodon/mastodon.git live && cd live
# 最新の安定版タグにチェックアウトgit checkout $(git tag -l | grep '^v[0-9.]*$' | sort -V | tail -n 1)
次に
# Gemfile に指定されている依存関係が読み取り専用でインストールされ、開発環境用のオプションは適用されないbundle config deployment 'true'
# development と test グループの依存関係を除外するbundle config without 'development test'
# Gemfile に記述された必要な Gem をインストールする# このとき、システムの利用可能な CPU コア数に基づいて並列インストールを行うbundle install -j$(getconf _NPROCESSORS_ONLN)
# JavaScript 依存パッケージをインストールする# yarn.lock ファイルは変更しないyarn install --pure-lockfile
Mastodon の
[ { // すべてのヘッダーを許可する "AllowedHeaders": [ "*" ], // HTTP ヘッダのうち、GET と HEAD のみ許可する "AllowedMethods": [ "GET", "HEAD" ], // どのオリジンからのリクエストも許可する "AllowedOrigins": [ "*" ], // ETag ヘッダのみクライアント側に公開する "ExposeHeaders": [ "ETag" ], // プリフライトリクエストの結果を 3,000 秒キャッシュする "MaxAgeSeconds": 3000 }]
次に
RAILS_ENV=production bundle exec rake mastodon:setup
# ドメイン名を指定するDomain name: mastodon.kkhys.me
# シングルユーザーモードにするかどうか# 今回はおひとり様インスタンスなので YesDo you want to enable single user mode? (y/N) y
# Docker を使うかどうかAre you using Docker to run Mastodon? (Y/n) n
# PostgreSQL の設定PostgreSQL host: /var/run/postgresqlPostgreSQL port: 5432Name of PostgreSQL database: mastodon_productionName of PostgreSQL user: mastodonPassword of PostgreSQL user:
# Redis の設定Redis host: localhostRedis port: 6379Redis password:
# ファイルストレージの設定# 選択肢に R2 がないので、後から変更するProvider Amazon S3S3 bucket name: files-mastodon-kkhys-meS3 region: autoS3 hostname: files.mastodon.kkhys.meS3 access key: xxxS3 secret key: xxxDo you want to access the uploaded files from your own domain? YesDomain for uploaded files: files.mastodon.kkhys.me
# SMTP サーバの設定# 今回は Gmail を使用したDo you want to send e-mails from localhost? NoSMTP server: smtp.gmail.comSMTP port: 587SMTP username: xxx@gmail.comSMTP password: xxxSMTP authentication: plainSMTP OpenSSL verify mode: noneEnable STARTTLS: alwaysE-mail address to send e-mails "from": Mastodon <xxx@gmail.com>Send a test e-mail with this configuration right now? YesSend test e-mail to: xxx
# アップデート情報などをメール送信しても良いかどうか# Yes がおすすめDo you want Mastodon to periodically check for important updates and notify you? (Recommended) Yes
# .env.production に保存しても良いかどうかSave configuration? Yes
# データベースのセットアップを初期化しても良いかどうかPrepare the database now? Yes
# アセットのコンパイルをしても良いかどうかCompile the assets now? (Y/n) Yes
# 管理者ユーザを作成するかどうか# ここで作成しておいた方が楽Do you want to create an admin user straight away? YesUsername: xxxE-mail: xxx
# 管理者ユーザのパスワードが出力されるのでメモしておくYou can login with the password: xxx
先ほど
vim /home/mastodon/live/.env.production
以下の
S3_ENDPOINT=https://xxx.r2.cloudflarestorage.com/S3_PERMISSION=private
Mastodon の
続いて、
SSL/TLS 証明書は
# 管理者ユーザに切り替えsudo su -
# Certbot を使用して、指定されたドメインの SSL/TLS 証明書を取得する# --nginx オプションは、Nginx サーバの設定を自動的に検出し、証明書の取得を簡素化する# ここでは、Nginx が既にインストールされていることが前提certbot certonly --nginx -d mastodon.kkhys.me
# Nginx の設定ディレクトリを作成する# sites-available ディレクトリは、サーバの設定ファイルを保存するための場所# sites-enabled ディレクトリは、現在有効なサイトの設定ファイルがリンクされている場所mkdir -p /etc/nginx/sites-{available,enabled} /etc/nginx/conf.d
# 初期状態を確認するために出力するcat /etc/nginx/nginx.conf
初期状態の
#user http;worker_processes 1;
#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;
#pid logs/nginx.pid;
events { worker_connections 1024;}
http { include mime.types; default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on; #tcp_nopush on;
#keepalive_timeout 0; keepalive_timeout 65;
#gzip on;
server { listen 80; server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { root /usr/share/nginx/html; index index.html index.htm; }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }
# proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #}
# deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
# another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias;
# location / { # root html; # index index.html index.htm; # } #}
# HTTPS server # #server { # listen 443 ssl; # server_name localhost;
# ssl_certificate cert.pem; # ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on;
# location / { # root html; # index index.html index.htm; # } #}
}
これを
vim /etc/nginx/nginx.conf
user http;worker_processes auto;worker_cpu_affinity auto;
events { multi_accept on; worker_connections 1024;}
http { charset utf-8; sendfile on; tcp_nopush on; tcp_nodelay on; server_tokens off; log_not_found off; types_hash_max_size 4096; client_max_body_size 16M;
# MIME include mime.types; default_type application/octet-stream;
# logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log warn;
# load configs include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;}
次に
# Mastodon のための Nginx 設定ファイルを、Nginx の設定用ディレクトリにコピーするcp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
# sites-available にある Mastodon の設定ファイルへのシンボリックリンクを作成するln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/
vim /etc/nginx/sites-available/mastodon
デフォルトでは
map $http_upgrade $connection_upgrade { default upgrade; '' close;}
upstream backend { server 127.0.0.1:3000 fail_timeout=0;}
upstream streaming { # Instruct nginx to send connections to the server with the least number of connections # to ensure load is distributed evenly. least_conn;
server 127.0.0.1:4000 fail_timeout=0; # Uncomment these lines for load-balancing multiple instances of streaming for scaling, # this assumes your running the streaming server on ports 4000, 4001, and 4002: # server 127.0.0.1:4001 fail_timeout=0; # server 127.0.0.1:4002 fail_timeout=0;}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
server { listen 80; listen [::]:80; server_name example.com; server_name mastodon.kkhys.me; root /home/mastodon/live/public; location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; }}
server { listen 443 ssl http2; listen 443 ssl; listen [::]:443 ssl http2; listen [::]:443 ssl; http2 on;
server_name example.com; server_name mastodon.kkhys.me;
ssl_protocols TLSv1.2 TLSv1.3;
# You can use https://ssl-config.mozilla.org/ to generate your cipher set. # We recommend their "Intermediate" level. 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:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off;
# Uncomment these lines once you acquire a certificate: # ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate /etc/letsencrypt/live/mastodon.kkhys.me/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/mastodon.kkhys.me/privkey.pem;
keepalive_timeout 70; sendfile on; client_max_body_size 99m;
root /home/mastodon/live/public;
gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon;
location / { try_files $uri @proxy; }
# If Docker is used for deployment and Rails serves static files, # then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`. location = /sw.js { add_header Cache-Control "public, max-age=604800, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/assets/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/avatars/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/emoji/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/headers/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/packs/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/shortcuts/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/sounds/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri =404; }
location ~ ^/system/ { add_header Cache-Control "public, max-age=2419200, immutable"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; add_header X-Content-Type-Options nosniff; add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; try_files $uri =404; }
location ^~ /api/v1/streaming { proxy_set_header Host $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 Proxy "";
proxy_pass http://streaming; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
tcp_nodelay on; }
location @proxy { proxy_set_header Host $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 Proxy ""; proxy_pass_header Server;
proxy_pass http://backend; proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
proxy_cache CACHE; proxy_cache_valid 200 7d; proxy_cache_valid 410 24h; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; add_header X-Cached $upstream_cache_status;
tcp_nodelay on; }
error_page 404 500 501 502 503 504 /500.html;}
Nginx の
chmod 701 /home/mastodon
# Nginx の設定ファイルにエラーがないかをテストするnginx -t
killall nginx
systemctl enable --now nginx
最後に
# Mastodon の Systemd サービスファイルをコピーする# これにより、Mastodon がシステムのサービスとして管理されるようになるcp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
# Systemd に新しく追加されたサービスファイルを認識させるsystemctl daemon-reload
# Mastodon 関連の 3 つのサービスをシステム起動時に自動的に開始するように設定し、即座にこれらのサービスを起動するsystemctl enable --now mastodon-{web,sidekiq,streaming}
これで
忙しい
ほかに やっておいた 方が 良いこと
その libvips に 切り替える
ImageMagick からv4.3.0で
本来なら
まずは
sudo pacman -S libvips
libvips の
sudo pacman -S libheif imagemagick openslide poppler-glib
次に.env.production
を
MASTODON_USE_LIBVIPS=true
最後に
sudo systemctl restart mastodon-{web,sidekiq,streaming}
検索機能の 追加
全文Mastodon では、
以下の
# admin ユーザで実行するpacman -S jdk17-openjdk
# ログアウトして mastodon ユーザに戻るexit
paru -S elasticsearch7
Mastodon では
Elasticsearch を
vim /home/mastodon/live/.env.production
ES_ENABLED=trueES_HOST=localhostES_PORT=9200ES_PRESET=single_node_cluster
次に
vim /etc/elasticsearch/elasticsearch.yml
# Elasticsearch のセキュリティ機能(認証とアクセス制御)を有効化する xpack.security.enabled: true
# Elasticsearch を単一ノード構成で動作させる discovery.type: single-node
続いて、
パスワードを
ただ、
# Elasticsearch サービスを起動し、サーバ再起動後も自動で起動するようにするsystemctl enable --now elasticsearch
# Elasticsearch用のキーストアを作成する/usr/share/elasticsearch/bin/elasticsearch-keystore create
# Elasticsearch の内蔵ユーザ(システムユーザ)のパスワードを自動生成する/usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
Changed password for user apm_systemPASSWORD apm_system = xxx
Changed password for user kibana_systemPASSWORD kibana_system = xxx
Changed password for user kibanaPASSWORD kibana = xxx
Changed password for user logstash_systemPASSWORD logstash_system = xxx
Changed password for user beats_systemPASSWORD beats_system = xxx
Changed password for user remote_monitoring_userPASSWORD remote_monitoring_user = xxx
Changed password for user elasticPASSWORD elastic = xxx
次に
# mastodon_full_access という名前のロールを作成するcurl -X POST -u elastic:xxx "localhost:9200/_security/role/mastodon_full_access?pretty" -H 'Content-Type: application/json' -d'{ // Elasticsearch クラスタの監視権限を付与する "cluster": ["monitor"], "indices": [{ "names": ["*"], "privileges": ["read", "monitor", "write", "manage"] }]}'
# mastodon というユーザを作成するcurl -X POST -u elastic:xxx "localhost:9200/_security/user/mastodon?pretty" -H 'Content-Type: application/json' -d'{ "password" : "xxx", // 先ほど作成した mastodon_full_access ロールをこのユーザに割り当てる "roles" : ["mastodon_full_access"]}'
な-u
を
Elasticsearch に
vim /home/mastodon/live/.env.production
ES_USER=mastodonES_PASS=xxx
Elasticsearch の
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
su - mastodon
cd live
RAILS_ENV=production bin/tootctl search deploy
tootctl search deploy
で
ここまでの
それを
適切な
2GB の
vim /etc/elasticsearch/jvm.options.d/ram.options
-Xms512m-Xmx512m
Elasticsearch サービスを
systemctl restart elasticsearch
curl -X GET -u elastic:xxx "localhost:9200/_nodes?pretty"
{ // ... "jvm" : { "mem" : { "heap_init_in_bytes" : 536870912, "heap_max_in_bytes" : 536870912 } } // ...}
上記のようになっていれば
次に、
Kuromoji の
Kuromoji を
まずは
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
Elasticsearch を
sudo systemctl restart elasticsearch
curl -X GET -u elastic:xxx "localhost:9200/_cat/plugins?v"
name component versionvultr analysis-kuromoji 7.17.18
問題なく
この
Mastodon では
curl -X GET -u elastic:xxx "localhost:9200/_cat/indices?v"
health status index uuid pri rep docs.count docs.deleted store.size pri.store.sizegreen open .geoip_databases xxx 1 0 38 0 36.7mb 36.7mbgreen open .security-7 xxx 1 0 9 0 35.1kb 35.1kbgreen open chewy_specifications xxx 1 0 5 0 19.3kb 19.3kbgreen open instances xxx 1 0 12 0 5.4kb 5.4kbgreen open statuses xxx 5 0 298 0 297.4kb 297.4kbgreen open accounts xxx 1 0 22 0 18.4kb 18.4kbgreen open public_statuses xxx 5 0 295 0 287.1kb 287.1kbgreen open tags xxx 1 0 22 0 7.2kb 7.2kb
Mastodon は
- statuses: 投稿の
検索に 使用 - accounts: ユーザアカウントの
検索に 使用 - public_statuses: 公開トゥートの
検索に 使用 - tags: ハッシュタグの
検索に 使用 - instances: 他の
Mastodon インスタンス情報の 検索や 管理に 使用
chewy に
以下の
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin remove analysis-kuromoji
あと、
ログインせずに
Mastodon は
ログローテーション
ログの
以下が
du -h -d1 /var/log
30M /var/log/nginx44K /var/log/letsencrypt4.0K /var/log/old1.5M /var/log/elasticsearch4.0K /var/log/gssproxy4.0K /var/log/private4.0K /var/log/audit1.2G /var/log/journal1.2G /var/log
ログファイルの
システムの
pacman -S logrotate
vim /etc/logrotate.conf
/etc/logrotate.conf
に
# ログファイルを毎日ローテーションするdaily
# 指定されたログファイルが存在しなくてもエラーを出さずに処理を続行するmissingok
# ローテーションによって保存される古いログファイルの数を指定するrotate 4
# ログファイルが 20MB 以上の場合にのみローテーションを実行するsize 20M
# ローテーション後に新しい(空の)ログファイルを作成するcreate
# ローテーションされたログファイルを圧縮するcompress
# ログファイルを圧縮するのを次回のローテーションまで遅延させるdelaycompress
# ログファイルが空の場合はローテーションを実行しないnotifempty
# ログローテーションで無視される拡張子のリストtabooext + .pacorig .pacnew .pacsave
# 追加設定ファイルを読み込んで使用するinclude /etc/logrotate.d
/etc/logrotate.d
ディレクトリ以下に
/var/log/nginx/*log { missingok notifempty create 640 http root sharedscripts compress postrotate test ! -r /run/nginx.pid || kill -USR1 `cat /run/nginx.pid` endscript}
logrotate
コマンドを/etc/logrotate.conf
logrotate -f /etc/logrotate.conf
journald の/etc/systemd/journald.conf
)で
vim /etc/systemd/journald.conf
[Journal]# ログを永続的に保存するStorage=persistent
# 最大ディスクスペースを 200MB に制限するSystemMaxUse=200M
# ログエントリの最大保持期間を 2 週間に設定するMaxRetentionSec=2weeks
システムログを
systemctl restart systemd-journald
最後に
du -h -d1 /var/log
4.2M /var/log/nginx44K /var/log/letsencrypt4.0K /var/log/old996K /var/log/elasticsearch4.0K /var/log/gssproxy4.0K /var/log/private4.0K /var/log/audit121M /var/log/journal152M /var/log
ログファイルの
自動更新
SSL 証明書のSSL 証明書には
まずは
systemctl edit --full --force certbot-renewal
[Unit]Description=Certbot Renewal Service
[Service]# サービスは一度実行されると完了するType=oneshot
# 証明書の更新を行う Certbot コマンドを実行するExecStart=/usr/bin/certbot renew
# サービスごとに一時ディレクトリを分離し、セキュリティを向上させるPrivateTmp=true
次に
sudoedit /etc/systemd/system/certbot-renewal.timer
[Unit]Description=Run Certbot Renewal Twice Daily
[Timer]# 毎日午前 0 時と午後 12 時に Certbot 更新サービスを実行するOnCalendar=*-*-* 00,12:00:00
# タイマーがシステムが停止中の間に実行されなかった場合、次回起動時に直ちに実行するPersistent=true
[Install]# timers.target によってタイマーが起動されるようにするWantedBy=timers.target
最後にcertbot-renewal.timer
を
systemctl daemon-reload
systemctl enable --now certbot-renewal.timer
正しく
systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATESSun 2024-10-27 00:00:00 JST 51min Sat 2024-10-26 12:00:00 JST 11h ago certbot-renewal.timer certbot-renewal.service
問題なし。
念の
certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Found the following certs: Certificate Name: mastodon.kkhys.me Serial Number: xxx Key Type: xxx Domains: mastodon.kkhys.me Expiry Date: 2025-01-17 14:27:26+00:00 (VALID: 83 days) Certificate Path: /etc/letsencrypt/live/mastodon.kkhys.me/fullchain.pem Private Key Path: /etc/letsencrypt/live/mastodon.kkhys.me/privkey.pem- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
やり残した こと
他に時間と
- Tor を
通じて オニオンサービスと して 提供する - データベースを
Neon などの Saas に 分離させる
ごに
さいMastodon は
周りの
検索基盤チームの
Elasticsearch×Sudachi移行戦略と 実践。 この 記事のような ドメインを 扱うのであれば Sudachi の 方が 向いているかもしれない ↩