1

I used hostapd, dnsmasq and apache2 for implementing the wifi-hotspot with captive portal on my Raspberry Pi 3B+, before I implement this project, I have never get in touch with wifi networks. Hence I search a lot of post on how to implement one.

Below is the configuration I used:

/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

I used Sony H4133, HUAWEI RNE-22, Redmi Note3, Samsung Galaxy S8+, Samsung Galaxy Tab S to test the portal. Only the Sony one work like a charm. Tab S can pop up a notification but when I click on it, it send me to google.com but not my portal. While others didn't even show the pop up.

I checked the access.log and find that the /generate_204 indeed 302 redirect to my page and return a 200 code. According to my research, any code return other than 204 should show up the pop up, but why it is not the case here?

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)"
AngusW
  • 15
  • 1
  • 4

3 Answers3

0

apache.conf is your problem. Config Apache2 in another way.
Every operating system has its own different way of detecting Internet access.

The mechanism is this basically:

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  

Each device, also Android different manufactures, behaves differently. For example, look at this list:

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

I suggest make another apache config file for each device/manufacture.


Create a directory for android in apache

cd /var/www/html/
sudo mkdir android 

Create a simple index.html file that is going to appear on the splash page of the android device.

Create android.conf in nano (or your favorite text editor) and copy the following code to create a "redirection rule" for Android devices.

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

Put these lines:

<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>

Save file and exit.

Done. Follow the procedure for other devices. Also, check this link out to get more information.

M. Rostami
  • 999
  • 3
  • 16
  • 27
  • Thanks a lot for your detail explain, it did solve a lot for my confusion. I even implement the ios part with the help for your guide and tested successfully. However, the Samsung Tab S still act the same and I observe that it opens the chrome browser and navigate to google.com instead of opening a dedicated browser for the captive portal. Also, the Redmi and HuaWei device still have no pop up, I suspect that they are not using the standard captive portal checking site due to China internet control policies. – AngusW Jan 11 '20 at 06:04
  • @AngusW My pleasure. Install a [packet monitoring package](https://linuxtechlab.com/install-wireshark-linux-centosubuntu/) and connect your phone to the raspberry pi, you'll find the request of devices. After that, add a new PHP config file to the new device. With Samsung devices, you can find the solution by this method but for the Chinese phone, it's a bit different. – M. Rostami Jan 11 '20 at 10:08
  • Recently, I have configured a captive portal system on Raspberry pi with [the NoDosSplash](https://raspberrypi.stackexchange.com/questions/88438/raspberry-pi-as-access-point-with-captive-portal/106018#106018). It's so great, however, I have the same problem with Chinese phone either. I asked about this problem in [this Github issue](https://github.com/nodogsplash/nodogsplash/issues/478), it would help you. – M. Rostami Jan 11 '20 at 10:11
0

Thanks @Orlando Novas Rodriguez, indeed setting dhcp range between 200.200.200.10/200.200.200.250 triggers captive portal and a pop-up saying sign in this wifi I'm using dnsmasq,

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

And redirecting to apache server hosting the captive portal page --address=/#/200.200.200.1

Tested on:

•Samsung j7 pro 2019 Android 9 dhcp-9

•Samsung A70 2020 Android 11 dhcp-11

•Huawei p smart 2019 dhcp-10

•android 4.4 KitKat dhcp-5.5

Justxd22
  • 1
  • 1
-1

I tried several captive portals and none works for me with Samsung devices. I used 192.168.12.1 as the IP address.

In the end, after many tests, I found the solution: you can't use an IP address like 192.186.45.1 or the one I was using. So, I set the DNS server IP address to 200.200.200.1 and I set the DHCP server range to 200.200.200.10 - 200.200.200.250. After those changes, it worked for me on all the devices I tested, even on the Samsung Note 8.

Kirby
  • 15,127
  • 10
  • 89
  • 104