网络基础零碎知识点扫盲

1,780 阅读12分钟

1.公网地址和内网地址的区别?

1.1 形象比喻

用邮寄系统作比喻。有公网ip,相当于说你有一个详细的地址,你可以写信寄给别人,别人也可以用这个地址和你进行各种通讯。 无公网ip像是住在一个大院里,所有进出邮件都由收发传达室转交。如果是普通的邮件,可以放在传达室,传达室的大爷看到你了就会转交给你。但有一些场景,比如说大学录取通知书,邮局的快递员说:必须本人签收。传达室的大爷就说了:对不起,所有的邮件都要经过我中转。于是邮局的快递员只好把信带回去了,导致收件人收不到。 实际场景中,有一些通讯无法在透明代理机制下顺利进行,如家里的智能安全摄像头,如果采用代理模式,会有隐私泄露的风险,如果是公网IP,用户可以直接通过公网IP连接,不经过代理,避免隐私泄露。

1.2 公网和内网IP的区别

  • 访问权限

访问互联网需要公网 IP 作为身份的标识,而私网 IP 则用于局域网,在公网上是不能使用私网 IP 地址来实现互联网访问的。

  • 唯一性

外网 IP 是全世界唯一的 IP 地址,仅分配给一个网络设备。而内网 IP 是由路由器分配给每一部内部使用的 IP 地址。不同内网的 IP 可以一样。

  • 数量

外网 IP 有限,无法分配给所有人,遵循先到先得,内网 IP 数量很充沛。

  • 意义

公有地址 (Public address)由 INIC(Internet Network Information Center 因特网信息中心)负责。这些 IP 地址分配给注册并向 INIC 提出申请的组织机构。通过它直接访问因特网。私有地址(Private address)属于非注册地址,专门为组织机构内部使用。

1.3 内网如何让外部网络访问

  • 静态外网IP端口映射

原理很简单,每个用户都会有一个外网IP,这个IP可以在百度里输入ip直接查到

image.png

如果别人输入这个ip地址,它会连接到你的路由器的80端口(如果80端口没有被封,通常是路由器的设置页面).也就相当于家里的路由器充当了内网与外网的一个网关,静态外网端口映射可以理解为设置这个网关,让外网通过访问不同的端口来访问内网的服务。

通常主流路由器都有一个功能叫做端口映射,刚好可以满足这个需求.通常设置端口映射就是填一个包含规则名,端口,目标主机ip,目标端口的的表单,填好后激活就可以使用了。其中规则名是这条规则的唯一标识,端口就是路由器开放的端口,目标主机和目标端口则是要映射服务的主机和端口

规则名端口目标主机IP目标端口
demo2000192.168.1.20060000

要做端口映射还有一个条件就是目标主机必须是静态ip,设置静态ip的方法是

  • Win 系统

image.png

image.png

  • Linux系统

通过修改/etc/network/interfaces(以ubuntu为例)

     # 配置静态IP使用以下内容
     auto eth0                    # eth0为以太网卡名称,可以使用ifconfig查询
     iface eth0 inet static
         address 192.168.1.200    # IP地址
         netmask 255.255.255.0    # 子网掩码
         gateway 192.168.1.1

     # 配置动态IP使用以下内容
     auto eth0    
     iface eth0 inet dhcp 

这是最简单的一种实现内网让外网访问的方法,其它方式可用搜索引擎搜索内网穿透关键字自行查找。

2. 正向代理和反向代理

2.1 正向代理

正向代理面向的是用户,用户对外访问网络,都会先经过代理服务器,然后由代理服务器访问真实目标服务器。如科学上网、VPN

image.png

2.2 反向代理

反向代理面向的是网络(服务器),用户访问到代理服务器后,由代理分发到真实目标服务器,如 nginx 网关 通过代理服务器分发内容到服务器,避免直接访问服务器,用作堡垒机,另外一种用途就是配置负载均衡

image.png

  • 反向代理模拟
  • 需求:假设有两个服务,一个对外暴露,一个不对外暴露只能内部访问,对外暴露的端口是80,在内部访问的端口是9000,通过访问对外暴露的80服务来访问9000服务
  # 配置虚拟主机 192.168.1.101
        server {
        listen     9000;
        server_name  127.0.0.1;
        location / {
            allow  127.0.0.1;
            deny   all;
            root   html;
            index  index.html index.htm;
        }
    } 
     
    #配置对外暴露的反向代理 本机地址是192.168.1.10
    server {
    listen       80;
    location /{
        proxy_pass http://127.0.0.1:9000;
    }
}

