Skip to content

Update go.yml

Update go.yml #13

name: Build, Run and Validate
permissions:
contents: read
pull-requests: write
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
build-run-validate:
name: Build Run and validate
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Install Dependencies
run: |
sudo apt update
sudo apt install -y wget git build-essential curl python3 python3-pip
- name: Install Go 1.23.4
uses: actions/setup-go@v4
with:
go-version: '1.23.4'
- name: Validate Go Installation
run: |
go version
if ! go version | grep -q "go1.23.4"; then
echo "Go installation failed or incorrect version"
exit 1
fi
- name: Clone caddy-waf Repository
run: |
git clone https://github.com/fabriziosalmi/caddy-waf.git
cd caddy-waf
- name: Validate Repository Cloning
run: |
if [ ! -d "caddy-waf" ]; then
echo "Repository cloning failed"
exit 1
fi
- name: Install Go Dependencies
run: |
cd caddy-waf
go mod tidy
go get -v github.com/fabriziosalmi/caddy-waf github.com/caddyserver/caddy/v2 github.com/oschwald/maxminddb-golang
- name: Download GeoLite2 Country Database
run: |
cd caddy-waf
wget https://git.io/GeoLite2-Country.mmdb
- name: Validate GeoLite2 Download
run: |
cd caddy-waf
if [ ! -f "GeoLite2-Country.mmdb" ]; then
echo "GeoLite2 database download failed"
exit 1
fi
- name: Install Python Dependencies
run: |
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install tqdm requests
- name: Cache Python Dependencies
id: cache-pip
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
pip-${{ runner.os }}-
- name: Retrieve and Initialize IP and DNS Blacklists
run: |
cd caddy-waf
source ../venv/bin/activate # Activate the virtual environment
echo "Running get_blacklisted_ip.py..."
python3 get_blacklisted_ip.py
if [ $? -ne 0 ]; then
echo "Failed to retrieve or initialize IP blacklist"
exit 1
fi
echo "IP blacklist retrieved and initialized successfully."
echo "Running get_blacklisted_dns.py..."
python3 get_blacklisted_dns.py
if [ $? -ne 0 ]; then
echo "Failed to retrieve or initialize DNS blacklist"
exit 1
fi
echo "DNS blacklist retrieved and initialized successfully."
- name: Build Caddy with caddy-waf
run: |
cd caddy-waf
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy build --with github.com/fabriziosalmi/caddy-waf=./
- name: Validate Build
run: |
cd caddy-waf
if [ ! -f "caddy" ]; then
echo "Caddy build failed"
exit 1
fi
- name: Create Dynamic Files
run: |
cd caddy-waf
# Create a valid JWT token for testing
echo "Creating valid.jwt..."
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" > valid.jwt
# Create a sample JSON file for testing
echo "Creating sample.json..."
echo '{"key": "value"}' > sample.json
echo "Dynamic files created successfully."
- name: Test Caddy Run and Validate WAF Provisioning
run: |
cd caddy-waf
chmod +x caddy
./caddy run > caddy_output.log 2>&1 &
sleep 5
if ! pgrep -f "caddy run"; then
echo "Caddy run failed"
cat caddy_output.log
exit 1
fi
if ! grep -q "WAF middleware provisioned successfully" caddy_output.log; then
echo "WAF provisioning log not found"
cat caddy_output.log
exit 1
fi
echo "Caddy WAF build and run successful with WAF middleware provisioned"
- name: Run Phase-Specific Curl Tests
run: |
cd caddy-waf
# Phase 1: Allow legitimate traffic (User-Agent)
echo "Testing Phase 1: Allow legitimate traffic..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -A "Mozilla/5.0" http://localhost:8080)
if [ "$RESPONSE" != "200" ]; then
echo "Failed: Legitimate request was blocked. Expected HTTP 200, got $RESPONSE"
exit 1
else
echo "Success: Legitimate request allowed (HTTP 200)."
fi
# Phase 1: Block known vulnerability scanners (User-Agent)
echo "Testing Phase 1: Block known vulnerability scanners..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -A "nikto" http://localhost:8080)
if [ "$RESPONSE" != "403" ]; then
echo "Failed: Vulnerability scanner request was not blocked. Expected HTTP 403, got $RESPONSE"
exit 1
else
echo "Success: Vulnerability scanner request blocked (HTTP 403)."
fi
# Phase 2: Block NoSQL injection in body
echo "Testing Phase 2: Block NoSQL injection..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST -d '{"$gt": ""}' http://localhost:8080)
if [ "$RESPONSE" != "403" ]; then
echo "Failed: NoSQL injection request was not blocked. Expected HTTP 403, got $RESPONSE"
exit 1
else
echo "Success: NoSQL injection request blocked (HTTP 403)."
fi
# Phase 3: Block HTTP response splitting (Headers)
echo "Testing Phase 3: Block HTTP response splitting..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Forwarded-For: 127.0.0.1\r\nInjected-Header: value" http://localhost:8080)
if [ "$RESPONSE" != "403" ]; then
echo "Failed: HTTP response splitting request was not blocked. Expected HTTP 403, got $RESPONSE"
exit 1
else
echo "Success: HTTP response splitting request blocked (HTTP 403)."
fi
# Phase 4: Block JWT tampering (Headers)
echo "Testing Phase 4: Block JWT tampering..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" http://localhost:8080)
if [ "$RESPONSE" != "403" ]; then
echo "Failed: JWT tampering request was not blocked. Expected HTTP 403, got $RESPONSE"
exit 1
else
echo "Success: JWT tampering request blocked (HTTP 403)."
fi
echo "All phase-specific WAF rule tests passed successfully!"
- name: Clean Up
if: always()
run: |
pkill -f "caddy run" || true
echo "Cleaned up running Caddy instances"