gclayburg / synology-diskstation-scripts

Update Synology DNS records from DHCP IP address reservation
169 stars 41 forks source link

Network Interface listed as device name #10

Closed WolfspiritM closed 8 years ago

WolfspiritM commented 8 years ago

Currently there is a hardcoded list of Network Interfaces checked to not store the network interface as hostname if the device doesn't provide one. On my Synology I have a bond and the network Interface name is called ovs_bond0 so I got a dns entry called "ovs_bond0" and I think that depends on if ovs is enabled or disabled, too.

As a fix I did the following: At the top I added ( in my case under ZonePath=):

NetworkInterfaces=",`ip -o link show | awk -F': ' '{printf $2","}'`"

Which results in a list like this depending on the setup: ,lo,sit0,eth0,eth1,ovs-system,ovs_bond0,docker0,docker4452410,

Then I changed the awk call to this:

awk -v YourNetworkName=$YourNetworkName -v RecordType=$1  -v StaticRecords=$2 -v adapters=$NetworkInterfaces

And removed the hardcoded list from the BEGIN block of the awk script.

Now I was thinking about people maybe having multiple machines for docker (for example) or having a system called ovs-system coincidentally. The main need of blocking that names is the dhcp-leases.log which stores devices like this: TIMESTAMP MAC IP HOSTNAME INTERFACE And if there is no hostname set for this device: TIMESTAMP MAC IP INTERFACE It would be easy to just add lines which contain more then 4 columns but I'm not sure if the following exists, too in some cases: TIMESTAMP MAC IP HOSTNAME (Interface is missing) So what I did is I changed the AWK script to add the line when the following is true:

  1. More then 4 Columns (no matter what the hostname is as with 4 columns we can be pretty sure that the interface would be the last one)
  2. Less then 4 Columns and Column 3 is not an Interfacename Also for anything else (static leases via dhcp-host) I removed that check as the interface is not contained in that line anyway. However I disallowed any name that is an asterisk (which is a placeholder) or empty in both cases.

The final AWK script I'm using:

    awk -v YourNetworkName=$YourNetworkName -v RecordType=$1  -v StaticRecords=$2 -v adapters=$NetworkInterfaces '
        BEGIN {
           # Set awks field separator
           FS="[\t =,]";
        }
        {IP=""} # clear out variables
        # Leases start with numbers. Don't use if column 4 is an Interface
        $1 ~ /^[0-9]/ {  if(NF>4 || index(adapters, "," $4 "," ) == 0) { IP=$3; NAME=$4; RENEW=86400 } } 
        # Static assignments start with dhcp-host
        $1 == "dhcp-host" {IP=$4; NAME=$3; RENEW=$5}
        # If we have an IP and a NAME (and if name is not a placeholder)
        (IP != "" && NAME!="*" && NAME!="") {
           split(IP,arr,".");
           ReverseIP = arr[4] "." arr[3] "." arr[2] "." arr[1];
           if(RecordType == "PTR" && index(StaticRecords, ReverseIP ".in-addr.arpa.," ) > 0) {IP="";}
           if(RecordType == "A" && index(StaticRecords, NAME "." YourNetworkName ".," ) > 0) {IP="";}
           # Print the last number in the IP address so we can sort the addresses
           # Add a tab character so that "cut" sees two fields... it will print the second
           # field and remove the first which is the last number in the IP address.
           if(IP != "" && NAME!="*" && NAME!="") {
               if (RecordType == "PTR") {print 1000 + arr[4] "\t" ReverseIP ".in-addr.arpa.\t" RENEW "\tPTR\t" NAME "." YourNetworkName ".\t;dynamic"}
               if (RecordType == "A") print 2000 + arr[4] "\t" NAME "." YourNetworkName ".\t" RENEW "\tA\t" IP "\t;dynamic"
           }
        }
    ' $DHCPAssigned| sort | cut -f 2- | uniq

P.S.: Also the static leases are saved in /etc/dhcpd/dhcpd-ovs_bond0-static.conf for me but as the script reads the dhcpd.conf, too, I didn't need to change anything. Is the call to eth0-static.conf really needed as both files contain the same data (at least in my bond0 case)?

Here is the final script: https://gist.github.com/WolfspiritM/a47aef594bef4498063f0d4db2140b34

gclayburg commented 8 years ago

This looks pretty good at first glance, Wolf. These changes look like a more robust fix to the static interface names.

I am still running DSM 5.2 and it looks like these changes will still work there. Could you generate a pull request? I'd like to test it out and merge it in if it works for me.

gclayburg commented 8 years ago

BTW, I think you are right about the reference to eth0-static.conf being unnecessary. I just put it in there after someone mentioned it helped them when running DSM 6.0. I didn't have any way to test it myself though. Since it is working for you with a different interface name, we should be able to remove it.

gclayburg commented 8 years ago

FYI - these changes are incorporated into the script. Nice work @WolfspiritM

WolfspiritM commented 8 years ago

Sorry that I haven't responded. I didn't see the dynamic network interface loading in the script so I just submitted a PR. This also fixes invalid hostnames :-)

P.S.: I'm on 6.1 and everything works fine.