Showing posts with label OpenWrt. Show all posts
Showing posts with label OpenWrt. Show all posts

Friday, March 27, 2026

Block guest WiFi clients from reaching other hosts on LAN

On Openwrt 25.12, I set up a guest wifi bridge onto LAN,

config wifi-iface 'wifinet2'
    option device 'radio1'
    option mode 'ap'
    option ssid 'xxxx'
    option encryption 'sae-mixed'
    option key 'xxxxxxx'
    option ocv '0'
    option ieee80211w '2'
    option ifname 'wifi-guest'
    option network 'lan'

However, I want to block hosts on the guest wifi from reaching other hosts on br-lan except the router.

I used the following config.

in  /root/guest_isolate.nft 

table bridge guest_isolation
delete table bridge guest_isolation

table bridge guest_isolation {
  chain forward {
    type filter hook forward priority 0; policy accept
    iifname "wifi-guest" counter drop
  }
}

in /etc/config/firewall

config include
        option type 'nftables'
        option path '/root/guest_isolate.nft'
        option position 'ruleset-post'

kmod-nft-bridge package must be installed.

Monday, February 17, 2025

Block clients of a specific AP from accessing WAN on OpenWrt 25.12

I updated this post to target the latest Openwrt 25.12 release. 

I wrote a post on blocking clients of AP from Internet access on Mikrotik router a while ago at https://jim-think.blogspot.com/2023/04/block-internet-access-for-iot-devices.html

I have become dissatisfied with MikroTik's WiFi compatibility. So I switched to Openwrt.

Steps

0. apk add kmod-nft-bridge

1. Add a WiFi interface for restricted devices.

config wifi-iface 'wifinet2'
    option device 'radio1'
    option mode 'ap'
    option ssid '<redacted>'
    option encryption 'psk2+ccmp'
    option key '<redacted>'
    option ocv '0'
    option network 'lan'   // bridged to lan
    option ieee80211w '1'
    option ifname 'no-internet'  // remember this

 

2. Create a file at  /root/no_internet.nft with following contents.

table bridge filter
delete table bridge filter
table bridge filter {
    chain prerouting {
        type filter hook prerouting priority dstnat; policy accept;
        iifname "
no-internet" mark set 0x1984
    }
}

3. Add firewall rules in /etc/config/firewall

config rule
    option name 'block-no-internet'
    list proto 'all'
    option src 'lan'
    option dest 'wan'
    option target 'REJECT'
    option mark '0x1984'

config include
    option    type        'nftables'
    option    path        '/root/no_internet.nft'
    option    position    'ruleset-post' 

4. Reboot or run service firewall restart.

5. Run nft list ruleset to verify. 

References

https://wiki.nftables.org/wiki-nftables/index.php/Setting_packet_metainformation#packet_mark

https://openwrt.org/docs/guide-user/firewall/fw3_configurations/bridge 

https://openwrt.org/docs/guide-user/firewall/firewall_configuration#includes_2203_and_later_with_fw4

Saturday, March 25, 2023

Belkin RT3200 wireless router review

The Belkin RT3200 is a very cheap ($50 on Walmart) WiFi 6 router based on MediaTek's MT7915 + MT7622 solution. It is extremely similar to Linksys E8450. (Foxconn owns Linksys and Belkin.)

Hardware highlights (source):
 - CPU: MT7622BV (2x ARM Cortex-A53 @ 1350 MHz)
 - RAM: 512MB DDR3
 - Flash: 128MB SPI-NAND
 - Ethernet: MT7531BE switch with 5 1000Base-T ports
 - WiFi 2.4 GHz: 802.11bgn 4T4R built-in antennas
                 MT7622VB built-in
 - WiFi   5 GHz: 802.11ac/ax 4T4R built-in antennas
                 MT7915AN chip on-board via PCIe
                 MT7975AN front-end

The router's stock firmware was okay but sluggish. I followed this to install OpenWrt. Just be sure to 1) backup the factory bootrom; 2) use UBI images ending in itb.

Then I enabled beam forming and BSS coloring and ran iperf3. It achieved ~450 Mbps in both direction between my wireless laptop with Intel AX201 and a wired NAS. The laptop was about 8 meters away from the router.

