ページコンテンツ
【概要】
modSecurityにはいくつかの設定ファイルがある。
今回はそのうちの1つである conf.d/mod_security.conf について深掘りする。
デフォルトの値を参考に、それぞれについて調べてみた。
※全体的に調査中。特に「??」とあるところは今後アップデート予定。
【設定内容】
modSecurityをconf.d/mod_security.confの内容は以下だった。
# Default recommended configuration
SecRuleEngine On
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type “text/xml” \
“id:’200000′,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML”
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
SecRule REQBODY_ERROR “!@eq 0” \
“id:’200001′, phase:2,t:none,log,deny,status:400,msg:’Failed to parse request body.’,logdata:’%{reqbody_error_msg}’,severity:2”
SecRule MULTIPART_STRICT_ERROR “!@eq 0” \
“id:’200002′,phase:2,t:none,log,deny,status:400,msg:’Multipart request body \
failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'”
SecRule MULTIPART_UNMATCHED_BOUNDARY “!@eq 0” \
“id:’200003′,phase:2,t:none,log,deny,status:44,msg:’Multipart parser detected a possible unmatched boundary.'”
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
SecRule TX:/^MSC_/ “!@streq 0” \
“id:’200004′,phase:2,t:none,deny,msg:’ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'”
SecResponseBodyAccess Off
SecDebugLog /var/log/httpd/modsec_debug.log
SecDebugLogLevel 0
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus “^(?:5|4(?!04))”
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/httpd/modsec_audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecTmpDir /var/lib/mod_security
SecDataDir /var/lib/mod_security
# ModSecurity Core Rules Set and Local configuration
IncludeOptional modsecurity.d/*.conf
IncludeOptional modsecurity.d/activated_rules/*.conf
IncludeOptional modsecurity.d/local_rules/*.conf
【各行の内容】
SecRuleEngine DetectionOnly
ModSecurityの動作モードを表す。設定値は以下の通り。
On : ルールに一致したリクエストをブロックするモード。
DetectionOnly : ルールに一致したリクエストについてのログを出すのみで、制限等は行わない。
SecRequestBodyAccess
modSecurityがサーバに送信されたデータのうちの、postデータやアップロードファイルに対してもアクセスし、検証を行うことを許可するかどうかを決める。設定値は以下の通り。
On : 許可する
Off : 許可しない
これをOnにすることで、SQLインジェクションやクロスサイトスクリプティング (XSS) などの攻撃に 対応できるので、メリットは大きい。ただしpostデータやアップロードファイルを検証するにあたり、サーバリソースを使うので、あまり大きなデータを受け取った場合、その分リソースを使ってしまう。
他の設定値で使用リソースの制限ができるようなので、サーバリソースに合わせて調整する必要がある。
ただ、多くのクラウドサーバではサービス側でこの辺の設定をしているので、適正値があるのかもしれない。
SecRule
Webアプリケーションへの攻撃を検知・防御するための具体的なロジックを定義する。上のようなon/offとかではなく、以下のようなフォーマットで記載する。
SecRule 対象 検査内容 [処理文字列]
対象 : 検査を行う対象。設定値としては以下のようなものがある。
ARGS : URLのクエリーは「 parameter=value 」というのが連なるが、そのvalueを対象とする。
ARGS_NAMES : 上の例のparameterを対象とする。
REQUEST_URI : URIのドメインより右のパスとクエリを対象とする。
REQUEST_METHOD : リクエストメソッドを対象とする。(GET、POST、PUTなど)
REQUEST_HEADERS:(http headerの値) : 指定したhttpヘッダーの値を対象とする。「:(http headerの値)」を省略すると、httpヘッダーの値全てを対象とする。
REQUEST_BODY : リクエストボディを対象とする。
REMOTE_ADDR : クライアントのIPアドレスを対象とする。IP制限をここでも設定できるのかも?
RESPONSE_BODY : レスポンスボディを対象とする。
XML : XMLリクエストボディを対象とする。
JSON : JSONリクエストボディを対象とする。
※パイプで区切って複数の対象を指定することもできる。
検査内容
上で指定された対象に対してどのような検査を行うのかを定義する。大抵「@」から始まる。
@rx : 正規表現
ex) @rx \b(union|select)\b → SQLインジェクションのキーワードを検出
@streq : 文字列完全一致
@contains : 部分文字列一致
@pm : 「Aho-Corasickアルゴリズム」を利用した高速マッチング
@eq : 数値の一致
@ge : 以上(>=)
@le : 以下(<=)
@gt : より大きい(>)
@lt : より小さい(>)
@validateByteRange : バイト範囲の妥当性チェック
@detectXSS : XSS検出のためのチェック
@detectSQLi : SQLインジェクション攻撃パターンのチェック
[処理文字列]
上記のチェックで一致した場合にどのような処理を行うかを定義。
カンマ区切りで複数の設定を行うことも可能。
id:ID_NUMBER : 処理に任意のIDを定義する。
phase:(フェーズ番号) : ルールが評価されるフェーズ。
phase:1 リクエストヘッダ処理前
phase:2 リクエストボディ処理後
phase:3 レスポンスヘッダ処理前
phase:4 レスポンスボディ処理後
phase:5 ログ出力時
deny : リクエストをブロックし、403を返す。
drop : 何も返さず、接続を閉じる。
pass : 何も処理しない。(ログは出る)
allow : 以降の処理をスルーして、許可とする。
log : ログ出力する
nolog : ログを出力しない(??何のためにある?logを指定しなければいいだけでは?)
msg:’メッセージ’ : 指定したメッセージを監査ログやエラーログに出力する(??結局どこに出力?)
severity:(レベル) : (処理ではない)深刻度を定義する。
0 緊急
1 警戒
2 致命的
3 エラー
4 警告
5 通知
6 情報
7 デバッグ
(??何の意味がある?実質意味ないかも。msgとかで代替できそう)
tag:(タグ文字列) : 処理にタグ付けする
(??同上)
t:(変換処理) : 対象文字列に対して変換処理する。変換処理は以下の通り。
lowercase 小文字に変換
urlDecode URLデコードを実施
htmlEntityDecode htmlエンティティデコード
compressWhitespace 多重のスペースを1つにする
removeNulls NULLを削除
none 何もしない(??何もしないなら定義しなければいいのに。。。)
setvar:(変数=値) : modSecurity内部で使う変数への値の設定(??どんな変数が使える?)
chain : 下に続くSecRuleと現在のSecRuleをandで繋げる
(別に使っても使わなくてもいい設定値だと思う。)
SecRequestBodyLimit
検査するリクエストボディの最大サイズを設定する。Byteで指定。(??これを超える場合はスルー?)
ちょっと違うがphpのpost_max_sizeに近しいイメージかな?この値はこのサイズを超える場合はエラーになるが。
SecRequestBodyNoFilesLimit
単純なリクエストボディの最大サイズ。アップロードファイルの容量は排除したリクエストボディの容量の最大値。Byteで指定。
これを超えるデータはディスクに書き込みながら処理される。
なるべく小さい値を設定したい。でも小さすぎるとディスクIOが大量に発生してしまう。
この下の値により、処理を排斥することも可能。
SecRequestBodyLimitAction
「SecRequestBodyLimit」「SecRequestBodyNoFilesLimit」を超えた時の処理を設定できる。
同じようなことはSecRuleでもできるが、そこで細かく決めなくても大粒で設定できる。
設定値は以下。
Reject : 403エラーを返す。
ProcessPartial : 指定したサイズまでの値で処理を行う。制限を超えた部分は処理対象から除外される。(ディスクIOが発生しないようになる)
SecPcreMatchLimit
正規表現のマッチングの最大マッチング数を指定。これを超えたマッチングが発生するとエラーとなる。(??本当か?それまでマッチングしたものも破棄する?)
SecPcreMatchLimitRecursion
正規表現マッチングの再起的処理の深さを定義。これを超えた場合はエラーとして返す。(??同上)
SecResponseBodyAccess
httpレスポンスを検査するかどうか。
On : httpレスポンスの検査を行う。ただしレスポンスの検査はリソースを大量に使う傾向にある。リクエストの検査を実施することで一定防衛できるので、あまりOnにされることはないとのこと。
Off : httpレスポンスの検査を行わない。
SecDebugLog
デバッグログの出力先。modSecurityが通常に出すログではない。
SecDebugLogLevel
デバッグロブのログレベル。
0 : デバッグログを出力しない。
1〜9 : 1が最も基本的なもので、9が最も詳細。9にすると大量のログが出るので、通常運用は0もしくは1がいいらしい。
SecAuditEngine
modSecurityの処理ログの出力の程度を指定。
On : 全ての処理ログを出力する。
RelevantOnly : ルールにマッチしたもののみ処理ログを出力する。
Off : ログを出力しない。
SecAuditLogRelevantStatus
SecAuditEngineを「RelevantOnly」に設定している場合に出力するログの対象をhttpコードで指定する。
正規表現で複数のhttpコードを指定できる。
ex) “^(?:5|4(?!04))” 5xx 4xxについてログ出力。ただし404は除く
SecAuditLogParts
監査ログに含める情報の種類を以下で指定。設定は以下のアルファベットを並べれば良い。
(??全部のログを出して調べる必要あり)
A : ログのIDとアクセス元IP/PORTとアクセス先IP/PORT
B : リクエストURI
E : ?
F : レスポンスのhttpコード
H : modSecurityの処理結果。結構な情報量。
SecAuditLogType
監査ログの書き方を指定。
Serial : 一連のログを1ファイルにそのまま書き連ねる。
Concurrent : トランザクションごとに個別にログを出力する。
SecAuditLog
監査ログ(modSecrityが処理したログ)を出力するログファイルをパスで指定。
SecArgumentSeparator
URLエンコードされていないリクエストパラメータの区切り文字を指定。
大抵は「&」を指定。
(??何で&?)
SecCookieFormat
cookieの解析を行う時に、そのどういったフォーマットで解析するかを指定。
0 : Netscape系の形式。chromeやfirefox等一般的なブラウザはこれなので、0でよい。
1 : RFC 2109 / RFC 2965に準拠した形式。厳密な構文だが、ほぼないので、無視して良いだろう。
【その他】
サーバ運用していると、海外からのクローラやあからさまなアタックが来るが、中にはサーバ負荷を上げるものもある。それらに対しては、何とか対応したいと思い、お手軽なアプリケーションWAFの導入を検討しているが、modSecurityが動き始めるとさらにサーバリソースを使うので、高負荷の原因になる可能性もあるかも、とも思う。
ただ、上記の設定値を見ただけでも、XSS等の対策用の設定値があり、それを使ってみるだけでも何か変わるかもしれないと期待してしまう。
まだよくわかってない点もあるし、他にも設定値があるので、引き続き調査して情報をアップデートしたい。