用http代理屏蔽isp广告

左手 posted @ 2013年8月01日 13:43 in 积累点滴 with tags isp广告 http代理 nodejs写http代理 拦截isp广告 , 3374 阅读

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

下载地址: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打印的重定向信息

Avatar_small
依云 说:
2013年8月01日 14:30

客服不承认的话,你表现得更加专业一点、不满一点,用他们听不懂的术语砸死他们,然后要求转接到经理啊技术部门啊之类的。

Avatar_small
依云 说:
2013年8月01日 14:31

再不行就说要去工信部举报。

Avatar_small
左手 说:
2013年8月02日 11:36

看来云大在这方面经验丰富呀。哈哈!@依云:

Avatar_small
不写可否 说:
2015年12月27日 23:50

你好!

代理服务器能否增加代理https网页的功能,现在很多网页都支持https了。

研究了两天实在不会增加,从来没写过代码,按照你的http的版本改的不行,实在太难。
var url = require('url');
var fs = require('fs');
var https = require('https');

var options = {
key : fs.readFileSync('ca.key'),
cert : fs.readFileSync('ca.crt')
};
https.createServer(options, function (req, res) {
var post_data, proxy_request, request_option, request_url;

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', function(chunk) {
post_data += chunk;
}).on('end', function() {
if (request_option.method === 'POST') {
proxy_request.end(post_data);
} else {
proxy_request.end();
}
});
proxy_request = https.request(options, request_option, function(result) {
var headers, statusCode;

headers = result.headers;
statusCode = result.statusCode;
res.writeHead(statusCode, headers);
result.on('data', function(chunk) {
res.write(chunk);
});
result.on('end', function() {
res.end();
});
}).on('error', function(error) {
res.end("remote https.request error" + error);
});
}).listen(8338, '0.0.0.0');

console.log('start proxy server by http://127.0.0.1:8338');

Avatar_small
左手 说:
2015年12月28日 17:09

@不写可否: 我之前写这个也是一时兴趣,没有花太多精力研究。建议参考goagent的node的服务端,好象是支持https的。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter