OpenWrt

OpenWrt

System config

Switch info (交换机配置)

swconfig list
swconfig dev switch0 show

以斐讯 K2 为例:

#swconfig dev switch0 show
Global attributes:
        enable_vlan: 1
Port 0:
        pvid: 1
        link: port:0 link:down
Port 1:
        pvid: 1
        link: port:1 link:down
Port 2:
        pvid: 1
        link: port:2 link:up speed:100baseT full-duplex 
Port 3:
        pvid: 1
        link: port:3 link:down
Port 4:
        pvid: 2
        link: port:4 link:up speed:100baseT full-duplex 
Port 5:
        pvid: 0
        link: port:5 link:down
Port 6:
        pvid: 0
        link: port:6 link:up speed:1000baseT full-duplex 
Port 7:
        pvid: 0
        link: port:7 link:down
VLAN 1:
        vid: 1
        ports: 0 1 2 3 6t 7t 
VLAN 2:
        vid: 2
        ports: 4 6t 7t 

Port 0 - Port 3 对应四个 LAN 口。 Port 4 是 WAN 口。Port 6 是 CPU。Port 5 / 7 未知。

VLAN 1: LAN
VLAN 2: WAN

端口名字的 t 后缀意为通过此端口发包(egress)时打上 vlan tag;没有后缀或 u 后缀则为 utag (untagged) 端口,表示从这个端口发出的包去掉 vlan tag。而进入端口(ingress)的包是否允许由包的 vlan id 决定以及端口是否属于该 vlan 决定,如果进来的包是 untagged,认为是属于 pvid vlan;进入交换机后的数据(在交换机内部)必然带有tag。

注意 t / u 与cisco等企业交换机常用的 trunk / access 模式有所区别。

同一个 t 端口可以属于多个 vlan;而一个 u 端口最多只能属于1个 vlan。

access vlan23 等效于 u && (pvid == 23)

当设置一个端口属于多个 t vlan (以及一个 u vlan),此端口等效于企业交换机的 trunk 模式。

网络配置: /etc/config/network

config interface 'lan'                         
        option type 'bridge'     
        option ifname 'eth0.1'                 
        option proto 'static'                  
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'         
        option ip6assign '60'                  
        option delegate '0'                    


config interface 'wan'                    
        option ifname 'eth0.2'        
        option _orig_ifname 'eth0.2'      
        option _orig_bridge 'false'       
        option proto 'pppoe'        
        option username 'username'   
        option password 'password'        
        option ipv6 'auto' 

config switch                
        option name 'switch0'             
        option reset '1'                  
        option enable_vlan '1'            

config switch_vlan            
        option device 'switch0'
        option vlan '1'        
        option ports '0 1 2 3 6t 7t'

config switch_vlan                  
        option device 'switch0'
        option vlan '2'             
        option ports '4 6t 7t'

eth0.X 里的 X 即对应此 interface 的 VLAN id。

光猫 / IPTV / VLAN

电信光猫里的WAN侧连接默认绑定端口(一个端口绑定 IPTV 连接;其他端口绑定 Internet 连接),也可以配置 VLAN 绑定。桥接模式下,这个 WAN 连接是与对应的 VLAN 连通的。

端口绑定:WAN收到的数据 untag 后从 LAN port 发出。接收的 untag 包视为属于对应 VLAN(如果收到的包自带tag,去掉之?)。
VLAN 绑定:WAN收到的数据打上 tag 后从 LAN port 发出;端口收到的包根据 tag 决定其 VLAN。如果路由器WAN接光猫LAN(路由器拨号),路由器里也需要把 WAN VLAN (对于上面的斐讯K2上配置,即为 VLAN 2)端口列表里的 WAN port (port 4) 设为 t 模式。

光猫某个端口最多只能绑定一个WAN连接;如果某个端口绑定了WAN连接,是否还能设置这个端口的VLAN绑定?(如果能设置,则这个端口最终类似于 trunk 模式)

PS. 电信光猫管理界面的VLAN绑定设置里“端口列表”里还包含了 SSID,不明白何意,802.11 Wireless frame 是没有 VLAN tag 字段的。(例外:802.11e 允许配置将 vlan id 映射为 wireless mac frame 里的 priority 字段;部分企业级路由支持 802.11e 协议)

光猫桥接 + 交换机 + AP

测试环境是电信宽带 + 中兴F450 光猫(4个LAN口,其中网口1是千兆口,其余是百兆口)。

