Contents
概要
WAF(Web Application Firewall)を導入します。WAFはWebアプリケーションの脆弱性を悪用した攻撃からWebアプリケーションを保護するセキュリティ対策の一つです。本稿ではApacheのモジュールとして利用できるModSecurityを使用します。
前提条件
OS
CentOS Stream 8を使用します。
SELinux
有効です。無効にする場合はこちらを参照して下さい。
Firewalld
無効です。有効化する場合はこちらを参照して必要な許可設定をして下さい。
その他
こちらでWebサーバーを構築後に実施して下さい。
所感
WAFの導入自体は簡単(ModSecurityのようなホスト型では)ですが、セキュリティ対策でWAFに信頼を寄せすぎると運用の難易度は高くなります。脆弱性対処の場合は対象のソフトウェアを更新することが恒久的な対策であり、WAFは補足的なものと捉えるほうが不要なトラブル(ユーザーとの理解の不一致等)を未然に防ぐことができます。
WAFのインフラ構成
WAFはホスト型とネットワーク型があります。前者はWebアプリケーションが存在するサーバー上にWAFを導入しますので、本稿のModSecurityはホスト型です。ネットワーク型はWebアプリケーションが存在するサーバー以外に専用の機器(物理/仮想)としてWAFを導入します。この場合、WAFはHTTPを処理するのでHTTPプロキシとして動作します。ネットワーク型は専用アプライアンスとして多くのベンダーが提供しており、主にロードバランサーに組み込まれるケースが多いですが、既に完成しているシステム上にネットワーク的に組み込むこと自体、ハードルが高いことがあります。
シグネチャベースのWAF
一般的なWAFはシグネチャを使用し、HTTPの文字列をパターンマッチして攻撃を検知します。この為、検知の精度はシグネチャに依存します。シグネチャを使用しない場合はホワイトリストとして全て閉じた状態で必要なルールを手動で書いていくか、ブラックリストして対処したい攻撃を検知するかになりますが、これの難易度は高く、ルールの精度やルールの運用の手間を考慮すると、あまりお勧めできません。また、基本的にシグネチャベースで導入することで、専用アプライアンスの場合はメーカーがシグネチャを提供する為、責任分界点を明確にし易いというメリットもあります。
WAFの誤検知
WAFの導入では誤検知すると”WAFが悪い”ということになる場合も多くありますが、それが正しい場合もあるものの、Webアプリケーション側が一般的なセキュリティ基準に準拠していない可能性もあり、極端な例としてはSQLインジェクション的な入力を認めるWebアプリケーションは正しいのか?ということになりますね。それを単純にWAFで許可するということは、WAFではなくWebアプリケーション側でセキュリティを担保するということになります。これはWAFに限らずL4ファイアウォールでもそうですが、WAFの場合は要素が多く責任所在が曖昧になりがちなので、もめるケースの一つです。
設定
インストール
WAF(ModSecurity)をインストールします。mod_security_crsはシグネチャです。
[root@centos ~]# dnf install mod_security mod_security_crs
/etc/httpd/conf.d/mod_security.conf
mod_security.confを直接編集しても問題ありませんが、mod_security.confはmodsecurity.dディレクトリ内に*.confが存在する場合、それを読み込む設定がされています(下記の設定値)。
IncludeOptional modsecurity.d/*.conf
今回はmod_security.confを編集せずに、新規に/etc/httpd/modsecurity.d/my.mod_security.confを作成してModSecurityの設定を行います(my.mod_security.confの設定が優先されます)。方針にもよりますが設定ファイルは小さいほうが楽です。mod_security.confで設定する場合は読み替えて下さい。尚、ModSecurityは特に設定を変更しなくても動作しますが、変更が必要となる主なケースを下記に挙げます。
- WAF機能のON/OFF
- ModSecurityはデフォルトでONです。ModSecurityをインストールしてApacheを再起動すると有効になります。トラブルが発生した場合はWAF機能をOFFにして切り分けを行います。また、特定のディレクトリや特定のIPアドレスに対してもON/OFFが可能です。
- 擬陽性対応
- 擬陽性とは正常なリクエストを攻撃と判断してブロックすることです。ここで言う「正常なリクエスト」とはWebアプリケーションとしては正常なリクエストである場合を含んでいますが、一般的には正常なリクエストではないかもしれません。但し、Webアプリケーションとして正常なリクエストであればWAFで許可(チューニング)する必要があります。内容によってはWebアプリケーション側を改修したほうが良い場合もあると思います。
- 偽陰性対応
- 偽陰性とは攻撃を正常なリクエストとして許可することです。基本的にはシグネチャで防いでいますが、新規の脆弱性には即時に対応できない場合があります(mod_security_crs自体頻繁には更新されていません)。状況によっては自身でシグネチャを作成して適用する必要もありますが、攻撃パターンを再現させることができなければ作成すること自体も困難な為、難易度が高いです。重大な脆弱性であれば、それを考えているよりも脆弱性に対応したWebアプリケーションのリリースのほうが早いと思いますので、Webアプリケーションをアップデートを検討したほうが確実です。
WAF機能のON/OFF
SecRuleEngineで切り替えます。DetectionOnlyはブロックせずにログ出力のみとなります。良くありがちなのが「DetectionOnlyでとりあえず様子見」としてずっとそのままのケースでしょうか。
SecRuleEngine [On|Off|DetectionOnly]
特定のIPアドレスからのみOFFにするには下記を追加します。
SecRule REMOTE_ADDR "@ipMatch 10.0.0.0/24" "id:1,phase:1,nolog,allow,ctl:ruleEngine=Off"
擬陽性対応
分かり易いのは下記のように特定のシグネチャIDを無効にすることです。対象のシグネチャIDはログから確認する必要があります。
SecRuleRemoveById 950109
また、特定のディレクトリに対してのみ特定のシグネチャIDを無効にするか等の検討も必要です。
擬陰性対応
難易度が高く省略します。
サービス再起動
設定を反映させる為、サービスを再起動します。
[root@centos ~]# systemctl restart httpd.service
その他
WAFのログ
ModSecurityのログは/var/log/httpd/modsec_audit.logに出力されます。お世辞にも見やすいとは言えない為、Kibana + Elasticsearch等でうまく可視化すると良いと思います。
WAFのログは非常に重要ですが、L4ファイアウォールに比べると情報量が非常に多く、本格的には対象のWebアプリケーションに精通しているエンジニアで無ければ判断は無理です。もちろんセキュリティの知識も開発エンジニア以上に必要です。WAFの導入(本格的な)は広範なレイヤの知識が必要となりますが、この「広範なレイヤの知識」というのが細分化されたSIerではそれ自体の理解が難しかったりします。初期に課題を正確に理解し、適切な体制で臨むべきです。
WAFの動作テスト
Webアプリケーションに入力フォームがあれば下記を入力するとSQLインジェクションとして検知されます。他にも様々なパターンに対応できますが、詳細は/etc/httpd/modsecurity.d/activated_rules内の定義ファイルを確認して下さい。
' or 'A'='A