下記の記事で仕立てた Bitnami の Redmine スタックが ubuntu 14.04 ベースだったため、LTSのサポートも切れていて、はらはらしながら使っていました。
blog.mori-soft.com
まあ、さっさとOSアップグレードするか別のスタック立ち上げてもよかったんですが、時間がないことに加えて、2020年6月末でこの Redmine を運用していた EC2 のリザーブドインスタンスの期限が迫っていたので、見て見ぬふりをしながらなんとかやり過ごしていました。
先日、晴れてリザーブドインスタンスの期限が来たので、新たに Redmine を立ち上げ直すことにしました。
今回も、 Bitnami の Redmine スタックを利用しますが、サーバーは EC2 のスポットインスタンスで立てます。というのも、別サーバーをスポットインスタンスで運用しているのですが、価格が高騰してストップすることもなく結構安定して使えているのと、今はスポットインスタンが停止してもデータ(ストレージ)が残り、価格が下がってから改めて再起動できるので、自分用のサーバーならスポットでも十分かな?と思ったためです。
前回の移行時と同じく比較しておきます。
|
移行前 |
移行後 |
EC2インスタンス |
t2.nano |
t3.nano |
OS |
Ubuntu 14.04, 64bit |
Debian 10, 64bit |
Redmine |
3.3.2 |
4.1.1 |
EC2 インスタンスの立ち上げ
というわけで、まずは t3.nano のインスタンスを立ち上げます。今回も Birnami を利用してお手軽にサーバーと Redmine を立ち上げたいと思います。下記のAMI一覧のページから使いたいリージョンのAMIをクリックするか、AWSのコンソールでコミュニティAMIで検索して立ち上げます。
Redmine Public AMIs
インスタンスタイプは t3.nano を選び、インスタンスの設定でスポットインスタンスを選択します。
上限金額(今回はオンデマンドの料金未満としました)を入力し、もしも停止しても再度インスタンスを立ち上げ直したいので『永続的リクエスト』には忘れずにチェックを入れます。また、『中断動作』として『停止』を選んでおきます。
あとは、デフォルト設定で起動すれば、新しい環境が出来上がりです。 次は、データのマイグレーションになります。
Redmine 4.1.1 へマイグレーション
さて、新しいサーバー(とRedmine)が立ち上がったので、古いサーバー上の Redmine のデータを移行したいと思います。前回のマイグレーション時の記事を参考にしてもよいですし、移行手順が下記にまとまっているので、この手順を参考に進めても OK です。
Upgrade Redmine
旧サーバーでの作業
まず、添付ファイルのバックアップを取ります。
bitnami@ip-172-30-0-73:/opt/bitnami/apps/redmine/htdocs$ tar zcvf ~/redmine_files.tgz ./files
次に、データベースのダンプを取ります。
bitnami@ip-172-30-0-73:~$ mysqldump -u bitnami -pxxxxxxx bitnami_redmine > redmine.dump
作成したファイルを新サーバーにアップロードしておきます。
新サーバーでの作業
まずは apache を停止します。
bitnami@ip-172-30-0-111:~/stack$ sudo ./ctlscript.sh stop apache
DB を復元します。パスワードは初期設定されているものを使用しています。初期パスワードは、立ち上げたインスタンスの bitnami ユーザーのホームディレクトリにファイルがあり、そこに記載されています(~/bitnami_credentials に記載)。
bitnami@ip-172-30-0-111:~/stack$ mysql -u root -p bitnami_redmine < ~/redmine.dump
Enter password:
bitnami@ip-172-30-0-111:~/stack$
下記ディレクトリで、添付ファイルを復元します。
bitnami@ip-172-30-0-111:~/stack/apps/redmine/htdocs$ tar zxvf redmine_files.tgz
Redmine のマイグレーションを行います。
bitnami@ip-172-30-0-111:~/stack/apps/redmine/htdocs$ sudo ruby bin/rake db:migrate RAILS_ENV=production
掃除
bitnami@ip-172-30-0-111:~/stack/apps/redmine/htdocs$ ruby bin/rake tmp:clear
最後に、apache の再起動を行えば完了です。
bitnami@ip-172-30-0-111:~/stack$ sudo ./ctlscript.sh start apache
前回よりもずいぶんと簡単になってました。
なお、マイグレーションが完了すると、ユーザー名・パスワードなども旧サーバーに設定したあるものになるので、ご注意ください。
サーバーの設定
Redmine が使えるようになったので、あとはサーバーの運用上必要な設定を行います。基本的には、前回マイグレーション時の下記記事に従っているのですが、
blog.mori-soft.com
最近の環境に合わせて、変えているところだけメモしておきます。
NTPクライアント起動
NTP クライアントは ntpd ではなく chrony を使うようです。
chrony は既にインストール済みでしたので、起動してあげればOKです。
bitnami@ip-172-30-0-111:/etc/chrony$ sudo systemctl status chrony
● chrony.service - chrony, an NTP client/server
Loaded: loaded (/lib/systemd/system/chrony.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sat 2020-06-27 00:10:36 JST; 1 day 14h ago
Docs: man:chronyd(8)
man:chronyc(1)
man:chrony.conf(5)
Main PID: 547 (code=exited, status=0/SUCCESS)
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
bitnami@ip-172-30-0-111:/etc/chrony$ sudo systemctl start chrony
bitnami@ip-172-30-0-111:/etc/chrony$ sudo systemctl status chrony
● chrony.service - chrony, an NTP client/server
Loaded: loaded (/lib/systemd/system/chrony.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2020-06-28 14:51:24 JST; 3s ago
Docs: man:chronyd(8)
man:chronyc(1)
man:chrony.conf(5)
Process: 25274 ExecStart=/usr/sbin/chronyd $DAEMON_OPTS (code=exited, status=0/SUCCESS)
Process: 25278 ExecStartPost=/usr/lib/chrony/chrony-helper update-daemon (code=exited, status=0/SUCCESS)
Main PID: 25276 (chronyd)
Tasks: 2 (limit: 535)
Memory: 1.3M
CGroup: /system.slice/chrony.service
├─25276 /usr/sbin/chronyd -F -1
└─25277 /usr/sbin/chronyd -F -1
6月 28 14:51:24 ip-172-30-0-111 systemd[1]: Starting chrony, an NTP client/server...
6月 28 14:51:24 ip-172-30-0-111 chronyd[25276]: chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 -DEBUG)
6月 28 14:51:24 ip-172-30-0-111 chronyd[25276]: Frequency 6.546 +/- 0.030 ppm read from /var/lib/chrony/chrony.drift
6月 28 14:51:24 ip-172-30-0-111 chronyd[25276]: Loaded seccomp filter
6月 28 14:51:24 ip-172-30-0-111 systemd[1]: Started chrony, an NTP client/server.
bitnami@ip-172-30-0-111:/etc/chrony$
unattended-upgrade と メール送信
一応、このサーバーにも unattended-upgrade を入れておきます。
(参考)
Debian 系で unattended-upgrades を有効にする場合の追加設定 (メール通知, autoremove, autoclean, 再起動) - Qiita
とは言っても、この stack では最初から unattended-upgrade が有効になっていたので、やることは autoremove, autoclean を追加で設定するのと、更新時にメールを送る設定だけです。
msmtp によるメール送信
以前よく使っていた smtp はメンテナンスされていないので、今は msmtp を使うほうが良いようです。
インストールします。
bitnami@ip-172-30-0-111:~$ sudo apt install msmtp msmtp-mta
設定ファイルのひな形をコピーします。
bitnami@ip-172-30-0-111:/etc$ sudo cp -p /usr/share/doc/msmtp/examples/msmtprc-user.example msmtprc
編集します。最終的に下記のような設定としました。
defaults
port 587
tls on
syslog LOG_MAIL
account sakura_via_ses
host xxxxx.xxxxxx.amazonaws.com
from xxxxx@mori-soft.com
auth on
user (Amazon SES のユーザー名)
password (Amazon SES のパスワード)
account default : sakura_via_ses
今回は、直接自分のメールサーバーに送るのではなく、 Amazon SES 経由でメールを送ることにしました。これは、SES経由にして、送信先アドレスを指定したもの以外に送れなくするためです。
なお、SES の設定については、下記の記事を参照してください。
blog.mori-soft.com
設定ができたらテストしておきます。
bitnami@ip-172-30-0-111:/etc$ echo "mail test" | sudo msmtp -a default メール送信先のアドレス
syslog を見ると、メール送信のログが出ています。
Jun 29 09:27:29 ip-172-30-0-111 msmtp: host=xxxxx.xxxxxx.amazonaws.com tls=on auth=on user=(Amazon SES のユーザー名) from=xxxxx@mori-soft.com recipients=メール送信先のアドレス mailsize=76 smtpstatus=250 smtpmsg='250 Ok 01000172fd78c077-73fd5f8e-8e2c-426b-9be9-a932fc2a0290-000000' exitcode=EX_OK
実際に宛先のメールアドレスで確認すると、メールが受信できてました。
あとは、 unattended-upgrade がメールを送る際は mailx が必要なので、これをインストールすればOKです。
bitnami@ip-172-30-0-111:/etc/apt/apt.conf.d$ sudo apt install mailutils
(参考)
Let's Encrypt の設定
Birnami の Redmine スタックには Let's Encrypt による HTTPS の利用が簡単にできるようになっています。至れり尽くせりですね。
Generate and Install a Let's Encrypt SSL Certificate for a Bitnami Application
上記リンク先の手順に従って、設定したいと思います。
なお、設定開始前に、http(80)とhttps(443)でアクセスできるようにポートを開けておきます。
最初に動かすとツールを更新するか?と聞かれるので、yesを選択しておきます。
bitnami@ip-172-30-0-111:~/stack$ sudo ./bncert-tool
An updated version is available. Would you like to download it? You would need to run it manually later. [Y/n]: y
The tool will exit now. To run the updated version run the following command:
/opt/bitnami/bncert-tool
bitnami@ip-172-30-0-111:~/stack$
ちなみに更新前のバージョン
lrwxrwxrwx 1 root root 46 6月 10 02:15 bncert-tool -> /opt/bitnami/bncert/bncert-0.5.9-linux-x64.run
こちらが更新後のバージョン
lrwxrwxrwx 1 root root 47 6月 27 16:06 bncert-tool -> /opt/bitnami/bncert/bncert-0.5.10-linux-x64.run*
もう一度、ツールを起動します。
bitnami@ip-172-30-0-111:~/stack$ sudo ./bncert-tool
----------------------------------------------------------------------------
Welcome to the Bitnami HTTPS Configuration tool.
----------------------------------------------------------------------------
Domains
Please provide a valid space-separated list of domains for which you wish to
configure your web server.
Domain list []: このサーバーのドメイン名
最初はドメイン名を入力します。
入力したのが、 www なしのドメイン名だったので、 www 付も作るか聞かれますが、なしにします。
The following domains were not included: www.このサーバーのドメイン名. Do you want to add them? [Y/n]: n
警告がでるので、一通り読んで、次に進みます。
Warning: No www domains (e.g. www.example.com) or non-www domains (e.g.
www.example.com) have been provided, so the following redirections will be
disabled: non-www to www, www to non-www.
Press [Enter] to continue:
HTTP -> HTTPS のリダイレクトです。
下記では、リダイレクトをしないとしてますが、実はあとから、リダイレクトありに変更しました(変更は再度同じツールを起動するだけでOKです)。
----------------------------------------------------------------------------
Enable/disable redirections
Please select the redirections you wish to enable or disable on your Bitnami
installation.
Enable HTTP to HTTPS redirection [Y/n]: n
今から起きることが説明されるので、問題なければ y を入力します。
----------------------------------------------------------------------------
Changes to perform
The following changes will be performed to your Bitnami installation:
1. Stop web server
2. Configure web server to use a free Let's Encrypt certificate for the domains:
このサーバーのドメイン名
3. Configure a cron job to automatically renew the certificate each month
4. Configure web server name to: このサーバーのドメイン名
5. Start web server once all changes have been performed
Do you agree to these changes? [Y/n]: y
メールアドレスを入力します。何かあるとき、 Let's Encrypt からメールが来ます。
----------------------------------------------------------------------------
Create a free HTTPS certificate with Let's Encrypt
Please provide a valid e-mail address for which to associate your Let's Encrypt
certificate.
Domain list: このサーバーのドメイン名
Server name: このサーバーのドメイン名
E-mail address []: xxxxx@mori-soft.com
subscriber agreement を読んで同意するかどうか決めます。
The Let's Encrypt Subscriber Agreement can be found at:
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Do you agree to the Let's Encrypt Subscriber Agreement? [Y/n]: y
設定処理の結果が表示されます。
----------------------------------------------------------------------------
Performing changes to your installation
The Bitnami HTTPS Configuration Tool will perform any necessary actions to your
Bitnami installation. This may take some time, please be patient.
----------------------------------------------------------------------------
Success
The Bitnami HTTPS Configuration Tool succeeded in modifying your installation.
The configuration report is shown below.
Backup files:
* /opt/bitnami/apache2/conf/httpd.conf.back.202006271629
* /opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf.back.202006271629
* /opt/bitnami/apache2/conf/bitnami/bitnami.conf.back.202006271629
Find more details in the log file:
/tmp/bncert-202006271629.log
If you find any issues, please check Bitnami Support forums at:
https://community.bitnami.com
Press [Enter] to continue:
bitnami@ip-172-30-0-111:~/stack$
特にエラーが表示されなければこれでOKです。
ブラウザから、指定したドメインに https でアクセスして問題なくアクセスできることを確認します。
最初にうまくいかなかった理由
さて、上記では何も問題がなかったように書きましたが、最初に設定した際はエラーになりました。その時はログにこんな感じのエラーが出てました。
2020/06/27 16:12:28 Could not obtain certificates:
error: one or more domains had a problem:
[このサーバーのドメイン名] acme: error: 400 :: urn:ietf:params:acme:error:connection :: Timeout during connect (likely firewall problem), url:
これは、AWS の セキュリティグループで https のアクセス元 ipアドレス を制限していたことが原因だったようです。
一時的にセキュリティグループの制限をなくすと、設定に成功し、その時のログを見ると、設定した証明書で正しく応答しているか確認しているとありました。
2020/06/27 16:30:47 [INFO] [このサーバーのドメイン名] Server responded with a certificate.
なので、IPアドレスで制限していたのがダメだったようです。
(参考)
bitnami redmineにSSL証明書(Let's Encrypt)を導入する - Qiita
あと、cronjob に renew も登録されています。
bitnami@ip-172-30-0-111:~/stack$ crontab -u bitnami -l
0 0 * * * sudo /opt/bitnami/letsencrypt/lego --path /opt/bitnami/letsencrypt --email="xxxxx@mori-soft.com" --http --http-timeout 30 --http.webroot /opt/bitnami/apps/letsencrypt --domains=このサーバーのドメイン名 renew && sudo /opt/bitnami/apache2/bin/httpd -f /opt/bitnami/apache2/conf/httpd.conf -k graceful
bitnami@ip-172-30-0-111:~/stack$
cron と同じコマンドを発行してみて、動作確認しておきます。
bitnami@ip-172-30-0-111:~/stack/letsencrypt$ sudo /opt/bitnami/letsencrypt/lego --path /opt/bitnami/letsencrypt --email="xxxxx@mori-soft.com" --http --http-timeout 30 --http.webroot /opt/bitnami/apps/letsencrypt --domains=このサーバーのドメイン名 renew
2020/06/29 11:05:29 [このサーバーのドメイン名] The certificate expires in 88 days, the number of days defined to perform the renewal is 30: no renewal.
bitnami@ip-172-30-0-111:~/stack/letsencrypt$
大丈夫そうですね。
送信元IPアドレス制限と http でのアクセス
元々 Redmine のサーバーは自分の仕事の管理で使っているので、EC2 のセキュリティグループを使って送信元のIPアドレスを制限していました。また、 http でのアクセスも禁止していました。
今回はこれらに加えて、 Let's Encrypt の更新を有効にしたいと思います。
この条件を整理すると、下記のような動作になると思います。
- サーバーには https でのみアクセスする
- 送信元 IP アドレスを制限する
- Let's Encrypt による更新(http を利用)を有効にする
これを実現するために、 Let's Encrypt の http -> https 転送を設定しました。
この転送設定(/opt/bitnami/apache2/conf/bitnami/bitnami.conf に設定があります)では、
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^localhost
RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
となっています。一部の条件に当てはまるもの以外は https へ転送しています。この一部の条件とは
- localhost へのアクセス
- IP アドレスへのアクセス
- /.well-known へのアクセス
です。なので、 サーバー名/.well-known へのアクセスは https へ転送されないとなっています。
これを踏まえて、セキュリティグループの設定として
- http は送信元IPアドレス制限なし
- https は送信元IPアドレス制限あり
としておけば、 http でアクセスした際は、基本的に https に転送され、https は送信元IPアドレスが制限されているので、許可されたIPアドレスから接続するクライアント以外からは接続できなくなります。
一方、Let's Encrypt が更新に使う /.well-known ディレクトリへの http でのアクセスは https に転送されないので、送信元IPアドレスにかかわらず接続できます。
こうすることで、目的のアクセス制御ができました。
一応、最終的には、
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^localhost
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
として、IPアドレスによる接続も、 https に転送するようにしています(証明書的には意味がありませんが、送信元IPアドレス制限を使いたいためです)。