星期日, 10月 25, 2015

DHCP snooping 與 IP Source Guard

###############################################

※關於dhcp snooping的觀念,請參考「防堵私自架設DHCP伺服器」這一篇文章
關於底下將提到的ip source guard觀念,請參考「建構自我防禦不可不知-以交換器為基礎之安全防護觀念
###############################################

身為網路管理人員,區域網路的環境中,如果有未經許可的路由器放在區網中,而此路由器又將DHCP Server功能開啟,對網管人員而言簡直是惡夢一場,因為區域網路中的電腦會租用到非法或不對的ip、gateway及dns資料,造成使用人員反應網路不通或有問題, 現在的Layer2交換器大多內建dhcp snooping功能,可將連接到正確及安全的dhcp server來源埠綁定為trust(信任),這樣在此交換器所不允許的埠下(設為untrust),只要是DHCP伺服器才會發送的【DHCPOffer】或【DHCPAck】這兩種訊息在Untrust介面下都會被攔阻下來,只允許透過Trust介面傳送。這樣,就不用擔心網路上私自架設的DHCP伺服器干擾內部網路的正常運作。
#############################################################
SMC 8126L2啟用 dhcp snooping  指令

ip dhcp snooping vlan 1
ip dhcp snooping vlan 2
ip dhcp snooping -- 大開關
UP-link Port 或是接 DHCP Server .. Port 要設定 TRUST
SW#1(config)#interface ethernet 1/24  - 接 DHCP Server01
SW#1(config-if)#ip dhcp snooping trust
若要取消dhcp snooping則下no ip dhcp snooping

###############################################
實例:
若交換器有切vlan id 11,22,33,44,第24埠上接dhcp server來源
則dhcp snooping啟用的步驟如下
Vty-0#configure
Vty-0(config)#ip dhcp snooping vlan 11 =>指定在vlan id 11啟用ip dhcp snooping
Vty-0(config)#ip dhcp snooping vlan 22
Vty-0(config)#ip dhcp snooping vlan 33
Vty-0(config)#ip dhcp snooping vlan 44
以上所有界面為untrust,即若有人架dhcp server則dhcp 送的【DHCPOffer】或【DHCPAck】訊息會被阻擋下來
我們必須加入至少一個dhcp server來源界面為trust
##本例設第24埠為trust界面
Vty-0(config)#interface ethernet 1/24
Vty-0(config-if)#ip dhcp snooping trust
Vty-0(config)#exit
Vty-0#show ip dhcp snooping =>顯示dhcp snooping資訊
Global DHCP Snooping status: disable
DHCP Snooping Information Option Status: disable
DHCP Snooping Information Policy: replace
DHCP Snooping is configured on the following VLANs:
   1,   11,   22,   33,   44,   55,   66,   77,   88,   99,  101,
Verify Source Mac-Address: enable
Interface           Trusted
----------          ----------
Eth 1/1             No
Eth 1/2             No
Eth 1/3             No
Eth 1/4             No
Eth 1/5             No
........
........
Eth 1/23            No
Eth 1/24            Yes
Eth 1/25            No
Eth 1/26            No



上面的Global DHCP Snooping status: 若為disable,則需開啟dhcp snooping 的大開關
開啟後,Switch會自動將DHCP分配到Client端的IP,建立一份表單(dhcp snooping binding table),有了這份表單,當我們之後要用到IP Source Guard的功能時,Switch就會根據Client端的IP及Mac Address是否在這份表單中來當作放行的依據,否則,Switch就不給上,這可以用來防止未經授權的使用者私自設定IP上網。

以下先設定Global DHCP Snooping status為Enabled

Vty-0#configure
Vty-0(config)#ip dhcp snooping
按「enter」
Vty-0(config)#exit
Vty-0#show ip dhcp snooping
看是否出現以下訊息
Global DHCP Snooping status: enabled
DHCP Snooping Information Option Status: enabled


Vty-0#show ip dhcp snooping binding  =>show出dhcp snooping是否有在學習紀錄dhcp配出來的ip及MAC對映

MAC Address       IP Address      Lease(sec) Type                 VLAN Interface
----------------- --------------- ---------- -------------------- ---- ---------
00-xx-xx-xx-a5-59 172.20.x.1--         86330 dhcp-snooping          77 Eth 1/18
00-xx-xx-xx-c3-63 172.20.x.1--         86360 dhcp-snooping          77 Eth 1/13

