A lightweight Rust utility that automatically updates your Cloudflare DNS records with your current IPv6 address. Born from the need to maintain a self-hosted Postfix mail server on a dynamic IPv6 connection.
My ISP provides a /64 IPv6 address block, which is perfect for hosting services like a Postfix mail server. I configured the server to receive mail directly on port 25 to my laptop. However, every time I reconnected to my hotspot, the IPv6 address would change, breaking my MX record and making my mail server unreachable.
This Rust tool automatically detects IPv6 address changes and updates the corresponding Cloudflare DNS AAAA record, ensuring my mail server (mx1.fustin.top β nnt@jol.fustin.top) remains accessible despite dynamic IP changes.
- π Fast and efficient IPv6 address detection via ip.se
- βοΈ Automatic Cloudflare DNS AAAA record updates
- π Secure API token management via environment variables
- β‘ Asynchronous operations with Tokio
- π§ Perfect for self-hosted mail servers on dynamic IPs
- π Designed for automation on network connection
- Rust 1.70 or higher
- A Cloudflare account with API access
- A domain managed by Cloudflare
Create a .env file in the project root with the following variables:
CFTOKEN=your_cloudflare_api_token
ZONE_ID=your_cloudflare_zone_id
DNS_RECORD_ID=your_dns_record_id
DOMAIN=your.domain.com-
API Token (
CFTOKEN):- Log into Cloudflare Dashboard
- Go to "My Profile" β "API Tokens"
- Create token with "Edit DNS" permissions
-
Zone ID (
ZONE_ID):- Select your domain in Cloudflare Dashboard
- Scroll down to "API" section on the right sidebar
- Copy the Zone ID
-
DNS Record ID (
DNS_RECORD_ID):- Use Cloudflare API or CLI to list DNS records
- Find the ID of the record you want to update
Make sure the .env file is also int the same working directory
docker run --rm --env-file $(pwd)/.env --network=host ghcr.io/lsnnt/ipv6updater:latest- Clone this repository:
git clone https://github.com/lsnnt/ipv6updater.git
cd ipv6updater- Build the project:
cargo build --releasecargo run --releaseThis is the recommended approach for macOS users who want to trigger updates when connecting to a specific WiFi network.
- Build the release binary:
cargo build --release- Create a shell script (
run_updater.sh):
#!/bin/bash
cd /path/to/ipv6updater
set -a # Automatically export variables
source .env
set +a
./target/release/ipv6updater- Make it executable:
chmod +x run_updater.sh- Create a Shortcuts automation:
- Open Shortcuts app on macOS
- Create a new automation triggered by "WiFi" connection
- Filter by your specific SSID (e.g., your hotspot name)
- Add "Run Shell Script" action pointing to your script
Now the DNS record updates automatically whenever you connect to your designated WiFi network!
Add to crontab to run every 5 minutes:
*/5 * * * * cd /path/to/ipv6updater && set -a && source .env && set +a && ./target/release/ipv6updater >> /var/log/ddns.log 2>&1[dependencies]
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.11", features = ["json"] }
serde_json = "1.0"
dotenv = "0.15"Problem: Running a Postfix mail server on a dynamic IPv6 connection where the address changes on every reconnection.
Solution: This tool ensures the MX record always points to the current IPv6 address.
Example Configuration:
- Domain:
jol.fustin.top - Mail server hostname:
mx1.fustin.top - Email address:
nnt@jol.fustin.top - MX record points to:
mx1.fustin.top - AAAA record for
mx1.fustin.topβ Auto-updated with current IPv6
Flow:
- Laptop connects to hotspot β New IPv6 address assigned
- Shortcuts automation triggers on WiFi connection
- Script runs β Detects new IPv6 from
curl ip.se - Updates
mx1.fustin.topAAAA record via Cloudflare API - Mail server remains reachable at consistent hostname
- Retrieves your current IPv6 address from ip.se
- Connects to Cloudflare API using your credentials
- Updates the specified DNS AAAA record with your current IP
- Adds a comment with the timestamp and IP for tracking
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "...",
"name": "your.domain.com",
"type": "AAAA",
"content": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"proxied": false,
"ttl": 1
}
}- Never commit your
.envfile to version control - Keep your API token secure and rotate it periodically
- Use API tokens with minimal required permissions
- Consider using systemd with
ProtectSystem=stricton Linux
"Failed to get IP address"
- Check your internet connection
- Verify ip.se is accessible from your network
- Test manually:
curl ip.se
"Cloudflare API error"
- Verify your API token has DNS edit permissions
- Confirm Zone ID and DNS Record ID are correct
- Check that the domain matches the DNS record
- Test API token: Visit https://dash.cloudflare.com/profile/api-tokens
macOS Shortcuts automation not running
- Check Shortcuts app permissions in System Preferences β Privacy & Security
- Verify the shell script has execute permissions (
chmod +x) - Test the script manually first
- Check Console.app for error messages
Mail server still unreachable after update
- DNS propagation can take a few minutes
- Check DNS update with:
dig AAAA mx1.yourdomain.com - Verify Postfix is listening on the correct IPv6 address
- Check firewall rules for port 25
- Better error handling and retry logic
- Configurable IP detection sources
- Multiple DNS record updates
- Logging to file
- Change detection (only update if IP changed)
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- IP detection powered by v6 ident
- DNS updates via Cloudflare API
- Cloudflare DNS Records API: https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-create-dns-record
- Cloudflare API Tokens - Create your API token
- Create API Token Guide - Official documentation
- Cloudflare DNS API Reference - Update DNS records
Created by @lsnnt
Repository: https://github.com/lsnnt/ipv6updater
Note: This tool is designed for IPv6 addresses. If you need IPv4 support, modify the DNS record type from "AAAA" to "A" in the code.