最简单的方案(测试通过)

路由器 WAN 接光猫的网口1拨号。

光猫里把 "Internet"(桥接) 这个连接取消绑定所有端口或绑定所有端口。

光猫的用户侧管理里配置IP为局域网IP和网段。

OpenWrt 路由器的交换机配置里把 WAN 接口加入 VLAN 1 (即 LAN 的 vlan), 属性设置为 untagged。把 vlan 2 (wan vlan)的 WAN 接口属性改为 tagged(默认是 untagged)。

这样做后就通了。但是理论上仍然有不明确的地方,这个光猫配置界面太傻逼,VLAN / 接口绑定配置项说明不清不楚的。从目前测试来看,似乎光猫的(用户侧)VLAN 绑定仅仅是针对“LAN <-> WAN”通信而言的,对于 LAN 口之间光猫不支持也不区分 VLAN, 所有 LAN 接口(以及无线 SSID)之间都是互通的(不管在连接设置里里是否绑定某些接口到连接),LAN 之间转发时应该原样保留数据帧(不会增加、修改或移除 VLAN tag)。

可以在光猫VLAN绑定设置里绑定网口1的 VLAN 2 到"Internet"连接。但不设置这个也可以通。原因似乎因为对于路由器而言 WAN 这个 vlan 只有自身使用,没有任何转发,而对于自身收到的包处理时无视是否有 vlan tag?

另一个方案(未测试)

OpenWrt 路由器WAN单根线连接光猫。路由器里默认配置了2个VLAN:

  • VLAN 1: 0 1 2 3 6t (LAN网络)
  • VLAN 2: 4 6t (WAN网络)

以电信中兴F450 光猫为例(需要已获取到光猫超级管理员权限)。光猫4个网口 1,2,3,4,假设 1 接路由器 WAN,2,3,4 当作 LAN 交换机端口用。

光猫管理界面 网络 - 网络连接设置页面,原有的 Internet (桥接) 连接不绑定任何端口(取消原 Internet 连接绑定的所有端口)、不使能 dhcp。

增加一个桥接类型连接,用于本地LAN网络,如取名为 Lan;绑定无线 SSID 到此连接。绑定 2,3,4端口到此连接。

在 网络 - VLAN 绑定里绑定用户侧 VLAN 1 到光猫的 Lan 接口;绑定用户侧 VLAN 2 到光猫的 Internet 接口;

光猫 网络 - 用户侧管理里配置光猫自己的 IP / 子网掩码 为局域网网段。

然后在OpenWrt路由器交换机设置里,把 VLAN 1 的 WAN 口属性由 off 改为 tagged;把 VLAN 2 的 WAN 口属性由 untagged 改为 tagged。

这样搞完后光猫的无线可以直接当AP用。端口1连接路由器,端口 2,3,4可以当作交换机端口使用。

Firewall rules (iptables)

自定义 iptables 规则文件:(先测试OK了再写入这个文件,避免配置失误把自己挡在路由器外面了)

/etc/firewall.user

/etc/init.d/firewall restart 生效。

Tips & Solutions

修改 Web UI 端口

Web UI 默认使用 80 端口。修改方法:编辑 /etc/config/uhttpd ,修改下面几行。

config uhttpd 'main'
        list listen_http '0.0.0.0:80'
        list listen_http '[::]:80'

重启 uhttpd 服务以使更改生效:

/etc/init.d/uhttpd restart

必须安装的软件包

opkg update
opkg install coreutils-nohup curl

  • coreutils-nohup: nohup

获取 WAN IP / 默认网关 IP 等

# 获取 WAN IP(OpenWRT 独有)
ubus call network.interface.wan status | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
# 获取 WAN IP (Linux 通用)(需要 GNU Grep -P (--perl-regexp)支持)
ip route get $(ip route show 0.0.0.0/0 | grep -oP 'via \K\S+') | grep -oP 'src \K\S+'

# 获取某个网卡(iface) IP (Linux 通用)。如果是 PPPoE 拨号方式上网,那么 pppoe-wan 网卡 IP 就是 WAN IP
ip addr | grep pppoe-wan | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1


# 获取默认网关 IP (Linux 通用)
ip route show 0/0 | head -n1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
# 改进版(能够匹配 default via 10.0.0.1 dev ens3 proto dhcp src 10.0.0.2 metric 100 里面的 10.0.0.1。
ip route show 0/0 | head -n1 | grep -oP '(?<=via\s)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

