mirror of
https://github.com/fabriziosalmi/caddy-waf.git
synced 2025-12-23 14:17:45 -05:00
190 lines
6.7 KiB
Bash
190 lines
6.7 KiB
Bash
#!/bin/bash
|
||
set -e
|
||
|
||
# --- Configuration ---
|
||
GREEN="\033[1;32m"
|
||
RED="\033[1;31m"
|
||
YELLOW="\033[1;33m"
|
||
NC="\033[0m" # No Color
|
||
REPO_URL="https://github.com/fabriziosalmi/caddy-waf.git"
|
||
REPO_DIR="caddy-waf"
|
||
GO_VERSION_REQUIRED="1.22.3"
|
||
GO_VERSION_TARGET="1.23.4"
|
||
XCADDY_VERSION="latest" # or specify a version like "v0.3.7"
|
||
GEOLITE2_DB_URL="https://git.io/GeoLite2-Country.mmdb"
|
||
GEOLITE2_DB_FILE="GeoLite2-Country.mmdb"
|
||
|
||
# --- Helper Functions ---
|
||
print_success() {
|
||
echo -e "${GREEN}✅ Success: $1${NC}"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠️ Warning: $1${NC}"
|
||
}
|
||
|
||
print_info() {
|
||
echo -e "ℹ️ Info: $1${NC}"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}❌ Error: $1${NC}"
|
||
echo -e "${RED} $1${NC}" >&2 # Print error to stderr as well
|
||
exit 1
|
||
}
|
||
|
||
check_command_exists() {
|
||
if ! command -v "$1" &> /dev/null; then
|
||
return 1 # Command not found
|
||
else
|
||
return 0 # Command found
|
||
fi
|
||
}
|
||
|
||
ensure_go_installed() {
|
||
if ! check_command_exists go; then
|
||
print_info "Go not found. Installing Go $GO_VERSION_TARGET..."
|
||
install_go
|
||
else
|
||
check_go_version
|
||
fi
|
||
}
|
||
|
||
ensure_xcaddy_installed() {
|
||
if ! check_command_exists xcaddy; then
|
||
print_info "xcaddy not found. Installing xcaddy..."
|
||
install_xcaddy
|
||
else
|
||
print_info "xcaddy is already installed."
|
||
fi
|
||
}
|
||
|
||
clone_or_update_repo() {
|
||
if [ -d "$REPO_DIR" ]; then
|
||
print_info "$REPO_DIR directory already exists. Pulling latest changes..."
|
||
cd "$REPO_DIR" || print_error "Could not change directory to $REPO_DIR"
|
||
git pull origin main || print_error "Failed to pull $REPO_DIR updates." # Specify origin and branch
|
||
cd .. # Go back to the script's directory
|
||
else
|
||
print_info "Cloning $REPO_DIR repository..."
|
||
git clone "$REPO_URL" "$REPO_DIR" || print_error "Failed to clone repository from $REPO_URL."
|
||
fi
|
||
cd "$REPO_DIR" || print_error "Could not change directory to $REPO_DIR after clone/pull"
|
||
}
|
||
|
||
update_dependencies() {
|
||
print_info "Running go mod tidy..."
|
||
go mod tidy || print_error "Failed to run go mod tidy."
|
||
print_success "Dependencies updated (go mod tidy)."
|
||
|
||
print_info "Fetching Go modules..."
|
||
go get -v github.com/caddyserver/caddy/v2 github.com/caddyserver/caddy/v2/caddyconfig/caddyfile github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile github.com/caddyserver/caddy/v2/modules/caddyhttp github.com/oschwald/maxminddb-golang github.com/fsnotify/fsnotify github.com/fabriziosalmi/caddy-waf || print_error "Failed to fetch Go modules." # Combined go get
|
||
print_success "Go modules fetched successfully."
|
||
}
|
||
|
||
download_geolite2_db() {
|
||
if [ ! -f "$GEOLITE2_DB_FILE" ]; then
|
||
print_info "Downloading GeoLite2 Country database..."
|
||
wget -q "$GEOLITE2_DB_URL" -O "$GEOLITE2_DB_FILE" || print_error "Failed to download GeoLite2 database from $GEOLITE2_DB_URL." # Specify output file
|
||
print_success "GeoLite2 database downloaded."
|
||
else
|
||
print_info "GeoLite2 database already exists."
|
||
fi
|
||
}
|
||
|
||
build_caddy() {
|
||
print_info "Building Caddy with caddy-waf module..."
|
||
xcaddy build --with github.com/fabriziosalmi/caddy-waf=./ || print_error "Failed to build Caddy."
|
||
print_success "Caddy built successfully."
|
||
}
|
||
|
||
format_caddyfile() {
|
||
print_info "Formatting Caddyfile..."
|
||
./caddy fmt --overwrite || print_warning "Failed to format Caddyfile (This is a warning, Caddy might still run)." # Warning instead of error
|
||
print_success "Caddyfile formatted."
|
||
}
|
||
|
||
run_caddy() {
|
||
print_info "Starting Caddy server..."
|
||
./caddy run || print_error "Failed to start Caddy." # Keep as error, Caddy run failure is critical
|
||
print_success "Caddy is running." # This line will likely not be reached in a typical run
|
||
}
|
||
|
||
|
||
# --- OS Specific Functions ---
|
||
|
||
install_go_linux() {
|
||
print_info "Installing Go $GO_VERSION_TARGET for Linux..."
|
||
GOBIN="/usr/local/go/bin" # Define GOBIN for clarity
|
||
wget "https://go.dev/dl/go${GO_VERSION_TARGET}.linux-amd64.tar.gz" || print_error "Failed to download Go for Linux."
|
||
sudo rm -rf /usr/local/go
|
||
sudo tar -C /usr/local -xzf "go${GO_VERSION_TARGET}.linux-amd64.tar.gz" || print_error "Failed to extract Go for Linux."
|
||
rm "go${GO_VERSION_TARGET}.linux-amd64.tar.gz"
|
||
export PATH="$PATH:$GOBIN" # Ensure PATH is updated in current shell
|
||
print_success "Go $GO_VERSION_TARGET installed successfully on Linux."
|
||
}
|
||
|
||
install_go_macos() {
|
||
print_info "Installing Go $GO_VERSION_TARGET for macOS..."
|
||
curl -LO "https://go.dev/dl/go${GO_VERSION_TARGET}.darwin-amd64.pkg" || print_error "Failed to download Go for macOS."
|
||
sudo installer -pkg "go${GO_VERSION_TARGET}.darwin-amd64.pkg" -target / || print_error "Failed to install Go package on macOS."
|
||
rm "go${GO_VERSION_TARGET}.darwin-amd64.pkg"
|
||
export PATH="$PATH:/usr/local/go/bin" # Ensure PATH is updated in current shell
|
||
print_success "Go $GO_VERSION_TARGET installed successfully on macOS."
|
||
}
|
||
|
||
install_xcaddy() {
|
||
print_info "Installing xcaddy $XCADDY_VERSION..."
|
||
GOBIN="$(go env GOBIN)"
|
||
if [ -z "$GOBIN" ]; then
|
||
GOBIN="$HOME/go/bin" # Default GOBIN if not set
|
||
fi
|
||
go install "github.com/caddyserver/xcaddy/cmd/xcaddy@$XCADDY_VERSION" || print_error "Failed to install xcaddy."
|
||
export PATH="$PATH:$GOBIN" # Ensure PATH is updated in current shell
|
||
print_success "xcaddy $XCADDY_VERSION installed successfully."
|
||
}
|
||
|
||
check_go_version() {
|
||
local version
|
||
version=$(go version 2>&1 | awk '{print $3}' | sed 's/go//') # Redirect stderr to stdout for error handling
|
||
if [[ "$version" == *"error"* ]]; then # Check for "error" string in output
|
||
print_warning "Failed to get Go version. Assuming Go is outdated or not properly installed. Attempting to install Go $GO_VERSION_TARGET."
|
||
install_go # Attempt reinstall if version check fails
|
||
return
|
||
fi
|
||
|
||
if [[ $(printf '%s\n' "$GO_VERSION_REQUIRED" "$version" | sort -V | head -n1) != "$GO_VERSION_REQUIRED" ]]; then
|
||
print_warning "Go version $version is older than required $GO_VERSION_REQUIRED. Attempting to install Go $GO_VERSION_TARGET."
|
||
install_go # Attempt reinstall if version is too old
|
||
else
|
||
print_info "Go version $version meets requirements ($GO_VERSION_REQUIRED or newer)."
|
||
fi
|
||
}
|
||
|
||
install_go() {
|
||
OS=$(uname -s)
|
||
if [ "$OS" == "Linux" ]; then
|
||
install_go_linux
|
||
elif [ "$OS" == "Darwin" ]; then
|
||
install_go_macos
|
||
else
|
||
print_error "Unsupported OS: $OS"
|
||
fi
|
||
check_go_version # Re-check version after install to confirm success
|
||
}
|
||
|
||
|
||
# --- Main Script Execution ---
|
||
|
||
print_info "Starting setup for caddy-waf..."
|
||
|
||
ensure_go_installed
|
||
ensure_xcaddy_installed
|
||
clone_or_update_repo
|
||
update_dependencies
|
||
download_geolite2_db
|
||
build_caddy
|
||
format_caddyfile
|
||
run_caddy
|
||
|
||
print_success "caddy-waf setup completed!" |