mrikirill / SynologyDDNSCloudflareMultidomain

Synology DDNS Cloudflare service provider with multidomains and subdomains
https://mrikirill.github.io/SynologyDDNSCloudflareMultidomain/
MIT License
465 stars 65 forks source link

Update cloudflare.php #14

Closed smoetje closed 3 years ago

smoetje commented 3 years ago

Patched several issues when ipv6 is active on your host / internet-connection, that ipv4 is also updated to Cloudflare as well again. Also fixed issue when DNS has IPV4 record but no (need for) IPV6 (or opposite). PATCH records instead of PUT (avoids weird error I had while testing the cloudflare api, that a record already exists).

Tested it offline and on DSM7, works flawlessly.

mrikirill commented 3 years ago

It fails for me on the lates DSM 7.0

smoetje commented 3 years ago

It fails for me on the lates DSM 7.0

Strange. It works fine here (I am working with DSM7 as well).

I am just wondering... Do you have pre-existing cloudflare DNS records? Or do you expect new DNS-records to be made by the script if they don't yet exist? The script only updates existing DNS records now, but it won't make any new record entries based on the input-array entered in DSM.

e.g. my test-Cloudflare containst the following existing records: domain1.xyz contains a dual stack config (containing IPV4 record and IPV6 record) domain2.xyz contains only containing an IPV4 record

If the script is used as follows: hostname: domain1.xyz---domain2.xyz it should work fine, updates the addresses based on existing DNS records in single or dual stack

If the script is used as follows: hostname: domain1.xyz---domain2.xyz---domain3.xyz with patch it probably won't work. Because there's no error handling, it'll probably just say "normal"...

In a newer version I already added some additional return DSM statuses based on what the clouflare api returns. I already have a working version which triggers a proper error message in DSM7 when the password is incorrect (it now says: "normal" but in fact: nothing happens). Because I didn't like DSM says "normal" when it definitely isn't the case but nothing happens. https://github.com/smoetje/SynologyDDNSCloudflareMultidomain/tree/error-messages

smoetje commented 3 years ago

It fails for me on the lates DSM 7.0

Ipv6 doesn't update on my live server as well, but it does in my cli tests... oops. I may have overlooked something, checking...

smoetje commented 3 years ago

The issue appears to be that, when I manually do curl from my DSM7 terminal: curl 'https://api64.ipify.org' ... I properly get an IPV6 address.

Launching from PHP from the DSM7 console however, I get an IPV4 address instead: php > echo(file_get_contents('https://api64.ipify.org')); results in an IPV4 address (defaults to V4 when V6 isn't supported) I tried to CURL within PHP instead: same result > ipv4

Strange, it did work in DSM6 but no longer after the upgrade to 7...

smoetje commented 3 years ago

This explains a lot...

DSM 6 (PHP 5.6)

php > curl_setopt($curl, CURLOPT_URL, "https://api64.ipify.org");  
php > $result = curl_exec($curl);  
php > var_dump($result);  
2a02:578:8571:bxx:11:32xx:fe2d:c1c5  
php > curl_close($curl);  

After upgrade: DSM 7 (PHP 7.3.3)

php > curl_setopt($curl, CURLOPT_URL, "https://api64.ipify.org");  
php > $result = curl_exec($curl);  
php > var_dump($result);  
94.11x.1xx.42  
php > curl_close($curl);  
smoetje commented 3 years ago

I have been investigating further this evening. It appears the provider ipfy.org randomly (and not consistently) gives either IPV4 or IPV6. Meaning: sometimes it works, sometimes it doesn't... php cli resulted in the same behavior.

Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"2a02:578:8571:32ff:febd:6776"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"2a02:578:8571:32ff:febd:6776"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"2a02:578:8571:32ff:febd:6776"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"2a02:578:8571:32ff:febd:6776"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"2a02:578:8571:32ff:febd:6776"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nic94.11x.1xx.42  olas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'
{"ip":"94.11x.1xx.42"}Nicolas@MORPHEUS:~$ curl 'https://api64.ipify.org?format=json'

There's a trick to "force" the curl command in the console with the -6 flag to only resolve ipv6. If it' can't it will result in an error (and that message won't pass the ip verification). That seems to be working consistently instead of random above. But I don't know how to properly code that -6 flag in php. That should however resolve the issue I think... (and replace the file_get_contents())

smoetje commented 3 years ago

I fixed the IPV6 detection as ipify gives a random (so: unreliable) result through file_get_contents(). Instead I use curl and forced it to make the call through ipv6 only. If it fails (because IPV6 is not active) it returns a false and the ipv6 property is not updated. I tested it in an ipv4 "only" environment and in a dual-stack "ipv4-ipv6" environment (on my nas/DSM7 itself).

Both over here now seem to work consistently fine. IPV4 is my connection on the router through NAT. IPV6 is the address from my Synology (V6 has no NAT). Ports are properly forwarded for both V4 & V6.

Although my IP's are not frequently updated I'll let it run further over here for a while, to observe the behavior...