Documentation
¶
Overview ¶
Package prefixlist provides utilities for fetching and managing IP prefix lists from various cloud providers.
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
}
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. It uses JSON unmarshaling by default to decode the response body into type T.
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, it defaults to JSON unmarshaling. This allows for custom parsing of the HTTP response (e.g., plain text lines).
func (*CachingFetcher[T]) Get ¶
func (f *CachingFetcher[T]) Get(ctx context.Context) (T, CacheResult, error)
Get fetches data from the URL with caching. It returns the data, cache result status (Fresh, Cached, or Stale), and any error encountered. If ReturnStale is enabled, it may return stale data immediately and start a background refresh.
func (*CachingFetcher[T]) GetCacheInfo ¶
func (f *CachingFetcher[T]) GetCacheInfo() (cachedAt, expiresAt time.Time, hasData bool)
GetCacheInfo returns information about the current cache status. It returns the time the data was cached, the time it expires, and whether data is present.
func (*CachingFetcher[T]) GetCachedData ¶
func (f *CachingFetcher[T]) GetCachedData() *T
GetCachedData returns the currently cached data without performing a fetch. It returns nil if no data is currently 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