プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

CloudWatch Agent を試してみました

さて、こちらの記事で書いたように、自分用の Redmine を 4.1.1 にアップデートしました。この際、サーバーも新たにしました。

以前、下記の記事で書いたようにディスク容量がひっ迫してえらい目にあったので、今回もディスクの空き容量の監視を行いたいと思います。

blog.mori-soft.com

更新前のサーバー(Redmine 3.3.2 を運用)では CloudWtach スクリプトを利用して、ディスク容量監視を行っていました。設定方法などはこちらの記事にありますのでご参考にどうぞ。

今回も同じようにすればよいと思い調べてみると、昨今は Cloudwatch スクリプトではなくて、CloudWatch Agent を使うのが良いようです。

ということで、試してみたので、メモっときます。

Cloudwatch Agent によるディスク使用量の監視

まず、 CloudWtach Agent がどんなものか調べてみました。

Amazon Systems Manager と統合されていたり、インスタンス内のログを CloudWtach で管理できたりと非常に便利そうです(使わないけど)。

ま、まずは試してみないとなんとも言えないので、やってみます。

IAM ロールの作成

CloudWatch Agent を使うには IAM ロールがいるとのことなので、作成します。

AWS のコンソールで IAM を選び、ロールの作成を選択します。サービスとして、EC2を選びます。

f:id:junichim:20200701165339p:plain

次に、ポリシーとして、 CloudWatchAgentServerPolicy を選択します。 Amazon Systems Manager は使わないので、 CloudWatchAgentAdminPolicy は不要です。

f:id:junichim:20200701165505p:plain

あと、ロール名を適当に設定すれば完了です。

f:id:junichim:20200701165654p:plain

これを EC2 のインスタンスに割り当てます。 割り当てたいインスタンスを選び、

f:id:junichim:20200701165813p:plain

アクションから、『インスタンスの設定』、『IAMロールの割り当て/置換』と進みます。

f:id:junichim:20200701170004p:plain

割り当て設定画面で、先ほど作成した IAM ロール名を選択すれば完了です。

インストール

実際に作業する際の手順は下記を参考にしました。

コマンドラインを使用して CloudWatch エージェントをインストールする - Amazon CloudWatch

インストールはコマンドラインから行います。

ダウンロード

bitnami@ip-172-30-0-111:~$ wget https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/debian/amd64/latest/amazon-cloudwatch-agent.deb
--2020-06-28 18:25:35--  https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/debian/amd64/latest/amazon-cloudwatch-agent.deb
s3.ap-northeast-1.amazonaws.com (s3.ap-northeast-1.amazonaws.com) をDNSに問いあわせています... 52.219.136.54
s3.ap-northeast-1.amazonaws.com (s3.ap-northeast-1.amazonaws.com)|52.219.136.54|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 57648712 (55M) [application/octet-stream]
`amazon-cloudwatch-agent.deb' に保存中

amazon-cloudwatch-agent.deb                 100%[==========================================================================================>]  54.98M  91.3MB/s 時間 0.6s

2020-06-28 18:25:36 (91.3 MB/s) - `amazon-cloudwatch-agent.deb' へ保存完了 [57648712/57648712]

bitnami@ip-172-30-0-111:~$

パッケージのインストール

bitnami@ip-172-30-0-111:~$ sudo dpkg -i -E amazon-cloudwatch-agent.deb
以前に未選択のパッケージ amazon-cloudwatch-agent を選択しています。
(データベースを読み込んでいます ... 現在 31402 個のファイルとディレクトリがインストールされています。)
amazon-cloudwatch-agent.deb を展開する準備をしています ...
create group cwagent, result: 0
create user cwagent, result: 0
amazon-cloudwatch-agent (1.246396.0-1) を展開しています...
amazon-cloudwatch-agent (1.246396.0-1) を設定しています ...
bitnami@ip-172-30-0-111:~$

