So-net無料ブログ作成

cronとanacronの連携 [Linux]

Linux のジョブスケジューリングは、cron と anacron の連携により行われている。
これまで、断片的に調べたことはあったが、連携という観点で調べたことはなかった。
以下は、連携という観点で調査した結果を備忘録としてまとめたものである。

1. 機能の特徴


(1) cron


・常駐プロセス(crond) が存在する。
・ジョブを実行する日時を正確に指定する。
・設定ファイルの同じエントリを 1 日に複数回実行できる。
・ユーザー毎に設定ファイルを作成できる。

(制限事項)
・(OS 停止中等により)実行できなかったジョブを再実行できない。
・同じ設定ファイルを複数のノードで使用した場合、問題が発生することがある。
 (ジョブの実行時刻に共有リソースが高負荷となることがある。)


(2) anacron


・常駐プロセスはなく、必要な時に anacron コマンドを実行する。
・ジョブの実施間隔(日数)、実行する時間帯を指定する。
 (厳密に日時を設定するものではない。)
・(OS 停止中等により)実行できなかったジョブを再実行できる。
 (実行時刻を厳密に指定しないため。)
・同じ設定ファイルを複数のノードで使用しても、問題が発生しない。
 (実行時刻をランダムに決定するため、共有リソースへの負荷の集中がない。)

(制限事項)
・ジョブを実行する日時を正確に指定することはできない。
・設定ファイルの同じエントリは、1 日 1 回しか実行できない。
・root しか設定ファイルを作成できない。


2. 設定ファイル


(1) cron


