Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

ufw dymanic updater

ufw

ufw commands

ufw status numbered

install prereqs

sudo apt-get install dnsutils

data files

$ cat /var/tmp/ufw-dynamic-ips.allow
yourdynamichost.selfip.com:1.2.3.4
 
$ ls /var/tmp/ufw-dynamic-ips.allow
-rw-r--r-- 1 root root 42 Oct 27 12:35 /var/tmp/ufw-dynamic-ips.allow

$ cat /etc/ufw-dynamic-hosts.allow
tcp:22:yourdynamichost.selfip.com:your_comment_here

script

$ cat /usr/local/sbin/ufw-dynhostupdate.sh
#!/bin/bash

start=$(date +"%Y-%m-%d %T")

HOSTS_ALLOW=/etc/ufw-dynamic-hosts.allow
IPS_ALLOW=/var/tmp/ufw-dynamic-ips.allow

add_rule() {
  local proto=$1
  local port=$2
  local ip=$3
  local comment=$4

  local regex="${port}\/${proto}.*ALLOW.*IN.*${ip}"
  local rule=$(/usr/sbin/ufw status numbered | grep $regex)
  if [ -z "$rule" ]; then
      /usr/sbin/ufw allow proto ${proto} from ${ip} to any port ${port} comment "${comment}"
      echo "${start} ADDED: ${proto} from ${ip} to any ${port} comment '${comment}'"
  else
        echo "${start} EXISTS: ${proto} ${ip} to ${port} (${comment})"
  fi
}

delete_rule() {
  local proto=$1
  local port=$2
  local ip=$3
  local comment=$4

  local regex="${port}\/${proto}.*ALLOW.*IN.*${ip}"
  local rule=$(/usr/sbin/ufw status numbered | grep $regex)
  if [ -n "$rule" ]; then
        /usr/sbin/ufw delete allow proto ${proto} from ${ip} to any port ${port}
        echo "${start} DELETED: ${proto} ${ip} to ${port} (${comment})"
  else
        echo "${start} NO DELETE: rule does not exist"
  fi
}


sed '/^[[:space:]]*$/d' ${HOSTS_ALLOW} | sed '/^[[:space:]]*#/d' | while read line
do
    proto=$(echo ${line} | cut -d: -f1)
    port=$(echo ${line} | cut -d: -f2)
    host=$(echo ${line} | cut -d: -f3)
    comment=$(echo ${line} | cut -d: -f4)

    if [ -f ${IPS_ALLOW} ]; then
      old_ip=$(cat ${IPS_ALLOW} | grep ${host} | cut -d: -f2)
    fi

    ip=$(dig +short $host | tail -n 1)

    if [ -z ${ip} ]; then
        if [ -n "${old_ip}" ]; then
            delete_rule $proto $port $old_ip
           # echo "${start} ${proto} ${port} ${old_ip} removed"
        fi
        echo "${start} FAIL: Failed to resolve the ip address of ${host}." 1>&2
        exit 1
    fi

    if [ -n "${old_ip}" ]; then
        if [ ${ip} != ${old_ip} ]; then
            delete_rule $proto $port $old_ip $comment
        fi
    fi
    add_rule $proto $port $ip $comment
    if [ -f ${IPS_ALLOW} ]; then
      sed -i.bak /^${host}*/d ${IPS_ALLOW}
    fi
    echo "${host}:${ip}" >> ${IPS_ALLOW}
done

crontab

$ crontab -l
*/5 * * * * /usr/local/sbin/ufw-dynhostupdate.sh >/dev/null 2>&1
# or if you want to log the changes that happen/don't happen:
*/5 * * * * /usr/local/sbin/ufw-dynhostupdate.sh >>/var/log/ufwdynhost.log 2>&1

$ cat /var/log/syslog | grep CRON
Oct 28 09:10:01 rubysash CRON[11113]: (root) CMD (/usr/local/sbin/ufw-dynhostupdate.sh >/dev/null 2>&1)