免流常见原理

1、修改HTTP连接header:

这里需要了解运营商如何分辨手机走的流量是否为免流流量,目前采用的多是检查HTTP header,查看是否是指定的Host、UA等,具体免流方法为将手机流量中,每一个HTTP请求中,均加入能够免流的Host、UA、或者其他一些免流参数即可.

2、指定端口免流:

这个是比较早期的免流方法,目前在大多数地区均不可用,原理为使用ss、***等工具,通过指定的端口,如137/138/139等端口,即可免流.

注:此方法中使用的免流代码已失效

实战

1、找到一款能够免流量费用的软件(直接使用即可免流量或者开通指定套餐免流量均可),或者网址.

我这里找到的是咪咕音乐
介绍中写了有免流量,实际测试发现确实是免流量的.

2、抓取数据包,打开咪咕音乐,播放音乐,使用wi.cap进行抓包,结果如图所示.

可以看到有Host、Accept、User-Agent、Connection、imei、imsi等header.

3、使用可以手工构造HTTP header的,类似于HTTP/HTTPS协议的***软件,如open***、***等,这里我使用的是***.

搭建***服务器,搭建时注意ss服务器端口和咪咕音乐服务器端口一致,这里是80端口,协议选择auth_sha1,混淆方式使用http_simple.
这里我使用了一段网上搭建***的脚本,可以直接wget http://***.ximcx.cn/×××/××× & bash ×××使用.
脚本内容为

