Overview
Creating a custom fetcher allows you to integrate IP ranges from any source into Caddy Defender. This guide walks through implementing theIPRangeFetcher interface and integrating your fetcher into the build system.
Creating a Custom Fetcher
Create the fetcher file
Create a new
.go file in the ranges/fetchers/ directory. The filename should match your service name (e.g., myservice.go).Implement the IPRangeFetcher interface
Your fetcher must implement all three methods of the
IPRangeFetcher interface defined in ranges/fetchers/fetcher.go:4:The
Name() method’s return value will be converted to lowercase and used as the key in the generated IP ranges map. Choose a descriptive, unique name.Add your fetcher to the fetchersList
Open For configurable fetchers, you can instantiate them with specific parameters:
ranges/main.go and add your fetcher to the fetchersList array around line 34:ranges/main.go
ranges/main.go
Regenerate the generated.go file
Run the ranges generator to fetch IP ranges and create the updated You should see output like:
ranges/data/generated.go file:Verify the output
Check that your IP ranges were added to The key will be the lowercase version of your
ranges/data/generated.go:ranges/data/generated.go
Name() return value.Interface Requirements
Your fetcher must satisfy these requirements:Must return: A unique, descriptive name for your serviceUsed for: Map key in generated output (converted to lowercase)Example:
"MyService" becomes key "myservice"Must return: A human-readable description of what the fetcher doesUsed for: Progress logging during executionExample:
"Fetches IP ranges for My Service API"Must return:
- A slice of CIDR-formatted IP ranges (IPv4 and/or IPv6)
- An error if the fetch operation fails
- IPv4:
"192.0.2.0/24","203.0.113.128/25" - IPv6:
"2001:db8::/32","2001:db8:1234::/48"
Best Practices
Error Handling
Error Handling
Always return descriptive errors that include:
- What operation failed
- The URL or source being accessed
- The underlying error
HTTP Requests
HTTP Requests
- Always close response bodies:
defer resp.Body.Close() - Check HTTP status codes before processing
- Set reasonable timeouts for HTTP clients
- Handle rate limiting if applicable
Data Validation
Data Validation
Validate that fetched data is in the correct CIDR format:Filter out invalid entries:
Performance
Performance
- Pre-allocate slices when the size is known:
- Use streaming JSON decoding for large responses:
- Consider caching if the API has rate limits
Naming Conventions
Naming Conventions
- Struct name:
MyServiceFetcher - File name:
myservice.go - Package:
fetchers - Name() return:
"MyService"(will become"myservice"in output)
Real-World Examples
Refer to these existing fetchers for implementation patterns:Simple Static Ranges
Seeranges/fetchers/private.go:12 - Returns hardcoded RFC 1918 private IP ranges
JSON API with Struct
Seeranges/fetchers/cloudflare.go:20 - Fetches from Cloudflare’s API and parses JSON response
Multiple API Endpoints
Seeranges/fetchers/openai.go:19 - Combines results from multiple OpenAI JSON endpoints
Text File Parsing
Seeranges/fetchers/vpn.go:21 - Fetches and parses newline-delimited IP ranges from a text file
Configurable with Validation
Seeranges/fetchers/asn.go:24 - Accepts ASN list parameter with validation in constructor
Subdirectory Organization
Seeranges/fetchers/aws/ - Complex fetchers can be organized in subdirectories with shared utilities
Troubleshooting
Fetcher not executing
Fetcher not executing
Problem: Your fetcher doesn’t appear in the outputSolutions:
- Verify you added it to
fetchersListinranges/main.go:34 - Check for compilation errors:
go build ./ranges - Ensure the package name is
fetchers
Error: oldString not found
Error: oldString not found
Problem: Fetch completes but ranges aren’t in outputSolutions:
- Check that
FetchIPRanges()returns non-empty slice - Verify CIDR format is correct
- Look for errors in console output (❌ messages)
Import cycle errors
Import cycle errors
Problem:
import cycle not allowedSolutions:- Don’t import
ranges/mainfrom your fetcher - Use the
fetcherspackage, not a subdirectory - For complex fetchers, create a subdirectory like
fetchers/myservice/
Timeout or slow fetching
Timeout or slow fetching
Problem: Fetcher takes too long or times outSolutions:
- Add HTTP client timeout:
- Check if the API requires authentication
- Verify the URL is accessible from your network
- Consider pagination for large datasets
Advanced: Conditional Fetchers
Some fetchers are only added to the list based on flags or conditions:Flag-Based Inclusion
Fromranges/main.go:57:
Dynamic Fetcher Creation
Fromranges/main.go:64:
ranges/main.go:
Next Steps
Fetchers Overview
Review the fetcher system architecture and available fetchers
Using IP Ranges
Learn how to use the generated IP ranges in your Caddy configuration