{"id":70458,"date":"2020-04-22T15:11:24","date_gmt":"2020-04-22T07:11:24","guid":{"rendered":"http:\/\/4563.org\/?p=70458"},"modified":"2020-04-22T15:11:24","modified_gmt":"2020-04-22T07:11:24","slug":"%e5%bc%80%e6%ba%90%e4%b8%aagodaddy-ddns-python%e8%84%9a%e6%9c%ac","status":"publish","type":"post","link":"http:\/\/4563.org\/?p=70458","title":{"rendered":"\u5f00\u6e90\u4e2agodaddy ddns python\u811a\u672c"},"content":{"rendered":"\n<p>  \t\t\t\t\t<strong>ansheng<\/strong>  \t\t\t\t\u5927\u4f6c\u6709\u8bdd\u8bf4 : 11&nbsp;\u5206\u949f\u524d\t<\/p>\n<h3>\u5f00\u6e90\u4e2agodaddy ddns python\u811a\u672c<\/h3>\n<p>  \t\t\u811a\u672c,Python3&#8230;<\/p>\n<p>  import json<br \/>  import re<br \/>  import os<br \/>  from sys import exit<br \/>  from urllib import request<br \/>  from urllib.error import HTTPError<\/p>\n<p>  # Begin settings<br \/>  # Get the Production API key\/secret from https:\/\/developer.godaddy.com\/keys\/.<br \/>  # Ensure it&#8217;s for &quot;Production&quot; as first time it&#8217;s created for &quot;Test&quot;.<br \/>  KEY = None# &lt;API production key&gt;<br \/>  SECRET = None# &lt;API secret&gt;<\/p>\n<p>  # set call API header<br \/>  HEADERS = {<br \/>  &nbsp; &nbsp; &quot;Accept&quot;: &quot;application\/json&quot;,<br \/>  &nbsp; &nbsp; &#8216;Content-type&#8217;: &#8216;application\/json&#8217;,<br \/>  &nbsp; &nbsp; &#8216;Authorization&#8217;: &#8216;sso-key {}:{}&#8217;.format(KEY, SECRET)<br \/>  }<\/p>\n<p>  # Domain to update.<br \/>  DOMAIN = None# &lt;domain name&gt;<\/p>\n<p>  # Advanced settings &#8211; change only if you know what you&#8217;re doing \ud83d\ude42<br \/>  # Record type, as seen in the DNS setup page, default A.<br \/>  TYPE = &#8216;A&#8217;<\/p>\n<p>  # Record name, as seen in the DNS setup page, default @.<br \/>  NAME = &#8216;@&#8217;<\/p>\n<p>  # Time To Live in seconds, minimum default 600 (10mins).<br \/>  # If your public IP seldom changes, set it to 3600 (1hr) or more for DNS servers cache performance.<br \/>  TTL = 600<\/p>\n<p>  # godaddy API URL<br \/>  GOD_ADDY_API_URL = &quot;https:\/\/api.godaddy.com\/v1\/domains\/{}\/records\/{}\/{}&quot;.format(DOMAIN, TYPE, NAME)<\/p>\n<p>  # Writable path to last known Public IP record cached. Best to place in tmpfs.<br \/>  CACHED_IP_FILE = &#8216;\/tmp\/current_ip&#8217;<br \/>  CACHED_IP = None<br \/>  if os.path.isfile(CACHED_IP_FILE):<br \/>  &nbsp; &nbsp; CACHED_IP = open(CACHED_IP_FILE, mode=&quot;r&quot;, encoding=&quot;utf-8&quot;).read()<\/p>\n<p>  # External URL to check for current Public IP, must contain only a single plain text IP.<br \/>  # Default http:\/\/api.ipify.org.<br \/>  CHECK_URL = &#8216;http:\/\/api.ipify.org&#8217;<\/p>\n<p>  if not KEY or not SECRET:<br \/>  &nbsp; &nbsp; print(&quot;Error: Requires API &#8216;Key\/Secret&#8217; value.&quot;)<br \/>  &nbsp; &nbsp; exit(1)<\/p>\n<p>  if not DOMAIN:<br \/>  &nbsp; &nbsp; print(&quot;Error: Requires &#8216;Domain&#8217; value.&quot;)<br \/>  &nbsp; &nbsp; exit(1)<\/p>\n<p>  # Get Host Public IP<br \/>  PUBLIC_IP = request.urlopen(CHECK_URL).read().decode(&#8216;utf-8&#8217;)<br \/>  regex = r&quot;^d{1,3}.d{1,3}.d{1,3}.d{1,3}$&quot;<br \/>  if re.search(regex, PUBLIC_IP):<br \/>  &nbsp; &nbsp; print(&quot;Get Public IP: {}&quot;.format(PUBLIC_IP))<br \/>  else:<br \/>  &nbsp; &nbsp; print(&quot;Fail! Public IP: {}&quot;.format(PUBLIC_IP))<br \/>  &nbsp; &nbsp; exit(1)<\/p>\n<p>  # Check if the IP needs to be updated<br \/>  if CACHED_IP != PUBLIC_IP:<br \/>  &nbsp; &nbsp; req = request.Request(url=GOD_ADDY_API_URL, headers=HEADERS)<br \/>  &nbsp; &nbsp; try:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;with request.urlopen(req) as response:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;data = json.loads(response.read().decode(&#8216;utf-8&#8217;))<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;NAME_BIND_IP = data[&quot;data&quot;] if data else None<br \/>  &nbsp; &nbsp; except HTTPError as e:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;if e.code in (422, 404):<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;NAME_BIND_IP = None<br \/>  &nbsp; &nbsp; if NAME_BIND_IP == PUBLIC_IP:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;print(&quot;unchanged! Current &#8216;Public IP&#8217; matches &#8216;GoDaddy&#8217; records. No update required!&quot;)<br \/>  &nbsp; &nbsp; else:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;print(&quot;changed! Updating &#8216;{}.{}&#8217;, {} to {}&quot;.format(NAME, DOMAIN, NAME_BIND_IP, PUBLIC_IP))<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;data = json.dumps([{&quot;data&quot;: PUBLIC_IP, &quot;name&quot;: NAME, &quot;ttl&quot;: TTL, &quot;type&quot;: TYPE}]).encode(&#8216;utf-8&#8217;)<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;req = request.Request(url=GOD_ADDY_API_URL, data=data, headers=HEADERS, method=&#8217;PUT&#8217;)<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;with request.urlopen(req) as response:<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;print(&quot;Success!&quot; if not response.read().decode(&#8216;utf-8&#8217;) else &quot;Success!&quot;)<br \/>  &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;open(&#8216;\/tmp\/current_ip&#8217;, mode=&quot;w&quot;, encoding=&quot;utf-8&quot;).write(PUBLIC_IP)<br \/>  else:<br \/>  &nbsp; &nbsp; print(&quot;Current &#8216;Public IP&#8217; matches &#8216;Cached IP&#8217; recorded. No update required!&quot;)<\/p>\n<p>  README<\/p>\n<p>  mkdir script<br \/>  cd script\/<br \/>  wget https:\/\/raw.githubusercontent.com\/anshengme\/ddns\/master\/godaddy_for_python.py<br \/>  crontab -e<br \/>  *\/5 * * * * \/usr\/bin\/python3 \/root\/script\/godaddy_for_python.py &gt;&gt; \/var\/log\/godaddy_for_python.py.log<\/p>\n<p>  \u8d34\u4e0aGitHub: https:\/\/github.com\/anshengme\/ddns\t\t\t\t<\/p>\n<p>  \t\t\t\t\t<strong>\u6211\u662f\u5927\u6c34\u903c<\/strong>  \t\t\t\t\u5927\u4f6c\u6709\u8bdd\u8bf4 : 9&nbsp;\u5206\u949f\u524d\t<\/p>\n<h3><\/h3>\n<p>  \t\t\u597d\u4e1c\u897f\uff0c\u6536\u85cf\u4e86\t\t\t\t<\/p>\n<p>  \t\t\t\t\t<strong>insightfy<\/strong>  \t\t\t\t\u5927\u4f6c\u6709\u8bdd\u8bf4 : 9&nbsp;\u5206\u949f\u524d\t<\/p>\n<h3><\/h3>\n<p>  \t\t\u4e00\u822c\u4e0d\u662f\u5230\u624bcf\u4e48 \u3001<br \/>  \u4e0d\u8fc7\u4e5f\u8c22\u8c22\u5927\u4f6c\t\t\t\t<\/p>\n<p>  \t\t\t\t\t<strong>ansheng<\/strong>  \t\t\t\t\u5927\u4f6c\u6709\u8bdd\u8bf4 : 4&nbsp;\u5206\u949f\u524d\t<\/p>\n<h3><\/h3>\n<p>  \t\tinsightfy \u5927\u4f6c\u6709\u8bdd\u8bf4 : 2020-4-22 15:30<br \/>  \u4e00\u822c\u4e0d\u662f\u5230\u624bcf\u4e48 \u3001<br \/>  \u4e0d\u8fc7\u4e5f\u8c22\u8c22\u5927\u4f6c<\/p>\n<p> :lol \u6211\u7684\u57df\u540d\u73b0\u5728\u653e\u5728\u72d7\u7239\uff0c\u6240\u4ee5\u5c31\u5f04\u72d7\u7239\u7684\u4e86\uff0c\u5982\u679c\u662fCF\uff0c\u5230\u65f6\u5019\u5728\u64b8\u4e2aCF\u5c31\u597d\u4e86  \t\t\t  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>ansheng \u5927\u4f6c\u6709\u8bdd\u8bf4 : 1&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/70458"}],"collection":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=70458"}],"version-history":[{"count":0,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/70458\/revisions"}],"wp:attachment":[{"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=70458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=70458"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=70458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}