#! /bin/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATH#=================================================================##   System Required:  CentOS 6,7, Debian, Ubuntu                   ##   Description: One click Install ShadowsocksR Server              ##   Author: 91yun                                                              ##   Thanks: @breakwa11 
       ##   Thanks: @Teddysun 
                            ##   Intro:  https://shadowsocks.be/9.html                              ##=================================================================#rm -f ×××clearyum -y install gitecho -e "\033[34m================================================================\033[0m\033[31m                欢迎使用×××免流Or×××一键脚本                         \033[0m\033[31m         妖火网论坛:http://yaohuo.me,I'M 西门吹雪             \033[0m\033[31m           即将开始搭建...   非妖火论坛妖友使用死全家                  \033[0m\033[34m================================================================\033[0m";echoecho#Current foldercur_dir=`pwd`# Get public IP addressIP=$(ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1)if [[ "$IP" = "" ]]; then    IP=$(wget -qO- -t1 -T2 ipv4.icanhazip.com)fi# Make sure only root can run our scriptfunction rootness(){    if [[ $EUID -ne 0 ]]; then       echo "Error:This script must be run as root!" 1>&2       exit 1    fi}# Check OSfunction checkos(){    if [ -f /etc/redhat-release ];then        OS='CentOS'    elif [ ! -z "`cat /etc/issue | grep bian`" ];then        OS='Debian'    elif [ ! -z "`cat /etc/issue | grep Ubuntu`" ];then        OS='Ubuntu'    else        echo "Not support OS, Please reinstall OS and retry!"        exit 1    fi}# Get versionfunction getversion(){    if [[ -s /etc/redhat-release ]];then        grep -oE  "[0-9.]+" /etc/redhat-release    else            grep -oE  "[0-9.]+" /etc/issue    fi    }# CentOS versionfunction centosversion(){    local code=$1    local version="`getversion`"    local main_ver=${version%%.*}    if [ $main_ver == $code ];then        return 0    else        return 1    fi        }# Disable selinuxfunction disable_selinux(){if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then    sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config    setenforce 0fi}# Pre-installation settingsfunction pre_install(){    # Not support CentOS 5    if centosversion 5; then        echo "Not support CentOS 5, please change OS to CentOS 6+/Debian 7+/Ubuntu 12+ and retry."        exit 1    fi    # Set ShadowsocksR config password    echo "请输入×××连接密码:"    read -p "(默认密码: yaohuo520):" shadowsockspwd    [ -z "$shadowsockspwd" ] && shadowsockspwd="yaohuo520"    echo    echo "---------------------------"    echo "password = $shadowsockspwd"    echo "---------------------------"    echo    # Set ShadowsocksR config port    while true    do    echo -e "请输入×××连接端口,不设置将默认138端口:"    read -p "(默认自动设置SS免流端口为138):" shadowsocksport    [ -z "$shadowsocksport" ] && shadowsocksport="138"    expr $shadowsocksport + 0 &>/dev/null    if [ $? -eq 0 ]; then        if [ $shadowsocksport -ge 1 ] && [ $shadowsocksport -le 65535 ]; then            echo            echo "---------------------------"            echo "port = $shadowsocksport"            echo "---------------------------"            echo            break        else            echo "输入错误,请输入1-65535之间的数字!"        fi    else        echo "输入错误,请输入1-65535之间的数字!"    fi    done    get_char(){        SAVEDSTTY=`stty -g`        stty -echo        stty cbreak        dd if=/dev/tty bs=1 count=1 2> /dev/null        stty -raw        stty echo        stty $SAVEDSTTY    }    echo    echo "Press any key to start...or Press Ctrl+C to cancel"    char=`get_char`    # Install necessary dependencies    if [ "$OS" == 'CentOS' ]; then        yum install -y wget unzip openssl-devel gcc swig python python-devel python-setuptools autoconf libtool libevent git ntpdate        yum install -y m2crypto automake make curl curl-devel zlib-devel perl perl-devel cpio expat-devel gettext-devel    else        apt-get -y update        apt-get -y install python python-dev python-pip python-m2crypto curl wget unzip gcc swig automake make perl cpio build-essential git ntpdate    fi    cd $cur_dir}# Download filesfunction download_files(){    # Download libsodium file    if ! wget --no-check-certificate -O libsodium-1.0.10.tar.gz https://github.com/jedisct1/libsodium/releases/download/1.0.10/libsodium-1.0.10.tar.gz; then        echo "Failed to download libsodium file!"        exit 1    fi    # Download ShadowsocksR file    # if ! wget --no-check-certificate -O manyuser.zip https://github.com/breakwa11/shadowsocks/archive/manyuser.zip; then        # echo "Failed to download ShadowsocksR file!"        # exit 1    # fi    # Download ShadowsocksR chkconfig file    if [ "$OS" == 'CentOS' ]; then        if ! wget --no-check-certificate https://raw.githubusercontent.com/91yun/shadowsocks_install/master/shadowsocksR -O /etc/init.d/shadowsocks; then            echo "Failed to download ShadowsocksR chkconfig file!"            exit 1        fi    else        if ! wget --no-check-certificate https://raw.githubusercontent.com/91yun/shadowsocks_install/master/shadowsocksR-debian -O /etc/init.d/shadowsocks; then            echo "Failed to download ShadowsocksR chkconfig file!"            exit 1        fi    fi}# firewall setfunction firewall_set(){    echo "firewall set start..."    if centosversion 6; then        /etc/init.d/iptables status > /dev/null 2>&1        if [ $? -eq 0 ]; then            iptables -L -n | grep '${shadowsocksport}' | grep 'ACCEPT' > /dev/null 2>&1            if [ $? -ne 0 ]; then                iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${shadowsocksport} -j ACCEPT                iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${shadowsocksport} -j ACCEPT                /etc/init.d/iptables save                /etc/init.d/iptables restart            else                echo "port ${shadowsocksport} has been set up."            fi        else            echo "WARNING: iptables looks like shutdown or not installed, please manually set it if necessary."        fi    elif centosversion 7; then        systemctl status firewalld > /dev/null 2>&1        if [ $? -eq 0 ];then            firewall-cmd --permanent --zone=public --add-port=${shadowsocksport}/tcp            firewall-cmd --permanent --zone=public --add-port=${shadowsocksport}/udp            firewall-cmd --reload        else            echo "Firewalld looks like not running, try to start..."            systemctl start firewalld            if [ $? -eq 0 ];then                firewall-cmd --permanent --zone=public --add-port=${shadowsocksport}/tcp                firewall-cmd --permanent --zone=public --add-port=${shadowsocksport}/udp                firewall-cmd --reload            else                echo "WARNING: Try to start firewalld failed. please enable port ${shadowsocksport} manually if necessary."            fi        fi    fi    echo "firewall set completed..."}# Config ShadowsocksRfunction config_shadowsocks(){    cat > /etc/shadowsocks.json<<-EOF{    "server": "0.0.0.0",    "server_ipv6": "::",    "server_port": ${shadowsocksport},    "local_address": "127.0.0.1",    "local_port": 1081,    "password": "${shadowsockspwd}",    "timeout": 120,    "udp_timeout": 60,    "method": "chacha20",    "protocol": "auth_sha1_compatible",    "protocol_param": "",    "obfs": "http_simple_compatible",    "obfs_param": "",    "dns_ipv6": false,    "connect_verbose_info": 0,    "redirect": "",    "fast_open": false,    "workers": 1}EOF}# Install ShadowsocksRfunction install_ss(){    # Install libsodium    tar zxf libsodium-1.0.10.tar.gz    cd $cur_dir/libsodium-1.0.10    ./configure && make && make install    echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf    ldconfig    # Install ShadowsocksR    cd $cur_dir    # unzip -q manyuser.zip    # mv shadowsocks-manyuser/shadowsocks /usr/local/    git clone -b manyuser https://github.com/breakwa11/shadowsocks.git /usr/local/shadowsocks    if [ -f /usr/local/shadowsocks/server.py ]; then        chmod +x /etc/init.d/shadowsocks        # Add run on system start up        if [ "$OS" == 'CentOS' ]; then            chkconfig --add shadowsocks            chkconfig shadowsocks on        else            update-rc.d -f shadowsocks defaults        fi        # Run ShadowsocksR in the background        /etc/init.d/shadowsocks start        clear        echo        echo "恭喜你,shadowsocksr安装完成!"        echo -e "服务器IP: \033[41;37m ${IP} \033[0m"        echo -e "远程连接端口: \033[41;37m ${shadowsocksport} \033[0m"        echo -e "远程连接密码: \033[41;37m ${shadowsockspwd} \033[0m"        echo -e "本地监听IP: \033[41;37m 127.0.0.1 \033[0m"        echo -e "本地监听端口: \033[41;37m 1080 \033[0m"        echo -e "认证方式: \033[41;37m auth_sha1 \033[0m"        echo -e "协议: \033[41;37m http_simple \033[0m"        echo -e "加密方式: \033[41;37m chacha20 \033[0m"        echo        echo "欢迎来访妖火论坛:http://yaohuo.me Or https://yaohw.com"        echo "如果你想改变认证方式和协议,请参考网址"        echo "https://github.com/breakwa11/shadowsocks-rss/wiki/Server-Setup"        echo        echo "安装完毕!去享受这种愉悦感把!I'm your old friend 西门吹雪"        echo    else        echo "Shadowsocks安装失败!"        install_cleanup        exit 1    fi}#改成北京时间function check_datetime(){    rm -rf /etc/localtime    ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime    ntpdate 1.cn.pool.ntp.org}# Install cleanupfunction install_cleanup(){    cd $cur_dir    rm -f manyuser.zip    rm -rf shadowsocks-manyuser    rm -f libsodium-1.0.10.tar.gz    rm -rf libsodium-1.0.10}# Uninstall ShadowsocksRfunction uninstall_shadowsocks(){    printf "你确定卸载shadowsocksr? (y/n) "    printf "\n"    read -p "(Default: n):" answer    if [ -z $answer ]; then        answer="n"    fi    if [ "$answer" = "y" ]; then        /etc/init.d/shadowsocks status > /dev/null 2>&1        if [ $? -eq 0 ]; then            /etc/init.d/shadowsocks stop        fi        checkos        if [ "$OS" == 'CentOS' ]; then            chkconfig --del shadowsocks        else            update-rc.d -f shadowsocks remove        fi        rm -f /etc/shadowsocks.json        rm -f /etc/init.d/shadowsocks        rm -rf /usr/local/shadowsocks        echo "ShadowsocksR uninstall success!"    else        echo "uninstall cancelled, Nothing to do"    fi}# Install ShadowsocksRfunction install_shadowsocks(){    checkos    rootness    disable_selinux    pre_install    download_files    config_shadowsocks    install_ss    if [ "$OS" == 'CentOS' ]; then        firewall_set > /dev/null 2>&1    fi    check_datetime    install_cleanup    }# Initialization stepaction=$1[ -z $1 ] && action=installcase "$action" ininstall)    install_shadowsocks    ;;uninstall)    uninstall_shadowsocks    ;;*)    echo "Arguments error! [${action} ]"    echo "Usage: `basename $0` {install|uninstall}"    ;;esac

