因为工作原因,需要访问一些国外的网站(科学上网),但直接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. Spark入门实战系列--2.Spark编译与部署(下)--Spark编译安装

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .编译Spark .时间不一样,SBT是白天编译,Maven是深夜进行的,获取依赖包速度不同 ...

  2. gulp-rev:项目部署缓存解决方案----gulp系列(六)

    引言: 前端工程化部署比较重要考虑的一个问题是缓存 ,可以参考 <变态的静态资源缓存与更新>. 使用gulp-rev解决的就是<变态的静态资源缓存与更新>提出的问题. rev会 ...

  3. tiltShift.js - CSS3 滤镜实现移轴镜头效果

    tiltShift.js 是一款很棒的 jQuery 插件,使用 CSS3 图片滤镜来实现照片的移轴镜头效果.使用非常简单,使用 data 属性配置参数.温馨提示:为保证最佳的效果,请在 IE10+. ...

  4. APPSCAN使用外部浏览器

    在使用appscan扫描时,自带浏览器可能存在兼容性问题(比如HTML5),故需要用到其他浏览器.在做139邮箱HTML5项目,需要使用chrome浏览器进行扫描.因此分享下如何使用外部浏览器,将之前 ...

  5. 23套新鲜出炉的网站和手机界面 PSD 素材

    Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这些套件让他们使用快速和有效的方式复制用户界面.这些类型的工具包提供了一个基本的用户界面元素,用于它们需要制作的网站或软件模型. 在这篇文章 ...

  6. html/css基础篇——link和@inport详解以及脚本执行顺序探讨

    先说一说两者之间的异同 两者都可以引用外部CSS的方式,现在主流浏览器两者都支持(ps:@import是CSS2.1提出的),但是存在一定的区别: 1.link是XHTML标签,除了加载CSS外,还可 ...

  7. SQL Server代理(5/12):理解SQL代理错误日志

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 如我们在这个系列的前几篇文章所见,SQL ...

  8. ES6笔记(7)-- Promise异步编程

    系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...

  9. 找到多个与名为“Login”的控制器匹配的类型

    添加了mvc区域以后,可能出现以下错误... 找到多个与名为“Login”的控制器匹配的类型.如果为此请求(“{controller}/{action}/{id}”)提供服务的路由在搜索匹配此请求的控 ...

  10. has no parameters and arguments were supplied

    这个问题,让Insus.NET花上不少时间与心机. 在项目中,Insus.NET是使用这个逻辑组件: <程序与数据库之间的连接桥梁和逻辑处理>http://www.cnblogs.com/ ...