Linux网络:代理 & 穿透 & 打洞


代理

正向代理

正向代理是一种常见的网络代理方式,它位于客户端与目标服务器之间,代表客户端向服务器发送请求,接收响应。

在这里插入图片描述

如图,客户端发送的所有请求,都交给正向代理服务器,由代理服务器转发数据给服务端。当服务端返回响应时,先把响应发给正向代理服务器,正向代理服务器再把这个响应转发给客户端。

基于这种代理方式,可以实现很多功能:

  1. 隐藏客户信息:这种方式下,服务端全程只与代理服务器交互,无法得知用户的IP地址等信息
  2. 缓存加速:正向代理服务器中,可以缓存一些经常访问的资源,当客户端请求资源时,如果已经在缓存中存在,那么不会去访问服务器,而是直接返回。这样既可以加速客户端的响应时间,还可以减轻服务端的压力
  3. 访问控制:正向代理服务器可以限制用户的访问内容,比如禁止某些网址的访问,如果检测到用户访问不允许的内容,直接拒绝

反向代理

反向代理也位于客户端与服务器之间,但是客户端需要通过互连网访问代理服务器,而不再由代理服务器去访问互连网。

在这里插入图片描述

可以看出,相比于正向代理,其实交换了互连网和代理服务器的顺序,就得到了反向代理。

反向代理一般由服务端配置,当客户端请求数据时,发送请求到互连网,再访问到反向代理服务器,由服务器把请求转发给后端。

反向代理也可以实现很多功能:

  1. 负载均衡:当处于一个分布式系统中,反向代理服务器可以把请求均匀的分配到不同的服务器上,实现负载均衡
  2. 安全保护:反向代理模式下,客户端与反向代理交互,无法得知具体的后端信息,可以保护后端,除此之外,在反向代理服务器上,还可以配置防火墙、访问控制列表等功能
  3. 缓存加速:这个和正向代理相似,可以把频繁访问的数据放到反向代理服务器上,如果访问到缓存内部的数据,直接返回,不再经过后端
  4. 动静分离:用户请求的数据,分为动态数据和静态数据,动态数据需要经过后端计算,而静态数据是固定的,对于这样的静态数据,就可以配置到反向代理服务器上,不再经过后端返回,而是代理服务器直接返回

内网穿透

内网穿透也称为NAT穿透,它允许位于内网的设备能够被公网上的设备所访问。简单来说,就是实现内外网之间的互联互通。

在这里插入图片描述

如图所示,现有三台主机,其中公网服务器具有公网IP,可以直接访问互连网。而客户端与服务端都处于内网环境,需要通过路由转发,将数据转发到公网。

那么要如何实现客户端与服务端之间的通信?

如果不考虑公网服务器的存在,只有两个处于内网的主机,那么可以使用NATP技术,让服务端获取一个公网地址以及具体端口。这样客户端就可以访问到内网的服务端了,但是这样有一个缺陷,那就是必须由服务端先发起通信,这样的话就不能算作一个服务器了。

如果有了公网服务器,就可以使用内网穿透的解决方案。

在这里插入图片描述

流程如下:

  1. 服务端提供一个端口6666,用于与公网服务器进行通信
  2. 服务端通过NAT建立映射关系,随后就可以通过该端口和公网服务器通信
  3. 公网服务器再提供另一个端口8888,这个端口用于接收来自互连网的请求
  4. 公网服务器接收到所有来自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 代理暴露给外网。以下是每个配置项的详细解释:

  1. serverAddrfrps 服务端的IP地址或域名
  2. serverPortfrps 服务端监听的端口
  3. name:代理规则的名称
  4. type:代理的类型,如 tcpudphttphttps
  5. localIPfrpc 客户端上要暴露的服务的IP地址
  6. localPortfrpc 客户端上要暴露的服务的端口
  7. remotePortfrps 服务器上用于接收流量的端口