4、搭建好后在手机端进行设置.
如图:

freetyst.mll.migu.cn\r\nAccept: */*\r\nUser-Agent: migumusic\r\nConnection: close\r\nimei: 000000000000000000\r\nimsi: 00000000000000000000

使用open***的话,免流代码如下

http-proxy-option EXT1 "GET http://migumovie.lovev.com"http-proxy-option EXT1 "Host: freetyst.mll.migu.cn"http-proxy-option EXT1 "Accept: */*"http-proxy-option EXT1 "User-Agent: migumusic"http-proxy-option EXT1 "Connection: close"http-proxy 10.0.0.172 80

最后的10.0.0.172 80是移动的HTTP代理服务器,也可以自己搭建HTTP代理服务器,然后修改10.0.0.172为自己的代理服务器

5、手机上开启ss,抓包查看

总结

这里免流的核心其实就是找到一个移动运营商允许的可以免流量使用的软件

而手机流量通过移动运行商时,移动运行商会检查数据包中有没有不收取流量的数据包
检查方法基本是使用的HTTP header中的关键字
因此,只需要找到检测的关键字,把手机上发出的每一个数据包都带上这个关键字,就可以免流了
同理,如果需要手机开热点出来给电脑用,也是一样的,只要发出的数据包带有这个关键字,就能免流
以上方法为HTTP协议的免流,如果发现某个软件使用的tcp等协议,也可以分析包里的特征,实现免流
如果使用的免流服务器为国外的服务器,当流量太大时,可能会被gfw干掉,另外据说有人使用国外服务器免流,被运营商发现过,真伪未知