crontab の -r オプション対策を考える

crontab の -r オプション対策を考える

Linux 等の Unix ライクな OS で定期的に自動実行したいコマンドがあるときに利用する機能といえば crontab ですが、このコマンドには -r オプションが存在し、このオプションをつけた状態で実行すると警告なしに現在の設定が消去されます。

私は crontab の編集を行う際、-e オプションで編集しています。いつかやるかもしれないとは思っていたものの、ついに先日、一般ユーザ権限でしたが、タイプミスで -r オプションをつけて実行してしまい、復旧のため面倒くさいことになってしまいました。

一度あることは二度あるということで、 -r オプションを実行しても問題ないように対策を考えてみます。

なお、あくまで一個人の考えなので、参考程度にとらえてください。また、Mac の場合は crontab ではなくMac OS X Tiger 以降は launchd への登録を推奨されています。Apple 公式のサポートページはこちら。ただ、推奨されていないものの、まだサポートされているため、対象外にもしておりません。

-r オプションの対策

パッと思いついたものとネットで軽く調べてみつかった対策を以下にまとめてみました。

  1. alias で -r オプションを無効化する
  2. alias で常に -i オプションの付与を行い、-r オプション実行時に確認を求めるようにする
  3. -r オプションを実行しても復旧できるよう、crontab の設定を自動バックアップする
  4. crontab コマンド自体を変更し、-r オプションを無くす
  5. crontab コマンドを使わない。(/etc/cron.d/等にスクリプトを格納する)

4 の crontab コマンド自体の変更は確実ではありますが、やはり OS のコマンドそのものに手を入れるのは抵抗があり、セキュリティ上のリスクもあります。

5 の crontab コマンドを使わず、すべて /etc/cron.d/ や /etc/cron.hourly/ 等に格納するのも確実で、ネットで検索すると crontab コマンドは絶対に利用してはいけない等の記事も見かけますが、やはり crontab タブが利用できないのは不便ですので、今回の対策としては除外します。

1 の -r オプションの無効化と 2 の -i オプションを常に有効化する対策はどちらかの選択になるかと思います。-i オプションは -r が実行されたときに確認を求めるため、実質的に誤操作による登録した cron の消失は防げると考えられるため、2 を選択したいと思います。

ただ、2 の対策だけでは、例えば alias が有効化されていない場合を考えると、十分ではないため、念には念を入れ、3 の自動バックアップも実施したいと思います。

alias によって -i オプションを常に有効化する

以下の設定を各ユーザホームディレクトリの .bashrc または .bash_profile に追加します。

.bashrc or .bash_profile

alias crontab='crontab -i'

なお、設定を有効化するには、一度ログアウトするか、以下コマンドを実行します。(.bash_profile と .bashrc は読み込まれるタイミングが異なるので注意)

#.bashrc の場合
source ~/.bashrc

#.bash_profile の場合
source ~/.bash_profile

設定が有効化されているか確認するには、以下のコマンドを実行します。

alias

以下のような結果が表示されれば OK です。(他の alias 設定も表示しています)

alias cp='cp -i'
alias crontab='crontab -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'

なお、/etc/bashrc に記載すると、全ユーザで有効化される OS が多い(各ユーザごとの .bashrc で読み込んでいることが多い)ので、OS 共通の設定としたい場合は、/etc/bashrc にも設定を追記しましょう。
また、新規ユーザ作成時のみ有効となりますが、/etc/skel/.bashrc や /etc/skel/.bash_profile への追記も効果があります。

crontab の設定を自動バックアップする

root も含めた、各ユーザごとの crontab の設定を自動でバックアップします。OS ごとに設定が格納されている領域が異なるので注意が必要です。

バックアップの取得世代は 1 世代取得することとします。以下のようなコマンドを root の crontab に登録します。

1 世代としているのは、rsync の –delete オプションを有効化していないため、誤って -r オプションを実行して消えたとしても、バックアップにファイルごと残るためです。

Linux の場合
crontab 設定の格納領域:/var/spool/cron/
バックアップの保存先:/backup/cron/

#以下を root の crontab に登録 (毎日 3 時にバックアップする場合)
0 3 * * * /usr/bin/rsync -a /var/spool/cron/ /backup/cron > /dev/null 2>&1

Mac の場合
crontab 設定の格納領域:/var/at/tabs/
バックアップの保存先:/var/backups/cron/

#以下を root の crontab に登録 (毎日 3 時にバックアップする場合)
0 3 * * * /usr/bin/rsync -a /var/spool/cron/ /var/backups/cron > /dev/null 2>&1

ただ、冒頭でも記載したとおり、Mac は crontab に代わって launchd の利用を推奨されているため、いつかはサポートを切られる可能性がありますので、それを理解した上で crontab を利用しましょう。