用192.168.1.101:9000直接访问虚拟主机

image.png

用127.0.0.1访问虚拟主机 image.png

2.3 两个特殊的端口

搭建网站通常有两种协议http和https,外网访问一般使用80端口和443端口。当然也不是绝对的,如果本地网站协议用的是Http,则使用80访问浏览器可以不带端口号(浏览器自动默认http访问时不带端口就是走80);如果本地网站用https协议的,则可以使用443端口访问时,浏览器不用带上端口号(浏览器自动默认https访问时不带端口就是走443)

3 使用Nginx在web应用中获取用户IP原理

在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆判断,或者统计ip访问次数等,通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我们使用了nginx作为反向代理后,使用request.getRemoteAddr()获取到的就一直是nginx服务器的ip的地址,那这时应该怎么办?

3.1 只有一个代理服务时

经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址。如果我们想要在web端获得用户的真实ip,就必须在nginx这里作一个赋值操作,如下:

proxy_set_header    X-real-ip   $remote_addr;

这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:request.getAttribute("X-real-ip")

3.2 途经多个代理服务时

当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖,不过仍有办法,获取客户真实的ip地址,通过设置X-Forwarded-For

proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

$proxy_add_x_forwarded_for变量包含客户端请求头中的 X-Forwarded-For 与 $remote_addr两部分,它们之间用逗号分开。

举个例子,有一个web应用www.xxx.com, 通过了两次nginx转发,即用户访问www.xxx.com 站点通过两台 nginx。

 在第一台 nginx 中:设置

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的proxy_add_x_forwarded_for变量的X-Forwarded-For部分是空的,所以只有remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

到了第二台nginx,设置:

 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”,以此类推,如果到了第三台nginx,设置了

 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

X-Forwarded-For的值就会变成成了“用户的真实ip,第一台nginx的ip,第二台nginx的ip”, 取 X-Forwarded-For字符串第一个逗号之前的值,就是用户的真实ip.

4 TCP三次握手和4次挥手

TCP比UDP传输数据安全可靠,这个可靠就是建立在三次握手和四次挥手上。 要诠释三次握手和四次挥手,就要引入几个概念:

  • seq:全称sequence,表示当前发送数据报文分段序号,数据报文比较大的时候,传输时会进行分段。一个TCP报文段的最大长度为65495字节
  • ack:表示期望下次收到的数据报文序号
  • 标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等。具体含义如下:
名称含义
SYN发起一个新连接。
ACK确认序号有效
FIN释放一个连接
RST重置连接。
PSH接收方应该尽快将这个报文交给应用层
URG紧急指针(urgent pointer)有效。

4.1 三次握手

在传输数据前,两台主机需要通过三次会话建立连接,这个过程我们称为三次握手。三次握手主要为了确认客户端和服务端收发数据都没问题。

第一次握手:客户端向服务端请求建立连接,

  • SYN=1(客户端发起一个新连接),
  • seq=x(序列号),

客户端进入SYN_SENT状态。这一步什么也证明不了。

第二次握手:服务端向客户端返回确认并请求建立连接,

  • SYN=1(服务端发起一个新连接),
  • ACK=1 (服务器端回复已收到),
  • ack=x+1(服务端期望下次收到客户端报文的消息序号)
  • seq=y(服务端的发送消息序列号)

服务端进入SYN_RCVD状态。这一步通信正常,说明客户端发送数据没问题,服务端接收数据也没问题。

第三次握手:客户端向服务端发送确认报文,

  • ACK=1 (客户端回复已收到),
  • ack=y+1(客户端期望下次收到服务端的报文序列号),
  • seq=x+1(客户端本次发送消息的序列号),

这一步通信正常,说明服务端发送数据没问题,客户端接收数据也没问题。 三次握手完成以后,2个主机之间,就可以传输数据啦~

状态变化:

  1. 客户端和服务器刚开始都处于CLOSED状态
  2. 客户端发起请求,客户端打开发送SYN_SENT状态,同时服务器打开监听LISTEN状态;
  3. 服务器在接收到客户端的请求时,服务器切换为回复SYN_RECVD状态;
  4. 客户端在接收到服务器的响应时,客户端切换为稳定连接ESTABLISHED状态的同时发送第二次数据包。
  5. 服务器在接收到客户端的第二次数据时,服务器切换为稳定连接ESTABLISHED状态。
  6. 双方建立稳定连接后,开始正常通信数据。

