Skip to main content

Update Hetzner Cloud firewall rules with Cloudflare IP ranges

Project description

Update Hetzner Cloud Firewall Rules with Current Cloudflare IP Ranges

codecov OpenSSF Best Practices OpenSSF Scorecard CodeQL Python package Docker build PyPI - Version PyPI - Python Version Ask DeepWiki SLSA 3

This tool, cf-ips-to-hcloud-fw, helps you keep your Hetzner Cloud firewall rules up-to-date with the current Cloudflare IP ranges.

Table of Contents

Overview

cf-ips-to-hcloud-fw fetches the current Cloudflare IP ranges and updates your Hetzner Cloud firewall rules using the hcloud API.

The tool specifically targets incoming firewall rules and replaces the networks with Cloudflare networks if their description contains __CLOUDFLARE_IPS_V4__, __CLOUDFLARE_IPS_V6__ or __CLOUDFLARE_IPS__.

Text in rule description Cloudflare IP ranges
__CLOUDFLARE_IPS_V4__ IPv4 only
__CLOUDFLARE_IPS_V6__ IPv6 only
__CLOUDFLARE_IPS__ IPv4 + IPv6

Note: Having both __CLOUDFLARE_IPS_V4__ and __CLOUDFLARE_IPS_V6__ in a rule description is equivalent to having __CLOUDFLARE_IPS__ there.

Installation

Using Python

To install cf-ips-to-hcloud-fw using Python, we recommend using pipx or uvx. Both are tools for installing and running Python applications in isolated environments. If you already have uv installed, uvx is the quickest option.

Using pipx (Recommended for Most Users)

  1. Install cf-ips-to-hcloud-fw using pipx:

    pipx install cf-ips-to-hcloud-fw
    
  2. Verify the installation:

    cf-ips-to-hcloud-fw -h
    

You should see the usage information for cf-ips-to-hcloud-fw.

To upgrade cf-ips-to-hcloud-fw, run:

[!TIP] To upgrade cf-ips-to-hcloud-fw, run pipx upgrade cf-ips-to-hcloud-fw.

Using uvx (Recommended for uv Users)

If you have uv installed, you can run cf-ips-to-hcloud-fw directly without installing it:

uvx cf-ips-to-hcloud-fw -c config.yaml

This approach automatically downloads and runs the latest version in an isolated environment without modifying your system Python.

[!TIP] uvx always fetches and runs the latest version, so no upgrade command is needed.

Using pip

We strongly recommend using a virtual environment when installing Python packages with pip. This helps to avoid conflicts between packages and allows you to manage packages on a per-project basis.

  1. Create a virtual environment:

    python3 -m venv cf-ips-to-hcloud-fw-venv
    
  2. Install cf-ips-to-hcloud-fw into the virtual environment:

    ./cf-ips-to-hcloud-fw-venv/bin/pip3 install cf-ips-to-hcloud-fw
    
  3. Verify the installation:

    ./cf-ips-to-hcloud-fw-venv/bin/cf-ips-to-hcloud-fw -h
    

You should see the usage information for cf-ips-to-hcloud-fw.

[!TIP] To upgrade cf-ips-to-hcloud-fw in your virtual environment, run ./cf-ips-to-hcloud-fw-venv/bin/pip3 install --upgrade cf-ips-to-hcloud-fw.

Docker and Kubernetes

As an alternative, cf-ips-to-hcloud-fw can be run using Docker or a Kubernetes CronJob. Simply mount your configuration file as /usr/src/app/config.yaml.

Here's an example using Docker:

docker run --rm \
  --mount type=bind,source=$(pwd)/config.yaml,target=/usr/src/app/config.yaml,readonly \
  jkreileder/cf-ips-to-hcloud-fw:1.2.1

(Add --pull=always if you use a rolling image tag.)

