代理服务器简介及libcurl测试

x33g5p2x  于2022-04-25 转载在 其他  
字(7.1k)|赞(0)|评价(0)|浏览(174)

**      代理服务器英文全称是Proxy Server****,其功能就是将局域网用户连接到Internet****,代理网络用户去获得网络信息**。形象地说,它是网络信息的中转站,是连接内部局域网和Internet的一种网关,该网关是运行代理服务软件的计算机,能够实现两种不同的网络互相通信。代理服务器有两个网络接口,一个接口用于连接Internet,另一个接口则用于连接内部网络。它的工作主要在开放系统互联(OSI)模型的会话层。

**      代理服务器定义**:代理服务器是在用户和互联网之间提供网关的系统或路由器。因此,它有助于防止网络攻击者进入专用网络。它是一个服务器,被称为”中介”,因为它介于最终用户和他们在线访问的网页之间。代理服务器本质上是互联网上具有自己IP地址的计算机。它接受来自客户端的传入请求并将这些请求转发到目标服务器。它充当最终用户和互联网之间的网关。它将客户端系统和Web服务器与全球网络分开。它代表用户使用不同的IP地址,对Web服务器隐藏用户的真实地址。

**      代理服务器的作用**:

**     **(1).提高安全性。它可以设置为网络过滤器或防火墙,保护你的计算机免受恶意软件等互联网威胁。

**     **(2).平衡互联网流量以防止崩溃。

**     **(3).控制办公室内的网站员工和员工访问。

**     **(4).通过缓存文件或压缩传入流量来节省带宽。

**     **(5).隐藏用户身份(IP地址),以免受到攻击。

**      代理服务器的工作原理**:因为代理服务器有自己的IP地址,所以它充当计算机和互联网的中间人。你的计算机知道这个地址,当你在Internet上发送请求时,它会被路由到代理,然后代理从Web服务器获取响应并将数据从页面转发到你计算机的浏览器,例如Chrome或 Microsoft Edge等。

**     **当客户端向服务器发出请求,该请求送到代理服务器,代理服务器接收到该连接请求后,对其进行身份认证和访问控制,如果客户端通过了代理服务器的身份认证和访问控制,就代替客户端向该服务器发出请求,服务器响应以后,代理服务器将响应的数据传送给客户端。可见代理服务器是客户访问Internet远程服务器时的中介,对客户而言它是服务器,对远程服务器而言它是客户,代理服务器是典型的客户/服务器模式的一个例子。在此模式中,客户端向服务器发出请求,服务器对请求才做出响应,服务器是被动的,仅在收到客户端的请求时才做出响应。客户的请求由代理服务器受理,此时代理服务器是一个服务器的角色,对客户的请求,代理服务器必须向真正的目标服务器发出请求,此时代理服务器又是目标服务器的客户。

**      有许多不同类型的代理服务器**:

**     **1.正向代理(Forward Proxy):位于客户端前面,用于将数据发送给内部网络中的用户组。用户利用代理服务器访问目标服务器。发送请求时,代理服务器会对其进行检查以决定是否应继续建立连接。正向代理最适合需要单点入口的内部网络。它为网络中的用户提供IP地址安全性,并允许直接的管理控制。但是,正向代理可能会限制组织满足个别最终用户需求的能力。

**     **2.反向代理(Reverse Proxy):能根据客户端的请求,从其代理的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端。反向代理访问模式下客户端只会得知反向代理服务器的IP地址,而不知道在代理服务器后面的原始服务器的存在。正向代理代理的是用户,而反向代理则相反,代理对象是目标服务器,是指服务端利用代理服务器给用户提供服务。

正向代理和反向代理处理流程如下:下图来自于:https://docs.microsoft.com  

**     **3.透明代理(Transparent Proxy):可以为用户提供与使用家用计算机相同的体验,它是”透明的”。他们也可以被”强制”给用户,这意味着他们在不知情的情况下被连接起来。透明代理非常适合希望使用代理而不让员工知道他们正在使用代理的公司。它具有提供无缝用户体验的优势。另一方面,透明代理更容易受到某些安全威胁的影响。

**     **4.匿名代理(Anonymous Proxy):专注于使互联网活动无法追踪。它的工作原理是代表用户访问互联网,同时隐藏他们的身份和计算机信息。

**     **5.扭曲代理(Distorting Proxy):将自己标识为网站的代理,但隐藏了自己的身份。它通过将其IP地址更改为不正确的地址来实现这一点。对于想要在访问互联网时隐藏其位置的人来说,扭曲代理是一个不错的选择。这种类型的代理可以使你看起来像是从特定国家/地区浏览,并为你提供不仅隐藏你的身份而且还隐藏代理身份的优势。这意味着即使你与代理相关联,你的身份仍然是安全的。但是,一些网站会自动阻止扭曲代理,这可能会阻止最终用户访问他们需要的网站。

