🦮 Strip whitespace from subdomain

📚 Improved documentation
This commit is contained in:
Timothy Miller 2021-02-28 01:51:43 -05:00
parent a816fb6c3f
commit 27ccdd0203
2 changed files with 37 additions and 34 deletions

View File

@ -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
@ -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).

View File

@ -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()