Docker images for cf-ips-to-hcloud-fw are available for both linux/amd64 and linux/arm64 architectures. The Docker images support the following tags:

  • 1: This tag always points to the latest 1.x.x release.
  • 1.2: This tag always points to the latest 1.2.x release.
  • 1.2.1: This tag points to the specific 1.2.1 release.
  • main: This tag points to the most recent development version of cf-ips-to-hcloud-fw. Use this at your own risk as it may contain unstable changes.

You can find the Docker images at:

  • Docker Hub: jkreileder/cf-ips-to-hcloud-fw or docker.io/jkreileder/cf-ips-to-hcloud-fw
  • Quay.io: quay.io/jkreileder/cf-ips-to-hcloud-fw
  • GitHub Packages: ghcr.io/jkreileder/cf-ips-to-hcloud-fw

Here's an example of how to create a Kubernetes Secret for your configuration:

apiVersion: v1
kind: Secret
metadata:
  name: cf-ips-to-hcloud-fw-config
type: Opaque
stringData:
  config.yaml: |
    - token: API_TOKEN_FOR_PROJECT_1
      firewalls:
        - firewall-1
        - firewall-2
    - token: API_TOKEN_FOR_PROJECT_2
      firewalls:
        - default

And here's an example of a Kubernetes CronJob that uses the Secret:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cf-ips-to-hcloud-fw
spec:
  schedule: "0 * * * *" # Run every hour
  jobTemplate:
    spec:
      template:
        spec:
          securityContext:
            runAsNonRoot: true
            runAsUser: 65534
          containers:
            - name: cf-ips-to-hcloud-fw
              image: jkreileder/cf-ips-to-hcloud-fw:1.2.1
              # imagePullPolicy: Always # Uncomment this if you use a rolling image tag
              securityContext:
                allowPrivilegeEscalation: false
                readOnlyRootFilesystem: true
                capabilities:
                  drop:
                    - ALL
              volumeMounts:
                - name: config-volume
                  mountPath: /usr/src/app/config.yaml
                  subPath: config.yaml
          volumes:
            - name: config-volume
              secret:
                secretName: cf-ips-to-hcloud-fw-config
          restartPolicy: OnFailure

Configuration

Preparing the Hetzner Cloud Firewall

To prepare your Hetzner Cloud Firewall:

  1. Set the rule descriptions: Include __CLOUDFLARE_IPS_V4__, __CLOUDFLARE_IPS_V6__, or __CLOUDFLARE_IPS__ in the description of any incoming firewall rule where you want to insert Cloudflare networks. This will be used as a marker to identify which rules should be updated with the Cloudflare IP ranges.

  2. Generate an API token: You'll need an API token with write permissions for the project that contains the firewall. This token will be used to authenticate your requests to the Hetzner Cloud API. You can generate a token in the Hetzner Cloud Console by going to "Security" > "API Tokens" > "Generate API Token".

Configuring the Application

To configure the application, you'll need to create a config.yaml file with your API tokens and the names of the firewalls you want to update:

- token: API_TOKEN_FOR_PROJECT_1 # Token with read-write permissions for a Hetzner Cloud project
  firewalls:
    - firewall-1
    - firewall-2
- token: API_TOKEN_FOR_PROJECT_2 # Token with read-write permissions for another Hetzner Cloud project
  firewalls:
    - default

Usage

Run the tool with your configuration file:

cf-ips-to-hcloud-fw -c config.yaml

Command-line Options

  • -c, --config FILE: Path to the configuration file (required)
  • -d, --debug: Enable debug logging for troubleshooting
  • -v, --version: Display the installed version

Example with debug logging:

cf-ips-to-hcloud-fw -c config.yaml -d

Verifying SLSA Attestations

Build provenance metadata and SBOM attestations are published with every artifact so you can verify their authenticity and contents.

These attestations are cryptographically signed. Use the commands below to validate the signatures. For GitHub-hosted artifacts you can further restrict verification with --signer-workflow. Container attestations can be fetched with docker scout attest get after verifying build provenance.

