OpenWrt Forum Archive

Topic: luci-app-ddns / ddns-scripts : I'm working on enhancements

The content of this topic has been archived between 23 Mar 2018 and 4 May 2018. Unfortunately there are posts – most likely complete pages – missing.

chris5560 wrote:

kpv,
never did a multi-wan setup.
As Bill said, you need a separate config for every single interface.
please try new scripts from trunk when packaged.

You'd only need to assure that any ddns client outgoing traffic created by wget/curl comes out of a specific wan interface (specified either by device name e.g. eth0.2 or by IP). E.g. OpenWrt's ping has the -I option: ping -I eth0.3 ...

Check http://wiki.openwrt.org/doc/howto/mwan3 … ace.source

Apparently the syntax is:
wget --bind-address=192.168.1.1 http://somewhere.com
curl --interface 192.168.1.1 --ipv4 http://somewhere.com

With the proliferation of 3g/4g I think that "dual-WAN" will be quite popular among "pro-sumers" (i.e. sophisticated consumers), let alone pros, as a xDSL backup option.

No, there is no garantie that wget/curl send via the interface the address belongs to.
For DDNS-Provider it makes no difference, except the the ddns provider reads your ip instead the parameter inside update url.
There are no --bind-address/--interface parameter inside scripts.
If using fallback configuration use Example 1 out of mwan3 docu, use ip_source "web"
why do you need to force that the IP is send over the interface the IP comes from ?

chris5560 wrote:

why do you need to force that the IP is send over the interface the IP comes from ?

Multi-WAN apps do connection-balancing, i.e. try to spread Web traffic over all WANs to increase overall throughput.

So, unless one can "bind" ddns-scripts curl/wget to a specific interface/IP, one can't have a specific dyndns name for each WAN.

mwan3 balance trafic outbound (inside to outside). If you need it inbound you need a different technology.
So every "outside" interface has it's own external IP ? If yes then you need:

config service "ddns_eth0"
  option interface "wan_0"
  option ip_source "network"
  option ip_network "wan_0"
  ...

config service "ddns_eth1"
  option interface "wan_1"
  option ip_source "network"
  option ip_network "wan_1"
  ...

config service "ddns_ethx"
  option interface "wan_x"
  option ip_source "network"
  option ip_network "wan_x"

The detection of interfaces ip is done by reading the address of the specified network/interface not by saying wget/curl which interface to use.
So having 3 interfaces you will have 3 configurations, possibly 3 external names ? If you want to loadbalance inbound there a two ways,
DNS is doing it. Test nslookup google.com multiple times, you will see changing ip's in the first position.
Or one server with one ip deciding to which internal box the traffic is forwarded.
For a pure backup solution you need to configure only one ddns configuration
Interfaces eth0 to ethx only one will be active (ifup) then they all belong to the same network!

config service "ddns"
  option interface "wan"
  option ip_source "web"
  option ip_url "http://checkip.dyndns.com" or "http://checkipv6.dyndns.com" for IPv6

this only works if only one interface is up at a time or it's garanted the whole traffic is going one interface (incl ddns-scripts)

Hi, am not sure if this is the correct place to post this, but here ya go...

I use dnsomatic.com, and my username is an email address, say: david@widgets.name (nb: .name, not .com)

When I do the following, it doesn't work:

root@my-router:~# /usr/lib/ddns/dynamic_dns_updater.sh dyndns0

 ************** =: ************** ************** **************
        STARTED =: PID '2632' at 2014-09-30 09:10
sh: 1: unknown operand
   verbose mode =: '1' - run normal, console mode
     UCI CONFIG =:
