因为工作原因,需要访问一些国外的网站(科学上网),但直接FQ并不方便,于是研究了一些代理软件,比如Nydus,Green等,
在Nydus的Proxy版本中发现了实现国内国外流量的智能分流的办法,通过搜索和分析发现其中原理是通过一个叫PAC脚本的东东来实现的。
1、什么是代理脚本(PAC)
一个PAC文件其实就是一个文本文件,最简单的格式就是包含一个叫FindProxyForURL的
JScript函数,IE通过传入两个变量来调用这个函数,一个是用户浏览的地址URL全路经,
一个是这个URL中的主机名部分(host)。这个FindProxyForURL函数有三种可能的字符串
返回值,一是"DIRECT",就是直接连接,不通过代理;二是"PROXY proxyaddr:port",
其中proxyaddr和port分别是代理的地址和代理的端口;三是"SOCKS socksaddr:port",
其中socksaddr和port分别是socks代理的地址和端口,一个自动代理文件可以是多个
选择的组合,其中用分号(;)隔开,如:
  
   function FindProxyForURL(url,host)
   {
     if (host == "www.mydomain.com")
         return "DIRECT";

return "PROXY myproxy:80;
                 PROXY myotherproxy:8080;
                 DIRECT";
   }
  
  
2、下面是代理脚本可能用到的函数和说明:
PAC Helper Functions

dnsDomainIs(host, domain)              Returns true if the host is part of the
                                       specified domain, false otherwise.

isInNet(hostname,                      Resolves the hostname and subnet IP,
                                       subnet mask) returns true if the
                                       hostname is within the subnet specified
                                       by the IP address and the subnet mask,
                                       false otherwise.

isPlainHostName(host)                  Returns true if there are no dots in the
                                       hostname, false otherwise.

isResolvable(host)                     Internet Explorer tries to resolve the
                                       hostname through DNS and returns true if
                                       successful, false otherwise.

localHostOrDomainIs                    Returns true if the host matches (host,
                                       domain) the host portion of the domain,
                                       or if the host matches the host and
                                       domain portions of the domain, false
                                       otherwise. (Executed only for URLs in
                                       the local domain.)

dnsDomainLevels(host)                  Returns the number of dots in the
                                       hostname.

dnsResolve(host)                       Returns a string containing the IP
                                       address of the specified host.

myIPAddress( )                         Returns a string containing the local
                                       machine’s IP address.

shExpMatch(url, shexp)                 Returns true if the supplied URL matches
                                       the specified shell expression, false
                                       otherwise.

dateRange(parmList)                    Returns true if the current date falls
                                       within the dates specified in parmList,
                                       false otherwise.

timeRange(parmList)                    Returns true if the current time falls
                                       within the times specified in parmList,
                                       false otherwise.

weekdayRange(parmList)                 Returns true if today is within the days
                                       of the week specified in parmList, false
                                       otherwise.

3、下面是各个函数应用的例子:
  a、isPlainHostName(host),本例演示判断是否为本地主机,如http://myservername/
  的方式访问,如果是直接连接,否则使用代理
  function FindProxyForURL(url, host)
  {
    if (isPlainHostName(host))
      return "DIRECT";
    else
      return "PROXY proxy:80";
  }
 
  b、dnsDomainIs(host, "")、localHostOrDomainIs(host, ""),本例演示判断访问主机
  是否属于某个域和某个域名,如果属于.company.com域的主机名,而域名不是
  www.company.com和home.company.com的直接连接,否则使用代理访问。
  function FindProxyForURL(url, host)
  {
    if ((isPlainHostName(host) ||
       dnsDomainIs(host, ".company.com")) &&
      !localHostOrDomainIs(host, "www.company.com") &&
      !localHostOrDomainIs(host, "home.company.com"))

return "DIRECT";
    else
      return "PROXY proxy:80";
  }
 
  c、isResolvable(host),本例演示主机名能否被dns服务器解析,如果能直接访问,否
  则就通过代理访问。
  function FindProxyForURL(url, host)
  {
    if (isResolvable(host))
      return "DIRECT";
    else
      return "PROXY proxy:80";
  }
 
  d、isInNet(host, "", ""),本例演示访问IP是否在某个子网内,如果是就直接访问,
  否则就通过代理,例子演示访问清华IP段的主页不用代理。
  function FindProxyForURL(url, host)
  {
    if (isInNet(host, "166.111.0.0", "255.255.0.0"))
      return "DIRECT";
    else
      return "PROXY proxy:80";
  }
 
e、shExpMatch(host, ""),本例演示根据主机域名来改变连接类型,本地主机、*.edu、
  *.com分别用不同的连接方式。
  function FindProxyForURL(url, host)
  {
    if (isPlainHostName(host))
      return "DIRECT";
    else if (shExpMatch(host, "*.com"))
      return "PROXY comproxy:80";
    else if (shExpMatch(host, "*.edu"))
      return "PROXY eduproxy:80";
    else
      return "PROXY proxy:80";
  }
 
f、url.substring(),本例演示根据不同的协议来选择不同的代理,http、https、ftp、
  gopher分别使用不同的代理。
  function FindProxyForURL(url, host)
  {
      if (url.substring(0, 5) == "http:") {
        return "PROXY proxy:80";
      }
      else if (url.substring(0, 4) == "ftp:") {
        return "PROXY fproxy:80";
      }
      else if (url.substring(0, 7) == "gopher:") {
        return "PROXY gproxy";
      }
      else if (url.substring(0, 6) == "https:") {
        return "PROXY secproxy:8080";
      }
      else {
        return "DIRECT";
      }
  }
 
  g、dnsResolve(host),本例演示判断访问主机是否某个IP,如果是就使用代理,否则直
  接连接。
  unction FindProxyForURL(url, host)
  {
      if (dnsResolve(host) == "XXX.XXX.XXX.XXX") {
        return "PROXY secproxy:8080";
      }
      else {
        return "PROXY proxy:80";
      }
  }
 
  h、myIpAddress(),本例演示判断本地IP是否某个IP,如果是就使用代理,否则直接使
  用连接。
  function FindProxyForURL(url, host)
  {
      if (myIpAddress() == "XXX.XXX.XXX.XXX") {
        return "PROXY proxy:80";
      }
      else {
        return "DIRECT";
      }
  }
 
  i、dnsDomainLevels(host),本例演示访问主机的域名级数是几级,就是域名有几个点
  如果域名中有点,就通过代理访问,否则直接连接。
  function FindProxyForURL(url, host)
  {
      if (dnsDomainLevels(host) > 0) { // if number of dots in host > 0
        return "PROXY proxy:80";
      }
        return "DIRECT";
  }
 
  j、weekdayRange(),本例演示当前日期的范围来改变使用代理,如果是GMT时间周三
  到周六,使用代理连接,否则直接连接。
  function FindProxyForURL(url, host)
  {
    if(weekdayRange("WED", "SAT", "GMT"))
     return "PROXY proxy:80";
    else
     return "DIRECT";
  }
 
  k、最后一个例子是演示随机使用代理,这样可以好好利用代理服务器。
function FindProxyForURL(url,host)
{
      return randomProxy();
}

function randomProxy()
{
     switch( Math.floor( Math.random() * 5 ) )
     {
         case 0:
             return "PROXY proxy1:80";
             break;
         case 1:
             return "PROXY proxy2:80";
             break;
         case 2:
             return "PROXY proxy3:80";
             break;
         case 3:
             return "PROXY proxy4:80";
             break;
         case 4:
             return "PROXY proxy5:80";
             break;
     }   
}

利用上面的函数和例子说明,大家就可以写出比较复杂有效的自动代理脚本。

当完成PAC的编写以后,在某个HTTP服务器上挂上pac的文件,比如对外提供如:http://127.0.0.1:8080/test.pac这样的地址。
 
再设置系统的代理设置为脚本地址,填上如上地址就可以了。轻松分流。国内国外两不误。
附上MAC系统的设置截图(windows在internet设置里面):
 
不但这些商业软件会有类似的实现,而且在著名的ShadowProxy中也有Pac的利用(因为一些原因,GitHub上已经找不到源码了, Nydus的代理版就是类似的一个商业化版本,目前还可以用)
 
除此了PAC这种方法以外,我还看到有一些VPN也提供了分流的方式,不过目前还不知道具体原理。以后再研究吧。
 
 

