Updating my dynamic IP in Cloudflare

Hi all,

My first post here.

I was looking to get Cloudflare working with the IPFire DDNS system.

First I found this and took the code from there: Cloudflare DDNS

Made some fixes to it to get it working with the Core Update 193.

Had to install couple of Python packages with Pakfire namely:

  • python3-certifi
  • python3-charset-normilzer
  • python3-idna
  • python3-requests
  • python3-urllib3

This seems to at least work. The FQDN in the list wont turn green for me as there is know bug with how Perl handles domain resolution.

But anyways. Wanted to share this if someone is looking for a temporary solution as long as IPFire wont officially support Cloudflare.

The current best practice seems to be to use Cloudflare token, but this old style of updating Cloudflare DNS works with the API Key as password only.

I’m not really a developer, so someone with better skills could definitely improve this code I’m sure.

#!/usr/bin/python3
###############################################################################
#                                                                             #
# ddns - A dynamic DNS client for IPFire                                      #
# Copyright (C) 2012-2017 IPFire development team                             #
#                                                                             #
# This program is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU General Public License as published by        #
# the Free Software Foundation, either version 3 of the License, or           #
# (at your option) any later version.                                         #
#                                                                             #
# This program is distributed in the hope that it will be useful,             #
# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
# GNU General Public License for more details.                                #
#                                                                             #
# You should have received a copy of the GNU General Public License           #
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################
....
....
....
import requests
....
....
....
def update_protocol(self, proto):
		API_HEADERS = {
			'X-Auth-Key': self.password,
			'X-Auth-Email': self.username
		}

		host, domain = self.hostname.split(".", 1)

		payload = {
			'name': domain
		}
		r = requests.get(self.url + "zones", headers=API_HEADERS, params=payload)
		data = r.json().get("result")
		zone_id = data[0]["id"]
		zone_name = data[0]["name"]

		payload = {
			"page": 1,
			"per_page": 50
		}
		r = requests.get(self.url + "zones/" + zone_id + "/dns_records", headers=API_HEADERS, params=payload)
		data = r.json().get("result")
		for entry in data:
			if self.hostname == entry["name"] and entry["type"] == "A":
				host_id = entry["id"]
				payload = {
					"comment": entry["comment"],
					"content": self.get_address(proto),
					"name": self.hostname,
					"proxied": entry["proxied"],
					"ttl": entry["ttl"],
					"type": entry["type"]
				}
				API_HEADERS['Content-Type'] = 'application/json'
				r = requests.put(self.url + "zones/" + zone_id + "/dns_records/" + host_id, json=payload, headers=API_HEADERS)	
				success = r.json().get("success")
		# Handle success messages.
		if success:
			return
		else:
			raise DDNSRequestError(_("Invalid hostname specified"))
		raise DDNSUpdateError