Added Cloudflare Dynamic DNS Updater
This commit is contained in:
parent
2fc53e72b5
commit
77b43a3bce
126
Dynamic_DNS/Cloudflare/README.md
Normal file
126
Dynamic_DNS/Cloudflare/README.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# 🔁 Dynamic DNS Updater for Cloudflare with Mullvad IP
|
||||||
|
|
||||||
|
This script updates A records in Cloudflare with your current public IP as reported by [Mullvad](https://mullvad.net)'s IP check service. It supports:
|
||||||
|
|
||||||
|
- Multiple domains/zones via `.env` files
|
||||||
|
- Secure API access using **Cloudflare API Tokens**
|
||||||
|
- Smart updates: only changes DNS if your IP has changed
|
||||||
|
- Daily logging to `./logs/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Features
|
||||||
|
|
||||||
|
- ✅ Fetches current public IP from Mullvad API (`https://ipv4.am.i.mullvad.net/json`)
|
||||||
|
- ✅ Uses `.env` files to manage multiple Cloudflare DNS records
|
||||||
|
- ✅ Supports **API Tokens** (safer than global keys)
|
||||||
|
- ✅ Skips unnecessary updates if IP hasn't changed
|
||||||
|
- ✅ Logs every run to `logs/update_YYYY-MM-DD.log`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Project Structure
|
||||||
|
|
||||||
|
.
|
||||||
|
├── update_cloudflare_ip.sh # Main script
|
||||||
|
├── zones/ # Folder for per-domain config files
|
||||||
|
│ ├── example_com.env
|
||||||
|
│ └── another_domain.env
|
||||||
|
└── logs/ # Auto-created daily log files
|
||||||
|
└── update_2025-10-05.log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Configuration
|
||||||
|
|
||||||
|
1. Create a `zones/` folder (already included in repo).
|
||||||
|
2. Add one `.env` file per domain/zone, named descriptively. Example:
|
||||||
|
|
||||||
|
### `zones/subdomain.domain.com.env`
|
||||||
|
|
||||||
|
```
|
||||||
|
ZONE_ID="your_cloudflare_zone_id"
|
||||||
|
DNS_RECORD_ID="your_dns_record_id"
|
||||||
|
CLOUDFLARE_API_TOKEN="your_cloudflare_api_token"
|
||||||
|
DNS_NAME="subdomain.domain.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ Use Cloudflare API Tokens with permission:
|
||||||
|
Zone → DNS → Edit for the required zone.
|
||||||
|
|
||||||
|
🧪 Usage
|
||||||
|
|
||||||
|
Make the script executable:
|
||||||
|
```
|
||||||
|
chmod +x update_cloudflare_ip.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Run it manually:
|
||||||
|
```
|
||||||
|
./update_cloudflare_ip.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Check logs:
|
||||||
|
```
|
||||||
|
cat logs/update_$(date +%F).log
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🕒 Automation (Cron Example)
|
||||||
|
|
||||||
|
To run the script every 10 minutes, edit your crontab:
|
||||||
|
```
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Add this line:
|
||||||
|
```
|
||||||
|
*/10 * * * * /path/to/update_cloudflare_ip.sh >> /dev/null 2>&1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, if you want to keep logs automatically:
|
||||||
|
```
|
||||||
|
*/10 * * * * /path/to/update_cloudflare_ip.sh >> /path/to/logs/cron.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## ✅ Requirements
|
||||||
|
|
||||||
|
* bash (scripted for Linux/macOS)
|
||||||
|
* curl
|
||||||
|
* jq (lightweight and flexible command-line JSON processor): https://github.com/jqlang/jq
|
||||||
|
|
||||||
|
Install jq if missing:
|
||||||
|
```
|
||||||
|
# Debian/Ubuntu
|
||||||
|
sudo apt install jq
|
||||||
|
|
||||||
|
# macOS (Homebrew)
|
||||||
|
brew install jq
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 Security Tip
|
||||||
|
|
||||||
|
Never share your .env files or commit them to public repositories. They contain sensitive credentials.
|
||||||
|
|
||||||
|
Use .gitignore to ignore your secrets:
|
||||||
|
|
||||||
|
.gitignore
|
||||||
|
```
|
||||||
|
zones/*.env
|
||||||
|
logs/
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 🙋 FAQ
|
||||||
|
|
||||||
|
Q: What happens if the IP hasn't changed?
|
||||||
|
A: The script detects it and skips the update.
|
||||||
|
|
||||||
|
Q: What if one domain fails?
|
||||||
|
A: The script continues to process the remaining .env files.
|
||||||
|
|
||||||
|
Q: Can I use IPv6?
|
||||||
|
A: Not currently. This script uses Mullvad's IPv4 API. IPv6 support can be added if needed.
|
||||||
0
Dynamic_DNS/Cloudflare/logs/Here_Be_Logs
Normal file
0
Dynamic_DNS/Cloudflare/logs/Here_Be_Logs
Normal file
93
Dynamic_DNS/Cloudflare/update_cloudflare_ip.sh
Normal file
93
Dynamic_DNS/Cloudflare/update_cloudflare_ip.sh
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Exit on error
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# --- Configuration ---
|
||||||
|
ENV_DIR="./zones"
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
DATE=$(date +%F)
|
||||||
|
LOG_FILE="$LOG_DIR/update_${DATE}.log"
|
||||||
|
|
||||||
|
# --- Ensure log directory exists ---
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# --- Logging function ---
|
||||||
|
log() {
|
||||||
|
local message="$1"
|
||||||
|
echo "$message" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Step 1: Get current IP from Mullvad ---
|
||||||
|
log "[*] Fetching IP from Mullvad..."
|
||||||
|
IP_INFO=$(curl -s https://ipv4.am.i.mullvad.net/json)
|
||||||
|
CURRENT_IP=$(echo "$IP_INFO" | jq -r '.ip')
|
||||||
|
|
||||||
|
if [[ -z "$CURRENT_IP" ]]; then
|
||||||
|
log "[!] Failed to extract IP address."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "[*] Current public IP is: $CURRENT_IP"
|
||||||
|
log ""
|
||||||
|
|
||||||
|
# --- Step 2: Loop through all .env files ---
|
||||||
|
for ENV_FILE in "$ENV_DIR"/*.env; do
|
||||||
|
log "[*] Processing config: $ENV_FILE"
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
set -a
|
||||||
|
source "$ENV_FILE"
|
||||||
|
set +a
|
||||||
|
|
||||||
|
# Check for required variables
|
||||||
|
if [[ -z "$ZONE_ID" || -z "$DNS_RECORD_ID" || -z "$CLOUDFLARE_API_TOKEN" || -z "$DNS_NAME" ]]; then
|
||||||
|
log "[!] Missing required variables in $ENV_FILE"
|
||||||
|
log ""
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Step 3: Get existing DNS record from Cloudflare ---
|
||||||
|
log "[*] Fetching current DNS record for $DNS_NAME..."
|
||||||
|
|
||||||
|
DNS_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
|
||||||
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||||
|
-H "Content-Type: application/json")
|
||||||
|
|
||||||
|
EXISTING_IP=$(echo "$DNS_RECORD" | jq -r '.result.content')
|
||||||
|
|
||||||
|
if [[ "$EXISTING_IP" == "$CURRENT_IP" ]]; then
|
||||||
|
log "[=] No update needed. $DNS_NAME already points to $CURRENT_IP"
|
||||||
|
log ""
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Step 4: Update DNS record ---
|
||||||
|
log "[*] IP has changed: $EXISTING_IP → $CURRENT_IP"
|
||||||
|
log "[*] Updating Cloudflare DNS record..."
|
||||||
|
|
||||||
|
UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
|
||||||
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"type\": \"A\",
|
||||||
|
\"name\": \"$DNS_NAME\",
|
||||||
|
\"content\": \"$CURRENT_IP\",
|
||||||
|
\"ttl\": 3600,
|
||||||
|
\"proxied\": true,
|
||||||
|
\"comment\": \"Auto-updated via script\"
|
||||||
|
}")
|
||||||
|
|
||||||
|
SUCCESS=$(echo "$UPDATE_RESPONSE" | jq -r '.success')
|
||||||
|
|
||||||
|
if [[ "$SUCCESS" == "true" ]]; then
|
||||||
|
log "[+] Successfully updated $DNS_NAME to $CURRENT_IP"
|
||||||
|
else
|
||||||
|
log "[!] Failed to update $DNS_NAME"
|
||||||
|
log "Cloudflare response:"
|
||||||
|
echo "$UPDATE_RESPONSE" | tee -a "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log ""
|
||||||
|
done
|
||||||
|
|
||||||
5
Dynamic_DNS/Cloudflare/zones/subdomain.domain.com.env
Normal file
5
Dynamic_DNS/Cloudflare/zones/subdomain.domain.com.env
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ZONE_ID="your_zone_id"
|
||||||
|
DNS_RECORD_ID="your_dns_record_id"
|
||||||
|
CLOUDFLARE_API_TOKEN="your_cloudflare_api_token"
|
||||||
|
DNS_NAME="subdomain.example.com"
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user