# 获取 WAN 网卡名 (wan / pppoe-wan 之类)
ubus call network.interface.wan status | grep l3_device | sed -n 's/^.*:\s*"\(.*\)".*$/\1/p'

Use DDNS for PPPoE WAN

使用 DDNS 以远程管理 OpenWRT 路由器。

dynu.com

# vi /lib/netifd/ppp-up
IP=`ubus call network.interface.wan status | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}';`
curl -k --user username:password "https://api.dynu.com/nic/update?hostname=user.dynu.com&myip=${IP}"
# myip 参数可省,默认为此 http 请求的 src IP。
# username 和 password 也可以通过 dynu API URL 里的 query parameters 传递。
  • 可以使用自己的某个二级域名 CNAME 到 DDNS 服务商提供的域名上去。
  • 要想远程连接路由器,还必须修改 OpenWrt 的 iptables 防火墙配置以允许来自 WAN 的 INPUT 流量。

PPPoE ip-up-script

推荐方法:使用 Hotplug 脚本。当某个网卡状态发生变化(up/down)时,OpenWrt 会用 Shell 执行 /etc/hotplug.d/iface 里所有脚本。

/etc/hotplug.d/iface 目录里的所有脚本文件名规范是"优先级-名称",如 "01-mvifcreate","95-ddns"。优先级数字较小的先执行。被执行的脚本会通过环境变量接收到以下参数:

  • $INTERFACE : 状态发生变化的网络接口名, ,如"wan"
  • $ACTION : 网卡事件名,枚举: ifup, ifdown
  • $DEVICE : 物理设备的名称,如"br-lan"

脚本示例:(注意: hotplug.d 脚本是通过 source 执行的。所以脚本里面不要出现 exit,否则可能破坏其它脚本的执行)

#!/bin/sh
[ "$ACTION" == ifup ] && echo Up

95-ddns

#!/bin/sh

[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && {
  echo wan_up
  /usr/bin/ddns.sh
}

不推荐方法:

/lib/netifd/ppp-up

这是 PPPoE 拨号成功时执行的脚本。在这里可以做:

  • 重新连接 VPN
  • 调用 DDNS 的 (http) api 以更新路由器 WAN IP。

PPPoE 重新连接

/etc/init.d/network restart

允许指定 IP 从 WAN 访问路由器 ssh

首先在路由器管理界面 -> 系统 -> 管理 -> Dropbear 实例,将 Dropbear(ssh server)监听接口改为 "未指定"(即监听 0.0.0.0) 并 "保存&应用" 即可。然后设置防火墙规则,有两种方式:

方式1: iptables

# 每个白名单 IP 添加一条 iptables 规则
iptables -I INPUT 1 -s 1.2.3.4 -j ACCEPT

方式2: iptables + ipset

ipset create trust hash:ip
ipset add trust 1.2.3.4
# add more ip

iptables -I INPUT 1 -m set --match-set trust src -j ACCEPT

允许从 WAN 连接路由器 Web UI

中国国内的宽带一般封了 80 等端口,所以如果需要从公网访问路由器 Web 管理界面时,除非更改默认的 80 端口,否则需要额外映射一个端口到 80:

# 亲测傻逼电信把 8080 也封了。下面示例用 8081 端口。
iptables -t nat -I PREROUTING 1 -i pppoe-wan -p tcp --dport 8081 -j REDIRECT --to-port 80

然后可以使用 http://IP_or_DDNS_DOMAIN:PORT/ 访问路由器 Web UI。

备注:需要配合上面的“允许指定 IP 从 WAN 访问路由器 ssh”使用。

KMS

IPv6

2018-05 测试电信宽带能够 pppoe 拨号获取到 WAN IPV6,分配到的是一个 240e::/64 地址块。但是某些版本 OpenWRT 固件配置有问题,虽然能获取到 IPV6 地址,但却无法通过 IPV6 上网,表现为 ping IPV6 地址时直接失败(但通过 VPS 能 ping 通路由器的的 IPV6 地址)。

修复:添加默认 ipv6 路由:

# pppoe-wan 是 WAN 接口名
ip -6 route add from :: dev pppoe-wan

然后在 Web UI 里:

接口配置(Network - Interface):清空 ULA-prefix。

接口配置 - LAN - DHCP 服务器 - IPV6 设置里,将 "RA"(路由通告服务), "DHCPV6", "NDP" 这三个选项均设为 "Relay" (中继模式)即可。


Last update: 2022-05-24 06:30:17 UTC