Linux网络:代理 & 穿透
- 代理
- 正向代理
- 反向代理
- 内网穿透
- frp
- 内网打洞
代理
正向代理
正向代理是一种常见的网络代理方式,它位于客户端与目标服务器之间,代表客户端向服务器发送请求,接收响应。
如图,客户端发送的所有请求,都交给正向代理服务器,由代理服务器转发数据给服务端。当服务端返回响应时,先把响应发给正向代理服务器,正向代理服务器再把这个响应转发给客户端。
基于这种代理方式,可以实现很多功能:
隐藏客户信息
:这种方式下,服务端全程只与代理服务器交互,无法得知用户的IP
地址等信息缓存加速
:正向代理服务器中,可以缓存一些经常访问的资源,当客户端请求资源时,如果已经在缓存中存在,那么不会去访问服务器,而是直接返回。这样既可以加速客户端的响应时间,还可以减轻服务端的压力访问控制
:正向代理服务器可以限制用户的访问内容,比如禁止某些网址的访问,如果检测到用户访问不允许的内容,直接拒绝
反向代理
反向代理也位于客户端与服务器之间,但是客户端需要通过互连网访问代理服务器,而不再由代理服务器去访问互连网。
可以看出,相比于正向代理,其实交换了互连网和代理服务器的顺序,就得到了反向代理。
反向代理一般由服务端配置,当客户端请求数据时,发送请求到互连网,再访问到反向代理服务器,由服务器把请求转发给后端。
反向代理也可以实现很多功能:
负载均衡
:当处于一个分布式系统中,反向代理服务器可以把请求均匀的分配到不同的服务器上,实现负载均衡安全保护
:反向代理模式下,客户端与反向代理交互,无法得知具体的后端信息,可以保护后端,除此之外,在反向代理服务器上,还可以配置防火墙、访问控制列表等功能缓存加速
:这个和正向代理相似,可以把频繁访问的数据放到反向代理服务器上,如果访问到缓存内部的数据,直接返回,不再经过后端动静分离
:用户请求的数据,分为动态数据和静态数据,动态数据需要经过后端计算,而静态数据是固定的,对于这样的静态数据,就可以配置到反向代理服务器上,不再经过后端返回,而是代理服务器直接返回
内网穿透
内网穿透也称为NAT穿透,它允许位于内网的设备能够被公网上的设备所访问。简单来说,就是实现内外网之间的互联互通。
如图所示,现有三台主机,其中公网服务器具有公网IP
,可以直接访问互连网。而客户端与服务端都处于内网环境,需要通过路由转发,将数据转发到公网。
那么要如何实现客户端与服务端之间的通信?
如果不考虑公网服务器的存在,只有两个处于内网的主机,那么可以使用NATP
技术,让服务端获取一个公网地址以及具体端口。这样客户端就可以访问到内网的服务端了,但是这样有一个缺陷,那就是必须由服务端先发起通信,这样的话就不能算作一个服务器了。
如果有了公网服务器,就可以使用内网穿透
的解决方案。
流程如下:
- 服务端提供一个端口
6666
,用于与公网服务器进行通信 - 服务端通过
NAT
建立映射关系,随后就可以通过该端口和公网服务器通信 - 公网服务器再提供另一个端口
8888
,这个端口用于接收来自互连网的请求 - 公网服务器接收到所有来自
8888
端口的请求,都转发给内网的6666
,这样就实现了内网穿透
后续任何客户端,只需要访问公网服务器的8888
端口,就可以间接访问到内网的主机,进而实现把内网的主机暴露到公网上。
frp
frp
(Fast Reverse Proxy)是一款高性能的反向代理应用,主要用于内网穿透。它由两个部分组成:frps
(服务端)和 frpc
(客户端)。frp 允许将内网服务暴露给公网,使得在不同地点的客户端可以通过公网访问内网的服务,即便这些服务原本只能在局域网内访问。
下载地址:
https://github.com/fatedier/frp/releases/tag/v0.58.1
接下来基于frp
这个工具,完成内网穿透的测试,你需要准备:
一台Windows
主机,一台Linux
云服务器,注意一定要有一台有公网地址的云服务器,本地的虚拟机不行。
云服务器下载Linux
版本的frp
,一般是frp_0.58.1_linux_amd64.tar.gz
,解压后得到如下内容:
其中frps
是服务端,frps.toml
是服务端的配置文件。
Windows
下载frp_0.58.1_windows_amd64.zip
,解压后得到如下内容:
和刚才一样,但是Windows
处于内网环境,此处使用客户端frpc.exe
,相应的配置文件是frpc.toml
。
- 配置
Linux
服务端:
在frps.toml
中,配置服务端使用的端口:
此处bindPort=7000
是默认值,我们就使用默认值。这个端口用于和客户端进行通信。
随后运行服务端程序./frps -c ./frps.toml
:
此处的-c
用于指定配置文件,看到frps started successfully
,那么一个frp
服务端就启动成功了。此处注意要开放云服务的7000
端口,一般在服务器的供应商的安全组中可以进行配置。
Windows
客户端配置:
客户端的配置文件是frpc.toml
,初始值如下:
serverAddr = "127.0.0.1"
serverPort = 7000[[proxies]]
name = "test-tcp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
简单介绍一下配置项:
这段配置是用于 frp
(Fast Reverse Proxy)的客户端配置文件 frpc.toml
的一个示例。它定义了如何将内网服务通过 frp
代理暴露给外网。以下是每个配置项的详细解释:
serverAddr
:frps
服务端的IP地址或域名serverPort
:frps
服务端监听的端口name
:代理规则的名称type
:代理的类型,如tcp
、udp
、http
、https
等localIP
:frpc
客户端上要暴露的服务的IP地址localPort
:frpc
客户端上要暴露的服务的端口remotePort
:frps
服务器上用于接收流量的端口
配置为如下规则:
serverAddr = "8.141.8.176"
serverPort = 7000[[proxies]]
name = "test-tcp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 6666
remotePort = 8888
此处8.141.8.176
是服务器的公网地址,服务端监听了7000
端口与客户端通信,此处也要填入7000
。
随后本地暴露6666
地址,服务端使用8888
端口接收数据。
经过以上配置,Linux
服务端就会把8.141.8.176:8888
的数据,转发给Windows
主机的6666
端口。
Windows
客户端启动服务:
此处-c
也是在指定配置文件。当看到start proxy success
说明服务启动成功了。
但是到目前为止,Windows
主机还没有在6666
端口开启一个tcp
的服务,为此可以运行一下脚本:
$port = 6666$listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Any, $port)try {$listener.Start()Write-Host "TCP 监听器已启动,正在监听端口 $port ..." -ForegroundColor Greenwhile ($true) {$client = $listener.AcceptTcpClient()Write-Host "有客户端连接进来!" -ForegroundColor Yellow$clientIP = $client.Client.RemoteEndPoint.Address.ToString()$clientPort = $client.Client.RemoteEndPoint.PortWrite-Host "客户端 IP: $clientIP, 端口: $clientPort" -ForegroundColor Cyan$stream = $client.GetStream()$reader = New-Object System.IO.StreamReader($stream)$writer = New-Object System.IO.StreamWriter($stream)$writer.AutoFlush = $true$message = $reader.ReadLine()Write-Host "收到客户端消息: $message" -ForegroundColor White$response = "你好,客户端!你发送了: $message"$writer.WriteLine($response)Write-Host "已发送回复给客户端。" -ForegroundColor Green$client.Close()Write-Host "客户端连接已关闭。" -ForegroundColor Red}
} catch {Write-Host "发生错误: $_" -ForegroundColor Red
} finally {$listener.Stop()Write-Host "TCP 监听器已停止。" -ForegroundColor Red
}
想要运行以上脚本很简单,直接粘贴到powershell
就可以了:
随后按下Enter
键,一个简单的tcp
服务就开启了,此处注意要关掉Windows
的防火墙。
- 测试内网穿透:
目前我们完成了三件事:
Linux
服务端启动frps
服务Windows
客户端启动frpc
Windows
在6666
端口开启了一个tcp
进程
接下来访问Linux
的8888
端口,这一步可以在任何地方执行,通过telnet
连接:
连接成功后,发送”你好世界“
,此时收到来自客户端的响应“你好,客户端!你发送了:你好世界”
,这说明Windows
的脚本开始工作了。
在power shell
接口也可以看到:
这个过程中最重要是,客户端访问的是Linux
的8888
端口,最后访问到的却是处于内网的Windows
的6666
端口的服务,这就是内网穿透。
内网打洞
内网打洞
是一种网络技术,它允许两个位于不同内网中的主机在没有公网IP的情况下,通过互联网直接建立连接。
内网打洞依赖于NAT
,通过在内网和外网之间建立一个虚拟通道,使得内网主机能够通过这个通道与外网进行通信。
一个内网的主机,想要访问互连网可以通过NAT
,但是NAT
最大的问题就是只能由内网的主机发起第一个数据包。
假设现在有两台内网的主机之间要通信:
A
想和B
通信,就要知道B
的地址和端口,同理,B
也要知道A
的地址和端口。这就导致A
和B
的第一个报文不知道要发往哪一个地址,虽然它们都能通过NAT
连到互连网,却不能进行点对点通信。
为了解决这个问题,需要一个具有公网地址的中介服务器:
两者之间进行点对点通信的困境,在于不知道第一个报文发到哪里,无法得知互相的地址和端口,导致无法进行下一步通信。
为此,一个具有公网地址的服务器出来做媒介,A
和B
的第一个报文都发送给公网服务器,报文内部携带了自己经过NAT
转化后的IP + Port
,随后公网服务器把这两个报文分别转发给对方:
当两者知道对方的地址与端口号后,那么就可以直接通过互连网通信了,不再需要公网服务器了,也就是说不再走灰色的部分进行通信,而是直接通过互连网进行点对点通信。
这个过程叫做内网打洞
,处于内网的两个主机,借用临时的公网服务器交换对方的IP + Port
,得知对方所处的位置,随后好像在网络中打了一个隧道,可以让两个内网的主机点对点通信。