Initial role commit
This commit is contained in:
257
README.md
257
README.md
@@ -1,3 +1,256 @@
|
||||
# ansible-role-ddclient-cloudflare
|
||||
# Ansible Role: ddclient
|
||||
|
||||
Simple Ansible for setting up Dynamic DNS with ddclient and cloudflare
|
||||
Configures and manages ddclient for dynamic DNS updates.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: ddclient
|
||||
vars:
|
||||
ddclient_daemon_interval: 300 # Checks IP every 5 minutes (default, can be omitted)
|
||||
ddclient_ipv4_detection: # Use ipify service to get your public IPv4 address
|
||||
method: webv4
|
||||
source: ipify-ipv4
|
||||
ddclient_ipv6_detection: {} # Disable ipv6 detection
|
||||
ddclient_protocols: # Use cloudflare to update your DNS records
|
||||
- protocol: cloudflare
|
||||
zone: example.com
|
||||
password: "{{ vault_cloudflare_token }}"
|
||||
ttl: 600
|
||||
domains:
|
||||
- home.example.com
|
||||
- vpn.example.com
|
||||
```
|
||||
|
||||
## Role Variables
|
||||
|
||||
> [!NOTE]
|
||||
> Read the [ddclient general documentation](https://ddclient.net/general.html) to familiarize yourself with the global configuration options.
|
||||
|
||||
### IPv4 Detection Configuration
|
||||
|
||||
The `ddclient_ipv4_detection` dictionary contains:
|
||||
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `method` | `webv4` | Detection method: `ipv4`, `ifv4`, `webv4`, `fwv4`, `cmdv4` |
|
||||
| `source` | `dyndns` | Source URL/interface/command (provider name or full URL) |
|
||||
| `skip_pattern` | | Pattern to skip in output |
|
||||
|
||||
### IPv6 Detection Configuration
|
||||
|
||||
The `ddclient_ipv6_detection` dictionary contains the same keys as IPv4, with `method` supporting: `ipv6`, `ifv6`, `webv6`, `fwv6`, `cmdv6`
|
||||
|
||||
To disable either IPv6 or IPv4 detection, set to empty dict:
|
||||
```yaml
|
||||
ddclient_ipv6_detection: {}
|
||||
```
|
||||
|
||||
### Firewall Authentication
|
||||
Only applicable if using the IP detection method `fw`.
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `ddclient_fw_login` | | Firewall login username |
|
||||
| `ddclient_fw_password` | | Firewall password |
|
||||
|
||||
### Protocol Configuration
|
||||
|
||||
**Common keys:**
|
||||
|
||||
| Key | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `protocol` | Yes | Protocol type (e.g., `cloudflare`, `dyndns2`, `namecheap`) |
|
||||
| `domains` | Yes | List of hostnames to update |
|
||||
| `login` | Yes* | Username/email/domain |
|
||||
| `password` | Yes* | Password/API key/token |
|
||||
| `zone` | No | Zone/domain name (Cloudflare, nsupdate) |
|
||||
| `ttl` | No | DNS TTL in seconds |
|
||||
| `server` | No | update DNS information on this server |
|
||||
| `mx` | No | Mail exchanger hostname |
|
||||
| `backupmx` | No | Backup MX flag (yes/no) |
|
||||
| `wildcard` | No | Wildcard DNS flag (yes/no) |
|
||||
| `custom` | No | Custom domain flag (yes/no) |
|
||||
| `tcp` | No | Use TCP instead of UDP (yes/no) |
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> *Required fields depend on the protocol
|
||||
> Read the [ddclient protocol documentation](https://ddclient.net/protocols.html) to know which options must be specified for a given protocol.
|
||||
|
||||
|
||||
### Daemon Settings
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `ddclient_daemon_interval` | `300` | Check interval in seconds (0 = run once) |
|
||||
| `ddclient_foreground` | `false` | Run in foreground (don't fork) |
|
||||
| `ddclient_pid` | `""` | PID file path (empty = use default) |
|
||||
| `ddclient_cache` | `""` | Cache file path (empty = use default) |
|
||||
|
||||
### Network Settings
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `ddclient_ssl` | `true` | Use SSL/HTTPS for updates |
|
||||
| `ddclient_proxy` | | HTTP proxy hostname (empty = no proxy) |
|
||||
| `ddclient_timeout` | `0` | Connection timeout in seconds (0 = no timeout) |
|
||||
|
||||
### Logging Settings
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `ddclient_syslog` | `true` | Log to syslog |
|
||||
| `ddclient_facility` | `daemon` | Syslog facility |
|
||||
| `ddclient_priority` | `notice` | Syslog priority |
|
||||
| `ddclient_mail` | | Email address for notifications |
|
||||
| `ddclient_mail_failure` | | Email address for failure notifications |
|
||||
| `ddclient_verbose` | `false` | Verbose output |
|
||||
| `ddclient_quiet` | `false` | Suppress unnecessary update messages |
|
||||
| `ddclient_debug` | `false` | Debug output |
|
||||
|
||||
### Update Behavior
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `ddclient_exec` | `true` | Execute updates (false = dry-run) |
|
||||
| `ddclient_retry` | `false` | Retry failed updates |
|
||||
| `ddclient_force` | `false` | Force updates even if unnecessary |
|
||||
| `ddclient_postscript` | | Script to run after update |
|
||||
|
||||
## More Example Playbooks
|
||||
|
||||
### Multiple Providers
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: ddclient
|
||||
vars:
|
||||
ddclient_protocols:
|
||||
- protocol: cloudflare
|
||||
zone: company.com
|
||||
login: token
|
||||
password: "{{ vault_cloudflare_password }}"
|
||||
domains:
|
||||
- www.company.com
|
||||
- api.company.com
|
||||
- protocol: dyndns2
|
||||
server: domains.google.com
|
||||
login: service-login
|
||||
password: "{{ vault_service_password }}"
|
||||
domains:
|
||||
- backup.ddns.net
|
||||
```
|
||||
|
||||
### Interface-based Detection (Server with Public IP)
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: ddclient
|
||||
vars:
|
||||
ddclient_ipv4_detection:
|
||||
method: ifv4
|
||||
source: eth0
|
||||
ddclient_protocols:
|
||||
- protocol: cloudflare
|
||||
zone: example.com
|
||||
login: token
|
||||
password: "{{ vault_cloudflare_token }}"
|
||||
domains:
|
||||
- server.example.com
|
||||
```
|
||||
|
||||
### Dual-Stack (IPv4 + IPv6)
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: ddclient
|
||||
vars:
|
||||
ddclient_ipv4_detection:
|
||||
method: webv4
|
||||
source: checkip.amazonaws.com
|
||||
ddclient_ipv6_detection:
|
||||
method: webv6
|
||||
source: checkipv6.dyndns.org
|
||||
ddclient_protocols:
|
||||
- protocol: cloudflare
|
||||
zone: example.com
|
||||
login: admin@example.com
|
||||
password: "{{ vault_cloudflare_token }}"
|
||||
ttl: 600
|
||||
domains:
|
||||
- dualstack.example.com
|
||||
```
|
||||
|
||||
### Dry-Run Mode (Testing)
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: ddclient
|
||||
vars:
|
||||
ddclient_exec: false # Don't actually update DNS
|
||||
ddclient_verbose: true
|
||||
ddclient_protocols:
|
||||
- protocol: cloudflare
|
||||
zone: example.com
|
||||
login: token
|
||||
password: test-token
|
||||
domains:
|
||||
- test.example.com
|
||||
```
|
||||
|
||||
## IP Detection Methods
|
||||
|
||||
### Web-based (webv4/webv6)
|
||||
Queries a web service to detect public IP. Best for systems behind NAT.
|
||||
|
||||
```yaml
|
||||
ddclient_ipv4_detection:
|
||||
method: webv4
|
||||
source: checkip.amazonaws.com # or dyndns, googledomains, etc.
|
||||
```
|
||||
|
||||
### Interface-based (ifv4/ifv6)
|
||||
Reads IP directly from a network interface. Best for servers with public IPs.
|
||||
|
||||
```yaml
|
||||
ddclient_ipv4_detection:
|
||||
method: ifv4
|
||||
source: eth0
|
||||
```
|
||||
|
||||
### Firewall/Router-based (fwv4/fwv6)
|
||||
Queries router's status page for WAN IP.
|
||||
|
||||
```yaml
|
||||
ddclient_ipv4_detection:
|
||||
method: fwv4
|
||||
source: 192.168.1.1/Status.htm
|
||||
skip_pattern: "WAN IP Address"
|
||||
ddclient_fw_login: admin
|
||||
ddclient_fw_password: routerpass
|
||||
```
|
||||
|
||||
### Command-based (cmdv4/cmdv6)
|
||||
Executes a custom script/command to get IP.
|
||||
|
||||
```yaml
|
||||
ddclient_ipv4_detection:
|
||||
method: cmdv4
|
||||
source: /usr/local/bin/get-public-ip.sh
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
50
defaults/main.yaml
Executable file
50
defaults/main.yaml
Executable file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
# Daemon settings
|
||||
ddclient_daemon_interval: 300 # Check interval in seconds (0 = run once)
|
||||
ddclient_foreground: false # Run in foreground (don't fork)
|
||||
ddclient_pid: "" # PID file path
|
||||
ddclient_cache: "" # Cache file path
|
||||
|
||||
# Network settings
|
||||
ddclient_ssl: true # Use SSL/HTTPS
|
||||
ddclient_proxy: "" # HTTP proxy (empty = no proxy)
|
||||
ddclient_timeout: 0 # Connection timeout (0 = no timeout)
|
||||
|
||||
# Logging settings
|
||||
ddclient_syslog: true # Log to syslog
|
||||
ddclient_facility: daemon # Syslog facility
|
||||
ddclient_priority: notice # Syslog priority
|
||||
ddclient_mail: "" # Email address for notifications
|
||||
ddclient_mail_failure: "" # Email address for failure notifications
|
||||
ddclient_verbose: false # Verbose output
|
||||
ddclient_quiet: false # Suppress unnecessary update messages
|
||||
ddclient_debug: false # Debug output
|
||||
|
||||
# Update behavior
|
||||
ddclient_exec: true # Actually execute updates (false = dry-run)
|
||||
ddclient_retry: false # Retry failed updates
|
||||
ddclient_force: false # Force updates even if unnecessary
|
||||
ddclient_postscript: "" # Script to run after update
|
||||
|
||||
# IP Detection configuration
|
||||
ddclient_ipv4_detection:
|
||||
static_ip: "" # Set static IP address (skips detection)
|
||||
method: webv4 # Method: ip, if, web, fw, cmd
|
||||
source: dyndns # Source for web/fw methods
|
||||
address: "" # IP address for method=ip
|
||||
interface: "" # Network interface (for method=if)
|
||||
command: "" # Command to run (for method=cmd)
|
||||
skip: "" # Pattern to skip in output
|
||||
|
||||
ddclient_ipv6_detection:
|
||||
static_ip: "" # Set static IP address (skips detection)
|
||||
method: webv6 # Method: ip, if, web, fw, cmd
|
||||
source: dyndns # Source for web/fw methods
|
||||
address: "" # IP address for method=ip
|
||||
interface: "" # Network interface (for method=if)
|
||||
command: "" # Command to run (for method=cmd)
|
||||
skip: "" # Pattern to skip in output
|
||||
|
||||
fw_login: "" # Firewall login (for method=fw)
|
||||
fw_password: "" # Firewall password (for method=fw)
|
||||
|
||||
5
handlers/main.yaml
Executable file
5
handlers/main.yaml
Executable file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Restart ddclient service
|
||||
ansible.builtin.service:
|
||||
name: ddclient
|
||||
state: restarted
|
||||
16
meta/main.yaml
Normal file
16
meta/main.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: ddclient
|
||||
author: Patrick Jaroszewski
|
||||
description: Ansible role to install and configure ddclient
|
||||
license: MIT License
|
||||
min_ansible_version: 2.11
|
||||
platforms:
|
||||
- name: Debian
|
||||
versions: all
|
||||
- name: Ubuntu
|
||||
version: all
|
||||
galaxy_tags:
|
||||
- ddns
|
||||
- dynamicdns
|
||||
- ddclient
|
||||
21
tasks/main.yaml
Executable file
21
tasks/main.yaml
Executable file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Install ddclient
|
||||
ansible.builtin.package:
|
||||
name: ddclient
|
||||
state: latest
|
||||
|
||||
- name: Copy over main ddclient configuration file
|
||||
ansible.builtin.template:
|
||||
src: "../templates/ddclient.conf.j2"
|
||||
dest: /etc/ddclient.conf
|
||||
owner: root
|
||||
mode: "0600"
|
||||
notify: Restart ddclient service
|
||||
|
||||
- name: Copy over ddclient service configuration
|
||||
ansible.builtin.template:
|
||||
src: "../templates/ddclient.j2"
|
||||
dest: /etc/default/ddclient
|
||||
owner: root
|
||||
mode: "0600"
|
||||
notify: Restart ddclient service
|
||||
101
templates/ddclient.conf.j2
Executable file
101
templates/ddclient.conf.j2
Executable file
@@ -0,0 +1,101 @@
|
||||
# {{ ansible_managed }}
|
||||
# /etc/ddclient.conf
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Daemon Settings
|
||||
# ============================================================
|
||||
daemon={{ ddclient_daemon_interval }}
|
||||
foreground={{ ddclient_foreground | ternary('yes', 'no') }}
|
||||
{% if ddclient_pid %}
|
||||
pid={{ ddclient_pid }}
|
||||
{% endif %}
|
||||
{% if ddclient_cache %}
|
||||
cache={{ ddclient_cache }}
|
||||
{% endif %}
|
||||
|
||||
# ============================================================
|
||||
# Network Settings
|
||||
# ============================================================
|
||||
ssl={{ ddclient_ssl | ternary('yes', 'no') }}
|
||||
{% if ddclient_proxy %}
|
||||
proxy={{ ddclient_proxy }}
|
||||
{% endif %}
|
||||
{% if ddclient_timeout %}
|
||||
timeout={{ ddclient_timeout }}
|
||||
{% endif %}
|
||||
|
||||
# ============================================================
|
||||
# Logging Settings
|
||||
# ============================================================
|
||||
syslog={{ ddclient_syslog | ternary('yes', 'no') }}
|
||||
{% if ddclient_facility %}
|
||||
facility={{ ddclient_facility }}
|
||||
{% endif %}
|
||||
{% if ddclient_priority %}
|
||||
priority={{ ddclient_priority }}
|
||||
{% endif %}
|
||||
{% if ddclient_mail %}
|
||||
mail={{ ddclient_mail }}
|
||||
{% endif %}
|
||||
{% if ddclient_mail_failure %}
|
||||
mail-failure={{ ddclient_mail_failure }}
|
||||
{% endif %}
|
||||
verbose={{ ddclient_verbose | ternary('yes', 'no') }}
|
||||
quiet={{ ddclient_quiet | ternary('yes', 'no') }}
|
||||
debug={{ ddclient_debug | ternary('yes', 'no') }}
|
||||
|
||||
# ============================================================
|
||||
# Update Behavior
|
||||
# ============================================================
|
||||
retry={{ ddclient_retry | ternary('yes', 'no') }}
|
||||
force={{ ddclient_force | ternary('yes', 'no') }}
|
||||
{% if ddclient_postscript %}
|
||||
postscript={{ ddclient_postscript }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
# ============================================================
|
||||
# IP Detection Method
|
||||
# ============================================================
|
||||
|
||||
# Disable the legacy use setting
|
||||
use=no
|
||||
|
||||
{% if ddclient_ipv4_detection is defined and ddclient_ipv4_detection %}
|
||||
usev4={{ ddclient_ipv4_detection.method }}
|
||||
{{ ddclient_ipv4_detection.method }}={{ ddclient_ipv4_detection.source }}
|
||||
{% if ddclient_ipv4_detection.skip_pattern is defined %}
|
||||
{{ ddclient_ipv4_detection.method }}-skip='{{ ddclient_ipv4_detection.skip_pattern }}'
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if ddclient_ipv6_detection is defined and ddclient_ipv6_detection %}
|
||||
usev6={{ ddclient_ipv6_detection.method }}
|
||||
{{ ddclient_ipv6_detection.method }}={{ ddclient_ipv6_detection.source }}
|
||||
{% if ddclient_ipv6_detection.skip_pattern is defined %}
|
||||
{{ ddclient_ipv6_detection.method }}-skip='{{ ddclient_ipv6_detection.skip_pattern }}'
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if ddclient_fw_login is defined %}
|
||||
fw-login={{ ddclient_fw_login }}
|
||||
{% if ddclient_fw_password is defined %}
|
||||
fw-password={{ ddclient_fw_password }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Protocol Configurations
|
||||
# ============================================================
|
||||
{% for proto in ddclient_protocols %}
|
||||
|
||||
{% for key, value in proto.items() %}
|
||||
{% if key != 'domains' %}
|
||||
{{ key }}={{ value }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ proto.domains | join(',') }}
|
||||
|
||||
{% endfor %}
|
||||
16
templates/ddclient.j2
Executable file
16
templates/ddclient.j2
Executable file
@@ -0,0 +1,16 @@
|
||||
# Configuration for ddclient scripts
|
||||
# {{ ansible_managed }}
|
||||
#
|
||||
# /etc/default/ddclient
|
||||
|
||||
# Set to "true" if ddclient should be run every time DHCP client ('dhclient'
|
||||
# from package isc-dhcp-client) updates the systems IP address.
|
||||
run_dhclient="false"
|
||||
|
||||
# Set to "true" if ddclient should be run every time a new ppp connection is
|
||||
# established. This might be useful, if you are using dial-on-demand.
|
||||
run_ipup="false"
|
||||
|
||||
# Set the time interval between the updates of the dynamic DNS name in seconds.
|
||||
# This option only takes effect if the ddclient runs in daemon mode.
|
||||
daemon_interval={{ ddclient_daemon_interval }}
|
||||
Reference in New Issue
Block a user