ddns.dyndns0.check_interval=10
ddns.dyndns0.check_unit=minutes
ddns.dyndns0.domain=my-router.no-ip.org
ddns.dyndns0.enabled=1
ddns.dyndns0.force_interval=72
ddns.dyndns0.force_unit=hours
ddns.dyndns0.interface=wan
ddns.dyndns0.ip_source=web
ddns.dyndns0.ip_url=http://myip.dnsomatic.com/
ddns.dyndns0.password=password
ddns.dyndns0.service_name=dnsomatic.com
ddns.dyndns0.username=david@widgets.name
ddns.dyndns0=service
 check interval =: 600 seconds
 force interval =: 259200 seconds
 retry interval =: 60 seconds
  retry counter =: 5 times
 old process id =: PID 'none'
    last update =: never
        waiting =: 10 seconds for interfaces to fully come up
 ******* DETECT =: Registered IP
  resolver prog =: nslookup my-router.no-ip.org  2>/dev/null
    resolved ip =: '172.27.0.1'
 *** START LOOP =: 2014-09-30 09:10
 ******* DETECT =: Local IP
  transfer prog =: /usr/bin/curl --noproxy '*' -q 'http://myip.dnsomatic.com/' 2>/dev/null
       local ip =: '12.99.39.133' detected via web at 'http://myip.dnsomatic.com/'
 ******* UPDATE =: LOCAL: '12.99.39.133' <=> REGISTERED: '172.27.0.1'
  transfer prog =: /usr/bin/curl --noproxy '*' -q 'http://david@widgets.name:password@updates.dnsomatic.com/nic/update?hostname=my-router.no-ip.org&myip=12.99.39.133' 2>/dev/null

!!!!!!!!! ERROR =: cURL Error '6'
* Couldn't resolve host 'widgets.name'
curl: (6) Couldn't resolve host 'widgets.name'

However, when I do this, it does work:

/usr/bin/curl --noproxy '*' --user david@widgets.name:password -q http://updates.dnsomatic.com/nic/update?hostname=db-router.no-ip.org&myip=12.99.39.133'

(Last edited by zxdavb on 30 Sep 2014, 19:03)

Please try to replace the @ inside your email address with %40 and give me a feedback if this fix the problem.
Thanks
Christian

chris,

As I wrote in the recent past, it'd be most helpful for those of us with multiple WANs (typically one ADSL with 3g backup) if ddns-scripts was be able to differentiate between the two WANs.

A quick check suggests there's an easy way to invoke wget/curl with a WAN's ip e.g.:

wget --bind-address=$(. /lib/functions/network.sh; network_get_ipaddr ip wan; echo $ip) http://somewhere.com

Br, KP

(Last edited by kpv on 30 Sep 2014, 15:45)

Hi,
because the overall minimum is BusyBox's Wget, the --bind-address parameter is not the solution.
Here some questions for my understanding:
- if you configure ADSL with 3G backup are both interfaces "UP" or only "WAN" connected via one of them ?
- If both interfaces are "UP" each of them has a seperate IP?
- Do you want to have both addresses registered at DDNS provider, or only the one doing the traffic ?

Thanks for your support to find a solution.
Christian

chris5560 wrote:

Hi,
because the overall minimum is BusyBox's Wget, the --bind-address parameter is not the solution.
Here some questions for my understanding:
- if you configure ADSL with 3G backup are both interfaces "UP" or only "WAN" connected via one of them ?
- If both interfaces are "UP" each of them has a seperate IP?
- Do you want to have both addresses registered at DDNS provider, or only the one doing the traffic ?

I understand that the limited wget supplied as part of busybox doesn't allow to bind to a specific address, but the "full" version of both wget and curl do.

Regarding your other questions:
- Both interfaces (wan, wan2) will be "up" all the time
- Each interface (wan, wan2) has a separate IP.
- Both addresses need to be registered (each with its own fqdn obviously) at the DDNS provider

Btw I did some very quick tests and it seems that even when invoking wget with "-bind-address" I'd still need to create a mwan3 policy route for this scenario to work ...

chris5560 wrote:

Please try to replace the @ inside your email address with %40 and give me a feedback if this fix the problem.
Thanks
Christian