**     **6.数据中心代理(Data Center Proxy):不隶属于互联网服务提供商(ISP),而是由另一家公司通过数据中心提供。代理服务器存在于物理数据中心,用户的请求通过该服务器进行路由。

**     **7.住宅代理(Residential Proxy):为你提供属于特定物理设备的IP地址。然后通过该设备引导所有请求。住宅代理非常适合需要验证其网站上的广告的用户,因此你可以阻止来自竞争对手或不良行为者的cookie、可疑或不需要的广告。

**     **8.公共代理(Public Proxy):任何人都可以免费访问公共代理。它的工作原理是让用户访问其IP地址,在他们访问网站时隐藏他们的身份。公共代理最适合那些以成本为主要关注点而安全性和速度不是主要关注点的用户。

**     **9.共享代理(Shared Proxy):一次由多个用户使用。它们使你可以访问可能由其他人共享的IP地址。

**      按协议分类**:

**     **1.HTTP代理服务器(HTTP Proxy Server):使用HTTP(超文本传输协议)协议,它允许用户使用不同的IP地址浏览网页,但不提供任何额外的隐私或安全性。所有用户活动在 Internet上仍然可见,就像没有代理一样。

**     **HTTP代理服务器是介于Web客户端和Web服务器之间的中间程序。它既作为Web客户单的服务器,又作为Web服务器的客户端。工作流程为:客户端和HTTP代理服务器建立连接后,客户端将请求数据发送给HTTP代理服务器,HTTP代理服务器处理请求数据,如果不需要请求Web服务器,直接回复客户端的请求;否则,HTTP代理服务器作为客户端和Web服务器建立连接,然后将请求数据发送给Web服务器,Web服务器处理该请求并响应数据发送给HTTP代理服务器,最后HTTP代理服务器对响应数据进行相应处理并回复客户端的请求。

**     **HTTP代理服务器按其所处的位置可以分成:正向HTTP代理服务器、反向HTTP代理服务器和透明HTTP代理服务器。

**     **(1).正向HTTP代理服务器:客户端的浏览器进行代理配置,浏览器的HTTP请求发送到HTTP代理服务器,HTTP代理服务器解析HTTP协议报文,得到Web服务器的域名或IP,然后进行相应的处理。此种HTTP代理服务器,用户知道它的存在。HTTP代理服务器处在客户端局域网与公共网络的出口处。

**     **(2).反向HTTP代理服务器:以HTTP代理服务器来接受互联网上的HTTP连接请求,然后将请求转发给内部网络上的Web服务器,并从Web服务器上得到的请求结果返回给互联网上请求连接的客户端,此时HTTP代理服务器对外表现为一个服务器。

**     **(3).透明HTTP代理服务器:客户端用户不需要在浏览器中设置任何HTTP代理代理服务器,只需要设置默认缺省网关,他们不知道HTTP代理服务器的存在。用户的公网HTTP请求数据包都被路由到缺省网关,此时局域网内运行了一个HTTP代理服务器,然后数据包被从定向到HTTP代理服务器的服务端口,最后由HTTP代理服务器向外发送请求。

**     **HTTP代理服务器提供了一种访问万维网的有效途径,它具有如下作用:

**     **(1).节约IP地址资源:整个局域网使用HTTP代理服务器访问公共网络,HTTP代理服务器只需一个公共网络IP即可,其它网络设备可使用内部IP。

**     **(2).提供安全功能:局域网内的用户对外是隐蔽不可见的,外部网络认为所有的请求都是从HTTP代理服务器发起,从而可防止内部局域网被不法分子攻击。

**     **(3).访问控制:用户只能通过HTTP代理服务器连接外部网络,HTTP代理服务器可以对用户的权限进行控制,对用户分组管理。

**     **(4).节约出口流量及提高访问的速度:一般HTTP代理服务器提供缓存功能,如果请求的页面,HTTP代理服务器有缓存并且有效,就不需要访问Web服务器,直接把页面内容返回给客户端。

**     **(5).减轻Web服务器的负载:对于被频繁访问的Web服务器,要处理海量客户端的请求,由于处理能力的限制,可能导致Web服务器过载,从而引起服务质量的下降和响应时间的延长。HTTP代理服务器通过缓存机制可以减少对Web服务器的请求数目。

**     **常用HTTP代理服务器:Apache、Squid。

**     **按其所处的位置,Web缓存可以分为客户端缓存、服务器缓存和代理缓存:

**     **(1).客户端缓存:用户使用浏览器访问万维网,浏览器一般具有缓存功能。为了加速浏览,浏览器将用户最近访问过得文档存储在本地磁盘。当访问者访问某个页面时,先查询本地磁盘该页面是否有缓存且有效,如果本地存在并且有效,直接从本地获取文档并显示。否则向服务器发送HTTP请求。

**     **(2).服务器缓存:服务器使用部分内存或者是磁盘来缓存文件。当客户端向Web服务器发送请求时,服务器处理请求,并把结果保存在缓存空间,当下一次有相同请求到来时,就可以直接从缓存中将结果直接发送给客户端。服务器缓存不是为了提供请求命中率,而是为了节省请求的逻辑业务处理,减轻Web服务器的负载。

