[{"data":1,"prerenderedAt":492},["ShallowReactive",2],{"Categories":3,"NavIndexCategoriesCountFooter":203,"content-\u002F2024\u002F10\u002F12\u002Fmonitoring-ip-changes-with-ddclient\u002F":204},[4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,68,70,71,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202],{"category":5},"System Administration",{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},"Software Development",{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":27},{"category":27},{"category":67},"Drones & RC",{"category":69},"DIY Projects",{"category":67},{"category":72},"Photography",{"category":69},{"category":69},{"category":69},{"category":67},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":67},{"category":69},{"category":69},{"category":67},{"category":67},{"category":72},{"category":72},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":5},{"category":5},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":5},{"category":67},{"category":67},{"category":72},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":72},{"category":67},{"category":138},"3D Printing - Laser Cutting - CNC",{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":5},{"category":138},{"category":27},{"category":27},{"category":138},{"category":138},{"category":72},{"category":158},"Photography,3D Printing - Laser Cutting - CNC",{"category":27},{"category":27},{"category":69},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":67},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":27},{"category":69},{"category":27},{"category":27},{"category":27},{"category":27},{"category":181},"Home Assistant",{"category":181},{"category":72},{"category":27},{"category":27},{"category":72},{"category":138},{"category":5},{"category":72},{"category":72},{"category":138},{"category":27},{"category":181},{"category":181},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},191,{"id":205,"title":206,"body":207,"category":5,"date":477,"description":478,"embedImage":479,"extension":480,"image":479,"intro":481,"meta":482,"navigation":483,"path":484,"seo":485,"series":479,"sitemap":486,"stem":487,"tags":488,"__hash__":491},"content\u002F2024\u002F10\u002F12\u002Fmonitoring-ip-changes-with-ddclient.md","Monitoring and updating DNS for IP changes with ddclient",{"type":208,"value":209,"toc":475},"minimark",[210,220,223,226,229,232,235,306,309,401,404,445,448,451,454,457,460,468,471],[211,212,213,214,219],"p",{},"Back in ",[215,216,218],"a",{"href":217},"\u002F2020\u002F01\u002F29\u002Fmonitoring-ip-changes\u002F","2020"," I moved a plain cron script to use the cloudflare API to handle changes in my ISP provided external IP address.",[211,221,222],{},"Recently - I was seeing an increasing number of failures from ipify - I believe due to load - after all they provide an excellent service and for free.",[211,224,225],{},"However - scripting for all possible failure rates was irritating.",[211,227,228],{},"But - I decided I wanted to pop in something more direct, that could handle the errors for me - and decided to go with ddclient.",[211,230,231],{},"As usual - provisioning with ansible.",[211,233,234],{},"First - we need some packages - ddclient and dnsutils:",[236,237,242],"pre",{"className":238,"code":239,"language":240,"meta":241,"style":241},"language-yaml shiki shiki-themes github-dark","- name: Install dns tools\n  ansible.builtin.apt:\n    pkg: [dnsutils, ddclient]\n    state: present\n","yaml","",[243,244,245,265,274,295],"code",{"__ignoreMap":241},[246,247,250,254,258,261],"span",{"class":248,"line":249},"line",1,[246,251,253],{"class":252},"s95oV","- ",[246,255,257],{"class":256},"s4JwU","name",[246,259,260],{"class":252},": ",[246,262,264],{"class":263},"sU2Wk","Install dns tools\n",[246,266,268,271],{"class":248,"line":267},2,[246,269,270],{"class":256},"  ansible.builtin.apt",[246,272,273],{"class":252},":\n",[246,275,277,280,283,286,289,292],{"class":248,"line":276},3,[246,278,279],{"class":256},"    pkg",[246,281,282],{"class":252},": [",[246,284,285],{"class":263},"dnsutils",[246,287,288],{"class":252},", ",[246,290,291],{"class":263},"ddclient",[246,293,294],{"class":252},"]\n",[246,296,298,301,303],{"class":248,"line":297},4,[246,299,300],{"class":256},"    state",[246,302,260],{"class":252},[246,304,305],{"class":263},"present\n",[211,307,308],{},"Next up - we need to configure ddclient - installing the config file from a jinja2 template:",[236,310,312],{"className":238,"code":311,"language":240,"meta":241,"style":241},"- name: ddclient config\n  ansible.builtin.template:\n    src: ddclient.conf.j2\n    dest: \u002Fetc\u002Fddclient.conf\n    mode: \"0600\"\n    owner: root\n    group: root\n  notify:\n    - ddclient | restart\n",[243,313,314,325,332,342,352,363,374,384,392],{"__ignoreMap":241},[246,315,316,318,320,322],{"class":248,"line":249},[246,317,253],{"class":252},[246,319,257],{"class":256},[246,321,260],{"class":252},[246,323,324],{"class":263},"ddclient config\n",[246,326,327,330],{"class":248,"line":267},[246,328,329],{"class":256},"  ansible.builtin.template",[246,331,273],{"class":252},[246,333,334,337,339],{"class":248,"line":276},[246,335,336],{"class":256},"    src",[246,338,260],{"class":252},[246,340,341],{"class":263},"ddclient.conf.j2\n",[246,343,344,347,349],{"class":248,"line":297},[246,345,346],{"class":256},"    dest",[246,348,260],{"class":252},[246,350,351],{"class":263},"\u002Fetc\u002Fddclient.conf\n",[246,353,355,358,360],{"class":248,"line":354},5,[246,356,357],{"class":256},"    mode",[246,359,260],{"class":252},[246,361,362],{"class":263},"\"0600\"\n",[246,364,366,369,371],{"class":248,"line":365},6,[246,367,368],{"class":256},"    owner",[246,370,260],{"class":252},[246,372,373],{"class":263},"root\n",[246,375,377,380,382],{"class":248,"line":376},7,[246,378,379],{"class":256},"    group",[246,381,260],{"class":252},[246,383,373],{"class":263},[246,385,387,390],{"class":248,"line":386},8,[246,388,389],{"class":256},"  notify",[246,391,273],{"class":252},[246,393,395,398],{"class":248,"line":394},9,[246,396,397],{"class":252},"    - ",[246,399,400],{"class":263},"ddclient | restart\n",[211,402,403],{},"Since this calls a handler to restart if the configuration changes - we need a handler:",[236,405,407],{"className":238,"code":406,"language":240,"meta":241,"style":241},"- name: ddclient | restart\n  ansible.builtin.service:\n    name: ddclient\n    state: restarted\n",[243,408,409,419,426,436],{"__ignoreMap":241},[246,410,411,413,415,417],{"class":248,"line":249},[246,412,253],{"class":252},[246,414,257],{"class":256},[246,416,260],{"class":252},[246,418,400],{"class":263},[246,420,421,424],{"class":248,"line":267},[246,422,423],{"class":256},"  ansible.builtin.service",[246,425,273],{"class":252},[246,427,428,431,433],{"class":248,"line":276},[246,429,430],{"class":256},"    name",[246,432,260],{"class":252},[246,434,435],{"class":263},"ddclient\n",[246,437,438,440,442],{"class":248,"line":297},[246,439,300],{"class":256},[246,441,260],{"class":252},[246,443,444],{"class":263},"restarted\n",[211,446,447],{},"Finally - it installs that jinja2 template - so we need that too.",[211,449,450],{},"Here we'll run every 5 minutes.",[211,452,453],{},"Since we're talking to cloudflare - the protocol is cloudflare",[211,455,456],{},"For the router - we'll still use ipify - on IPv4. I do have IPv6 connectivity - but for now - this is enough to ensure i can connect back home after an unexpected address change.",[211,458,459],{},"Finally - it grabs 3 values from inventory variables using ansible vault where needed.",[236,461,466],{"className":462,"code":464,"language":465,"meta":241},[463],"language-text","daemon=300\nsyslog=yes\nmail=root\nmail-failure=root\nssl=yes\n\nprotocol=cloudflare\nuse=web, web=ipify-ipv4\nzone={{cloudflare_zone}}\npassword='{{cloudflare_bearer_token_home}}'\n{{cloudflare_hostname}}\n","text",[243,467,464],{"__ignoreMap":241},[211,469,470],{},"This is enough to get ddclient to replace the hand written shell scripts I was using previously - and it handles ipify issues quite cleanly - I get status report emails for each failure and following success.",[472,473,474],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":241,"searchDepth":267,"depth":267,"links":476},[],"2024-10-12 11:37 +0200","Back in 2020 I moved a plain cron script to use the cloudflare API to handle changes in my ISP provided external IP address.",null,"md","Replacing ipify and shell scripts with ddclient",{},true,"\u002F2024\u002F10\u002F12\u002Fmonitoring-ip-changes-with-ddclient",{"title":206,"description":478},{"loc":484},"2024\u002F10\u002F12\u002Fmonitoring-ip-changes-with-ddclient",[489,490,291],"ipify","cloudflare","tzt9LKuQEESBGi3CxOoGxPjpfgw7JkaAeGXKn4cTX0g",1775293006504]