Jamyy's Weblog

BASH: 從 dhcpd.leases 揪出不明連線裝置

by Jamyy on 九月.28, 2016, under Coding, Linux

監視 dhcpd.leases 記錄, 若發現不明裝置的連線記錄則 email 通知
環境: CentOS 6, ISC DHCP service (dhcpd)

建立工作路徑
$ mkdir ~/check_dhcpd_lease
$ cd $_

編輯已知設備清單
$ vi known_devices.txt

# mac address [(space or tab) device name]
0a:0b:0c:ab:cd:ef 老爸的手機
01:02:03:1a:2b:3c 老爸的筆電
03:04:05:11:22:33 老媽的手機
00:11:22:dd:ee:ff 智慧插座
0d:0e:0f:2a:2b:2c 電視棒

取得最新 IEEE OUI 清單
$ wget http://standards.ieee.org/regauth/oui/oui.txt
註: OUI 是 MAC address 的一部分, 用以識別設備廠牌、製造商

編輯 Shell Script: 若 dhcpd.leases 出現不在 known_devices.txt 裡面的 MAC address 就發信通知
$ vi check_dhcpd_lease.sh && chmod +x $_

#!/bin/bash

BASEPATH=~/check_dhcpd_lease
OUI_DB=$BASEPATH/oui.txt
KNOWN_DEV=$BASEPATH/known_devices.txt
QUEUE=$BASEPATH/waiting_for_checking.txt
LEASE_DB=/var/lib/dhcpd/dhcpd.leases

if [ ! -e $QUEUE ]; then
   touch $QUEUE
elif [ $(cat $QUEUE | wc -l) -gt 0 ]; then
   sort $QUEUE | uniq | awk '{print $NF}' | tr -d \; | while read i; do
      if [ -z "$(grep $i $KNOWN_DEV)" ]; then

         # MAC address 剔除冒號、小寫轉大寫、取出前六碼, 比對 oui.txt 取出製造商資訊
         OUI=$(echo $i | tr -d : | tr "[a-f]" "[A-F]" | egrep -o "^[0-9A-F]{6}")
         VENDOR=$(grep $OUI $OUI_DB | cut -f 3)

         # 以 MAC address 字串所在列號 (C) 為基礎點, 找出與 lease 開頭字串相隔列數 (B)、與結尾大括弧相隔列數 (A), 用以取得整段 dhcpd.leases 內容 (LEASE_TXT)
         C=$(grep -n $i $LEASE_DB | tail -n 1 | cut -d : -f 1)
         B=$(head -n $C $LEASE_DB | tac | grep -n ^lease | head -n 1 | cut -d : -f 1)
         A=$(tail -n +$C $LEASE_DB | grep -n "}" | head -n 1 | cut -d : -f 1)
         LEASE_TXT=$(tail -n +$((C-B)) $LEASE_DB | grep -B $((--B)) -A $((--A)) $i | sed 's/\\/\\\\/g' | sed 's/$/\\n/g')

         # 取出租約起始時間、結束時間 (UTC時間), 用來轉成當地時間
         TIME_START=$(echo -e $LEASE_TXT | grep starts | tr -d \; | awk '{print $3,$4}')
         TIME_END=$(echo -e $LEASE_TXT | grep ends | tr -d \; | awk '{print $3,$4}')

         # 組合相關資訊為信文內容, 寄給指定收件者
         # date --date "UTC時間+0" 可將 UTC時間 轉成 當地時間
         (echo "$i ($VENDOR)"; echo; echo -n starts\ ; date '+%Y/%m/%d %H:%M:%S' --date "$TIME_START+0"; echo -n ends\ ; date '+%Y/%m/%d %H:%M:%S' --date "$TIME_END+0"; echo; echo -e $LEASE_TXT) | mail -s "Warning: Unknown Device" myaccount@gmail.com

         # 將查獲的不明裝置 MAC address 寫入 known_devices.txt, 避免重複通知
         echo -e "$i\tunknown($VENDOR)" >> $KNOWN_DEV

      fi
   done
   true > $QUEUE
fi

建立一個 Screen session
$ screen

監視、收集 dhcpd.leases 裡面的 hardware ethernet (MAC address) 資訊
$ while [ true ]; do tail -F /var/lib/dhcpd/dhcpd.leases | grep --line-buffered "hardware ethernet" >> waiting_for_checking.txt; done
註: 以無窮迴圈包住, 避免意外中斷

脫離 Screen session
ctrl + a, then d

排程檢查收集到的資料
$ crontab -e

* * * * * ~/check_dhcpd_lease/check_dhcpd_lease.sh



說明:

  • 原本就有記錄家中網路設備 MAC address 的習慣, 受到 WiFi 連線密碼容易遭到比對破解議題的啟發, 發展此方案來強化家用網路安全性
  • 讓 dhcpd 發配固定 IP (fixed-address) 給已知裝置, 可減少 dhcpd.leases 寫入內容 (發配固定 IP 的資訊不會寫入 dhcpd.leases)
  • 亦可從主機或防火牆的 ARP table 找出非法裝置, 補充於文末



補充: 從主機 ARP table 找出不明裝置

#!/bin/bash

BASEPATH=~/check_dhcpd_lease
OUI_DB=$BASEPATH/oui.txt
KNOWN_DEV=$BASEPATH/known_devices.txt
UNKNOWN_DEV=/tmp/unknown_devices.txt

# 顯示重複出現的 MAC address (一個 MAC address 有多個 IP address)
arp -an | awk '{print $4}' | sort | uniq -c | awk '$1>1' | awk '{print $2}' | while read i; do arp -an | grep $i; done

# 找出不明裝置
arp -an | grep -v incomplete | awk '{print $4}' | while read i; do
   grep $i $KNOWN_DEV > /dev/null || echo $i >> $UNKNOWN_DEV
done

# 列出不明裝置的 IP address、MAC address、製造商
if [ -e $UNKNOWN_DEV ]; then
   cat $UNKNOWN_DEV | while read i; do
      IP=$(arp -an | grep $i | awk '{print $2}' | sed -E 's/(\(|\))//g')
      OUI=$(echo $i | tr -d : | tr "[a-f]" "[A-F]" | egrep -o "^[0-9A-F]{6}")
      VENDOR=$(grep $OUI $OUI_DB | cut -f 3)
      echo "$IP $i ($VENDOR)"
   done
   rm -f $UNKNOWN_DEV
fi


:,