1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Firewall script with hostname?

Discussion in 'Tomato Firmware' started by hubbaloo, Apr 19, 2010.

  1. hubbaloo

    hubbaloo Addicted to LI Member

    Hi,
    I have a squeezebox network music player which I would like to connect to a server via the internet. The server is accessible by dynamic dns hostname, but the squeezebox only allows an IP address to be entered (open bug for years :().
    My idea was to map a custom IP address in the firewall to the server hostname

    Code:
    # firewall startup script
    DYN_IP=/usr/bin/nslookup xxx.dyndns.org
    iptables -I PREROUTING 1 -t nat -d 10.0.0.1 -j DNAT --to-destination DYN_IP
    1) The nslookup variable doesn't seem to work
    2) Perhaps this should be run as a cron script, every 2 days. Wouldn't the firewall have to be restarted each time though?

    The firewall entry works if the external IP is hardcoded, so the problem is trying to make it use a variable.

    Any ideas!
     
  2. mstombs

    mstombs Network Guru Member

    you need $(command) or `command` to assign result of an expression to a variable, but I think you can just put the hostname into iptables command, and it will be translated to IP address automatically, but yes you would have to re-start the firewall to update. You probably also need an entry in the FORWARD chain for a port forward.

    [edit] Maybe this has to be in WAN-UP, as there won't be a WAN connection to do the dns look-up in the firewall script?
     
  3. rhester72

    rhester72 Network Guru Member

    You can also substitute `nvram get wan_ipaddr` in WAN-UP.

    Rodney
     
  4. hubbaloo

    hubbaloo Addicted to LI Member

    It doesn't work putting the hostname straight into iptables. I've tried the below in the WAN Up section, but it doesn't work either.
    Code:
    DYN_IP=`/usr/bin/nslookup xxx.dyndns.org`
    iptables -I PREROUTING 1 -t nat -d 10.0.0.1 -j DNAT --to-destination $(DYN_IP)
    Also is there another way to restart iptables other than rebooting the router? I'm thinking later on when this script runs as a cron.
     
  5. SgtPepperKSU

    SgtPepperKSU Network Guru Member

    Have you taken a look at the output of nslookup? It's not just an IP address. You're plugging all sorts of junk into the iptables command.

    Try using the following instead:
    Code:
    iptables -I PREROUTING 1 -t nat -d 10.0.0.1 -j DNAT --to-destination `nslookup xxx.dyndns.org | grep "Address 1:" | tail -1 | cut -f 3 -d ' '`
    EDIT: Also, you can restart iptables with
    Code:
    service firewall restart
     
  6. hubbaloo

    hubbaloo Addicted to LI Member

    Yes of course, I hadn't considered the output of nslookup was incorrect. Thanks very much for your help.
     
  7. rhester72

    rhester72 Network Guru Member

    I would strongly advise against use of nslookup for this because you're depending on DNS propagation not being a race condition. The wan_ipaddr NVRAM variable will -always- be correct and current.

    Rodney
     
  8. SgtPepperKSU

    SgtPepperKSU Network Guru Member

    It will always be "correct" and current, but it is a completely different address than he is looking for...

    wan_ipaddr is the IP address of the WAN on this router, but he wants to DNAT to a completely different location, known only by a DNS name (or, at least that's how I've read his posts).
     
  9. rhester72

    rhester72 Network Guru Member

    Ohhhhhh...I thought he wanted his own public IP. Got it.

    Rodney
     
  10. hubbaloo

    hubbaloo Addicted to LI Member

    Exactly :smile:
     
  11. mstombs

    mstombs Network Guru Member

    It must be possible to parse the output of nslookup, but its much easier in c-code, here's an example which simply returns the first IP address gethostbyname returns, or nothing if the lookup fails. Not depending on what dns you use the return my be an OpenDNS or similar result.

    Code:
    #include <netdb.h>
    #include <stdio.h>
    #include <arpa/inet.h>
    
    int main(int argc, char **argv) {
        if (argc < 2) {
            printf ("Usage: %s hostname\n", argv[0]);
            return (-1);
        }
    
        struct hostent *hp = gethostbyname (argv[1]);
    
        if (hp == NULL) {
           printf("\n");
           return (-1);
        }
        
        printf( "%s\n", inet_ntoa ( *(struct in_addr*)hp->h_addr) );
        
        return (0);
    }

    Code:
    root@unknown:/tmp/home/root# x=$(./ipaddr www.linksysinfo.com)
    root@unknown:/tmp/home/root# echo $x
    67.215.66.132
    root@unknown:/tmp/home/root# x=$(./ipaddr www.linksysinfo)
    root@unknown:/tmp/home/root# echo $x
    92.242.140.13
    root@unknown:/tmp/home/root# x=$(./ipaddr fred)
    root@unknown:/tmp/home/root# echo $x
    
    root@unknown:/tmp/home/root#
    Would be even smaller if it could be added to busybox, attached a working binary compiled using teddy_bear K26 toolchain, which also works on teddy_bear K24 router
     

    Attached Files:

Share This Page