特に問題もなくパッケージがインストールされました。

設定

CloudWtach Agent の設定はウィザードでやるのが簡単なようです。

bitnami@ip-172-30-0-111:~$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
default choice: [1]:
1
Trying to fetch the default region based on ec2 metadata...
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]:
1
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]:
1
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:
1
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:
2
Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]:
1
Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for specific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]:
4
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
2
Current config as follows:
{
// 中略
}
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]:
1
Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]:
2
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:
2
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.
Current config as follows:
{
// 中略
}
Please check the above content of the config.
The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:
2
Program exits now.
bitnami@ip-172-30-0-111:~$

中略としているところでは、作成されたjsonファイルが表示されています。 ほとんどがデフォルトを選べば問題ないようです。なお、メトリクスの種類として、ディスクの i-ノードの残り容量を知りたかったので、 Standard を選択しています。

試用

設定が終わったら、起動してみます。

bitnami@ip-172-30-0-111:~$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
/opt/aws/amazon-cloudwatch-agent/bin/config-downloader --output-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d --download-source file:/opt/aws/amazon-cloudwatch-agent/bin/config.json --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
Successfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_config.json.tmp
Start configuration validation...
/opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --input-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
2020/06/28 21:12:56 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_config.json.tmp ...
Valid Json input schema.
I! Detecting runasuser...
No csm configuration found.
No log configuration found.
Configuration validation first phase succeeded
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -schematest -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
Configuration validation second phase succeeded
Configuration validation succeeded
Created symlink /etc/systemd/system/multi-user.target.wants/amazon-cloudwatch-agent.service → /etc/systemd/system/amazon-cloudwatch-agent.service.
bitnami@ip-172-30-0-111:~$

動いているか確認します。

bitnami@ip-172-30-0-111:~$ /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
{
  "status": "running",
  "starttime": "2020-06-28T12:12:57+00:00",
  "version": "1.246396.0"
}
bitnami@ip-172-30-0-111:~$

問題ないようです。

しばらくしてから、 AWS のコンソールで CloudWatch のメトリクスを見ると、 カスタムメトリクス CWA が追加されており、ディスク容量などの状態を見ることができました。

費用問題

さて、これでディスク容量も監視できるようになったし、めでたしめでたし、と終わりたかったのですが、よくよく考えてみるとカスタムメトリクスが結構大量に追加されています。これって、お金かかるんじゃなかったっけ?と思い出して、調べてみました。

すると、今回の場合はカスタムメトリクスが28個も追加されてて、0.3/メトリクス/月なので、約$8.5ぐらい毎月かかることになります。

マジ!?

EC2のインスタンス代よりはるかに大きいです・・・

せっかく、EC2 のインスタンス代を抑えようとしてスポットインスタンスをつかったりしてたのに、本末転倒感がたっぷりです(まあ、監視も必要なので、本当は本末転倒ではないんですがね)。

ということで、このままで使い続けるわけにはいかないので、一旦アンインストールしておきます。

アンインストール

とりあえず、メトリクスの送信を停止します。

bitnami@ip-172-30-0-111:~$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a stop
bitnami@ip-172-30-0-111:~$ 
bitnami@ip-172-30-0-111:~$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
{
  "status": "stopped",
  "starttime": "",
  "version": "1.246396.0"
}
bitnami@ip-172-30-0-111:~$ 

改めて、状態を確認します。

bitnami@ip-172-30-0-111:~$ sudo systemctl status amazon-cloudwatch-agent.service 
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Tue 2020-06-30 08:34:15 JST; 2min 55s ago
  Process: 2302 ExecStart=/opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwatch-agent (code=killed, signal=TERM)
 Main PID: 2302 (code=killed, signal=TERM)

 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: Stopping Amazon CloudWatch Agent...
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: amazon-cloudwatch-agent.service: Main process exited, code=killed, status=15/TERM
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: amazon-cloudwatch-agent.service: Succeeded.
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: Stopped Amazon CloudWatch Agent.
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
bitnami@ip-172-30-0-111:~$ 

