连上Wi-Fi 热点自动弹窗的实现方法

  当我们连上某个热点, 会自动弹出登录窗口的专业名称叫做: 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\nwep_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
View Code

  以上代码中:

    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\n" #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\nwep_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
View Code

  其中以下代码尤为重要:

  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\n" #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 

厦门点燃未来网络科技有限公司, 是厦门最好的微信应用, 小程序, 微信网站, 公众号开发公司

转载于:https://www.cnblogs.com/diligenceday/p/7134874.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值