以上先啟用後,之後若是啟用ip source guard功能,則可限制使用者只能拿到DHCP Server發的IP,若使用者自行設定IP是不能上的,若有額外必須設固定IP, 則需要手動加ip及mac到binding table中。
ip source guard 啟用後,每一埠有限制筆數(5-16筆,視交換器廠牌類型),因此若此埠下還有接網路交換器,而使用者多的話,則此埠最好不要開ip source guard以免底下使用者要不到IP

ip source-guard 啟用步驟(以port20啟用為例)

SW1(config)#interface ethernet 1/1-20
SW1(config-if)#ip source-guard sip-mac (需要IP和MAC在Binding Table中有資料且一致才行)
SW1(config-if)#exit

加入一筆資料mac為 11-11-11-11-11-11 IP為172.20.1.99,在port2的位置可接受固定IP

Vty-0(config)#ip source-guard binding 11-11-11-11-11-11 vlan 11 172.20.1.99  interface ethernet 1/2



###################################################################
LINUX  DHCP Server  搭配交換器的 DHCP Option 82功能 .   可以控制用戶端的 DHCP IP 取得,例如我們可以設定使用者從哪個埠連上來,我就給哪個IP或哪個區段的IP。或是同一網段下,我們可以設定交換器第1埠給哪一個IP,第2埠給給哪一組的IP。也可以經由DHCP Server的LOG檔中看到使用者使用哪一台MAC Address裝置從哪一埠,哪一組vlan連上來。對於管理者管理內部網路是很有用的工具之一,log紀錄檔可參考下圖:


##################################################
Linux DHCP Server dhcpd.conf

###################################################
#
# Sample configuration file for ISC dhcpd for Debian
#
# Attention: If /etc/ltsp/dhcpd.conf exists, that will be used as
# configuration file instead of this file.
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.

#subnet 10.152.187.0 netmask 255.255.255.0 {
#}

# This is a very basic subnet declaration.

#subnet 10.254.239.0 netmask 255.255.255.224 {
#  range 10.254.239.10 10.254.239.20;
#  option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}

# This declaration allows BOOTP clients to get dynamic addresses,
# which we don't really recommend.

#subnet 10.254.239.32 netmask 255.255.255.224 {
#  range dynamic-bootp 10.254.239.40 10.254.239.60;
#  option broadcast-address 10.254.239.31;
#  option routers rtr-239-32-1.example.org;
#}

# A slightly different configuration for an internal subnet.
#subnet 10.5.5.0 netmask 255.255.255.224 {
#  range 10.5.5.26 10.5.5.30;
#  option domain-name-servers ns1.internal.example.org;
#  option domain-name "internal.example.org";
#  option routers 10.5.5.1;
#  option broadcast-address 10.5.5.31;
#  default-lease-time 600;
#  max-lease-time 7200;
#}

# Hosts which require special configuration options can be listed in
# host statements.   If no address is specified, the address will be
# allocated dynamically (if possible), but the host-specific information
# will still come from the host declaration.

#host passacaglia {
#  hardware ethernet 0:0:c0:5d:bd:95;
#  filename "vmunix.passacaglia";
#  server-name "toccata.fugue.com";
#}

# Fixed IP addresses can also be specified for hosts.   These addresses
# should not also be listed as being available for dynamic assignment.
# Hosts for which fixed IP addresses have been specified can boot using
# BOOTP or DHCP.   Hosts for which no fixed address is specified can only
# be booted with DHCP, unless there is an address range on the subnet
# to which a BOOTP client is connected which has the dynamic-bootp flag
# set.
#host fantasia {
#  hardware ethernet 08:00:07:26:c0:a5;
#  fixed-address fantasia.fugue.com;
#}

# You can declare a class of clients and then do address allocation
# based on that.   The example below shows a case where all clients
# in a certain class get addresses on the 10.17.224/24 subnet, and all
# other clients get addresses on the 10.0.29/24 subnet.

#class "foo" {
#  match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
#}