关于一些网络代理实现智能流量分流的研究(PAC脚本介绍及利用)的更多相关文章

  1. 云原生网络代理(MOSN)的进化之路

    本文系云原生应用最佳实践杭州站活动演讲稿整理.杭州站活动邀请了 Apache APISIX 项目 VP 温铭.又拍云平台开发部高级工程师莫红波.蚂蚁金服技术专家王发康.有赞中间件开发工程师张超,分享云 ...

  2. [内网渗透] MSF路由转发/网络代理

    这里只做记录,不做详解 0x01 路由转发 已经拿到一台公网服务器: 1.1 方法1 进到meterpreter的会话: route #查看路由信息 background退出当前会话,通过会话2,转发 ...

  3. [WEB安全]给BurpSuite设置非本地的网络代理

    目录 0x01 一般情况 0x02 移动端流量抓取 0x03 多重代理的情形 0x04 参考链接 在Web渗透测试过程中,BurpSuite是不可或缺的神器之一. BurpSuite的核心是代理Pro ...

  4. 《UNIX/Linux网络日志分析与流量监控》新书发布

    本书从UNIX/Linux系统的原始日志(Raw Log)采集与分析讲起,逐步深入到日志审计与计算机取证环节.书中提供了多个案例,每个案例都以一种生动的记事手法讲述了网络遭到入侵之后,管理人员开展系统 ...

  5. 《Unix/Linux网络日志分析与流量监控》获2015年度最受读者喜爱的IT图书奖

    <Unix/Linux网络日志分析与流量监控>获2015年度最受读者喜爱的IT图书奖.刊登在<中华读书报>( 2015年01月28日 19 版) 我的2015年新作刊登在< ...

  6. Proxy SwitchySharp chrome网络代理【转】

    Proxy SwitchySharp chrome网络代理插件概述 SwitchySharp 是 Google Chrome 浏览器上的一个代理管理扩展程序,是一款可以自己设置谷歌浏览器使用方式的ch ...

  7. Docker网络代理设置

    背景 在一些实验室环境,服务器没有直接连接外网的权限,需要通过网络代理.我们通常会将网络代理直接配置在/etc/environment./etc/profile之类的配置文件中,这对于大部分操作都是可 ...

  8. centos 桥接配置 设置网络代理 lnmp搭建

    一.桥接配置 centos设置  编辑->虚拟网络编辑器->桥接模式->还原默认设置 虚拟机->设置->网络适配器->桥接 cd /etc/sysconfig/ne ...

  9. 工作随笔——Java网络代理(http,socks)

    简单说一下Java如何便捷的使用网络代理功能 此方法使用于大部分情况,一些特殊框架(如:mina)无效. // 代码设置http代理 System.setProperty("proxySet ...

随机推荐

  1. 可视化(番外篇)——在Eclipse RCP中玩转OpenGL

    最近在看有关Eclipse RCP方面的东西,鉴于Gephi是使用opengl作为绘图引擎,所以,萌生了在Eclipse RCP下添加画布,使用opengl绘图的想法,网上有博文详细介绍这方面的内容, ...

  2. javascript中遇到的字符串对象处理

    在javascript中对参数处理: 1 <script> 2 function getParam() 3 { 4 urlInfo=window.location.href; //获取当前 ...

  3. APP数据接口开发的一些经验

    刚接到这样的任务时,没有感觉到任何压力,不就是给移动端应用提供数据吗?那边发来参数,这边处理数据,返回JSON.做网站开发时经常使用ajax请求后台数据,不就是这么回事吗.于是,在确认完需求后就开始干 ...

  4. SQLServer存储过程中事务的使用

    create proc usp_Stock @GoodsId int, @Number int, @StockPrice money, @SupplierId int, @EmpId int, ), ...

  5. ASP.NET MVC 学习之路由(URL Routing)

    在ASP.NET MVC中,一个URL请求是由对应的一个Controller中的Action来处理的,由URL Routing来告诉MVC如何定位到正确的Controller和Action. 默认路由 ...

  6. XMPP客户端开发(2)--发送接收消息

    客户端连接上服务器并登录以后,可以发送.接收消息. 首先需要定义Chat,MessageListener和ChatMessageListener几个变量: private static Chat ch ...

  7. Tigase数据库结构(1)

    Tigase数据库有很多张表,其中最主要的是3张表:tig_users,tig_nodes和tig_pairs. 1.tig_users tig_users存储用户信息,有uid(主键,用户ID),u ...

  8. 360手机卫士会影响Widget的运行

    最近开发了一个Widget,老是运行时间长了就会出现NullPointerException错误,一直不知道是什么原因造成的,后来把Widget加入360一键清理的保护名单,错误就少很多,但是仍然有错 ...

  9. [教学] Firemonkey 之 StringGrid Header 自订显示

    StringGrid Header 高度设定方法: uses FMX.Header; procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObj ...

  10. php实现中文字符串截取各种问题

    用php截取中文字符串会出现各种问题,做一简单汇总,文中的问题暂时还未解决,有大神解决了问题欢迎指教 <?php header('Content-Type:text/html;charset=u ...