Commit baef00dddc1d02409c7e3c05fd9e10e2a1906eea
1 parent
885154d3
Showing
1 changed file
with
410 additions
and
100 deletions
README.md
... | ... | @@ -2,50 +2,64 @@ dyndns.pl |
2 | 2 | ========= |
3 | 3 | |
4 | 4 | Perl CGI-BIN script to handle Dynamic DNS updates through HTTP (e.g. from a |
5 | -router), updating DNS records through secure DNS update statements. | |
5 | +router), updating DNS records through secure DNS update statements to run your | |
6 | +own Dynamic DNS Service. | |
6 | 7 | |
7 | -**Version 1.0**, latest version, documentation and bugtracker available on my | |
8 | +**Version 1.1**, latest version, documentation and bugtracker available on my | |
8 | 9 | [GitLab instance](https://gitlab.lindenaar.net/scripts/dyndns) |
9 | 10 | |
10 | -Copyright (c) 2013 - 2015 Frederik Lindenaar. free for distribution under the | |
11 | +Copyright (c) 2013 - 2019 Frederik Lindenaar. free for distribution under the | |
11 | 12 | GNU License, see [below](#license) |
12 | 13 | |
13 | 14 | |
14 | 15 | Introduction |
15 | 16 | ------------ |
16 | -This script provides a simple interface to allow Dynamic DNS updates for DNS | |
17 | -zones. It is intended to be used for routers and (aDSL) modems to register their | |
18 | -IP address by simply opening a URL (this is supported by many modern devices) | |
19 | -but can also be used by end-users (either directly by using a client). Please | |
20 | -bear in mind that this script suits my setup and still might have glitches, but | |
21 | -so far turned out to be a quite stable solution for my needs and I use it in a | |
22 | -production setup. In case you have any comments / questions or issues, please | |
23 | -raise them through my | |
24 | -[GitLab instance](https://gitlab.lindenaar.net/scripts/dyndns) so that all | |
25 | -users benefit. | |
26 | - | |
27 | -Setup | |
28 | ------ | |
17 | +`dyndns.pl` provides a simple interface to allow Dynamic DNS updates for DNS | |
18 | +zones through HTTP requests. It is intended for routers and (aDSL) modems to | |
19 | +register their IP address by simply opening a URL (this is supported by most | |
20 | +modern devices) but can also be used by end-users (either directly by using a | |
21 | +client). The script itself uses DNS' `nsupdate` calls to perform the update. | |
22 | +With this script you can integrate devices not supporting `nsupdate` and | |
23 | +environments where the master DNS server is not publicly available. The script | |
24 | +suits my setup/and needs and still might have glitches, but turned out to be a | |
25 | +very stable solution the last 6 years on both Linux as well as MacOS. | |
26 | + | |
27 | +Please [see below](#integration) on how to setup the client side including: | |
28 | + * [Cisco Routers](#cisco_integration) | |
29 | + * [AVM Fritz!Box routers](#fritzbox_integration) | |
30 | + * [Synology DSM](#synology_integration) (NAS) | |
31 | + | |
32 | +In case you have any comments / questions or issues, please raise them through | |
33 | +my [GitLab instance](https://gitlab.lindenaar.net/scripts/dyndns) so that other | |
34 | +users can benefit and respond. Please also use this to submit setup instructions | |
35 | +for other devices you have set up for inclusion in this document. | |
36 | + | |
37 | + | |
38 | +Setup of the server side | |
39 | +======================== | |
29 | 40 | This script is to be executed as CGI-BIN script by a web server. As it is |
30 | -written in Perl, it requires that installed (which is pretty standard nowadays | |
31 | -on all *nix platforms). This description covers the installation on Apache 2.4, | |
32 | -which should be similar for other web servers, with ISC Bind v9. For performance | |
33 | -reasons consider using the Apache mod_perl module for highly a volatile domain. | |
41 | +written in Perl, it requires that installed (which is pretty standard on \*nix | |
42 | +platforms). This description covers the installation on Apache 2.4 and should be | |
43 | +similar for other web servers, with ISC Bind v9. For performance reasons | |
44 | +consider using the Apache mod_perl module for highly a volatile domain. | |
34 | 45 | |
46 | + | |
47 | +<a name=installation>Installation</a> | |
48 | +------------------------------------- | |
35 | 49 | The setup of this solution consists of the following steps: |
36 | 50 | |
37 | 51 | 1. Ensure that the Perl modules CGI and Net::DNS are installed. |
38 | - * on Debian/Ubunto linux this can be done by: | |
52 | + * on Debian/Ubuntu linux this can be done by: | |
39 | 53 | |
40 | - ~~~~ | |
54 | + ``` | |
41 | 55 | sudo apt-get install libcgi-pm-perl libnet-dns-perl |
42 | - ~~~~ | |
56 | + ``` | |
43 | 57 | |
44 | - * or if you have cpan installed: | |
58 | + * or directly from CPAN (assuming that is installed): | |
45 | 59 | |
46 | - ~~~ | |
60 | + ``` | |
47 | 61 | cpan CGI Net::DNS |
48 | - ~~~ | |
62 | + ``` | |
49 | 63 | |
50 | 64 | 2. Install the file `dyndns.pl` either in your cgi-bin directory or in a |
51 | 65 | separate folder |
... | ... | @@ -60,22 +74,27 @@ The setup of this solution consists of the following steps: |
60 | 74 | server's cgi-bin directory) add the following line to your Apache virtual |
61 | 75 | host configuration (replacing `[INSTALL_DIR]` with the install directory): |
62 | 76 | |
63 | - ScriptAlias /dyndns [INSTALL_DIR]/dyndns.pl | |
77 | + ``` | |
78 | + ScriptAlias /dyndns [INSTALL_DIR]/dyndns.pl | |
79 | + ``` | |
64 | 80 | |
65 | 81 | in case you have installed the script in a non-standard folder, you will |
66 | 82 | also need the following to make this work on Apache 2.4 (again replacing |
67 | 83 | `[INSTALL_DIR]` with the install directory): |
68 | 84 | |
69 | - ~~~ | |
85 | + ``` | |
70 | 86 | <Directory [INSTALL_DIR]/> |
71 | 87 | AllowOverride None |
72 | 88 | Options +ExecCGI -MultiViews -Indexes |
73 | 89 | Require all granted |
74 | 90 | </Directory> |
75 | - ~~~ | |
91 | + ``` | |
76 | 92 | |
77 | 93 | reload apache with `/etc/init.d/apache reload` to make the script |
78 | - available at <http://myserver.mydomain.tld/dyndns> | |
94 | + available at <http://myserver.mydomain.tld/dyndns>. | |
95 | + | |
96 | + It is also possible to run as a virtual host, [see below](#VirtualHost) for | |
97 | + an example of that. | |
79 | 98 | |
80 | 99 | 5. To setup your Bind nameserver, either update `named.conf` direcly or create |
81 | 100 | a separate file (e.g. `named.dyndns.conf` in the Bind configuration |
... | ... | @@ -83,7 +102,7 @@ The setup of this solution consists of the following steps: |
83 | 102 | (e.g. `include "named.dyndns.conf";`). For a basic dynamic DNS setup a |
84 | 103 | configuration like below is required: |
85 | 104 | |
86 | - ~~~ | |
105 | + ``` | |
87 | 106 | // Define the keys for DynDNS |
88 | 107 | key "dyndns.mydomain.tld" { |
89 | 108 | algorithm hmac-md5; secret "QdDJC7QVYmsCxgWoSAUmBg=="; |
... | ... | @@ -106,13 +125,13 @@ The setup of this solution consists of the following steps: |
106 | 125 | grant siteuser name site.dyndns.mydomain.tld ANY; |
107 | 126 | }; |
108 | 127 | }; |
109 | - ~~~ | |
128 | + ``` | |
110 | 129 | |
111 | 130 | The above defines a domain zone file `dyndns/db.dyndns.mydomain.tld` with |
112 | 131 | two signer/keys. *siteuser* only can update `site.dyndns.mydomain.tld` |
113 | 132 | while *dyndns.mydomain.tld* can update all entries in the domain (intended |
114 | 133 | for expiry). If you intend to use expiry or want to be able to retrieve a |
115 | - list of all entries, comment out the `allow-transfer` statement and update | |
134 | + list of all entries, uncomment the `allow-transfer` statement and update | |
116 | 135 | the IP adres to that of your web server. |
117 | 136 | |
118 | 137 | To seed these entries with fresh keys), use the following |
... | ... | @@ -120,23 +139,23 @@ The setup of this solution consists of the following steps: |
120 | 139 | |
121 | 140 | * to generate a new key *dyndns.mydomain.tld*: |
122 | 141 | |
123 | - ~~~ | |
142 | + ``` | |
124 | 143 | ddns-confgen -a hmac-md5 -k dyndns.mydomain.tld -z dyndns.mydomain.tld |
125 | - ~~~ | |
144 | + ``` | |
126 | 145 | |
127 | 146 | * generate the required configuration for *siteuser* (or any new user): |
128 | 147 | |
129 | - ~~~ | |
148 | + ``` | |
130 | 149 | ddns-confgen -a hmac-md5 -k siteuser -s site.dyndns.mydomain.tld |
131 | - ~~~ | |
150 | + ``` | |
132 | 151 | |
133 | 152 | 6. Generate an initial zone file like the one below for the dyndns domain in |
134 | 153 | the location specified in the config file above. |
135 | 154 | |
136 | - ~~~ | |
155 | + ``` | |
137 | 156 | $TTL 3600 ; 1 hour |
138 | 157 | @ IN SOA auth.dns.mydomain.tld. hostmaster.mydomain.tld. ( |
139 | - 2015051401 ; serial | |
158 | + 2019000001 ; serial | |
140 | 159 | 43200 ; refresh (12 hours) |
141 | 160 | 3600 ; retry (1 hour) |
142 | 161 | 86400 ; expire (24 hours) |
... | ... | @@ -145,7 +164,7 @@ The setup of this solution consists of the following steps: |
145 | 164 | TXT "Dynamic DNS zone for mydomain.tld" |
146 | 165 | |
147 | 166 | site A 1.2.3.4 |
148 | - ~~~ | |
167 | + ``` | |
149 | 168 | |
150 | 169 | Please note that Bind will rewrite this file and you need to be careful |
151 | 170 | with it. Entries do not need to exist initially, as long as the signer/key |
... | ... | @@ -168,38 +187,111 @@ The setup of this solution consists of the following steps: |
168 | 187 | |
169 | 188 | * <http://myserver.mydomain.tld/dyndns/list?domain=dyndns.mydomain.tld> |
170 | 189 | to list the entries in the domain (requires zone transfer rights!) |
171 | - * <http://myserver.mydomain.tld/dyndns/update?host=site.dyndns.mydomain.tld&user=siteuser&key=......> | |
190 | + * <http://myserver.mydomain.tld/dyndns/update?host=site.dyndns.mydomain.tld&user=siteuser&secret=......> | |
172 | 191 | to add/update a site and |
173 | - * <http://myserver.mydomain.tld/dyndns/delete?host=site.dyndns.mydomain.tld&user=siteuser&key=......> | |
192 | + * <http://myserver.mydomain.tld/dyndns/delete?host=site.dyndns.mydomain.tld&user=siteuser&secret=......> | |
174 | 193 | to delete (clear) it. |
175 | 194 | |
176 | 195 | Please read the section below as well on the configuration and different modes |
177 | 196 | (operations) available. |
178 | 197 | |
198 | + | |
179 | 199 | <a name=configuration>Configuration</a> |
180 | 200 | --------------------------------------- |
181 | - | |
182 | 201 | At the top of the script is a "Configuration" section, which contains the |
183 | -configurable options of the scripts. | |
202 | +configurable options of the scripts. As of version 1.1 the script also supports | |
203 | +a [configuration file](#config_file) so that modifying the script is no longer | |
204 | +required. | |
205 | + | |
184 | 206 | |
185 | 207 | Parameter | Description |
186 | -:----------------+:------------------------------------------------------------- | |
208 | +:----------------|:------------------------------------------------------------- | |
209 | +`$ConfigFile` | Enable/disable config file support, [see below](config_file) | |
187 | 210 | `$DNSServer` | IP address of the DNS Server to send DNS update requests to |
188 | -`$ExpandCNAMEs` | Max. CNAME lookups for `$host` (0 to disable), see below | |
211 | +`@DNSDomain` | How to determine the host's domain name, [see below](#conf_dnszone) | |
212 | +`$DomainListKey` | Secret required to use the list mode, set to '' to always enable and to 'off' to disable this mode | |
213 | +`$ExpandCNAMEs` | Max. CNAME lookups for `$host` (0 to disable), [see below](#conf_cname) | |
189 | 214 | `$AllowDebugKey` | Output debug log after result when `debug` parameter equals this value. Set to '' to always enable and to 'off' to disable debugging |
190 | -`$AuthMode` | Defines how to authenticate DNS update requests, see below | |
215 | +`$AuthMode` | Defines how to authenticate DNS update requests, [see below](#conf_auth) | |
191 | 216 | `$StaticSigner` | Static signer ID to be used for AuthMode `static` or `both` |
192 | 217 | `$StaticKey` | Static signing key to be used for AuthMode `static` or `both` |
193 | -`$RequireRR` | Require an existing DNS record of this type to allow updates. | |
194 | -`$ExpireAfter` | Expire time for registrations in minutes, hours, weeks or seconds. Format is number optionally followed by m, h, w, s (seconds is default). | |
218 | +`$RequireRR` | Require an existing DNS record of this type to allow updates | |
219 | +`$ExpireAfter` | Expire time for registrations in minutes, hours, weeks or seconds. Format is number optionally followed by m, h, w, s (seconds is default) | |
195 | 220 | `@ReplaceRR` | List of DNS Record types to remove (clear) as part of update. |
196 | 221 | `$UpdateTXT` | Add host TXT record during update with this text followed by a timestamp. Used for expiry (so don't change!), leave empty to not add this |
197 | -`$DeleteTXT` | Set TXT record upon deletion with this text and a timestamp. | |
198 | - | |
199 | -Please note that the values must be correctly quoted, etc. not to break the script. | |
200 | - | |
201 | - | |
202 | -#### CNAME Support | |
222 | +`$DeleteTXT` | Set TXT record upon deletion with this text and a timestamp. | |
223 | +`$RecordTTL` | TTL for created records in minutes, hours, weeks or seconds. Format is number optionally followed by m, h, w, s (seconds is default) | |
224 | + | |
225 | +Please note: when changing the script all values must be correctly quoted, etc. | |
226 | +not to break the script. Therefore as of version 1.1 a config file is supported | |
227 | +(preferred), [see below](config_file). | |
228 | + | |
229 | + | |
230 | +#### <a name=config_file>Configuration File</a> | |
231 | +The script can read its settings from a config located in the same directory as | |
232 | +the script and with the extension `.cfg` (ignoring a `.pl` extension) so the | |
233 | +default config file would be `dyndns.cfg`. The behavior of how to support the | |
234 | +config file is configured through the variable `$ConfigFile` and can be one of: | |
235 | + * `optional` - config file is read if it exists, this is the default | |
236 | + * `required` - config file is read and must exist (or the script will fail) | |
237 | + * `ignore` - config file is ignored and not read, configuration in the script | |
238 | + | |
239 | +The general format of the config file is `keyword = value`, see the table below | |
240 | +for a mapping of the parameters to keywords. For lists (variables starting with | |
241 | +a `@`) the value is comma-separated. The config file supports comments, ignores | |
242 | +empty lines, starting/trailing spaces and everything following a `#`. Refer to | |
243 | +`dyndns.cfg.dist` for an example config file. Please note that the script will | |
244 | +fail if it encounters an error or unknown keyword in the config file. | |
245 | + | |
246 | +Parameter | Config Setting | Default value | |
247 | +:-----------------|:-------------------|:------------------------------ | |
248 | +`$AllowDebugKey` | `allow_debug_key` | `off` (debugging disabled) | |
249 | +`$AuthMode` | `auth_mode` | `remote` ([see below](#conf_auth)) | |
250 | +`$DeleteTXT` | `delete_txt` | `DynDNS cleared on` | |
251 | +`$DNSServer` | `dns_server` | `192.168.1.1` | |
252 | +`@DNSDomain` | `dns_domain` | `?, !, 0` ([see below](#conf_dnszone)) | |
253 | +`$DomainListKey` | `domain_list_key` | `off` (domain list disabled) | |
254 | +`$ExpandCNAMEs` | `expand_cnames` | `1` (1 level, [see below](#conf_cname)) | |
255 | +`$ExpireAfter` | `expire_after` | `1w` (1 week, [see below](#expire)) | |
256 | +`$RecordTTL` | `record_ttl` | `1h` (1 hour) | |
257 | +`$RequireRR` | `require_rr` | | |
258 | +`@ReplaceRR` | `replace_rr` | `A, AAAA, TXT` | |
259 | +`$StaticKey` | `static_key` | | |
260 | +`$StaticSigner` | `static_signer` | | |
261 | +`$UpdateTXT` | `update_txt` | `Last DynDNS update on` | |
262 | + | |
263 | +Please note that since `$ConfigFile` determines config file support, it cannot | |
264 | +be configured in the file. By default the config file is optional not to break | |
265 | +existing configurations. | |
266 | + | |
267 | + | |
268 | +#### <a name=conf_dnszone>DNS Zone (Domain Name) Selection</a> | |
269 | +In order to send the right update request to the DNS server, the correct DNS | |
270 | +zone to update must be determined based on the request's hostname. Most of the | |
271 | +time an update for `hostname.subdomain.mydomain.tld` is an update of `hostname` | |
272 | +the DNS zone `subdomain.mydomain.tld` and then the defaults are sufficient. | |
273 | +However, in some scenarios (e.g. one of my use cases) an update should be sent | |
274 | +for hostname `hostname.subdomain` in the zone `mydomain.tld` instead. The DNS | |
275 | +server cannot figure this out itself (at least ISC's Bind9 can not) so it is | |
276 | +implemented here. | |
277 | + | |
278 | +The array `@DNSDomain` contains a list of values matched against the hostname | |
279 | +to determine the DNS zone to update and can contain: | |
280 | + | |
281 | +Value | match hostname ending with | |
282 | +:----------------|:------------------------------------------------------- | |
283 | +`"?"` | the domain name from parameter `domain` | |
284 | +`"!"` | server name the HTTP(S) request was sent to | |
285 | +`0` | domain from hostname (strip of everythin till first `.`) | |
286 | +positive number | last # parts from hostname | |
287 | +negative number | last # parts of server name the HTTP(S) request was sent to | |
288 | +any other string | use value specified | |
289 | + | |
290 | +The first parameter matching the hostname's end will be used. The default is | |
291 | +`( '?', '!', 0 )`, which should be OK in most cases. | |
292 | + | |
293 | + | |
294 | +#### <a name=conf_cname>CNAME Support</a> | |
203 | 295 | The script supports using separate subdomain (e.g. dyndns.mydomain.tld) for |
204 | 296 | dynamic DNS and CNAMEs to entries in that subdomain from another zone (e.g. |
205 | 297 | mydomain.tld). The advantage of such a setup is that only one zone (SOA file) |
... | ... | @@ -212,17 +304,18 @@ the host provided is a CNAME and if so, performs the request for the actual |
212 | 304 | hostname instead of the provided one. The value of `$ExpandCNAMEs` determines |
213 | 305 | the maximum number of CNAME lookups supported (so nesting is allowed and this |
214 | 306 | limits the level of nesting to prevent loops). |
307 | + | |
215 | 308 | To disable lookups for CNAME expansion, set `$ExpandCNAMEs` to 0. |
216 | 309 | |
217 | 310 | |
218 | -#### Authentication Modes | |
311 | +#### <a name=conf_auth>Authentication Modes</a> | |
219 | 312 | For signing DNS update requests sent to the DNS server the script supports 3 |
220 | 313 | ways to obtain the signer and key: |
221 | 314 | |
222 | 315 | AuthMode | Description |
223 | -:--------+:--------------------------------------------------------------------- | |
316 | +:--------|:--------------------------------------------------------------------- | |
224 | 317 | *static* | use only static authentication information from `$StaticSigner` and`$StaticKey` (and ignore authentication information provided in the request) |
225 | -*remote* | use only authentication information provided in the request | |
318 | +*remote* | use only authentication information provided in the request | |
226 | 319 | *both* | use authentication information provided in the request (fields `user` and `secret`) when provided, otherwise use static values from `$StaticSigner` and `$StaticKey`. Please note that this is checked per parameter |
227 | 320 | |
228 | 321 | |
... | ... | @@ -230,51 +323,59 @@ Supported Operations |
230 | 323 | -------------------- |
231 | 324 | The script can perform the following operations (modes): |
232 | 325 | |
233 | -Mode | Description | Required Parameters | Optional Parameters | |
234 | -:------+:-------------------------+:--------------------+:---------------------- | |
235 | -list | Show DDNS domain entries | `domain`__**__ | | |
236 | -view | Show DDNS hostname entry | `host` | | |
237 | -update | Update/add a DDNS host | `host` + auth.__*__ | `ipv4addr`, `ipv6addr` | |
238 | -delete | Remove DDNS registration | `host` + auth.__*__ | | |
239 | -expire | Expire registrations | `domain`__**__ + auth.__*__ | |
326 | +Mode | Description | Required Parameters | Optional Parameters | |
327 | +:------|:-----------------------|:--------------------|:---------------------- | |
328 | +list | List zone __***__ | `secret` __***__ | `domain`__**__ | |
329 | +view | Show host's DNS entry | `host` | | |
330 | +update | Update/add a DDNS host | `host` + auth.__*__ | `ipv4addr`, `ipv6addr` | |
331 | +delete | Remove registration | `host` + auth.__*__ | | |
332 | +expire | Expire registrations | `domain`__**__ + auth.__*__ | |
240 | 333 | |
241 | -__*__ Modes that change registrations require authentication, depending on the | |
242 | - value of `$AuthMode` the parameters `user` and `secret` may be required | |
334 | +__*__ modes that change DNS require authentication, depending on the value of | |
335 | + `$AuthMode` the parameters `user` and `secret` may be required | |
243 | 336 | (`$AuthMode` *remote*) required or optional (`$AuthMode` *both*) |
244 | 337 | |
245 | 338 | __**__ in case `domain` is omitted, it will be determined using the `host` |
246 | - parameter, if provided | |
247 | - | |
248 | - | |
249 | -#### Parameters | |
250 | -The script supports the following parameters (please see the table above for which is needed for what mode): | |
251 | - | |
252 | -Parameter | Description | |
253 | -:---------+:-------------------------------------------------------------------- | |
254 | -`mode` | the action to perform (if not provided as part of the path name) | |
255 | -`domain` | domain for list/expire request, determined from `host` if ommitted | |
256 | -`host` | hostname to act on, expand CNAMEs max. `$ExpandCNAMEs` levels deep | |
257 | -`ip` | alias / shortcut for `ipv4addr` | |
258 | -`ipv4addr`| The IPv4 address to register for the host (update mode only) __*__ | |
259 | -`ipv6addr`| The IPv6 address to register for the host (update mode only) __*__ | |
260 | -`user` | signer of the DNS Update, used for `AuthMode` *remote* and *both* | |
261 | -`key` | key to sign the DNS Update, used for `AuthMode` *remote* and *both* | |
262 | -`debug` | debug key, show debug information if this equals `$AllowDebugKey` | |
263 | - | |
264 | -__*__ in update mode, if `ipv4addr` or `ipv6addr` is not provided with the | |
339 | + parameter, if provided, or by using the virtualhost the script runs on | |
340 | + based on the `@DNSDomain` setting | |
341 | + | |
342 | +__***__ list mode is only available when `$DomainListKey` is not set to `off`, | |
343 | + in case `$DomainListKey` is not empty, `secret` is required and must | |
344 | + equal the key in `$DomainListKey` | |
345 | + | |
346 | + | |
347 | +#### <a name=req_params>Request Parameters</a> | |
348 | +The script supports (requires) the following parameters (please see the table | |
349 | +above for which is needed for what mode): | |
350 | + | |
351 | +Parameter | Description | |
352 | +:----------|:------------------------------------------------------------------- | |
353 | +`mode` | the action to perform (if not provided as part of the path name) | |
354 | +`domain` | domain for list/expire request, determined from `host` if ommitted | |
355 | +`host` | hostname to act on, expand CNAMEs max. `$ExpandCNAMEs` levels deep | |
356 | +`ip` | alias / shortcut for `ipv4addr` | |
357 | +`ipv4addr` | The IPv4 address to register for the host (update mode only) __*__ | |
358 | +`ipv6` | alias / shortcut for `ipv6addr` | |
359 | +`ipv6addr` | The IPv6 address to register for the host (update mode only) __*__ | |
360 | +`user` | signer of the DNS Update, used for `AuthMode` *remote* and *both* | |
361 | +`secret` | key to sign the DNS Update, used for `AuthMode` *remote* and *both*, also used as `$DomainListKey` for list mode. | |
362 | +`debug` | debug key, show debug information if this equals `$AllowDebugKey` | |
363 | + | |
364 | +__*__ in update mode, if `ipv4addr` or `ipv6addr` is set to `auto` in the | |
265 | 365 | request, the CGI variable `$REMOTE_ADDR` (the client address), its value |
266 | - will be used instead as IPv4/IPv6 address. | |
366 | + will be used instead as IPv4/IPv6 address. __Please Note__ that if both | |
367 | + are omitted existing addresses will be removed! | |
267 | 368 | |
268 | 369 | |
269 | -#### <a name="invoking">Invoking the script</a> | |
370 | +#### <a name=invoking>Invoking the script</a> | |
270 | 371 | The script is implemented using the perl CGI module so for testing purposes it |
271 | 372 | can be called from the command line with parameters as arguments, i.e. |
272 | 373 | |
273 | 374 | ./dyndns.pl mode=expire domain=mydomain.tld debug=.... |
274 | 375 | |
275 | -Which is quite handy for debugging purposes. Please note that the Perl CGI | |
276 | -library sets `$REMOTE_ADDR` to 127.0.0.1 and that the output will always be | |
277 | -the HTML-based result. | |
376 | +Which is quite handy for debugging. Please note that the Perl CGI library sets | |
377 | +`$REMOTE_ADDR` to 127.0.0.1, the server name in this case will be `localhost` | |
378 | +and that the output is the HTML result. | |
278 | 379 | |
279 | 380 | The standard way to use the script is to place it in the cgi-bin folder your |
280 | 381 | server, which allows it to be called as: |
... | ... | @@ -295,14 +396,54 @@ When combining the setup would become: |
295 | 396 | |
296 | 397 | http://myserver.mydomain.tld/dyndns/list?domain=mydomain.tld&debug=... |
297 | 398 | |
399 | +If using a dedicated virtual host [see below](#VirtualHost) it becomes: | |
400 | + | |
401 | + http://myserver.mydomain.tld/list?domain=mydomain.tld&debug=... | |
402 | + | |
298 | 403 | Which is how I use it. |
299 | 404 | |
300 | 405 | |
406 | +### <a name=expire>Expiring Records</a> | |
407 | +The script can expire registrations after a while. For this, it must add a TXT | |
408 | +record containing the date of the last change (on by default) and when requested | |
409 | +it will remove any entry older than the value configured in `$ExpireAfter`. | |
410 | + | |
411 | +Please note that: | |
412 | + * as this is dependent on the value of a TXT record, it may fail if these | |
413 | + records are updated through another method. | |
414 | + * there is no security implemented (other than the value of `$ExpireAfter`) | |
415 | + | |
416 | +To initiate the expiry, the script must be called with two parameters: | |
417 | + 1. `mode` should be set to `expire` | |
418 | + 2. `domain` must be set to the DNS Zone (domain) to run against. | |
419 | + | |
420 | +Both can be setup easily in cron with entries like: | |
421 | + | |
422 | +~~~ | |
423 | +# Samples to run the expiry every hour | |
424 | + | |
425 | +# Cron fields definition: | |
426 | +#.---------------- minute (0 - 59) | |
427 | +#| .------------- hour (0 - 23) | |
428 | +#| | .---------- day of month (1 - 31) | |
429 | +#| | | .------- month (1 - 12) OR jan,feb,mar,apr ... | |
430 | +#| | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat | |
431 | +#| | | | | | |
432 | +#* * * * * user-name command to be executed | |
433 | + | |
434 | +# Directly run the script, does not require specific permissions | |
435 | +15 * * * * www-data [INSTALL_DIR]/dyndns.pl mode=expire domain=mydomain.tld | |
436 | + | |
437 | +# example using curl | |
438 | +15 * * * * www-data curl https://myserver.mydomain.tld/expire?domain=mydomain.tld > /dev/null | |
439 | +~~~ | |
440 | + | |
441 | + | |
301 | 442 | Name Server Setup Requirements |
302 | 443 | ------------------------------ |
303 | 444 | As the script is only translating requests, depends heavily on the setup of the |
304 | 445 | nameserver. The DNS server (obviously) needs to allow DNS updates. In addition |
305 | -to the setup described above, please note that: | |
446 | +to the setup described above, please note that: | |
306 | 447 | |
307 | 448 | * For the modes list and expire to work, the script needs to perform a DNS |
308 | 449 | zone transfer (AXFR). This must be allowed for the host running the script. |
... | ... | @@ -314,22 +455,191 @@ to the setup described above, please note that: |
314 | 455 | used Perl Net::DNS library). The keys setup in the nameservers must |
315 | 456 | therefore be of the same time or authentication won't work. |
316 | 457 | |
317 | -The solution scales reasonable well, although adding the keys to the nameserver | |
318 | -configuration is still manual in my setup (but since it does not happen that | |
319 | -often, it's no hassle). This setup has been tested against ISC Bind version 9. | |
320 | - | |
458 | +This setup has been tested against ISC Bind version 9 and scales pretty well. | |
459 | +Adding the keys to the nameserver configuration is still manual in my setup but | |
460 | +bit difficult script, if needed. | |
461 | + | |
462 | + | |
463 | +<a name=VirtualHost>Configure as Virtual Host</a> | |
464 | +------------------------------------------------- | |
465 | +Running dyndns.pl on a Virtual Host is possible using `mod_rewrite`. This is how | |
466 | +I use it as it allows the URLs to become even more simple, e.g.: | |
467 | + | |
468 | + * to update: `https://dyndns.mydomain.tld/update/hostname.mydomain.tld?secret=...` | |
469 | + * to delete: `https://dyndns.mydomain.tld/delete/hostname.mydomain.tld?secret=...` | |
470 | + * to view: `https://dyndns.mydomain.tld/view/hostname.mydomain.tld` | |
471 | + * to list: `https://dyndns.mydomain.tld/list/mydomain.tld?secret=...` | |
472 | + * to expire: `https://dyndns.mydomain.tld/expire/mydomain.tld` | |
473 | + | |
474 | +An example Apache 2.4 config is shown below (please replace `[INSTALL_DIR]` with | |
475 | +the install directory and obviously replace the server name as well): | |
476 | + | |
477 | +~~~ | |
478 | +<VirtualHost *:80 *:443> | |
479 | + ServerName dyndns.mydomain.tld | |
480 | + | |
481 | + # Enable URL Rewriting | |
482 | + RewriteEngine On | |
321 | 483 | |
322 | -<a name="license">License</a> | |
323 | ------------------------------ | |
324 | -This script, documentation and configration examples are free software: you can | |
484 | + # Enforce HTTPS access | |
485 | + RewriteCond %{HTTPS} off | |
486 | + RewriteRule / https://%{HTTP_HOST}%{REQUEST_URI} [R] | |
487 | + | |
488 | + # re-route everything to the dyndns script | |
489 | + RewriteRule (.*) /dyndns/$1 [PT] | |
490 | + | |
491 | + ScriptAlias /dyndns [INSTALL_DIR]/dyndns.pl | |
492 | + | |
493 | + <Directory [INSTALL_DIR]> | |
494 | + AllowOverride None | |
495 | + Options +ExecCGI -MultiViews | |
496 | + Require all granted | |
497 | + </Directory> | |
498 | + | |
499 | +</VirtualHost> | |
500 | +~~~ | |
501 | + | |
502 | + | |
503 | +<a name=integration>Integration with devices</a> | |
504 | +================================================ | |
505 | +Integration on routers and other devices is straigtforward, provided do support | |
506 | +DDNS registrations using a custom URL. The Basic format for the registration | |
507 | +URL to register is: | |
508 | + | |
509 | +~~~ | |
510 | +https://SERVER/cgi-bin/dyndns/update?host=HOSTNAME&ip=IPADDRESS&secret=KEY` | |
511 | +~~~ | |
512 | + | |
513 | +Check the [list of parameters supported](req_params) for all available options, | |
514 | +the above URL contains the absolute minimum where: | |
515 | + | |
516 | +Parameter | Value | |
517 | +:-----------|:--------------------------------------------------------------- | |
518 | +`SERVER` | is the host the script is installed on | |
519 | +`HOSTNAME` | is the client's hostname as configured in the DNS server | |
520 | +`SECRET` | is the secret key as configured in the DNS server | |
521 | +`IPADDRESS` | is the ipv4 address (often dynamic, can also be set to `auto`) | |
522 | + | |
523 | +Depending on how you have configured the URL of the script to be, the path | |
524 | +(`/cgi-bin/dyndns/` may need to be altered as per your setup). | |
525 | + | |
526 | +Please note that: | |
527 | + * The generated secret may contain a `+`, which must be encoded correctly in | |
528 | + the request or it will fail. I found that not all clients (e.g. a Fritz!Box) | |
529 | + do this correctly, make sure that your secrets either don't contain a `+` | |
530 | + or encode it manually (replace any `+` with `%2B` in that case). | |
531 | + * In case the IP address of the device is behind NAT and you want to have the | |
532 | + public address register, use the `auto` value for parameters `ip`/`ipv4addr` | |
533 | + and `ipv6`/`ipv6addr` to have the script auto-detect it (though that this | |
534 | + can only be used for either an IPv4 or an IPv6 address and will only work | |
535 | + for devices registering using that protocol!) | |
536 | + * Some devices have a preference to connect over IPv6 (e.g. Cisco routers). | |
537 | + This can be used to register the IPv4 and IPv6 addresses together by passing | |
538 | + the IPv4 address as parameter en setting the IPv6 parameter to `auto`. | |
539 | + * Some devices (e.g. a Fritz!Box) support a separate URL for IPv4 and IPv6 | |
540 | + registrations. Unfortunately this script cannot handle this yet and will | |
541 | + unregister a previous registration when the second request comes in. Please | |
542 | + raise a ticket if you have such a situation to work on a solution together. | |
543 | + | |
544 | +To check whether the client's registration was successful (and correct) visit: | |
545 | + | |
546 | +~~~ | |
547 | +https://SERVER/cgi-bin/dyndns/view?host | |
548 | +~~~ | |
549 | + | |
550 | + | |
551 | +<a name=cisco_integration>Cisco Routers</a> | |
552 | +------------------------------------------- | |
553 | +For Cisco routers add the following config: | |
554 | + | |
555 | +``` | |
556 | +ip ddns update method DYNDNS | |
557 | + HTTP | |
558 | + add https://SERVER/cgi-bin/dyndns/update?host=<h>&ip=<a>&secret=SECRET | |
559 | + remove https://SERVER/cgi-bin/dyndns/delete?host=<h>&secret=SECRET | |
560 | + interval maximum 0 1 0 0 | |
561 | +``` | |
562 | + | |
563 | +replacing `SERVER` for the host the script is installed on and `SECRET` | |
564 | +for a DNS key authorized to update the record. The cisco router will replace <a> | |
565 | +and <h> with the IPv4 address and hostname. | |
566 | + | |
567 | +To setup interface `Dialer0` to register as `hostname.dyndns.mydomain.tld` add: | |
568 | + | |
569 | +``` | |
570 | +interface Dialer0 | |
571 | + ip ddns update hostname hostname.dyndns.mydomain.tld | |
572 | + ip ddns update DYNDNS | |
573 | +``` | |
574 | + | |
575 | +Which instructs to register using the address of Dialer0 as soon as that is up | |
576 | +or changes (this also works for non-dialer devices). | |
577 | + | |
578 | +Please note that before entering the `?` as part of the URL, a `CTRL`-`V` is | |
579 | +required to prevent the Cisco CLI to list the available command parameters. | |
580 | + | |
581 | + | |
582 | +<a name=fritzbox_integration>AVM Fritz!Box routers</a> | |
583 | +------------------------------------------------------ | |
584 | +To setup DynDNS on a Fritz!Box perform the following steps: | |
585 | + * Login to your Fritz!Box as an admin user | |
586 | + * Open the 'Internet' menu an go through the 'External Access' page | |
587 | + * Open the 'DynDNS' tab | |
588 | + * Enable the 'Use DynDNS' checkbox | |
589 | + * Select DynDNS Provider: 'User-defined' | |
590 | + * Enter the following data (replacing `YOURDOMAIN` with your DynDNS domain | |
591 | + and `SERVER` with your server name - check the rest of the URL as well!) | |
592 | + - Update URL: `https://SERVER/cgi-bin/dyndns/update?host=<domain>&ip=<ipaddr>&secret=<pass>` | |
593 | + - Domain name: hostname setup in DNS | |
594 | + - Username/Email: put here something, not used unless you add it to the URL | |
595 | + - Password: secret key setup in DNS | |
596 | + * Click 'Apply' to store and activate the DDNS registrations | |
597 | + | |
598 | +Check [this page](https://service.avm.de/help/en/FRITZ-Box-7581/017p2/hilfe_dyndns) | |
599 | +for the available parameters that can be substituted in the URL. | |
600 | + | |
601 | +The status of the DynDNS registrations can be seen in the 'Internet' menu on the | |
602 | +'Online Monitor' page. | |
603 | + | |
604 | +To stop DynDNS registrations, uncheck 'Use DynDNS' from the same screen. | |
605 | + | |
606 | + | |
607 | +<a name=synology_integration>Synology DSM (NAS)</a> | |
608 | +--------------------------------------------------- | |
609 | +To setup DynDNS on a Synology NAS (DSM 6 or later) perform the following steps: | |
610 | + * Login to your Synology NAS DSM as an admin user | |
611 | + * Open the Control Panel and go to 'External Access' | |
612 | + * Click 'Customize' to add a new DDNS provider | |
613 | + * Enter the following data (replacing `YOURDOMAIN` with your DynDNS domain | |
614 | + and `SERVER` with your server name - check the rest of the URL as well!) | |
615 | + - Service Provider: `YOURDOMAIN` | |
616 | + - Query URL `https://SERVER/cgi-bin/dyndns/update?host=__HOSTNAME__&ip=__MYIP__&secret=__PASSWORD__` | |
617 | + * Click Save to store the custom DDNS provider | |
618 | + * Click Add to register the DDNS registration and enter: | |
619 | + - Service Provider: select the name you have just added (`*YOURDOMAIN`) | |
620 | + - Hostname: hostname setup in DNS | |
621 | + - Username/Email: put here something, not used unless you add it to the URL | |
622 | + - Password/Key: secret key setup in DNS | |
623 | + * Click 'OK' to store and activate the DDNS registrations | |
624 | + | |
625 | +After a while the screen should display that the status is Normal and when the | |
626 | +last update occurred. | |
627 | + | |
628 | +To stop DDNS registrations, 'Delete' the registration from the same screen. | |
629 | + | |
630 | + | |
631 | +<a name=license>License</a> | |
632 | +============================= | |
633 | +This script, documentation and configuration examples are free software: you can | |
325 | 634 | redistribute and/or modify it under the terms of the GNU General Public License |
326 | 635 | as published by the Free Software Foundation, either version 3 of the License, |
327 | 636 | or (at your option) any later version. |
328 | 637 | |
329 | -This script, documenatation and configuration examples are distributed in the | |
638 | +This script, documentation and configuration examples are distributed in the | |
330 | 639 | hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
331 | 640 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
332 | 641 | General Public License for more details. |
333 | 642 | |
334 | 643 | You should have received a copy of the GNU General Public License along with |
335 | 644 | this program. If not, download it from <http://www.gnu.org/licenses/>. |
645 | + | |
... | ... |