139 lines
3.7 KiB
Markdown
139 lines
3.7 KiB
Markdown
[🇵🇱 Polish version](README.pl.md)
|
|
|
|
# IONOS DDNS Auto-Updater & Creator
|
|
|
|
A Python-based system service that automatically updates DNS records on IONOS. Unlike standard DDNS scripts, this solution uses the **IONOS REST API**, allowing it to:
|
|
1. **Update** existing DNS records.
|
|
2. **Create** new DNS records automatically if they don't exist.
|
|
3. Check the current DNS value before updating to avoid API rate limits.
|
|
|
|
## Features
|
|
- **Smart Check:** Compares public IP with current DNS resolution before sending API requests.
|
|
- **Auto-Discovery:** Automatically detects which DNS Zone a subdomain belongs to.
|
|
- **System Service:** Runs as a background `systemd` service with crash protection.
|
|
- **Logging:** Detailed logs in `/var/log/ionos-ddns.log`.
|
|
|
|
## Prerequisites
|
|
- Python 3
|
|
- An IONOS account with access to the "Developer API".
|
|
- An API Key (Prefix + Secret) generated at [developer.hosting.ionos.com](https://developer.hosting.ionos.com/).
|
|
|
|
## Installation
|
|
|
|
### 1. Clone the repository to `/opt`
|
|
It is recommended to install this in a system directory.
|
|
|
|
```bash
|
|
sudo mkdir -p /opt/ionos-ddns
|
|
cd /opt
|
|
sudo git clone https://git.invelio.co.uk/rafal/ionos-ddns.git
|
|
cd /opt/ionos-ddns
|
|
|
|
```
|
|
|
|
### 2. Install dependencies
|
|
```
|
|
sudo apt update
|
|
sudo apt install python3-pip
|
|
sudo pip3 install -r requirements.txt
|
|
```
|
|
|
|
### 3. Configuration
|
|
```
|
|
sudo nano config.json
|
|
```
|
|
Fill in your api_prefix and api_secret.
|
|
|
|
Domains List: Edit domains.txt and add domains one per line:
|
|
```
|
|
sudo nano domains.txt
|
|
```
|
|
Example:
|
|
```
|
|
mydomain.com
|
|
vpn.mydomain.com
|
|
server.other-domain.net
|
|
```
|
|
IMPORTANT: Secure your API keys! Since config.json contains sensitive credentials, restrict access to it so only the root user can read it:
|
|
```
|
|
sudo chown root:root /opt/ionos-ddns/config.json
|
|
sudo chmod 600 /opt/ionos-ddns/config.json
|
|
```
|
|
|
|
Make script executable:
|
|
```
|
|
sudo chmod +x /opt/ionos-ddns/update_ddns.py
|
|
```
|
|
|
|
### 4. Install System Service
|
|
Copy the service file to systemd directory:
|
|
```
|
|
sudo cp ionos-ddns.service /etc/systemd/system/
|
|
```
|
|
Reload daemon, enable and start the service:
|
|
```
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable ionos-ddns.service
|
|
sudo systemctl start ionos-ddns.service
|
|
```
|
|
|
|
### Monitoring
|
|
Check the service status:
|
|
```
|
|
sudo systemctl status ionos-ddns.service
|
|
```
|
|
View logs:
|
|
```
|
|
tail -f /var/log/ionos-ddns.log
|
|
```
|
|
|
|
### How it works
|
|
The script runs in an infinite loop (every 10 minutes).
|
|
|
|
Fetches your current Public IP.
|
|
|
|
Reads domains.txt.
|
|
|
|
For each domain:
|
|
|
|
Finds the correct Zone ID via API.
|
|
|
|
Checks if an A-Record exists.
|
|
|
|
If exists: Checks if IP matches. If not, performs PUT (Update).
|
|
|
|
If missing: Performs POST (Create).
|
|
|
|
### ERROR
|
|
This error (400 Invalid API key format) means that the IONOS server rejected the key because its structure is incorrect.
|
|
The most common causes are:
|
|
Extra spaces (accidentally copied when pasting).
|
|
Manually adding a dot in the config file (the script adds the dot automatically).
|
|
Using the wrong type of key (Cloud API key instead of Hosting/DNS API key).
|
|
Here is how to fix it step by step.
|
|
```
|
|
sudo nano /opt/ionos-ddns/config.json
|
|
```
|
|
Make sure the quotation marks are placed directly against the characters, with no spaces.
|
|
WRONG (note the spaces):
|
|
```
|
|
"api_prefix": " 23498723498 ",
|
|
"api_secret": " a1b2c3d4 "
|
|
```
|
|
CORRECT:
|
|
```
|
|
"api_prefix": "23498723498",
|
|
"api_secret": "a1b2c3d4"
|
|
```
|
|
Do not add a dot in config.json
|
|
The Python script contains this line:
|
|
```
|
|
"X-API-Key": f"{prefix}.{secret}"
|
|
```
|
|
It automatically joins these two values with a dot.
|
|
If you entered in config.json something like:
|
|
prefix: "myPrefix."
|
|
then the script sends:
|
|
"myPrefix..secret" (two dots), which causes the error.
|
|
api_prefix: Only the first part of the key.
|
|
api_secret: Only the second, long part of the key. |