#shared-network 224-29 {
#  subnet 10.17.224.0 netmask 255.255.255.0 {
#    option routers rtr-224.example.org;
#  }
#  subnet 10.0.29.0 netmask 255.255.255.0 {
#    option routers rtr-29.example.org;
#  }
#  pool {
#    allow members of "foo";
#    range 10.17.224.10 10.17.224.250;
#  }
#  pool {
#    deny members of "foo";
#    range 10.0.29.10 10.0.29.230;
#  }
#}
 class "by-oui-mac" {
 match if (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:20:6a:8a")
 or (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:0:3:6b")
 or (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:0:7:eb");
 log (info, (binary-to-ascii (16,8,":",substring(hardware, 0, 4))));
 }

class "other" {
 match if not (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:20:6a:8a")
 and not (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:0:3:6b")
 and not (binary-to-ascii (16,8,":",substring(hardware, 0, 4)) = "1:0:7:eb");
 log (info, concat("other-mac",(binary-to-ascii (16,8,":",substring(hardware, 0, 4)))));
 }


 class "No_AID"{
        match if  not exists agent.remote-id;  }

 class "fixed6"{
        match if  binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 2, 6)) = "70:72:cf:95:aa:5c" and binary-to-ascii (10, 8, "/", suffix ( option agent.circuit-id, 2)) = "1/5";
  }

  class "fixed7"{
        match if  binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 2, 6)) = "70:72:cf:95:aa:5c"
and binary-to-ascii (10, 8, "/", suffix ( option agent.circuit-id, 2)) = "1/6";
  }

class "port4"{ match if binary-to-ascii (10, 8, "/", suffix ( option agent.circuit-id, 2)) = "1/4"; }

# Test01
subnet 192.168.2.0 netmask 255.255.255.0 {
    pool{
range 192.168.2.6;
        allow members of "fixed6";
  }

  pool{
        range 192.168.2.7;
        allow members of "fixed7";
  }

 pool{
        range 192.168.2.4;
        allow members of "port4";
  }

 pool{
        range 192.168.2.210  192.168.2.220;
        option routers 192.168.2.2;
        allow members of "by-oui-mac";
  }


pool{
        range 192.168.2.141 192.168.2.150;
        allow members of "No_AID";
      # MyNotebook
host E10089 {
hardware ethernet 20:6A:99:6F:2C:70;
fixed-address 192.168.2.33;
}

  }

  }
     
if exists agent.circuit-id
{
  log (info, concat("Lease for ",
                binary-to-ascii (10, 8, ".", leased-address),
                " is connected to interface ",
                binary-to-ascii (10, 8, "/",
                suffix ( option agent.circuit-id, 2)),
                " (add 1 to port number!), VLAN ",
                binary-to-ascii (10, 16, "",
                substring( option agent.circuit-id, 2, 2)),
                " on switch ",
                binary-to-ascii(16, 8, ":",
                substring( option agent.remote-id, 2, 6))));
  log (info, concat("Lease for ",
                binary-to-ascii (10, 8, ".", leased-address),
                " raw option-82 info is CID: ",
                binary-to-ascii (10, 8, ".", option agent.circuit-id),
                " AID: ",
                binary-to-ascii(16, 8, ".", option agent.remote-id)));
}
else { log (info, "client is neither known no agent-id"); }

###############################################
說明:
substring(option agent.circuit-id,2,2)   代表偏移量2, 長度2. 這個表達式取出了Option 82中的VID部分
binary-to-ascii(10,16,"",substring(option agent.circuit-id,2,2))   10表示十進制, 16表示16個bit. 這個表達式的結果就是把Option 82種的VLAN ID轉成10進制.
以上參考:Linux平臺上支持Option82的DHCP服務器配置




##################################################
參考資料:

  1. DHCP snooping的觀念與運作方式及 IP source guard的設定
  2. 防堵私自架設DHCP伺服器
  3. Linux DHCP Option 82 設定
  4. How to configure Option 82 aware DHCP Server(Zyxel)
  5. Static Addressing Within a DHCP Structure
  6. ISC DHCP and option 82
  7. How to use DHCP option 82 on ECS4110-28T for assign different DHCP IP pools to clients?(Edge-Core KW)
  8. Sample configuration file for ISC dhcpd using Option 82
  9. DHCP Option 82, Cisco switches and routers and the ISC DHCP server
  10. Use DHCP Snooping, Option 82  and Filtering on AT-8800, AT-8600, AT-8700XL
  11. Linux平臺上支持Option82的DHCP服務器配置
  12. 測試DHCP Option82 設定了好久的dhcpd.conf
  13. Understand DHCP relay option 82 Agent Circuit ID (Zyxel KW)
  14. Rogue DHCP (wikipedia)
  15. ISC-DHCP-Server的文件
  16. 瞭解DHCP Snooping,IPsource Guard的好文章



沒有留言: