diskfullのときの原因ドリリング

1日でつみあがったログファイル、ン十GB。しかもエラーログ。これシステムの脆弱性じゃないの?と思う一方、調査の仕方をメモ。

参考にしました。ありがとうございます

qiita.com

ディスクドライブ単位の使用状況を見る

df -h

-hは単位を適切に表示するオプション。

フォルダごとにディスク使用率を見る

ディレクトリやファイルへのアクセス権が必要なので root権限にしておく。

du -sh /var/log/*

-hは単位を適切に表示するオプション。 -sはファイルごとの詳細を表示するオプション。

怪しいディレクトリに潜っていき、再帰的に行って原因特定する。

【BIND】zoneファイルの更新メモ(TTL変更例)

zoneファイルの更新でいくつかハマった。 二度とないようにメモっておく。

やったこと

TTLの更新。例えばドメインやIP変更前にわざと短くして配布しておき、本変更をすぐに世界のDNSキャッシュに反映させるあれ。

zoneファイルの置き場

zoneファイルの置き場について。

場所は設定ファイルに記述されているんだけど、俗にいうchrootして設定ファイルの場所が変わっている場合がある。

chrootしているかどうかを見るには、bindの起動コマンドに-tオプションが付与されているかを見る。

ps aux | grep named

結果

named 643 0.0 0.9 30268 2336 ? S Jan05 0:07 /usr/sbin/named -u named -t /var/named/chroot

named.confの見方

見方といっても、変更に最低限必要なものだけ。

全体設定ファイルnamed.confは、デフォルトでは/etc/named.confに配置されている。 chrootしている場合、頭のパスにchrootしたパスをつけたものになる。

less /var/named/chroot/etc/named.conf

見るところは以下の通り。

directoryオプション

設定ファイル内に相対パスで記述したときに基準となるファイルパス。例によってchrootの影響を受ける。

options {
  ...
  directory "/var/named";
  ...
};

zoneオプション

ゾーン情報の設定。 ドメインとゾーンファイルが指定。ゾーンファイルパスは例によってdirectoryオプションとchrootの影響を受ける。

ちなみに、type slave;が記述されている場合、プライマリDNSから設定がtransferされるようになっているはずなのでゾーンファイル変更不要。

options {
   ...
   zone "hoo.var.com" {
     type master;
     file "hoo.var.com.zone";
   }
   ...
};

zoneファイルの変更

以下を変更。

1) TTLを短くする。以下、例。

$TTL  8H

;$TTL  8H
$TTL  600 ; 10 minutes

2) serialをあげる

一般的には、変更日のYYYYMMDD + 連番2桁 として管理を楽にする。

 2015112801

 2017022601

serialが新しくないと、reloadしても設定を読み込んでくれない。 戻し作業で再変更する場合は、連番を上げたバージョンを用意する。

 2017022602

3) minimumの変更

仮にDNSサーバーが落ちて解決不能となったときに、落ちてるから問い合わせても無駄だよ期間を指定する Negative-TTL の値。 別にTTLの2倍程度だったら問題ないんだけど、それ以上だと復旧しているのにキャッシュに残ったせいで復旧が遅れることがあるらしいので、変更しておく。

あと、いつの時代の基準化わからねど、普通はTTLと同じにするそうだ。(大手サービスでDNSサーバーに余力のあるところは数秒とかに設定しているとこも多いそう。)

8H  ; minimum

600  ; minimum

設定ファイルの上書きとリロード

rootじゃないと操作できないから気を付けてね。

設定ファイルを上書きする

設定ファイルを上書きする。

  • ファイルパスの完全一致
  • 権限の完全一致
  • ファイルのタイムスタンプが前設定ファイルより新しい(重要)

※言うまでもなくだけど、cp -ipでちゃんとバックアップとってね

ゾーンファイルの確認

named-checkzone "hoo.var.com" /var/named/chroot/var/named/hoo.var.com.zone

OKが出力されたらエラーなし。

named-confの確認

chrootしているときは -t オプションを使う。

以下、chrootしながら/var/named/chroot/etc/named.conf をチェックする例。

named-checkconf -t /var/named/chroot /etc/named.conf

何も出力されなかったらエラーなし。 これはnamed.confのチェックしかしないので注意。

-z オプションでゾーンファイルのチェックもできるけど、正常メッセージでもわっと出たときに初見びびるかも。

リロード

rndc reload

確認

自分に向けてdig。SOAレコードと正引きの2つともテストする。

dig @127.0.0.1 hoo.var.com

色々いっぱい出るけど、 ;;AUTHORITY SECTION: にserialとminimumが載ってればOK。

dig @127.0.0.1 www.hoo.var.com

こちらは、 ;; ANSWER SECTION:TTLつきで正引きの結果が表示される。

以上

メモおわり。

chrootと、zoneファイルのタイムスタンプが罠だった。 bind以外のDNSサーバーだとどうなのかな。

17/02/07雑記

ちょっと本格的にAngularを再開。

色々作りこんでいく中でいくつか悩みとアイディアが出たのでメモ。

RestAPIにするか否か

顧客管理のようなシステムを作っている。

顧客への「発送」業務があり、これは顧客によりあったりなかったりする。

データモデルがつまり 顧客 1 ― * 発送 という形になっている。

基本的にresource型のRestfulAPIを守ろうとしたが、 どうしてもブラウザ上で「顧客」を登録してから「発送」を登録することになる。

ただでさえ遠いWebサーバーに2往復もするのに加えて、 業務手続でできれば分離したいコードが、準コントローラーなコード中にむき出しになってしまう。 しかもこれは、1画面に1つ占有するコードみたいなもので、再利用が難しい。(思い切ってService化するのもアリだが)

Restじゃなくて、普通にWebAPI化しようとも悩んだ。(あくまで業務手続という体を守りつつ、実質1画面専用のAPI) がしかし、どうしてもパラメータが複雑になってしまう。 変なJSONにしてPHPとPOSTパラメータの周りをうろちょろするぐらいなら、 JSON親和性の高いうちに、クライアントでシンプルなAPIパラメータに変形してしまったほうが良いだろう。

・・・と思い、結局RestfulAPIで、クライアントにもりもりコードを持っていくスタイルを取った。 WebAPIのリクエストベースなテストも書きやすくなるしね。

しかし、Angularのテスト可用性が本当に死んでいる。 もともとリッチUIの予定だったので、打検はもともとだったが。。

Validation

HTMLのValidatorAPI。ありゃだめだった、エラーメッセージが1つしか出ない。

おとなしくAngular$validationsなりフレームワークやライブラリに頼って、 ラベルか自分でポップアップするかしたほうがよさそう。

17/02/07雑記

ちょっと本格的にAngularを再開。

色々作りこんでいく中でいくつか悩みとアイディアが出たのでメモ。

RestAPIにするか否か

顧客管理のようなシステムを作っている。

顧客への「発送」業務があり、これは顧客によりあったりなかったりする。

データモデルがつまり 顧客 1 ― * 発送 という形になっている。

基本的にresource型のRestfulAPIを守ろうとしたが、 どうしてもブラウザ上で「顧客」を登録してから「発送」を登録することになる。

ただでさえ遠いWebサーバーに2往復もするのに加えて、 業務手続でできれば分離したいコードが、準コントローラーなコード中にむき出しになってしまう。 しかもこれは、1画面に1つ占有するコードみたいなもので、再利用が難しい。(思い切ってService化するのもアリだが)

Restじゃなくて、普通にWebAPI化しようとも悩んだ。(あくまで業務手続という体を守りつつ、実質1画面専用のAPI) がしかし、どうしてもパラメータが複雑になってしまう。 変なJSONにしてPHPとPOSTパラメータの周りをうろちょろするぐらいなら、 JSON親和性の高いうちに、クライアントでシンプルなAPIパラメータに変形してしまったほうが良いだろう。

・・・と思い、結局RestfulAPIで、クライアントにもりもりコードを持っていくスタイルを取った。 WebAPIのリクエストベースなテストも書きやすくなるしね。

しかし、Angularのテスト可用性が本当に死んでいる。 もともとリッチUIの予定だったので、打検はもともとだったが。。

Validation

HTMLのValidatorAPI。ありゃだめだった、エラーメッセージが1つしか出ない。

おとなしくAngular$validationsなりフレームワークやライブラリに頼って、 ラベルか自分でポップアップするかしたほうがよさそう。

【JavaScript】ValidationAPIの標準エラーメッセージをフックして上書きする関数作った

GitHub

github.com

これで、Scriptトリガーの日本語英語切り替えが楽になる。

長さなどを文字列埋め込みできるようにメッセージをformatできるようにすればよかったけど、 Formatメソッド作らなきゃいけなくなるから削る。

【HTML】JavaScriptで検証結果のポップアップを呼び出す

ハマった。

デフォルトのValidationAPIはsubmitされないとポップアップしない?

<form id="f">
  <input type="text" name="firstname" id="firstname" required> 
  <button type="submit">submit</button>
</form>

これをJavaScriptから

let elForm = document.getElementById('f');
elForm.submit();

したら、検証を無視してページ遷移が発生。

で、それっぽいAPIがあるんだけど、どれを見ても検証結果の true / falseを知ることができるだけで、検証結果のメッセージがポップアップしない。

if (elForm.checkValidatity()) {
   document.getElementById('error').innerText = ('エラーがあります。');
}

俺はデフォルトのあの動作が欲しいんだ。

とりあえずの解決法

function popupInvalided(elForm) {

    const fnSubmitHandler = (event) {
        event.preventDefault();
    }

    let btn = document.createElement('button');
    btn.setAttribute('type', 'submit');
    btn.style.display = 'none';

    elForm.addEventHandler(fnSubmitHandler);
    elForm.appendChild(btn);
    
    setTimeout(() => {
        btn.click();
        setTimeout(() => {
            elForm.removeEventListener('submit', fnSubmitHandler);
            btn.remove();
        });
    }, 0);
}

探したらポップアップするAPIあると思うんだけど。 これだけのためにW3C文書読む気になれない。

おまけ:setCustomValitiyの挙動

setCustomValidityで自由にエラー扱いにできるしエラーメッセージも動的に決められるが、 JavaScriptで空文字を再設定しない限り、ずっとその項目はエラーになり続ける。

// 書きかけたバグ
if (!input.checkValidity()) {
    input.setCustomValidity('オリジナルのメッセージ');
}

回避策

  • HTMLにtitleつけて回避する。
<input type="text" required title="名前は必須です。">
  • setCustomValidityを使うところは、checkValidity()の前だけにする。