このままだと再起動するとサービスが始まるので、無効にしておきます。

(参考) https://forums.aws.amazon.com/thread.jspa?messageID=908106

bitnami@ip-172-30-0-111:~$ sudo systemctl disable amazon-cloudwatch-agent.service 
Removed /etc/systemd/system/multi-user.target.wants/amazon-cloudwatch-agent.service.
bitnami@ip-172-30-0-111:~$ 
bitnami@ip-172-30-0-111:~$ sudo systemctl status amazon-cloudwatch-agent.service 
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
   Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: Stopping Amazon CloudWatch Agent...
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: amazon-cloudwatch-agent.service: Main process exited, code=killed, status=15/TERM
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: amazon-cloudwatch-agent.service: Succeeded.
 6月 30 08:34:15 ip-172-30-0-111 systemd[1]: Stopped Amazon CloudWatch Agent.
bitnami@ip-172-30-0-111:~$ 

まあ、このままにしておいてもいいんですが、ついでなのでパッケージも削除しておきます。

bitnami@ip-172-30-0-111:~$ sudo dpkg -r amazon-cloudwatch-agent 
(データベースを読み込んでいます ... 現在 32407 個のファイルとディレクトリがインストールされています。)
amazon-cloudwatch-agent (1.246396.0-1) を削除しています ...
bitnami@ip-172-30-0-111:~$ 

ゴミ収集

bitnami@ip-172-30-0-111:~$ sudo rm -rf /opt/aws/

これでアンインストールされました。

メトリクスは自分で削除することはできなくて、一度メトリクスを追加したら15ヶ月は消えないそうです・・・・ 高い授業料になりました。

次善策

ということで、 CloudWatch Agent は便利そうですが、お金もそれなりに必要なので今回は採用を見合わせました。

じゃあ、どうやって監視するのがいいのか? 例えば、

  • 既にサポート外となった、 CloudWatch スクリプトを使う
  • zabbixサーバー立てる
  • 自分でディスク容量調べて、メール通知する
  • etc

なんかが頭に浮かんでますが、どうするのがいいか、決めきれていません。 あー、悩ましい。 しばらく考えてみようと思います。

一応、モニタリングスクリプトの記事もまだあります。

Amazon EC2 Linux インスタンスのメモリとディスクのメトリクスのモニタリング - Amazon Elastic Compute Cloud

Redmine のアップデート 3.3.2 -> 4.1.1

下記の記事で仕立てた 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 を選び、インスタンスの設定でスポットインスタンスを選択します。

f:id:junichim:20200701085506p:plain

上限金額(今回はオンデマンドの料金未満としました)を入力し、もしも停止しても再度インスタンスを立ち上げ直したいので『永続的リクエスト』には忘れずにチェックを入れます。また、『中断動作』として『停止』を選んでおきます。

あとは、デフォルト設定で起動すれば、新しい環境が出来上がりです。 次は、データのマイグレーションになります。

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

編集します。最終的に下記のような設定としました。

# Example for a user configuration file ~/.msmtprc
#
# This file focusses on TLS and authentication. Features not used here include
# logging, timeouts, SOCKS proxies, TLS parameters, Delivery Status Notification
# (DSN) settings, and more.


# Set default values for all following accounts.
defaults

# Use the mail submission port 587 instead of the SMTP port 25.
port 587

# Always use TLS.
tls on

# Set a list of trusted CAs for TLS. The default is to use system settings, but
# you can select your own file.
#tls_trust_file /etc/ssl/certs/ca-certificates.crt
# If you select your own file, you should also use the tls_crl_file command to
# check for revoked certificates, but unfortunately getting revocation lists and
# keeping them up to date is not straightforward.
#tls_crl_file ~/.tls-crls


