当我们连上某个热点, 会自动弹出登录窗口的专业名称叫做: Captive portal
原理, 实现方式有三种
1 : dns 跳转, 在热点上面实现配置, 把所有dns请求返回都配置为:服务器地址 ;服务器有404跳转或者DNS url跳转 , 跳转到的界面即为自动弹出登录界面;
2 : http跳转,对所有的http请求返回302或者301或者404跳转, 跳转到的界面即为自动弹出登录界面;
3 : ip跳转,既把所有的ip包里的目标地址改为认证服务器,然后在认证服务器上做404跳转
第三种实现起来比较麻烦, 我们要实现第一种和第二种 Captive portal;
配置本地服务器
使用NodeJS搭建一个本地WEB服务器, 服务器端口为默认的80, 无论访问服务器的任意地址 都有正常200返回,app.use函数是精华.., 然后使用node app.js启动服务器:
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var http = require("http"); var index = require('./routes/index'); var app = express(); app.set('views', path.join(__dirname, 'views')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use('/', index); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); //该函数是关键 , 如论用户访问任何页面 , 都会重定向到本地index.html文件 app.use(function(req, res, next) { res.status = 200; res.redirect('/index.html'); }); http.createServer(app).listen(80);
使用HTTP跳转
本机环境是kali系统, 外加一个usb网卡, 使用以下代码实现热点:
#!/bin/bash ## quick and dirty AP with hostapd and dnsmasq ## exit properly with ctrl-c echo "Exit this script with Ctrl-C and it will attempt to clean up properly." if [ -z $1 ]; then echo -n "SSID: " read ssid else ssid=$1 fi # get wep key function get_wep_key() { echo -n "WEP Key [must be exactly 5 or 13 ascii characters]: " read wep_key if [[ $wep_key =~ ^[a-zA-Z0-9]{5}$ ]] ; then echo "Key accepted" elif [[ $wep_key =~ ^[a-zA-Z0-9]{13}$ ]] ; then echo "Key accepted" else echo "WEP key must be exactly 5 or 13 characters" get_wep_key fi } # get mac function get_mac() { echo -n "Enter MAC address in the following format AB:CD:EF:12:34:56: " read new_mac if [[ $new_mac =~ ^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$ ]] ; then macchanger --mac=$new_mac wlan0 else echo "MAC Address format not correct." get_mac fi } # ask for WEP echo -n "Do you want WEP enabled? [y/n]: " read wep case $wep in y*) get_wep_key ;; *) ;; esac # ask for MAC change echo -n "Do you want to change your MAC? [y/n]: " read changemac case $changemac in y*) echo -n "Custom MAC? [y/n]: " read random_mac case $random_mac in y*) get_mac ;; n*) macchanger -r wlan0 ;; *) echo "Invalid choice, keeping current MAC address." ;; esac ;; n*) ;; esac # install packages if need be if [ $(dpkg-query -W -f='${Status}' dnsmasq 2>/dev/null | grep -c "ok installed") -eq 0 ]; then apt-get install dnsmasq fi if [ $(dpkg-query -W -f='${Status}' hostapd 2>/dev/null | grep -c "ok installed") -eq 0 ]; then apt-get install hostapd fi # trap control c trap ctrl_c INT function ctrl_c() { echo "wlan0 managed mode" iwconfig wlan0 mode managed echo "downing wlan0" ifconfig wlan0 down echo "flushing firewall" iptables -F iptables -F -t nat echo "resetting wlan0 mac" macchanger -p wlan0 kill -9 `cat /tmp/dnsmasq.run` } ## script begins # stop and disable services service hostapd stop service dnsmasq stop pkill -9 dnsmasq pkill -9 hostapd # bring up wlan0 nmcli radio wifi off rfkill unblock wlan iwconfig wlan0 mode monitor ifconfig wlan0 10.0.0.1/24 up # forwarding and nat sysctl -w net.ipv4.conf.all.route_localnet=1 iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 10.0.0.1:80 # dns masq conf cat > /tmp/dnsmasq.conf <<! bind-interfaces interface=wlan0 dhcp-range=10.0.0.2,10.0.0.254 ! # hostapd conf cat > /tmp/hostapd.conf<<! interface=wlan0 driver=nl80211 ssid=${ssid} hw_mode=g channel=6 ! # if WEP key, add to hostapd conf if [[ -n $wep_key ]]; then echo -e "wep_default_key=0 wep_key0="${wep_key}"" >> /tmp/hostapd.conf; fi # run dnsmasq and hostapd dnsmasq --pid-file=/tmp/dnsmasq.run -C /tmp/dnsmasq.conf hostapd /tmp/hostapd.conf
以上代码中:
sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 10.0.0.1:80
是本例子的精华所在, 第一句的意思是指所有的ipv4请求全部重定向到本地, 第二句的意思为所有准备访问本地80端口的机器,全部指向到10.0.0.1的80端口, 而我们本地的80端口为我们部署的服务器, 这样即可实现 Captive portal
使用DNS跳转
在本地网关搭建DNS服务器, 局域网内部的所有DNS请求全部返回10.0.0.1
sh文件代码如下:
#!/bin/bash ## quick and dirty AP with hostapd and dnsmasq ## exit properly with ctrl-c echo "Exit this script with Ctrl-C and it will attempt to clean up properly." if [ -z $1 ]; then echo -n "SSID: " read ssid else ssid=$1 fi # get wep key function get_wep_key() { echo -n "WEP Key [must be exactly 5 or 13 ascii characters]: " read wep_key if [[ $wep_key =~ ^[a-zA-Z0-9]{5}$ ]] ; then echo "Key accepted" elif [[ $wep_key =~ ^[a-zA-Z0-9]{13}$ ]] ; then echo "Key accepted" else echo "WEP key must be exactly 5 or 13 characters" get_wep_key fi } # get mac function get_mac() { echo -n "Enter MAC address in the following format AB:CD:EF:12:34:56: " read new_mac if [[ $new_mac =~ ^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$ ]] ; then macchanger --mac=$new_mac wlan0 else echo "MAC Address format not correct." get_mac fi } # ask for WEP echo -n "Do you want WEP enabled? [y/n]: " read wep case $wep in y*) get_wep_key ;; *) ;; esac # ask for MAC change echo -n "Do you want to change your MAC? [y/n]: " read changemac case $changemac in y*) echo -n "Custom MAC? [y/n]: " read random_mac case $random_mac in y*) get_mac ;; n*) macchanger -r wlan0 ;; *) echo "Invalid choice, keeping current MAC address." ;; esac ;; n*) ;; esac # install packages if need be if [ $(dpkg-query -W -f='${Status}' dnsmasq 2>/dev/null | grep -c "ok installed") -eq 0 ]; then apt-get install dnsmasq fi if [ $(dpkg-query -W -f='${Status}' hostapd 2>/dev/null | grep -c "ok installed") -eq 0 ]; then apt-get install hostapd fi # trap control c trap ctrl_c INT function ctrl_c() { echo "wlan0 managed mode" iwconfig wlan0 mode managed echo "downing wlan0" ifconfig wlan0 down echo "flushing firewall" iptables -F iptables -F -t nat echo "resetting wlan0 mac" macchanger -p wlan0 kill -9 `cat /tmp/dnsmasq.run` } ## script begins # stop and disable services service hostapd stop service dnsmasq stop pkill -9 dnsmasq pkill -9 hostapd # bring up wlan0 nmcli radio wifi off rfkill unblock wlan iwconfig wlan0 mode monitor ifconfig wlan0 10.0.0.1/24 up #dhcp iptables --policy INPUT ACCEPT iptables --policy FORWARD ACCEPT iptables --policy OUTPUT ACCEPT iptables -F iptables -t nat -F iptables -t nat -A PREROUTING -i wlan0 -p udp --dport 53 -j DNAT --to 10.0.0.1 # dns masq conf cat > /tmp/dnsmasq.conf <<! bind-interfaces interface=wlan0 address=/#/10.0.0.1 dhcp-range=10.0.0.2,10.0.0.254 dhcp-option=6,10.0.0.1 #DNS dhcp-option=3,10.0.0.1 #Gateway dhcp-option=252,"http://wpad.example.com/wpad.dat " #WPAD dhcp-authoritative ! # hostapd conf cat > /tmp/hostapd.conf<<! interface=wlan0 driver=nl80211 ssid=${ssid} hw_mode=g channel=6 ! # if WEP key, add to hostapd conf if [[ -n $wep_key ]]; then echo -e "wep_default_key=0 wep_key0="${wep_key}"" >> /tmp/hostapd.conf; fi # run dnsmasq and hostapd dnsmasq --pid-file=/tmp/dnsmasq.run -C /tmp/dnsmasq.conf hostapd /tmp/hostapd.conf
其中以下代码尤为重要:
bind-interfaces
interface=wlan0
address=/#/10.0.0.1 《==这个配置说明为所有dns请求都返回10.0.0.1
dhcp-range=10.0.0.2,10.0.0.254 《==客户机器IP池
dhcp-option=6,10.0.0.1 #DNS 《==本地DNS服务器
dhcp-option=3,10.0.0.1 #Gateway 《==本地网关
dhcp-option=252,"http://wpad.example.com/wpad.dat
" #WPAD
dhcp-authoritative
参考
dnsmasq参考API : https://wiki.archlinux.org/index.php/dnsmasq
Captive portal是怎样强制弹出窗口的呢? : https://www.zhihu.com/question/38843766
作者: NONO
出处:http://www.cnblogs.com/diligenceday/
企业网站:http://www.idrwl.com/
开源博客:http://www.github.com/sqqihao
QQ:287101329
微信:18101055830
厦门点燃未来网络科技有限公司, 是厦门最好的微信应用, 小程序, 微信网站, 公众号开发公司