1+ #! /bin/bash
2+ set -e
3+
4+ # --- Configuration ---
5+ GREEN=" \033[1;32m"
6+ RED=" \033[1;31m"
7+ YELLOW=" \033[1;33m"
8+ NC=" \033[0m" # No Color
9+ GO_VERSION_REQUIRED=" 1.22.3"
10+ GO_VERSION_TARGET=" 1.23.4"
11+ XCADDY_VERSION=" latest"
12+ GEOLITE2_DB_URL=" https://git.io/GeoLite2-Country.mmdb"
13+ GEOLITE2_DB_FILE=" GeoLite2-Country.mmdb"
14+
15+ # Default modules - can be overridden with environment variables
16+ WAF_MODULE=${WAF_MODULE:- " github.com/fabriziosalmi/caddy-waf@latest" }
17+ # Add additional modules here, comma-separated in EXTRA_MODULES env var
18+ # Example: EXTRA_MODULES="github.com/greenpau/caddy-security@latest,github.com/example/module@latest"
19+ EXTRA_MODULES=${EXTRA_MODULES:- " " }
20+
21+ # --- Helper Functions ---
22+ print_success () {
23+ echo -e " ${GREEN} ✅ Success: $1 ${NC} "
24+ }
25+
26+ print_warning () {
27+ echo -e " ${YELLOW} ⚠️ Warning: $1 ${NC} "
28+ }
29+
30+ print_info () {
31+ echo -e " ℹ️ Info: $1 ${NC} "
32+ }
33+
34+ print_error () {
35+ echo -e " ${RED} ❌ Error: $1 ${NC} "
36+ echo -e " ${RED} $1 ${NC} " >&2
37+ exit 1
38+ }
39+
40+ check_command_exists () {
41+ if ! command -v " $1 " & > /dev/null; then
42+ return 1 # Command not found
43+ else
44+ return 0 # Command found
45+ fi
46+ }
47+
48+ ensure_go_installed () {
49+ if ! check_command_exists go; then
50+ print_info " Go not found. Installing Go $GO_VERSION_TARGET ..."
51+ if [[ " $OSTYPE " == " linux-gnu" * ]]; then
52+ install_go_linux
53+ elif [[ " $OSTYPE " == " darwin" * ]]; then
54+ install_go_macos
55+ else
56+ print_error " Unsupported OS type: $OSTYPE "
57+ fi
58+ else
59+ check_go_version
60+ fi
61+ }
62+
63+ check_go_version () {
64+ local version
65+ version=$( go version 2>&1 | awk ' {print $3}' | sed ' s/go//' )
66+ if [[ " $version " == * " error" * ]]; then
67+ print_warning " Error checking Go version. Attempting to proceed anyway."
68+ return
69+ fi
70+
71+ # Compare versions (simple string comparison, assumes semantic versioning)
72+ if [[ " $version " < " $GO_VERSION_REQUIRED " ]]; then
73+ print_warning " Go version $version is older than required version $GO_VERSION_REQUIRED ."
74+ print_info " Installing Go $GO_VERSION_TARGET ..."
75+ if [[ " $OSTYPE " == " linux-gnu" * ]]; then
76+ install_go_linux
77+ elif [[ " $OSTYPE " == " darwin" * ]]; then
78+ install_go_macos
79+ else
80+ print_error " Unsupported OS type: $OSTYPE "
81+ fi
82+ else
83+ print_info " Go version $version is installed (minimum required: $GO_VERSION_REQUIRED )."
84+ fi
85+ }
86+
87+ ensure_xcaddy_installed () {
88+ if ! check_command_exists xcaddy; then
89+ print_info " xcaddy not found. Installing xcaddy..."
90+ install_xcaddy
91+ else
92+ print_info " xcaddy is already installed."
93+ fi
94+ }
95+
96+ install_xcaddy () {
97+ print_info " Installing xcaddy $XCADDY_VERSION ..."
98+ GOBIN=" $( go env GOBIN) "
99+ if [ -z " $GOBIN " ]; then
100+ GOBIN=" $HOME /go/bin" # Default GOBIN if not set
101+ fi
102+ go install " github.com/caddyserver/xcaddy/cmd/xcaddy@$XCADDY_VERSION " || print_error " Failed to install xcaddy."
103+ export PATH=" $PATH :$GOBIN " # Ensure PATH is updated in current shell
104+ print_success " xcaddy $XCADDY_VERSION installed successfully."
105+ }
106+
107+ download_geolite2_db () {
108+ if [ ! -f " $GEOLITE2_DB_FILE " ]; then
109+ print_info " Downloading GeoLite2 Country database..."
110+ if check_command_exists wget; then
111+ wget -q " $GEOLITE2_DB_URL " -O " $GEOLITE2_DB_FILE " || print_error " Failed to download GeoLite2 database."
112+ elif check_command_exists curl; then
113+ curl -s " $GEOLITE2_DB_URL " -o " $GEOLITE2_DB_FILE " || print_error " Failed to download GeoLite2 database."
114+ else
115+ print_error " Neither wget nor curl is installed. Cannot download GeoLite2 database."
116+ fi
117+ print_success " GeoLite2 database downloaded."
118+ else
119+ print_info " GeoLite2 database already exists."
120+ fi
121+ }
122+
123+ build_caddy_with_modules () {
124+ print_info " Building Caddy with modules..."
125+
126+ # Start building the xcaddy command
127+ CMD=" xcaddy build --with $WAF_MODULE "
128+
129+ # Add any extra modules
130+ if [ -n " $EXTRA_MODULES " ]; then
131+ IFS=' ,' read -ra MODULES <<< " $EXTRA_MODULES"
132+ for MODULE in " ${MODULES[@]} " ; do
133+ CMD=" $CMD --with $MODULE "
134+ done
135+ fi
136+
137+ print_info " Running command: $CMD "
138+ eval $CMD || print_error " Failed to build Caddy with modules."
139+
140+ print_success " Caddy built successfully with the following modules:"
141+ print_info " - $WAF_MODULE "
142+ if [ -n " $EXTRA_MODULES " ]; then
143+ IFS=' ,' read -ra MODULES <<< " $EXTRA_MODULES"
144+ for MODULE in " ${MODULES[@]} " ; do
145+ print_info " - $MODULE "
146+ done
147+ fi
148+ }
149+
150+ format_caddyfile () {
151+ if [ -f " Caddyfile" ]; then
152+ print_info " Formatting Caddyfile..."
153+ ./caddy fmt --overwrite Caddyfile || print_warning " Failed to format Caddyfile."
154+ print_success " Caddyfile formatted."
155+ else
156+ print_info " No Caddyfile found to format."
157+ fi
158+ }
159+
160+ check_modules () {
161+ print_info " Checking loaded modules..."
162+ ./caddy list-modules | grep -E " (waf|security)" || print_warning " Modules may not be properly loaded."
163+ }
164+
165+ # --- OS Specific Functions ---
166+
167+ install_go_linux () {
168+ print_info " Installing Go $GO_VERSION_TARGET for Linux..."
169+ # Download and install Go
170+ wget -q https://golang.org/dl/go${GO_VERSION_TARGET} .linux-amd64.tar.gz -O go.tar.gz || print_error " Failed to download Go."
171+ sudo rm -rf /usr/local/go
172+ sudo tar -C /usr/local -xzf go.tar.gz
173+ rm go.tar.gz
174+ export PATH=" $PATH :/usr/local/go/bin"
175+ print_success " Go $GO_VERSION_TARGET installed successfully on Linux."
176+ }
177+
178+ install_go_macos () {
179+ print_info " Installing Go $GO_VERSION_TARGET for macOS..."
180+ # Download and install Go
181+ curl -sL https://golang.org/dl/go${GO_VERSION_TARGET} .darwin-amd64.tar.gz -o go.tar.gz || print_error " Failed to download Go."
182+ sudo rm -rf /usr/local/go
183+ sudo tar -C /usr/local -xzf go.tar.gz
184+ rm go.tar.gz
185+ export PATH=" $PATH :/usr/local/go/bin"
186+ print_success " Go $GO_VERSION_TARGET installed successfully on macOS."
187+ }
188+
189+ # --- Main Script ---
190+
191+ print_info " Starting setup for Caddy with multiple modules..."
192+
193+ # Display selected modules
194+ print_info " Will install the following modules:"
195+ print_info " - WAF Module: $WAF_MODULE "
196+ if [ -n " $EXTRA_MODULES " ]; then
197+ print_info " - Extra Modules: $EXTRA_MODULES "
198+ fi
199+
200+ # Prompt user to confirm
201+ read -p " Continue with these modules? [Y/n] " -n 1 -r
202+ echo
203+ if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ ! -z $REPLY ]]; then
204+ print_info " Installation cancelled by user."
205+ exit 0
206+ fi
207+
208+ ensure_go_installed
209+ ensure_xcaddy_installed
210+ download_geolite2_db
211+ build_caddy_with_modules
212+ format_caddyfile
213+ check_modules
214+
215+ print_success " Setup completed! You now have Caddy built with WAF and your selected modules."
216+ print_info " To run Caddy: ./caddy run"
217+ print_info " For a list of all installed modules: ./caddy list-modules"
0 commit comments