Skip to main content

netcup-dyndns-and-trusted-proxies-updater

This script is designed for users with a dynamic dual-stack address, using Netcup as their provider. It automatically updates your IPv6 address in the Trusted Proxy configuration for Nextcloud.

The script checks the current IPv4/IPv6 address of the host and updates the corresponding values at Netcup if necessary. Additionally, it updates the Trusted Proxies configuration in Nextcloud via the OCC CLI.

Prerequisites

This script needs Python 3.13 or newer.

Installation

Install the PyPI project with your preferred tool:

pipx install netcup-dyndns-and-trusted-proxies-updater
uv tool install netcup-dyndns-and-trusted-proxies-updater
pip install netcup-dyndns-and-trusted-proxies-updater

Using an Installed Tool

All three installation methods provide the netcup-dyndns command. Confirm the installed version and repository URL with:

netcup-dyndns --version

By default, the command creates .settings.json and .temp in the current working directory. First inspect the paths it will use:

netcup-dyndns --show-paths

Run it once to create the settings file, edit the generated file with your credentials and domains, then run the updater again:

netcup-dyndns

For a service, cron job, or any other setup where the current directory is not stable, specify absolute paths explicitly:

netcup-dyndns \
  --settings-file /etc/netcup-dyndns/settings.json \
  --cache-dir /var/lib/netcup-dyndns

Use the same --settings-file and --cache-dir values for every run. The cache directory stores the last observed IP addresses and retry state.

You can also clone this repository to run it from source:

git clone <repository-url>
cd netcup-dyndns-and-trusted-proxies-updater
uv run src/netcup-dyndns.py

The first run will create a settings.json file and a temp folder in your project directory. 3. Configure the settings.json file with the following parameters:

{
    "API_PASSWORD": "",
    "API_KEY": "",
    "CUSTOMER_ID": "",
    "NETCUP_DOMAIN": "",
    "NEXTCLOUD_PATH": "",
    "TRUSTED_PROXIES_POS": "",
    "PARALLEL_PROCESSES": 1,
    "IP_MODE": "both",
    "DISABLE_NEXTCLOUD_NGINX": false
}

API_PASSWORD: Your Netcup API password.
API_KEY: Your Netcup API key.
CUSTOMER_ID: Your Netcup customer ID.
NETCUP_DOMAIN: The domain name(s) you want to update, separated by commas (e.g., example.com, example.net).
NEXTCLOUD_PATH: The file path to your Nextcloud instance (required unless DISABLE_NEXTCLOUD_NGINX is true). TRUSTED_PROXIES_POS: The position in the TrustedProxies configuration where the new IP address should be added (e.g., the first, second, etc.; required unless DISABLE_NEXTCLOUD_NGINX is true). PARALLEL_PROCESSES: Number of parallel threads for DNS updates (Default: 1 for sequential execution. Values > 1 enable the ThreadPoolExecutor). IP_MODE: Determines which IP types to update. Options are "both" (default), "ipv4", or "ipv6". DISABLE_NEXTCLOUD_NGINX: Set to true to disable all Nextcloud OCC and Nginx reload tasks. Useful if you only want to use the script as a pure DynDNS client (Default: false).

Command-Line Arguments

Every setting can also be provided as a command-line argument. Command-line arguments always take precedence over .settings.json (and any secret provider overrides, see Providing Secrets at Runtime), which is useful for one-off overrides or wiring the script into other tooling without editing the settings file. Run with --help to see all available options:

netcup-dyndns --help
options:
  -h, --help            show this help message and exit
  --version             show the version and repository URL, then exit
  --settings-file PATH  path to the settings JSON file
  --cache-dir PATH      directory for temporary IP and retry cache files
  --show-paths          show the resolved settings-file and cache-directory paths, then exit
  --api-password API_PASSWORD
                        Netcup API password. Overrides API_PASSWORD.
  --api-key API_KEY     Netcup API key. Overrides API_KEY.
  --customer-id CUSTOMER_ID
                        N
  --netcup-domain NETCUP_DOMAIN
                        Comma-separated domain(s) to update, e.g.
                        'example.com,example.net'. Overrides NETCUP_DOMAIN.
  --nextcloud-path NEXTCLOUD_PATH
                        Path to the Nextcloud installation. Overrides
                        NEXTCLOUD_PATH.
  --trusted-proxies-pos TRUSTED_PROXIES_POS
                        Position in the trusted_proxies configuration to
                        update. Overrides TRUSTED_PROXIES_POS.
  --parallel-processes PARALLEL_PROCESSES
                        Number of parallel DNS-update workers. Overrides
                        PARALLEL_PROCESSES.
  --ip-mode {both,ipv4,ipv6}
                        Which IP types to update: 'both' (default), 'ipv4', or
                        'ipv6'. Overrides IP_MODE.
  --disable-nextcloud-nginx, --no-disable-nextcloud-nginx
                        Disable the Nextcloud OCC / Nginx reload tasks (use
                        --no-disable-nextcloud-nginx to force-enable them).
                        Overrides DISABLE_NEXTCLOUD_NGINX.

Example, overriding just the domain for a single run without touching .settings.json:

netcup-dyndns --netcup-domain example.com,example.net

Docker Installation (alternative)

