do-firewall-allowlister

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2025 License: MIT

README

DigitalOcean Firewall Allowlister

A Go service that automatically manages DigitalOcean firewall rules by allowing traffic from supported sources. The service can run as a daemon with scheduled updates or as a one-shot command.

Note: This project is personal project need for my own use case. make this publicly available for anyone who might find it useful. since this is also me for learning and trying out new things. so it might not be the best code, but it works for me. and i'm always open to suggestions and improvements.

Features

  • 🔥 Automatic Firewall Management: Updates DigitalOcean firewall rules automatically
  • ☁️ Cloudflare Integration: Fetches and allows current Cloudflare IP ranges
  • 📊 Netdata Support: Resolves and allows IPs for Netdata monitoring domains
  • Flexible Scheduling: Runs on configurable cron schedules
  • 🔧 Multiple Modes: Daemon mode for continuous operation, one-shot for manual execution
  • 🧪 Dry-Run Support: Test changes without modifying actual firewall rules
  • 📝 Structured Logging: JSON logging with configurable levels
  • ⚙️ Flexible Configuration: YAML files, environment variables, and CLI flags

Installation

Using Pre-built Binaries

Download the latest release from GitHub Releases:

# Linux (x86_64)
curl -L https://github.com/kholisrag/do-firewall-allowlister/releases/latest/download/do-firewall-allowlister_Linux_x86_64.tar.gz | tar xz

# macOS (x86_64)
curl -L https://github.com/kholisrag/do-firewall-allowlister/releases/latest/download/do-firewall-allowlister_Darwin_x86_64.tar.gz | tar xz

# Windows (x86_64)
curl -L https://github.com/kholisrag/do-firewall-allowlister/releases/latest/download/do-firewall-allowlister_Windows_x86_64.zip -o do-firewall-allowlister.zip
Using Docker

Multi-architecture Docker images are available:

# Run directly
docker run --rm ghcr.io/kholisrag/do-firewall-allowlister:latest --help

# With configuration file
docker run --rm -v $(pwd)/config.yaml:/config.yaml ghcr.io/kholisrag/do-firewall-allowlister:latest validate --config /config.yaml
Using Go Install
go install github.com/kholisrag/do-firewall-allowlister/cmd/do-firewall-allowlister@latest
From Source
git clone https://github.com/kholisrag/do-firewall-allowlister.git
cd do-firewall-allowlister

# Using Task (recommended)
task build

# Or using Go directly
go build -o do-firewall-allowlister ./cmd/do-firewall-allowlister

Configuration

The service uses a hierarchical configuration system with the following priority (highest to lowest):

  1. CLI Flags (highest priority)
  2. Environment Variables
  3. YAML Configuration File (lowest priority)
Configuration File

Create a config.yaml file:

logLevel: INFO

cron:
  schedule: "0 0 * * *" # Daily at midnight
  timezone: "UTC"

digitalocean:
  api_key: "your-digitalocean-api-key"
  firewall_id: "your-firewall-id"
  inbound_rules:
    - port: 80
      protocol: tcp
    - port: 443
      protocol: tcp

netdata:
  domains:
    - "app.netdata.cloud"
    - "api.netdata.cloud"
    - "mqtt.netdata.cloud"

cloudflare:
  ips_url: "https://api.cloudflare.com/client/v4/ips"
Environment Variables

All configuration options can be set via environment variables with the FIREWALL_ALLOWLISTER_ prefix:

export FIREWALL_ALLOWLISTER_LOG_LEVEL=DEBUG
export FIREWALL_ALLOWLISTER_DIGITALOCEAN_API_KEY=your-api-key
export FIREWALL_ALLOWLISTER_DIGITALOCEAN_FIREWALL_ID=your-firewall-id
export FIREWALL_ALLOWLISTER_CRON_SCHEDULE="0 */6 * * *"
CLI Flags

All configuration options can be overridden with global CLI flags that work with any command:

./do-firewall-allowlister daemon \
  --config config.yaml \
  --log-level DEBUG \
  --digitalocean.api-key your-api-key \
  --digitalocean.firewall-id your-firewall-id \
  --dry-run

