2018年のサーバー構築
本サイトは2018年1月12日〜14日ごろに、3代目の機体(5代目くらいの構築)で公開を再開しました。 本記事はその記録です。
基本方針
今回の再構築では次の基本方針を掲げました。
- 壊れにくい
- ソフトウェアの更新などによるサービスの停止を起こしにくい
- 攻撃を食らっても被害をサービス停止までに止める
- 再構築しやすい
- 機体の更新などで再構築する場合にも,できる限り短い時間で作業ができる
このサイトはアップデート失敗などで停止し、 再構築に手間取ることによって長期間に渡って公開停止になることを、 繰り返してきました。 再発を防ぐために、壊れにくく直しやすい作りが必要でした。
これらを実現するための方法として、VMを利用して軽量OSを動作させ、 その上でそのOSのやり方に沿ってサイトを構築することとしました。 (いまどき自宅サーバでやっています。 あんまりネットワークに負荷をかけると、 私とはなんの関係もない近隣住民に被害が発生します。 私が気に入らない場合はコメントでお願いします。)
使用ソフトウェア
OS周り
- VM環境: VirtualBox
- VM OS: Alpine Linux Virtual版
ウェブサーバ
メールサーバ
DNSサーバ(サーバ間連携用)
- DNSサーバ: Dnsmasq
設定内容
OS周り
各サーバ共通で以下の様な設定をしました。
- VM作成時のオプションとしては
- OS: 「Linux 2.6以降」
- 適当なサイズのストレージを設定
- ネットワークは「ブリッジアダプター」
- インストーラを普通に使う
Login: root # インストールCDはrootにパスワードなしで入れる様になっている setup-alpine
- communityリポジトリを有効化
vi /etc/apk/repositories
- 次の通り編集
http://.../alpine/v3.7/main http://.../alpine/v3.7/community ←コメントアウトを解除
- 次の通り編集
- sshでのログインのため、証明書を配置
- まずホスト側で鍵を作る
ssh-keygen -t ed25519 -f .ssh/id_local_(名前)
- SSHクライアント用の設定ファイルを作成しサーバへの接続を容易にする設定
Host (名前) Hostname (IPアドレス) IdentityFile ~/.ssh/id_local_(名前) User root
- 公開鍵をサーバに配置
vi ~/.ssh/authorized_keys
- 内容
ssh-ed25519 ..... ***@****.**
- 内容
- まずホスト側で鍵を作る
- 以降「apkでインストール」は次のコマンドを表す
apk add (パッケージ)
- 「自動起動の設定」は次のコマンドを表す
rc-update add (サービス名) default
DNSサーバ
- apkでdnsmasq-dnssecをインストール
- 設定は決まった場所にファイルを置いて上書き
- 内容については
dnsmasqで始めるプライベートDNSサーバ - GeekFactory
を参考にしております。
# Never forward plain names (without a dot or domain part) domain-needed # Never forward addresses in the non-routed address spaces. bogus-priv # Set this (and domain: see below) if you want to have a domain # automatically added to simple names in a hosts-file. expand-hosts
- 内容については
dnsmasqで始めるプライベートDNSサーバ - GeekFactory
を参考にしております。
- /etc/hostsに必要なホストを記載
127.0.0.1 localhost.localdomain localhost 192.168.0.3 intdns.airport intdns 192.168.0.4 mail mail.airport 192.168.0.5 exserv exserv.airport xxxx.xx
メールサーバ
- apkで以下をインストール
- postfix dovecot dovecot-pigeonhole-plugin rspamd rspamd-controller rspamd-proxy redis clamav-daemon
- 設定していく
メール以外
- DHCPでは配信してもらえないDNSサーバを見に行かせる
/etc/udhcpc/udhcpc.conf に以下を追記
RESOLV_CONF=no
/etc/resolv.confを以下の様に変更
search airport nameserver 192.168.0.3
- 証明書を作る
cd /etc/ssl vi local.cf
- local.cfの内容:
[ req ] default_bits = 4096 encrypt_key = yes x509_extensions = extensions distinguished_name = req_distinguished_name [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, fully qualified host name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ extensions ] nsCertType = server subjectAltName = @alt_names [alt_names] DNS.1 = xxxx.xx DNS.2 = mail
- 本当はDNS.3 = mail.airportも書いておかないといけないらしい(手遅れ)
- 準備ができたので作る
mkdir dovecot cd dovecot openssl req -new -x509 -config ../local.cf -newkey rsa:4096 -nodes -keyout server.key -days 3652 -subj /C=JP/ST=Osaka/CN=mail.airport/emailAddress=xxx@xxxx.xx/ -out server.cer cd ../postfix/ openssl req -new -x509 -config ../local.cf -newkey rsa:4096 -nodes -keyout server.key -days 3652 -subj /C=JP/ST=Osaka/CN=mail.airport/emailAddress=xxx@xxxx.xx/ -out server.cer
- local.cfの内容:
Postfix
- 次のサイトを参考としております。
- Dovecotとの連携について(main.cfのmaster_service_disableのあたりまでとmaster.cf):Dovecotの公式サイト
- Rspamdとの連携について(main.cfの下4行):Rspamdの公式サイト
- 設定ファイルに追記
vi /etc/postfix/main.cf
- 末尾に次の内容を追加する:
### ### Local Configurations ### ### myhostname = mail.airport virtual_mailbox_domains = xxxx.xx virtual_mailbox_base = /var/vmail virtual_minimum_uid = 100 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_alias_maps = hash:/etc/postfix/virtual virtual_transport = lmtp:unix:private/dovecot-lmtp strict_rfc821_envelopes = yes smtpd_helo_required = yes smtpd_helo_restrictions = reject_non_fqdn_helo_hostname smtpd_sender_restrictions = reject_unknown_sender_domain smtpd_recipient_restrictions = reject_unknown_recipient_domain, reject_non_fqdn_recipient, reject_unverified_recipient, reject_unauth_destination unknown_address_reject_code = 554 unknown_hostname_reject_code = 554 unknown_client_reject_code = 554 unknown_local_recipient_reject_code = 550 smtpd_tls_cert_file=/etc/ssl/postfix/server.cer smtpd_tls_key_file=/etc/ssl/postfix/server.key smtpd_tls_security_level = may smtp_tls_security_level = may alias_maps = hash:/etc/postfix/aliases mailbox_size_limit = 0 message_size_limit = 20480000 queue_run_delay = 300s minimal_backoff_time = 300s master_service_disable = smtpd_milters = unix:/var/run/rspamd.sock milter_protocol = 6 milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} milter_default_action = accept
- master.cfも編集する
vi /etc/postfix/master.cf
- 次の通り追記する
submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth -o smtpd_sasl_security_options=noanonymous -o smtpd_sasl_local_domain=$myhostname -o smtpd_tls_auth_only=yes -o smtpd_reject_unlisted_recipient=no -o smtpd_client_restrictions=$mua_client_restrictions -o smtpd_helo_restrictions=$mua_helo_restrictions -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_recipient_restrictions=reject_unknown_recipient_domain,reject_non_fqdn_recipient,permit_sasl_authenticated,reject -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_login_maps=hash:/etc/postfix/virtual -o milter_macro_daemon_name=ORIGINATING
- 末尾に次の内容を追加する:
- エイリアスを更新
newaliases
Dovecot
- 次のサイトを参考としております。
- Postfixとの連携について:Dovecotの公式サイト
- Rspamdとの連携について:Dovecot antispam with Rspamd (part 2) — There is no spoon.
- 全ての設定を追加のファイルで行う
vi /etc/dovecot/local.conf
- 設定内容は以下の通り
protocols = imap lmtp ssl_cert = </etc/ssl/dovecot/server.cer ssl_key = </etc/ssl/dovecot/server.key # Services service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { group = postfix mode = 0600 user = postfix } } service imap-login { inet_listener imap { address = 0.0.0.0 port = 143 } inet_listener imaps { address = 0.0.0.0 port = 993 } } service imap { } service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0660 user = postfix } user = doveauth } service auth-worker { user = doveauth } verbose_proctitle = yes # Storage mail_location = maildir:~/maildir mail_plugins = acl quota # Protocol protocol lmtp { postmaster_address = xxx@xxxx.xx # required mail_plugins = quota sieve } protocol imap { mail_plugins = $mail_plugins imap_acl imap_quota mail_log notify } # Authentication auth_mechanisms = plain passdb { driver = passwd-file args = username_format=%u /var/vmail/auth.d/%d/passwd } userdb { driver = passwd-file args = username_format=%u /var/vmail/auth.d/%d/passwd } plugin { quota = dict:user::file:%h/maildir/dovecot-quota quota_rule = *:storage=1GB quota_rule2 = Trash:storage=+10%% acl = vfile:/var/vmail/conf.d/%d/acls:cache_secs=300 } # for mail filtering plugin { sieve = ~/.dovecot.sieve sieve_dir = ~/sieve sieve_global_dir = /var/vmail/conf.d/%d/sieve sieve_before = /etc/dovecot/sieve/rspam_deliver.sieve }
- 上記で使ったrspam_deliver.sieveを作る
mkdir /etc/dovecot/sieve vi /etc/dovecot/rspam_deliver.sieve
- rspam_deliver.sieveの内容は以下の通り
require "fileinto"; require "imap4flags"; if header :is "X-Spam" "Yes" { fileinto "Junk"; setflag "\\seen"; stop; }
- rspam_deliver.sieveの内容は以下の通り
- それをコンパイルしておく
sievec /etc/dovecot/rspam_deliver.sieve
- 設定内容は以下の通り
Rspamd
- 次のサイトを参考としております。
- DKIMキーを生成
rspamadm dkim_keygen -s 'miimou' -d xxxx.xx > /etc/rspamd/local.d/dkim_priv.key chown rspamd /etc/rspamd/local.d/dkim_priv.key chmod 600 /etc/rspamd/local.d/dkim_priv.key vi /etc/rspamd/local.d/dkim_priv.key # -----END PRIVATE KEY-----より後をコピーしてから削除 vi /etc/rspamd/local.d/dkim_pub.key # コピーした内容を貼り付け
- この/etc/rspamd/local.d/dkim_pub.keyの内容は少し変更してDNSにも入れる
DNSサーバに入って
vi /etc/dnsmasq.d/local.conf
以下を追記(公開鍵なので隠す必要はないが,長いので省略)
txt-record=miimou._domainkey.xxxx.xx,"v=DKIM1; k=rsa; p=xxxx"
- local.dとoverride.dにファイルを配置する
- local.d/antivirus.conf
clamav { attachments_only = false; servers = "/run/clamav/clamd.sock"; }
- local.d/arc.conf
path = "/etc/rspamd/local.d/dkim_priv.key"; selector = "arc"; use_esld = false;
- local.d/dkim_signing.conf
path = "/etc/rspamd/local.d/dkim_priv.key"; selector = "miimou"; use_esld = false;
- local.d/milter_headers.conf
use = ["x-spamd-result","x-rspamd-server","x-rspamd-queue-id","authentication-results","x-spam-level","x-virus"]; authenticated_headers = ["authentication-results","x-virus"];
- local.d/redis.conf
servers = "127.0.0.1";
- local.d/statistic.conf
autolearn = [-5, 10]
- local.d/worker-controller.inc
bind_socket = "0.0.0.0:11334"; password = "$2$xxx$xxxxxxxx" enable_password = "$2$xxx$xxxxxxxx"
- passwordの値は次のコマンドで生成する
rspamadm pw
- passwordの値は次のコマンドで生成する
- local.d/worker-normal.inc
enabled = false;
- local.d/worker-proxy.inc
milter = yes; timeout = 120s; bind_socket = "/var/run/rspamd.sock mode=0666"; upstream "local" { default = yes; self_scan = yes; }
- override.d/metrics.conf
actions { add_header = 10; }
- local.d/antivirus.conf
メールアカウントの用意
- ディレクトリを作成
mkdir /var/vmail
- 認証設定
mkdir -p /var/vmail/auth.d/xxxx.xx vi /var/vmail/auth.d/xxxx.xx/passwd
- 内容はこんな感じ.issoはWebサーバ編で使うので用意
xxx@xxxx.xx:$6$xxxx$xxxxxxxx:5000:5000::/var/vmail/xxxx.xx/xxx::userdb_quota_rule=*:storage=1G isso@xxxx.xx:$6$xxxx$xxxxxxxx:5000:5000::/var/vmail/xxxx.xx/isso::userdb_quota_rule=*:storage=32M
- $6$xxxx$xxxxxxxxはパスワードハッシュ。次のコマンドで作成
mkpasswd
- $6$xxxx$xxxxxxxxはパスワードハッシュ。次のコマンドで作成
- 内容はこんな感じ.issoはWebサーバ編で使うので用意
- メールディレクトリの用意
mkdir -p /var/vmail/xxxx.xx/xxx/maildir mkdir -p /var/vmail/xxxx.xx/isso/maildir chown 5000 /var/vmail/xxxx.xx/xxx/maildir chown 5000 /var/vmail/xxxx.xx/isso/maildir
自動起動
- clamd, dovecot, rspamd, freshclam, redis, postfix
Webサーバ
- メールサーバ編でやったようにDNSサーバの参照設定を行う
- apkで次をインストール
- nginx, sqlite, uwsgi, uwsgi-python3, python3, python3-dev, py-virtualenv, alpine-sdk, linux-headers
- とりあえずnginxを設定
- /etc/nginx/conf.d/xxxx.xx(作成)
server { listen 80; listen [::]:80; location ~ ^/isso/(.*)$ { include uwsgi_params; uwsgi_pass 127.0.0.1:8080; uwsgi_param SCRIPT_NAME /isso; uwsgi_param PATH_INFO /$1; } root /var/www/xxxx.xx; index index.html index.htm; server_name xxxx.xx; }
- コンテンツは/var/www/xxxx.xxに配置
- /etc/nginx/conf.d/xxxx.xx(作成)
Issoのインストール
Issoの公式の説明を参考にしております。
まずvirtualenvを用意して入る
virtualenv /opt/isso source /opt/isso/bin/activate
Issoを入れる
pip install isso
設定ファイルを作る
mkdir /etc/isso vi /etc/isso/isso.conf
- 設定する
[general] dbpath = /opt/isso/var/comments.db host = http://xxxx.xx/ max-age = 15m notify = smtp [moderation] enabled = true [smtp] username = isso@xxxx.xx password = xxxx host = mail port = 587 security = starttls to = xxx@xxxx.xx from = xxx@xxxx.xx timeout = 10
- 設定する
uWSGIの設定を作成する
vi /etc/uwsgi/conf.d/isso.ini
- 設定内容は以下の通り
[uwsgi] socket = 127.0.0.1:8080 master = True ; processes = 1 cache2 = name=hash,items=1024,blocksize=32 ; spooler = /opt/isso/var/mail plugin = python3 module = isso.run ; virtualenv = /opt/isso env = ISSO_SETTINGS=/etc/isso/isso.conf
- 設定内容は以下の通り
メールサーバのPostfixの証明書をコピーしてきて/usr/local/share/ca-certificates/mail-smtp.crtに配置(ホスト側で)
scp mail:/etc/ssl/postfix/server.cer tmp_201801_mail.crt scp tmp_201801_mail.crt exserv:/usr/local/share/ca-certificates/mail-smtp.crt
読み込ませる
update-ca-certificates
データ置き場を作る
dir /opt/isso/var own isso:isso /opt/isso/var
自動起動
- nginx, uwsgi, uwsgi.isso
結び
この記事では本サーバの構築手順について記しました。 これは備忘録として残すものですから、 各自環境に応じてアレンジしてみてください。