I then switched the bandwidth from 80MHz to 160MHz. But iperf3 did not show improvements. So I reverted the change.

I also connected EA7500 to RT3200. They negotiated a PHY rate of 1733 Mbps. But the iperf3 test was only ~480 Mbps.

I did not enable WED or HW offloading as I configured the router to be an access point.

Conclusion

If you have a decent 802.11ac wave 2 router, replacing it with RT3200 will not increase the throughput much. But it is a good cheap router if you do not have one yet.


Friday, April 1, 2022

NAT64 (RFC 6146) and DNS64 (RFC6147) on OpenWrt 21.02

Tested on OpenWrt 21.02.02 on Linksys EA8300.

 

NAT64

opkg update && opkg install kmod-jool jool-tools

Add the following to /etc/rc.local

insmod jool_common
insmod jool
jool instance add --netfilter --pool6 64:ff9b::/96

DNS64

Add the following to the LAN's dhcp section in /etc/config/dhcp

    list dns '2001:4860:4860::6464'
    list dns '2001:4860:4860::64'

References

Sunday, March 13, 2022

Fixing AT&T fiber's connectivity to China on OpenWrt

Note: AT&T fiber's IPv6 and IPv4 connectivity to China was restored as of Jan 2023. So the workaround below is unnecessary.

I switched to AT&T fiber last month and then found out that I could not open douban.com anymore. Some web search led me to https://www.reddit.com/r/ATT/comments/mbutte/is_att_blocking_china_internet_backbones/

So basically AT&T fiber has connectivity issue with IPv4 addresses in China. And they are unwilling to admit it or fix it. So I had three options,

  1. Switch back to Comcast.
  2. Install VPN on my devices and turn on VPN when I want to visit Chinese websites.
  3. Connect my router to a VPN and change its routing table to use the VPN for IPv4 addresses in China.

Option 1 is not preferred because Comcast's cable network has abysmal upload speed. Option 2 is feasible but requires VPN on my laptop, phone, and tablet. So I chose option 3.

Although AT&T fiber does not allow customers to bring their own router, the AT&T router supports IPv6 prefix delegation and IPv4 port forwarding. So I installed a OpenWRT router behind the AT&T one.

I configured wireguard on OpenWRT to connect to a VPS. Then I downloaded a list of IP net blocks in China from ip2location. I wrote a script to convert the list to a big OpenWRT static route config file and appended it to /etc/config/network. Then I executed service network reload. However, the command hung. It seemed OpenWrt could not handle 7000+ static routes. So I gave up on this option.

Eventually I worked out a solution using ipset, iptables, and shadowsocks.

1) Install shadowsocks on the VPS and configure it to run as a server.

2) Install shadowsocks-libev on OpenWrt and configure it to run ss-redir on port 2333.

3) Install ipset on OpenWrt.

4) On OpenWrt, create a file at /root/ipset.conf with following contents,

create china hash:net family inet hashsize 2048 maxelem 65536
add china 223.223.192.0/20
add china 47.89.54.0/23

repeat the "add china" pattern for all ip blocks in China.

5) On OpenWrt, append the following to /etc/firewall.user. This will instruct iptables to redirect all TCP connections to China to the ss-redir port.

ipset restore < /root/ipset.conf
iptables -t nat -A prerouting_lan_rule -p tcp -m set --match-set china dst -j REDIRECT --to-port 2333

6) Run service firewall restart on OpenWrt. (Or simply reboot OpenWrt)

7) Visit https://www.123cha.com. It should display the IP of the VPS.

Tuesday, March 1, 2022

Setting up 802.11s mesh on OpenWRT 21.02 routers

Update: I ran iperf3 on both 802.11s and WDS modes. 802.11s got about 150Mbps, while WDS had more than 200 Mbps. I reverted my setup to WDS.


I have two routers, Linksys EA7300v2 and Lenovo Y1, both running OpenWrt. I use WDS between them to build a wireless bridge. Recently I learned that WDS is deprecated and 802.11s is the replacement.

Here are steps to create a 802.11s mesh on OpenWrt 21.02,