Global flags are available for all commands and include:

  • --config, -c: Path to configuration file
  • --log-level: Logging level
  • --digitalocean.api-key: DigitalOcean API key
  • --digitalocean.firewall-id: DigitalOcean firewall ID
  • --cron.schedule: Cron schedule expression
  • --cron.timezone: Timezone for cron schedule
  • --cloudflare.ips-url: Cloudflare IPs API URL

Usage

Daemon Mode

Run the service continuously with scheduled updates:

# Run with default config.yaml
./do-firewall-allowlister daemon

# Run with custom config and dry-run mode
./do-firewall-allowlister daemon --config /path/to/config.yaml --dry-run

# Run with environment variables
FIREWALL_ALLOWLISTER_DIGITALOCEAN_API_KEY=your-key \
./do-firewall-allowlister daemon --dry-run
One-Shot Mode

Execute firewall updates once and exit:

# Run once with default config
./do-firewall-allowlister oneshot

# Run once with dry-run to see what would be changed
./do-firewall-allowlister oneshot --dry-run

# Run with custom configuration
./do-firewall-allowlister oneshot --config /path/to/config.yaml
Configuration Validation

Validate your configuration and test connectivity:

# Validate configuration file
./do-firewall-allowlister validate --config config.yaml

# Validate with environment variables
FIREWALL_ALLOWLISTER_DIGITALOCEAN_API_KEY=your-key \
./do-firewall-allowlister validate
Status Check

Check the status of external services:

# Get status in JSON format
./do-firewall-allowlister status --config config.yaml

# Get status in table format
./do-firewall-allowlister status --format table
Version Information

Get detailed version and build information:

# Text format
./do-firewall-allowlister version

# JSON format
./do-firewall-allowlister version --output json

How It Works

  1. IP Collection: The service fetches current Cloudflare IP ranges from their API and resolves IP addresses for configured Netdata domains
  2. Firewall Update: It updates the specified DigitalOcean firewall with inbound rules allowing traffic from these IPs on configured ports
  3. Scheduling: In daemon mode, it runs on a configurable cron schedule to keep firewall rules up-to-date
  4. Safety: Dry-run mode allows you to see what changes would be made without actually modifying firewall rules

Configuration Options

Option Environment Variable CLI Flag Description
Log Level FIREWALL_ALLOWLISTER_LOG_LEVEL --log-level Logging level (DEBUG, INFO, WARN, ERROR, FATAL)
Cron Schedule FIREWALL_ALLOWLISTER_CRON_SCHEDULE --cron.schedule Cron expression for scheduling
Timezone FIREWALL_ALLOWLISTER_CRON_TIMEZONE --cron.timezone Timezone for cron schedule
DO API Key FIREWALL_ALLOWLISTER_DIGITALOCEAN_API_KEY --digitalocean.api-key DigitalOcean API key
Firewall ID FIREWALL_ALLOWLISTER_DIGITALOCEAN_FIREWALL_ID --digitalocean.firewall-id DigitalOcean firewall ID
Cloudflare URL FIREWALL_ALLOWLISTER_CLOUDFLARE_IPS_URL --cloudflare.ips-url Cloudflare IPs API endpoint

Examples

Docker Deployment

The project includes a multi-stage Dockerfile using distroless images for security:

# Build the image
docker build -t do-firewall-allowlister .

# Run with configuration
docker run --rm -v $(pwd)/config.yaml:/config.yaml \
  do-firewall-allowlister daemon --config /config.yaml

# Run one-shot with dry-run
docker run --rm -v $(pwd)/config.yaml:/config.yaml \
  do-firewall-allowlister oneshot --config /config.yaml --dry-run

Or use the pre-built multi-architecture images:

# Pull and run
docker run --rm -v $(pwd)/config.yaml:/config.yaml \
  ghcr.io/kholisrag/do-firewall-allowlister:latest daemon --config /config.yaml
Systemd Service

Create /etc/systemd/system/do-firewall-allowlister.service:

[Unit]
Description=DigitalOcean Firewall Allowlister
After=network.target

