openwrt - firewall

最後更新: 2018-06-06

介紹

opnewrt 的 backend 是 iptables

它的 frontend 在 layer 3 會做這三件事

  • redirect (-p tcp --dport 1025:1030 -j REDIRECT --to-port 25)
  • forwardings (nat)
  • access rule (open port on firewall)

一般來來說, 它的 firewall rule 由以下兩個檔案所控制

  • /etc/config/firewall
  • /etc/firewall.user     <-- 它是被前者(firewall) include 進去
config include
       option path /etc/firewall.user

 


套用設定

 

  • /etc/init.d/firewall restart

 

全域的 Default 設定:

/etc/config/firewall:

config defaults
    option syn_flood '1'
    option drop_invalid '1'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'
    option disable_ipv6 '1'
....

 


基本設定

 

最基本的設定是 2 個 zone (lan, wan) policy 及 default 的 forwarding

定義 lan zone

config zone
        option name             lan
        option network          'lan'
        option input            ACCEPT
        option output           ACCEPT
        option forward          REJECT

定義 wan zone

config zone
        option name             wan
        option network          'wan'
        option input            REJECT
        option output           ACCEPT
        option forward          REJECT
        option masq             1
        option mtu_fix          1

# Zone 與 Zone 之間的 Forward 設定 (用來 override lan zone 的 forward option)

config forwarding
        option src              lan
        option dest             wan

Opening ports on Router itself:

config rule
        option 'name' 'FW_SSH'
        option src              wan
        option dest_port        22
        option target           ACCEPT
        # 同時 allow tcp 及 udp
        option proto            'tcp udp'
        # Default 是 yes 的
        option enabled          yes

 


Port ranges

 

config redirect
        option target 'DNAT'
        option src 'wan'
        option dest 'lan'
        option proto 'udp'
        option src_dport '60001-60010'
        # option dest_port '60001-60010' <- 不填都可以 !!
        option name 'ssh'
        option dest_ip '192.168.123.13'

 


一切由 Zone 說起

 

  • name
  • network         <--    List of interfaces attached to this zone, if ommitted, the value of name is used by default
                                  (option 'network'     'lan wwan')
  • masq             <--    outgoing zone traffic should be masqueraded
  • masq_src
  • masq_dest
  • conntrack
  • input
  • forward
  • output
  • family (ipv4, ipv6 or any)
  • log  (default 0)

 

  • src
  • src_ip
  • src_port
  • src_dport                # 在 input 時, package 要去目的地的那個 port
  • src_mac 

 

  • dest
  • dest_ip                   # 在 redirect 時作 NAT 到那 lan ip 之用
  • dest_port               # 在 redirect 時作 NAT 到那 port 之用

Forwardings:

  • src(zone) ---> dest(zone)

 

Redirects(DNAT / SNAT)

  • reflection 1  <-- 是否啟用
  • target  DNAT(default) / SNAT

 

Rules 的 target:

  • target       ACCEPT / REJECT / DROP(default)

 

Zone declaration for a specific subnet

config zone
        option name             server_zone
        option input            ACCEPT
        option output           ACCEPT
        option forward          DROP
        option subnet           '192.168.0.0/24'

DMZ zone

config redirect
    option src              wan
    option proto            all
    option dest_ip          192.168.1.2

 

MASQUERADE 用其他 Port

iptables -t nat -nL --line-number | less

...
Chain zone_wan_nat (1 references)
num  target     prot opt source               destination
1    MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0
...

# 設定用 port 31000-40000

iptables -t nat -I zone_wan_nat -p tcp -j MASQUERADE --to-ports 31000-40000

# 還原返

iptables -t nat -D zone_wan_nat -p tcp -j MASQUERADE --to-ports 31000-40000

 


Example

 

Router 上常用的 rule

Enable / Disable 某 Rule:

config 'rule'
        option name     'FW_SSH'
        option enabled  '0'

限制某 IP 可以 access 某 port:

config 'rule'
        option 'name'      'FW_SSH'
        option 'src'       'wan'
        option 'dest_port' '22'
        option 'target'    'ACCEPT'
        option 'proto'     'tcp'                     # 非必要
        option 'dest_ip'   'YOUR_WAN_IP'             # 非必要
        option 'src_ip'    'WHAT_IP_ALLOW_ACCESS'

remapped ssh port (2222) on wan:

不改 router 上 listen 的 port 22

config redirect
       option src              wan
       option src_dport        2222
       option dest             lan
       option dest_port        22
       option proto            tcp

Allow Ping:

config rule
        option name             Allow-Ping
        option src              wan
        option proto            icmp
        option icmp_type        echo-request
        option family           ipv4
        option target           ACCEPT

Port Forward(DNAT)

在 Openwrt 上, port forward 都是在 firewall 層面上設定的

/etc/config/firewall

不同的只是 'target' 是 'DNAT'

Example:

Wan Port: 2222 ----> 192.168.1.100:22

config 'redirect'
        option 'name'      'server_ssh'         <-- 可以略過
        option 'src'       'wan'
        option 'dest'      'lan'
        option 'proto'     'tcp udp'
        option 'src_dport' '22'
        option 'dest_ip'   '192.168.1.100'
        option 'dest_port' '22'
        option 'target' 'DNAT'              <-- 可以略過

SNAT

config redirect
        option src              lan
        option dest             wan
        option 'proto'          'all'
        option 'name'           'Wan_ip2_DMZ'
        option src_ip           your_local_ip
        option src_dip          your_wan_ip
        option target           SNAT

Transparent proxy rule

config redirect
        option src              lan
        option proto            tcp
        option src_ip           !192.168.1.100
        option src_dport        80
        option dest_ip          192.168.1.100
        option dest_port        3128

