はじめに
Amazon Linux1 から Amazon Linux2への移行を行いました。
その時、Amazon Linux1 では問題のなかったやり方でAmazon Linux2のタイムゾーン変更設定を行ったところ、**「下手したらなかなか致命的なリスクになるのでは?」**という事象を発見したので書き留めました。
Linuxにバリバリ詳しいわけでは無いので、間違いや微妙な表現などがあったら、ご指摘頂けると助かります!
タイムゾーンの設定
Linuxのタイムゾーンは /etc/localtime
ファイルで設定します。
この/etc/localtime
を各国や地域のタイムゾーンに対応したバイナリファイルに指定することによって、Linux内の時間帯が設定されます。
例えば、日本であれば特段の事情がない限り「日本標準時(JST)」を指定することになります。
各タイムゾーンは/usr/share/zoneinfo/
に格納されています。
※詳しくはこちらを参照↓
デフォルトでは/etc/localtime
がUTCのバイナリファイルとなっています。
その為、 dateコマンドを入力するとUTCの時間帯が返ってきます。
$ strings /etc/localtime
TZif2
TZif2
UTC0
$ strings /usr/share/zoneinfo/Etc/UTC
TZif2
TZif2
UTC0
$ date
Sun Jul 11 14:27:26 UTC 2021 ###日本では7/11 23時27分
Amazon Linux2でやってはいけない変更方法
/etc/localtime
にタイムゾーンファイルをcp
するやり方はしてはいけません。
これは先ほどのリンク先にも紹介されていたやり方だし、ググるとこのやり方を紹介するページをちょくちょく散見します。
昔のLinuxであれば特に問題ないやり方だったのかもしれません(※ Amazon Linux1では問題ないやり方だった)。
「/etc/localtime」には、このファイルの中身をコピーするか、シンボリックリンクを張ることになります。作業例を以下に示します。
○/etc/localtimeの設定例
# date
Wed Dec 12 04:14:10 GMT 2015 ←「GMT」で表示
# cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ←ファイルコピー
# date
Wed Dec 12 13:15:11 JST 2015 ←「JST」で表示
なぜcpでタイムゾーン変更してはいけないか
結論から言うと、Amazon Linux2では
$ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
このようにコピーを行うと、UTCのバイナリファイルである /usr/share/zoneinfo/UTC
と/usr/share/zoneinfo/Etc/UTC
の中身が
/usr/share/zoneinfo/Asia/Tokyo
のファイルになってしまいます。
何故こうなるかというと、Amazon Linux2はデフォルトで /etc/localtime
が/usr/share/zoneinfo/UTC
へのシンボリックリンクになっているからです。
$ ls -la /etc/localtime
lrwxrwxrwx 1 root root 25 Jul 9 02:40 /etc/localtime -> ../usr/share/zoneinfo/UTC
※ちなみに、Amazon Linux1ではシンボリックリンクになってません。
$ ls -la /etc/localtime
-rw-r--r-- 1 root root 118 Dec 25 2012 /etc/localtime
恐らく、Amazon Linux2はCentOS7ベースで作られたOSなので、systemdで制御されるtimedatectl の影響だと思われます。
なので、Amazon Linux2だけでなく、CentOSでも同じ事象が発生するかも知れません。
(ここら辺が詳しく無いので、教えてくれる人がいると幸いです)
これによるリスク
具体的なcodeは記載しませんが、私のプロダクトではRailsで
「受け取った時間dataをUTCとして認識して、JSTの時間dataに変換する」
という処理がありました。
この時、ローカルシステムの /usr/share/zoneinfo/Etc/UTC
を受け取って処理をしているらしいのですが、
既述の通りEtc/UTC
は Asia/Japn
のファイルに上書きされてしまっているので、
「受け取った時間dataをJSTとして認識して、JSTの時間dataに変換する(つまり変換されない)」
という処理に変わってしまいました。
時間が9時間ズレるので大変な事になります・・・
Amazon Linux2でタイムゾーン変更するには
CentOS7ベースで作られて居るので、timedetactlコマンドを使用しましょう。
$ timedatectl set-timezone Asia/Tokyo