Coder Social home page Coder Social logo

gaofeird / cloudflare-ddns Goto Github PK

View Code? Open in Web Editor NEW

This project forked from favonia/cloudflare-ddns

0.0 0.0 0.0 422 KB

🌟 A small (~2.5MB), feature-rich, and robust Cloudflare DDNS updater

License: Apache License 2.0

Go 99.60% Dockerfile 0.40%

cloudflare-ddns's Introduction

🌟 Cloudflare DDNS

Github Source GitHub Workflow Status Codecov GitHub go.mod Go version Docker Image Size

A small and fast DDNS updater for Cloudflare.

πŸ”‡ Quiet mode enabled
🌟 Cloudflare DDNS
πŸ₯· Priviledges after dropping:
   πŸ”Έ Effective UID:      1000
   πŸ”Έ Effective GID:      1000
   πŸ”Έ Supplementary GIDs: (empty)
🐣 Added a new A record of "……" (ID: ……)
🐣 Added a new AAAA record of "……" (ID: ……)

πŸ“œ Highlights

  • Ultra-small Docker images (about 2.5 MB) for all common architectures.
  • Ability to update multiple domains across different zones.
  • Ability to enable or disable IPv4 and IPv6 individually.
  • Support of internationalized domain names.
  • Support of wildcard domain names (e.g., *.example.org).
  • Ability to remove stale records or choose to remove records on exit/stop.
  • Ability to obtain IP addresses from Cloudflare, ipify, or local network interfaces.
  • Support of timezone and Cron expressions.
  • Full configurability via environment variables.
  • Ability to pass API tokens via a file instead of an environment variable.
  • Local caching to reduce Cloudflare API usage.
  • Integration with Healthchecks.io.

πŸ•΅οΈ Privacy

By default, public IP addresses are obtained using the Cloudflare debugging page. This minimizes the impact on privacy because we are already using the Cloudflare API to update DNS records. Moreover, if Cloudflare servers are not reachable, chances are you could not update DNS records anyways. You can also configure the tool to use ipify, which claims not to log any visitor information.

πŸ›‘οΈ Security

🚷 The superuser privilege is immediately dropped after the updater starts.

The updater honors PGID and PUID and will drop Linux capabilities (divided superuser privileges).

πŸ”Œ The source code depends on six external libraries (outside the Go project).
  • cap:
    Manipulation of Linux capabilities.
  • cloudflare-go:
    The official Go binding of Cloudflare API v4. It provides robust handling of pagination, rate limiting, and other tricky details.
  • cron:
    Parsing of Cron expressions.
  • go-cache:
    Essentially map[string]interface{} with expiration times.
  • mock (for testing only):
    A comprehensive, semi-official framework for mocking.
  • testify (for testing only):
    A comprehensive tool set for testing Go programs.

⛷️ Quick Start

πŸ‹ Directly run the provided Docker images.
docker run \
  --network host \
  -e CF_API_TOKEN=YOUR-CLOUDFLARE-API-TOKEN \
  -e DOMAINS=www.example.org \
  -e PROXIED=true \
  favonia/cloudflare-ddns
🧬 Directly run the updater from its source.

You need the Go tool to run the updater from its source.