1) Run command iw list | grep "Supported interface modes" -A 9 and check if the output contains "mesh point". If it does not, then the wireless driver does not support 802.11s.

2) Opkg remove the wpad-basic-wolfssl package and then install wpad-wolfssl. Because the former does not support mesh.

3) Reboot the device.

3) Append the following config to both devices' /etc/config/wireless file,

config wifi-iface '{set_a_name}'
    option device '{set_accordingly}'
    option mode 'mesh'
    option mesh_fwding '1'
    option mesh_rssi_threshold '0'
    option network 'lan'
    option mesh_id '{set_the_same_id}'
    option encryption 'sae'
    option key '{set_the_same_key}'
    option ifname 'wlan-mesh'

4) Run wifi reload.

5) Wait a few seconds and run iw dev wlan-mesh station dump. If the output is not empty, then the mesh setup is successful.

6) If the output is empty after a few minutes, run logread and see if there are any errors. I found that the EA7300 would fail to start the mesh if I set the channel to auto or a DFS channel. But the Lenovo Y1 does not have this problem. So I manually set the radios on both devices to channel 48 and it worked after wifi reload. 

References

  • https://openwrt.org/docs/guide-user/network/wifi/mesh/80211s
  • https://www.cwnp.com/wp-content/uploads/pdf/802.11s_mesh_networking_v1.0.pdf
  • https://www.simianer.de/blog/home-wifi-setup-with-802.11s-meshing-and-802.11r-roaming

Thursday, August 3, 2017

Policy Based IPv6 Routing on LEDE

My home router runs LEDE 17.01. It has two IPv6 connections, an ISATAP tunnel and TunnelBroker. The ISATAP connection has shorter latency than the TunnelBroker. However, ISATAP only allows one IPv4 address to have one IPv6 address. In order to let my home computers have IPv6 connections, I have two choices. The first is to use NAT on IPv6 so that hosts behind the router appears as one hosts on the IPv6 Internet. The second choice is to assign home computers addresses allocated on TunnelBroker and route all their traffic through TunnelBroker. And installing a SOCKS/HTTP proxy on the router, so a host can enjoy the low latency ISATAP link via the proxy.

So, I configured the router to have the following IPv6 routing table

default from 2001:xxxxx::/64 dev 6in4-henet proto static metric 16 pref medium
default from 2001:xxxxx::/64 dev 6in4-henet proto static metric 16 pref medium
2000::/3 via 2001:da8:xxxx dev isatap src 2001:da8:xxxx metric 2 pref medium

As a result, the router will opt for the ISATAP link over the TunnelBroker link. However, I found that although hosts behind the router can get IPv6 addresses, they cannot connect to any IPv6 hosts outside my home, because the router puts all IPv6 traffic whose destination matches 2000::/3 through the ISATAP link!

Later, I came up with a solution. Linux supports policy-based routing. So the router can have two IPv6 routing tables, namely the `main` and `henet` table. For IPv6 packets whose source addresses are within my TunnelBroker's block, the router should lookup the `henet` table, which contains

2001:xxxxx/64 dev br-lan
default from 2001:xxxxx::/64 dev 6in4-henet

I wrote a script to achieve this effect

ip -6 route flush table henet
ip -6 route add 2001:xxxx/64 dev br-lan metric 128 table henet
ip -6 route add default dev 6in4-henet metric 256 table henet
ip -6 rule add from 2001:xxxxx/64 table henet

You should also add `252 henet` to /etc/iproute2/rt_tables before invoking the above commands.

Thursday, August 25, 2016

Setting up IKEv2 with strongSwan on OpenWrt 15.05.1

I have been using OpenVPN on my OpenWrt router for remote access. OpenVPN is a SSLVPN solution similar to Anyconnect from Cisco. IPsec is a IETF standard for providing network layer security. The support of IPsec is builtin to recent Linux kernel. However, the kernel needs the encryption key before setting up IPsec. You can manually create IPsec tunnels with a preshared key, but this approach does not support mobile clients which have dynamic IP addresses.

The Internet Key Exchange protocol is aimed at negotiating security parameters before setting up an IPsec tunnel. Usually, an IKE daemon listens on UDP/500 for requests and then does several rounds of exchanges with the remote client and then send negotiated parameters to the Linux kernel and thus sets up an IPsec tunnel.

IKEv2 is the latest one which is much easier to deploy than its predecessor IKEv1. StrongSwan is an IKE daemon with full support of IKEv2. To install strongSwan on OpenWrt, you need install strongswan-minimal package. You also need to install strongswan-mod-openssl in order to use pubkey authentication.

There are several configuration files:

/etc/ipsec.conf contains information of IPsec tunnels.
/etc/strongswan.conf contains configuration for strongswan.
/etc/ipsec.secrets contains various credentials of IPsec tunnels.


The following is all needed to setup a tunnel with PSK. PSK is not so safe as public key, especially if the PSK is very weak.

in /etc/ipsec.conf:

conn mytunnel
left=%any
 leftsubnet=10.1.0.0/16
leftid=home
leftfirewall=yes
right=IP_OF_THE_PEER
 rightsubnet=10.2.0.0/16
rightid=moon
auto=add
mobike=no
authby=psk

in /etc/ipsec.secrets:

moon : PSK YOUR_PSK_FOR_TUNNEL

use `ipsec up mytunnel` to establish the tunnel and `ipsec statusall` to check tunnel status.

Friday, December 4, 2015

How WiFiDog Works

I introduced WiFiDog in a previous post. In this post, I examine how WiFiDog works by exploiting Netfilter/Iptables.

WiFiDog creates the following chains in magle table, WiFiDog_br-wlan_Incoming /Outgoing /Trusted, and WiFiDog_br-wlan_AuthServers /Global /Internet /Known /Locked /Unknown /Validate in filter table. br-wlan is the GatewayInterface set in /etc/wifidog.conf

WiFiDog_br-wlan_Outgoing is chained in mangle PREROUTING. If a client passes authentication, WiFiDog daemon inserts a rule in WiFiDog_br-wlan_Outgoing, marking the packets from this user with mark 0x2.

WiFiDog_br-wlan_Internet is chained in filter FORWARD table. The contents in this chain is derived from /etc/wifidog.conf, which resembles the following:

Chain WiFiDog_br-wlan_Internet (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere             state INVALID
TCPMSS     tcp  --  anywhere      anywhere    tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
WiFiDog_br-wlan_AuthServers  all  --  anywhere        anywhere            
WiFiDog_br-wlan_Locked  all  --  anywhere             anywhere         mark match 0x254
WiFiDog_br-wlan_Global  all  --  anywhere             anywhere            
WiFiDog_br-wlan_Validate  all  --  anywhere           anywhere         mark match 0x1
WiFiDog_br-wlan_Known  all  --  anywhere              anywhere         mark match 0x2
WiFiDog_br-wlan_Unknown  all  --  anywhere            anywhere            

At this point, WiFiDog is capable of separating known users and unknown users. However, there is one more thing, redirecting unknown users to the web portal. This is done with WiFiDog_br-wlan_Unknown chain in the nat table. There is a rule:
REDIRECT   tcp  --  anywhere             anywhere         tcp dpt:www redir ports 2060
which redirects unkown user's HTTP connection to 2060 port on the router.

Enable Web Proxy Auto-discovery on OpenWrt with Dnsmasq

Recently, I set up shaodowsocks and polipo on an OpenWrt router. I'd like every client connected be able to bypass the Great Fire Wall of China automatically. This can be done by pushing an proxy auto-config to the client. And there exists a protocol called Web Proxy Autodiscovery (WPAD).

Dnsmasq is capable of WPAD. Just add this line in /etc/config/dhcp.conf under config dhcp lan section

list dhcp_option '252,http://192.168.10.1:8000/proxy.pac'

the HTTP URL should be replaced adequately. There should be no spaces between the comma and URL. You can convert GFWlist to a PAC file with gfwlist2pac.

A note for iPad users:
iPad do not enable WPAD by default (because WPAD can redirect a client's HTTP connection without informing the user). The user can enable it in the configuration for wireless access points.

Saturday, November 21, 2015

WifiDog on Openwrt

WifiDog is a Captive Portal on Openwrt. It utilizes Linux netfilter in order to force a client to log in before granting access to the Internet. Although there is a Wifi in its name, it can work on wired network as well. WifiDog has two components, a gateway and an auth server. The gateway is running on an access point, and redirects unknown clients to the auth server's login page. The auth server is simply a Web server which implements WifiDog's auth protocol.

To install wifidog gateway on openwrt, just type opkg install wifidog in command line. It's config file is at /etc/wifidog.conf. You may want to customize GatewayID, GatewayInterface,  AuthServer, CheckInterval, and TrustedMACList. The comments in the config file explains these options clearly.

The crucial part is the AuthServer section. Upon connection, the client will be redirected to the auth server for authentication. You should have at least one AuthServer section. If you have multiple AuthServer sections, WifiDog will use the first auth server that responses to its ping request. The auth server implements wifidog's auth and ping protocols. An auth server written in php is available at https://github.com/wifidog/wifidog-auth. You may also write an auth server which suits you need. I have written one in python.

You should understand wifidog's protocols before writing an auth server. The protocol is fully describe in http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1. I will give a summary below.

Wifidog gateway keeps a list of authorized users' IP, MAC and token. If an unknown user tries to visit a website, it will be redirect to the auth server's login page. If login is successful, the user will be redirected to the gateway's portal with the URL containing the user's IP, MAC and token (a random string). The gateway will verify these information with auth server via auth protocol. Every check interval (default value is 60 seconds), the gateway will contact the auth server and check every user's token by the auth protocol. If the re-authorization for a user fails, the gateway will remove the user from the list and then blocks its internet access. The auth protocol also allow the gateway to send accounting information for a user to the auth server.

Thursday, October 29, 2015

Connecting two networks with OpenVPN

I have two routers in two cities, both is connected to the Internet via different ISPs. I wanted to let computers behind both routers to be able to talk to each other directly (without port forwarding and other stuff).

Firstly, I set up a OpenVPN server in p2p mode with static keys, whose IP address is 129.168.20.1, on one router, and a p2p client, whose IP address is 192.168.20.2, on the other router. Below are their configuration files:

p2pserver.conf
-------------------------------
mode p2p
proto udp
port 2333
dev tun
ifconfig 192.168.20.1 192.168.20.2
secret static.key
mssfix 1450
verb 1
log /tmp/p2p.log
keepalive 10 120
persist-tun
persist-key
route 192.168.99.0 255.255.255.0

p2pclient.conf
---------------------------------
mode p2p 
proto udp 
dev tun
remote server's_domain name 2333
ifconfig 192.168.20.2 192.168.20.1
verb 1
secret static.key
keepalive 10 120
log /tmp/p2p.log
mssfix 1450
route 192.168.33.0 255.255.255.0


There is one thing to notice. You should add route of the other end's subnet, so that all traffic to the other subnet will be forwarded through the tun device. To enable forwarding through tun device, you should add firewall rules.

Firstly, add following lines in /etc/config/network

config interface 'p2phome'
option ifname 'tun0'
option _orig_ifname 'tun0'
option _orig_bridge 'false'
option proto 'none'

Then, add the new interface to the lan zone of firewall. And enable forwarding in the lan zone. This can be done with OpenWRT's Web UI.

Saturday, August 29, 2015

Openconnect Server (ocserv) on Openwrt

I'd like to set up a VPN server on a router running Openwrt. There are several choices, L2TP, PPTP, OpenVPN and openconnect. PPTP is not very secure. L2TP must be used with IPSec for security. While OpenVPN and openconnect are both SSL-VPN. They are easy to configure and adaptive to the restrictions of ISP. Because there is a luci app for openconnect server. It's easier to set up than OpenVPN. I would set up an openconnect server, which operates in pseudo-bridge mode, meaning remote clients are on the same subnet as the computers at home.

Tuesday, July 28, 2015

Openwrt Synchronized Wifi Hotspot

There are three wireless routers at my home. All run Openwrt. One acts as gateway. The other two are APs. Sometimes, my mother wants to turn off WiFi before sleep. She would power off the gateway router. As a result, all clients will connect to the other two APs, and cannot access the Internet.

I want to make things more elegant. When the two APs detect that the gateway is down, they will turn off their wifi as well, and turn it on when the gateway is online again. Fortunately, the two APs have enough ROM for python. So I need not mess around with shell scripts.

Friday, July 24, 2015

Netgear WNR2000 v4 刷 OpenWrt 和 Gargoyle

最近淘了一个二手的WNR2000,硬件版本v4,使用AR9341单芯片方案,4MB闪存,32MB内存。发现自带固件功能太弱,可玩性不高,故刷Openwrt.

WNR2000是Openwrt支持的硬件,可以参考http://wiki.openwrt.org/toh/netgear/wnr2000,但是这个网页里的信息过时了。telnetenable已经不适用于这台WNR2000。可喜的是电路板上留有TTL焊盘,焊上排针就可以使用。离网络口隔离变压器最远的是GND,然后是RX,TX,波特率是115200。

连接上TTL即可看到终端,官方固件是基于Openwrt改造的,进入终端还有Openwrt的字符画。不过可用的指令很少。

Wednesday, February 25, 2015

Openwrt配置6in4

美国一家ISP, Hurricane Electric提供免费的IPv6接入的服务,叫做Tunnel Broker, 这个服务使用了6in4转换机制。用户只需要在网站注册,就可以申请免费的6in4隧道。不过有一个限制是Endpoint必须有公网IP。

对于刷好Openwrt Barrier Breaker的路由器,只需要简单的操作就可以实现6in4

1. 在tunnelbroker上申请一个隧道,申请时可以选择ping延迟最低服务节点。申请成功后会获得一个页面,里面有配置6in4的全部信息。

2.在Openwrt中新建一个Interface,名称为henet,选择Protocol为6in4,如果没有这个选项,请安装luci-proto-ipv6,6in4软件包,点击Sumbit

3.修改将tunnelbroker上的信息填入henet的配置中,具体可以参考http://wiki.openwrt.org/doc/uci/network#protocol_6to4_ipv6-in-ipv4_tunnel如果你的公网IP会变化,需要勾选,并填写一些信息,Update Key可以在Tunnel Details页面的Advanced选项中看到。

4.将henet的firewall zone设置为wan。

5. 在/etc/config/firewall下添加:
    config rule
    option src 'wan'
    option target 'ACCEPT'
    option proto '41'


6.修改/etc/config/network,在lan下添加option ip6addr,其后地址可以从Routed /64中任选一个。

重新启动路由器,并且刷新本机的DHCP,就可以获得一个公网IPV6地址了。测试网址http://test-ipv6.com/

不过,由于中国内并没有服务节点,最近的节点延迟也有100ms+,加之国际出口带宽有限,这种方式获得的IPv6质量很不好。

Sunday, February 22, 2015

Openwrt配置WLAN漫游

Update:

802.11f was deprecated. The new kid in town is 802.11r. OpenWrt 21.02 supports 802.11r. Here is a post on how to enable it.

家里有两台无线路由,都以AP的形式接入LAN。而我希望做的是能让无线设备在两个AP中选择信号最好的接入,并且实现漫游。

我所在大学的无线网络支持在同一个AC下漫游,因为学校采用的是H3C的解决方案,他们的私有技术可以支持接入点的快速切换。而我家中的路由一个是ralink的方案,一个是atheros的方案,不过它们都刷了OpenWrt系统。上网搜索后发现802.11协议只支持由客户端(比如手机)发起的切换。与GSM的handover不同,802.11的handover必须先断开链接,再建立新的链接。

要实现漫游,只需要把两个接入点的SSID,加密方式(我使用WPA2-PSK-CCMP)和密钥保持一致,两个AP使用不重叠的信道。

此外,还有一个802.11f协议,用于支持不同厂商AP之间的通信。要在Openwrt上开启这个协议,只需要在/etc/config/wireless里面增加一个 iapp_interface 字段,可以参考这个wiki.

应用这些设置后,我的小米手机可以自动在两个接入点中漫游,切换延迟大约半秒。