Skip to main content

ipsets fqdn resolving

 

 

Concept

  • Use a Sqlite3 database to store the list of entries that need to be updated.
  • A script run on an interval will perform lookups for each fqdn, no more frequent than the DNS record's TTL
    • next_lookup_dt is set after a lookup to the current time plus the lookup's ttl in seconds
      • UPDATE entries SET last_lookup_dt = datetime('now'), next_lookup_dt = datetime('now', '+$ttl seconds') WHERE fqdn=$fqdn and ipset=$ipset;
    • Query for a list of entries that need to be checked due to expired ttl of last lookup
      • SELECT * FROM entries WHERE next_lookup_dt <= datetime('now');

We have two options for dealing with changed IPs.

The first involves creating a new ipset, swapping it with the current in-memory set, and then destroying the old ipset.

The second involves locating and deleting the entry that needs to be updated.

 

Code

# CREATE the sqlite3 database and table(s)
sqlite3 /opt/ipsets-dynamic/ipsets-dynamic.db <<EOF
CREATE TABLE entries (
    fqdn TEXT NOT NULL,
    ipset TEXT NOT NULL,
    last_ip_address TEXT,
    last_lookup_dt DATETIME DEFAULT (datetime('now')),
    next_lookup_dt DATETIME DEFAULT (datetime('now')),
    last_change_dt DATETIME DEFAULT (datetime('now')),
    added DATETIME DEFAULT (datetime('now')),
    comment TEXT,
    PRIMARY KEY (fqdn, ipset)
);
EOF

 

Example

Assuming the ipset list exists as below:

ipset list unifisiteallowlist -output json | grep -v initval
# OUTPUT
[
  {
    "name" : "unifisiteallowlist",
    "type" : "hash:net",
    "revision" : 7,
    "header" : {
      "family" : "inet",
      "hashsize" : 1024,
      "maxelem" : 65536,
      "comment" : true,
      "bucketsize" : 12,
      "memsize" : 1800,
      "references" : 1,
      "numentries" : 10
    },
    "members" : [
      {
        "elem" : "1.2.3.4",
        "comment" : "resolve:some-fqdn.domain.com"
      },
   ]
  }
]
ipset list unifisiteallowlist -output json | grep -v initval | jq '.[].members[] | select(.comment | contains("resolve:some-fqdn.domain.com")) | .elem'
# OUTPUT
"1.2.3.4"