course:nctu-網路管理:hw2
網路管理:作業二
0x01 作業要求
DHCP
- DHCP assignment of client ip address and network settings
- Web servers should have static IPs, while client should have dynamicly allocated IPs
Firewall
- Only allow traffic from the network of external interface to web server
- Failover on gateways are required with synchronized state stable (via CARP+pfsync)
- Both external interface and internal interface should failover
- If either external interface or internal interface failed on the master gateway, the slave gateway should take control for both external and internal interface
NAT
- Web servers and clients are free to access the Internet
- Web servers are round-robinly load balanced with source tracking
Alternate queueing
- The ssh interactive packets should have priority over ssh bulk transfer packets
- For those who established more than five connections to the web servers, impose a global speed limit of 100kbit/s
Bonus-Authenticates client PCs with a captive portal
- Users will be redirected to a special web page for the first time
- After the users click “Agree” button or login with some username/password/voucher, they will be allowed to surf the Internet freely
- Before login, only DNS traffic is allowed to pass
- Also provide a link for user to logout
- If I can’t penetrate your captive portal easily, you’ll get extra points
Hint
- In order to make CARP and pfsync work, don’t forget to enable the <swap em>promiscuous mode</swap> on your virtual machine network settings.
- No physical switch is needed here. Just make sure that they are on the same network in the VM.
- DHCP should setup on both gateways, and their dynamic IP pools should be separated.
- pfsync should be on a dedicate network or a encrypted channel.
- You may use web server of your choice, and program your website with whatever frameworks you’re comfortable with.
0x02 環境配置
我是使用實驗室的 VMware Esxi 環境,我拿了三個 public IP,兩個配給 fw[1|2] em0,一個用在 em0 carp,這次作業重點會在兩台 firewall(ksh_firewall1、ksh_firewall2) 上面
先開三台 vSwitch,分別用於內網(NA2_ksh_inner)、外網、CARP & pfsync 專屬(NA2_ksh_pfsync)
接著開第一台 firewall(NA2_firewall1) 需要三張網卡,分別接在三台 vSwitch 上,接著把 OS 灌起來,因為之後要重編核心,所以記得要裝 src
0x03 DHCP Server
安裝 DHCP Server
#pkg install isc-dhcp43-server
DHCP 設定檔
- fw1 和 fw2 發的 IP 記得要切開,避免 fw1 斷掉時 fw2 發到 fw1 已發出去的 IP (DHCP無同步機制) 造成衝突
- /usr/local/etc/dhcpd.conf
option domain-name "example.org"; default-lease-time 600; max-lease-time 7200; log-facility local7; subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.101 192.168.1.200; #要發的 IP 範圍 option domain-name "ksh_fw.nctucs.net"; #domain name option routers 192.168.1.253; #router, 因為在這次架構中,會幫忙內網 routing 的是兩台 fw,所以這個要設成兩台 fw 的內網 carp IP option broadcast-address 192.168.1.255; option domain-name-servers 140.113.17.5, 140.113.1.1; default-lease-time 3600; max-lease-time 21600; } #兩台web拿固定IP host kshweb1 { hardware ethernet 00:0c:29:66:71:d5; #拿固定 IP 機器的 mac-address fixed-address 192.168.1.1; #固定 IP,記得跟上面動態分配的隔開 } host kshweb2 { hardware ethernet 00:0c:29:88:27:ad; fixed-address 192.168.1.2; }
開機啟動
- /etc/rc.conf
# DHCP Setting dhcpd_enable="YES" dhcpd_flags="-q" dhcpd_conf="/usr/local/etc/dhcpd.conf" dhcpd_ifaces="em2" dhcpd_withumask="022" # file creation mask
0x04 Firewall、NAT、ALTQ
接下來的firewall、NAT、ALTQ 都是靠 pf 做的
重編 kernel
確認 hardware platform
% uname -m
移動到目錄底下複製一份核心,名字任取,修改內容
cd /usr/src/sys/amd64/conf/ cp GENERIC kernel_pf
ident kernel_pf ... # Option and device for PF and PFSync device pf device pflog device pfsync # For Using PF ALTQ options ALTQ options ALTQ_CBQ # Class Bases Queuing (CBQ) options ALTQ_RED # Random Early Detection (RED) options ALTQ_RIO # RED In/Out options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC) options ALTQ_PRIQ # Priority Queuing (PRIQ) options ALTQ_NOPCC # Required for SMP build
重新編譯,安裝新 kernel
# cd /usr/src # make buildkernel KERNCONF=kernel_pf # make installkernel KERNCONF=kernel_pf
pf rule
################################################################# # Macro definitions ################################################################# ext_if="em0" lan_net="192.168.1.0/24" int_if="em2" ################################################################# # Tables ################################################################# table <ssh_bruteforce> persist #table <trusted> { 140.113.83.0/24 } ################################################################# # Options ################################################################# set skip on lo0 ################################################################# # Normalization ################################################################# scrub in all ################################################################# # Queueing ################################################################# altq on $ext_if cbq bandwidth 100Mb queue { main, ftp, udp, web, ssh, icmp } queue main bandwidth 28% cbq(default borrow red) queue udp bandwidth 30% cbq(borrow red) queue web bandwidth 20% cbq(borrow red) queue ssh bandwidth 20% cbq(borrow red) { ssh_interactive, ssh_bulk } queue ssh_interactive priority 7 bandwidth 20% queue ssh_bulk priority 5 bandwidth 80% queue icmp bandwidth 2% cbq ################################################################# # Translation ################################################################# nat pass on $ext_if from $lan_net to any -> 140.113.24.184 #內網流量 nat 到對外網卡 no nat on $ext_if from !$lan_net to any #非內網 IP 不做 NAT #內部兩台web server 做 round-robin ,同 IP 連線固定不跳換(sticky-address) rdr on $ext_if proto tcp from any to any port 80 -> {192.168.1.1, 192.168.1.2} round-robin sticky-address #內部client url 使用 public IP 連線到web server 要多做一次nat rdr on $int_if proto tcp from $lan_net to $ext_if port 80 -> {192.168.1.1, 192.168.1.2} round-robin sticky-address nat on $int_if proto tcp to {192.168.1.1, 192.168.1.2} port 80 -> $int_if ################################################################# # Filtering ################################################################# block drop in quick on $ext_if from <ssh_bruteforce> to any pass in quick on $ext_if from <trusted> to any #block in on $ext_if proto tcp from any to $ext_if port 22 pass quick on em1 proto pfsync keep state (no-sync) pass in quick on $ext_if proto { tcp, udp } from any to $ext_if port {ssh, www} keep state pass log quick on $ext_if proto tcp to port ssh queue (ssh_bulk, ssh_interactive) pass in quick on $ext_if proto tcp to port www queue http pass out on $ext_if proto udp queue udp pass out on $ext_if proto icmp queue icmp pass proto carp pass quick on $ext_if proto {tcp, udp} from 140.113.24.187 keep state #block in quick on $ext_if all
rc.conf
#package filter setting pf_enable="YES" pf_rules="/etc/pf.conf" pf_flags="" # pfctl 啟動時的附加選項 pflog_enable="YES" pflog_logfile="/var/log/pflog" pflog_flags="" pfsync_enable="YES" pfsync_syncdev="em1" gateway_enable="YES"
0x05 CARP
將 carp module 載入核心
carp_load=“YES”
# kldload carp
設定 alias IP
hostname="kshfw1.nctucs.net" ifconfig_em0="inet 140.113.24.187 netmask 255.255.255.224" ifconfig_em0_alias0="vhid 1 advskew 100 pass youpasswd 140.113.24.184/27" defaultrouter="140.113.24.161" ifconfig_em1="172.20.1.1 netmask 255.255.255.0" ifconfig_em2="inet 192.168.1.253 netmask 255.255.255.0" ifconfig_em2_alias0="vhid 2 advskew 100 pass youpasswd 192.168.1.252/32"
# /etc/rc.d/netif restart # /etc/rc.d/routing restart
設定 preempt
net.inet.carp.preempt=1
pf 放行 carp 封包
pass proto carp
# service pf reload
- 可用
pfctl -s state
檢測兩邊 state 是否相同,確保連線狀態是有同步的 - 可在 client 用 wget 下載大檔案途中關閉 fw1 interface,確認 carp 和 pfsync 是否正確運作不影響下載
- pfsync 記得指定 syncdev,syncpeer 則非必要,預設用 244.0.0.240 multicast
0x06 參考資料
course/nctu-網路管理/hw2.txt · 上一次變更: 由 127.0.0.1