Extend the captive portal via Wi-Fi and allow each user to use their own account

Hi, I created a repeater with my Comfast CF-EW72 v2 running OpenWrt 25.12.4. When a user logs into the captive portal with their account, it unlocks the entire network and everyone can connect without an account. Please help me find a solution to this problem.

It sounds like the captive portal is only seeing the repeater as one client, so once that MAC/IP is allowed everyone behind it looks allowed too. If the Comfast is doing NAT, try to avoid that and keep clients bridged so the portal can see each device separately. If you really need per-user logins, it is usually cleaner to run the portal on the main gateway/AP side, not behind a repeater that hides the clients.

If you want each user checked separately, the repeater must not hide the clients behind one IP/MAC. First check whether the CF-EW72 is routed/NAT mode or a real bridge/WDS/802.11s-style link. In NAT mode the portal can only allow/block the repeater itself. If you can bridge the wireless clients back to the gateway, then the captive portal should see separate DHCP leases/MACs again.

How can I check if Comfast is in NAT mode?

upstream IP and LAN IP aren't in the same subnet.

The upstream is on: 10.0.0.253/24 and the LAN is on: 192.168.1.1/24

By definition, the captive portal on the upstream (10.0.0.0/24) sees only the router itself and it cannot see the devices behind it. As such, even though you still need to login to the captive portal in general, all devices behind the router are hidden by the NAT masquerading layer and appear only as a single device (i.e. the router itself). Thus, the first device to login to the captive portal is effectively presenting as the router and everything behind the router is thus also authenticated through the captive portal using the initial credentials provided.

To fix this, you need to take the NAT masquerading out of the equation entirely. Essentially, you'll be making your router into a bridged AP.

In this particular case, though, you'll want to setup the wan via a bridge and then connect the wifi to the wan network. And keep your lan separate such that it can be used to manage the device itself (and importantly not expose the router's administrative functions to the upstream untrusted network).

The specific details to achieve this depend on your device (in particular, if it uses swconfig or DSA).

Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button (red circle; this works best in the 'Markdown' composer view in the blue oval):

Screenshot 2025-10-20 at 8.14.14 PM

Remember to redact passwords, VPN keys, MAC addresses and any public IP addresses you may have:

ubus call system board
cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall

for ubus call system board

{
        "kernel": "6.12.87",
        "hostname": "OpenWrt",
        "system": "MediaTek MT7621 ver:1 eco:3",
        "model": "COMFAST CF-EW72 V2",
        "board_name": "comfast,cf-ew72-v2",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "25.12.4",
                "firmware_url": "https://downloads.openwrt.org/",
                "revision": "r32933-4ccb782af7",
                "target": "ramips/mt7621",
                "description": "OpenWrt 25.12.4 r32933-4ccb782af7",
                "builddate": "1778712129"
        }
}

for cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        list ipaddr '127.0.0.1/8'

config globals 'globals'
        option dhcp_default_duid '0004cf1f048740c14095bbaafe526333968b'
        option ula_prefix 'fdca:4f51:53c8::/48'
        option packet_steering '1'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        list ipaddr '192.168.1.1/24'
        option ip6assign '60'
        option multipath 'off'

config interface 'wwan'
        option proto 'static'
        option ipaddr '10.0.0.253'
        option netmask '255.255.255.0'
        option gateway '10.0.0.254'
        list dns '10.0.0.254'
        option multipath 'off'

config interface 'repeater_bridge'
        option proto 'relay'
        option ipaddr '10.0.0.253'
        list network 'lan'
        list network 'wwan'
        option multipath 'off'

for cat /etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
        option band '2g'
        option channel '6'
        option htmode 'HT20'
        option cell_density '0'

config wifi-iface 'default_radio0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'OpenWrt'
        option encryption 'none'

config wifi-device 'radio1'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
        option band '5g'
        option channel '36'
        option htmode 'VHT80'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'OpenWrt'
        option encryption 'none'
        option disabled '1'

config wifi-iface 'wifinet2'
        option device 'radio0'
        option mode 'sta'
        option network 'wwan'
        option ssid 'TP-Link_Outdoor_B0A112'
        option encryption 'none'

config wifi-iface 'wifinet3'
        option device 'radio0'
        option mode 'ap'
        option ssid 'M24g'
        option encryption 'none'
        option wds '1'
        option network 'lan'

config wifi-iface 'wifinet4'
        option device 'radio0'
        option mode 'ap'
        option ssid 'OpenWrt24g'
        option encryption 'none'
        option network 'lan'

for cat /etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option boguspriv '1'
        option filterwin2k '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option nonegcache '0'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option nonwildcard '1'
        option localservice '1'
        option ednspacket_max '1232'
        option filter_aaaa '0'
        option filter_a '0'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/odhcpd.leases'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'
        option piodir '/tmp/odhcpd-piodir'
        option hostsdir '/tmp/hosts'

for cat /etc/config/firewall

config defaults
        option syn_flood '1'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'
        list network 'wwan'
        list network 'repeater_bridge'

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

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

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

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

Ah... ok, I didn't realize that this was using wifi for the upstream connection. This complicates things considerably, as you cannot directly bridge a wifi upstream to a downstream wifi network. To do this, you need to use relayd. This is something of a hack that works in normal wifi environments. I don't know that it is suitable for use with the captive portal scenario, but it might be possible.

Keep in mind that the relayd guide is intended for use with the assumption that the upstream network is fully trusted, so the management of the device is possible on the upstream/relay network. You'll want to make sure that you setup a separate subnet specifically for the device management and then set the firewall such that the upstream/relay networks do not accept input to the router.

Hi, indeed, the router managing the captive portal sees all other users as a single entity (the router) and they have unrestricted access without authentication. Do you have a solution to allow users to authenticate individually?

that would be the link above, or put the captive portal on the extender.

A possible solution was provided above:

I followed the procedures on this page, but once the first person enters their portal login, all others will have internet access without logging in. And when just one user logs out, all the others are disconnected.

Then you're running the captive portal on the relay ?