毎週次のエラーメールが届きます。 cron、logrotate、またはdenyhostsのいずれかに問題があるようです。どちらかわかりません。
Subject: Cron <root@vps> test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
/etc/cron.daily/logrotate:
test: 91: /etc/hosts.deny: unexpected operator
助言がありますか?
/etc/logrotate.d/denyhostsは非常に短く、テストを使用していないようです。
はい、しかしそれはこれを持っています:
postrotate
/etc/init.d/denyhosts restart > /dev/null
endscript
そのスクリプトは次のようなことをします
HOSTS_DENY=$(grep ^HOSTS_DENY $CONFIG | cut -d = -f 2)
test -e $HOSTS_DENY || touch $HOSTS_DENY
スクリプトが正しいと仮定すると、推測しなければならないのであれば、構成ファイルのHOSTS_DENY行が何らかの形で不正であると言えます。
幸い、推測する必要はありません。このコマンドは、エラーの原因を正確に示します。
/bin/sh -x /etc/init.d/denyhosts restart
/etc/logrotate.d/denyhostsではどうですか?
Denyhostsパッケージをアンインストールした後、これと同じ問題が発生しました。パッケージが実際にインストールされていることを確認します。
mlambie@prime:~$ dpkg -l | grep denyhosts
rc denyhosts 2.6-6.1ubuntu1 a utility to help sys admins thwart SSH crac
パッケージがインストールされている場合、最初の2文字は「ii」になります。たとえば、openssh-serverをインストールして、次の結果を取得します。
mlambie@prime:~$ dpkg -l | grep openssh-server
ii openssh-server 1:5.3p1-3ubuntu7 secure Shell (SSH) server, for secure access
私の場合、パッケージが削除されたときにlogrotate構成が正常に削除されなかったと思うので、手動でrmしました。
私には、/ etc /hosts.denyまたは/etc/cron.daily/logrotateの91行目にエラーがあるように見えます。
Hosts.denyのエントリが有効にフォーマットされていることを確認してください。
/etd/logrotate.d/denyhostsは非常に短く、テストを使用していないようです。
/var/log/denyhosts {
create 0640 root root
missingok
weekly
rotate 7
compress
postrotate
/etc/init.d/denyhosts restart > /dev/null
endscript
}
/ etc内のファイルの91行目の「test」の唯一のインスタンスは、無関係のファイルにあります。
Cron.daily/logrotateジョブは/ usr/sbin/logrotate(バイナリファイル)にあります-バグがそこにある場合、どこでソースコードを確認できますか?
私の賭けは、sh
コマンドに単一の等号( "=")ではなく二重の等号( "==")を持つtest
スクリプトがあることです。 Bashの組み込みのtest
は==
または=
を許可しますが、Bourne Shell(Ubuntuでは少なくともdash
)は=
のみを許可します。また、私の/usr/bin/test
は単一の等しいもののみを許可します。ただし、これと同じエラーが発生する他の例については、この回答の下部を参照してください。
logrotate.conf
を調べて、その問題が発生している可能性のある行91があるかどうかを確認します。
何らかの理由で、テスト用にエラーメッセージを再作成する場合:
次の内容のファイルを「a」と呼びましょう。
echo 'In script "a"'
f="/etc/hosts.deny"
test $f == "foo"
今やる:
sh a
あなたは得るべきです:
In script "a"
test: 3: /etc/hosts.deny: unexpected operator
次のいずれかを使用して、同様のエラーを再現することもできます。
sh -c "test /etc/hosts.deny +"
sh -c "test /etc/hosts.deny -"
sh -c "test /etc/hosts.deny /"
sh -c "test /etc/hosts.deny *"
編集:検索を絞り込むには、次のことを試してください。
$ su -
$ find /etc -type f | xargs awk 'FNR==91 && /test/ {print FILENAME, $0}'
ルートにsu
してから、find
/awk
コマンドを実行します。 /etc
の下の各ファイルについて、「test」という単語がその行に表示されている場合は、ファイル名とファイルの91行目が表示されます。次に、正しくない演算子を探すことができます。
正気のためだけにあなたは使いたいかもしれません:
foo:~# which test
/usr/bin/test
テストプログラムがあなたが思っているものであることを確認します。防御的なプログラミング方法の1つは、cronジョブのコマンドへのフルパスを使用することです。これにより、適切なバイナリが確実に呼び出され、攻撃者がPATHの前半で同様の名前の別のコマンドに置き換えることを防ぎます。
ここにいくつかのトラブルシューティングのヒントがあります。ジャスティンは絶対に正しい方向に進んでいると思います。問題はおそらくdenyhostsの設定にあります。しかし、それを追跡しましょう。
もともとlogrotateからエラーが発生しています。したがって、logrotateを実行します。
logrotate /etc/logrotate.conf
エラーが発生したと仮定すると、少なくとも再現可能なケースがあります。ここで、問題がlogrotateにあるのかdenyhostsにあるのかを見てみましょう。 logrotateで見たdenyhostsコマンドを使用してみましょう。
/etc/init.d/denyhosts restart > /dev/null
それがあなたにエラーを与えるならば、あなたはこれを追跡することに本当に近いです。詳細については、行末から「>/dev/null」を削除してみてください。ヘルプが必要な場合は、ここに出力を投稿してください。
ただし、上記の2つのトリックのどちらでもエラーが発生しない場合でも、cronジョブからエラーが発生する場合は、問題が発生しています。何かをデバッグする試みの間に1週間待つのは大変です。
/ etc/crontabに別の行を追加します。 cron.weekly行をコピーして、他のすべての行の下に貼り付けます。次に、すべての「when」エントリがアスタリスクになるように編集します。
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
これを次のように変更します。
* * * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
その後、1分に1回、1日中、1週間中実行されます。これは明らかにnotそこに残したいものですが、トラブルシューティングに役立つ場合があります。
コマンドラインからスクリプトを実行したときに表示されないcronジョブのエラーが表示される場合、ほとんどの場合、環境の違いです。最初にパスを確認してください。