Documentation
¶
Overview ¶
Example ¶
Example demonstrates basic usage of the prefix list system
package main
import (
"context"
"fmt"
"net/netip"
"github.com/dioad/net/authz/prefixlist"
"github.com/rs/zerolog"
)
func main() {
logger := zerolog.Nop()
// Create a multi-provider with GitLab provider
gitlabProvider := prefixlist.NewGitLabProvider()
multiProvider := prefixlist.NewMultiProvider([]prefixlist.Provider{gitlabProvider}, logger)
ctx := context.Background()
_, err := multiProvider.Prefixes(ctx)
if err != nil {
panic(err)
}
// Check if an IP is in the allowed list
addr, err := netip.ParseAddr("34.74.90.65")
if err != nil {
panic(err)
}
if multiProvider.Contains(addr) {
fmt.Println("IP is allowed")
} else {
fmt.Println("IP is denied")
}
}
Output: IP is allowed
Index ¶
- func FetchTextLines(ctx context.Context, url string) ([]string, error)
- type AWSProvider
- type AtlassianProvider
- type CacheConfig
- type CacheResult
- type CachingFetcher
- type CloudflareProvider
- type Config
- type FastlyProvider
- type FetchFunc
- type FetchResult
- type GitHubProvider
- type GitLabProvider
- type GoogleProvider
- type HTTPJSONProvider
- type HTTPTextProvider
- type HetznerProvider
- type Listener
- type MultiProvider
- type Provider
- type ProviderConfig
- type TransformFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AWSProvider ¶
type AWSProvider struct {
*HTTPJSONProvider[awsIPRanges]
// contains filtered or unexported fields
}
AWSProvider fetches IP ranges from AWS
func NewAWSProvider ¶
func NewAWSProvider(service, region string) *AWSProvider
NewAWSProvider creates a new AWS prefix list provider
type AtlassianProvider ¶
type AtlassianProvider struct {
*HTTPJSONProvider[atlassianIPRanges]
// contains filtered or unexported fields
}
AtlassianProvider fetches IP ranges from Atlassian
func NewAtlassianProvider ¶
func NewAtlassianProvider(regions, products []string) *AtlassianProvider
NewAtlassianProvider creates a new Atlassian prefix list provider regions: optional list of regions to filter by (e.g., ["global", "us-east-1"]) products: optional list of products to filter by (e.g., ["jira", "confluence"]) Only prefixes with "egress" direction are included
type CacheConfig ¶
type CacheConfig struct {
// StaticExpiry defines a fixed cache duration (e.g., 1 hour)
StaticExpiry time.Duration
// ReturnStale controls whether stale data should be returned while refreshing
// If true, returns stale data immediately and refreshes in background
// If false, blocks until fresh data is fetched
ReturnStale bool
// ExpiryHeader specifies the HTTP header to check for expiry (e.g., "Expires", "Cache-Control")
// If set, this takes precedence over StaticExpiry
ExpiryHeader string
}
CacheConfig configures the caching behavior of a CachingFetcher
type CacheResult ¶
type CacheResult int
CacheResult indicates the status of cached data
const ( // CacheResultFresh indicates data was freshly fetched CacheResultFresh CacheResult = iota // CacheResultCached indicates data was returned from cache CacheResultCached // CacheResultStale indicates stale data was returned due to fetch error CacheResultStale )
type CachingFetcher ¶
type CachingFetcher[T any] struct { // contains filtered or unexported fields }
CachingFetcher is a generic caching HTTP fetcher that handles HTTP requests with caching
func NewCachingFetcher ¶
func NewCachingFetcher[T any](url string, config CacheConfig) *CachingFetcher[T]
NewCachingFetcher creates a new caching fetcher for the specified URL and type Uses JSON unmarshaling by default
func NewCachingFetcherWithFunc ¶
func NewCachingFetcherWithFunc[T any](url string, config CacheConfig, fetchFunc FetchFunc[T]) *CachingFetcher[T]
NewCachingFetcherWithFunc creates a new caching fetcher with a custom fetch function If fetchFunc is nil, defaults to JSON unmarshaling
func (*CachingFetcher[T]) Get ¶
func (f *CachingFetcher[T]) Get(ctx context.Context) (T, CacheResult, error)
Get fetches data from the URL with caching Returns the data, cache result status, and any error encountered
func (*CachingFetcher[T]) GetCacheInfo ¶
func (f *CachingFetcher[T]) GetCacheInfo() (cachedAt, expiresAt time.Time, hasData bool)
GetCacheInfo returns information about the cache status
func (*CachingFetcher[T]) GetCachedData ¶
func (f *CachingFetcher[T]) GetCachedData() *T
GetCachedData returns the currently cached data without fetching Returns nil if no data is cached
type CloudflareProvider ¶
type CloudflareProvider struct {
*HTTPTextProvider
}
CloudflareProvider fetches IP ranges from Cloudflare
func NewCloudflareProvider ¶
func NewCloudflareProvider(ipv6 bool) *CloudflareProvider
NewCloudflareProvider creates a new Cloudflare prefix list provider
type Config ¶
type Config struct {
// Providers lists the enabled providers
Providers []ProviderConfig `mapstructure:"providers" yaml:"providers"`
}
Config represents the configuration for prefix list providers
type FastlyProvider ¶
type FastlyProvider struct {
*HTTPJSONProvider[fastlyIPRanges]
}
FastlyProvider fetches IP ranges from Fastly CDN
func NewFastlyProvider ¶
func NewFastlyProvider() *FastlyProvider
NewFastlyProvider creates a new Fastly prefix list provider
type FetchResult ¶
type FetchResult[T any] struct { Data T Result CacheResult Error error }
FetchResult contains the fetched data and metadata about the fetch
type GitHubProvider ¶
type GitHubProvider struct {
*HTTPJSONProvider[githubMeta]
// contains filtered or unexported fields
}
GitHubProvider fetches IP ranges from GitHub's meta API
func NewGitHubProvider ¶
func NewGitHubProvider(filter string) *GitHubProvider
NewGitHubProvider creates a new GitHub prefix list provider
type GitLabProvider ¶
type GitLabProvider struct {
// contains filtered or unexported fields
}
GitLabProvider provides static IP ranges for GitLab webhooks
func NewGitLabProvider ¶
func NewGitLabProvider() *GitLabProvider
NewGitLabProvider creates a new GitLab prefix list provider
func (*GitLabProvider) Name ¶
func (p *GitLabProvider) Name() string
type GoogleProvider ¶
type GoogleProvider struct {
*HTTPJSONProvider[googleIPRanges]
// contains filtered or unexported fields
}
GoogleProvider fetches IP ranges from Google Cloud
func NewGoogleProvider ¶
func NewGoogleProvider(scopes, services []string) *GoogleProvider
NewGoogleProvider creates a new Google Cloud prefix list provider scopes: optional list of scopes to filter by (e.g., ["us-central1", "europe-west1"]) services: optional list of services to filter by (e.g., ["Google Cloud"])
type HTTPJSONProvider ¶
type HTTPJSONProvider[T any] struct { // contains filtered or unexported fields }
HTTPJSONProvider is a generic provider that fetches JSON data and transforms it into prefixes
func NewHTTPJSONProvider ¶
func NewHTTPJSONProvider[T any](name, url string, config CacheConfig, transform TransformFunc[T]) *HTTPJSONProvider[T]
NewHTTPJSONProvider creates a new HTTP JSON-based provider Parameters:
- name: the name of the provider (e.g., "github", "aws")
- url: the HTTP endpoint to fetch from
- config: caching configuration
- transform: function to transform the JSON response into prefixes
func (*HTTPJSONProvider[T]) Name ¶
func (p *HTTPJSONProvider[T]) Name() string
type HTTPTextProvider ¶
type HTTPTextProvider struct {
// contains filtered or unexported fields
}
HTTPTextProvider is a provider for HTTP endpoints that return plain text lists of prefixes
func NewHTTPTextProvider ¶
func NewHTTPTextProvider(name, url string, config CacheConfig) *HTTPTextProvider
NewHTTPTextProvider creates a new HTTP text-based provider The endpoint is expected to return a plain text list of CIDR ranges (one per line)
func (*HTTPTextProvider) Name ¶
func (p *HTTPTextProvider) Name() string
type HetznerProvider ¶
type HetznerProvider struct {
// contains filtered or unexported fields
}
HetznerProvider provides static IP ranges for Hetzner Cloud
func NewHetznerProvider ¶
func NewHetznerProvider() *HetznerProvider
NewHetznerProvider creates a new Hetzner prefix list provider
func (*HetznerProvider) Name ¶
func (p *HetznerProvider) Name() string
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener wraps a net.Listener and filters connections based on prefix lists
Example ¶
ExampleListener demonstrates using the prefix list listener
package main
import (
"context"
"fmt"
"net"
"github.com/dioad/net/authz/prefixlist"
"github.com/rs/zerolog"
)
func main() {
logger := zerolog.Nop()
// Create a base listener
baseListener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
panic(err)
}
defer baseListener.Close()
// Create a multi-provider with GitLab provider
gitlabProvider := prefixlist.NewGitLabProvider()
multiProvider := prefixlist.NewMultiProvider([]prefixlist.Provider{gitlabProvider}, logger)
ctx := context.Background()
_, err = multiProvider.Prefixes(ctx)
if err != nil {
panic(err)
}
// Wrap with prefix list listener
plListener := prefixlist.NewListener(baseListener, multiProvider, logger)
fmt.Printf("Listening on %s with prefix list filtering\n", plListener.Addr())
// Now only connections from allowed IPs will be accepted
// conn, err := plListener.Accept()
}
func NewListener ¶
NewListener creates a new prefix list filtering listener
func (*Listener) Accept ¶
Accept waits for and returns the next connection, filtering based on prefix lists
type MultiProvider ¶
type MultiProvider struct {
// contains filtered or unexported fields
}
MultiProvider wraps multiple providers and implements the Provider interface
func NewMultiProvider ¶
func NewMultiProvider(providers []Provider, logger zerolog.Logger) *MultiProvider
NewMultiProvider creates a new multi-provider that wraps multiple providers
func NewMultiProviderFromConfig ¶
func NewMultiProviderFromConfig(cfg Config, logger zerolog.Logger) (*MultiProvider, error)
NewMultiProviderFromConfig creates a MultiProvider from configuration
Example ¶
ExampleNewMultiProviderFromConfig demonstrates creating a multi-provider from configuration
package main
import (
"context"
"fmt"
"github.com/dioad/net/authz/prefixlist"
"github.com/rs/zerolog"
)
func main() {
logger := zerolog.Nop()
config := prefixlist.Config{
Providers: []prefixlist.ProviderConfig{
{
Name: "github",
Enabled: true,
Filter: map[string]string{"service": "hooks"}, // Only GitHub webhook IPs
},
{
Name: "gitlab",
Enabled: true,
},
},
}
multiProvider, err := prefixlist.NewMultiProviderFromConfig(config, logger)
if err != nil {
panic(err)
}
ctx := context.Background()
_, err = multiProvider.Prefixes(ctx)
if err != nil {
panic(err)
}
fmt.Println("MultiProvider created with multiple providers")
}
Output: MultiProvider created with multiple providers
func (*MultiProvider) Contains ¶
func (m *MultiProvider) Contains(addr netip.Addr) bool
Contains checks if an IP address is in any of the cached prefix lists
func (*MultiProvider) GetPrefixes ¶
func (m *MultiProvider) GetPrefixes() []netip.Prefix
GetPrefixes returns a copy of all current prefixes
func (*MultiProvider) Name ¶
func (m *MultiProvider) Name() string
Name returns a combined name of all providers
type Provider ¶
type Provider interface {
// Name returns the provider name (e.g., "github", "cloudflare")
Name() string
// Prefixes returns the current list of IP prefixes from the provider
Prefixes(ctx context.Context) ([]netip.Prefix, error)
// Contains checks if an IP address is in the provider's prefix list
Contains(addr netip.Addr) bool
}
Provider defines the interface for fetching IP prefix lists from different sources
func NewProviderFromConfig ¶
func NewProviderFromConfig(cfg ProviderConfig) (Provider, error)
NewProviderFromConfig creates a provider instance from configuration
type ProviderConfig ¶
type ProviderConfig struct {
// Name is the provider name (github, cloudflare, google, atlassian, gitlab, aws)
Name string `mapstructure:"name" yaml:"name"`
// Enabled controls whether this provider is active
Enabled bool `mapstructure:"enabled" yaml:"enabled"`
// Filter optionally filters prefixes using a map of key-value pairs
// Examples:
// GitHub: {"service": "hooks"} or {"service": "actions"}
// AWS: {"service": "EC2", "region": "us-east-1"}
// Google: {"scope": "us-central1", "service": "Google Cloud"}
// Atlassian: {"region": "global", "product": "jira"}
// Cloudflare: {"version": "ipv6"}
Filter map[string]string `mapstructure:"filter" yaml:"filter,omitempty"`
}
ProviderConfig represents configuration for a single provider