# Syslog logging with facility LOG_MAIL instead of the default LOG_USER
syslog LOG_MAIL


# sakura via Amazon SES
account sakura_via_ses

# Host name of the SMTP server
host xxxxx.xxxxxx.amazonaws.com

# As an alternative to tls_trust_file/tls_crl_file, you can use tls_fingerprint
# to pin a single certificate. You have to update the fingerprint when the
# server certificate changes, but an attacker cannot trick you into accepting
# a fraudulent certificate. Get the fingerprint with
# $ msmtp --serverinfo --tls --tls-certcheck=off --host=smtp.freemail.example
#tls_fingerprint 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33

# Envelope-from address
from xxxxx@mori-soft.com

# Authentication. The password is given using one of five methods, see below.
auth on
user (Amazon SES のユーザー名)

# Password method 1: Add the password to the system keyring, and let msmtp get
# it automatically. To set the keyring password using Gnome's libsecret:
# $ secret-tool store --label=msmtp \
#   host smtp.freemail.example \
#   service smtp \
#   user joe.smith

# Password method 2: Store the password in an encrypted file, and tell msmtp
# which command to use to decrypt it. This is usually used with GnuPG, as in
# this example. Usually gpg-agent will ask once for the decryption password.
#passwordeval gpg2 --no-tty -q -d ~/.msmtp-password.gpg

# Password method 3: Store the password directly in this file. Usually it is not
# a good idea to store passwords in plain text files. If you do it anyway, at
# least make sure that this file can only be read by yourself.
#password secret123
password (Amazon SES のパスワード)

# Password method 4: Store the password in ~/.netrc. This method is probably not
# relevant anymore.

# Password method 5: Do not specify a password. Msmtp will then prompt you for
# it. This means you need to be able to type into a terminal when msmtp runs.


# A second mail address at the same freemail service
#account freemail2 : freemail
#from joey@freemail.example


# The SMTP server of your ISP
#account isp
#host mail.isp.example
#from smithjoe@isp.example
#auth on
#user 12345


# Set a default account
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 # bncert-autorenew
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 に設定があります)では、

  # BEGIN: Enable HTTP to HTTPS redirection
  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]
  # END: Enable HTTP to HTTPS redirection

となっています。一部の条件に当てはまるもの以外は 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アドレスにかかわらず接続できます。

こうすることで、目的のアクセス制御ができました。

一応、最終的には、

  # BEGIN: Enable HTTP to HTTPS redirection
  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]
  # END: Enable HTTP to HTTPS redirection

として、IPアドレスによる接続も、 https に転送するようにしています(証明書的には意味がありませんが、送信元IPアドレス制限を使いたいためです)。

自宅環境のもろもろを整備

コロナウィルスの緊急事態宣言も解除され、なんとなく元に戻っていくような雰囲気があります。個人的には、子供の学校が再開されたことで、大きく元に戻ってきたな感を感じています。

今更感もありますが、せっかくなので、子供の休校に伴い家で過ごす時間が増えたときに自宅の環境をいろいろと整えましたことをメモにして残しておきます。

ノートPCの更新

別記事にまとめたように、この機に、自宅の古いノートPCを更新しました。

Thinkpad T410 を Windows 10 にアップグレードしました - プログラマーのメモ書き

Thinkpad T410 の HDD を SSD に換装 - プログラマーのメモ書き

その際に、 WIndows 10 の設定として

  • 家庭内ネットワークなので、ネットワークの設定を パブリックからプライベートに変更
  • SMB v1 の自動削除を無効に変更

などをやっておきました。

ネットワーク設定をプライベートに変更

ネットワーク設定のほうは、WIndows 10 の場合、スタートメニューの『設定』から『ネットワークとインターネット』を開き、

f:id:junichim:20200606144536p:plain

『接続プロパティの変更』を選択すると、『ネットワークプロファイル』のところで、

