$ -weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)"
-weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)"
-weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)"
# Pin to a specific version
mise use -g github:caddyserver/[email protected] # Or use the latest version
mise use -g github:caddyserver/xcaddy
# Pin to a specific version
mise use -g github:caddyserver/[email protected] # Or use the latest version
mise use -g github:caddyserver/xcaddy
# Pin to a specific version
mise use -g github:caddyserver/[email protected] # Or use the latest version
mise use -g github:caddyserver/xcaddy
xcaddy version
xcaddy version
xcaddy version
# Place the database where your Caddyfile can reference it
mv GeoLite2-ASN.mmdb ~/GeoLite2-ASN.mmdb
# Place the database where your Caddyfile can reference it
mv GeoLite2-ASN.mmdb ~/GeoLite2-ASN.mmdb
# Place the database where your Caddyfile can reference it
mv GeoLite2-ASN.mmdb ~/GeoLite2-ASN.mmdb
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3
mv caddy /usr/local/bin/caddy
mv caddy /usr/local/bin/caddy
mv caddy /usr/local/bin/caddy
tee ~/Library/LaunchAgents/com.caddyserver.caddy.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict> <key>Label</key> <string>com.caddyserver.caddy</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/caddy</string> <string>run</string> <string>--config</string> <string>/Users/username/.config/caddy/Caddyfile</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/Users/username/.config/caddy/caddy-stdout.log</string> <key>StandardErrorPath</key> <string>/Users/username/.config/caddy/caddy-stderr.log</string>
</dict>
</plist>
EOF
tee ~/Library/LaunchAgents/com.caddyserver.caddy.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict> <key>Label</key> <string>com.caddyserver.caddy</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/caddy</string> <string>run</string> <string>--config</string> <string>/Users/username/.config/caddy/Caddyfile</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/Users/username/.config/caddy/caddy-stdout.log</string> <key>StandardErrorPath</key> <string>/Users/username/.config/caddy/caddy-stderr.log</string>
</dict>
</plist>
EOF
tee ~/Library/LaunchAgents/com.caddyserver.caddy.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict> <key>Label</key> <string>com.caddyserver.caddy</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/caddy</string> <string>run</string> <string>--config</string> <string>/Users/username/.config/caddy/Caddyfile</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/Users/username/.config/caddy/caddy-stdout.log</string> <key>StandardErrorPath</key> <string>/Users/username/.config/caddy/caddy-stderr.log</string>
</dict>
</plist>
EOF
# Start Caddy -weight: 500;">service
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Stop Caddy -weight: 500;">service
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Reload config without restarting the -weight: 500;">service
caddy reload --config ~/.config/caddy/Caddyfile
# Start Caddy -weight: 500;">service
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Stop Caddy -weight: 500;">service
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Reload config without restarting the -weight: 500;">service
caddy reload --config ~/.config/caddy/Caddyfile
# Start Caddy -weight: 500;">service
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Stop Caddy -weight: 500;">service
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Reload config without restarting the -weight: 500;">service
caddy reload --config ~/.config/caddy/Caddyfile
caddy hash-password
caddy hash-password
caddy hash-password
$2a$14$Mpdg/pw/CBar4/YMFRcwbuN2gWsOQgaCowWDHPHsc402vF18TRGRK
$2a$14$Mpdg/pw/CBar4/YMFRcwbuN2gWsOQgaCowWDHPHsc402vF18TRGRK
$2a$14$Mpdg/pw/CBar4/YMFRcwbuN2gWsOQgaCowWDHPHsc402vF18TRGRK
site1.example.com { log { output file /Users/username/.config/caddy/site1.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } handle /googlechat { reverse_proxy 192.168.111.98:18789 } handle { basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 192.168.111.98:18789 respond 501 }
} site2.example.com { log { output file /Users/username/.config/caddy/site2.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 127.0.0.1:3644 respond 501
}
site1.example.com { log { output file /Users/username/.config/caddy/site1.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } handle /googlechat { reverse_proxy 192.168.111.98:18789 } handle { basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 192.168.111.98:18789 respond 501 }
} site2.example.com { log { output file /Users/username/.config/caddy/site2.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 127.0.0.1:3644 respond 501
}
site1.example.com { log { output file /Users/username/.config/caddy/site1.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } handle /googlechat { reverse_proxy 192.168.111.98:18789 } handle { basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 192.168.111.98:18789 respond 501 }
} site2.example.com { log { output file /Users/username/.config/caddy/site2.example.com-caddy.log } @allowed { maxmind_geolocation { db_path "/Users/username/GeoLite2-ASN.mmdb" allow_asn 48323 21497 59497 58309 } } basic_auth @allowed { admin $2a$14$... } reverse_proxy @allowed 127.0.0.1:3644 respond 501
}
# Install mise
-weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)" # Install xcaddy
mise use -g github:caddyserver/[email protected] # Build custom Caddy
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3 # Install the binary
mv caddy /usr/local/bin/caddy # Generate password hash for basic_auth
caddy hash-password # macOS -weight: 500;">service management
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Manage Caddyfile
caddy validate --config ~/.config/caddy/Caddyfile
caddy reload --config ~/.config/caddy/Caddyfile
caddy fmt --overwrite ~/.config/caddy/Caddyfile
# Install mise
-weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)" # Install xcaddy
mise use -g github:caddyserver/[email protected] # Build custom Caddy
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3 # Install the binary
mv caddy /usr/local/bin/caddy # Generate password hash for basic_auth
caddy hash-password # macOS -weight: 500;">service management
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Manage Caddyfile
caddy validate --config ~/.config/caddy/Caddyfile
caddy reload --config ~/.config/caddy/Caddyfile
caddy fmt --overwrite ~/.config/caddy/Caddyfile
# Install mise
-weight: 500;">curl https://mise.run | sh
export PATH="$HOME/.local/bin:$PATH"
eval "$(mise activate bash)" # Install xcaddy
mise use -g github:caddyserver/[email protected] # Build custom Caddy
xcaddy build v2.11.2 \ --with github.com/porech/caddy-maxmind-geolocation@v1.0.3 # Install the binary
mv caddy /usr/local/bin/caddy # Generate password hash for basic_auth
caddy hash-password # macOS -weight: 500;">service management
launchctl load -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist
launchctl unload -w ~/Library/LaunchAgents/com.caddyserver.caddy.plist # Manage Caddyfile
caddy validate --config ~/.config/caddy/Caddyfile
caddy reload --config ~/.config/caddy/Caddyfile
caddy fmt --overwrite ~/.config/caddy/Caddyfile - Provenance verification — validates release authenticity
- Download progress reports — visual feedback during -weight: 500;">install - Browse and search all available plugins by name or category
- Select plugins you need and download a pre-built binary directly
- Copy the xcaddy build command with all your selected --with flags - MaxMind GeoIP ASN filtering — only allow traffic from specific ISPs/networks
- Basic authentication — password-protect the proxy
- Reverse proxying — forward traffic to backend services
- Separate handling for webhook endpoints (no auth required) - GeoIP check (@allowed matcher) — only ASNs 48323, 21497, 59497, and 58309 can proceed past basic auth. All others get the respond 501.
- Basic auth — only requests matching @allowed are prompted for credentials.
- Reverse proxy — authenticated + allowed requests are forwarded to the backend.
- Fallback — anything that doesn't match gets a 501 response. - mise documentation
- Caddy modules directory
- Caddy download / plugin picker