SELECT PASSWORD('mypass');
で mysql.user の authentication_string に格納されるのを得られるんですが、MySQL 8から PASSWORD() 関数がなくなったのでどうすればいいかというと、
SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('mypass')))));
こうすればいいです。
と、 @yoku0825 さんに教えてもらいました!
# 最終更新から 24 時間以上経過しているか if [[ "$(find /path/to/file -mtime +0)" != "" ]]; then echo 'OLD!' else echo 'NEW!' fi
-mtime +0 がなぜ「24時間以上前」になるのか?について:
-mtime n ファイルの最終内容更新日時が、基点となる時刻から計算して n 日前に当たれば、真を返す (訳注: 基点となる時刻は、デフォルトでは find を実行している今現在である)。 (snip) なお、デフォルトの動作のように、現在時刻から数えて 24 時間前から 48 時間前までを 1 日前とする
つまり、
なので、
つまり、
-mtime 0 = 最終更新が0日前 = 0時間前から24時間前 -mtime 1 = 最終更新が1日前 = 24時間前から48時間前 -mtime 2 = 最終更新が2日前 = 48時間前から72時間前
次に n の記法について。
数値の引き数は、以下の形で指定することができる。 +n n より大きい。 -n n より小さい。 n ちょうど n。
なので、
-mtime +0-mtime 1 または -mtime 2 または ...となる。
コピー元・先両方に末尾に / をつけて、コピー先のディレクトリまで指定する。
rsync -av /path/to/dir/ remote:/path/to/dir/
rsync -av /path/to/dir remote:/path/to とか別の書き方もあるけどパット見わかりづらいので ダメ 。
ディレクトリの末尾に / をつけるのが肝要。
コピー元・先両方をファイルのパスで指定する、 もしくは、 コピー元をファイルのパスで、コピー先を末尾に / をつけたディレクトリのパスで指定する。
rsync -av /path/to/file remote:/path/to/file もしくは rsync -av /path/to/file remote:/path/to/
コピー元・先でパスが同じなら -R を使うのもよい。コピー先のパス指定ミスが防げるので。
rsync -avR /path/to/dir/ remote:/ rsync -avR /path/to/file remote:/
rsync -av remote:/path/to/file1 remote:/path/to/file2 /path/to/dir/
と書いてもよいが、リモートホスト名は省略できる。
rsync -av remote:/path/to/file1 :/path/to/file2 /path/to/dir/
Managing multiple Postfix instances on a single host に従い、multi instances の設定をした後、その service unit を用意する方法のメモ。
/lib/systemd/system-generators/* などにあるファイルはOS起動時や systemd のリロード (systemctl daemon-reload) 時に実行される
/lib/systemd/system-generators/postfix-instance-generator が含まれているpostfix-instance-generator は、 postconf -h multi_instance_directories の結果に応じて /run/systemd/generator/postfix.service.wants/postfix@postfix-XXX.service な symlink を作る
postmulti -I postfix-XXX -G mta -e create すると、 /etc/postfix/main.cf の multi_instance_directories に /etc/postfix-XXX が追加される/run/systemd/generator/postfix.service.wants/* は、 systemctl start postfix したときに一緒に start されるsystemctl start postfix で子インスタンスも起動される。stopとかrestartも同様子インスタンスの設定したあとに systemctl daemon-reload すればおk
で、apache2 プロセスが次のエラーメッセージを吐いて落ちるという連絡を受けて調べました。これはその原因と対処法のメモです。
[mpm_prefork:emerg] [pid 18633] (43)Identifier removed: AH00144: couldn't grab the accept mutex [mpm_prefork:emerg] [pid 18632] (43)Identifier removed: AH00144: couldn't grab the accept mutex [core:alert] [pid 18624] AH00050: Child 18632 returned a Fatal error... Apache is exiting! [:emerg] [pid 18624] AH02818: MPM run failed, exiting
簡単にいうと、Apache が Mutex に使っているセマフォを systemd-logind が消してしまうのが原因です。
Mutex ディレクティブ のデフォルトは Mutex default で、どの機構が採用されるかは APR に委ねられています。
どの機構が採用されるかはこのようにして確認できます。
$ cat mutex-default.c
#include <apr_portable.h>
int main(int argc, char** argv)
{
printf("%s\n", apr_proc_mutex_defname());
return 0;
}
$ gcc $(apr-config --includes) mutex-default.c $(apr-config --link-ld)
$ ./a.out
sysvsem
存在する IPC セマフォなどの確認は ipcs コマンドでできます。
Apache が起動していれば、セマフォがいくつか表示されるはずです。
$ ipcs -a ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status ------ Semaphore Arrays -------- key semid owner perms nsems 0x00000000 5111808 gyoza 600 1 0x00000000 5144577 gyoza 600 1 0x00000000 5046274 gyoza 600 1 0x00000000 5177347 gyoza 600 1 0x00000000 5210116 gyoza 600 1
systemd-logind はデフォルトで RemoveIPC=yes になっています。
RemoveIPC とは logind.conf(5) によれば次のように説明されています。
RemoveIPC= Controls whether System V and POSIX IPC objects belonging to the user shall be removed when the user fully logs out. Takes a boolean argument. If enabled, the user may not consume IPC resources after the last of the user's sessions terminated. This covers System V semaphores, shared memory and message queues, as well as POSIX shared memory and message queues. Note that IPC objects of the root user and other system users are excluded from the effect of this setting. Defaults to "yes".
つまり、
ということです。
システムユーザーとは、 uid が 999 以下のユーザーのことです。
これで再現します。
通常は Apache はシステムユーザである www-data の権限で起動されるのでこの問題は発生しませんが、この環境では深淵な理由で非システムユーザーで起動していました。
内製のデーモンで IPC を使っていると同じようにハマりそうなので、後者の対処法を採用しました。
Mutex file:/var/lock/apache2 default
# install -d -o root -g root -m 755 /etc/systemd/logind.conf.d/ # cat << EOF > /etc/systemd/logind.conf.d/ipc.conf [Login] RemoveIPC=no EOF # systemctl restart systemd-logind.service
自宅サーバー (!) がちょいちょい落ちるんです。たぶんコンソールには kernal panic 時の oops メッセージが表示されてると思うんですが、モニタは繋いでないし宅内には他にサーバーもいないのでシリアル経由で送信することもできないので確認する術がなく。
で、そういえば netconsole ってのがあったなーと思い出したんで、設定してみた次第です。
ちなみに送信先は GCE の Always Free のインスタンス (ちゃんと中国とオーストラリアからのアクセスはフィルタしています) です。
netconsole は UDP を使います。受信側のポート番号を決めて (6666 とします) 、まずはそれが通るようにフィルタリングの設定をします。
疎通確認はこんな感じで。
# 受信側 sudo tcpdump -i any -nlxX port 6666
# 送信側 echo konyanya-chiwa > /dev/udp/DEST_IP_ADDRESS/6666
echo 'options netconsole netconsole=6665@SRC_IP_ADDRESS/eth0,6666@DEST_IP_ADDRESS/GW_MAC_ADDRESS' | sudo tee /etc/modprobe.d/netconsole.conf echo netconsole | sudo tee -a /etc/modules sudo modprobe netconsole
SRC_IP_ADDRESS
DEST_IP_ADDRESS
GW_MAC_ADDRESS
00:00:5e:00:53:31 な感じで指定試行錯誤するときはこんな感じでおk
sudo modprobe netconsole 'netconsole=6665@SRC_IP_ADDRESS/eth0,6666@DEST_IP_ADDRESS/GW_MAC_ADDRESS' sudo rmmod netconsole
syslog は使わずに udplogger を使いました。
curl -L -o udplogger.c 'https://osdn.net/projects/akari/scm/svn/blobs/head/branches/udplogger/udplogger.c?export=raw' gcc -Wall -o udplogger udplogger.c mkdir /var/log/netconsole udplogger dir=/var/log/netconsole port=6666
送信側で
echo s | sudo tee /proc/sysrq-trigger
すると、受信側で
# /var/log/netconsole/YYYY-MM-DD.log 2020-02-21 13:25:36 192.0.2.100:6665 [271267.178610] sysrq: Emergency Sync
と出力されるはずです。
sudo systemctl edit apt-daily.timer sudo systemctl edit apt-daily-upgrade.timer
どちらも次の内容で保存します。
[Timer] Persistent=false
もしくは、直接ファイルを編集して反映してもよいです。
sudo install -d -o root -g root -m 755 /etc/systemd/system/apt-daily.timer.d cat <<EOF | sudo tee /etc/systemd/system/apt-daily.timer.d/override.conf [Timer] Persistent=false EOF cp -pR /etc/systemd/system/apt-daily.timer.d/ /etc/systemd/system/apt-daily-upgrade.timer.d/ sudo systemctl daemon-reload
Ubuntu 18.04、少なくとも EC2 用の Ubuntu cloud image の 20200131 版 (18.04.4) では、毎日 6:00 頃に apt update と unattended-upgrade (セキュリティ関連の更新パッケージのインストール) が行われる (詳しくは後述) のですが、その時間帯に電源がオフで稼働していなかった場合は、次の OS 起動時に実行される設定になっています。
「その時間帯に電源がオフで稼働していなかった」は、AMI からインスタンスを起動したときも同じ状況になるので、AMI が古ければ古いほど更新パッケージが多くなり、起動直後に負荷が高まったり、しばらく apt install できない (unattended-upgrade がロックを獲得しているので) 時間が続いたりします。
その結果、次のような問題が発生します。
特にオートスケーリングの場合は、一刻も早くインスタンスを投入したいので深刻な問題になります。
またもし、AMI 採取用のインスタンスから日次で AMI を作る運用の場合は、パッケージはほぼ最新であることが期待できます。
というわけで、 OS 起動時の更新処理を実行されないようにした、というお話でした。
まず定期的に更新処理が実施される仕組みの説明から。
次の 2 つの systemd の timer ユニットがトリガーとなります。
apt-daily.timerapt-daily-upgrade.timer内容を確認すると、
$ systemctl cat apt-daily.timer # /lib/systemd/system/apt-daily.timer [Unit] Description=Daily apt download activities [Timer] OnCalendar=*-*-* 6,18:00 RandomizedDelaySec=12h Persistent=true [Install] WantedBy=timers.target $ systemctl cat apt-daily-upgrade.timer # /lib/systemd/system/apt-daily-upgrade.timer [Unit] Description=Daily apt upgrade and clean activities After=apt-daily.timer [Timer] OnCalendar=*-*-* 6:00 RandomizedDelaySec=60m Persistent=true [Install] WantedBy=timers.target
となっており、 apt-daily.timer は毎日 6:00 と 18:00 頃、 apt-daily-upgrade.timer は毎日 6:00 頃に発火するのがわかります。
発火すると、対応する systemd の service ユニットが実行されます。
systemctl cat で確認すると、実行されるコマンドライン (ExecStart) が確認できます。
apt-daily.service
ExecStart=/usr/lib/apt/apt.systemd.daily updateapt-daily-upgrade.service
ExecStart=/usr/lib/apt/apt.systemd.daily installざっくり言うと、
/usr/lib/apt/apt.systemd.daily update は
- apt-get update
- apt-get --download-only dist-upgrade
- unattended-upgrade --download-only
/usr/lib/apt/apt.systemd.daily install は
- unattended-upgrade
を行うためのもので、APT の設定で個別に実施する/しないを制御することができます。
デフォルトでの次のような設定になっていて、
$ apt-config dump | grep Periodic APT::Periodic ""; APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "0"; APT::Periodic::AutocleanInterval "0"; APT::Periodic::Unattended-Upgrade "1";
apt-get update 実施する--download-only 系は実施しないunattended-upgrade 実施するという挙動になります。
ここまでが定期的に実行される仕組みの説明で、次からは主題の OS 起動時の更新処理の仕組みについてです。
timer ユニットの定義をみると Persistent=true というのがあり、これがキモです。
systemd.timer(5) から引用すると
Persistent=
Takes a boolean argument. If true, the time when the service unit was last triggered is stored on disk. When the timer is activated, the service unit is triggered immediately if it would have been triggered at least once during the time when the timer was inactive. This is useful to catch up on missed runs of the service when the system was powered down. Note that this setting only has an effect on timers configured with OnCalendar=. Defaults to false.
とのことなので、冒頭の方法で Persistent=false と上書き設定したわけです。
定期的なのも含め一切の自動的な更新処理をオフにしたい場合は、 /usr/lib/apt/apt.systemd.daily に
# check if the user really wants to do something AutoAptEnable=1 # default is yes eval $(apt-config shell AutoAptEnable APT::Periodic::Enable) if [ $AutoAptEnable -eq 0 ]; then exit 0 fi
という処理があるので
echo 'APT::Periodic::Enable "0";' | sudo tee /etc/apt/apt.conf.d/99disable-periodic
とかするといいんじゃないかと思います。
あと /etc/cron.daily/apt-compat という crontab があるんですが、
if [ -d /run/systemd/system ]; then exit 0 fi
となってるので systemd な環境では無いのと同じです。