[Service]
Type=simple
User=firewall-allowlister
WorkingDirectory=/opt/do-firewall-allowlister
ExecStart=/opt/do-firewall-allowlister/do-firewall-allowlister daemon --config /etc/do-firewall-allowlister/config.yaml
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: do-firewall-allowlister
spec:
  replicas: 1
  selector:
    matchLabels:
      app: do-firewall-allowlister
  template:
    metadata:
      labels:
        app: do-firewall-allowlister
    spec:
      containers:
        - name: do-firewall-allowlister
          image: your-registry/do-firewall-allowlister:latest
          command: ["./do-firewall-allowlister", "daemon"]
          env:
            - name: FIREWALL_ALLOWLISTER_DIGITALOCEAN_API_KEY
              valueFrom:
                secretKeyRef:
                  name: do-api-secret
                  key: api-key
            - name: FIREWALL_ALLOWLISTER_DIGITALOCEAN_FIREWALL_ID
              value: "your-firewall-id"
            - name: FIREWALL_ALLOWLISTER_LOG_LEVEL
              value: "INFO"

Development

Prerequisites
  • Go 1.21 or later
  • Task (recommended) or Make
  • GoReleaser (for releases)
  • Docker (for container builds)
  • DigitalOcean API token with firewall management permissions
Quick Start
# Clone the repository
git clone https://github.com/kholisrag/do-firewall-allowlister.git
cd do-firewall-allowlister

# Install dependencies
task deps

# Run tests
task test:short

# Build for current platform
task build

# See all available tasks
task --list
Available Tasks
# Development
task build              # Build binary for current platform
task build:all          # Build binaries for all platforms
task test               # Run all tests with coverage
task test:short         # Run short tests
task test:integration   # Run integration tests
task test:coverage      # Generate coverage report

# Code Quality
task fmt                # Format Go code
task lint               # Run linters
task check              # Run all checks (format, lint, test)

# Docker
task docker:build       # Build Docker image
task docker:run         # Run Docker container
task docker:push        # Push Docker image

# Release
task release:dry        # Dry run release with GoReleaser
task release            # Create release with GoReleaser

# Utilities
task clean              # Clean build artifacts
task dev                # Run in development mode
task validate           # Validate configuration
Manual Commands

If you prefer not to use Task:

# Build for current platform
go build -o do-firewall-allowlister ./cmd/do-firewall-allowlister

# Build for multiple platforms
GOOS=linux GOARCH=amd64 go build -o do-firewall-allowlister-linux-amd64 ./cmd/do-firewall-allowlister
GOOS=darwin GOARCH=amd64 go build -o do-firewall-allowlister-darwin-amd64 ./cmd/do-firewall-allowlister

# Run tests
go test -short ./...
go test -race -coverprofile=coverage.out ./...

# Format and lint
go fmt ./...
go vet ./...
golangci-lint run

# Docker build
docker build -t do-firewall-allowlister .

Security Considerations

  • API Key Security: Store DigitalOcean API keys securely using environment variables or secret management systems
  • Firewall Access: Ensure the API key has minimal required permissions (firewall read/write only)
  • Network Security: The service makes outbound HTTPS requests to Cloudflare and DigitalOcean APIs
  • Logging: Avoid logging sensitive information; API keys are not logged by default

Troubleshooting

Common Issues
  1. Invalid API Key: Ensure your DigitalOcean API key has firewall management permissions
  2. Firewall Not Found: Verify the firewall ID exists and is accessible with your API key
  3. DNS Resolution Failures: Check network connectivity for Netdata domain resolution
  4. Cron Schedule Errors: Validate cron expressions using online cron validators
Debug Mode

Enable debug logging to troubleshoot issues:

./do-firewall-allowlister daemon --log-level DEBUG --dry-run
Validation

Always test with dry-run mode first:

./do-firewall-allowlister oneshot --dry-run

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • DigitalOcean for their excellent API
  • Cloudflare for providing public IP ranges
  • Netdata for their monitoring platform
  • The Go community for excellent libraries and tools

Directories

Path Synopsis
cmd
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL