This article explains how to build a captive web portal with a Raspberry PI, redirecting all clients to a web site on the internet.
This article is based on excellent port of Brennan available on this link (https://brennanhm.ca/knowledgebase/2016/10/raspberry-pi-access-point-and-captive-portal-without-internet/)
Situation
The following schema gives an overall view of the situation
We want that the clients connecting to our Hotspot are automatically redirected to a web site on the internet and nowhere else.
Creating the hotspot
Any router should do the job (here an Asus RT-AC66U)
Configure the router with the following parameters
- Choose the SSID you want (here ASUS)
- Configure the authentication to "Open"
Then, disable DHCP
Then configure the firewall to allow only connection to the captive web site
Configure the Raspberry Pi
Install required packages
Add the two following packages
apt-get install dnsmasq nginx |
- dnsmasq : provides DHCP and DNS services for small networks
- nginx : a web server that will redirect our clients to the captive web site
Configure a static IP address for the Raspberry Pi
sudo nano /etc/dhcpcd.conf |
Modify the file to fit your needs
# Example static IP configuration: |
Configure the hosts file
sudo nano /etc/hosts |
Modify the file like bellow
127.0.0.1 localhost 127.0.1.1 raspberrypi |
Notice the two entries at the end of the file
- 192.168.1.30 is for the local host
- 212.147.79.236 is the ip address of the captive web portal
Dnsmasq will upload this file on startup and answer DNS queries consequently
Configure dnsmasq
sudo nano /etc/dnsmasq.conf |
Modify the file like bellow
# Never forward addresses in the non-routed address spaces. |
Restart dnsmasq
sudo service dnsmasq restart |
This configuration turns the Raspberry Pi into a fake DNS server.
It will resolve all DNS queries to it's own IP address, except the captive web portal (gremaudpi.emf-informatique.ch) that will be resolved to the IP address found in the hosts file (212.147.79.236 )
We can test the result by connecting to our hotspot with a laptop and launch following commands
We can see that www.google.com resolves to the Raspberry Pi address (192.168.1.30)
And our captive web site address (gremaudpi.emf-informatique.ch) resolves to the real address (212.147.79.236)
Configure nginx
Now we want to configure nginx to redirect all http and https requests to our captive web site.
sudo nano /etc/nginx/sites-available/default |
# Default server configuration root /var/www/html; # Add index.php to the list if you are using PHP server_name _; return 302 $scheme://gremaudpi.emf-informatique.ch/hotspot/; |
Remark: Notice the last line that redirect all traffic to the captive web portal by answering with an HTTP status code "302 Found" which is a common way of performing a url redirection. This will allow most smartphones (android and iphones) to spontaneously open a popup to our web site when connecting to the hostspot.
Restart nginx
sudo service nginx restart |
Configure the web site
The web site I will use is very basic and made of three pages
http://gremaudpi.emf-informatique.ch/hotspot/index.html
This page will serve following code
<html> |
http://gremaudpi.emf-informatique.ch/hotspot/page1/index.html
This page will serve following code
<html> |
Test the result
Now, when you connect to the WIFI hotspot with a smartphone,
you should be automatically redirected to the captive web site.
Where you can navigate as you want
The only problem is that I could never get reed of the annoying header "Connexion Wi-Fi requise" nor of the footer "QUITTER"
If you have an idea how to do this, please post a comment.
That's all folks…
Hello,
I've tryed your setup and it's working perfectly as a captive portal, but this configuration is not managing the complete request_uri.
I try to explain: I have to redirect all the people that connects to a particular SSID to mywebsite.com when they try to reach any other website, BUT when they try to reach mywebsite.com/something they were redirected to the "homepage" without the "*.com/something".
I am making a free audioguide for all the people visiting an astrophotography exhibition, pointing the query_uri to the particular photo; for example, audioguide.com/?1 is the first photo, audioguide.com/?2 is the second one and so on.. pointing the /?1 is useless because they are redirected to the main page.
I am looking for a way to resolve this issue for like 2 months, reading nginx configuration and other ways.. please HELP!
If I modify the response of nginx with the line below it works ONLY for the direct query like /?1 /?2 .. but i can't redirect everything to the "home"
return 302 $scheme://audioguide.com/$request_uri
Thanks in advance for your time.
Greetings,
Riccardo