Instead of installing uv and Python locally, you can run this project as a lightweight Docker container. The provided Docker/Dockerfile uses a multi-stage build: uv and dependency resolution happen only in a throw-away build stage, and the final runtime image is based on python:3.13-slim with just the resolved virtual environment and application code — no uv, compilers, or other build tools are present in the image you actually run.

  1. Create and fill in your .settings.json file (see Configuration for the available keys), then make sure it is readable by the container:

    chmod 644 .settings.json
    
  2. Build and start the container with Docker Compose:

    docker compose -f Docker/docker-compose.yml up -d --build
    

    This mounts .settings.json read-write into the container and persists the cached IP addresses in a named volume (dyndns-cache) across restarts. By default, the container checks for IP changes every UPDATE_INTERVAL_SECONDS (300s/5 minutes); adjust this in Docker/docker-compose.yml as needed.

    Alternatively, to trigger a single run (e.g. from a host cron job or systemd timer) instead of running continuously:

    docker compose -f Docker/docker-compose.yml run --rm -e RUN_ONCE=true netcup-dyndns-updater
    
  3. Nextcloud/Nginx integration caveat: nginx_trusted_proxies_configuration shells out to sudo, php occ, and systemctl restart nginx on the host. These are not available inside the minimal container, so set DISABLE_NEXTCLOUD_NGINX: true in .settings.json when running via Docker unless you specifically bind-mount those host binaries into a privileged container (not recommended). Running purely as a DynDNS client works out of the box.

Providing Secrets at Runtime

As an alternative to storing credentials in plain text in .settings.json, the script supports two optional, opt-in mechanisms to override settings at runtime. Both are disabled unless explicitly configured via environment variables, and neither requires any additional dependency.

1. Secret files (Docker/Kubernetes secrets convention)

Set an environment variable named <KEY>_FILE pointing at a file whose contents will be read (and trimmed) to override the corresponding setting, e.g.:

API_PASSWORD_FILE=/run/secrets/api_password
API_KEY_FILE=/run/secrets/api_key
CUSTOMER_ID_FILE=/run/secrets/customer_id

This works with Docker Compose secrets:, Kubernetes Secret volumes, or any tool that projects a secret's value into a file (including an OpenBAO Agent injector sidecar).

2. Direct retrieval from an OpenBAO (or Vault-compatible) server

Configure the following environment variables to have the script fetch a KV v2 secret at startup and use its values to override matching settings keys (API_PASSWORD, API_KEY, CUSTOMER_ID, etc.):

OPENBAO_ADDR=https://openbao.example.internal:8200
OPENBAO_TOKEN=s.xxxxxxxxxxxxxxxxxxxx      # or OPENBAO_TOKEN_FILE=/run/secrets/openbao_token
OPENBAO_SECRET_PATH=secret/data/netcup-dyndns   # optional, this is the default

The secret is expected at <OPENBAO_ADDR>/v1/<OPENBAO_SECRET_PATH> in the standard KV v2 response shape ({"data": {"data": {...}}}). Only keys already recognized by .settings.json are applied; unknown keys in the secret are ignored.

If both mechanisms are configured, secret-file overrides take precedence over OpenBAO values, since they are applied last. Neither mechanism is required — you can continue to configure everything directly in .settings.json. Command-line arguments (see Command-Line Arguments) are applied after both, and therefore always take precedence over secret provider values as well.

Usage

To run the script periodically, set up a cron job or a systemd timer. This will ensure your IP address is regularly checked and updated.

While updating DNS records, a progress bar is shown. Its total is derived from the number of subdomains listed in NETCUP_DOMAIN (each subdomain accounts for one A and one AAAA record), and it advances by one step for every record that is successfully updated, reaching 100% once all A and AAAA records for every configured subdomain have been updated:

Updating DNS records: 100%|██████████| 4/4 records

Regular progress is logged to stdout with timestamps and log levels (INFO/WARNING). Errors are logged in red (ERROR) so failures stand out immediately.

When multiple domains or subdomains are configured, the script prints a summary at the end grouped by domain instead of a flat sequential list, e.g.:

example.com
  - sub          A     -> 1.2.3.4
  - sub          AAAA  -> ::1
  - www          A     -> 1.2.3.4
example.net
  - app          A     -> 1.2.3.4

Configuration

Upon the first execution, the script creates a settings.json file and a temp folder.

The API identifiers for Netcup (API key, password, and customer ID) must be configured in the settings.json file. In the NETCUP_DOMAIN field, list all desired domain names separated by commas (e.g., example.com, example.net). NEXTCLOUD_PATH should point to the directory where your Nextcloud instance is located. TRUSTED_PROXIES_POS specifies the position in the TrustedProxies configuration where the new IP address should be inserted.

Contributing

To ensure proper code formatting, run the following command:

uv run --dev ruff check

To run tests:

uv run --dev pytest

To run tests with a coverage report:

uv run --dev pytest --cov=src --cov-report=term-missing

License

Licensed under the terms of GNU General Public License v3.0. See LICENSE file.

Download files

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

Source Distribution

Built Distribution

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

File details

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

File metadata

  • Download URL: netcup_dyndns_and_trusted_proxies_updater-1.2.1.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for netcup_dyndns_and_trusted_proxies_updater-1.2.1.tar.gz
Algorithm Hash digest
SHA256 9af428a04359c1b617dc8f34c198f1a51e07c47b70539059322fd1ff3210124d
MD5 c02e787bed17894d5a2ec17c0ae6f9ef
BLAKE2b-256 1c736a1a9f76a85f9cf6393e2ecefdd47a0b577657ff08a9b55bc53617592d81

See more details on using hashes here.

File details

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

File metadata

  • Download URL: netcup_dyndns_and_trusted_proxies_updater-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 27.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for netcup_dyndns_and_trusted_proxies_updater-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 012141073efa9a1f75262894b48f33c824b7be6162068a371b03e57d8ddf580c
MD5 ea8c423754774e9ec9bc3554ad8e83b8
BLAKE2b-256 44d33551b0150a4b8390a902bb1662929880af9ee12b4d2acb1ba95ef1d8a7ce

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 files

1.2.0

2 files

Supported by

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