FRITZ!Box and netcup DynDNS

Polls a FRITZ!Box's external IPv4-address and on change, updates a netcup DNS entry using the netcup DNS API. Can easily be adapted to use another source for the DNS-entry value, and to update various types of DNS entries, including AAAA.

Depends on node-red-contrib-fritz.

netcup API key and password can be created in the customer control panel.

send login requestrun at start and every minuteget external IPv4 address from FRITZ!Boxmsg.payload.NewExternalIPAddress has changedstore msg.payload.NewExternalIPAddress in msg.external_ipv4msg.payload.status == successconfigurationrun oncestore msg.payload.responsedata.apisessionid in msg.apisessionidsend infoDnsRecords requestget id of DNS record from responsecreate updateDnsRecords POST datasend updateDnsRecords requestcreate logout POST datasend logout requestmsg.payload has key NewExternalIPAddressmsg.payload.NewExternalIPAddress is IPv4 addresscreate login POST datacreate infoDnsRecords POST datamsg.payload.status == successlog error if msg.payload.status != success
Flow 1
[{"id":"1f73a5d7.e3db6a","type":"tab","label":"FRITZ!Box and netcup DynDNS","disabled":false,"info":""},{"id":"7702c44a.c888bc","type":"http request","z":"1f73a5d7.e3db6a","name":"send login request","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON","tls":"30a69635.622642","persist":false,"proxy":"","authType":"","x":430,"y":460,"wires":[["2b3e84a6.3a497c"]]},{"id":"c7f51cb.af9796","type":"inject","z":"1f73a5d7.e3db6a","name":"run at start and every minute","props":[],"repeat":"60","crontab":"","once":true,"onceDelay":"5","topic":"","x":150,"y":100,"wires":[["6f0de282.d3a8ac"]]},{"id":"6f0de282.d3a8ac","type":"fritzbox-in","z":"1f73a5d7.e3db6a","device":"bd2c7b29.a934a","name":"get external IPv4 address from FRITZ!Box","service":"urn:schemas-upnp-org:service:WANIPConnection:1","action":"GetExternalIPAddress","arguments":"{}","x":240,"y":160,"wires":[["b8a09678.fec5c"]]},{"id":"aeaea103.71ba1","type":"rbe","z":"1f73a5d7.e3db6a","name":"msg.payload.NewExternalIPAddress has changed","func":"rbe","gap":"","start":"","inout":"out","property":"payload.NewExternalIPAddress","x":270,"y":340,"wires":[["6a7e2610.73a738"]]},{"id":"6a7e2610.73a738","type":"change","z":"1f73a5d7.e3db6a","name":"store msg.payload.NewExternalIPAddress in msg.external_ipv4","rules":[{"t":"set","p":"external_ipv4","pt":"msg","to":"payload.NewExternalIPAddress","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":400,"wires":[["d1968848.fb2a58"]]},{"id":"2b3e84a6.3a497c","type":"switch","z":"1f73a5d7.e3db6a","name":"msg.payload.status == success","property":"payload.status","propertyType":"msg","rules":[{"t":"eq","v":"success","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":210,"y":520,"wires":[["f5ea7c7.85fa78"]]},{"id":"261617dc.1bc","type":"change","z":"1f73a5d7.e3db6a","name":"configuration","rules":[{"t":"set","p":"netcup_apikey","pt":"flow","to":"netcup-api-key","tot":"str"},{"t":"set","p":"netcup_apipassword","pt":"flow","to":"netcup-api-password","tot":"str"},{"t":"set","p":"netcup_customernumber","pt":"flow","to":"12345","tot":"str"},{"t":"set","p":"dnsrecord_domainname","pt":"flow","to":"domain.tld","tot":"str"},{"t":"set","p":"dnsrecord_hostname","pt":"flow","to":"subdomain","tot":"str"},{"t":"set","p":"dnsrecord_type","pt":"flow","to":"A","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":40,"wires":[[]]},{"id":"79351b8b.0283f4","type":"inject","z":"1f73a5d7.e3db6a","name":"run once","props":[],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":80,"y":40,"wires":[["261617dc.1bc"]]},{"id":"f5ea7c7.85fa78","type":"change","z":"1f73a5d7.e3db6a","name":"store msg.payload.responsedata.apisessionid in msg.apisessionid","rules":[{"t":"set","p":"apisessionid","pt":"msg","to":"payload.responsedata.apisessionid","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":580,"wires":[["fa2d5518.45f7b"]]},{"id":"6c8cd140.a486a8","type":"http request","z":"1f73a5d7.e3db6a","name":"send infoDnsRecords request","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON","tls":"30a69635.622642","persist":false,"proxy":"","authType":"","x":530,"y":640,"wires":[["b3671332.6e2d5"]]},{"id":"cd75e7b8.523ff8","type":"function","z":"1f73a5d7.e3db6a","name":"get id of DNS record from response","func":"const dnsrecords = msg.payload.responsedata.dnsrecords;\nconst dnsrecord_hostname = flow.get(\"dnsrecord_hostname\");\nconst dnsrecord_type = flow.get(\"dnsrecord_type\");\n\nfor (let i = 0; i < dnsrecords.length; ++i) {\n    const record = dnsrecords[i];\n    if (record.hostname === dnsrecord_hostname && record.type === dnsrecord_type) {\n        msg.dnsrecordid = record.id;\n        break;\n    }\n}\n\nif (!msg.dnsrecordid) {\n    node.error(`No DNS record found with hostname ${flow.dnsrecord_hostname} and type ${flow.dnsrecord_type}.`, msg);\n} else {\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":220,"y":760,"wires":[["5432b1ff.6348a"]]},{"id":"5432b1ff.6348a","type":"change","z":"1f73a5d7.e3db6a","name":"create updateDnsRecords POST data","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t    \"action\": \"updateDnsRecords\",\t    \"param\": {\t        \"domainname\": $flowContext(\"dnsrecord_domainname\"),\t        \"customernumber\": $flowContext(\"netcup_customernumber\"),\t        \"apikey\": $flowContext(\"netcup_apikey\"),\t        \"apisessionid\": apisessionid,\t        \"dnsrecordset\": {\t            \"dnsrecords\": [{\t                \"id\": dnsrecordid,\t                \"hostname\": $flowContext(\"dnsrecord_hostname\"),\t                \"type\": $flowContext(\"dnsrecord_type\"),\t                \"destination\": external_ipv4\t            }]\t        }\t    }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":820,"wires":[["eb7d4920.dfa26"]]},{"id":"eb7d4920.dfa26","type":"http request","z":"1f73a5d7.e3db6a","name":"send updateDnsRecords request","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON","tls":"30a69635.622642","persist":false,"proxy":"","authType":"","x":560,"y":820,"wires":[["1f38f24c.459326"]]},{"id":"3aa01976.7b821e","type":"change","z":"1f73a5d7.e3db6a","name":"create logout POST data","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t    \"action\": \"logout\",\t    \"param\": {\t        \"customernumber\": $flowContext(\"netcup_customernumber\"),\t        \"apikey\": $flowContext(\"netcup_apikey\"),\t        \"apisessionid\": apisessionid\t    }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":940,"wires":[["5d8e283d.6d1bf8"]]},{"id":"5d8e283d.6d1bf8","type":"http request","z":"1f73a5d7.e3db6a","name":"send logout request","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON","tls":"30a69635.622642","persist":false,"proxy":"","authType":"","x":440,"y":940,"wires":[[]]},{"id":"b8a09678.fec5c","type":"switch","z":"1f73a5d7.e3db6a","name":"msg.payload has key NewExternalIPAddress","property":"payload","propertyType":"msg","rules":[{"t":"hask","v":"NewExternalIPAddress","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":250,"y":220,"wires":[["838a9b4c.8eed08"]]},{"id":"838a9b4c.8eed08","type":"switch","z":"1f73a5d7.e3db6a","name":"msg.payload.NewExternalIPAddress is IPv4 address","property":"payload.NewExternalIPAddress","propertyType":"msg","rules":[{"t":"regex","v":"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$","vt":"str","case":false}],"checkall":"true","repair":false,"outputs":1,"x":280,"y":280,"wires":[["aeaea103.71ba1"]]},{"id":"d1968848.fb2a58","type":"change","z":"1f73a5d7.e3db6a","name":"create login POST data","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"action\": \"login\",\t   \"param\": {\t        \"apikey\": $flowContext(\"netcup_apikey\"),\t        \"apipassword\": $flowContext(\"netcup_apipassword\"),\t        \"customernumber\": $flowContext(\"netcup_customernumber\")\t        \t   }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":460,"wires":[["7702c44a.c888bc"]]},{"id":"fa2d5518.45f7b","type":"change","z":"1f73a5d7.e3db6a","name":"create infoDnsRecords POST data","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t    \"action\": \"infoDnsRecords\",\t    \"param\": {\t        \"domainname\": $flowContext(\"dnsrecord_domainname\"),\t        \"customernumber\": $flowContext(\"netcup_customernumber\"),\t        \"apikey\": $flowContext(\"netcup_apikey\"),\t        \"apisessionid\": apisessionid\t    }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":640,"wires":[["6c8cd140.a486a8"]]},{"id":"b3671332.6e2d5","type":"switch","z":"1f73a5d7.e3db6a","name":"msg.payload.status == success","property":"payload.status","propertyType":"msg","rules":[{"t":"eq","v":"success","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":210,"y":700,"wires":[["cd75e7b8.523ff8"]]},{"id":"1f38f24c.459326","type":"function","z":"1f73a5d7.e3db6a","name":"log error if msg.payload.status != success","func":"if (msg.payload.status != \"success\") {\n    node.error(\"Update of DNS entry failed.\", msg);\n} else {\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":240,"y":880,"wires":[["3aa01976.7b821e"]]},{"id":"30a69635.622642","type":"tls-config","z":"","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":true},{"id":"bd2c7b29.a934a","type":"fritzbox-config","z":"","name":"","host":"fritz.box","port":"49000","ssl":false}]

Flow Info

Created 5 years, 2 months ago
Rating: not yet rated

Owner

Actions

Node Types

Core
  • change (x7)
  • function (x2)
  • http request (x4)
  • inject (x2)
  • rbe (x1)
  • switch (x4)
  • tls-config (x1)
Other

Tags

  • dyndns
  • dns
  • netcup
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option