**     **(3).代理缓存:是指在代理服务器实现缓存。当客户端的HTTP请求达到HTTP代理服务器时,它先判断本地有没有该请求的缓存,有的话直接将内容返回给客户端;否则,先与Web服务器建立连接发送请求,得到Web服务器的响应后,将响应内容保存在本地缓存中供以后使用,最后将响应内容回复给客户端。

**     **2.HTTPS代理服务器(HTTPS Proxy Server):也称为SSL代理,工作方式与HTTP代理类似,但不同之处在于它建立了安全连接。HTTPS代理对所有使用HTTPS协议的网络流量进行加密。

**     **3.SOCKS代理服务器(SOCKS Proxy Server):全能代理,它只是简单地将一端的系统连接到另外一端,支持多种协议,包括HTTP、FTP等。它只是简单地传递数据包,而不必关心是何种应用协议。

**     **注:以上内容主要来自于网络整理。

**     **以下为调用libcurl接口的测试代码:

namespace {

// reference: https://stackoverflow.com/questions/2329571/c-libcurl-get-output-into-a-string
struct String {
	char* ptr;
	size_t len;
};

void init_string(struct String* s)
{
	s->len = 0;
	s->ptr = (char*)malloc(s->len + 1);
	if (s->ptr == nullptr) {
		fprintf(stderr, "failed to malloc\n");
		exit(EXIT_FAILURE);
	}
	s->ptr[0] = '\0';
}

size_t write_func(void* ptr, size_t size, size_t nmemb, struct String* s)
{
	size_t new_len = s->len + size*nmemb;
	s->ptr = (char*)realloc(s->ptr, new_len + 1);
	if (s->ptr == nullptr) {
		fprintf(stderr, "failed to realloc\n");
		exit(EXIT_FAILURE);
	}
	memcpy(s->ptr + s->len, ptr, size*nmemb);
	s->ptr[new_len] = '\0';
	s->len = new_len;

	return size*nmemb;
}

} // namespace

int test_curl_proxy_http()
{
	CURL* curl = curl_easy_init(); // 开始一个libcurl简单会话
	if (curl) {
		struct String s;
		init_string(&s);

		// 存放服务器响应内容
		CHECK(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_func) == CURLE_OK);
		CHECK(curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s) == CURLE_OK);

		CHECK(curl_easy_setopt(curl, CURLOPT_URL, "https://license.xxxx.com/api/v2/health") == CURLE_OK); // 服务器地址
		CHECK(curl_easy_setopt(curl, CURLOPT_PROXY, "https://licenseproxytest.xxxx.com:9999") == CURLE_OK); // 代理服务器地址:端口
		CHECK(curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L) == CURLE_OK); // 使用HTTP管道方式
		CHECK(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) == CURLE_OK); // 输出较详细信息
		CHECK(curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10) == CURLE_OK); // 设置超时时间10秒
		//CHECK(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L) == CURLE_OK); // 不验证证书
#if _MSC_VER
		// windows找不到证书,需要显示指定否则调用curl_easy_perform会返回60;只有CURLOPT_SSL_VERIFYPEER设为true时此句才会生效
		// 在Linux下会默认查找证书位置:/etc/ssl/certs/
		CHECK(curl_easy_setopt(curl, CURLOPT_CAINFO, "../../../testdata/ca-bundle.crt") == CURLE_OK); // 带有服务器端公钥的证书
#endif
		//CHECK(curl_easy_setopt(curl, CURLOPT_SSLCERT, ".pem") == CURLE_OK); // 客户端证书
		//CHECK(curl_easy_setopt(curl, CURLOPT_SSLKEY, ".pem") == CURLE_OK); // 客户端私钥

		struct curl_slist* headers = nullptr;
		headers = curl_slist_append(headers, "Proxy-Connection: Keep-Alive"); // 将字符串附加到链表
		CHECK(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers) == CURLE_OK); // header链表

		CURLcode curl_code = curl_easy_perform(curl); // 以阻塞方式执行整个请求,并在完成时返回,如果失败则更早返回
		if (curl_code != CURLE_OK) {
			fprintf(stderr, "failed to curl_easy_perform: %d\n", curl_code);
			return -1;
		}

		long value = 0;
		curl_code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &value); // 提取信息
		if (curl_code != CURLE_OK) {
			fprintf(stderr, "failed to curl_easy_getinfo: %d\n", curl_code);
			return -1;
		}

		fprintf(stdout, "response: %s\n", s.ptr); // json格式
		free(s.ptr);

		curl_easy_cleanup(curl); // 结束libcurl会话
		return 0;
	}

	return -1;
}

**     **执行结果如下:

**      GitHub**:zhuhttps://github.com/fengbingchun/OpenSSL_Test

阅读世界,共赴山海

423全民读书节,邀你共读

相关文章

微信公众号

最新文章

更多