f:id:junichim:20200606144713p:plain

パブリックとプライベートが選択できるので、プライベートを選択しておきます。

SMB v1 の自動削除を無効

こちらは、コントロールパネルの『プログラムと機能』から、『Windows の機能の有効化または無効化』を選択します。 『SMB 1.0/CIFS ファイル共有のサポート 』を開いて、『SMB 1.0/CIFS 自動削除』にチェックが入っているのを外しておきます。

f:id:junichim:20200606145212p:plain

これで、自動削除されなくなります。

NAS 共有設定の変更

自宅のNASは、古い Netgear の ReadyNas Ultra 2 をまだ使っています。 で、 今まで(Windows 7 時代)は問題なかったのですが、Windows 10 からこの共有フォルダへアクセスしようとするとうまくアクセスできません。ユーザー認証した状態でも、具体的にはフォルダによって、ファイルの更新ができたり、できなかったりします。

ちょっと調べてみたところ、どうも WIndows 10 からはゲストアクセスができなくなったようです。共有フォルダがゲストアクセスで使っていたので、それに引っかかったようです。

https://support.microsoft.com/ja-jp/help/4046019/guest-access-in-smb2-disabled-by-default-in-windows-10-and-windows-ser

ただ、上記のページを見ると、SMB v1 には影響しないとあるんですが、実際 SMB v1 時代の NAS にアクセスできなくなってますね。

後者のフォルダによって、ファイルの更新ができたりできなかったりというのは、共有フォルダ内の所有者・グループの設定がおかしかったのが原因でした。このため、ユーザー認証してもうまく読み書きができなかったこともわかりました。

なので、そのあたりを更新して、整理しました。

設定方法

今のNASの使い方としては、家族内で使っているだけなのと、お互いにみられると困るものがない(とはいえ、基本的にはお互いを信頼して見ない)ような状態です。 なので、いったん、すべてのファイルの所有者として、代表のユーザーを設定したうえで、同じグループのユーザーもアクセスできるようにします。

まずは NAS のコントールパネルにログインします。次に、『共有』、『共有リスト』と進み、設定を行いたい共有フォルダのいずれかのプロトコルのアイコンをクリックします。

f:id:junichim:20200606145722p:plain

表示された設定画面で、『CIFS』タブを選択し、

f:id:junichim:20200606153137p:plain

『ゲストアクセスを許可する』のチェックを外しておきます。次に、『詳細設定』タブを選択します。

f:id:junichim:20200606154111p:plain

『共有フォルダの所有者』および『共有フォルダのグループ』に新たに設定したいユーザー名とグループ名を入力します。 また、グループのアクセス権として、リード・ライトを許可し、その他には、無効としておきます。家族は同じグループに属しているので、これで問題なくアクセスできます。

あと、

この共有の既存のファイルやフォルダに関する所有者とアクセス権を、上のように設定します。 セキュリティレベルを変更し、ファイルアクセスの問題を回避するには、このオプションが便利です。

のオプションにチェックをつけて有効にし、画面下部の『適用』ボタンを押します。

これで、共有フォルダ内のユーザーとグループが、指定したものに置き換えられます。

ルータ、ハブの電源の見直し

夏前でもあるので、気休めですが、ルータとハブの電源を、サージ付きコンセント・タップからとるようにしました。

そのうちの一つがコンセント直付けで使うタイプ

だったのですが、つけたらずっと赤いランプが点灯しています。

f:id:junichim:20200518093018j:plain

この手のランプって、サージが働いた時につくんじゃないか?と思って慌てて調べてみると、どうも普段の時にランプが点く仕様のようです。

BSTAPD01WH : 電源タップ | バッファロー

ちゃんと書いてありました。なので、私の確認不足ですね。

でも、これは反対にしてほしいです、どうでしょうか? > Buffalo さん

とまあ、こんな感じで、多少、自宅環境を快適に整備してみました。