第四章 TCP IP通信案例:访问Internet上的Web服务器 - Huoke/Linux-net-Programma GitHub Wiki

本章我们分析一个完整的TCP/IP通信的实例————访问Internet上的Web服务器,通过该实例把这些知识串联起来。选择使用Web服务器展开讨论的理由是:

  • Internet上的Web服务器随处都可以获得,我们通过浏览器访问任何一个网站都是在与Web服务器通信。
  • 本书后续章节将编写简单的Web服务器程序,因此先学习其工作原理是有好处的。 Web客户端和服务器之间使用HTTP协议通信。HTTP协议的内容相当广泛,涵盖了网络应用层协议需要考虑的诸多方面。因此,学习HTTP协议对应用层协议设计将大有裨益。

4.1 实例总图

我们按照如下方法来部署通信实例: 在Kongming20上运行wget客户端程序,在ernest-laptop上运行squid代理服务器程序。客户通过代理服务器的中转,获取Internet上的主机 www.baidu.com的首页文档index.html,如图4-1所示:

从上图可见。wget客户端程序和代理服务器之间,以及代理服务器与Web服务器之间都是使用HTTP协议通信的。HTTP协议是一种应用层协议,它默认使用的传输层协议是TCP协议。我们将在后续简单讨论HTTP协议。

为了将ernest-laptop设置为Kongming20的HTTP代理服务器,我们需要在Kongming20上设置环境变量http_proxy:

export http_proxy="ernest-laptop:3128" #在Kongming20上执行

其中,3128是squid服务器默认使用的端口号(可以通过lsof命令查看服务器程序监听的端口号)。设置好环境变量之后,Kongming20访问任何Internet上的Web服务器时,其HTTP请求都将首先发送至ernest-laptop的3128端口。

squid代理服务器接收到wget客户端的HTTP请求之后,将简单地修改这个请求,然后把它发送给最终的目标Web服务器。既然代理服务器访问的是Internet上的机器,可以预见它发送的IP数据报都将经过路由器的中转,这一点也体现在图4-1中了。

4.2 部署代理服务器

先简单介绍一下HTTP代理服务器的工作原理,以及如何部署squid代理服务器。

4.2.1 HTTP代理服务器的工作原理

在HTTP通信链上,客户端和目标服务器之间通常存在某些中转代理服务器,它们提供对目标资源的中转访问。一个HTTP请求可能被多个代理服务器转发,后面的服务器称为前面服务器的上游服务器。代理服务器按照其使用方式和作用,分为正向代理服务器、反向代理服务器和透明代理服务器。

  1. 正向代理服务器 正向代理服务器要求客户端自己设置代理服务器的地址。客户端的每次请求都将直接发送到代服务器,并由代理服务器来请求目标资源。比如处于防火墙内的局域网机器要访问Internet,或者要访问一下被屏蔽掉的国外网站,就需要使用正向代理服务器。
  2. 反向代理服务器 反向服务器代理则被设置在服务器端,因而客户无须进行任何设置。反向代理是指用代理服务器来接收Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从内部服务器上得到的结果返回给客户端。这种情况下,代理服务器对外就表现为一个真实的服务器。各大网站通常分区域设置了多个代理服务器,所以在不同的地方ping同一个域名可能得到不同的IP地址,因为这些IP地址实际上是代理服务器的IP地址。图4-2显示了正向代理服务器和反向代理服务器在HTTP通信链上的逻辑位置。

图4-2中,正向代理服务器和客户端主机处于同一个逻辑网络中。该逻辑网络可以是一个本地LAN,也可以是一个更大的网络。反向代理服务器和真正的Web服务器也位于同一个逻辑网络中,这通常由提供网站的公司来配置和管理。 3. 透明代理只能设置在网关上。用户访问Internet的数据报必然经过网关,如果在网关上设置代理,则代理对用户来说显然是透明的。透明代理可以看做正向代理的一种特殊情况。

代理服务器通常还提供缓存目标资源的功能(可选),这样用户下次访问同一资源时速度将很快。优秀的开源软件squid、varnish都是提供了缓存能力的代理服务器软件,其中squid支持所有代理方式,而varnish仅能用作反向代理。

4.2.2 部署squid代理服务器

现在我们在ernest-laptop上部署squid代理服务器。这个过程很简单,只需要修改squid服务器的配置文件/etc/squid3/squid.conf,在其中加入如下两行代码(需要root权限,且应该加在合适的位置,详情可参考其他类似条目的设置):

acl localnet src 192.168.1.0/24
http_access allow localnet

这两行代码的含义是:允许网络192.168.1.0上的所有机器通过该代理服务器来访问Web服务器。其中,“192.168.1.0/24”是CIDR(Classless Inter-Domain Routing, 无类域间路由)风格的IP地址表示方法:“/”前的部分指定网络的IP地址,“/”后的部分则指定子网掩码中 “1”的位数。对IPv4而言,上述表示等价于 “192.168.1.0/255.255.255.0”(IP地址/子网掩码)。

我们通过上面的两行代码简单地配置了squid的访问控制。但实际应用中,squid提供更多更安全的配置,比如用户验证等。

下面在ernest-laptop上执行如下命令,以重启squid服务器:

$ sudo service squid3 restart
*Restarting Squid HTTP Proxy 3.0 squid3     [OK]

service 是一个脚本程序(/usr/sbin/service), 它为/etc/init.d/目录下的众多服务器程序(httpd 、vsftp、 sshd、mysqld等)的启动(start)、停止(stop)、重启(restart)等动作提供一个统一的管理。现在,Linux程序员已经越来越偏向于使用service脚本来管理服务器程序了。

4.3 使用tcpdump抓取传输数据包