配置为如下规则:

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 Green

    while ($true) {
        $client = $listener.AcceptTcpClient()
        Write-Host "有客户端连接进来!" -ForegroundColor Yellow

        $clientIP = $client.Client.RemoteEndPoint.Address.ToString()
        $clientPort = $client.Client.RemoteEndPoint.Port
        Write-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的防火墙。

  • 测试内网穿透:

目前我们完成了三件事:

  1. Linux服务端启动frps服务
  2. Windows客户端启动frpc
  3. Windows6666端口开启了一个tcp进程

接下来访问Linux8888端口,这一步可以在任何地方执行,通过telnet连接:

在这里插入图片描述

连接成功后,发送”你好世界“,此时收到来自客户端的响应“你好,客户端!你发送了:你好世界”,这说明Windows的脚本开始工作了。

power shell接口也可以看到:

在这里插入图片描述

这个过程中最重要是,客户端访问的是Linux8888端口,最后访问到的却是处于内网的Windows6666端口的服务,这就是内网穿透。


内网打洞

内网打洞是一种网络技术,它允许两个位于不同内网中的主机在没有公网IP的情况下,通过互联网直接建立连接。

内网打洞依赖于NAT,通过在内网和外网之间建立一个虚拟通道,使得内网主机能够通过这个通道与外网进行通信。

一个内网的主机,想要访问互连网可以通过NAT,但是NAT最大的问题就是只能由内网的主机发起第一个数据包

假设现在有两台内网的主机之间要通信:

在这里插入图片描述

A想和B通信,就要知道B的地址和端口,同理,B也要知道A的地址和端口。这就导致AB第一个报文不知道要发往哪一个地址,虽然它们都能通过NAT连到互连网,却不能进行点对点通信。

为了解决这个问题,需要一个具有公网地址的中介服务器:

在这里插入图片描述

两者之间进行点对点通信的困境,在于不知道第一个报文发到哪里,无法得知互相的地址和端口,导致无法进行下一步通信。

为此,一个具有公网地址的服务器出来做媒介,AB的第一个报文都发送给公网服务器,报文内部携带了自己经过NAT转化后的IP + Port,随后公网服务器把这两个报文分别转发给对方:

在这里插入图片描述

当两者知道对方的地址与端口号后,那么就可以直接通过互连网通信了,不再需要公网服务器了,也就是说不再走灰色的部分进行通信,而是直接通过互连网进行点对点通信。

这个过程叫做内网打洞,处于内网的两个主机,借用临时的公网服务器交换对方的IP + Port,得知对方所处的位置,随后好像在网络中打了一个隧道,可以让两个内网的主机点对点通信。


代码是工作之余写的,代码分为转发服务器和代理服务器 先说转发服务器 转发服务器其实也可以说成是重定向服务器,比如转发服务器监听80端口,如果有浏览器用户访问服务器IP(浏览器默认请求80端口),转发服务器接收到浏览器用户的请求后,便把浏览器用户的请求重定向到本机的其它端口或者处于同一网段其它机器的指定端口 再说一下代理服务器 先说明一下,我这个代理服务器只能代理指定的网站或其它可以代理的客户,比如建在内网的SVN服务或者有些地方不能访问的外网网站。 代理服务器分为服务器端和客户端,服务器端需要运行在客户端和大家都能访问的外网上,客户端需要放在能访问到需要代理的客户的网络上,也可以放在客户的本机上。 用法: 解压proxy.tar.gz 进入proxy目录,然后make,会生成三个我们需要的程序,transmit(转发服务器)、manager(代理服务器端)、client(代理客户端) 服务器端用法: ./transmit [端口](比如80) ./manager [端口](随便指定) 客户端用法: ./client -i [代理服务器IP]:[端口] -t [客户IP]:[端口] -d [客户域名] 举例: 假如我的外网服务器IP为1.2.3.4,代理的客户为网易(网易域名:www.163.com,IP:202.108.9.33) 服务器端如下运行 ./transmit 80 ./mananger 8000 客户端如下运行 ./client -i 1.2.3.4:8000 -t 202.108.9.33 -d www.163.com 或 ./client -i 1.2.3.4:8000 -t 202.108.9.33:80 -d www.163.com 然后在本机hosts文件(windows是c:windowssystem32driversetchosts linux是/etc/hosts)填加如下一行 1.2.3.4 www.163.com 这时在浏览器里敲www.163.com就可以通过代理服务器访问网易了 当然如果客户是自己申请域名,就可以直接把自己的域名指向1.2.3.4,而不用修改本机hosts文件了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盒马盒马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值