Hey thanks for your quick response.  Yes, using %40 seems to fix the problem!

This is true either by executing the script directly:

/usr/bin/curl --noproxy '*' -q 'http://david%40widgets.name:password@updates.dnsomatic.com/nic/update?hostname=my-router.no-ip.org&myip=12.99.39.133'

...or via UCI:

uci set ddns.dyndns0.username=david%40widgets.name
uci commit
/usr/lib/ddns/dynamic_dns_updater.sh dyndns0

In both cases, I see: good 12.99.39.133

Can I humbly suggest your script either utilize the --user option, or parse the ddns.XXXX.username parameter and substitute any @ with %40, rather than require the user to do what I have done (i.e. do the @/%40 swap myself)?  I think to have to do so is a bit counter-intuitive. 

In the meantime, I have a workaround, thanks!

(Last edited by zxdavb on 30 Sep 2014, 19:01)

Hi zxdavb,
it's not my plan letting the user do the replace.
I had an idea where to look at and this was the test if I'm on the right way before creating a patch.
Will be implemeted in ddns-scripts 2.0.1-6 (so the plan ;-)
Many thanks for testing.
Christian

Hi kpv,
could you please provide me your /etc/config/ddns (except USERNAME and PASSWORD).
Thanks
Christian

chris5560 wrote:

Hi zxdavb,
it's not my plan letting the user do the replace.
I had an idea where to look at and this was the test if I'm on the right way before creating a patch.
Will be implemeted in ddns-scripts 2.0.1-6 (so the plan ;-)
Many thanks for testing.
Christian

Thanks Christian

chris5560 wrote:

Hi kpv,
could you please provide me your /etc/config/ddns (except USERNAME and PASSWORD).

Hi, this was my ddns config, which I created according to the mwan3 wiki page but before actually checking the ddns code:

root@OpenWrt:/etc/config# cat ddns
config service 'xyz1'
   option enabled '0'
   option interface 'wan'
   option check_interval '10'
   option check_unit 'minutes'
   option domain 'xyz1.mooo.com'
   option force_interval '24'
   option force_unit 'hours'
   option service_name 'freedns.afraid.org'
   option username 'xyz1'
   option password 'secret'
   #option ip_source 'network'
   #option ip_network 'wan'
   option ip_source 'interface'
   option ip_interface 'eth0.2'

config service 'xyz2'
   option enabled '0'
   option interface 'wan2'
   option check_interval '10'
   option check_unit 'minutes'
   option domain 'xyz2.mooo.com'
   option force_interval '24'
   option force_unit 'hours'
   option service_name 'freedns.afraid.org'
   option username 'xyz2'
   option password 'secret'
   #option ip_source 'network'
   #option ip_network 'wan2'
   option ip_source 'interface'
   option ip_interface 'eth0.3'

root@OpenWrt:/etc/config#

Hi,
basicly no config could start because option enabled '0'; to enable them they need to be option enabled '1'.
There are known problems with updating freedns.afraid.org already with the old scripts (1.0.0-x) without current solution.
Are there any errors in the log file at /var/log/ddns/[section].log ?

Obviously I had enabled them while doing the testing, sorry for not being clear enough about it. There were no errors, but the ddns fqdn would switch randomly from one to the other every few minutes.

Anyway, I did some testing earlier today, and it seems that I need both wget-full (which allows binding to an IP) and mwan3 policy route(s) in order for it to work as described in post #89 (note: ideally I'd like to utilize ipsets which mwan3 doesn't support yet afaik).

What do you meen with "ddns fqdn" switch randomly ?
Please enable only one section of your config and tell me if the detected/registered IP changes ?
Did ddns fqdn continue to change ?

Be carefully with looking for the right registered IP after sending an update out to ddns provider.
I ran a loop on my router during script testing only doing nslookup for my fqdn using Googles public dns 8.8.8.8.
It takes up to five minutes until I get a stable answer after sending a new IP to my provider.

