🦮 Strip whitespace from subdomain
📚 Improved documentation
This commit is contained in:
parent
a816fb6c3f
commit
27ccdd0203
50
README.md
50
README.md
@ -8,7 +8,11 @@ A small, 🕵️ privacy centric, and ⚡ lightning fast multi-architecture Dock
|
|||||||
|
|
||||||
## 🇺🇸 Origin
|
## 🇺🇸 Origin
|
||||||
|
|
||||||
This script was written for the Raspberry Pi platform to enable low cost, simple self hosting to promote a more decentralized internet. On execution, the script fetches public IPv4 and IPv6 addresses and creates/updates DNS records for the subdomains in Cloudflare. Stale, duplicate DNS records are removed for housekeeping.
|
This script was written for the Raspberry Pi platform to enable low cost self hosting that just works to promote a more decentralized internet.
|
||||||
|
|
||||||
|
## 🧹 More than just DDNS
|
||||||
|
|
||||||
|
`cloudflare-ddns` handles the busy work for you, so deploying your web apps is less of a clickfest. On execution, the script fetches public IPv4 and IPv6 addresses and creates/updates DNS records for the subdomains in Cloudflare. Stale, duplicate DNS records are removed for housekeeping.
|
||||||
|
|
||||||
## 📊 Stats
|
## 📊 Stats
|
||||||
|
|
||||||
@ -80,7 +84,7 @@ You can handle ddns for multiple domains (cloudflare zones) using the same docke
|
|||||||
"api_key": {
|
"api_key": {
|
||||||
"api_key": "api_key_here",
|
"api_key": "api_key_here",
|
||||||
"account_email": "your_email_here"
|
"account_email": "your_email_here"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zone_id": "your_zone_id_here",
|
"zone_id": "your_zone_id_here",
|
||||||
"subdomains": [
|
"subdomains": [
|
||||||
@ -95,7 +99,7 @@ You can handle ddns for multiple domains (cloudflare zones) using the same docke
|
|||||||
"api_key": {
|
"api_key": {
|
||||||
"api_key": "api_key_here",
|
"api_key": "api_key_here",
|
||||||
"account_email": "your_email_here"
|
"account_email": "your_email_here"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zone_id": "your_zone_id_here",
|
"zone_id": "your_zone_id_here",
|
||||||
"subdomains": [
|
"subdomains": [
|
||||||
@ -143,6 +147,26 @@ From the project root directory
|
|||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 🐧 Deploy with Linux + Cron
|
||||||
|
|
||||||
|
### 🏃 Running (all distros)
|
||||||
|
|
||||||
|
This script requires Python 3.5+, which comes preinstalled on the latest version of Raspbian. Download/clone this repo and give permission to the project's bash script by running `chmod +x ./start-sync.sh`. Now you can execute `./start-sync.sh`, which will set up a virtualenv, pull in any dependencies, and fire the script.
|
||||||
|
|
||||||
|
1. Upload the cloudflare-ddns folder to your home directory /home/your_username_here/
|
||||||
|
|
||||||
|
2. Run the following code in terminal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Add the following lines to sync your DNS records every 15 minutes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
*/15 * * * * /home/your_username_here/cloudflare-ddns/start-sync.sh
|
||||||
|
```
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
Create a config.json file with your production credentials.
|
Create a config.json file with your production credentials.
|
||||||
@ -189,26 +213,6 @@ Recommended for production
|
|||||||
docker run -d timothyjmiller/cloudflare_ddns:latest
|
docker run -d timothyjmiller/cloudflare_ddns:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🐧 (legacy) Linux + cron instructions (all distros)
|
|
||||||
|
|
||||||
### 🏃 Running
|
|
||||||
|
|
||||||
This script requires Python 3.5+, which comes preinstalled on the latest version of Raspbian. Download/clone this repo and give permission to the project's bash script by running `chmod +x ./start-sync.sh`. Now you can execute `./start-sync.sh`, which will set up a virtualenv, pull in any dependencies, and fire the script.
|
|
||||||
|
|
||||||
1. Upload the cloudflare-ddns folder to your home directory /home/your_username_here/
|
|
||||||
|
|
||||||
2. Run the following code in terminal
|
|
||||||
|
|
||||||
```bash
|
|
||||||
crontab -e
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Add the following lines to sync your DNS records every 15 minutes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
*/15 * * * * /home/your_username_here/cloudflare-ddns/start-sync.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This Template is licensed under the GNU General Public License, version 3 (GPLv3).
|
This Template is licensed under the GNU General Public License, version 3 (GPLv3).
|
||||||
|
|||||||
@ -18,8 +18,7 @@ class GracefulExit:
|
|||||||
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||||
|
|
||||||
def exit_gracefully(self, signum, frame):
|
def exit_gracefully(self, signum, frame):
|
||||||
print("\nReceived {} signal".format(self.signals[signum]))
|
print("🛑 Stopping main thread...")
|
||||||
print("Cleaning up resources. End of the program")
|
|
||||||
self.kill_now = True
|
self.kill_now = True
|
||||||
|
|
||||||
with open(PATH + "config.json") as config_file:
|
with open(PATH + "config.json") as config_file:
|
||||||
@ -49,14 +48,14 @@ def getIPs():
|
|||||||
a.pop()
|
a.pop()
|
||||||
a = dict(s.split("=") for s in a)["ip"]
|
a = dict(s.split("=") for s in a)["ip"]
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Warning: IPv4 not detected.")
|
print("⚠️ Warning: IPv4 not detected.")
|
||||||
deleteEntries("A")
|
deleteEntries("A")
|
||||||
try:
|
try:
|
||||||
aaaa = requests.get("https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
|
aaaa = requests.get("https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
|
||||||
aaaa.pop()
|
aaaa.pop()
|
||||||
aaaa = dict(s.split("=") for s in aaaa)["ip"]
|
aaaa = dict(s.split("=") for s in aaaa)["ip"]
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Warning: IPv6 not detected.")
|
print("⚠️ Warning: IPv6 not detected.")
|
||||||
deleteEntries("AAAA")
|
deleteEntries("AAAA")
|
||||||
ips = []
|
ips = []
|
||||||
if(a is not None):
|
if(a is not None):
|
||||||
@ -78,7 +77,7 @@ def commitRecord(ip):
|
|||||||
base_domain_name = response["result"]["name"]
|
base_domain_name = response["result"]["name"]
|
||||||
ttl = 300 # default Cloudflare TTL
|
ttl = 300 # default Cloudflare TTL
|
||||||
for subdomain in subdomains:
|
for subdomain in subdomains:
|
||||||
subdomain = subdomain.lower()
|
subdomain = subdomain.lower().strip()
|
||||||
record = {
|
record = {
|
||||||
"type": ip["type"],
|
"type": ip["type"],
|
||||||
"name": subdomain,
|
"name": subdomain,
|
||||||
@ -108,16 +107,16 @@ def commitRecord(ip):
|
|||||||
modified = True
|
modified = True
|
||||||
if identifier:
|
if identifier:
|
||||||
if modified:
|
if modified:
|
||||||
print("Updating record " + str(record))
|
print("📡 Updating record " + str(record))
|
||||||
response = cf_api(
|
response = cf_api(
|
||||||
"zones/" + c['zone_id'] + "/dns_records/" + identifier, "PUT", c, {}, record)
|
"zones/" + c['zone_id'] + "/dns_records/" + identifier, "PUT", c, {}, record)
|
||||||
else:
|
else:
|
||||||
print("Adding new record " + str(record))
|
print("➕ Adding new record " + str(record))
|
||||||
response = cf_api(
|
response = cf_api(
|
||||||
"zones/" + c['zone_id'] + "/dns_records", "POST", c, {}, record)
|
"zones/" + c['zone_id'] + "/dns_records", "POST", c, {}, record)
|
||||||
for identifier in duplicate_ids:
|
for identifier in duplicate_ids:
|
||||||
identifier = str(identifier)
|
identifier = str(identifier)
|
||||||
print("Deleting stale record " + identifier)
|
print("🗑️ Deleting stale record " + identifier)
|
||||||
response = cf_api(
|
response = cf_api(
|
||||||
"zones/" + c['zone_id'] + "/dns_records/" + identifier, "DELETE", c)
|
"zones/" + c['zone_id'] + "/dns_records/" + identifier, "DELETE", c)
|
||||||
return True
|
return True
|
||||||
@ -151,8 +150,8 @@ def updateIPs():
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if(len(sys.argv) > 1):
|
if(len(sys.argv) > 1):
|
||||||
if(sys.argv[1] == "--repeat"):
|
if(sys.argv[1] == "--repeat"):
|
||||||
delay = 5*60 # 5 minutes
|
delay = 5*60
|
||||||
print("Updating A & AAAA records every " + str(delay) + " seconds")
|
print("⏲️ Updating IPv4 (A) & IPv6 (AAAA) records every 5 minutes")
|
||||||
next_time = time.time()
|
next_time = time.time()
|
||||||
killer = GracefulExit()
|
killer = GracefulExit()
|
||||||
while not killer.kill_now:
|
while not killer.kill_now:
|
||||||
@ -160,7 +159,7 @@ if __name__ == '__main__':
|
|||||||
updateIPs()
|
updateIPs()
|
||||||
next_time += (time.time() - next_time) // delay * delay + delay
|
next_time += (time.time() - next_time) // delay * delay + delay
|
||||||
else:
|
else:
|
||||||
print("Unrecognized parameter '" + sys.argv[1] + "'. Stopping now.")
|
print("😡 Unrecognized parameter '" + sys.argv[1] + "'. Stopping now.")
|
||||||
else:
|
else:
|
||||||
updateIPs()
|
updateIPs()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user