作ったものとか » Notes

CaddyでWAFしてみる

2026-02-23 19:15:24 caddy

Windows に Caddy+Coraza+CoreRuleSet で WAF を入れます。

WebApplicationIISCadCCdoRyrSazarequests

準備するもの

Caddy+Coraza+CoreRuleSetまでの手順

上の「準備するもの」のインストールについても記載しています。

Go コンパイラー

https://go.dev/dl/

インストール後に go コマンドにパスを通しておきます。

xcaddy

1
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

インストール後に xcaddy コマンドにパスを通しておきます。

Coraza WAF Caddy Module (を組み込んだ caddy のビルド)

xcaddy コマンドを実行して coraza-caddy を組み込んだ caddy を作成します。

1
xcaddy build --with github.com/corazawaf/coraza-caddy/v2 --with github.com/caddyserver/replace-response

他に組み込みたいモジュールがあれば、上記のコマンドに --with を追記します。

Caddy のモジュールとしては coraza-caddy があれば WAF は実現できます。 ですがここでは replace-response も組み込んでいます。 これは、Webアプリの書き方によって露出することがあるオリジナルの URL を置き換えるためです。

ちょっとだけ解説

xcaddy コマンドは、指定されたオプションを使って、caddy のソースコードをフェッチして、それをビルドするツール。

--with オプションで指定されたパッケージはモジュールと呼ばれるもので、パッケージの初期化関数 (init() のこと) で自身の機能や設定ファイルの読み込み処理を caddy に登録している。

coraza-caddy のソースコードを見るとイメージしやすいかもしれません。

https://github.com/corazawaf/coraza-caddy/blob/main/caddy/main.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Copyright 2023 The OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0

package main

import (
	caddycmd "github.com/caddyserver/caddy/v2/cmd"
	_ "github.com/caddyserver/caddy/v2/modules/standard"

	_ "github.com/corazawaf/coraza-caddy/v2"  // ←★xcaddy はこの行を埋め込んだソースコードを生成してビルドする。
)

func main() { // ←★main() はデバッグや単体組み込のためにあるので無視してよい。
	caddycmd.Main()
}

https://github.com/corazawaf/coraza-caddy/blob/main/coraza.go

1
2
3
4
func init() {
	caddy.RegisterModule(corazaModule{})
	httpcaddyfile.RegisterHandlerDirective("coraza_waf", parseCaddyfile)
}

CoreRuleSet

https://github.com/coreruleset/coreruleset/releases

最新版の minimal 付きのものをダウンロードして、上でビルドした caddy のある場所に展開します。

1
2
3
caddy.exe
coreruleset-4.23.0/
  crs-setup.conf.example 等

あとで少しファイルのリネームを行います。

動作確認と設定

IIS のバインドを変更する

ふつうは HTTP は 80、HTTP は 443 ですが、そちらは caddy がバインドするので、IIS ではそれぞれ 1080, 1443 にバインドしておきます。

WebApplicationTTCICPIPS11048403CadCCTdoRCyrSPaz8a0,443requests

サイトの設定から変更しておきます。

Caddyfile

以下の内容の Caddyfile を caddy.exe と同じ場所に置きます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{
	order coraza_waf first
}

(waf) {
	coraza_waf {
		load_owasp_crs
		directives `
		Include @coraza.conf-recommended
		Include @crs-setup.conf.example
		#Windows ではパス区切り文字の関係か、rules/xxx.conf が読めない旨のエラーが出る。
		#Include @owasp_crs/*.conf
		Include ./coreruleset-4.23.0/rules/*.conf
		SecDefaultAction "phase:3,log,auditlog,pass"
		SecDefaultAction "phase:4,log,auditlog,pass"
		SecDefaultAction "phase:5,log,auditlog,pass"
		SecRuleEngine On
		#適当なファイルに出力する。
		#SecDebugLog /home/coraza/logs/debug.log
		SecDebugLog ./debug.log
		SecDebugLogLevel 9
		SecRule REQUEST_URI "@streq /admin" "id:101,phase:1,t:lowercase,deny,status:403"
		SecRule REQUEST_BODY "@rx maliciouspayload" "id:102,phase:2,t:lowercase,deny,status:403"
		SecRule RESPONSE_STATUS "@rx 406" "id:103,phase:3,t:lowercase,deny,status:403"
		SecResponseBodyAccess On
		SecResponseBodyMimeType application/json
		SecRule RESPONSE_BODY "@contains responsebodycode" "id:104,phase:4,t:lowercase,deny,status:403"
		SecAuditEngine On
		#適当なファイルに出力する。
		#SecAuditLog /home/coraza/logs/audit.log
		SecAuditLog ./audit.log
		SecAuditLogFormat json
		`
	}

	# handle_errors 403 {
	# 	header X-Blocked "true"
	# 	root * /etc/caddy/custom-pages
	# 	rewrite * /{err.status_code}.html
	# 	file_server
	# 	templates
	# }
}

https://mysite.example.com {
	tls internal

	import waf

	reverse_proxy http://localhost:1080 {
		# HTTPS で自己署名証明書の場合は下の行を有効にする。
		# transport http {
		# 	tls_insecure_skip_verify
		# }
	}
	replace localhost:1080 mysite.example.com
}

(WAF の部分の記述内容は https://github.com/corazawaf/coraza-caddy/blob/main/example/Caddyfile から持ってきています)

Coraza WAF Caddy Module (coraza-caddy) には CRS の定義が含まれている どうやら Windows ではロードした内容が含まれるパスをたどることができないようで、結果としてファイル読み込みができない旨のエラーが出ます。

そういうわけで、上の Caddyfile ではローカルの CRS (前の手順でダウンロードしていたもの) を読み込むようにしています。

12
13
		#Include @owasp_crs/*.conf
		Include ./coreruleset-4.23.0/rules/*.conf