Skip to main content

Cliente Python para gestionar DNS en el panel XMS (Digital Value). CLI, biblioteca y servidor dyndns2/checkip compatible con ddclient. A, AAAA y TXT.

Project description

xms-dns

Cliente Python para gestionar DNS en el panel XMS (Digital Value). Incluye CLI (xms-dns), biblioteca y servidor dyndns2/checkip (xms-dns-server) compatible con ddclient. Soporta registros A, AAAA y TXT.

Setup

pip install xms-dns

For development:

git clone https://github.com/soukron/xms-dns.git
cd xms-dns
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Config file (optional, no secrets)

Create ~/.config/xms-dns/config with non-sensitive settings only:

mkdir -p ~/.config/xms-dns
cat > ~/.config/xms-dns/config <<'EOF'
XMS_BASE_URL=https://xms.digitalvalue.es
XMS_LOGIN=admin#example.test
EOF
chmod 600 ~/.config/xms-dns/config

Passwords are not read from this file. Use xms-dns login instead.

Environment variables override the config file. Override paths with XMS_CONFIG_DIR or XMS_CACHE_DIR.

Login

xms-dns login

Resolves settings in this order:

  1. Environment variables (XMS_BASE_URL, XMS_LOGIN, XMS_PASSWORD)
  2. Config file (XMS_BASE_URL, XMS_LOGIN only)
  3. Interactive prompts for anything still missing (password always prompted unless in env)

Connection type is always siempre (permanent session). On success, the session cookie is saved to ~/.cache/xms-dns/auth.cache.

HTTP calls

Login and operations are separate executions:

  • xms-dns login — authenticates against the panel and saves the session (its own HTTP calls; not counted against other commands).
  • Any other command — exactly one HTTP request to the panel, using the cached session. Credentials are never sent again.

Example: xms-dns domains is a single GET to Operacion=Dominios. xms-dns list is a single GET to load the zone.

The only exception is upsert when the value changes: XMS has no inline edit, so the client deletes and recreates the record (two or three requests).

CLI

Global flags:

  • -o / --output — output format: table (default), csv, json, or yaml
  • -v / --verbose — log HTTP requests to stderr
  • --debug — log requests and response bodies to stderr (includes verbose)
xms-dns login
xms-dns list gmbros.net
xms-dns -o csv list gmbros.net
xms-dns -o json domains
xms-dns -v list gmbros.net
xms-dns --debug upsert gmbros.net dyndns-test A 203.0.113.10

DNS commands use the cached session only. If not logged in or session expired:

error: Not logged in. Run: xms-dns login

Server (dyndns2 + checkip)

Start the dynamic DNS server:

xms-dns-server

Environment variables:

Variable Default Purpose
XMS_BASE_URL https://xms.digitalvalue.es XMS panel URL
XMS_SERVER_HOST 127.0.0.1 Bind address
XMS_SERVER_PORT 8080 Bind port
XMS_TRUST_PROXY unset Set to 1 to trust X-Forwarded-For for client IP
XMS_CACHE_DIR ~/.cache/xms-dns Session cache directory

Reverse proxy (production): if xms-dns-server runs behind nginx, Caddy, Traefik, etc., set XMS_TRUST_PROXY=1. Otherwise /checkip and updates without myip see the proxy IP (127.0.0.1) instead of the client. Only enable this when a trusted proxy overwrites X-Forwarded-For — do not expose the server directly to the internet with this flag on.

Authentication

The server does not use xms-dns login. Each dyndns2 client sends XMS credentials via HTTP Basic auth:

  • username → XMS login (e.g. admin#example.test)
  • password → XMS password

The session cookie is cached per user in ~/.cache/xms-dns/server/{sha256}.cache (separate from the CLI auth.cache). If the cached session expires, the server re-authenticates with the credentials from the current request.

Endpoints

  • GET /nic/update?hostname=home.example.test&myip=... — dyndns2 update. Returns good {value}, nochg {value}, badauth, etc. Always HTTP 200.
  • Record types: A (default), AAAA, TXT.
    • A / AAAA: pass the address in myip, or omit it to use the client IP (X-Forwarded-For when XMS_TRUST_PROXY=1).
    • AAAA: set type=AAAA, or pass an IPv6 address in myip (auto-detected).
    • TXT: set type=TXT and pass the record data in txt= (or value=).
  • GET /checkip — returns the caller's public IPv4. Optional ?format=pfsense for legacy pfSense.

If myip is omitted, the client IP is used (see X-Forwarded-For when XMS_TRUST_PROXY=1).

ddclient example

protocol=dyndns2
server=dyndns.example.test
login=admin#example.test
password=your-xms-password
home.example.test

Put TLS termination on a reverse proxy in production; bind locally by default. Remember XMS_TRUST_PROXY=1 on the server process (see above).

Library

from xms_dns import XmsClient

# Login once (CLI does this via `xms-dns login`)
with XmsClient(base_url="...", login="...", password="...") as client:
    client.authenticate()

# Later operations reuse auth.cache
with XmsClient.from_env() as client:
    client.ensure_session()
    client.upsert_record("gmbros.net", "home", "A", "203.0.113.10")

Tests

All default tests use mocked HTTP responses and do not contact the live XMS panel:

pytest

Live smoke test

xms-dns login   # or set XMS_PASSWORD for one-shot login inside the script
XMS_LIVE=1 python scripts/smoke_test.py

Security

  • Do not store passwords in the config file
  • Keep ~/.cache/xms-dns/auth.cache private (chmod 600)
  • Keep server session caches private too: ~/.cache/xms-dns/server/*.cache (chmod 600)

License

Copyright (c) 2026 Sergio Garcia.

Licensed under CC BY-NC 4.0: non-commercial use with attribution required.

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

xms_dns-0.1.0.tar.gz (30.3 kB view details)

Uploaded Source

Built Distribution

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

xms_dns-0.1.0-py3-none-any.whl (38.8 kB view details)

Uploaded Python 3

File details

Details for the file xms_dns-0.1.0.tar.gz.

File metadata

  • Download URL: xms_dns-0.1.0.tar.gz
  • Upload date:
  • Size: 30.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for xms_dns-0.1.0.tar.gz
Algorithm Hash digest
SHA256 226b77c9b424c71896e0b07885297c0918be918e199c44fa85e94512f7e1d41c
MD5 321f19e68eead5ff744c951b25c74a6c
BLAKE2b-256 32da9090716c8da3dca2eb8cee52eb351db1c7fc11ef744168222b2e5b9f0ffa

See more details on using hashes here.

File details

Details for the file xms_dns-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: xms_dns-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for xms_dns-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 983d90e0d20e15506586d952b39ef3949e9400d067aea857d000f16ff27274fa
MD5 1ea7e4b3e96ccb7231802651f59686f0
BLAKE2b-256 d5793edc72ca9daac337aecf0b498bff69b56aad3ba3dfe178c2937c1fbf443a

See more details on using hashes here.

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