Mastodonインスタンス”今.jp”を立ててみた。

サーバのお勉強を兼ねて、Mastodonのインスタンス(https://今.jp/)を立ててみました。
※個人によるベストエフォート運用となりますので、データやサービスの永続性は保証できませんがもしよろしければ遊びに来てください。

構成は下図のようなイメージとなっております。

追記部分に構築時のメモを残しておきますので、ご興味が御座いましたらご参考ください。

●パーティション構成

biosboot 1.0 MiB
/boot 0.5 GiB
/ 8.0 GiB
/home 1.0 GiB
/var 10 GiB
/var/lib/docker 8.0 GiB
/mastodon 70 GiB
swap max

※CentOS 7.3.1611(Minimal)のインストーラに「inst.gpt」を与えて、明示的にGPTパーティションとしています。

OSインストールはVNCコンソールから行いましたが、以後の設定は全てSSH接続で行います。
※また、常時使用は推奨されませんが構築時はsudo suを使っております。

●gccをインストールします。
Minimalインストールした場合gccが入っておりません・・・
また、後々インストールしようとすると依存関係が解消できずにハマるので最初に入れておきます。


$ sudo su
# yum install gcc screen

●一度抜けてscreenを使用します。
これで不慮の通信障害に見舞われた場合でも最悪の事態は回避出来ます。


# exit
$ screen
# sudo su

●ファイアウォール設定は最小限にします。
DHCPは使っていない(?)ので、ファイアウォールから削除します。


# firewall-cmd --remove-service=dhcpv6-client --zone=public --permanent
# firewall-cmd --reload

●ファイアウォール設定は最小限にします。
気持ち程度ですが、SSH接続出来るドメインを制限しておきます。
1.hosts.allowの最終行に「sshd: ●●.△△.jp」を追加。
(●●.△△.jpの部分は、お使いのプロバイダに合わせて変更してください。)
2.hosts.denyの最終行に「ALL: ALL」を追加。


# vi /etc/hosts.allow
# vi /etc/hosts.deny

●sshdの設定変更を行います。
特定のユーザのみ(AllowUsers)、かつ、鍵認証でのみ接続出来るように設定ファイルを変更します。


# vi /etc/ssh/sshd_config

気持ち程度ですが、キーを作り直しておきます。


# ssh-keygen -t dsa -b 1024 -f /etc/ssh/ssh_host_dsa_key -N ''
# ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
# ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N ''
# ssh-keygen -t ed25519 -b 256 -f /etc/ssh/ssh_host_ed25519_key -N ''

鍵認証用のファイルを作成。


$ mkdir /home/ユーザ/.ssh
$ chmod 700 /home/ユーザ/.ssh
$ touch /home/ユーザ/.ssh/authorized_keys
$ chmod 600 /home/ユーザ/.ssh/authorized_keys
$ vi /home/ユーザ/.ssh/authorized_keys

sshdを再起動。


$ sudo su
# systemctl restart sshd.service

●suできるユーザを限定しておきます。


# vi /etc/pam.d/su

●chronyd(ntpd)の設定を変更します。
※以下のサーバに設定しています。
server ntp1.sakura.ad.jp
server ntp1.v6.mfeed.ad.jp
server ntp2.v6.mfeed.ad.jp
server ntp3.v6.mfeed.ad.jp


# vi /etc/chrony.conf
# systemctl restart chronyd.service
# chronyc sources

●アップデートを実施して再起動します。


# yum update
# reboot

●メールの転送設定を行います。
※例えば「root: shukukei@mojizuri.jp」のように設定しています。


$ screen
$ sudo su
# vi /etc/aliases
# newaliases

●Postfixの設定を行います。
直接送るのではなく、外部のメールサーバを経由して送信するように設定しています。


# yum install cyrus-sasl-plain
# vi /etc/postfix/main.cf

今回はSendGridさんを経由して送信したいので、以下の設定を記述しました。


smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:apikey:
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
header_size_limit = 4096000
relayhost = [smtp.sendgrid.net]:587

たとえばGmailさんを経由して送信する場合は、以下のような設定で送信出来ます。


smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:メールアドレス:パスワード
smtp_sasl_tls_security_options = noanonymous
smtp_tls_security_level = encrypt
relayhost = [smtp.gmail.com]:587

Postfixを再起動します。


# systemctl restart postfix.service

ここからがMastodon v1.2.2のインストールとなります。

●Dockerをインストールします。


# yum install yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum makecache fast
# yum install docker-ce docker-ce-selinux
# systemctl start docker.service
# docker run hello-world

# useradd mastodon
# usermod -aG docker mastodon

# systemctl restart docker.service

# su mastodon
$ docker run hello-world
$ exit

# systemctl enable docker.service

●GitとDocker Composeをインストールします。


# yum install git
# curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

# chown mastodon.mastodon /mastodon
# semanage fcontext -a -t user_home_dir_t "/mastodon(/.*)?"
# restorecon -R -v /mastodon

●Mastodonをインストールします。
※masterではなく、タグ付けされたバージョンを追いかけることにしました。


# su mastodon

$ cd /mastodon
$ git clone https://github.com/tootsuite/mastodon.git /mastodon
$ git checkout $(git describe --tags `git rev-list --tags --max-count=1`)

永続化設定(2行×2カ所、4行をコメント解除)と、sidekiqを4つに分けました。


$ vi docker-compose.yml

執筆時点でのsidekiq設定値は以下の通り。
default:14
mailers:2
pull:2
push:2

数を変えたい場合は、docker-compose.ymlを編集後に以下を実行すればよいらしい。(未検証)


$/usr/local/bin/docker-compose down --remove-orphan
$/usr/local/bin/docker-compose up -d

設定を行います。


$ cp .env.production.sample .env.production
$ vi .env.production

具体的には以下の変更を行いました。


DB_POOL=20

~中略~

LOCAL_DOMAIN=xn--wmq.jp
LOCAL_HTTPS=true

~中略~

DEFAULT_LOCALE=ja

~中略~

SMTP_SERVER=smtp.sendgrid.net
SMTP_PORT=587
SMTP_LOGIN=apikey
SMTP_PASSWORD=
SMTP_FROM_ADDRESS=sendonly@xn--wmq.jp
SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=peer
SMTP_ENABLE_STARTTLS_AUTO=true

SendGridさんでメールを送りたいので、追加で以下の設定を行いました。


$ cd config/environments
$ vi production.rb
	:ca_file => File.expand_path(File.dirname(__FILE__)) + '/gd_bundle-g2-g1.crt',
$ wget https://certs.godaddy.com/repository/gd_bundle-g2-g1.crt

※以下のウェブサイトを参考にさせていただきました。
Mastodon+SendGridでSMTP_OPENSSL_VERIFY_MODEをpeerで動作させる – Qiita

シークレットを生成します。


$ cd /mastodon
$ /usr/local/bin/docker-compose build
$ /usr/local/bin/docker-compose run --rm web rake secret
$ vi .env.production
$ /usr/local/bin/docker-compose run --rm web rake secret
$ vi .env.production
$ /usr/local/bin/docker-compose run --rm web rake secret
$ vi .env.production

データベースとアセットを準備して立ち上げます。


$ /usr/local/bin/docker-compose run --rm web rails db:migrate
$ /usr/local/bin/docker-compose run --rm web rails assets:precompile
$ /usr/local/bin/docker-compose up -d

定期的なメンテナンスを実施するようにcron設定を行います。


$ crontab -e

具体的には以下の2行を追加しました。


00 3 * * * cd /mastodon && /usr/local/bin/docker-compose run --rm web rake mastodon:daily
00 3 * * 5 cd /mastodon && /usr/local/bin/docker-compose run --rm web rake mastodon:media:remove_remote

●Apacheの設定を行います。


$ exit
# vi /etc/httpd/conf.d/ssl.conf

証明書等の設定の他に、以下のような設定を行いました。


DocumentRoot "/mastodon/public"
ServerName xn--wmq.jp:443


        Require all granted


ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass /500.html !
ProxyPass /oops.png !
ProxyPass /api/v1/streaming/ ws://localhost:4000/
ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/

ErrorDocument 500 /500.html
ErrorDocument 501 /500.html
ErrorDocument 502 /500.html
ErrorDocument 503 /500.html
ErrorDocument 504 /500.html

●SELinuxの設定を行います。


# semanage fcontext -a -t httpd_sys_content_t "/mastodon/public(/.*)?"
# restorecon -R -v /mastodon/public

# semanage port -a -t http_cache_port_t -p tcp 3000
# semanage port -a -t http_cache_port_t -p tcp 4000
# setsebool -P httpd_can_network_relay on

最後にhttpdを再起動して、ファイアウォールの設定を行えば完了です。


# systemctl restart httpd.service
# firewall-cmd --add-service=https --zone=public --permanent
# firewall-cmd --reload

コマンドラインでも実施出来るようですが、
面倒だったので動作確認も兼ねてブラウザでサーバにアクセスし、管理者用とするユーザを作成します。
ユーザ作成後、以下のコマンドで管理者権限を付与します。


# su mastodon
$ /usr/local/bin/docker-compose run --rm web rails mastodon:make_admin USERNAME=ユーザ名
$ exit

メモリとディスクの消費量は以下のような感じです。
※SiteGuard Liteのメモリ消費量も含んでいます。

●さらに追加で以下の設定を行いました。(検証中)

/etc/httpd/conf.d/autoindex.conf
→全行コメントアウト。

/etc/httpd/conf.d/welcome.conf
→全行コメントアウト。
(削除すると再生成されるため削除してはいけないらしい)

/etc/httpd/conf.modules.d/00-base.conf


#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#

LoadModule access_compat_module modules/mod_access_compat.so
#LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
#LoadModule allowmethods_module modules/mod_allowmethods.so
#LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_core_module modules/mod_authn_core.so
#LoadModule authn_dbd_module modules/mod_authn_dbd.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
#LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_socache_module modules/mod_authn_socache.so
LoadModule authz_core_module modules/mod_authz_core.so
#LoadModule authz_dbd_module modules/mod_authz_dbd.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_host_module modules/mod_authz_host.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_user_module modules/mod_authz_user.so
#LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule cache_module modules/mod_cache.so
#LoadModule cache_disk_module modules/mod_cache_disk.so
#LoadModule data_module modules/mod_data.so
#LoadModule dbd_module modules/mod_dbd.so
#LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
#LoadModule dumpio_module modules/mod_dumpio.so
#LoadModule echo_module modules/mod_echo.so
#LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
#LoadModule filter_module modules/mod_filter.so
LoadModule headers_module modules/mod_headers.so
#LoadModule include_module modules/mod_include.so
#LoadModule info_module modules/mod_info.so
LoadModule log_config_module modules/mod_log_config.so
#LoadModule logio_module modules/mod_logio.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule mime_module modules/mod_mime.so
#LoadModule negotiation_module modules/mod_negotiation.so
LoadModule remoteip_module modules/mod_remoteip.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so
#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
#LoadModule socache_dbm_module modules/mod_socache_dbm.so
#LoadModule socache_memcache_module modules/mod_socache_memcache.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule status_module modules/mod_status.so
#LoadModule substitute_module modules/mod_substitute.so
#LoadModule suexec_module modules/mod_suexec.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule unixd_module modules/mod_unixd.so
#LoadModule userdir_module modules/mod_userdir.so
#LoadModule version_module modules/mod_version.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so

#LoadModule buffer_module modules/mod_buffer.so
#LoadModule watchdog_module modules/mod_watchdog.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule dialup_module modules/mod_dialup.so
#LoadModule charset_lite_module modules/mod_charset_lite.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule ratelimit_module modules/mod_ratelimit.so
#LoadModule reflector_module modules/mod_reflector.so
#LoadModule request_module modules/mod_request.so
#LoadModule sed_module modules/mod_sed.so
#LoadModule speling_module modules/mod_speling.so

/etc/httpd/conf.modules.d/00-lua.conf


#LoadModule lua_module modules/mod_lua.so

/etc/httpd/conf.modules.d/00-proxy.conf


# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so
#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
#LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_express_module modules/mod_proxy_express.so
#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
#LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

/etc/httpd/conf.modules.d/00-dav.conf


#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_lock_module modules/mod_dav_lock.so

/etc/sysctl.conf


net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_sack = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

net.core.somaxconn = 4096
net.core.netdev_max_backlog = 4096

kernel.sysrq = 0
kernel.panic = 120
#vm.swappiness = 0

/etc/rc.local
※「# chmod +x /etc/rc.local」を実行すること。


/sbin/ip link set dev eth0 txqueuelen 60000
/sbin/ethtool -K eth0 tx off sg off tso off gso off gro off
/sbin/ip link set dev eth1 txqueuelen 60000
/sbin/ethtool -K eth1 tx off sg off tso off gso off gro off
/sbin/ip link set dev eth2 txqueuelen 60000
/sbin/ethtool -K eth2 tx off sg off tso off gso off gro off

いつもはDebian GNU/Linuxとnginxを使っており、CentOSとApacheの組み合わせに手間取りましたので備忘録としてこの記事を残しておきます。