精华内容
下载资源
问答
  • 简单HTTP代理服务器-源码c++

    热门讨论 2015-08-26 21:28:21
    一个简单的http代理服务器。 支持http 和https c/c++源码。 代码易阅读和修改。供参考 经过测试,基本没有问题。
  • HTTP 代理原理及实现

    万次阅读 2019-04-25 11:50:34
    Web 代理是一种存在于网络中间的...今天这篇文章,我打算谈谈 HTTP 代理本身的一些原理,以及如何用 Node.js 快速实现代理HTTP 代理存在两种形式,分别简单介绍如下: 第一种是RFC 7230 - HTTP/1.1: Message Sy...

    Web 代理是一种存在于网络中间的实体,提供各式各样的功能。现代网络系统中,Web 代理无处不在。我之前有关 HTTP 的博文中,多次提到了代理对 HTTP 请求及响应的影响。今天这篇文章,我打算谈谈 HTTP 代理本身的一些原理,以及如何用 Node.js 快速实现代理。

    HTTP 代理存在两种形式,分别简单介绍如下:

    第一种是 RFC 7230 - HTTP/1.1: Message Syntax and Routing(即修订后的 RFC 2616,HTTP/1.1 协议的第一部分)描述的普通代理。这种代理扮演的是「中间人」角色,对于连接到它的客户端来说,它是服务端;对于要连接的服务端来说,它是客户端。它就负责在两端之间来回传送 HTTP 报文。

    第二种是 Tunneling TCP based protocols through Web proxy servers(通过 Web 代理服务器用隧道方式传输基于 TCP 的协议)描述的隧道代理。它通过 HTTP 协议正文部分(Body)完成通讯,以 HTTP 的方式实现任意基于 TCP 的应用层协议代理。这种代理使用 HTTP 的 CONNECT 方法建立连接,但 CONNECT 最开始并不是 RFC 2616 - HTTP/1.1 的一部分,直到 2014 年发布的 HTTP/1.1 修订版中,才增加了对 CONNECT 及隧道代理的描述,详见 RFC 7231 - HTTP/1.1: Semantics and Content。实际上这种代理早就被广泛实现。

    本文描述的第一种代理,对应《HTTP 权威指南》一书中第六章「代理」;第二种代理,对应第八章「集成点:网关、隧道及中继」中的 8.5 小节「隧道」。

    普通代理

    第一种 Web 代理原理特别简单:

    HTTP 客户端向代理发送请求报文,代理服务器需要正确地处理请求和连接(例如正确处理 Connection: keep-alive),同时向服务器发送请求,并将收到的响应转发给客户端。

    下面这张图片来自于《HTTP 权威指南》,直观地展示了上述行为:

    假如我通过代理访问 A 网站,对于 A 来说,它会把代理当做客户端,完全察觉不到真正客户端的存在,这实现了隐藏客户端 IP 的目的。当然代理也可以修改 HTTP 请求头部,通过 X-Forwarded-IP 这样的自定义头部告诉服务端真正的客户端 IP。但服务器无法验证这个自定义头部真的是由代理添加,还是客户端修改了请求头,所以从 HTTP 头部字段获取 IP 时,需要格外小心。这部分内容可以参考我之前的《HTTP 请求头中的 X-Forwarded-For》这篇文章。

    给浏览器显式的指定代理,需要手动修改浏览器或操作系统相关设置,或者指定 PAC(Proxy Auto-Configuration,自动配置代理)文件自动设置,还有些浏览器支持 WPAD(Web Proxy Autodiscovery Protocol,Web 代理自动发现协议)。显式指定浏览器代理这种方式一般称之为正向代理,浏览器启用正向代理后,会对 HTTP 请求报文做一些修改,来规避老旧代理服务器的一些问题,这部分内容可以参考我之前的《Http 请求头中的 Proxy-Connection》这篇文章。

    还有一种情况是访问 A 网站时,实际上访问的是代理,代理收到请求报文后,再向真正提供服务的服务器发起请求,并将响应转发给浏览器。这种情况一般被称之为反向代理,它可以用来隐藏服务器 IP 及端口。一般使用反向代理后,需要通过修改 DNS 让域名解析到代理服务器 IP,这时浏览器无法察觉到真正服务器的存在,当然也就不需要修改配置了。反向代理是 Web 系统最为常见的一种部署方式,例如本博客就是使用 Nginx 的 proxy_pass 功能将浏览器请求转发到背后的 Node.js 服务。

    了解完第一种代理的基本原理后,我们用 Node.js 实现一下它。只包含核心逻辑的代码如下:

    var http = require('http');
    var net = require('net');
    var url = require('url');
    
    function request(cReq, cRes) {
        var u = url.parse(cReq.url);
    
        var options = {
            hostname : u.hostname, 
            port     : u.port || 80,
            path     : u.path,       
            method     : cReq.method,
            headers     : cReq.headers
        };
    
        var pReq = http.request(options, function(pRes) {
            cRes.writeHead(pRes.statusCode, pRes.headers);
            pRes.pipe(cRes);
        }).on('error', function(e) {
            cRes.end();
        });
    
        cReq.pipe(pReq);
    }
    
    http.createServer().on('request', request).listen(8888, '0.0.0.0');

    以上代码运行后,会在本地 8888 端口开启 HTTP 代理服务,这个服务从请求报文中解析出请求 URL 和其他必要参数,新建到服务端的请求,并把代理收到的请求转发给新建的请求,最后再把服务端响应返回给浏览器。修改浏览器的 HTTP 代理为 127.0.0.1:8888 后再访问 HTTP 网站,代理可以正常工作。

    但是,使用我们这个代理服务后,HTTPS 网站完全无法访问,这是为什么呢?答案很简单,这个代理提供的是 HTTP 服务,根本没办法承载 HTTPS 服务。那么是否把这个代理改为 HTTPS 就可以了呢?显然也不可以,因为这种代理的本质是中间人,而 HTTPS 网站的证书认证机制是中间人劫持的克星。普通的 HTTPS 服务中,服务端不验证客户端的证书,中间人可以作为客户端与服务端成功完成 TLS 握手;但是中间人没有证书私钥,无论如何也无法伪造成服务端跟客户端建立 TLS 连接。当然如果你拥有证书私钥,代理证书对应的 HTTPS 网站当然就没问题了。

    HTTP 抓包神器 Fiddler 的工作原理也是在本地开启 HTTP 代理服务,通过让浏览器流量走这个代理,从而实现显示和修改 HTTP 包的功能。如果要让 Fiddler 解密 HTTPS 包的内容,需要先将它自带的根证书导入到系统受信任的根证书列表中。一旦完成这一步,浏览器就会信任 Fiddler 后续的「伪造证书」,从而在浏览器和 Fiddler、Fiddler 和服务端之间都能成功建立 TLS 连接。而对于 Fiddler 这个节点来说,两端的 TLS 流量都是可以解密的。

    如果我们不导入根证书,Fiddler 的 HTTP 代理还能代理 HTTPS 流量么?实践证明,不导入根证书,Fiddler 只是无法解密 HTTPS 流量,HTTPS 网站还是可以正常访问。这是如何做到的,这些 HTTPS 流量是否安全呢?这些问题将在下一节揭晓。

    隧道代理

    第二种 Web 代理的原理也很简单:

    HTTP 客户端通过 CONNECT 方法请求隧道代理创建一条到达任意目的服务器和端口的 TCP 连接,并对客户端和服务器之间的后继数据进行盲转发。

    下面这张图片同样来自于《HTTP 权威指南》,直观地展示了上述行为:

    假如我通过代理访问 A 网站,浏览器首先通过 CONNECT 请求,让代理创建一条到 A 网站的 TCP 连接;一旦 TCP 连接建好,代理无脑转发后续流量即可。所以这种代理,理论上适用于任意基于 TCP 的应用层协议,HTTPS 网站使用的 TLS 协议当然也可以。这也是这种代理为什么被称为隧道的原因。对于 HTTPS 来说,客户端透过代理直接跟服务端进行 TLS 握手协商密钥,所以依然是安全的,下图中的抓包信息显示了这种场景:

    CONNECT imququ.com:443 HTTP/1.1

    对于 CONNECT 请求来说,只是用来让代理创建 TCP 连接,所以只需要提供服务器域名及端口即可,并不需要具体的资源路径。代理收到这样的请求后,需要与服务端建立 TCP 连接,并响应给浏览器这样一个 HTTP 报文:

    HTTP/1.1 200 Connection Established

    浏览器收到了这个响应报文,就可以认为到服务端的 TCP 连接已经打通,后续直接往这个 TCP 连接写协议数据即可。通过 Wireshark 的 Follow TCP Steam 功能,可以清楚地看到浏览器和代理之间的数据传递:

    可以看到,浏览器建立到服务端 TCP 连接产生的 HTTP 往返,完全是明文,这也是为什么 CONNECT 请求只需要提供域名和端口:如果发送了完整 URL、Cookie 等信息,会被中间人一览无余,降低了 HTTPS 的安全性。HTTP 代理承载的 HTTPS 流量,应用数据要等到 TLS 握手成功之后通过 Application Data 协议传输,中间节点无法得知用于流量加密的 master-secret,无法解密数据。而 CONNECT 暴露的域名和端口,对于普通的 HTTPS 请求来说,中间人一样可以拿到(IP 和端口很容易拿到,请求的域名可以通过 DNS Query 或者 TLS Client Hello 中的 Server Name Indication 拿到),所以这种方式并没有增加不安全性。

    了解完原理后,再用 Node.js 实现一个支持 CONNECT 的代理也很简单。核心代码如下:

    var http = require('http');
    var net = require('net');
    var url = require('url');
    
    function connect(cReq, cSock) {
        var u = url.parse('http://' + cReq.url);
    
        var pSock = net.connect(u.port, u.hostname, function() {
            cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
            pSock.pipe(cSock);
        }).on('error', function(e) {
            cSock.end();
        });
    
        cSock.pipe(pSock);
    }
    
    http.createServer().on('connect', connect).listen(8888, '0.0.0.0');

    以上代码运行后,会在本地 8888 端口开启 HTTP 代理服务,这个服务从 CONNECT 请求报文中解析出域名和端口,创建到服务端的 TCP 连接,并和 CONNECT 请求中的 TCP 连接串起来,最后再响应一个 Connection Established 响应。修改浏览器的 HTTP 代理为 127.0.0.1:8888 后再访问 HTTPS 网站,代理可以正常工作。

    最后,将两种代理的实现代码合二为一,就可以得到全功能的 Proxy 程序了,全部代码在 50 行以内(当然异常什么的基本没考虑,这是我博客代码的一贯风格):

    var http = require('http');
    var net = require('net');
    var url = require('url');
    
    function request(cReq, cRes) {
        var u = url.parse(cReq.url);
    
        var options = {
            hostname : u.hostname, 
            port     : u.port || 80,
            path     : u.path,       
            method     : cReq.method,
            headers     : cReq.headers
        };
    
        var pReq = http.request(options, function(pRes) {
            cRes.writeHead(pRes.statusCode, pRes.headers);
            pRes.pipe(cRes);
        }).on('error', function(e) {
            cRes.end();
        });
    
        cReq.pipe(pReq);
    }
    
    function connect(cReq, cSock) {
        var u = url.parse('http://' + cReq.url);
    
        var pSock = net.connect(u.port, u.hostname, function() {
            cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
            pSock.pipe(cSock);
        }).on('error', function(e) {
            cSock.end();
        });
    
        cSock.pipe(pSock);
    }
    
    http.createServer()
        .on('request', request)
        .on('connect', connect)
        .listen(8888, '0.0.0.0');

    需要注意的是,大部分浏览器显式配置了代理之后,只会让 HTTPS 网站走隧道代理,这是因为建立隧道需要耗费一次往返,能不用就尽量不用。但这并不代表 HTTP 请求不能走隧道代理,我们用 Node.js 写段程序验证下(先运行前面的代理服务):

    var http = require('http');
    
    var options = {
        hostname : '127.0.0.1',
        port     : 8888,
        path     : 'imququ.com:80',
        method     : 'CONNECT'
    };
    
    var req = http.request(options);
    
    req.on('connect', function(res, socket) {
        socket.write('GET / HTTP/1.1\r\n' +
                     'Host: imququ.com\r\n' +
                     'Connection: Close\r\n' +
                     '\r\n');
    
        socket.on('data', function(chunk) {
            console.log(chunk.toString());
        });
    
        socket.on('end', function() {
            console.log('socket end.');
        });
    });
    
    req.end();

    这段代码运行完,结果如下:

    HTTP/1.1 301 Moved Permanently
    Server: nginx
    Date: Thu, 19 Nov 2015 15:57:47 GMT
    Content-Type: text/html
    Content-Length: 178
    Connection: close
    Location: https://imququ.com/
    
    <html>
    <head><title>301 Moved Permanently</title></head>
    <body bgcolor="white">
    <center><h1>301 Moved Permanently</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>
    
    socket end.

    可以看到,通过 CONNECT 让代理打开到目标服务器的 TCP 连接,用来承载 HTTP 流量也是完全没问题的。

    最后,HTTP 的认证机制可以跟代理配合使用,使得必须输入正确的用户名和密码才能使用代理,这部分内容比较简单,这里略过。

     

    我们知道 TLS 有三大功能:内容加密、身份认证和数据完整性。其中内容加密依赖于密钥协商机制;数据完整性依赖于 MAC(Message authentication code)校验机制;而身份认证则依赖于证书认证机制。一般操作系统或浏览器会维护一个受信任根证书列表,包含在列表之中的证书,或者由列表中的证书签发的证书都会被客户端信任。

    提供 HTTPS 服务的证书可以自己生成,然后手动加入到系统根证书列表中。但是对外提供服务的 HTTPS 网站,不可能要求每个用户都手动导入你的证书,所以更常见的做法是向 CA(Certificate Authority,证书颁发机构)申请。根据证书的不同级别,CA 会进行不同级别的验证,验证通过后 CA 会用他们的证书签发网站证书,这个过程通常是收费的(有免费的证书,最近免费的 Let's Encrypt 也很火,这里不多介绍)。由于 CA 使用的证书都是由广泛内置在各系统中的根证书签发,所以从 CA 获得的网站证书会被绝大部分客户端信任。

    通过 CA 申请证书很简单,本文为了方便演示,采用自己签发证书的偷懒办法。现在广泛使用的证书是 x509.v3 格式,使用以下命令可以创建:

    openssl genrsa -out private.pem 2048
    openssl req -new -x509 -key private.pem -out public.crt -days 99999

    第二行命令运行后,需要填写一些证书信息。需要注意的是 Common Name 一定要填写后续提供 HTTPS 服务的域名或 IP。例如你打算在本地测试,Common Name 可以填写 127.0.0.1。证书创建好之后,再将 public.crt 添加到系统受信任根证书列表中。为了确保添加成功,可以用浏览器验证一下:

    接着,可以改造之前的 Node.js 代码了,需要改动的地方不多:

    var http = require('http');
    var https = require('https');
    var fs = require('fs');
    var net = require('net');
    var url = require('url');
    
    function request(cReq, cRes) {
        var u = url.parse(cReq.url);
    
        var options = {
            hostname : u.hostname, 
            port     : u.port || 80,
            path     : u.path,       
            method     : cReq.method,
            headers     : cReq.headers
        };
    
        var pReq = http.request(options, function(pRes) {
            cRes.writeHead(pRes.statusCode, pRes.headers);
            pRes.pipe(cRes);
        }).on('error', function(e) {
            cRes.end();
        });
    
        cReq.pipe(pReq);
    }
    
    function connect(cReq, cSock) {
        var u = url.parse('http://' + cReq.url);
    
        var pSock = net.connect(u.port, u.hostname, function() {
            cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
            pSock.pipe(cSock);
        }).on('error', function(e) {
            cSock.end();
        });
    
        cSock.pipe(pSock);
    }
    
    var options = {
        key: fs.readFileSync('./private.pem'),
        cert: fs.readFileSync('./public.crt')
    };
    
    https.createServer(options)
        .on('request', request)
        .on('connect', connect)
        .listen(8888, '0.0.0.0');

    可以看到,除了将 http.createServer 换成 https.createServer,增加证书相关配置之外,这段代码没有任何改变。这也是引入 TLS 层的妙处,应用层不需要任何改动,就能获得诸多安全特性。

    运行服务后,只需要将浏览器的代理设置为 HTTPS 127.0.0.1:8888 即可,功能照旧。这样改造,只是将浏览器到代理之间的流量升级为了 HTTPS,代理自身逻辑、与服务端的通讯方式,都没有任何变化。

    最后,还是写段 Node.js 代码验证下这个 HTTPS 代理服务:

    var https = require('https');
    
    var options = {
        hostname : '127.0.0.1',
        port     : 8888,
        path     : 'imququ.com:80',
        method     : 'CONNECT'
    };
    
    //禁用证书验证,不然自签名的证书无法建立 TLS 连接
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    
    var req = https.request(options);
    
    req.on('connect', function(res, socket) {
        socket.write('GET / HTTP/1.1\r\n' +
                     'Host: imququ.com\r\n' +
                     'Connection: Close\r\n' +
                     '\r\n');
    
        socket.on('data', function(chunk) {
            console.log(chunk.toString());
        });
    
        socket.on('end', function() {
            console.log('socket end.');
        });
    });
    
    req.end();

    这段代码和前面文章最后那段的区别只是 http.request 换成了 https.request,运行结果完全一样,这里就不贴了。本文所有代码可以从这个仓库获得:proxy-demo

    转自:

    https://imququ.com/post/web-proxy.html

    https://imququ.com/post/web-proxy-2.html

    展开全文
  • centos搭建http代理

    千次阅读 2020-04-11 16:43:55
    文章目录一、配置:步骤:1、安装openssl2、安装squid3、安net-tools4、修改squid的配置文件squid.conf①、修改端口号②、开发防火墙5、启动squid6、本机代理访问:7、修改支持所有代理访问(使用) 一、配置: 一台...

    一、配置:

    一台centos云服务器:

    主要说下我这里的一些搭建的问题,centos的系统版本不要选的太高,不然可能设置不成功。

    我这里的是设置CentOS7.2 位系统的linux阿里云服务器。
    重要的事情说三遍(不然肯定踩坑,我搞了第三天才找到原因,才弄出来):CentOS7.2 位系统的linux阿里云服务器,CentOS7.2 位系统的linux阿里云服务器,CentOS7.2 位系统的linux阿里云服务器

    吐槽一下啊,之前是用的是centos8系统,结果就是搭建不成功,然后我正好设置socks5尝试,结果还是不行,偶然看到一个文章说需要7.2 centos系统,我更换系统之后,然后再搜些文章,测试就成功了搭建sock5,然后想着squid搭建http不成功是不是也是系统版本的原因,然后我就用我自己的服务器测试,结果还真是系统的原因,我自己的系统更换为7.2的搭建sock5和http都成功了。

    步骤:

    1、安装openssl

    判断是否安装openssl:

    openssl version -a
    

    如果出现下面的界面,说明已经安装,然后不用再安装:
    在这里插入图片描述

    安装命令:

    yum install openssl
    

    2、安装squid

    安装命令:

    yum install squid -y
    # -y 代表自动选择y,全自动安装
    

    在这里插入图片描述

    出现这个就代表安装成功了。
    在这里插入图片描述

    3、安net-tools

    安装命令:

    yum install net-tools
    

    安装成功:
    在这里插入图片描述

    4、修改squid的配置文件squid.conf

    ①、修改端口号

    参考配置内容:

     cat /etc/squid/squid.conf
    

    默认是3128的端口号,建议修改,防止人家扫描代理被分享

    在这里插入图片描述

    使用vi修改配置文件,找到上面端口号的位置,我这里改为6128

    vi /etc/squid/squid.conf
    
    

    改好端口号:
    在这里插入图片描述
    默认squid的access日志里的时间为unix时间戳,不方便阅读,可以通过在 /etc/squid/squid.conf 增加一行logformat配置:

    #此行加在配置文件末尾即可
    #access log time human-readable
    logformat squid %tl.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
    

    ②、开启防火墙

    开启squid的端口号并且重新启动:

    firewall-cmd --zone=public --add-port=6128/tcp --permanent
    firewall-cmd –reload
    

    如果报错FirewallD is not running
    需要下面解决方法:

    root用户身份运行以下命令:

    启用防火墙
    systemctl enable firewalld
    动防火墙
    systemctl start firewalld
    查防火墙的状态
    systemctl status firewalld
    

    下面这个就是启动防火墙成功。
    在这里插入图片描述

    然后再执行上面开启squid的端口号6128(你的根据自己的设置进行更改)

    5、启动squid

    systemctl start squid
    
    

    查看进程:

     netstat -tunpl
    

    在这里插入图片描述

    6、本机代理访问:

    本机代理访问

    curl -x 127.0.0.1:6128 www.baidu.com
    

    说明初步配置代理成功了。但是使用自己电脑还不能使用这个代理。

    在这里插入图片描述

    7、修改支持所有代理访问(使用)

    编辑squid的配置文件,在http_access deny all的前面添加俩行:

    acl client src 0.0.0.0/0
    http_access allow client
    

    可以把下图的中的http_access deny all 直接注释
    如果修改并且保存:
    在这里插入图片描述
    然后重新启动squid:

    systemctl restart squid
    

    这个时候可以使用代理了,但是会是透明代理,需要设置用户名和密码,增强代理的可用性,防止被随意扫描使用,也可以加些设置字段,然后弄成高匿的代理。

    8、设置用户名+密码

    ①、设置密码文件

    #设置密码
    yum -y install httpd-tools
    touch /etc/squid/passwd && chown squid /etc/squid/passwd
    

    在这里插入图片描述

    ②、创建用户密码

    #创建用户密码
    htpasswd /etc/squid/passwd yourusername
    

    执行命名(yourusername就是代理的用户名)之后,俩次输入密码(代理的密码)
    在这里插入图片描述

    ③、更改配置文件:

     vi /etc/squid/squid.con
    
    #在配置文件的acl代码块下添加
    auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
    auth_param basic children 5
    auth_param basic realm Squid Basic Authentication
    auth_param basic credentialsttl 2 hours
    acl auth_users proxy_auth REQUIRED
    http_access allow auth_users
    #添加
    http_access allow all
    #或注释掉
    http_access deny all
    

    一会我会把我最终可用的配置文件复制下来放到最后的下方。
    在这里插入图片描述

    ④、重启服务squid:

    #进行配置后请记得重启服务
    systemctl restart squid
    

    这个时候可以使用用户名的代理进行测试了。

    我这里使用的是谷歌的一个插件SwitchyOmega

    然后访问:http://httpbin.org/ip
    在这里插入图片描述

    从结果中可以看出 、即使设置了用户+密码,http的代理依然不是高匿的,前面就是我的本机代理,后面是代理ip,还是不好,下面需要在配置中设置一下即可。

    9、把代理设置为高匿的代理:

    vi /etc/squid/squid.conf
    

    在配置的文件中后面加入这些自段即可。

    request_header_access X-Forwarded-For deny all
    request_header_access From deny all
    request_header_access Via deny all
    

    更改配置文件之后记得保存:
    然后重启:

    systemctl restart squid
    

    然后再次访问:http://httpbin.org/ip
    在这里插入图片描述

    这个时候,即可变成高匿的代理。

    10、我的配置文件:

    我想跟多人看到的更关系这个配置文件,所以我是有winscp链接我的服务器,然后我把文件下载复制到这里了,希望能帮助的需要的小伙伴了,我当时想要完整的都没有找到,弄了第三天总算把这个弄好了,注意系统版本呀,我的是centos 7.2 64位的linuxcentos 7.2 64位的linuxcentos 7.2 64位的linux,重要的事情提示三遍,在看不到自己和我一样踩坑吧,我可是才坑第三天才搞出来,各种博客也没人说是版本有限制,不说了,说多了都是泪。直接上配置文件代码。

    #
    # Recommended minimum configuration:
    #
    
    # Example rule allowing access from your local networks.
    # Adapt to list your (internal) IP networks from where browsing
    # should be allowed
    acl localnet src 10.0.0.0/8	# RFC1918 possible internal network
    acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
    acl localnet src 192.168.0.0/16	# RFC1918 possible internal network
    acl localnet src fc00::/7       # RFC 4193 local private network range
    acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
    
    acl SSL_ports port 443
    acl Safe_ports port 80		# http
    acl Safe_ports port 21		# ftp
    acl Safe_ports port 443		# https
    acl Safe_ports port 70		# gopher
    acl Safe_ports port 210		# wais
    acl Safe_ports port 1025-65535	# unregistered ports
    acl Safe_ports port 280		# http-mgmt
    acl Safe_ports port 488		# gss-http
    acl Safe_ports port 591		# filemaker
    acl Safe_ports port 777		# multiling http
    acl CONNECT method CONNECT
    
    
    
    #在配置文件的acl代码块下添加
    auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
    auth_param basic children 5
    auth_param basic realm Squid Basic Authentication
    auth_param basic credentialsttl 2 hours
    acl auth_users proxy_auth REQUIRED
    http_access allow auth_users
    
    #
    # Recommended minimum Access Permission configuration:
    #
    # Deny requests to certain unsafe ports
    http_access deny !Safe_ports
    
    # Deny CONNECT to other than secure SSL ports
    http_access deny CONNECT !SSL_ports
    
    # Only allow cachemgr access from localhost
    http_access allow localhost manager
    http_access deny manager
    
    # We strongly recommend the following be uncommented to protect innocent
    # web applications running on the proxy server who think the only
    # one who can access services on "localhost" is a local user
    #http_access deny to_localhost
    
    #
    # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
    #
    
    # Example rule allowing access from your local networks.
    # Adapt localnet in the ACL section to list your (internal) IP networks
    # from where browsing should be allowed
    http_access allow localnet
    http_access allow localhost
    
    #acl client src 0.0.0.0/0
    #http_access allow client
    http_access allow all
    # And finally deny all other access to this proxy
    #http_access deny all
    
    # Squid normally listens to port 3128
    http_port 9999
    
    # Uncomment and adjust the following to add a disk cache directory.
    #cache_dir ufs /var/spool/squid 100 16 256
    
    # Leave coredumps in the first cache dir
    coredump_dir /var/spool/squid
    
    #
    # Add any of your own refresh_pattern entries above these.
    #
    refresh_pattern ^ftp:		1440	20%	10080
    refresh_pattern ^gopher:	1440	0%	1440
    refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
    refresh_pattern .		0	20%	4320
    
    
    request_header_access X-Forwarded-For deny all
    request_header_access From deny all
    request_header_access Via deny all
    
    
    #此行加在配置文件末尾即可
    #access log time human-readable
    logformat squid %tl.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
    
    
    
    

    11、设置开机自启动:

    突然搜到俩种方法:我也不清楚哪个正确,都粘贴这里吧:

    方法1:

    chkconfig --level 35 squid on
    

    然后
    运行结果如下图:
    在这里插入图片描述

    方法2:
    其实当你看到上面的步骤,就知道下面的命令了,其实上面的命令就是转到下面的命令了,其实上面的就是转到下面这个命令。

    systemctl enable squid
    

    然后我把服务器重启,然后重启中测试代理是不可
    在这里插入图片描述
    在这里插入图片描述
    等待一会重启好,我没有自己手动启动代理服务测试开启自启动称成功了。

    结果如下图:
    在这里插入图片描述

    在这里插入图片描述

    补充一个点

    如果你在ecs上可以使用,本地代理的时候可以,但是远程无法使用,这个时候可能就是你的防火墙打开了,但是没有把访问的端口给释放给指定ip,这个时候需要关闭防火墙即可。
    因为我后续另一台测试配置代理时候,安装防火墙后,端口没有配置成功,还把我的elasticsearch端口给拦截了,突然发现es服务器也不能使用了,这个时候关闭防火墙即可解决。

    关闭命令

    systemctl stop firewalld
    

    参考文章:
    https://guozh.net/centos-install-squid-proxy-server/
    https://www.liquidweb.com/kb/how-to-start-and-enable-firewalld-on-centos-7/
    https://zhuanlan.zhihu.com/p/95523737
    https://blog.csdn.net/u011884440/article/details/78824224
    https://www.cnblogs.com/zhaojingyu/p/10197411.html
    https://blog.csdn.net/f365420465/article/details/100526360
    https://www.cnblogs.com/NetKillWill/p/squid.html
    https://www.bbsmax.com/A/ke5jR4w75r/
    https://alanhou.org/centos-7-squid/

    展开全文
  • 基于host的http代理--hproxy

    千次阅读 2019-08-29 22:35:51
    本文主要讲述,如何实现一个基于host方式的http代理,以及它与普通代理之间的区别。这种方式的代理主要可以应用于哪些实际的测试场景。 与普通代理的区别 所谓的普通代理,就是我们日常会用到的那种代理,通常需要...

    无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。

    在这里插入图片描述

    说到代理,大多数情况我们都会想到通过浏览器设置的正向代理,以及类似nginx的反向代理;而实际上除此之外还有一种基于host方式实现的代理。

    本文主要讲述,如何实现一个基于host方式的http代理,以及它与普通代理之间的区别。这种方式的代理主要可以应用于哪些实际的测试场景。

    与普通代理的区别

    所谓的普通代理,就是我们日常会用到的那种代理,通常需要客户端本身支持,使用时对客户端进行代理信息配置。最常见的就是对浏览器、curl等客户端配置代理,一般主要用来翻墙的!
    在这里插入图片描述

    而host代理则不是主流的代理方式,它的特点是通过设置host就能实现代理,而不需客户端本身支持,相对应用的访问更广一些。下面我们就来逐一对比下它们的具体区别:

    对比项普通代理HOST代理
    需要客户端支持
    设置方式配置客户端配置HOST
    支持透明代理
    支持绝对路径
    支持非80端口
    实现方式sockethttp
    URL路径支持绝对路径相对路径
    代理服务与客户端同机支持不支持
    代理配置方式域名配置灵活host配置不灵活

    通过对比可以发现它们都能满足基本的HTTP代理功能,主要区别在于适用的场景有所不同;普通代理只要客户端本身支持基本上什么请求都可以代理,HOST代理只要请求是80/443端口都可以代理。

    实现方式

    接收请求

    实现一个HOST代理是非常简单的,你只需要基于一个现成的WEB框架,比如:Flask,Tornado;再加上一个url请求框架即可,比如:requests。而首先你得实现一个可以接手任意URL路径的请求处理函数,如下:

    from werkzeug.routing import BaseConverter
    from flask import Flask, request, jsonify
    
    
    class RegexConverter(BaseConverter):
        def __init__(self, url_map, *args):
            super(RegexConverter, self).__init__(url_map)
            self.url = url_map
            self.regex = args[0]   # 正则的匹配规则
    
        def to_python(self, value):
            return value
    
    
    app = Flask(__name__, static_url_path='/do_not_use_this_path__')
    app.url_map.converters['re'] = RegexConverter
    
    
    @app.route('/<re(r".*"):path>')
    def proxy(path):
        url = request.base_url
        query = request.args
        method = request.method
        headers = request.headers
        form_data = request.form
        body = request.data
        files = request.files
    
        payload = {
            'path': f'/{path}',
            'url': url,
            'method': method,
            'headers': dict(headers),
            'query': query,
            'form_data': form_data,
            'body': body.decode('utf-8'),
            'files': files
        }
    
        return jsonify(payload)
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=80)
    

    启动这个web服务之后,只要在host文件中配置一个指向该服务所在机器的IP和目标域名映射即可。比如:

    # host文件添加一个映射
    10.0.0.1 www.baidu.com
    

    之后,就可以在浏览器访问http://www.baidu.com这个网址了,路径内容和参数随便输,它都会完整把你请求的信息给返回来,类似一个镜像服务。效果如下:
    在这里插入图片描述

    代理请求

    目前来说,我们已经完成HTTP代理的一半功能了,剩下的就是如何去发送获取到的HTTP请求,之后在把请求响应内容组装好,再发回给浏览器或客户端。首先是组装要发送的请求,样例代码如下:

    class METHOD:
        GET = 'GET'
        POST = 'POST'
        PUT = 'PUT'
        DELETE = 'DELETE'
        HEAD = 'HEAD'
        OPTIONS = 'OPTIONS'
        
    def warp_request_data(payload):
        """
        :param payload: {
            'path': path,
            'url': url,
            'method': method,
            'headers': dict(headers),
            'query': query,
            'form_data': form_data,
            'body': body.decode('utf-8'),
            'files': files
        }
        :return:
        """
        send_data = {'method': payload['method'], 'url': payload['url'],
                     'headers': payload['headers'], 'data': None, 'files': None}
    
        if payload['method'] in (METHOD.GET, METHOD.HEAD, METHOD.OPTIONS):
            send_data['data'] = payload['query']
        elif payload['method'] in (METHOD.POST, METHOD.DELETE, METHOD.PUT):
            if payload['query']:
                payload['url'] = f"{payload['url']}?{urllib.parse.urlencode(payload['query'])}"
            if payload['form_data']:
                ct = payload['headers'].get('Content-Type')
                if 'application/x-www-form-urlencoded' in ct:
                    send_data['data'] = payload['form_data']
                elif 'multipart/form-data' in ct:
                    send_data['data'] = payload['form_data']
                    send_data['files'] = payload['files']
            elif payload['body']:
                send_data['data'] = payload['body']
            elif payload['files']:
                send_data['files'] = payload['files']
    
        return send_data
    

    接着,通过requests发送组装好的请求数据内容。方法如下:

    from requests import request as sender
    
    def send_request(req):
        return sender(req['method'].lower(), req['url'], headers=req['headers'],
                      data=req['data'], files=req['files'])
    

    最后,把获取到的响应进行再次组装,便于主程序直接返回内容给浏览器或客户端。代码如下:

    def warp_response_data(rep):
        body = rep.content
        if 'Transfer-Encoding' in rep.headers:      # 不支持chunk
            del rep.headers['Transfer-Encoding']
            rep.headers['Content-Length'] = len(body)
        if 'Connection' in rep.headers:             # 不支持keep-alive
            del rep.headers['Connection']
        if 'Content-Encoding' in rep.headers:       # 不支持gzip
            del rep.headers['Content-Encoding']
        rep.headers['Server'] = 'host proxy/0.1'    # 修改服务器信息
    
        return {
            'code': rep.status_code,
            'headers': dict(rep.headers),
            'body': body
        }
    

    同时,需要在http处理的主函数中添加对http请求的代理操作。最后的http处理主函数新增内容如下:

    @app.route('/<re(r".*"):path>')
    def proxy(path):
        req = Action.warp_request_data(payload)
        rep = Action.send_request(req)
        ret = Action.warp_response_data(rep)
    
        return ret['body'], ret['code'], ret['headers']
    

    插件机制

    目前为止完成了这么多功能之后,一个http的代理就已经初步完成了。只是目前仅仅是做了代理,但是没有任何的作用。因为我们不能对它进行任何操作。要让它变得有意义就得添加插件机制,让用户可以对代理的请求进行处理和操作。

    首先,定义一个插件类,用于注册和执行插件内容。代码如下:

    class Plugins:
        def fire(self, context):        # 插件事件触发
            for func in self.events:
                func(context)
    
        def register(self, func):       # 插件事件注册
            self.events.append(func)
    
    
    class PRE_PROXY(Plugins):
        def __init__(self):
            self.events = []
    
    
    class POST_PROXY(Plugins):
        def __init__(self):
            self.events = []
    
    
    pre_proxy = PRE_PROXY()
    post_proxy = POST_PROXY()
    
    
    def before_proxy(func):         # 注册触发代理前装饰器
        pre_proxy.register(func)
        return func
    
    
    def after_proxy(func):          # 注册触发代理后装饰器
        post_proxy.register(func)
        return func
    

    同时,也要在http主函数中添加插件函数的调用,修改后的代码如下:

    ...
        context = {}
        req = Action.warp_request_data(payload)
    
        context['request'] = req
        pre_proxy.fire(context)         # 触发代理前事件
    
        rep = Action.send_request(req)
        ret = Action.warp_response_data(rep)
    
        context['response'] = ret
        post_proxy.fire(context)        # 触发代理后事件
    ...
    

    最后,在同目录下新建一个插件脚本文件script.py。其内容如下:

    from .plugins import before_proxy, after_proxy
    
    @before_proxy
    def before(context):
        print(context)
    
    @after_proxy
    def after(context):
        print(context)
    

    这个脚本内容非常的简单,导入2个注册装饰器分别用来注册代理前和代理后的事件。注册函数可以接收到一个请求和响应的上下文对象参数,这里仅仅是打印了出来。

    当然,插件还可以做很多其它的事情,比如:过滤特定url并保存请求信息;修改请求和响应信息内容等。完整项目代码请关注公众号并回复hproxy即可!

    应用场景

    这类http代理主要应用的场景一般多为测试或者开发,日常生活中翻墙还是要是普通代理。主要可以用于辅助测试,比如:mock系统,api接口测试等。

    对于mock系统,可以用来录制mock内容,尤其是针对服务端请求第三方接口的请求录制。比如:

    • 录制调用第三方银行的接口请求,作为mock内容
    • 选择性的mock同域名下的部分URL请求,其它URL则透传

    用于api自动化测试,可以直接录制对应接口的API请求,用于快速生成自动化测试用例。当然还可以用于安全测试,篡改指定的http请求内容。

    后期功能增强

    虽然目前该demo程序已经可以开始用于辅助测试工作了,但是想要更加的易用,还有很多的特性需要支持。

    • 协程支持
    • 过滤功能
    • https支持
    • websocket支持
    • keep-alive支持
    • chunk支持

    获取更多关于Python和测试开发相关的文章,请扫描如下二维码!
    在这里插入图片描述

    展开全文
  • HTTP代理与HTTPS代理IP

    千次阅读 2021-03-10 16:34:11
    如今越来越多的网站采用https协议,据说这样比较安全,导致一度火爆的HTTP代理IP也出现些许力不从心,许多用户为了能更安全的上网,要求使用https代理IP,这到底是为什么?IP和HTTPS代理有什么不同? 安全超文本传输...

    在这里插入图片描述

    如今越来越多的网站采用https协议,据说这样比较安全,导致一度火爆的HTTP代理IP也出现些许力不从心,许多用户为了能更安全的上网,要求使用https代理IP,这到底是为什么?IP和HTTPS代理有什么不同?

    安全超文本传输协议HTTPS(SecureHypertextTransferProtocol)是基于HTTP开发的一个安全的通信通道,用于在用户计算机和服务器之间交换信息。其信息交换使用安全套接字层(SSL),简单地说,这是一种使用TLS/SSL加密的HTTP协议的安全版本。

    由于HTTP协议采用明文传输信息,因此存在信息窃听、篡改和劫持的风险,而TLS/SSL协议具有认证、信息加密和完整性检查等功能,可避免此类问题。

    TLS/SSL是在TCP和HTTP之间的一层协议,它不会影响原始的TCP和HTTP协议,因此基本上不需要对HTTP页面做很多HTTPS的修改。
    文章转自:http://h.zhimaruanjian.com/faq/169059.html

    展开全文
  • golang 实现HTTP代理和反向代理

    千次阅读 2018-10-18 17:16:13
    代理的核心功能可以用一句话概括:接受客户端的请求,转发到后端服务器,获得应答之后返回给客户端。下图是 《HTTP 权威指南》一书中给出的图例,可以很清晰地说明这一流程: 代理的功能有很多,事实上整个互联网...
  • HTTP 代理服务器的设计与实现

    千次阅读 热门讨论 2018-11-07 14:01:39
    (1) 设计并实现一个基本 HTTP 代理服务器。要求在指定端口(例如 8080)接收来自客户的 HTTP 请求并且根据其中的 URL 地址访问该地址 所指向的 HTTP 服务器(原服务器),接收 HTTP 服务器的响应报文,并 将响应报文...
  • 国内免费http代理ip地址

    千次阅读 2021-08-18 10:29:32
    最常用的代理协议是HTTP代理ip协议。让用处非常广泛,这里就不一一介绍了,很多用户由于公司的内网环境,那么用户需要访问因特网,要设置浏览器为LAN设置代理服务器才能访问。 123.181.3.82:8888 [普匿] 中国-河北-...
  • 国内最新免费HTTP代理IP

    千次阅读 2021-07-07 13:42:20
    110.86.177.154:9999 [未知代理ip] 中国福建省莆田市 电信免费HTTP 175.146.102.146:9999 [普匿代理ip] 中国辽宁省鞍山市 联通免费HTTP 112.123.40.232:9999 [高匿代理ip] 中国安徽省池州市 联通免费HTTP 114.238....
  • HTTP代理服务器的实现

    万次阅读 2018-04-21 20:18:04
    接下来都是我对HTTP代理服务器的理解。 HTTP代理服务(proxy server) 器就是客户端也是服务端,是一个事务处理的中间人,就像下图所展示的一样, 图片来源于《HTTP权威...
  • Python实现的简易HTTP代理服务器

    万次阅读 多人点赞 2019-03-14 16:05:32
    Python实现的简易HTTP代理服务器 使用socket编程实现代理服务器,首先它得是一个服务器 至此,http代理服务器的核心代码已经完成 于是一个非常令人尴尬的问题就出现了,在某一次读取完毕之后,我怎么知道我读完了呢...
  • 近年来,随着因特网、电子平台和新媒体的发展,人们对http代理ip服务的需求逐渐增加,同时对隐私的保护也越来越重视,许多私人用户也开始借助该软件保护个人上网安全。事实上,很多普通用户开始重视http代理ip服务,...
  • 本来打算通过UDP53来绕过认证,在准备实现DNS隧道的时候,发现所涉及的内容实在是太多了…(DNS解析原理,域名的原理,隧道技术,代理技术 and so on),每一个知识点都能让我深入去研究一段时间。因此在实现DNS隧道...
  • 什么是HTTP代理HTTP代理的作用

    千次阅读 2020-03-20 18:30:42
    1、HTTP代理HTTP代理就是介于浏览器和web服务器之间的一台服务器,连接代理后,浏览器不再直接向web服务器取回网页,而是向代理服务器发出request信号,代理服务器再想web服务器发出请求,收到web服务器返回的数据...
  • linux搭建http代理服务器

    千次阅读 2019-12-09 11:44:59
    如果想通过某台LINUX服务器作为跳板,...它适用于需要完整 HTTP 代理特性,但系统资源又不足以运行大型代理的场景,比如嵌入式部署。 安装 TinyProxy yum -y install tinyproxy 配置 TinyProxy vim /etc/tinyprox...
  • 免费http代理服务器ip地址和端口

    万次阅读 2021-03-08 16:04:02
    当前,在网络上有很多关于HTTP代理和SOCKS代理的讨论,这些都是基础的http代理服务器ip地址,下面我们来详细介绍一下HTTP代理和SOCKS代理的使用技巧,以及分享一些http代理服务器ip地址,感兴趣的小伙伴不妨来看下哦...
  • HTTP代理关闭还是自动的呢?

    千次阅读 2021-06-10 18:59:59
    HTTP代理则是首选,是生活中比较常用的代理服务器之一。 对于电脑小白来说,最为纠结的问题就是HTTP代理是关闭还是自动好呢? HTTP主要指的是用户使用代理服务器进行网络访问,不同于浏览器和web服务器,是前面两者...
  • http代理的作用

    千次阅读 2019-02-27 10:31:29
    经常使用网络的人可能会常常听到这样的一个词:http代理。那么它真正的作用很多人都是模棱两可的,在这里给大家普及一下在我们大部分人的网络活动中,http是比较常见的网络协议,因而http代理也是普通人最常使用的一...
  • HTTP代理服务器

    万次阅读 2019-06-14 21:40:16
    代理服务器实现流程 创建一个监听服务器,监听客户端的连接。 客户端连接上后,将客户端要上网的信息,发给网络web服务器, 然后从那里读取数据,再发给客户端。 注:客户端是通过浏览器的设置,来设置我的地址...
  • Zabbix5.0监控Elasticsearch(Http代理

    千次阅读 2021-09-17 14:24:38
    上次写了一篇Zabbix5.0使用Sender模式监控Elasticsearch的文章,今天补充另外一种更简单方便的监控方式,这也是Zabbix5.0官方推荐的监控方式,使用http代理的方式去监控Elasticsearch,官方还提供了监控模板,部署...
  • Linux配置http代理(原理)

    千次阅读 2020-07-05 17:58:00
    全局代理 如果要全局用户使用应用于所有的Shell,就需要修改 /etc/profile 文件 代理服务开启 设置全局代理,需要编辑profile文件 vi /etc/profile 文末添加以下代理配置,参考代理是否需要用户名密码 #无用户名...
  • HTTP代理服务器有哪些

    千次阅读 2020-05-23 15:27:49
    先讲解一下什么是HTTP代理服务器:它是介于Web客户端和Web服务器之间的信息中转站。它既是Web客户端的服务器,又是Web服务器的客户端。再来说下HTTP代理有哪些?HTTP代理服务器按其所处的位置可以分成:正向HTTP代理...
  • 于是尝试自己搭建了一个ADSL代理实现HTTP代理。 ADSL拨号代理:电信宽带每一次拨号后会更换IP,利用这一点在IP更换后将新的IP存入到代理池中。 代理的搭建过程分为以下几步: (1)购买代理服务器,笔者选择了淘b...
  • 国内透明免费http代理ip地址分享

    千次阅读 2021-03-08 16:18:31
    不管付费还是免费,哪些国内的http代理ip地址是真正意义上可以使用的?下面就给大家分享一些,提供给大家使用。 ip地址分享: 43.243.166.2218080透明HTTP中国 香港 123.139.56.2389999透明HTTP中国 陕西省 西安市 ...
  • 一、nginx http 代理 nginx http 代理 通过proxy_set_header,返回客户端真实IP地址及端口,而不是代理主机ip, #proxy ngx 代理不支持 https,有https需求可以用squid server { listen 9998; allow 192....
  • Web代理 VS HTTP代理

    千次阅读 2019-01-24 18:19:10
    HTTP代理比Web代理更快,并支持所有站点。但它没有加密。   Web代理和HTTP代理是匿名浏览的两种常用方法。许多人使用它们来隐藏真实的IP并保护在线隐私。但是,哪一个更快,更可靠,更适合上网?   Web代理 ...
  •  但是如何使用C/C++通过代理进行http请求的资(源)料(码)却没有找到。  也不知道是不是我的关键字搜索的不对。。。  所以准备自己研究一把。   二、 第一步:分析  分析代理服务器原理:  客户端 &...
  • Python爬虫方式抓取免费http代理IP

    千次阅读 2019-07-23 16:37:43
    我们新手在练手的时候,常常需要一些代理IP进行爬虫抓取,但是因为学习阶段,对IP质量要求不高,主要是弄懂原理,所以花钱购买爬虫代理IP就显得没必要(大款忽略),今天跟大家分享一下,如果使用爬虫抓取免费的代理...
  • 问题: 使用hexo搭建博客, 执行hexo init时包含git clone的操作,但是使用的是https协议, 不是ssh, 所以为git设置https代理, 但是只设置https代理并不能加速, 与此同时, 只设置http代理能稍微加点速度, 只有同时设置...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 767,313
精华内容 306,925
关键字:

http代理