用http代理屏蔽isp广告

最近装了“*城宽带”,发现打开网站时还会弹出广告。打电话给客服沟通,客服表示不知道他们有广告,声称是我本人电脑设置有问题。很无耐,写一代理用来屏蔽广告。

下载地址:http://pan.baidu.com/share/link?shareid=3835585554&uk=590772501#dir/path=%2Fpub%2Fother下载adbreak.zip
使用方法:
1. 解压软件包,点击adbreak.bat
软件启动后如下图:

2. 设置浏览器代理脚本配置,以IE为例。(firefox使用autoproxy、chrome使用proxy-switchysharp将指定网址的代理定向到 8337端口,使用goagent也可以直接修改GoAgent Pac文件,参照adbreak.pac)
工具->Internet选项->链接->局域网设置 勾选 “使用自动脚本配置” 在下面的“地址”这一栏填入 http://127.0.0.1:8337/break.pac

3. 设置屏蔽的网址:
编辑break.pac脚本,在 disable_url 中添加要屏蔽的网址。默认带的几个网址是用来屏蔽“*城宽带”这边的几个广告的。

4. 如何知道广告的网址?
首先建议使用抓包工具,如果没有抓包工具可以使用adbreak自带的代理来查看地址。
设置方法:将第2条中的设置地址改为http://127.0.0.1:8337/proxy.pac。
这时再用浏览器上网,所有的请求是走的adbreak自带的http代理访问,会将网址打印在地址栏中。使用浏览器浏览网页,弹出广告后,查看adbreak中的地址列表,找出广告地址。(你访问网址被拦截后的第一条)
由于cmd自带的缓冲区显示内容有限,需要将修改缓冲区大小,以显示足够多的请求地址。
设置方法:鼠右键点击adbreak标题栏,选择属性->布局 “将屏幕缓冲区大小”中的“高度”设为 5000

说明:程序使用nodejs运行,启用后占用 8337、8338 两个端口,8337端口有break.pac和proxy.pac两个文件。
使用break.pac文件时,当弹出ISP的广告时,break.pac脚本识别到广告地址将这个请求定向到8337端口,这时原请求地址被附加在广告请求地址的Referer中,代理读取referer地址,将请求重定向到原地址。
使用proxy.pac时,请求请重定向到8338端口,这时所请求的文件通过adbreak从网络获取,可以得到每一个请求的地址。用来从地址列表中找出广告的地址。

附adbreak的coffee源代码:

http = require 'http'
url = require 'url'

http.createServer (req, res)->
  request_url = req.url
  request_pac = request_url.match /\/((?:break|proxy).pac)((?:\?.*)?)/

  if request_pac isnt null
    console.log "[#{req.method}] #{request_url}"
    res.writeHead 200, 'Content-Type': 'application/x-ns-proxy-autoconfig'
    pac = require('fs').createReadStream request_pac[1]
    pac.pipe res
    pac.on 'end', ->
      res.end()
  else
    referer = req.headers.referer
    if referer
      console.log "[#{req.method}] -referer- #{request_url}"
      res.writeHead 302, 'Location': referer
    else
      res.writeHead 200, 'Content-Type': 'text/plain'
      console.log "[#{req.method}] -disable- #{request_url}"
      res.write 'no referer'

    res.end()

  return

.listen 8337, '0.0.0.0'
console.log 'start break server by http://127.0.0.1:8337'

http.createServer (req, res)->
  # 请求地址
  request_url = req.url
  # 请求记录
  console.log "[#{req.method}] #{request_url}"
  # 请求数据
  post_data = ''

  request_option = url.parse request_url

  request_option.method = req.method
  request_option.headers = req.headers

  # 接收数据
  req.on 'data', (chunk)->
    post_data += chunk
    return
  # 结束请求
  .on 'end', ->
    if request_option.method is 'POST' then proxy_request.end post_data else proxy_request.end()
    return
  # 开始代理请求
  proxy_request = http.request request_option, (result)->
    # header
    headers = result.headers
    # statusCode
    statusCode = result.statusCode
    # 写入头
    res.writeHead statusCode, headers
    # 写入代理数据
    result.on 'data', (chunk)->
      res.write chunk

      return
    # 数据结束
    result.on 'end', ->
      res.end()

      return

    return
  # 错误处理
  .on 'error', (error)->
    res.end "remote http.request error#{error}"
    return

  return

.listen 8338, '0.0.0.0'
console.log 'start proxy server by http://127.0.0.1:8338'

附使用截图:
“*城宽带”拦截网络访问弹自家广告抓包截图:

可以看到访问www.jd.com被强制转向到了count.chanet.com.cn上面,后面连续跳转了多个广告请求,还有骗京东自家的推广点击的。在第11个请求时,被定向到了京东首页。

代理的拦截效果截图:

访问优酷,被重定向到了ye87.net

ye87.net被代理拦截重新定向到了youku

adbreak打印的重定向信息