# WAN Ping 基本介紹與設定 ## Ping 在測試是否能到達位在某個網路的某個 host 時,很常用到的一個工具就是 `ping`。`ping` 會先發出 `ICMP echo request` 封包,若此封包有到達指定的 host,且該 host 的設定是會回覆 `ICMP echo request`,那就會回傳 `ICMP echo reply` 的封包。待我們收到 `ICMP echo reply` 後,`ping` 就會計算 round-trip time、packet loss 等資訊。 :::info ICMP 是 network-layer 的 protocol,也就是第三層的 protocol。TCP 跟 UDP 由於會用到 port number,所以是屬於第四層的 protocol。而 ICMP 不需要用到 port number,只需要用到 IP address,所以是第三層的 protocol。 ::: 所以若 `ping` 了某個 IP 但沒回應,並不一定代表那個 IP 沒有 host,有可能是那個 host 選擇不回應 `ICMP echo request`。 那什麼情況會選擇不回應 `ICMP echo request`? 由於若我們的電腦回覆了 `ICMP echo request`,那別人就能知道這個 IP address 是有電腦在的,那駭客就能更進一步地做攻擊。 ## WAN Ping  從前面的說明可以知道若我們的電腦會回覆 `ICMP echo request`,那就可能將我們的電腦暴露於駭客攻擊的風險下。 尤其若是 router 或 modem 這類裝置,若會回覆 `ICMP echo reply`,那駭客就有可能可以攻擊到內網的裝置。 所以 WAN ping 就是設定說,若有人從外網對我們裝置的 public WAN IP 發送了 `ICMP echo request`,那我們的裝置是否要回傳 `ICMP echo reply`?   若開啟 WAN ping,就會回傳 `ICMP echo reply` 封包;若沒開啟 WAN ping,那就是忽略 `ICMP echo request`、不回傳 `ICMP echo reply` 封包。 ### 開啟 WAN Ping 的時機 大部分都會建議不要開啟 WAN ping,除非是在診斷網路相關問題時,才會暫時將此功能開啟。 ## 透過 `iptables` 設定是否回應 Ping > 由於一般小老百姓好像不太容易拿到免費的 public WAN IP,所以以下都是用內網的 IP 做設定 以下用我的 MacBook 跟 Virtualbox 的 Ubuntu 虛擬機做測試,Ubuntu 虛擬機被分配到的 IP 是 192.168.50.241,MacBook 被分配到的 IP 則是 192.168.50.180。  以下是都沒有做任何設定的情況,從 Macbook ping 到 Ubuntu 虛擬機,理論上是可以順利 ping 過去的。   用 `tcpdump` 可以看到有收到來自 MacBook 的 `ICMP echo request` 封包,且 Ubuntu 虛擬機也有回傳 `ICMP echo reply` 封包。 ### 設定不回應 `ICMP echo request` 以下測試也是從 MacBook ping 到 Ubuntu 虛擬機,但是這次會在 Ubuntu 做以下設定讓 Ubuntu 不回應來自 `enp0s8` interface 的 `ICMP echo request` 封包: ```shell $ sudo iptables -t filter -A INPUT -i enp0s8 -p icmp --icmp-type echo-request -j DROP ``` - 由於是要對來到本機的 `ICMP echo request` 封包做操作,所以是 `INPUT` chain。 那由於做的操作是將這個封包丟掉、不處理它(`DROP`),所以要用 `filter` table。 所以就是 `filter` table 的 `INPUT` chain。 - `-i enp0s8`:只有指定是從 `enp0s8` 這個 network interface 進來的封包(實際應用時要換成自己 router 的 WAN interface)。如果沒有指定哪個 network interface 的話,會變成全部的 `ICMP echo request` 都 `DROP`。 - `-p icmp --icmp-type echo-request`:指定這個封包的 protocol 是 `icmp`,且 ICMP type 是 `echo-request`。 - `-j DROP`:記得要做 `DROP` 而不是 `REJECT`。用 `REJECT` 的話對方還是會知道這個 public WAN IP 是有效的。   從以上截圖畫面可以看到,我的 MacBook ping 到 Ubuntu 虛擬機時,全部都 `Request timeout`。從 `tcpdump` 的結果也可以看到 `enp0s8` 這個 interface 有收到來自 MacBook 的 `ICMP echo request`,但這裡就都沒有回送 `ICMP echo reply` 給 MacBook。 :::info 若要查詢 ICMP type,可以用 `sudo iptables -p icmp -h` 指令,會列出有哪些 ICMP type 可以用。 ```shell $ sudo iptables -p icmp -h iptables v1.8.10 (nf_tables) Usage: iptables -[ACD] chain rule-specification [options] iptables -I chain [rulenum] rule-specification [options] iptables -R chain rulenum rule-specification [options] iptables -D chain rulenum [options] iptables -[LS] [chain [rulenum]] [options] iptables -[FZ] [chain] [options] iptables -[NX] chain iptables -E old-chain-name new-chain-name iptables -P chain target [options] iptables -h (print this help information) Commands: Either long or short options are allowed. --append -A chain Append to chain --check -C chain Check for the existence of a rule --delete -D chain Delete matching rule from chain --delete -D chain rulenum Delete rule rulenum (1 = first) from chain --insert -I chain [rulenum] Insert in chain as rulenum (default 1=first) --replace -R chain rulenum Replace rule rulenum (1 = first) in chain --list -L [chain [rulenum]] List the rules in a chain or all chains --list-rules -S [chain [rulenum]] Print the rules in a chain or all chains --flush -F [chain] Delete all rules in chain or all chains --zero -Z [chain [rulenum]] Zero counters in chain or all chains --new -N chain Create a new user-defined chain --delete-chain -X [chain] Delete a user-defined chain --policy -P chain target Change policy on chain to target --rename-chain -E old-chain new-chain Change chain name, (moving any references) Options: --ipv4 -4 Nothing (line is ignored by ip6tables-restore) --ipv6 -6 Error (line is ignored by iptables-restore) [!] --protocol -p proto protocol: by number or name, eg. `tcp' [!] --source -s address[/mask][...] source specification [!] --destination -d address[/mask][...] destination specification [!] --in-interface -i input name[+] network interface name ([+] for wildcard) --jump -j target target for rule (may load target extension) --goto -g chain jump to chain with no return --match -m match extended match (may load extension) --numeric -n numeric output of addresses and ports [!] --out-interface -o output name[+] network interface name ([+] for wildcard) --table -t table table to manipulate (default: `filter') --verbose -v verbose mode --wait -w [seconds] maximum wait to acquire xtables lock before give up --line-numbers print line numbers when listing --exact -x expand numbers (display exact values) [!] --fragment -f match second or further fragments only --modprobe=<command> try to insert modules using this command --set-counters -c PKTS BYTES set the counter during insert/append [!] --version -V print package version. icmp match options: [!] --icmp-type typename match icmp type [!] --icmp-type type[/code] (or numeric type or type/code) Valid ICMP Types: any echo-reply (pong) destination-unreachable network-unreachable host-unreachable protocol-unreachable port-unreachable fragmentation-needed source-route-failed network-unknown host-unknown network-prohibited host-prohibited TOS-network-unreachable TOS-host-unreachable communication-prohibited host-precedence-violation precedence-cutoff source-quench redirect network-redirect host-redirect TOS-network-redirect TOS-host-redirect echo-request (ping) router-advertisement router-solicitation time-exceeded (ttl-exceeded) ttl-zero-during-transit ttl-zero-during-reassembly parameter-problem ip-header-bad required-option-missing timestamp-request timestamp-reply address-mask-request address-mask-reply ``` ::: ## 透過 OpenWRT 的 `uci` 指令設定是否回應 Ping 接下來將我的安裝了 OpenWRT 23.05.5 的 Marvell ESPRESSObin v7 開發板一起加入同一個 LAN 內。從以下截圖可看到我的開發板被分配到的 IP 是 192.168.50.141。   OpenWRT 內建的防火牆本身就有針對 WAN ping 的規則,可以查看 `/etc/config/firewall`:  或者用 `uci show firewall` 指令查看:  如果沒更改過的話,預設上應該是針對來自 `wan` 的 `icmp` `echo-request`,且只有 `ipv4`,且是 `ACCEPT`。 OpenWRT 預設沒有 `tcpdump`,但可以安裝 `tcpdump-mini` 來監測是否有人正在 ping: ```shell $ opkg update $ opkg install tcpdump-mini ```   從以上截圖可看到,目前 OpenWRT 對於來自 `wan` 的 `ipv4` 的 `ICMP echo request` 是 `ACCEPT`,所以我的 MacBook 可以 `ping` 成功過去,且用 `tcpdump` 也能看到我的 Marvell ESPRESSObin v7 開發板有收到 `ICMP echo request` 封包,也有回傳 `ICMP echo reply` 封包。 ### 不回應 `ICMP echo request` 接下來,如果要設定成不回應 `ICMP echo request`,就需要對 OpenWRT 做以下設定: ```openwrt= root@OpenWrt:/# uci set firewall.@rule[1].target='DROP' root@OpenWrt:/# uci commit firewall root@OpenWrt:/# /etc/init.d/firewall restart ``` - 從 `uci show firewall` 可以看到 `Allow-Ping` 這個規則是 `firewall.@rule[1]`,編號是 `1`,所以就設定編號 `1` 的防火牆規則的 target 是 `'DROP'` - 我們用 `uci set` 所做的設定只會儲存在記憶體裡面,並不會修改到 `/etc/config/` 裡面的設定檔,也不會立即生效,當我們的 OpenWRT 裝置重新開機後,用 `uci set` 做的設定就會消失,所以才需要做後面兩個指令。 - 做 `uci commit firewall` 才會將目前記憶體中 firewall 的設定儲存到 `/etc/config/firewall` 裡面,重開機時才能把這些設定保留住。 - `/etc/init.d/firewall restart`,重新啟動 firewall。由於大部分 `/etc/config/` 底下的設定檔都只有在啟動該服務時才會讀取 config 檔案,所以我們要重新啟動防火牆,這樣他才會去讀取並載入 `/etc/config/firewall` 的設定,並且立即生效~ 以下是實際測試時的截圖:   可以看到目前已將 `Allow-Ping` 這個防火牆規則的 target 改成 `'DROP'`,且當我從 MacBook `ping` 到 192.168.50.141,得到的結果都是 `Request timeout`。用 `tcpdump` 也能看到我的 OpenWRT 裝置有從 192.168.50.180(也就是 MacBook 被分配到的 LAN IP)收到 `ICMP echo request` 封包,但都沒有回傳 `ICMP echo reply` 封包。 ## References - https://en.wikipedia.org/wiki/Ping_(networking_utility) - https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up