Block access a host

config rule
        option 'name'           'Block an IP'
        option src              wan
	option proto            all
        option src_ip           <block ip>
        option target           REJECT

Simple DMZ rule

config redirect
	option src              wan
	option proto            all
	option dest_ip          192.168.1.2

 



NOTRACK

 

By default, the firewall will disable connection tracking for a zone if no masquerading is enabled.

The purpose of NOTRACK is to speed up routing and save memory.

Debug generated rule set

/etc/init.d/firewall stop                  # flush all rules and set the policies to ACCEPT)

# see the rules as they're executed

FW_TRACE=1 fw reload

# log it

FW_TRACE=1 fw reload 2>/tmp/iptables.log

 


iptables as tcpdump

 

iptables -A INPUT -s s.s.s.s -j LOGGING

iptables -A OUTPUT -d d.d.d.d -j LOGGING

tcpdump.sh

#!/bin/ash

while [ true ]; do
  sleep 1
  echo "Dumping & Cleaning"
  dmesg -c
done

還原

iptables -D INPUT -s s.s.s -j LOGGING

iptables -D OUTPUT -d d.d.d.d -j LOGGING

 



Firewall 的構成

 

Openwrt 的 Firewall 結構與 dd-wrt 是完全不一樣的

它是一個以 zone 為本的結構來

 

Example:

# admin 是一個自己定義的 zone 來

Chain INPUT
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           ctstate RELATED,ESTABLISHED
DROP       all  --  0.0.0.0/0            0.0.0.0/0           ctstate INVALID
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
+ syn_flood
+ input_rule --- NULL
+ input
        + zone_admin
                     + input_admin --- NULL
                     + zone_admin_ACCEPT (可以看成是此 zone 的 default policy)

 

# 在 input 上的一條不錯的 rule

Chain syn_flood (1 references)

target     prot opt source               destination
RETURN     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x17/0x02 limit: avg 25/sec burst 50
DROP       all  --  0.0.0.0/0            0.0.0.0/0

 

Chain OUTPUT
+output_rule --- NULL
+output
            + zone_admin_ACCEPT

 

Chain FORWARD
forwarding_rule --- NULL
forward
        + zone_admin_forward
                             + forwarding_admin
                             + zone_admin_REJECT

 

結論:

所有整個firewall 共分 3 段

本身的 Chain       ->      Zone 的 Chain (及Policy)       ->     Zone 的 Rules

input                             zone_???                                       input_??
                                                                                          zone_???_<POLICY>

output                          zone_???_<POLICY>                      zone_???_<DROP|ACCEPT|REJECT>

forward                         zone_???_forward                          forwarding_???
                                                                                           zone_admin_<POLICY>

 

# 就算沒有用到, 系統依然會建立以下類似的 rule

  • zone_admin_ACCEPT
  • zone_admin_DROP
  • zone_admin_REJECT

 

Version 14:

Table: Filter

<1>

Chain INPUT (Policy: ACCEPT, Packets: 0, Traffic: 0.00 B)

- delegate_input

<2>

Chain delegate_input (References: 1)

- input_rule
- syn_flood
- zone_lan_input
- zone_wan_input

<3>

input_rule

-- ACCEPT
-- RETURN

syn_flood

-- ACCEPT
-- RETURN

zone_lan_input

-- input_lan_rule
-- ACCEPT ctstate DNAT
-- zone_lan_src_ACCEPT

zone_wan_input

-- input_wan_rule
-- ACCEPT ctstate DNAT
-- zone_wan_src_DROP

 


DNS hijack

 

# hijack

config 'redirect'
        option '_name' 'DNS_Redirect'
        option 'src' 'lan'
        option 'proto' 'tcpudp'
        option 'src_dport' '53'
        option 'dest_ip' 'loc.dns.server.ip'
        option 'dest_port' '53'
        option 'target' 'DNAT'
        option 'dest' 'lan'
        option 'src_ip' '!loc.dns.server.ip'
      

# Allow DNS route backup
# Allow Wan access Local DNS

config 'redirect'
        option '_name' 'DNS'
        option 'src' 'wan'
        option 'proto' 'tcpudp'
        option 'src_dport' '53'
        option 'dest_ip' '192.168.1.249'
        option 'dest_port' '53'
        option 'target' 'DNAT'
        option 'dest' 'lan'
        option 'src_ip' 'your.wan.ip.addr'

 

 


Limit the rate

 

i.e.

config redirect
        option target 'DNAT'
        option src 'wan'
        option dest 'lan'
        option proto 'tcp'
        option src_dport '443'
        option dest_ip '192.168.123.14'
        option dest_port '443'
        option name 'web-https'
        option limit '64/s'
        option limit_burst '10'

 


Don't forward private networks IPs to WAN

 

destination IPs (10.0.0.0/8. 172.16.0.0/12, 192.168.0.0/16)

config rule
        option target 'REJECT'
        option dest_ip '10.0.0.0/8'
        option name 'priv2wan-10'
        option src 'lan'
        option dest 'wan'
        option proto 'all'

config rule
        option src 'lan'
        option dest 'wan'
        option name 'priv2wan-192'
        option dest_ip '192.168.0.0/16'
        option target 'REJECT'
        option proto 'all'

config rule
        option enabled '1'
        option src 'lan'
        option dest 'wan'
        option name 'priv2wan-172'
        option proto 'all'
        option dest_ip '172.16.0.0/12'
        option target 'REJECT'

測試

ping 10.0.0.1

From 192.168.123.1 icmp_seq=1 Destination Port Unreachable