image.png

4.2 四次挥手

当我们的应用程序不需要数据通信了,就会发起断开 TCP 连接。终止一个TCP连接需要经过四次挥手。 流程是客户端告诉服务器,我要断开连接了。服务器端回复,收到断开消息。可能服务器还会再向客户端发送消息,消息发送完之后,告诉客户端,可以断开连接了。客户端收到服务端断开消息后进行回复。服务器收到回复后会断开连接,客户端经过2*MSL(Maximum Segment Lifetime,最大段生命周期)后,也会断开连接。

image.png

第一次挥手。客户端发起 FIN 包(FIN = 1),客户端进入 FIN_WAIT_1 状态。

  • FIN=1(客户端发起一个关闭连接),
  • seq=u(序列号)

第二次挥手。服务器端收到 FIN 包,发出确认包 ACK(ack = u + 1),并带上自己的序号 seq=v,服务器端进入了 CLOSE_WAIT 状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的 ACK 后,进入了 FIN_WAIT_2 状态。

  • ACK=1(客户端信息已收到),
  • seq=v(服务端回复收到客户端断开连接报文序列号)
  • ack=u+1

第三次挥手。服务器端数据发送完毕后,向客户端发送 FIN 包(seq=w ack=u+1),半连接状态下服务器可能又发送了一些数据,假设发送 seq 为 w。服务器此时进入了 LAST_ACK 状态。

  • FIN=1(服务端发起一个关闭连接),
  • seq=w(半连接状态序列号)
  • ack=u+1

第四次挥手。客户端收到服务器的 FIN 包后,发出确认包(ACK=1,ack=w+1),此时客户端就进入了 TIME_WAIT 状态。注意此时 TCP 连接还没有释放,必须经过 2*MSL 后,才进入 CLOSED 状态。而服务器端收到客户端的确认包 ACK 后就进入了 CLOSED 状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。

  • ACK=1(客户端收到回复信息),
  • seq=u+1(客户端报文序列号),
  • ack=w+1

5 什么是ARP欺骗?

ARP 欺骗是一种以 ARP 地址解析协议为基础的一种网络攻击方式, 什么是 ARP 地址解析协议: 一台电脑主机要把以太网数据帧发送到同一局域网的另外一台主机, 它的底层是通过 Mac 地址来确定目的主机, 但是我们在应用层是使用 IP 地址来访问目标主机的, 所以 ARP 的作用就是当一台主机访问一个目标 IP 地址的时候, 它为该主机返回目标 IP 主机的 Mac 地址.

ARP欺骗的分类

  1. 主机欺骗,主机B欺骗局域网中的主机A。
  2. 网关欺骗,局域网中的主机欺骗网关,获取其它主机的进入流量。

ARP欺骗的危害

  1. 造成局域网中的其它主机断网。
  2. 劫持局域网中其它主机或网关的流量,获取敏感信息等。

ARP欺骗举例

Ubuntu下可以直接使用如下命令安装arpspoof :

apt install dsniff

安装好之后先打开IP转发开关:

echo 1 > /proc/sys/net/ipv4/ip_forward

然后使用 arpspoof 命令进行欺骗, 命令使用方法如下:

arpspoof -i <网卡名> -t <欺骗的目标> <我是谁>

加入局域网中的网关地址是192.168.0.1,主机A地址是192.168.0.10, 分别开两个终端:

终端1, 欺骗主机A我是网关

arpspoof -i eth0 -t 192.168.0.10 192.168.0.1

终端2, 欺骗网关我是主机A

arpspoof -i eth0 -t 192.168.0.1 192.168.0.10

欺骗成功之后可以通过抓包工具查看主机 A 所有的流量.

6. 网络协议

image.png

有些资料会把应用层、表示层、会话层合并起来简单表示为“应用层”,变成五层协议。

这五层协议的分工,看到过一个形象的总结: 买东西时候要封装打包(应用层)
打包后要在包裹上贴快递单(传输层)
在快递单上要写源地址目的地址(网络层)
让快递小哥来取件(数据链路层)
快递小哥骑车送件到收货人(物理层)

参考文章