Verifying Python Wheels and Source Code

GH_REPO=jkreileder/cf-ips-to-hcloud-fw
VERSION=1.2.1

# Verifying build provenance
gh attestation verify cf_ips_to_hcloud_fw-$VERSION-py3-none-any.whl \
  --repo $GH_REPO \
  --signer-workflow $GH_REPO/.github/workflows/python-package.yaml@refs/tags/v$VERSION
gh attestation verify cf_ips_to_hcloud_fw-$VERSION.tar.gz \
  --repo $GH_REPO \
  --signer-workflow $GH_REPO/.github/workflows/python-package.yaml@refs/tags/v$VERSION

# Verifying and showing SBOM (only available for the the wheel)
gh attestation verify cf_ips_to_hcloud_fw-$VERSION-py3-none-any.whl \
  --repo $GH_REPO \
  --signer-workflow $GH_REPO/.github/workflows/python-package.yaml@refs/tags/v$VERSION \
  --predicate-type https://spdx.dev/Document/v2.3
# Add --format json --jq '.[].verificationResult.statement.predicate' to also output the SBOM

Verifying Docker Images

It's recommended that you use an immutable image reference (pin to a digest) to avoid TOCTOU attacks.

Build provenance:

GH_REPO=jkreileder/cf-ips-to-hcloud-fw
IMAGE_REPO=docker.io/jkreileder/cf-ips-to-hcloud-fw
VERSION=1.2.1
IMAGE=$IMAGE_REPO@$(crane digest $IMAGE_REPO:$VERSION)

# Verifying build provenance
gh attestation verify oci://$IMAGE \
  --repo $GH_REPO \
  --signer-workflow $GH_REPO/.github/workflows/docker.yaml@refs/tags/v$VERSION

# The SBOMs are attached to the now verified image, you can view with
DIGEST=$(docker scout attest list --format json $IMAGE --predicate-type https://spdx.dev/Document \
  | jq -r 'limit(1; .[] | select(.reference | startswith("jkreileder/cf-ips-to-hcloud-fw")) | .digest)')
docker scout attest get $IMAGE $DIGEST --predicate-type https://spdx.dev/Document

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines on how to contribute to this project.

Security

If you discover a security vulnerability, please see SECURITY.md for responsible disclosure instructions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cf_ips_to_hcloud_fw-1.2.1.tar.gz (65.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cf_ips_to_hcloud_fw-1.2.1-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file cf_ips_to_hcloud_fw-1.2.1.tar.gz.

File metadata

  • Download URL: cf_ips_to_hcloud_fw-1.2.1.tar.gz
  • Upload date:
  • Size: 65.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cf_ips_to_hcloud_fw-1.2.1.tar.gz
Algorithm Hash digest
SHA256 eb2b93f27322e8fc186640fb4b5a971f969d77d3c76f729bddfebeb75e4ccaf7
MD5 450d2de48b64f4110e909132c3d75873
BLAKE2b-256 f051dc8350df7391b9b00741e1254becbb6412ce6946d863b8697bec17ef0f07

See more details on using hashes here.

Provenance

The following attestation bundles were made for cf_ips_to_hcloud_fw-1.2.1.tar.gz:

Publisher: python-package.yaml on jkreileder/cf-ips-to-hcloud-fw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cf_ips_to_hcloud_fw-1.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for cf_ips_to_hcloud_fw-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6c32f1352ee9e0d66bf4ec324e64b62509f166274d89ff255b845b6b792d2ccf
MD5 8a86db25f3e4fbaf478675d80f12aac1
BLAKE2b-256 6eeeb02dc20f49f514f9e57a6a0611ab2bc6c59cec6d29b96fcdf6c154734a4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for cf_ips_to_hcloud_fw-1.2.1-py3-none-any.whl:

Publisher: python-package.yaml on jkreileder/cf-ips-to-hcloud-fw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page