Did you check the error log at freedns.afraid.org?
Normally there should be one for your account telling you if there were problems with your updates.

Please have a look into the ddns-scripts logs if the detection of local and registered IP works correct or are there IP toggles.

chris5560 wrote:

Hi zxdavb,
it's not my plan letting the user do the replace.
I had an idea where to look at and this was the test if I'm on the right way before creating a patch.
Will be implemeted in ddns-scripts 2.0.1-6 (so the plan ;-)
Many thanks for testing.
Christian

Hi,

If I have uci set ddns.dyndns0.username=david@widgets.name, I now get success:

transfer prog =: /usr/bin/curl --noproxy '*' -q 'http://david%40widgets.name:password@updates.dnsomatic.com/nic/update?hostname=db-router.no-ip.org&myip=12.99.39.133' 2>/dev/null

But (just so you know), when it was uci set ddns.dyndns0.username=david%40widgets.name, I got:

transfer prog =: /usr/bin/curl --noproxy '*' -q 'http://david%2540widgets.name:password%40updates.dnsomatic.com/nic/update?hostname=db-router.no-ip.org&myip=12.99.39.133' 2>/dev/null

Which didn't work.

(Last edited by zxdavb on 3 Oct 2014, 14:39)

Hi Chris,

there is an issue that I am getting after doing a sysupgrade. I don't know if you'd care to look at it...

Before the sysupgrade, it's all good:

root@db-router:/# ls /etc/rc.d | grep ddns
S95ddns
root@db-router:/#

After the sysupgrade, I have to remember to re-enable ddns:

root@db-router:/# ps -w | grep ddns
 2344 root      1356 S    grep ddns
root@db-router:/# ls /etc/rc.d | grep ddns
root@db-router:/# /etc/init.d/ddns enable
root@db-router:/# /etc/init.d/ddns start
root@db-router:/# ps -w | grep ddns
 1930 root      1468 S    {dynamic_dns_upd} /bin/sh /usr/lib/ddns/dynamic_dns_updater.sh dyndns0 0
 1931 root      1468 S    {dynamic_dns_upd} /bin/sh /usr/lib/ddns/dynamic_dns_updater.sh opendns 0
 2346 root      1356 S    grep ddns
root@db-router:/# ls /etc/rc.d | grep ddns
S95ddns
root@db-router:/#

(Last edited by zxdavb on 2 Oct 2014, 17:27)

Is the "," (comma) at the end really part of your username ?
Are you already using 2.0.1-6 ? It was released yesterday.
run opkg update and opkg list | grep ddns-scripts to check if it's already compiled for your hardware.
the "@" AFTER password should not be replaced.
The correct uci command is uci set ddns.dyndns0.username='david%40widgets.name' or in 2.0.1-6 with the @-sign.
Don't forget the single qoutes around the value behind the "=" if using uci set command.

ddns-scripts are not enabled by default. after install or sysupgrade you need to enable it again.
As I know sysupgrade also delete everything inside /etc/rc.d directory and reinstall/enable only basics.
For me this make sence because it's not a basic service that is required after a sysupgrade.
After a sysupgrade the "Adminstrator" has to check every single service if it is working correctly step by step, So enable and start and check ;-)

(Last edited by chris5560 on 2 Oct 2014, 17:45)

chris5560 wrote:

Is the "," (comma) at the end really part of your username ?
Are you already using 2.0.1-6 ? It was released yesterday.
run opkg update and opkg list | grep ddns-scripts to check if it's already compiled for your hardware.
the "@" AFTER password should not be replaced.
The correct uci command is uci set ddns.dyndns0.username='david%40widgets.name' or in 2.0.1-6 with the @-sign.
Don't forget the single qoutes around the value behind the "=" if using uci set command.

