udhcp client script hooking

Hooking เป็นเทคนิคหนึ่งซึ่งทำให้ซอฟต์แวร์สามารถ ปรับเปลี่ยน หรือเพิ่มเติม ได้ในภายหลัง โดยผ่านการดักจับ (intercept) function call, message หรือ event

การที่ต้องมีความสามารถนี้เนื่องจาก เพื่อให้ซอฟต์แวร์สามารถปรับเปลี่ยนไปตามเหตุการณ์ หรือค่าบางอย่างที่เกิดขึ้นในโปรแกรมในขณะ run-time ได้ในภายหลังโดยที่ไม่ต้องไปแก้ไขที่ source code ต้นฉบับ ซึ่งอาจทำโดยบุคคลที่ไม่ใช่ผู้พัฒนาโปรแกรมนั้นๆ ทำให้โปรแกรมมีความยืดหยุ่นสูง สามารถเปลี่ยนแปลงในภายหลังได้ง่าย

โปรโตคอล DHCP เองนั้นมีความยืดหยุ่นสูง สามารถใส่ค่า option ไว้ได้หลายค่า การจะเขียนโปรแกรมเพื่อประมวลผล option ต่างๆที่ใส่มาใน โปรโตคอล DHCP จึงไม่ใช่เรื่องง่าย เนื่องจากบางครั้งเราไม่รู้ว่า option ที่ใส่มานั้นต้องการจะทำอะไรกับมัน ใน DHCP client หลายๆตัว จึงได้ออกแบบให้นักพัฒนา หรือ ผู้ดูแลระบบสามารถเขียน script ง่ายๆในการประมวลผล DHCP option เหล่านั้นได้โดยไม่ต้องแก้ไข source code หลักของโปรแกรม และ script เหล่านั้นเป็นสิ่งที่ผู้ดูแลระบบคุ้นเคยอยู่แล้ว เช่น shell script เป็นต้น

udhcp เป็น dhcp client ที่นิยมใช้ใน embedded system เนื่องจากมีขนาดเล็ก ประมาณ 19KB เราจึงเห็น udhcp ถูกใส่ไว้ใน busybox ซึ่งเป็น UNIX utility suite ที่มักใช้ใน embedded system

DHCP protocol นอกจากจะช่วยแจก IP address ให้แก่ client ได้แล้ว ยังสามารถ ส่งค่าต่างๆไปให้ client ได้ ยกตัวอย่างเช่น DNS server ip address และ gateway address เป็นต้น

dhcp client ส่วนมาก จะรับค่ามาตรฐานเหล่านี้มาแล้วทำการเซ็ทให้กับ client อัตโนมัติ แต่ค่าบางค่า อย่างเช่น hostname dhcp client จะไม่ทำอะไรให้ เนื่องจากไม่ใช่เรื่องปกติที่ client จะรับค่า hostname มาจาก dhcp server

การส่งค่า hostname จะใช้ dhcp option 12 หรือ 0x0c เมื่อใช้ wireshark จับ dhcp protocol ดู จะมีลักษณะดังภาพด้านล่าง

สำหรับ udhcp แล้วจะรับค่า option มาแล้วเซ็ทไว้ใน UNIX environment variable แต่ถ้าหากเราต้องการเซ็ทค่า hostname ให้กับ Linux client ก็สามารถทำได้ โดยทำการแก้ไข udhcp client script ซึ่งจะเป็นส่วนที่ทำการ เซ็ทค่าต่างๆใน Linux ให้ udhcp client อีกต่อนึง script นี้มักจะอยู่ที่ path /usr/share/udhcpc/default.script

ในส่วนของ dhcp server ถ้าเราต้องการ ตั้งชื่อ Linux client ของเราว่า Rigel ใน dhcp server configuration file ต้องใส่ค่า option host-name “Rigel”; เข้าไปใน configuration ไฟล์ดังนี้

/etc/dhcp3/dhcpd.conf

host fairway {
    hardware ethernet 00:26:82:A7:C2:1A;
    fixed-address 192.168.1.11;
    option host-name "Rigel";
    netmask 255.255.255.0;
    option routers  192.168.1.1;
}

ในไฟล์ /usr/share/udhcpc/default.script เพิ่ม shell script ในการเซ็ท hostname เข้าไปในส่วน renew และ bound ดังนี้

if [ -n "$hostname" ] ; then
   echo -n > $HOSTNAME_CONF
   echo $hostname > $HOSTNAME_CONF
   hostname -F $HOSTNAME_CONF
fi

/usr/share/udhcpc/default.script (บรรทัด 37-41)

#!/bin/sh

# udhcpc script edited by Tim Riker <Tim@Rikers.org>

[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

RESOLV_CONF="/etc/resolv.conf"
HOSTNAME_CONF="/etc/hostname"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"

case "$1" in
        deconfig)
                /sbin/ifconfig $interface 0.0.0.0
                ;;

        renew|bound)
                /sbin/ifconfig $interface $ip $BROADCAST $NETMASK

                if [ -n "$router" ] ; then
                        echo "deleting routers"
                        while route del default gw 0.0.0.0 dev $interface ; do
                                :
                        done

                        for i in $router ; do
                                route add default gw $i dev $interface
                        done
                fi

                echo -n > $RESOLV_CONF
                [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
                for i in $dns ; do
                        echo adding dns $i
                        echo nameserver $i >> $RESOLV_CONF
                done
                if [ -n "$hostname" ] ; then
                        echo -n > $HOSTNAME_CONF
                        echo $hostname > $HOSTNAME_CONF
                        hostname -F $HOSTNAME_CONF
                fi
                ;;
esac

exit 0

เมื่อทำการ run udhcpc อีกครั้งจะได้ผลดังนี้

# udhcpc
udhcpc (v1.17.1) started
Sending discover...
Sending select for 192.168.1.11...
Lease of 192.168.1.11 obtained, lease time 600
deleting routers
adding dns 192.168.1.1
adding dns 192.168.1.2
# hostname
Rigel

ค่า option ที่ udhcpc ทำการเซ็ทให้ใน UNIX environment variable มีดังนี้

$HOME          - The set $HOME env or "/"
$PATH            - the set $PATH env or "/bin:/usr/bin:/sbin:/usr/sbin"
$1                  - What action the script should perform
interface         - The interface this was obtained on
ip                   - The obtained IP
mask             - The number of bits in the netmask (ie: 24)
siaddr            - The bootp next server option
sname           - The bootp server name option
boot_file         - The bootp boot file option
subnet           - The assigend subnet mask
timezone       - Offset in seconds from UTC
router            - A list of routers
timesvr          - A list of time servers
namesvr        - A list of IEN 116 name servers
dns               - A list of DNS server
logsvr            - A list of MIT-LCS UDP log servers
cookiesvr       - A list of RFC 865 cookie servers
lprsvr             - A list of LPR servers
hostname      - The assigned hostname
bootsize        - The length in 512 octect blocks of the bootfile
domain          - The domain name of the network
swapsvr         - The IP address of the client's swap server
rootpath        - The path name of the client's root disk
ipttl              - The TTL to use for this network
mtu              - The MTU to use for this network
broadcast     - The broadcast address for this network
ntpsrv           - A list of NTP servers
wins             - A list of WINS servers
lease            - The lease time, in seconds
dhcptype      - DHCP message type (safely ignored)
serverid        - The IP of the server
message      - Reason for a DHCPNAK
tftp               - The TFTP server name
bootfile         - The bootfile name

สามารถศึกษาเพิ่มเติมได้จาก README.udhcpc

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s