因为工作原因,需要访问一些国外的网站(科学上网),但直接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. 帮助你实现漂亮界面的14套免费的 HTML/CSS 源码

    在网络上能找很多免费的 PSD 格式素材,但是很少有 HTML/CSS 界面组件下载.在这篇文章中,收集了14套免费的 HTML/CSS 界面源码分享给前端设计师和开发者们.这些组件包括按钮.滑块.表 ...

  2. JAVA 设计模式 适配器模式

    用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器模式是一种结构型模式. 结构

  3. 如何使用Jedis操作Redis消息队列

    资源链接 Jedis的jar包 Commons-io的jar包 使用方法 代码样例如下,使用前,注意打开redis的server程序. 代码样例 package RedisExample; impor ...

  4. Moon转告给你一个比Log4net更好日志框架--TracerX Logger 及其对应的日志查看器

    一.介绍 TracerX logger是一个易于上手,且拥有众多高级特性的.NET日志框架. 它能够发送输出结果到多目的地(循环文件.事件日志等....).它也能生成文本和二进制文件.它拥有一个强大的 ...

  5. 六、GAIA

    1.      GAIA CSR GAIA (Generic Application Interface Architecture)提供了一个端到端的,与主机无关的生态系统来实现主机应用程序对设备的功 ...

  6. 编写Chrome扩展程序

    Chrome的扩展程序很多,也很容易入门,可以来简单实现一下 看看,慢慢就能实现出一个扩展程序来 每个扩展程序应用一般会包含: 一个manifest清单文件 html文件 js文件 其他文件等 可以看 ...

  7. 玩爽了!直接在Chrome里抓取数据

    一个小测试发现可以自动做题,于是想通过脚本的方式看能不能获取相应的题库,刚好可以学习一下JS异步操作.花了一天时间,总算跑顺利了,遇到了不少坑.记录下来分享. 1.JS如何顺序执行 JS有强大的异步操 ...

  8. js简单实现div宽度匀速增加/减小

    效果类似百度首页音乐盒. 点击音乐右边的div可以变长或者变短. 代码: <!DOCTYPE html> <html lang="en"> <head ...

  9. 两个dropDownList和一个GridView的选择与显示

    很久没有写ASP.NET了,今天有看到论坛上一个问题:"两个dropDownList和一个GridView,已经进行了数据绑定,现在想让第一个下拉菜单的数据改变时,第二个下拉菜单自动变到相应 ...

  10. go语言 hello 小结

    在编译go语言的时候: 写了一段这样的代码 package main import "fmt" func main() {     fmt.Println("Hello, ...