ddns-scripts are not enabled by default. after install or sysupgrade you need to enable it again.
As I know sysupgrade also delete everything inside /etc/rc.d directory and reinstall/enable only basics.
For me this make sence because it's not a basic service that is required after a sysupgrade.
After a sysupgrade the "Adminstrator" has to check every single service if it is working correctly step by step, So enable and start and check ;-)

Hi, Christian,

Ignore, the, comma, sorry, I, wasn't, very, clear!

Yes, definitely using 2.0.1-6 (I've got my own buildroot):

root@db-router:/# opkg list-installed | grep ddns
ddns-scripts - 2.0.1-6
luci-app-ddns - svn-r10533-1

[EDIT]

Sorry, just noticed a transcription error in my original post (that I have now corrected), it should have read: http://david%2540widgets.name:password%40updates.dnsomatic.com/nic/update

...and not: http://david%40widgets.name:password%2540updates.dnsomatic.com/nic/update

What the script seems to be doing is scanning david%40widgets.name, and substituting %25 for % (i.e. the hex ascii value of the % character), and so turning %40 into %2540.  Looking at the __urlencode function in your code, I wonder if % should be added to the list of exceptions?

For me, it's not a problem either way (2.0.1-6 works perfectly with @).  However, if using %40 instead of @ is standard practice, then I just thought you might like to know...

Oddly, after a sysupgrade, the tinyproxy package (if installed) is in rc.d by default (I note polipo isn't), but ddns is not!  I would have thought id tinyproxy is good enough to be in rc.d, then so should ddns-scripts (in fact, more so for ddns).

Dave

(Last edited by zxdavb on 3 Oct 2014, 14:44)

Hi Dave,
if using 2.0.1-6 or later you have to put back in the @ into the email/username.
This is the way it should work because doku says "put in your email into the username field" or something like that.
The %40 was only a quick fix. So 2.0.1-6 is now working well.

I personally hate auto enable what I have not configured before usage.
I've a long time experiance with sysupgrades and rollouts for up to 1000 user systems.
Nobody knows your configuration, so why auto enable whatever before you not setup the configuration files ?

Christian

(Last edited by chris5560 on 3 Oct 2014, 15:23)

Hi Chris,

Yes, the latest change has sorted out my problem.  Also, thanks for taking the time to answer my question about auto starting ddns-scripts...

My thinking was that it's reasonable to auto enable the startup of the ddns client (i.e. /etc/init.d/ddns in /etc/rc.d/), and then leave it to decide (via ddns.XXXXX.enabled=1) whether to have the scripts running in the background, or not. 

Clearly some /etc/init.d/XXX scripts should be in rc.d by default, and some shouldn't.  In this case, I do think that /etc/init.d/ddns is important enough to be so, given that it was installed (i.e. it's not a default package).  However, I am not experienced enough to comment upon the wider implications of doing so...

However, if there's no scripts running, then what's the downside?  It's hardly going to consume CPU/memory unless enable=1...

It's a bit like fstab starting automatically, mounting whatever, then exiting. 

My specific grief is that if it's enabled before a sysupgrade, then it should be certainly remain enabled after an upgrade, and that's the fault of sysupgrade, I guess. I will have a look at the code & take a view...

I will find out how tinyproxy was doing it, cause I could then just make that change to my buildroot...

Dave

(Last edited by zxdavb on 3 Oct 2014, 16:40)

Dave,
inside buildroot you can create a directory called files. inside this directory you can put all your custom files overwriting the existing or doing adds. Inside there you could add i.e. ./files/etc/uci-defaults/ddns-enable with the following content:

#!/bin/sh
[ -f /etc/init.d/ddns ] && /etc/init.d/ddns enable

All files inside /etc/uci-defaults are running nearby first during boot (before starting any services and will be deleted if they exit with exit code 0.
Exit code not 0 will not remove the file and will run it on next boot again.
You find more details in OpenWrt Wiki.
Christian

Hi Chris,

More trouble I'm afraid.  I am not sure if my configuration is unusual, or not; but maybe it's a realistic use-case, so I'll leave it to you if you wanted to think about it or not...

I use ddns-scripts to manage two domains with dnsomatic.com, both appear to be failing to update, each in a different way.  They worked well with the old version of ddns-scripts.

The first is db-network.local (NB: TLD is .local), which ultimately ends up at opendns.com:

Fri Oct  3 21:37:38 2014 user.crit ddns-scripts[1539]: opendns: CRITICAL ERROR - can not detect registered local IP - EXITING

If I run /usr/lib/ddns/dynamic_dns_updater.sh opendns 3 then I get (partial output):

 ******* DETECT =: Registered IP
  resolver prog =: nslookup db-network.local  2>/dev/null

!!!!!!!!! ERROR =: BusyBox nslookup Error '1'
Server:    127.0.0.1
Address 1: 127.0.0.1 localhost

nslookup: can't resolve 'db-network.local': Name or service not known

!!!!!!!!! ERROR =: detecting Registered IP - NO retry
!!!!!!!!! ERROR =: Registered IP <> Local IP - LocalIP: '78.150.0.240' - RegisteredIP: '' - NO retry

The second is db-router.no-ip.org, which ultimately ends up at no-ip.org:

Fri Oct  3 22:22:49 2014 user.crit ddns-scripts[1538]: dyndns0: CRITICAL ERROR - Registered IP <> Local IP - LocalIP: '78.150.0.240' - RegisteredIP: '172.27.0.1' - EXITING

If I run /usr/lib/ddns/dynamic_dns_updater.sh dyndns0 3 then I get (partial output):

 ******* DETECT =: Local IP
  transfer prog =: /usr/bin/curl --noproxy '*' -q 'http://myip.dnsomatic.com/' 2>/dev/null
       local ip =: '78.150.0.240' detected via web at 'http://myip.dnsomatic.com/'
   VERBOSE MODE =: NO UPDATE send to DDNS provider
   VERBOSE MODE =: NO WAITING for Check Interval

 ******* DETECT =: Registered IP
  resolver prog =: nslookup db-router.no-ip.org  2>/dev/null
    resolved ip =: '172.27.0.1'

!!!!!!!!! ERROR =: Registered IP <> Local IP - LocalIP: '78.150.0.240' - RegisteredIP: '172.27.0.1' - NO retry

NB: the OpenWrt router is configured as follows (so that internal clients resolve to a RFC1918 address, whilst external clients get a public address):

root@db-router:~# uci show dhcp | grep cname
dhcp.@cname[0]=cname
dhcp.@cname[0].cname=db-router.no-ip.org
dhcp.@cname[0].target=db-router.widgets.lan

root@db-router:~# cat /tmp/hosts/dhcp
# auto-generated config file from /etc/config/dhcp
172.27.0.1 db-router

root@db-router:~# cat /var/etc/dnsmasq.conf | grep domain=
domain=widgets.lan

For your reference, the configuration is as follows:

root@db-router:~# cat /etc/config/ddns

config service 'dyndns0'
        option enabled '1'
        option service_name 'dnsomatic.com'
        option interface 'wan'
        option ip_source 'web'
        option ip_url 'http://myip.dnsomatic.com/'
        option domain 'db-router.no-ip.org'
        option password 'password'
        option force_interval '72'
        option force_unit 'hours'
        option check_interval '10'
        option check_unit 'minutes'
        option username 'david@widgets.name'

config service 'opendns'
        option enabled '1'
        option service_name 'dnsomatic.com'
        option interface 'wan'
        option ip_source 'web'
        option ip_url 'http://myip.dnsomatic.com/'
        option domain 'db-network.local'
        option password 'password'
        option check_interval '10'
        option check_unit 'minutes'
        option force_interval '72'
        option force_unit 'hours'
        option username 'david@widgets.name'

(Last edited by zxdavb on 4 Oct 2014, 11:29)

Sorry, posts 101 to 100 are missing from our archive.