・/etc/crontab
・/etc/cron.d/*
・/var/spool/cron/*


(2) anacron


・/etc/anacrontab


3. cron と anacron の連携

3-1. CentOS 6/7 の場合


(1) anacron の起動


下記の順序で、cron から anacron が起動される。

(a) /etc/cron.d/0hourly

毎時 01 分に /etc/cron.hourly/* を実行する。


(b) /etc/cron.hourly/0anacron

'/usr/sbin/anacron -s' を実行する。


ただし、同じ日に anacron が既に実行されている場合には、実行しない。
(/var/spool/anacron/cron.daily に直近の実行日を保存している。)


(2) /etc/cron.{daily,weekly,monthly}/* の実行


(a) /etc/anacron


/usr/sbin/anacron により、このファイルが参照される。
また、設定されているジョブが実行される。

(例)
# These replace cron's entries
1          5  cron.daily    run-parts --report /etc/cron.daily
7         10  cron.weekly   run-parts --report /etc/cron.weekly
@monthly  15  cron.monthly  run-parts --report /etc/cron.monthly

3-2. Debian 7/8 の場合


anacron がインストールされている場合には、下記のようになる。
インストールされていない場合には、cron のみでの対応となる。
(/etc/cron.{daily,weekly,monthly}/* は、/etc/crontab から実行される。)

(1) anacron の起動


下記の順序で、cron から anacron が起動される。

(a) /etc/cron.d/0anacron

07:30 に '/etc/init.d/anacron start' を実行する。


(b) /etc/init.d/anacron

'/usr/sbin/anacron -s' を実行する。


(補足)
上記以外に、/etc/init.d/anacron は、ランレベル2〜5 で自動起動される。


(2) /etc/cron.{daily,weekly,monthly}/* の実行


(a) /etc/anacron


/usr/sbin/anacron により、このファイルが参照される。
また、設定されているジョブが実行される。

(例)
# These replace cron's entries
1          5  cron.daily    run-parts --report /etc/cron.daily
7         10  cron.weekly   run-parts --report /etc/cron.weekly
@monthly  15  cron.monthly  run-parts --report /etc/cron.monthly

4. 備考


(1) anacron でのジョブの実行時刻の決定方法


/etc/anacrontab の設定値を参照し、下記の手順により決定される。

(a) ジョブの実行が許可された時間帯かどうかの判断


START_HOURS_RANGE に指定された時間帯の場合のみ、処理を継続する。

(例)
START_HOURS_RANGE=3-22


(補足)
未指定の場合には、すべての時間帯で実行可能となると思われる。
(Debian 7/8 では未指定であるが、実行できているため。)


(b) 遅延時間(分単位)の算出


(b-1) エントリ共通の遅延時間の算出


指定されている最大値以下で遅延時間をランダムに算出する。
(最大値: RANDOM_DELAY に指定されている値)
未指定の場合には、0 とする。

(例)
RANDOM_DELAY=45


(b-2) エントリ毎の遅延時間の算出


指定されている遅延時間を取得する。
(各エントリの第 2 項目で指定されている。)


(b-3) エントリ共通/エントリ毎の遅延時間の和を求める。


(c) ジョブの実行時刻の算出


現在時刻に遅延時間を加算した時刻をジョブの実行時刻とする。



ハードウェアクロックの確認方法 [Linux]

ハードウェアクロック(RTC) の値を確認する必要があり、その方法についてまとめてみた。

・ハードウェアクロック: BIOS 設定画面で表示される時刻
・システムクロック: date コマンドで表示される時刻
・通常は、ブート時にハードウェアクロックをシステムクロックにコピーする。
・通常は、シャットダウン時にシステムクロックをハードウェアクロックにコピーする。
・システムクロックのズレについては、NTP 等を使用して補正する。

詳細は、以下の通りである。

1. ハードウェアクロックの表示


(1) systemd が導入されているシステム

# timedatectl [status]
...
        RTC time: xxx
...
 RTC in local TZ: yyy
...


・xxx: 時刻 (タイムゾーンを含まない)
・yyy: タイムゾーン (yes: local TZ, no: UTC)


(2) すべてのシステム

# hwclock --debug
...
Hardware clock is on yyy
...
Time read from Hardware Clock: xxx
...


・xxx: 時刻 (タイムゾーンを含まない)
・yyy: タイムゾーン (local time, UTC)


2. ハードウェアクロックのタイムゾーンのみの確認


(1) systemd が導入されているシステム

# timedatectl [status] | grep TZ


(2) すべてのシステム


(a) hwclock コマンドを使用する場合

# hwclock --debug | grep "is on"


(b) /etc/adjtime を参照する場合

# tail -n 1 /etc/adjtime


・LOCAL: local TZ
・UTC: UTC



last rebootの実行結果が正しくない [Linux]

[ソフトウェアのバージョン]
・systemd 215-17+deb8u4 (on Debian 8)
・systemd-219-19.el7_2.11.x86_64 (on CentOS 7)

1. 発生事象


last reboot の実行結果が正しくない。

・開始時刻のみが 9 時間進んだ時刻となる。

(誤) -- 時間の逆行が発生
reboot   system boot  3.16.0-4-686-pae Wed Jul 27 10:00 - 01:14  (-8:-45)
reboot   system boot  3.10.0-229.20.1. Sat Jul 23 09:12 - 00:18  (-8:-53)

(正) -- 開始時刻を 9 時間遅らせた場合
reboot   system boot  3.16.0-4-686-pae Wed Jul 27 01:00 - 01:14  (00:14)
reboot   system boot  3.10.0-229.20.1. Sat Jul 23 00:12 - 00:18  (00:06)


(補足)
・ハードウェアクロック(RTC) のタイムゾーンに local TZ (JST) を設定している。
・Debian 7/8、CentOS 6/7、Windows 7 でマルチブートを行っている。
 (Debian 7、CentOS 6、Windows 7 の RTC のタイムゾーン: local TZ (JST))
・Debian 7、CentOS 6 では発生しない。
・Debian 7、CentOS 6 の last コマンドを使用しても状況は変わらない。
 (/var/log/wtmp に保存されている値の問題である。)
・上記以外で時間に関する問題は発生していない。


2. 原因と対処方法


(1) systemd のバグとの情報がある。


RTC のタイムゾーンに local TZ を設定した場合に対応できていない。
(完全には対応できていない。)

(補足)
timedatectl コマンドでもその旨のワーニングが出力される。

# timedatectl status
...
 RTC in local TZ: yes
...

Warning:
The system is configured to read the RTC time in the local time zone. This
mode can not be fully supported. It will create various problems with time
zone changes and daylight saving time adjustments. The RTC time is never
updated, it relies on external facilities to maintain it. If at all
possible, use RTC in UTC by calling 'timedatectl set-local-rtc 0'.


(2) RTC のタイムゾーンを UTC に統一することで改善されるとの情報がある。


下記の事象に基づいており、理論的には正しいと思われる。

・systemd は RTC のタイムゾーンを UTC に設定することを前提としている。
・マルチブートするすべての OS で、RTC のタイムゾーンを統一する。


(3) 今回は何もしない。


下記の理由により、今回は何もしない。

・last reboot の実行結果以外での問題は発生していない。
・hwclock --systohc の実行により、RTC を更新できている。
・BIOS 設定画面で表示される時刻を統一したい。


[追記]


Linuxのログイン履歴のバックアップ [Linux]

先日、Linux のログイン履歴の外部メディアへのバックアップに関する相談を受けた。
少々面白い話題であったので、そのやり取りの要点をまとめてみた。

1. ログイン履歴の所在


Linux のログイン履歴は、下記のファイルに保存されている。
また、これらはバイナリ・ファイルであり、特定のコマンドの実行によりテキスト・データでの情報が取得できる。

(1) /var/log/wtmp


・ログインに成功した場合のログイン履歴
・last コマンドを実行することでテキスト・データでの情報が取得できる。
・-f オプションで参照するファイルを指定可能
 (デフォルト値は、/var/log/wtmp である。)


(2) /var/log/btmp


・ログインに失敗した場合のログイン履歴
・lastb コマンドを実行することでテキスト・データでの情報が取得できる。
・-f オプションで参照するファイルを指定可能
 (デフォルト値は、/var/log/btmp である。)


(補足)
バイナリ・ファイルからテキスト・データを抜き出し整形することも可能であるが、手間がかかったり、整形ミスが発生したりするため、あまり勧められない。


2. テキスト・ファイルでのログが求められる場合の対応


本番環境以外はすべて Windows である場合、このような要件が追加されることがある。

(1) 運用スクリプトの追加作成が許される場合


ログのバックアップの際に、テキスト・ファイルへの変換を行う。

(例)
# last -f <wtmp-file> | gzip -c > wtmp-yyyy-mm-dd.txt.gz
# lastb -f <btmp-file> | gzip -c > btmp-yyyy-mm-dd.txt.gz
# (back up wtmp-*.gz and btmp-*.gz to external media)


(2) 運用スクリプトの追加作成が許されない場合


(a) RedHat 系の場合


/var/log/secure をバックアップする。

・/var/log/secure は、テキスト・ファイルである。
・システムログの authpriv.* が出力される。


(b) Debian 系の場合


/var/log/auth.log をバックアップする。

・/var/log/auth.log は、テキスト・ファイルである。
・システムログの auth,authpriv.* が出力される。


3. 備考


(1) 本番環境とは別に Linux 環境を用意することを勧める。


この提案が受け入れられるなら、バイナリ・ファイルでのバックアップが可能となる。

(補足)
・スキルされあれば、別途費用をかけず構築することが可能がある。
・今回の要件だけなら、minimal 環境で十分である。


(2) バイナリ・ファイルをバックアップする運用をしばらく実施することを勧める。


本番サーバーを含め、どこかのサーバーにバイナリ・ファイルをバックアップする運用をしばらく実施することを勧める。
本当に不要か(テキスト形式でないといけないのか)を見極めるのは、それからでも遅くないと思われる。



fsckの実施条件のカスタマイズ [Linux]

fsck について、実施条件のカスタマイズの必要があり、その仕様をまとめてみた。
詳細は、以下の通りである。

1. 自動実行

1-1. ブート時の fsck の自動実行


/etc/fstab の第 6 項目の値を 0 以外にする。

・通常は、root ファイルシステムには 1、それ以外には 2 を設定する。
・設定値が 0 の場合には、fsck は自動実行されない。

(補足)
ブート時に fsck の実行条件が判断される。
また、fsck の実行が必要と判断された場合には、fsck が実行される。


1-2. fsck が実行される条件


(1) マウント回数による指定


fsck の実行なしにマウントできる回数の最大値を指定する。

(a) 設定値の確認

# tune2fs -l <device-path> | grep -i mount
...
Mount count: 10
Maximum mount count: 30    … fsck の実行なしにマウントできる回数の最大値


(b) 設定値の変更

# tune2fs -c <count> <device-path>


指定できる値は、下記の通りである。
・正の整数: マウント回数の最大値
・0, -1: チェックを無効化する


(2) 時間間隔による指定


最後の fsck の実行からの経過時間を指定する。

(a) 設定値の確認

# tune2fs -l <device-path> | grep -i interval
Check interval: 15552000 (6 months)


(b) 設定値の変更

# tune2fs -i <interval> <device-path>


指定できる値は、下記の通りである。
・x[d]: x 日
・xw: x 週
・xm: x ヶ月
・0: チェックを無効化する


2. 手動実行


ブート時以外でのマウント時に、fsck の実行条件が判断される。
また、fsck の実行が必要と判断された場合には、その旨のメッセージが出力される。
(fsck が自動実行されることはない。)

(補足)
必要なら、アン・マウントし、fsck を実行した後に再度マウントする。


3. 備考


(1) fsck が実行される条件の初期値


ディストリビューション、およびそのバージョンによって異なる。



ファイルの属性のコピー [Linux]

ファイルに関する処理で役立つかも知れない小ネタを紹介する。

1. ファイルのタイムスタンプのコピー
% touch -r rfile file [...]
または
% touch --reference=rfile file [...]


rfile: コピー元のファイル
file: コピー先のファイル


2. ファイルのオーナー情報のコピー
% chown --reference=rfile file [...]


rfile: コピー元のファイル
file: コピー先のファイル


3. ファイル・パーミションのコピー
% chmod --reference=rfile file [...]


rfile: コピー元のファイル
file: コピー先のファイル


4. その他


(1) ファイルのタイムスタンプ(最終更新時刻)での秒の表示

% ls -l [-d] --full[-time] file [...]
または
% stat -c "%n: %y" file [...]


ClamAV (Clam AntiVirus)への移行 [Linux]

1. 背景


これまで Linux 上でのウイルスチェックには、下記のフリー版を使用してきた。

・Avira AntiVir Personal (v2.1)
・BitDefender Antivirus Scanner for Unices

しかし、下記の理由から、もうすぐ使用できなくなる(いつまで使用できるかは不明)。

・Avira AntiVir Personal
 2016-06-30 をもって、Linux 版のサポートが終了となる。

・BitDefender Antivirus Scanner for Unices
 2016-02-02 付けで、今後はサポートされない旨の告知があった。
 また、2016-06-20 時点で、フリー・ライセンスの更新ページがなくなっている。
 (年次でのフリー・ライセンスの更新ができず、ウイルス情報を更新できなくなる。)

このため、ClamAV (Clam AntiVirus) への移行を行った。


2. 要件


・ウイルス情報の更新、ウイルスチェックは cron を使用して時刻指定で起動する。
 (また、必要な場合には、任意のタイミングで手動で起動する。)

・複数の Linux をマルチブートするため、ウイルス情報を共有する。
 (CentOS 6、CentOS 7、Debian 7、Debian 8 で共有する。)

・受信メールのウイルスチェックは、Procmail と ClamAV を組み合わせて実施する。
 (詳細は省略。また、ISP が当該機能を無料で提供する場合には、そちらを使用する。)


3. 前処理


ウイルス情報を共有するため、実行ユーザーの UID、GID を統一する。
設定例は、下記の通りである。

(1) CentOS 6 の場合

# grep clam /etc/group
clam:x:502:
# grep clam /etc/passwd
clam:x:131:502::/var/lib/clamav:/bin/false


(2) CentOS 7 の場合

# grep clam /etc/group
clamupdate:x:502:
# grep clam /etc/passwd
clamupdate:x:131:502::/var/lib/clamav:/sbin/nologin


(3) Debian 7、Debian 8 の場合

# grep clam /etc/group
clamav:x:502:
# grep clam /etc/passwd
clamav:x:131:502::/var/lib/clamav:/bin/false

4. インストール


(1) CentOS 6 の場合


EPEL リポジトリから下記のパッケージをインストールする。

clamav-0.99.1-1.el6.i686
clamav-db-0.99.1-1.el6.i686


(2) CentOS 7 の場合


EPEL リポジトリから下記のパッケージをインストールする。

clamav-0.99.1-1.el7.x86_64
clamav-data-0.99.1-1.el7.noarch
clamav-filesystem-0.99.1-1.el7.noarch
clamav-lib-0.99.1-1.el7.x86_64
clamav-update-0.99.1-1.el7.x86_64


(3) Debian 7、Debian 8 の場合


標準のリポジトリから下記のパッケージをインストールする。

clamav
clamav-base
clamav-freshclam
libclamav7


(補足)
Debian 7 では v0.99、Debian 8 では v0.99.2 がインストールされる。


5. 設定


(1) ウイルス情報の共有のための設定


・/var/lib/clamav/ を 共有ディレクトリに移動する。
・/var/lib/clamav を上記で移動したディレクトリへのシンボリック・リンクにする。


(2) ウイルス情報の更新のための設定


(a) 初期設定の無効化


実施する時刻を独自に設定するため、下記の初期設定を無効にする。

# CentOS 6 の場合
/etc/cron.daily/freshclam

# CentOS 7 の場合
/etc/cron.d/clamav-update

# Debian 7 の場合
/etc/init.d/clamav-freshclam の自動起動

# Debian 8 の場合
clamav-freshclam.service の自動起動


(b) cron への登録


freshclam を実行するためのエントリを追加する。


(3) ウイルスチェックのための設定


(a) cron への登録


clamscan を実行するためのエントリを追加する。


6. 備考


(1) ウイルス情報の取得のために接続するサーバー


下記のファイル内の DatabaseMirror で指定されている。

# CentOS 6、CentOS 7 の場合
/etc/freshclam.conf

# Debian 7、Debian 8 の場合
/etc/clamav/freshclam.conf

(補足)
初期値として指定されているサーバーには複数の IP アドレスが設定されている。
(nslookup の実行結果で確認できる。)
このため、DNS ラウンドロビンによるロードバランシングが行われる。


(2) ウイルス情報の取得時のワーニング


インストールされている ClamAV のバージョンが古い場合に表示される。
(動作上は問題ない。)

(例)
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Local version: 0.99 Recommended version: 0.99.2


また、--no-warnings の指定により、ワーニングの表示を無効化できる。



MewからFirefoxを起動する設定の変更 [Linux]

Mew でのメール参照において、メッセージ内の URL を Firefox のタブで表示する設定を行っており、特に問題なく使用できていた。
しかし、最近、選択する URL によっては、Firefox を起動できないという問題が発生するようになってしまった。そこで、左記問題への対応を行った。
詳細は、以下の通りである。

1. 発生事象


Mew のメール参照において、メッセージ内の URL の選択による Firefox の起動ができないことがある。

・問題を発生する URL とそうでない URL が存在する。
・選択した URL は、指定したスクリプトに正しく引き渡されている。
・上記スクリプトを手動で実行した場合には、問題は発生しない。
・ソフトウェアのバージョン: Mew 6.3/6.4/6.6、Firefox ESR 38.8.0/45.1.1

(1) 関係する設定 (~/.mew.el)

;; browse specified URL (with Firefox)
(setq browse-url-browser-function 'browse-url-firefox)
(setq browse-url-firefox-program "firefox-mew")
(define-key mew-message-mode-map "B" 'browse-url-at-point)
(define-key mew-message-mode-map [mouse-2] 'browse-url-at-mouse)


・firefox-mew は、URL($1の値) を指定して Firefox(スクリプト) を実行する。
・Firefox は、バージョン/オプションを指定して firefox コマンドを実行する。
・最終的には、下記のコマンドを実行する。
 exec /usr/local/firefox-<ver>/firefox -P www-<ver> -new-tab <url>


2. 対象方法


下記のいずれかの手順を実施する。


2-1. 対処方法-1


browse-url-firefox を browse-url-generic に変更する。
(今回は、こちらでの対応を行った。)

[変更前]
(setq browse-url-browser-function 'browse-url-firefox)
(setq browse-url-firefox-program "firefox-mew")

[変更後]
(setq browse-url-browser-function 'browse-url-generic)
(setq browse-url-generic-program "firefox-mew")

2-2. 対処方法-2


firefox-mew から直接 firefox コマンドを実行するように変更する。


[追記]


Firefoxのアドオンの整理 [Linux]

久しぶりに Firefox のアドオンの整理を行った。
その結果、下記のアドオンに絞り込んだ。

# Firefox のバージョン
・Firefox 38.8.0 ESR
・Firefox 45.1.1 ESR

1. Adblock Plus


不要な広告表示を抑止する。


2. Classic Theme Restorer


Firefox の UI をカスタマイズする。

(補足)
再起動ボタンの表示にも対応可能である。


3. Flashblock


Flash コンテンツの自動再生を抑止する。


4. gtranslate


Google 翻訳を使用した翻訳機能である。
翻訳の結果を見たいが、元のページを変更されたくないという方にはお薦めである。


5. Stylish


ユーザースタイルシートを管理する。

(補足)
Remove Google left sidebar for any country と自作のスタイルを使用している。


6. Tab Mix Plus


タブ機能を拡張する。

(補足)
タブが 1 個の場合には、タブを非表示にすることも可能である。


7. User Agent Switcher


User Agent を一時的に変更する。

(補足)
Linux 版 Firefox ではログインできないサイトへのログイン時に使用している。


8. Vacuum Places Improved


SQLite ファイルの最適化を行う。


9. YesScript


特定のページ(URL) において、JavaScript の使用を抑止する。

(補足)
通常は無効化しており、必要となった場合に有効化している。


10. 備考


Windows 版 Firefox では、さらに下記のアドオンを使用している。

(1) IE Tab v2


Firefox 上での Internet Explorer のレタリングエンジンの使用を可能にする。


(2) Video DownloadHelper


MP3 ファイルのダウンロード(作成)を行う。
通常は無効化しており、必要な時に有効化している。



ハードウェアクロックのシステムクロックとの同期 [Linux]

systemd を使用している環境では、ハードウェアクロック(RTC) のシステムクロックとの同期(システムクロックに合わせる処理) が行われないようである。このため、現在使用中の環境について、状況と対処方法をまとめてみた。
詳細は、以下の通りである。

1. 状況と対処方法


(1) CentOS 6


シャットダウン、またはリブート時に実施される。
(/etc/init.d/halt)


(2) Debian 7


シャットダウン、またはリブート時に実施される。
(/etc/rc{0,6}.d/K08hwclock.sh -> /etc/init.d/hwclock.sh)


(3) Debian 8 (systemd、ntpd を使用)


実施されない(chronyd を使用する場合を除く)。

このため、下記の対応を実施する。

(a) /usr/sbin/halt.local というファイル名のシェルスクリプトの作成


halt-local.service で実行される。


(b) /usr/sbin/halt.local への設定


下記の設定を追加する。

# synchronize the hardware clock to the system time
hwclock --systohc


(c) halt-local.service の自動起動の設定


自動起動が無効化されている(disabled と出力される)場合には、有効化する。

# systemctl status halt-local.service
(または # systemctl list-unit-files halt-local.service)
# systemctl enable halt-local.service


(4) CentOS 7 (systemd、ntpd を使用)


実施されない(chronyd を使用する場合を除く)。

このため、下記の対応を実施する。

(a) /usr/sbin/halt.local の作成


halt-local.service で実行される。


(b) /usr/sbin/halt.local への設定


下記の設定を追加する。

# synchronize the hardware clock to the system time
hwclock --systohc


(c) halt-local.service の自動起動の設定


自動起動が無効化されている(disabled と出力される)場合には、有効化する。

# systemctl status halt-local.service
(または # systemctl list-unit-files halt-local.service)
# systemctl enable halt-local.service

2. 備考


ログ: /etc/adjtime