CF_API_TOKEN=YOUR-CLOUDFLARE-API-TOKEN \
  DOMAINS=www.example.org \
  PROXIED=true \
  go run ./cmd/*.go

πŸ‹ Deployment with Docker Compose

πŸ“¦ Step 1: Updating the Compose File

Incorporate the following fragment into the compose file (typically docker-compose.yml or docker-compose.yaml).

version: "3"
services:
  cloudflare-ddns:
    image: favonia/cloudflare-ddns:latest
    network_mode: host
    restart: always
    security_opt:
      - no-new-privileges:true
    environment:
      - PGID=1000
      - PUID=1000
      - CF_API_TOKEN
      - DOMAINS
      - PROXIED=true
πŸ“‘ Use network_mode: host to enable IPv6 (or read more).

The easiest way to enable IPv6 is to use network_mode: host so that the tool can access the host IPv6 network directly. If you wish to keep the tool isolated from the host network, check out the official documentation on IPv6 and this GitHub issue about IPv6. If your host OS is Linux, here’s the tl;dr:

  1. Use network_mode: bridge instead of network_mode: host.
  2. Edit or create /etc/docker/daemon.json with the following content:
    {
      "ipv6": true,
      "fixed-cidr-v6": "fd00::/8",
      "experimental": true,
      "ip6tables": true
    }
  3. Restart the Docker daemon (if you are using systemd):
    systemctl restart docker.service
πŸ” Use restart: always to automatically restart the updater on system reboot.

Docker’s default restart policies should prevent excessive logging when there are configuration errors.

πŸ›‘οΈ Use no-new-privileges:true, PUID, and PGID to protect yourself.

Change 1000 to the user or group IDs you wish to use to run the updater. The setting no-new-privileges:true provides additional protection, especially when you run the container as a non-superuser. The updater itself will read PUID and PGID and attempt to drop all those privileges as much as possible.

🎭 Use PROXIED=true to hide your IP addresses.

The setting PROXIED=true instructs Cloudflare to cache webpages on your machine and hide your actual IP addresses. If you wish to bypass that and expose your actual IP addresses, simply remove PROXIED=true. (The default value of PROXIED is false.)

πŸͺ§ Step 2: Updating the Environment File

Add these lines to your environment file (typically .env):

CF_API_TOKEN=YOUR-CLOUDFLARE-API-TOKEN
DOMAINS=example.org,www.example.org,example.io
πŸ”‘ CF_API_TOKEN is your Cloudflare API token.

The value of CF_API_TOKEN should be an API token (not an API key), which can be obtained from the API Tokens page. Use the Edit zone DNS template to create and copy a token into the environment file. ⚠️ The less secure API key authentication is deliberately not supported.

πŸ“ DOMAINS contains the domains to update.

The value of DOMAINS should be a list of fully qualified domain names separated by commas. For example, DOMAINS=example.org,www.example.org,example.io instructs the tool to manage the domains example.org, www.example.org, and example.io. These domains do not have to be in the same zone---the tool will identify their zones automatically.

πŸš€ Step 3: Building the Container

docker-compose pull cloudflare-ddns
docker-compose up --detach --build cloudflare-ddns

☸️ Deployment with Kubernetes

Kubernetes offers great flexibility in assembling different objects together. The following shows a minimum setup.

πŸ“ Step 1: Creating a YAML File

Save the following configuration as cloudflare-ddns.yaml.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cloudflare-ddns
  labels:
    app: cloudflare-ddns
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: cloudflare-ddns
  template:
    metadata:
      name: cloudflare-ddns
      labels:
        app: cloudflare-ddns
    spec:
      restartPolicy: Always
      containers:
        - name: cloudflare-ddns
          image: favonia/cloudflare-ddns:latest
          securityContext:
            allowPrivilegeEscalation: false
            runAsUser: 1000
            runAsGroup: 1000
          env:
            - name: "IP6_PROVIDER"
              value: "none"
            - name: "PROXIED"
              value: "true"
            - name: "CF_API_TOKEN"
              value: YOUR-CLOUDFLARE-API-TOKEN
            - name: "DOMAINS"
              value: "example.org,www.example.org,example.io"
πŸ” Use restartPolicy: Always to automatically restart the updater on system reboot.

Kubernetes’s default restart policies should prevent excessive logging when there are configuration errors.

πŸ›‘οΈ Use runAsUser, runAsGroup, and allowPrivilegeEscalation: false to protect yourself.

Kubernetes comes with built-in support to drop superuser privileges. The updater itself will also attempt to drop all of them.

πŸ“‘ Use IP6_PROVIDER: "none" to disable IPv6 management.

The support of IPv6 in Kubernetes has been improving, but a working setup still takes effort. Since Kubernetes 1.21+, the IPv4/IPv6 dual stack is enabled by default, but a setup which allows IPv6 egress traffic (e.g., to reach Cloudflare servers to detect public IPv6 addresses) still requires deep understanding of Kubernetes and is beyond this simple guide. The popular tool minicube, which implements a simple local Kubernetes cluster, unfortunately does not support IPv6 yet. Until there is an easy way to enable IPv6 in Kubernetes, the template here will have IPv6 disabled.

If you manage to enable IPv6, congratulations. Feel free to remove IP6_PROVIDER: "none" to detect and update both A and AAAA records. There is almost no danger in enabling IPv6 even when the IPv6 setup is not working. In the worst case, the updater will remove all AAAA records associated with the domains in DOMAINS and IP6_DOMAINS because those records will appear to be β€œstale.” The deleted records will be recreated once the updater correctly detects the IPv6 addresses.

🎭 Use PROXIED: "true" to hide your IP addresses.

The setting PROXIED: "true" instructs Cloudflare to cache webpages on your machine and hide your actual IP addresses. If you wish to bypass that and expose your actual IP addresses, simply remove PROXIED: "true". (The default value of PROXIED is false.)

πŸ”‘ CF_API_TOKEN is your Cloudflare API token.

The value of CF_API_TOKEN should be an API token (not an API key), which can be obtained from the API Tokens page. Use the Edit zone DNS template to create and copy a token into the environment file. ⚠️ The less secure API key authentication is deliberately not supported.

πŸ“ DOMAINS contains the domains to update.

The value of DOMAINS should be a list of fully qualified domain names separated by commas. For example, DOMAINS=example.org,www.example.org,example.io instructs this tool to manage the domains example.org, www.example.org, and example.io. These domains do not have to be in the same zone---this tool will identify their zones automatically.

πŸš€ Step 2: Creating the Deployment

kubectl create -f cloudflare-ddns.yaml

πŸŽ›οΈ Further Customization

βš™οΈ All Settings

πŸ”‘ Cloudflare accounts and API tokens
Name Valid Values Meaning Required? Default Value
CF_ACCOUNT_ID Cloudflare Account IDs The account ID used to distinguish multiple zone IDs with the same name No "" (unset)
CF_API_TOKEN_FILE Paths to files containing Cloudflare API tokens A file that contains the token to access the Cloudflare API Exactly one of CF_API_TOKEN and CF_API_TOKEN_FILE should be set N/A
CF_API_TOKEN Cloudflare API tokens The token to access the Cloudflare API Exactly one of CF_API_TOKEN and CF_API_TOKEN_FILE should be set N/A

In most cases, CF_ACCOUNT_ID is not needed.

πŸ“ Domains and IP providers
Name Valid Values Meaning Required? Default Value
DOMAINS Comma-separated fully qualified domain names or wildcard domain names The domains this tool should manage for both A and AAAA records (See below) N/A
IP4_DOMAINS Comma-separated fully qualified domain names or wildcard domain names The domains this tool should manage for A records (See below) N/A
IP6_DOMAINS Comma-separated fully qualified domain names or wildcard domain names The domains this tool should manage for AAAA records (See below) N/A
IP4_PROVIDER cloudflare.doh, cloudflare.trace, ipify, local, and none How to detect IPv4 addresses. (See below) No cloudflare.trace
IP6_PROVIDER cloudflare.doh, cloudflare.trace, ipify, local, and none How to detect IPv6 addresses. (See below) No cloudflare.trace
πŸ“ At least one of DOMAINS and IP4/6_DOMAINS must be non-empty.

At least one domain should be listed in DOMAINS, IP4_DOMAINS, or IP6_DOMAINS. Otherwise, if all of them are empty, then this updater has nothing to do. It is fine to list the same domain in both IP4_DOMAINS and IP6_DOMAINS, which is equivalent to listing it in DOMAINS. Internationalized domain names are supported using the non-transitional processing that is fully compatible with IDNA2008.

πŸ“œ Available providers for IP4_PROVIDER and IP6_PROVIDER
  • cloudflare.doh
    Get the public IP address by querying whoami.cloudflare. against Cloudflare via DNS-over-HTTPS and update DNS records accordingly.
  • cloudflare.trace
    Get the public IP address by parsing the Cloudflare debugging page and update DNS records accordingly.
  • ipify
    Get the public IP address via ipify’s public API and update DNS records accordingly.
  • local
    Get the address via local network interfaces and update DNS records accordingly. When multiple local network interfaces or in general multiple IP addresses are present, the tool will use the address that would have been used for outbound UDP connections to Cloudflare servers. ⚠️ You need access to the host network (such as network_mode: host in Docker Compose or hostNetwork: true in Kubernetes) for this policy, for otherwise the tool will detect the addresses inside the bridge network in Docker or the default namespaces in Kubernetes instead of those in the host network.
  • none
    Stop the DNS updating completely. Existing DNS records will not be removed.

The option IP4_PROVIDER is governing IPv4 addresses and A-type records, while the option IP6_PROVIDER is governing IPv6 addresses and AAAA-type records. The two options act independently of each other.

⏳ Schedules, timeouts, and parameters of new DNS records
Name Valid Values Meaning Required? Default Value
CACHE_EXPIRATION Positive time durations with a unit, such as 1h and 10m. See time.ParseDuration The expiration of cached Cloudflare API responses No 6h0m0s (6 hours)
DELETE_ON_STOP Boolean values, such as true, false, 0 and 1. See strconv.ParseBool Whether managed DNS records should be deleted on exit No false
DETECTION_TIMEOUT Positive time durations with a unit, such as 1h and 10m. See time.ParseDuration The timeout of each attempt to detect IP addresses No 5s (5 seconds)
PROXIED Boolean values, such as true, false, 0 and 1. See strconv.ParseBool Whether new DNS records should be proxied by Cloudflare No false
TTL Time-to-live (TTL) values in seconds The TTL values used to create new DNS records No 1 (This means β€œautomatic” to Cloudflare)
TZ Recognized timezones, such as UTC The timezone used for logging and parsing UPDATE_CRON No UTC
UPDATE_CRON Cron expressions. See the documentation of cron The schedule to re-check IP addresses and update DNS records (if necessary) No @every 5m (every 5 minutes)
UPDATE_ON_START Boolean values, such as true, false, 0 and 1. See strconv.ParseBool Whether to check IP addresses on start regardless of UPDATE_CRON No true
UPDATE_TIMEOUT Positive time durations with a unit, such as 1h and 10m. See time.ParseDuration The timeout of each attempt to update DNS records, per domain, per record type No 30s (30 seconds)

Note that the update schedule does not take the time to update records into consideration. For example, if the schedule is β€œfor every 5 minutes”, and if the updating itself takes 2 minutes, then the actual interval between adjacent updates is 3 minutes, not 5 minutes.

πŸ›‘οΈ Dropping superuser privileges
Name Valid Values Meaning Required? Default Value
PGID Non-zero POSIX group ID The group ID this tool should assume No Effective group ID; if it is zero, then the real group ID; if it is still zero, then 1000
PUID Non-zero POSIX user ID The user ID this tool should assume No Effective user ID; if it is zero, then the real user ID; if it is still zero, then 1000

The updater will also try to drop supplementary group IDs.

πŸ‘οΈ Monitoring the tool
Name Valid Values Meaning Required? Default Value
QUIET Boolean values, such as true, false, 0 and 1. See strconv.ParseBool Whether the updater should reduce the logging to the standard output No false
HEALTHCHECKS Healthchecks.io ping URLs, such as https://hc-ping.com/<uuid> or https://hc-ping.com/<project-ping-key>/<name-slug> If set, the tool will ping Healthchecks.io when it successfully updates IP addresses No N/A

πŸ”‚ Restarting the Container

If you are using Docker Compose, run docker-compose up --detach after changing the settings.

If you are using Kubernetes, run kubectl replace -f cloudflare-ddns.yaml after changing the settings.

🚡 Migration Guides

I am migrating from oznu/cloudflare-ddns.

⚠️ oznu/cloudflare-ddns relies on unverified DNS responses to obtain public IP addresses; a malicious hacker could potentially manipulate or forge DNS responses and trick it into updating your domain with any IP address. In comparison, we use only verified responses from Cloudflare or ipify.

Old Parameter New Paramater
API_KEY=key βœ”οΈ Use CF_API_TOKEN=key
API_KEY_FILE=file βœ”οΈ Use CF_API_TOKEN_FILE=file
ZONE=example.org and SUBDOMAIN=sub βœ”οΈ Use DOMAINS=sub.example.org directly
PROXIED=true βœ”οΈ Same
RRTYPE=A βœ”οΈ Both IPv4 and IPv6 are enabled by default; use IP6_PROVIDER=none to disable IPv6
RRTYPE=AAAA βœ”οΈ Both IPv4 and IPv6 are enabled by default; use IP4_PROVIDER=none to disable IPv4
DELETE_ON_STOP=true βœ”οΈ Same
INTERFACE=iface βœ”οΈ Not required for local providers; we can handle multiple network interfaces
CUSTOM_LOOKUP_CMD=cmd ❌ There is not even a shell in the minimum Docker image.
DNS_SERVER=server ❌ Only the Cloudflare server is supported.

πŸ’– Feedback

Questions, suggestions, feature requests, and contributions are all welcome! Feel free to open a GitHub issue.

cloudflare-ddns's People

Contributors

dependabot[bot] avatar favonia avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.