Android Phone 的强制门户没有弹出

Captive Portal for Android Phone did not pop up

我使用 hostapd、dnsmasq 和 apache2 在我的 Raspberry Pi 3B+ 上实现带有强制门户的 wifi 热点,在我实现这个项目之前,我从未接触过 wifi 网络。因此,我搜索了很多 post 如何实现一个。

以下是我使用的配置:

/etc/apache/apache.conf:

# Apple
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^CaptiveNetworkSupport(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^192.168.0.200$
RewriteRule ^(.*)$ http://192.168.0.200/index.html [L,R=302]

# Android
RedirectMatch 302 /generate_204 http://192.168.0.200/index.html

# All
RewriteCond %{REQUEST_URI} !=/index.html
RewriteRule ^(.*)$ http://192.168.0.200/index.html [L]

# 404 Redirect
ErrorDocument 404 http://192.168.0.200/index.html

/etc/dnsmasq.conf:

interface=wlan0
dhcp-range=192.168.0.201,192.168.0.210,255.255.255.0,24h
address=/#/192.168.0.200

我用索尼H4133、华为RNE-22、红米Note3、三星Galaxy S8+、三星Galaxy Tab S测试门户。只有 Sony 一个像魅力一样工作。 Tab S 可以弹出通知,但当我单击它时,它会将我转到 google.com 而不是我的门户。而其他人甚至没有显示弹出窗口。

我检查了 access.log 并发现 /generate_204 确实是 302 重定向到我的页面和 return 一个 200 代码。根据我的研究,除了 204 之外的任何代码 return 都应该出现在弹出窗口中,但为什么这里不是这种情况?

access.log:

192.168.0.204 - - [04/Jan/2020:12:20:10 +0800] "GET /index.html HTTP/1.1" 200 899 "-" "MQ 3.3.8/3.0 (Android 6.0.1) Xiaomi Redmi Note 3"
192.168.0.204 - - [04/Jan/2020:12:20:11 +0800] "GET /generate_204 HTTP/1.1" 302 561 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:15 +0800] "POST /getconfig HTTP/1.1" 302 531 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:15 +0800] "GET /index.html HTTP/1.1" 200 862 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:15 +0800] "POST /mistats/v2 HTTP/1.1" 302 531 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:15 +0800] "GET /index.html HTTP/1.1" 200 862 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:20 +0800] "POST /mistats/v2 HTTP/1.1" 302 531 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"
192.168.0.204 - - [04/Jan/2020:12:20:20 +0800] "GET /index.html HTTP/1.1" 200 862 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; Redmi Note 3 MIUI/V10.2.1.0.MHOMIXM)"



192.168.0.205 - - [04/Jan/2020:12:23:31 +0800] "GET /generate_204 HTTP/1.1" 302 570 "-" "Dalvik/2.1.0 (Linux; U; Android 8.0.0; RNE-L22 Build/HUAWEIRNE-L22)"
192.168.0.205 - - [04/Jan/2020:12:23:31 +0800] "GET /generate_204 HTTP/1.1" 302 560 "-" "Dalvik/2.1.0 (Linux; U; Android 8.0.0; RNE-L22 Build/HUAWEIRNE-L22)"
192.168.0.205 - - [04/Jan/2020:12:23:31 +0800] "GET /generate_204 HTTP/1.1" 302 560 "-" "Dalvik/2.1.0 (Linux; U; Android 8.0.0; RNE-L22 Build/HUAWEIRNE-L22)"
192.168.0.205 - - [04/Jan/2020:12:23:44 +0800] "GET /generate_204 HTTP/1.1" 302 570 "-" "Dalvik/2.1.0 (Linux; U; Android 8.0.0; RNE-L22 Build/HUAWEIRNE-L22)"
192.168.0.205 - - [04/Jan/2020:12:23:56 +0800] "GET /generate_204 HTTP/1.1" 302 570 "-" "Dalvik/2.1.0 (Linux; U; Android 8.0.0; RNE-L22 Build/HUAWEIRNE-L22)"

apache.conf 是你的问题。以另一种方式配置Apache2。
每个操作系统都有自己不同的检测互联网访问的方式。

机制基本上是这样的:

GET/POST http://x.com/bar.html
If bar.html == [expected content] > Open Internet
If bar.html != [expected content] > Captive Portal
If bar.html[status] != SUCCESS > No Network  

每个设备,也 Android 不同的制造商,行为不同。例如,查看此列表:

xperia z5:
connectivitycheck.gstatic.com:80
clients3.google.com:80
---------------------
galaxy j3 2016:
172.217.21.14:80    connectivitycheck.android.com
---------------------
galaxy j7 2015:
172.16.98.10:80
connectivitycheck.gstatic.com:80
---------------------
galaxy note4:
nothing!
---------------------
ios 11:
captive.apple.com/hotspot-detect.html
---------------------
windows 10:
www.msftconnecttest.com

我建议为每个 device/manufacture 创建另一个 apache 配置文件。


在 apache 中为 android 创建一个目录

cd /var/www/html/
sudo mkdir android 

创建一个简单的 index.html 文件,该文件将出现在 android 设备的初始页面上。

在 nano(或您最喜欢的文本编辑器)中创建 android.conf 并复制以下代码为 Android 设备创建 "redirection rule"。

sudo nano /etc/apache2/sites-enabled/android.conf  

输入这些行:

<VirtualHost *:80>

    Servername connectivitycheck.gstatic.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/android

    RedirectMatch 302 /generate_204 /index.html

    ErrorLog ${APACHE_LOG_DIR}/android_error.log
    CustomLog ${APACHE_LOG_DIR}/android_access.log combined

</VirtualHost>

保存文件并退出。

完成。按照其他设备的程序进行操作。另外,查看 this link 以获取更多信息。

我尝试了几个强制门户,none 适合我的三星设备。我使用 192.168.12.1 作为 IP 地址。

最后,经过多次测试,我找到了解决办法:不能使用像192.186.45.1这样的IP地址,也不能使用我用的IP地址。因此,我将 DNS 服务器 IP 地址设置为 200.200.200.1,并将 DHCP 服务器范围设置为 200.200.200.10 - 200.200.200.250。在这些更改之后,它适用于我测试的所有设备,甚至是三星 Note 8。

谢谢@,确实在 200.200.200.10/200.200.200.250 之间设置 dhcp 范围会触发强制门户和 pop-up 说登录此 wifi 我正在使用 dnsmasq,

--dhcp-range=200.200.200.10,200.200.200.250,255.255.255.0,8h

并重定向到托管强制门户页面的 apache 服务器 --address=/#/200.200.200.1

测试于:

•三星 j7 pro 2019 Android 9 dhcp-9

•三星 A70 2020 Android 11 dhcp-11

•华为p smart 2019 dhcp-10

•android 4.4 KitKat dhcp-5.5