网络代理
# # (opens new window)代理服务器
:Proxy Server ,用于代替一个主机与其它主机进行通信。
- 工作在会话层,代理应用层的消息。
- 按协议分类:
- SSH 代理
- FTP 代理
- HTTP 代理
- HTTPS 代理
- SOCKS 代理:全称为 SOCKetS ,工作在应用层与传输层之间,比 HTTP 代理更底层、更快。
- SOCKS4 只支持 TCP 连接,而 SOCKS5 还支持 UDP 连接、密码认证。
- FTP、HTTP、SOCKS 代理都是明文通信,而 SSH、HTTPS、shadowsocks 代理是加密通信。
- 按代理反向分类:
- 正向代理 :侧重于代替客户端,向服务器发出访问请求。
- 反向代理 :侧重于代替服务器,接收客户端的访问请求。
- 用途:
- 可以使客户端访问到某些代理服务器才能访问的网络,像 VPN 的功能。
- 可以担任防火墙,过滤客户端发送、接收的数据。
- 可以动态更改将客户端的流量转发到哪个服务器,比如实现负载均衡。
- 可以隔离服务器与客户端,使得服务器不知道客户端的真实 IP 、客户端不知道服务器的真实 IP 。
- 缺点:
- 客户端的通信数据都要经过代理服务器,可能被监听、篡改。
# # (opens new window)Squid
:一个代理服务器,采用 C++ 开发。
- 官网(opens new window) (opens new window)
- 支持 FTP、HTTP、HTTPS 代理协议。
- 常用作简单的 HTTP 正向代理服务器。
- 也可用于反向代理,缓存 HTTP 服务器的响应报文,但比 Nginx 的功能少。
# # (opens new window)部署
用 yum 安装:
yum install squid systemctl start squid systemctl enable squid
1
2
3或者用 docker-compose 部署:
version: '3' services: squid: container_name: squid image: sameersbn/squid:3.5.27-2 restart: unless-stopped ports: - 3128:3128 volumes: - ./conf:/etc/squid/
1
2
3
4
5
6
7
8
9
10
11
# # (opens new window)配置
用 yum 安装 Squid 时,开启正向代理的步骤:
编辑配置文件
/etc/squid/squid.conf
:http_port 3128 # 定义一个 acl 组,名为 local_ip ,指向源 IP 为 10.0.0.1/24 的流量 # acl local_ip src 10.0.0.1/24 # 定义一个 acl 组,用密码文件进行身份认证 auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd acl auth_user proxy_auth REQUIRED # 允许指定 acl 组的流量 # http_access allow local_ip http_access allow auth_user # 禁止剩下的所有流量 http_access deny all # 不缓存所有响应报文 cache deny all # 默认会在 HTTP 请求 Headers 中加入 X-Forwarded-For ,声明客户端的真实 IP 。这里删除该 Header forwarded_for delete # 记录访问日志 access_log /var/log/squid/access.log squid # 每隔 30 天翻转一次日志 logfile_rotate 30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25生成密码文件:
yum install httpd-tools htpasswd -cb /etc/squid/passwd leo ******
1
2测试使用该代理:
systemctl restart squid curl -x http://leo:******@127.0.0.1:3128 cip.cc
1
2
# # (opens new window)SOCKS5
用 docker-compose 部署一个 SOCKS5 服务器:
version: '3' services: socks5: container_name: socks5 image: serjs/go-socks5-proxy restart: unless-stopped environment: PROXY_USER: root PROXY_PASSWORD: ****** ports: - 1080:1080
1
2
3
4
5
6
7
8
9
10
11
12- 该镜像采用 Golang 开发,详见官方文档 (opens new window) (opens new window)。
# # (opens new window)Shadowsocks
:一种基于 SOCKS5 协议的代理协议,简称为 ss ,常用于实现 VPN 。
- 官方文档(opens new window) (opens new window)
- 支持设置密码、加密传输数据。
- 原理:
- 在一台主机上运行 ss 服务器。
- 在本机运行 ss 客户端,将本机的流量发送到 ss 服务器,被它代理转发。
- ShadowsocksR :简称为 SSR ,是 shadowsocks 的分叉项目。
# # (opens new window)Shadowsocks-libev
:一个 ss 代理服务器软件。
于 2015 年发布,采用 C 语言开发,于 2020 年停止更新。
支持 AEAD Cipher 加密算法。
支持 Obfs 混淆,可以将 ss 流量伪装成 http 流量。
用 Docker 部署服务器:
docker run -d --name shadowsocks \ --restart unless-stopped \ -p 8388:8388 \ shadowsocks/shadowsocks-libev:v3.3.5 \ ss-server -s 0.0.0.0 -k ****** -m aes-256-gcm
1
2
3
4
5服务器的命令:
ss-server # 启动服务器 -c config.json # 使用指定的配置文件 -s 0.0.0.0 # 设置服务器监听的 IP -p 8388 # 设置服务器监听的端口 -k ****** # 设置服务器的认证密码 -m aes-256-gcm # 设置服务器的加密方式 -v # 显示详细日志
1
2
3
4
5
6
7
# # (opens new window)Shadowsocks-rust
:一个 ss 代理服务器软件。
用 Docker 部署服务器:
docker run -d --name ssserver-rust \ --restart unless-stopped \ -p 8388:8388 \ -v /root/shadowsocks-rust/config.json:/etc/shadowsocks-rust/config.json \ ghcr.io/shadowsocks/ssserver-rust:v1.14.3
1
2
3
4
5配置文件示例:
{ "server": "0.0.0.0", "server_port": 8388, "password": "******", "method": "chacha20-ietf-poly1305", "fast_open": false }
1
2
3
4
5
6
7
# # (opens new window)客户端
Windows 版 ss 客户端 (opens new window) (opens new window):
- 运行 ss 客户端之后,它会连接到 ss 服务器,同时在本机监听一个代理端口。
- 本机的进程可以通过 HTTP、Socket 代理协议,将数据发送到该代理端口,然后 ss 客户端会将这些数据转发到 ss 服务器,实现正向代理。
- 也可以开启 ss 客户端的全局模式,代理本机的所有流量。
Linux 版 ss 客户端 :
它是一个命令行工具,功能较少,不能连接多个 ss 服务器,在本机提供的代理端口只支持 Socket 协议。
部署示例:
# 安装 pip3 install shadowsocks # 编辑配置文件 cat > ss.json <<EOF{ "server": "10.0.0.1", "server_port": 8388, "local_address": "127.0.0.1", "local_port": 8388, "password": "******", "timeout": 5, "method": "aes-256-cfb"}EOF # 启动客户端 sslocal -c ss.json -d start
1
2
3
4
5
6
7
8一个 sslocal 客户端只能连接一个 ss 服务器。
可以再运行代理服务器 privoxy ,监听一个 HTTP 代理端口,将该端口的流量转发到 Socket 代理端口。
# 安装 yum install -y privoxy systemctl start privoxy systemctl enable privoxy # 编辑配置文件 sed '/listen-address 127.0.0.1:8118/d' /etc/privoxy/config -i cat >> /etc/privoxy/config <<EOFlisten-address 0.0.0.0:8118# 将 HTTP 请求转发到该代理forward-socks5 / 127.0.0.1:8388 .# 第一个字段为 url_pattern ,取值为 / 则匹配所有 HTTP 请求# 第二、三个字段为代理、父级代理,取值为 . 则表示忽略# 不代理这些 HTTP 请求forward 10.*.*.*/ .forward 127.*.*.*/ .forward 172.16.*.*/ .forward 192.168.*.*/ .EOF # 重启 systemctl restart privoxy
1
2
3
4
5
6
7
8
9
10
11试用该代理:
curl -x 127.0.0.1:8118 google.com
1
# # (opens new window)V2Ray
:一个代理服务器,比 ss 的功能更多。
于 2019 年发布,采用 Goalng 语言开发。是 Project V 社区研发的主要软件,后来改名为 v2fly 。
V2Ray 服务器的流量分为两个方向:
- inbounds :入站流量,即客户端发送到 V2Ray 的流量。
- 客户端可使用 V2Ray 原创的 VMess 代理协议,也兼容 HTTP、Shadowsocks 等代理协议。
- outbounds :出站流量,即 V2Ray 将客户端的流量转发到某个网站。
- inbounds :入站流量,即客户端发送到 V2Ray 的流量。
用 Docker 部署服务器:
docker run -d --name v2fly \ --restart unless-stopped \ -v /root/v2fly/config.json:/etc/v2fly/config.json \ -p 80:80 \ v2fly/v2fly-core:v5.1.0 \ run -c /etc/v2fly/config.json
1
2
3
4
5
6配置文件示例:
{ "inbounds": [{ "port": 80, "protocol": "vmess", "settings": { // 只允许这些 id 的客户端连接 "clients": [{ "id": "******" }] } }], "outbounds": [{ "protocol": "freedom", "settings": {} }] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14在 Windows 上常用的客户端软件是 v2rayN (opens new window) (opens new window)。
# # (opens new window)Trojan
:一个代理服务器。能加密通信,并伪装成互联网常见的 HTTPS 流量。
- 于 2019 年发布,采用 C++ 语言开发。
# # (opens new window)代理客户端
- 有的程序不支持使用代理,有的程序只支持使用 HTTP 等简单的代理协议。因此建议安装一个专用的代理客户端,通过两种方式代理其它程序的流量:
- 透明代理(Transparent proxy):
- 拦截其它程序发出的流量,转发到代理服务器。其它程序不会感知到代理,不需要主动使用代理。
- 转换代理协议:
- 通过某种代理协议连接到代理服务器,再在本机监听一个采用 HTTP 等简单代理协议的端口,将该端口收到的流量转发到代理服务器。
- 此时,具有代理功能的程序,一般都能通过该端口使用代理。但没有代理功能的程序,依然不能使用代理。
- 透明代理(Transparent proxy):
# # (opens new window)Proxifier
:一个 GUI 工具,用作代理客户端,收费。
- 特点:
- 支持 Windows、MacOS 系统,不支持 Linux 。
- 支持 HTTP、HTTPS、SOCKS4、SOCKS5 代理协议。
- 支持透明代理。原理如下:
- Windows 系统上,一般程序需要调用 Winsock API 进行 Socket 通信。
- Winsock 提供了 LSP(Layered Service Provider) 功能:允许程序自定义一个 LSP DLL 库,在一般程序调用 Winsock API 时被加载,从而可以劫持其流量。
- 支持灵活的代理规则:将某个程序发向某 IP:Port 的 TCP 包,转发到某个代理服务器。支持通配符。
- 支持用多个代理服务器组成代理链。
- 用法:
- 安装 Proxifier 并启动。
- 添加代理服务器。
- 添加代理规则。
- 保持 Proxifier 运行,即可代理本机程序的流量。
# # (opens new window)ProxyChains
:一个 Unix 系统的命令行工具,采用 C 语言开发,用作代理客户端。
- GitHub(opens new window) (opens new window)
- 支持透明代理。原理如下:
- 声明环境变量 LD_PRELOAD ,让程序在导入 DLL 库时,优先导入 libproxychains4.so 库。
- 在 libproxychains4.so 库中,重写关于 Socket 通信的函数,将程序发出的 TCP 流量转发到代理服务器。
- 缺点:
- 只能代理 TCP 流量,不支持 UDP、ICMP 。
- 只能代理指定的程序,不能代理系统所有进程。
- 只能代理采用动态链接库的程序。
- Chrome 浏览器在沙盒中运行网页,也不会被代理。
用法:
安装:
wget https://github.com/rofl0r/proxychains-ng/archive/refs/tags/v4.14.tar.gz tar -zxvf v4.14.tar.gz cd proxychains-ng-4.14 ./configure --prefix=/usr --sysconfdir=/etc make make install
1
2
3
4
5
6编辑配置文件 /etc/proxychains.conf ,示例:
quiet_mode # 安静模式,运行时不输出过程信息 dynamic_chain # 自动选用 ProxyList 中可用的代理,且按顺序 proxy_dns # 将 DNS 请求也代理 # 取消代理发向指定 IP 的数据包 localnet 127.0.0.0/255.0.0.0 localnet 10.0.0.0/255.0.0.0 localnet 172.16.0.0/255.240.0.0 localnet 192.168.0.0/255.255.0.0 # 发送数据包时,修改目标 IP:Port dnat 1.1.1.1:80 1.1.1.2:443 dnat 1.1.1.1:443 1.1.1.2 dnat 1.1.1.1 1.1.1.2 # 声明一组代理服务器,支持 HTTP、SOCKS4、SOCKS5 代理协议,支持设置账号密码 [ProxyList] http 127.0.0.1 3128 socks5 127.0.0.1 1080 root ******
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19执行命令:
proxychains4 curl cip.cc # 在代理下执行一条命令 proxychains4 bash # 创建一个 shell ,在其中执行的命令都采用代理
1
2
# # (opens new window)redsocks
:一个 Linux 系统的命令行工具,采用 C 语言开发,用作代理客户端。
- GitHub(opens new window) (opens new window)
- 支持透明代理。原理如下:
- redsocks 连接到代理服务器,并在本机监听一个端口,将该端口收到的流量转发到代理服务器。
- 用户手动配置 iptables 防火墙规则,将本机发出的 TCP 流量重定向到 redsocks 端口。
- 缺点:
- 需要手动配置 iptables 规则,比较麻烦。
- 有些程序可能无视 iptables 规则。
用法:
用 apt 安装:
apt install redsocks
1或者手动编译后安装:
git clone https://github.com/darkk/redsocks cd redsocks make cp redsocks /usr/bin/redsocks
1
2
3
4编辑配置文件 /etc/redsocks.conf ,示例:
base { log_debug = off; log_info = on; log = stderr; # 日志的保存位置,可改为 "file:/var/log/redsocks.log" 文件 daemon = on; redirector = iptables; } redsocks { // 在本机监听的端口 local_ip = 127.0.0.1; local_port = 12345; // 要连接的代理服务器 ip = 10.0.0.1; port = 1080; type = socks5; login = <username>; password = <password>; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20- 可以定义多个 redsocks{} 代理配置。
用 systemctl 保持运行:
systemctl restart redsocks systemctl enable redsocks
1
2或者手动启动:
redsocks -c /etc/redsocks.conf
1添加 iptables 规则:
iptables -t nat -A OUTPUT -p tcp -d 192.168.1.0/24 -j REDIRECT --to-ports 12345 # 编辑 nat 表,将本机发出的某些流量重定向 REDSOCKS 端口 iptables -t nat -L OUTPUT # 查看 iptables 规则
1
2系统重启时会重置 iptables 规则。因此建议将配置 iptables 的命令保存为一个 shell 脚本,每次系统重启时执行它。
# # (opens new window)Clash
:一个通用的代理客户端,采用 Golang 开发。
- GitHub(opens new window) (opens new window)
- 支持 HTTP、SOCKS、Shadowsocks、Vmess 等多种代理协议。
- 支持 Linux、MacOS、Windows、Android 系统。
- 在 Linux 系统上支持透明代理。
- 原理与 redsocks 类似,需要手动配置 iptables 规则。
# # (opens new window)反向代理
实现反向代理的常见工具:
- LVS
- F5
- :一个通过硬件实现负载均衡的服务器,基于 BIG-IP 协议。
- HAProxy
- :一个反向代理服务器,可以实现第四层的 TCP 代理、第七层的 HTTP 代理。
- Nginx
- :一个反向代理服务器,可以实现第四层的 TCP 代理、第七层的 HTTP 代理。
- frp
# # (opens new window)LVS
:Linux 虚拟服务器(Linux Virtual Server),是 Linux 的一个内核模块,通过转发 TCP/UDP 数据包,实现第四层的反向代理。
LVS 工作在内核态,比 Nginx 等用户态代理的性能更高。
原理:
- 创建一些 IPVS(IP Virtual Server)作为负载均衡器。
- 每个 IPVS 绑定一个 Virtual IP ,称为 VIP 。
- 每个 IPVS 负责将将访问 VIP 的 TCP、UDP 流量反向代理到某些后端的 Real Server IP ,称为 RIP 。
- 配置 iptables 规则,将访问 VIP 的流量交给 IPVS 处理。
- 创建一些 IPVS(IP Virtual Server)作为负载均衡器。
有多种反向代理模式:
- NAT 模式
- :转发请求报文给后端时进行 DNAT ,转发响应报文给客户端时进行 SNAT ,实现透明代理。
- TUN 模式
- :将客户端的请求报文通过 IP 隧道(Tunnel)转发给后端,而后端直接返回响应报文给客户端。
- 比 NAT 模式的速度更快。
- DR 模式
- :通过改写请求报文的目标 MAC 地址,将它转发给后端。而后端直接返回响应报文给客户端。
- 比 TUN 模式的速度更快,但需要后端有一个独立的网卡。
- NAT 模式
支持多种负载均衡算法:
rr # round robin(轮询),将请求报文轮流转发给各个后端,使得每个后端收到的请求数差不多相等。这是默认策略 wrr # weight round robin(加权轮询),给每个后端设置权重,权重更大的后端,更大概率收到请求 sh # source hashing ,计算请求报文的源 IP 的哈希值,将哈希值相同的请求转发给同一个后端 dh # destination hashing ,计算报文的目标 IP 的哈希值 lc # least connection(最少连接),监控每个后端的当前 TCP 连接数,将请求转发给连接数最少的后端 wlc # weight least connection(加权的 lc ) lblc # locality based least connections(基于局部的最少连接),记录每个请求的目标 IP 上一次使用的后端,作为转发规则,如果目标后端负载过大,则采用 lc 算法 lblcr # locality based least connections with replication(带复制的 lblc ),记录每个请求的目标 IP 使用的一组后端,采用 lc 从组中选出一个后端 sed # shortest expected delay ,监控每个后端的平均响应耗时,将请求转发给耗时最短的后端 nq # never queue ,优先将请求转发给当前连接数为 0 的后端,如果不存在这样的后端,则采用 sed 算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# # (opens new window)frp
:一个命令行工具,提供了反向代理、内网穿透的功能。
- GitHub(opens new window) (opens new window)
- 采用 Golang 开发。
- 支持 TCP、UDP、HTTP、HTTPS 等多种代理协议。
- 采用 C/S 架构工作。
- frps :服务器,部署在任一主机上,不需访问外部,只需被 frpc、用户访问。
- frps 所在主机通常拥有一个固定的外网 IP ,供外网用户访问。
- 用户向 frps 发送网络包时,会先被 frps 转发到 frpc ,再被 frpc 转发到内网服务。
- frpc :客户端,部署在任一主机上,不需被外部访问,只需访问到 frps、内网服务。
- frps :服务器,部署在任一主机上,不需访问外部,只需被 frpc、用户访问。
例:
登录一台主机,下载 frp 的发行版,编辑配置文件 frps.ini :
[common] bind_port = 7000 # 让 frps 监听一个端口,供 frpc 访问,用于它们内部通信 token = xxxxxx # 用于 frpc 与 frps 之间的认证
1
2
3启动服务器:
./frps -c frps.ini
1或者用 docker-compose 部署:
version: '3' services: frps: container_name: frps image: snowdreamtech/frps:0.37.0 restart: unless-stopped ports: - 7000:7000 volumes: - ./frps.ini:/etc/frp/frps.ini
1
2
3
4
5
6
7
8
9
10
11登录另一个主机,编辑配置文件 frpc.ini :
[common] server_addr = 1.1.1.1 # frps 的地址 server_port = 7000 token = xxxxxx # 定义一个反向代理,名称自定义 [proxy1] type = tcp # 代理的类型 local_ip = 10.0.0.1 local_port = 80-90,443 remote_port = 80-90,443 # 让 frps 监听 remote_port 端口,供用户访问,并将该端口收到的网络包转发到 local_ip:local_port # bandwidth_limit = 1MB # 限制带宽,默认无限制 # use_compression = false # frpc 与 frps 之间通信时,是否压缩 # use_encryption = false # frpc 与 frps 之间通信时,是否加密 # 可以定义多个反向代理 [proxy2] ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18启动客户端:
./frpc -c frpc.ini
1或者用 docker-compose 部署:
version: '3' services: frpc: container_name: frpc image: snowdreamtech/frpc:0.37.0 restart: unless-stopped volumes: - ./frpc.ini:/etc/frp/frpc.ini
1
2
3
4
5
6
7
8
9让用户访问 frps 的反向代理端口:
curl 1.1.1.1:10080
1
# # (opens new window)VPN
:虚拟私有网络(Virtual Private Network),指由公网上的几台主机组成一个虚拟的私有网络。
- 常用于实现正向代理。比如某个机房的各个服务器不暴露到公网,但机房的网关暴露到公网,用户可通过公网连接该网关,从而访问该机房的内网服务器。
- VPN 软件与代理软件类似,不过通常会转发客户端整个主机的流量、加密通信内容,而代理软件不一定提供这些功能。