First Commit
This commit is contained in:
parent
51ca26f5ce
commit
7d1ba02c42
8 changed files with 1106 additions and 61 deletions
213
README.md
213
README.md
|
|
@ -41,9 +41,8 @@ SECRET_KEY=sk1_your_secret_key_here
|
|||
# Required: The domain to update
|
||||
DOMAIN=example.com
|
||||
|
||||
# Required for multi-machine setup: Unique identifier for this machine
|
||||
# Each machine should have a different MACHINE_ID
|
||||
MACHINE_ID=server1
|
||||
# Required: Name of the machine for tracking
|
||||
MACHINE_ID="exmample_machine"
|
||||
```
|
||||
|
||||
### Getting Porkbun API Credentials
|
||||
|
|
@ -149,24 +148,6 @@ This means:
|
|||
- If you ever want to manually take control of a record that was created by this script,
|
||||
you can remove or change the `ddns:<MACHINE_ID>` note and the script will stop managing it.
|
||||
|
||||
### Automated Updates with Cron
|
||||
|
||||
To automatically update DNS every 5 minutes:
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
Add this line (adjust path as needed):
|
||||
```cron
|
||||
*/5 * * * * /home/user/porkbun/updateDNS.sh >> /var/log/porkbun-ddns.log 2>&1
|
||||
```
|
||||
|
||||
Or every hour:
|
||||
```cron
|
||||
0 * * * * /home/user/porkbun/updateDNS.sh >> /var/log/porkbun-ddns.log 2>&1
|
||||
```
|
||||
|
||||
## Dry-run mode
|
||||
|
||||
You can run the script in **dry-run** mode to see what it would do without actually
|
||||
|
|
@ -188,6 +169,135 @@ In dry-run mode:
|
|||
This is useful when first configuring the script or making changes to your DNS setup,
|
||||
so you can verify behavior before applying it.
|
||||
|
||||
## Systemd integration helpers
|
||||
|
||||
This repository also includes helper scripts to install the updater as a systemd service,
|
||||
uninstall it cleanly, and view logs more easily.
|
||||
|
||||
### `install.sh` – install systemd timer + service
|
||||
|
||||
`install.sh` sets up a `porkbun-ddns` systemd service and timer that will run
|
||||
`updateDNS.sh` for you on a schedule (default: every 5 minutes).
|
||||
|
||||
What it does:
|
||||
|
||||
- Verifies required files exist in the current directory:
|
||||
- `updateDNS.sh`
|
||||
- `.env`
|
||||
- `porkbun-ddns.service`
|
||||
- `porkbun-ddns.timer`
|
||||
- Ensures `updateDNS.sh` is executable.
|
||||
- Checks for required dependencies: `curl`, `jq`, `systemctl`.
|
||||
- Validates that `.env` contains `API_KEY`, `SECRET_KEY`, `DOMAIN`, and `MACHINE_ID`.
|
||||
- Runs `updateDNS.sh` once as a test (with your current config).
|
||||
- Installs and enables:
|
||||
- `/etc/systemd/system/porkbun-ddns.service`
|
||||
- `/etc/systemd/system/porkbun-ddns.timer`
|
||||
- Starts the timer and shows its status.
|
||||
|
||||
Usage:
|
||||
|
||||
```bash
|
||||
cd /path/to/porkbun
|
||||
./install.sh
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Do **not** run `install.sh` directly as root; it will use `sudo` when needed.
|
||||
- The service runs as the current user (it rewrites `User=` and `Group=` in
|
||||
the service file to match who ran `install.sh`).
|
||||
|
||||
After installation, some useful commands:
|
||||
|
||||
```bash
|
||||
systemctl status porkbun-ddns.timer
|
||||
systemctl status porkbun-ddns.service
|
||||
journalctl -u porkbun-ddns.service -n 50
|
||||
```
|
||||
|
||||
### `uninstall.sh` – remove systemd timer + service
|
||||
|
||||
`uninstall.sh` cleanly removes the `porkbun-ddns` systemd units while leaving your
|
||||
scripts and configuration files intact.
|
||||
|
||||
What it does:
|
||||
|
||||
- Stops `porkbun-ddns.timer` and `porkbun-ddns.service` if they are running.
|
||||
- Disables the timer so it no longer starts at boot.
|
||||
- Removes `/etc/systemd/system/porkbun-ddns.service` and
|
||||
`/etc/systemd/system/porkbun-ddns.timer`.
|
||||
- Reloads systemd and resets any failed state for these units.
|
||||
|
||||
Usage:
|
||||
|
||||
```bash
|
||||
cd /path/to/porkbun
|
||||
./uninstall.sh
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Do **not** run `uninstall.sh` as root; it will use `sudo` for systemd operations.
|
||||
- Your local files remain:
|
||||
- `updateDNS.sh`
|
||||
- `.env`
|
||||
- `porkbun-ddns.service`
|
||||
- `porkbun-ddns.timer`
|
||||
so you can reinstall later with `./install.sh`.
|
||||
|
||||
### `logs.sh` – convenient log viewer
|
||||
|
||||
`logs.sh` is a small wrapper around `journalctl` and `systemctl` to make it easier
|
||||
to inspect the `porkbun-ddns.service` logs and status.
|
||||
|
||||
Basic usage (show last 50 lines):
|
||||
|
||||
```bash
|
||||
cd /path/to/porkbun
|
||||
./logs.sh
|
||||
```
|
||||
|
||||
Common options:
|
||||
|
||||
- Follow logs in real-time (like `tail -f`):
|
||||
|
||||
```bash
|
||||
./logs.sh -f
|
||||
```
|
||||
|
||||
- Show last N lines:
|
||||
|
||||
```bash
|
||||
./logs.sh -n 100
|
||||
```
|
||||
|
||||
- Show logs from today only:
|
||||
|
||||
```bash
|
||||
./logs.sh -t
|
||||
```
|
||||
|
||||
- Show logs from the last hour:
|
||||
|
||||
```bash
|
||||
./logs.sh -h
|
||||
```
|
||||
|
||||
- Show only error messages:
|
||||
|
||||
```bash
|
||||
./logs.sh -e
|
||||
```
|
||||
|
||||
- Show service and timer status plus recent runs:
|
||||
|
||||
```bash
|
||||
./logs.sh -s
|
||||
```
|
||||
|
||||
Run `./logs.sh --help` for the full list of options.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Load Configuration** - Reads API credentials and settings from `.env`
|
||||
|
|
@ -195,13 +305,12 @@ so you can verify behavior before applying it.
|
|||
3. **Retrieve DNS Records** - Gets all existing DNS records for the domain and displays them
|
||||
4. **Check for Duplicates** - Detects if multiple records exist for this machine ID
|
||||
5. **Skip if Unchanged** - If IP matches and exactly one record exists, skips update
|
||||
6. **Clean Old Records** - Deletes A/ALIAS/CNAME records with no machine ID (migration cleanup)
|
||||
7. **Delete Own Records** - Removes this machine's previous A records (by matching notes field)
|
||||
8. **Verify Cleanup** - Ensures all old records were deleted before creating new ones
|
||||
9. **Create New Record** - Adds fresh A record with current IP and machine ID in notes
|
||||
10. **Verify Creation** - Confirms exactly one record exists for this machine
|
||||
6. **Delete Own Records** - Removes this machine's previous A records (by matching notes field)
|
||||
7. **Verify Cleanup** - Ensures all old records were deleted before creating new ones
|
||||
8. **Create New Record** - Adds fresh A record with current IP and machine ID in notes
|
||||
9. **Verify Creation** - Confirms exactly one record exists for this machine
|
||||
|
||||
> Note: The script now only deletes and verifies records that it manages
|
||||
> Note: The script only deletes and verifies records that it manages
|
||||
> (those whose notes are exactly `ddns:<MACHINE_ID>`). Other records in the
|
||||
> same zone are left untouched.
|
||||
|
||||
|
|
@ -228,18 +337,9 @@ so you can verify behavior before applying it.
|
|||
|
||||
1. **Immediately revoke** the API keys in your Porkbun account
|
||||
2. **Generate new keys** and update your `.env` file
|
||||
3. **Remove secrets from git history** if they were committed:
|
||||
```bash
|
||||
git filter-branch --force --index-filter \
|
||||
"git rm --cached --ignore-unmatch .env" \
|
||||
--prune-empty --tag-name-filter cat -- --all
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "dig: command not found"
|
||||
The script now uses `curl` instead of `dig`, so this shouldn't happen. If you see this, update to the latest version.
|
||||
|
||||
### Error: "API access not enabled"
|
||||
1. Log in to Porkbun
|
||||
2. Go to your domain settings
|
||||
|
|
@ -258,7 +358,7 @@ The script now uses `curl` instead of `dig`, so this shouldn't happen. If you se
|
|||
- Check DNS records in Porkbun dashboard to see notes field (look for `ddns:<MACHINE_ID>`)
|
||||
|
||||
### IP not updating
|
||||
- Check script is running (add to cron for automatic updates)
|
||||
- Check script is running
|
||||
- Verify your public IP actually changed
|
||||
- Check Porkbun API status
|
||||
- Review logs for error messages
|
||||
|
|
@ -278,23 +378,23 @@ Example output with the new structured logging format:
|
|||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Using environment file: /home/user/porkbun/.env
|
||||
IP source: Porkbun API (/ping)
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Current Public IP: 45.73.134.145
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Machine ID: KACPER_NIX
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Domain: aksal.cloud
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Machine ID: EXAMPLE_MACHINE
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Domain: example.com
|
||||
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Processing DNS record for: aksal.cloud (IP: 45.73.134.145)
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Machine ID: KACPER_NIX
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Existing records for FQDN 'aksal.cloud':
|
||||
Type: A, Name: aksal.cloud, Content: 45.73.134.145, Notes: ddns:KACPER_NIX, Managed: true, ID: 508029248
|
||||
Type: NS, Name: aksal.cloud, Content: curitiba.porkbun.com, Notes: none, Managed: false, ID: 506591857
|
||||
Type: NS, Name: aksal.cloud, Content: fortaleza.porkbun.com, Notes: none, Managed: false, ID: 506591856
|
||||
Type: NS, Name: aksal.cloud, Content: maceio.porkbun.com, Notes: none, Managed: false, ID: 506591854
|
||||
Type: NS, Name: aksal.cloud, Content: salvador.porkbun.com, Notes: none, Managed: false, ID: 506591855
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Processing DNS record for: example.com (IP: 45.73.134.145)
|
||||
Mon Nov 24 12:04:38 PM EST 2025 [INFO] Machine ID: EXAMPLE_MACHINE
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Existing records for FQDN 'example.com':
|
||||
Type: A, Name: example.com, Content: 45.73.134.145, Notes: ddns:EXAMPLE_MACHINE, Managed: true, ID: 508029248
|
||||
Type: NS, Name: example.com, Content: curitiba.porkbun.com, Notes: none, Managed: false, ID: 506591857
|
||||
Type: NS, Name: example.com, Content: fortaleza.porkbun.com, Notes: none, Managed: false, ID: 506591856
|
||||
Type: NS, Name: example.com, Content: maceio.porkbun.com, Notes: none, Managed: false, ID: 506591854
|
||||
Type: NS, Name: example.com, Content: salvador.porkbun.com, Notes: none, Managed: false, ID: 506591855
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Record already exists with correct IP (45.73.134.145). No update needed.
|
||||
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Processing DNS record for: *.aksal.cloud (IP: 45.73.134.145)
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Machine ID: KACPER_NIX
|
||||
Mon Nov 24 12:04:40 PM EST 2025 [INFO] Existing records for FQDN '*.aksal.cloud':
|
||||
Type: A, Name: *.aksal.cloud, Content: 45.73.134.145, Notes: ddns:KACPER_NIX, Managed: true, ID: 508029259
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Processing DNS record for: *.example.com (IP: 45.73.134.145)
|
||||
Mon Nov 24 12:04:39 PM EST 2025 [INFO] Machine ID: EXAMPLE_MACHINE
|
||||
Mon Nov 24 12:04:40 PM EST 2025 [INFO] Existing records for FQDN '*.example.com':
|
||||
Type: A, Name: *.example.com, Content: 45.73.134.145, Notes: ddns:EXAMPLE_MACHINE, Managed: true, ID: 508029259
|
||||
Mon Nov 24 12:04:40 PM EST 2025 [INFO] Record already exists with correct IP (45.73.134.145). No update needed.
|
||||
|
||||
Mon Nov 24 12:04:40 PM EST 2025 [INFO] DNS update completed successfully
|
||||
|
|
@ -310,18 +410,9 @@ Mon Nov 24 12:04:40 PM EST 2025 [INFO] DNS update completed successfully
|
|||
|
||||
This script is provided as-is for use with Porkbun DNS services.
|
||||
|
||||
## Support
|
||||
|
||||
For issues with:
|
||||
- **This script**: Open an issue or review the code
|
||||
- **Porkbun API**: Contact [Porkbun Support](https://porkbun.com/support)
|
||||
- **DNS concepts**: See [Porkbun DNS Documentation](https://kb.porkbun.com/)
|
||||
|
||||
## Contributing
|
||||
|
||||
Improvements welcome! Consider adding:
|
||||
- IPv6 support (AAAA records)
|
||||
- Email notifications on IP change
|
||||
- Systemd service file
|
||||
- Docker container version
|
||||
- Health check endpoint
|
||||
- Health check endpoint
|
||||
Loading…
Add table
Add a link
Reference in a new issue