前言

本文的内容

本文主要讲的是Proxy(代理),大部分为正向代理的内容,少部分涉及反向代理

本文内容分为以下部分:

  • Proxy的介绍与分类(前言部分)
  • Proxy的作用与原理(少部分内容)
  • Proxy的运用(大部分内容), 你也许能学到以下知识
    • 搭建游戏加速服务器
    • 分享【内网】或【只有连上VPN】才能访问的资源给其他人
    • 异地组网的方法(两种方案: 基于tun/tap配合路由表,基于代理配合iptables)
    • 搭建透明代理网关
    • 校园网免费上网的方法
    • 突破受限网络的方法
    • 窃听一个加密的代理隧道的流量(shadowsocks aes-xxx-cfb)
    • 躲开监管的思路
  • Proxy存在的安全问题(仅举例说明抛砖引玉,并非以偏概全)

这篇文章不只是讲的是一些知识点,

还有一些我自己对这个工具的思考、想法以及使用Proxy的经验的分享


本文的目的

很多人使用Proxy只是为了突破GFW的限制,但它其实有很多有意思的玩法

希望这篇文章能让你看到Proxy不一样的地方


什么是Proxy(代理)

寓意

Proxy指的是代理软件或代理服务器,也可以认为是一种网络访问方式


用途

在受限的网络中连接Internet

防火墙:因为所有内部网的用户通过代理服务器访问外界时,只映射为一个IP地址,所以外界不能直接访问到内部网;同时可以设置IP地址过滤,限制内部网对外部的访问权限;另外,两个没有互联的内部网,也可以通过第三方的代理服务器进行互联来交换信息。

节省IP开销

如前面所讲,所有用户对外只占用一个IP,所以不必租用过多的IP地址,降低网络的维护成本。这样,局域网内没有与外网相连的众多机器就可以通过内网的一台代理服务器连接到外网,大大减少费用。当然也有它不利的一面,如许多网络黑客通过这种方法隐藏自己的真实IP地址,而逃过监视。

例如校园网限制上网账户的终端数量为1,在可上网的电脑上搭建一个代理服务器,整个宿舍就可以共用一个上网账户来上网,可以节约网费。

提高访问速度

本身带宽较小,通过带宽较大的proxy与目标主机连接。而且通常代理服务器都设置一个较大的硬盘缓冲区(可能高达几个GB或更大),当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,从而达到提高访问速度的目的。

例如很多网吧都有一个web缓存服务器,用于将访问较多的内容缓存下来以达到访问加速的效果。为什么他能知道什么内容访问较多?为什么能把从远程服务器的请求弄到本地服务器上?就是使用了代理服务器来实现这个功能。


代理简单分类(按TCP/IP模型)

TCP/IP模型与OSI参考模型

360截图17090916295523

传输层代理

传输层代理即工作在传输层的代理,也称为四层代理,一般为socks协议(SOCKS4、SOCKS5),是非常灵活的代理

如何理解?即使用这种代理,不仅可以浏览网页,还可以玩游戏、发邮件、访问FTP服务器、上QQ、上微信等


应用层代理

应用层代理工作在TCP/IP模型的应用层之上,也称为七层代理,它只能用于支持代理的应用层协议(如HTTP,FTP)。

它提供的控制最多,但是不灵活,必须要有相应的协议支持

如何理解?比如说使用HTTP代理只能用来访问HTTP网站,使用FTP代理只能访问FTP服务器


代理简单分类(按功能)

可以分为以下两类

正向代理

个人理解,正向代理的作用就是让客户端流量走服务器的网络线路

举例

HTTP\HTTPS代理、Socks5代理等

配置方法请查看后文部分


反向代理(简单举例)

个人理解,反向代理的作用就是帮助外部的人员访问处于内部不能访问的资源,

由于存在防火墙等原因,外部人员不能直接访问内部服务,反向代理服务器的作用就是将内部的服务暴露出来

在反向代理服务器的帮助下,外部的人员不需要做任何操作,只需要像访问一个正常的服务器一样进行资源访问,

因为反向代理服务器帮助外部人员在内部服务器之间传递信息

Nginx

nginx是一个高性能的WEB服务器,nginx的安装过程这里就不细说了

当配置文件类似如下

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

include /etc/nginx/conf.d/*.conf;

# 主要部分如下
server {
listen 80;
server_name test.example.com; # 当识别到域名为test.example.com

# 转发请求给内部服务
location / {
proxy_pass http://127.0.0.1:8005;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {

}
}


}

配置好域名*.example.com指向这个服务器,客户访问test.example.com时,

nginx就会把请求都转发给位于127.0.0.1:8005的内部服务


启动一个flask web程序进行测试(模拟一个内部服务)

可见此程序监听127.0.0.1,端口为8005,本来外部是无法访问的

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask, render_template, Response, request


app = Flask(__name__)

@app.route('/') # 主页
def index():

return "Hello Flask!", 200


if __name__ == '__main__':
app.run(host='127.0.0.1', port=8005, debug=False)

360截图17120524599646

内部测试正常

360截图17860531233413

通过域名可以访问

360截图18430704116119110


Frp

frp的安装过程这里就省略了

服务端配置文件frps.ini

1
2
3
[common]
# Frp服务端的监听端口
bind_port = 8091

然后在VPS(有公网IP)上运行frp服务端

1
frps -c frps.ini

360截图18430703281713

以下操作在一台联网的但没有公网IP的计算机上操作

客户端配置文件fortest.ini

1
2
3
4
5
6
7
8
9
10
11
[common]
# 服务端ip地址
server_addr = lxscloud.top
# 服务端监听端口
server_port = 8091

[testweb]
type = tcp
local_port = 8005
local_ip = 127.0.0.1
remote_port = 8092

然后在本地起一个服务

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask, render_template, Response, request


app = Flask(__name__)

@app.route('/') # 主页
def index():
return "HAHAHAHA", 200


if __name__ == '__main__':
app.run(host='127.0.0.1', port=8005, debug=False)

360截图17860601062235

再启动frpc

1
frpc -c fortest.ini

360截图17571121839479

此时访问vps的8092端口,会有神奇的发现。

这就是所谓的内网穿透的实现方式之一

360截图16850822246420


代理与VPN的异同

虽然代理和VPN都位于请求的中间,都隐藏了客户的 IP 地址,并且都将信息转发给客户

按功能来看代理与VPN功能非常相似,但是还是存在一些区别

以下均为个人观点,仅供参考

专用性的不同

VPN,又称虚拟专用网络,VPN的连接每次都需要建立一个隧道,

在Windows上可以看到各种VPN软件创建的虚拟网卡,故VPN看起来更私有

(代理只需要开放一个端口来监听连接)

v1

v6

v2

v3

v5

v4

安全性

VPN传输前要对数据进行加密,而代理传输数据前是可以选择不加密的;

大多数 VPN 不会记录流量,免费代理可能监视流量;

这并不能说明代理的安全性不如VPN

支持的协议

VPN中可以使用ping来检查联通情况,而代理并不支持,ping是基于ICMP协议的

因为代理一般只能工作在传输层,而ICMP包是网络层协议(如上面提及,网络层协位于传输层之下),

所以代理无法转发ICMP数据包

而VPN可以工作在数据链路层,因此一般来说VPN支持的协议更多

速度

VPN的处理传输数据的方式和代理存在较大的区别,代理对数据处理一般比VPN简单,

并且有的VPN不支持多线程数据处理(如OPENVPN),理论上来说代理比VPN速度更快

功能

代理一般来说功能更灵活,可以设定规则来定义应用的访问是否通过代理服务器;

而VPN一般来说只支持全局模式,即整个系统的流量全部从VPN走


命令行代理软件推荐

以下代理软件支持多系统(win、mac、linux),多平台(X86、ARM、MIPS等),

支持多协议(http、tls、ss、socks),支持多功能(redirect、端口转发等)

GOST(GO Simple Tunnel)

项目地址:https://github.com/ginuerzh/gost

官方文档:https://latest.gost.run/


glider

项目地址:https://github.com/nadoo/glider

glider is a forward proxy with multiple protocols support, and also a dns/dhcp server with ipset management features(like dnsmasq).


正文

正向代理原理

HTTP代理

这里讲的是RFC 7230 - HTTP/1.1:Message Syntax and Routing,也就是普通模式,

这种模式下代理服务器只能帮客户端代理http请求


我们假设客户端已经设置好了HTTP代理服务器

首先客户端使用浏览器上网,发起了一个http请求(使用POST方法),类似如下

1
2
3
4
5
POST /test.php  HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: your-server.com

key1=val&key2=val2&key3=val3

然后请求发到了代理服务器,代理服务器会对请求进行处理

这个处理并不是必要的,代理服务器可以加上一些http头,就像下面这样,也可以不加任何东西

1
2
3
4
5
6
POST /test.php  HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: 目标服务器
X-Forwarded-For: xx.xx.xx.xx

key1=val&key2=val2&key3=val3

最后代理服务器向目标服务器发送报文,然后代理服务器接收返回的报文

然后代理服务器将返回的报文发送给客户端,这次的请求完成


HTTP\HTTPS代理

这里讲的是Tunneling TCP basedprotocols through Web proxy servers,也就是隧道模式(HTTP隧道)

这种模式下代理服务器不仅能帮客户端代理http请求,还能代理https请求和完成TCP连接,因为代理服务器只充当一条隧道,并不处理报文


我们假设客户端已经设置好了代理服务器

首先客户端使用浏览器上网,发起了一个http请求,

此时客户端会先连接代理服务器,向代理服务器发送隧道请求行(CONNECT方法),请求向目标服务器之间建立隧道

1
2
CONNECT 目标服务器IP:port  HTTP/1.1

代理服务器接收到该请求行后,向请求行中标记的目标服务器IP:port建立TCP连接

连接建立就将隧道建立完成的响应报文发送给客户端

1
HTTP/1.1 200 Connection Established

客户端收到隧道建立完成的响应报文,知道隧道建立完成了,即TCP连接已经建立

此时客户端直接与目标服务器通讯,就像没有代理服务器一样,而代理服务器此时会转发TCP连接(TCP透明传输)


Socks5代理

待补充


突破受限的网络

访问不能被访问的网站

访问不能被访问的网站请遵守法律,请文明上网,切勿做出违法行为

如果我们想要访问不能被访问的网站(简称:翻Wall,科学上网),可以非常容易的找到“梯子”,

一般来说,“梯子”是一个正向代理客户端,对于服务端平时并不需要自己搭建,只需找到提供服务的网站付费即可

“梯子”即使用HTTP\HTTPS代理、Socks5代理、Shadowsocks、ShadowsocksR、V2Ray、Trojan等软件访问不能被访问的网站

HTTP\HTTPS代理、Socks5代理

一般浏览器里面就可以设置

360截图172905058912996

当然也可以设置系统代理

360截图18141217375737


Shadowsocks客户端

Shadowsocks.exe图标如下

360截图1679052110414196

设置界面如下

360截图18430705498254

支持的加密算法如下

360截图1757111376122116


ShadowsocksR客户端

ShadowsocksR-dotnet.exe图标如下

360截图17290501437841

设置界面如下

360截图16790523242164

支持的加密算法如下

360截图1631031911189114

支持的协议如下

360截图16790524498754

支持的混淆方式如下

360截图1654052860106110


CLASH

介绍

Clash集成了Shadowsocks、ShadowsocksR、V2Ray、Trojan等软件的客户端,

同时有独特的Clash配置文件,配置和使用起来非常方便,可以定义各种规则,

还提供了系统代理、tun模式,

所以在“梯子”软件中非常受欢迎

360截图1767090993109115

支持的协议

Socks5、Shadowsocks、VMESS、Trojan


校园网“免费”上网

这里仅提供思路,仅供学习交流用途,因阅读本文而直接、间接造成的损失本人概不负责

经过我的思考,一般来说有以下条思路,根据效果的不同我我会标出其特点和要求

在内网搭建代理服务器

在某些情况下,我们的校园网一般被分为几个区域,

我们平时使用的校园网有免费的内网通道,仅能访问学习内网;也有要付费的能上网的通道,也能访问内网资源

但是办公室、电脑室的有线网络一般是使用免费的内网通道登录就能上网,正好处于可以相互通信的内网

此时可以在办公区搭建代理服务器,平时就使用免费的内网通道连接内网的自己搭建的代理服务器上网


简化版拓扑图如下:

360截图17860601675496


利用某些未被禁止联通外网的协议

以下方式可能可以绕过认证,但需要一台VPS搭建服务器

DNS隧道代理上网

如果上网认证主机可以进行DNS查询,可选择使用dns隧道上网

dns隧道工具将进入隧道的其他协议流量封装到dns协议内,在隧道上传输,

这些数据包出隧道时进行解封装,还原数据.

DNS隧道传输过程如下

  • 本地主机A发送一条dns请求,查询一个我们设定好的域名
  • 因为沿途的dns服务器都没有这个域名的相关信息,最终这条请求被转发到权威域名服务器B(假如是腾讯云上注册的域名,腾讯的域名服务器就是针对你的域名的权威服务器)
  • 我们添加了一条NS记录,关于要查询的域名,需要转到我们的公务服务器C做解析,B就会把C的地址返回给A
  • A知道了C的地址,就可以建立起dns隧道了

参考自:https://blog.csdn.net/qq_41832237/article/details/126564404

可使用软件搭建:DNS2TCP


ICMP隧道代理上网

如果未上网认证主机可以ping通外网,不拦截icmp数据包,

那此时可选择使用icmp协议隧道把目标内网流量转发出来,

防火墙一般也不会屏蔽ping的数据包

可使用软件搭建:ptunnelgost


利用某些放行的端口

有的学校/公司会放行53端口的UDP协议用于DNS查询,意味着53端口使用UDP发送数据畅通无阻

测试方法如下:

  1. VPS服务器监听53 UDP

    1
    nc -lvp 53 -u
  2. 处于未认证网络的客户端发包

    1
    echo "test" | nc vps的IP 53 -u

如果服务器收到了test信息,说明 53 UDP是放行的

这时我们可以在VPS搭一个代理,这里使用glider(https://github.com/nadoo/glider),走KCP协议

表示走KCP协议把流量转发到SOCKS5服务器

1
./glider -listen 'kcp://aes:password@:53?dataShards=10&parityShards=3&mode=fast,socks5://'

客户端跑如下命令

表示监听socks5在本地1080端口,走53端口的KCP协议到VPS的socks5服务器

1
./glider -listen :1080 -forward 'kcp://aes:password@VPS的IP:53?dataShards=10&parityShards=3&mode=fast,socks5://'

测试方法如下,使用curl通过本地的socks5服务器访问www.baidu.com

1
curl --socks5 127.0.0.1:1080 www.baidu.com

利用IPV6免费的特点

配合云服务器IPV6-TO-IPV4


访问内部网络

可用于以下等用途

从外部访问内网资源

下面模拟一个简单的常见

网络拓扑图

拓扑图如下(模拟)

360截图18720124193156

查看服务器网络接口,可以看到存在内网段172.43.1.0/24和172.43.2.0/24

360截图1632021364107103

代理访问

这里选用glider作为代理服务器

1
./glider -listen :8443

360截图17571119578149

客户机设置好代理

360截图16790525256969

访问成功

360截图18481106347754

内网横向渗透

软件选择

软件选择有很多

  • Cobalt Strike(CS)的Pivoting选项中的socks4a代理服务器

    360截图18430710617067

  • Metasploit(msf):在获取meterpreter shell的基础上搭建socks服务器(需要先使用route add添加路由)

    • msf5:use auxiliary/server/socks5use auxiliary/server/socks4a

    • msf6:use auxiliary/server/socks_proxy

      360截图17860605335470`

  • Frp(frp也有Socks5插件)

  • 普通代理软件(最好是二进制版,因为二进制版使用方便)

连接

连接操作和上面“从外部访问内网资源”部分大同小异,这里不再多说


节省IP开销

隐藏自己的真实IP地址

使用Tor等匿名代理可以在一定程度上隐藏自己的真实IP(切勿进行非法操作

某些防火墙可以自动把恶意攻击、扫描的访问者的IP记录到黑名单,

IP被记录到黑名单的访问者将会被服务器拒绝访问

利用代理,可以解除服务器对IP的封锁


例如挂上代理后访问一个WEB服务器,服务器中记录的访问者IP并非真实访问者的IP

真实的IP地址

360截图172905038790104

服务器记录的IP地址

360截图17911015103103147

查询可得

360截图167905188711495


多人共享网络

例如校园网进行网络认证,可以在认证过的主机上启用代理服务器,

处于和这台主机同一局域网(通过wifi热点或多网卡)的主机虽然未进行校园网网络认证,但是连接代理后一样可以上网

多人共享网络的操作方式就是认证过的主机起一个代理服务器,然后其它未认证过的主机主机连这个代理,前面已有提及,这里不再多说


伪装物理位置

例子(假设):有一个游戏只有香港用户才能玩,

这时假如找一个位于香港网络中的服务器然后在上面搭建代理服务器,

处于内地位置的用户连接上这个代理服务器后就能玩上这个游戏

未挂代理的位置

360截图172905038790104

挂上代理之后的位置

360截图1796032411189139


提高访问速度

加快网页加载速度

根据网站配置规则

配置代理规则,对不同网络需求的网址进行分类

像爱奇艺之类的中国网站,走本地的线路访问会比较快,像Youtube则需要走代理线路

以clash为例,如下图根据不同的网站的特点进行线路的选择

360截图18481108498743

提高资源下载速度

一般优化可以从以下方面下手

服务器选择

  • 上网带宽、网络线路
  • 服务器数据包转发性能、CPU性能、稳定性
  • 服务器机房所处位置
  • 服务端软件性能
  • 服务器网络稳定性

软件选择

  • 性能:多线程支持、语言运行效率
  • 安全性:是否支持加密
  • 其它:是否需要支持代理规则功能

选择传输层协议

尽量选择使用TCP协议来传输代理服务器与客户端之间的数据

客户端设备

  • 网卡性能、网卡速率、数据包转发性能、CPU性能
  • 客户端软件性能

根据网络环境的优化

  • 代理服务器与客户端均处于内网:
    • 可以直接选SOCKS5协议,性能佳,同时支持UDP和TCP
    • 选择C/C++或Golang或RUST语言编写的服务端客户端
  • 代理服务器处于公网与客户端可访问外网:
    • 考虑使用加密(性能会降低)
    • 可考虑使用混淆(可混淆为HTTP、TLS、WS协议)

高级玩法

这里仅为举例说明,实际使用请尽情发挥

混淆\伪造流量

可以参考我的上一篇文章

如下是一个正常的HTTP请求

360截图18141217223351

Wireshark中可以见到HTTP请求

360截图18470126429160

仔细查看HTTP报文,可以发现如下信息:HOST、UA等,

这些信息称为header,也就是请求头

360截图17260827387857

如果能将header中的信息改掉,那么就称为混淆,或者说是伪造

(下面的图片只是为了看到变化,不要太过在意GET和:8080那里的变化)

(应该关注的地方是a.lxscloud.top变成了b.lxscloud.top以及User-Agent的变化)

360截图18180718244723

以上的意思大致为:

本来我访问的是a.lxscloud.top,

但是我通过一些手段让这个请求的Host等发生变化,

让流量监测设备误以为我访问的是b.lxscloud.top,

但实际上我访问的还是a.lxscloud.top这个服务器


负载均衡

正向代理服务器的负载均衡

这里使用的是glider的负载均衡功能(使用高可用性模式-High availability mode)

代理服务器启动命令如下,代理数据出口设置了两个网卡接口,即eth0和eth1

priority是权重设置

1
glider -verbose -listen :8443 -forward direct://#interface=eth0\&priority=100 -forward direct://#interface=eth1\&priority=200 -strategy ha

360截图17571113332257

反向代理服务器的负载均衡

这里以nginx举例

nginx的负载均衡配置文件如下

可见有一个testloadbalance组,其中记录了多个后端服务器,weight可以设置权重

1
2
3
4
5
6
7
8
9
10
11
12
13
http {
upstream testloadbalance {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://testloadbalance;
}
}
}

搭建透明代理网关

所谓透明代理就是客户端根本不需要知道有代理服务器的存在,它改变你的报文,并会传送真实IP,多用于路由器的NAT转发中

一般透明代理网关是搭建在刷了openwrt的路由器(Linux设备)上的,

将WIFI、lan口的流量重定向到代理服务器,用于自动翻Wall、IP自动分流等用途,

一个最明显的用途就是手机、电脑等设备接上这个路由器就能翻Wall而不需要做任何操作


要搭建透明代理网关,一般需要三个部分:

  • 代理客户端(一般是Socks代理)
  • Socks代理与Nat转换
  • iptables重定向

代理客户端

在openwrt上很容易见到使用Shadowsocks作为代理客户端,并且一般都直接集成透明代理网关功能

这里探究它实现整个透明代理的逻辑:

方式一:Shadowsocks启动后会在本地监听一个Socks代理服务的端口,一般是1080端口,此端口用于传输代理数据

方式二:直接使用Shadowsocks-redir,包含Shadowsocks流量与Nat数据的转换,直接解决了代理客户端Socks代理与Nat转换两条

360截图18260728656187

Socks代理与Nat转换

一般可选Squid、Redsocks2、Shadowsocks-redir(ss-redir)

iptables重定向

配置iptables重定向是为了让流量都走代理服务器出去,

同时流量不能直接走代理,需要进行Nat转换再转发

需要UDP转发可以使用TProxy,

iptables规则示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
iptables -t nat -N shadowsocks# 保留地址、私有地址、回环地址 不走代理
iptables -t nat -A shadowsocks -d 0/8 -j RETURN
iptables -t nat -A shadowsocks -d 127/8 -j RETURN
iptables -t nat -A shadowsocks -d 10/8 -j RETURN
iptables -t nat -A shadowsocks -d 169.254/16 -j RETURN
iptables -t nat -A shadowsocks -d 172.16/12 -j RETURN
iptables -t nat -A shadowsocks -d 192.168/16 -j RETURN
iptables -t nat -A shadowsocks -d 224/4 -j RETURN
iptables -t nat -A shadowsocks -d 240/4 -j RETURN# 以下IP为局域网内不走代理的设备IP
iptables -t nat -A shadowsocks -s 192.168.2.10 -j RETURN# 发往shadowsocks服务器的数据不走代理,否则陷入死循环
# 替换111.111.111.111为你的ss服务器ip/域名
iptables -t nat -A shadowsocks -d 111.111.111.111 -j RETURN
# 大陆地址不走代理,因为这毫无意义,绕一大圈很费劲的
iptables -t nat -A shadowsocks -m set --match-set cidr_cn dst -j RETURN# 其余的全部重定向至ss-redir监听端口1080(端口号随意,统一就行)
iptables -t nat -A shadowsocks ! -p icmp -j REDIRECT --to-ports 1080# OUTPUT链添加一条规则,重定向至shadowsocks链
iptables -t nat -A OUTPUT ! -p icmp -j shadowsocks
iptables -t nat -A PREROUTING ! -p icmp -j shadowsocks

透明代理实例(在openwrt路由器上搭建透明代理网关,路由器下接的设备流量自动走代理)

本实例中的软件程序基于**glider, 详见前面“命令行代理软件推荐**”部分

glider中有Redir协议TProxy协议,对应用于转换tcp和udp数据

启动glider(有两种方式配置,命令行参数和配置文件)

命令行配置启动

1
./glider -listen redir://:12345 -listen tproxy://:12345 -forward ss://none:test@192.168.81.1:31090

使用配置文件,保存以下内容为glider.conf(我的代理服务器运行在192.168.81.1:31090)

1
2
3
4
5
6
7
8
# Verbose mode, print logs
verbose=False

listen=redir://:12345
listen=tproxy://:12345

# 修改为你的代理服务器
forward=ss://none:test@192.168.81.1:31090

然后启动

1
./glider -config ./glider.conf
配置iptables(参考自GOST)

192.168.78.0、192.168.77.0、192.168.1.0是我本机的本地网段,所以要避免走代理

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
26
27
28
29
30
31
32
33
34
35
36
37
iptables -t nat -N GOST
# 忽略局域网流量,请根据实际网络环境进行调整
iptables -t nat -A GOST -d 192.168.1.0/24 -j RETURN
iptables -t nat -A GOST -d 192.168.77.0/24 -j RETURN
iptables -t nat -A GOST -d 192.168.78.0/24 -j RETURN
# 忽略出口流量
iptables -t nat -A GOST -p tcp -m mark --mark 100 -j RETURN
# 重定向TCP流量到12345端口
iptables -t nat -A GOST -p tcp -j REDIRECT --to-ports 12345
# 拦截局域网流量
iptables -t nat -A PREROUTING -p tcp -j GOST
# 拦截本机流量
iptables -t nat -A OUTPUT -p tcp -j GOST


ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

iptables -t mangle -N GOSTU
iptables -t mangle -A GOSTU -p udp -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A GOSTU -p udp -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A GOSTU -p udp -d 192.168.1.0/24 -j RETURN
iptables -t mangle -A GOSTU -p udp -d 192.168.77.0/24 -j RETURN
iptables -t mangle -A GOSTU -p udp -d 192.168.78.0/24 -j RETURN
iptables -t mangle -A GOSTU -p udp -m mark --mark 100 -j RETURN
iptables -t mangle -A GOSTU -p udp -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 127.0.0.1 --on-port 12345
iptables -t mangle -A PREROUTING -p udp -j GOSTU

iptables -t mangle -N GOST_LOCALU
iptables -t mangle -A GOST_LOCALU -p udp -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -d 192.168.1.0/24 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -d 192.168.77.0/24 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -d 192.168.78.0/24 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -m mark --mark 100 -j RETURN
iptables -t mangle -A GOST_LOCALU -p udp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp -j GOST_LOCALU

配置完成后即可上网,可游戏(支持udp)


异地组网(组建虚拟局域网,基于隧道)

前置知识

TAP/TUN 是什么

在计算机网络中,TUN 与 TAP 是操作系统内核中的虚拟网络设备。不同于普通靠硬件网路板卡实现的设备,这些虚拟的网络设备全部由软件实现,并向运行于操作系统上的软件提供与硬件的网络设备完全相同的功能。 TAP 等同于一个以太网设备,它操作第二层数据包如以太网数据帧。TUN 模拟了网络层设备,操作第三层数据包比如 IP 数据封包。

操作系统通过 TUN/TAP 设备向绑定该设备的用户空间的程序发送数据,反之,用户空间的程序也可以像操作硬件网络设备那样,通过 TUN/TAP 设备发送数据。在后种情况下,TUN/TAP 设备向操作系统的网络栈投递(或“注入”)数据包,从而模拟从外部接受数据的过程。

引用自https://zhuanlan.zhihu.com/p/388742230

小结
  • tun是三层设备(工作在网络层)

    360截图16821214265235

    • tun设备能处理IP数据报,能进行 IP 数据封包,也就是能操作三层以上的数据包
    • 能传输TCP/IP协议,例如ICMP数据包(能使用ping),TCP和UDP更不再话下
    • 由于不能封装以太网帧(没有mac地址),客户端使用tun设备需要由程序操作或手动指定IP,不能由上游接口的DHCP服务器分配
  • tap是二层设备(工作在数据链路层)

    360截图16850822556065

    • tap设备能操作以太网帧,在Linux内核中被认为和实体网卡没有区别
    • 可以把tap设备理解为没有实体硬件的实体网卡,能实现tun设备的所有功能
    • 使用tap设备可以不指定IP,如果上游接口绑定了一个存在DHCP服务器的接口,客户端tap设备能被DHCP分配IP
    • 虚拟化网络可以使用tap设备来实现,例如两台虚拟机之间使用LinuxBridge(桥接)互通

以下案例基于gost实现

基于TUN设备(两台openwrt设备互通宿舍和工作室)

拓扑

360截图17060220112138124

网络状况

如拓扑图所示,看起来网络情况较为复杂,实际上我们只需要关注几个点:

  • 目标:工作室openwrt和宿舍openwrt互通

  • 已知:10.102.x.x与10.101.x.x可互通,但工作室只能拿到192.168.a.c

    也就是PC1、AR4能直接访问AR5开放的所有端口,但AR5访问不了任何一个AR4上开放的端口

    (且AR3的NAT类型为对称型,无法穿透)

也就是说可以在AR5上部署tun服务器,AR4上部署tun客户端

实操

下载路由器对应平台的gost二进制程序后,测试二进制程序是否可用

1
2
chmod +x gost
./gost -h

360截图17001018839879

服务端

AR5(openwrt设备)上运行tun服务端

这里服务端口为31070, 指定了tun设备的IP为192.168.123.1

1
./gost -L=tun://:31070?net=192.168.123.1/24

360截图16720403485638

此时查看网卡能发现tun0设备

1
ip addr

360截图18750819106119116

客户端

AR5(openwrt设备)上运行tun客户端, 指定了tun设备的IP为192.168.123.2

(SERVER_I请替换成你自己的tun服务设备IP)

1
./gost -L=tun://:0/SERVER_IP:31070?net=192.168.123.2/24

同样的,能看到tun0

360截图1739022796133141

测试连通性

使用ping测试连通性

360截图18000906375028

添加路由

例如我想在AR5下访问宿舍的设备(网段为192.168.77.0/24)

只需要在AR5添加路由(通过192.168.123.1转发)

1
ip route add 192.168.77.0/24 via 192.168.123.1

360截图17001022115730

AR4(tun客户端)下的设备想要访问AR5(tun服务端)的资源(宿舍访问工作室,工作室网段为192.168.40.0/24),可以在启动服务端时指定参数

会自动配置路由

1
./gost -L="tun://:31070?net=192.168.123.1/24&gw=192.168.123.2&route=192.168.40.0/24"

当然也可以像上面那样手动配置路由

1
ip route add 192.168.40.0/24 via 192.168.123.2

但是此时ping 192.168.40.0/24的设备还是不通

这是因为192.168.123.2(AR4)上面没有转发,最简单的解决方式就是给tun0配置一下接口

可用直接在luci界面操作

360截图16900206224524

360截图17081028426691

360截图17071207125814

此时再ping一下192.168.40.0/24中的设备,可以发现已经通了

360截图1694072599108100

EXT

上面在AR4添加newlan接口后,重启gost会报个错,如下图所示

可以忽略这个错误,因为系统已经为tun0配置了192.168.123.2的IP,而gost启动时会自动执行ip addr add 198.18.123.2/24 dev tun0,

所以说规则已经存在了

360截图17970216203565

基于TAP设备(服务部署到另外一个网段并固定IP)

案例说明

之前192.168.1.0/24有一台实体主机部署服务,但现在我把服务的容器部署在了192.168.77.0/24

由于网口有限,我已经腾不出物理网卡了,但我的某些嵌入式设备改与服务通信的那个ip比较麻烦,它们认定了在192.168.1.1的主机通信

最简单的方式就是借助tap网卡,实现虚拟容器的双网卡功能

下图是我路由器是设置的两个内网段

360截图187508198511395

拓扑

拓扑图如下,我需要借助tap设备给Server1分配一个192.168.1.1的IP

因此,tap网卡部署到AR1和Server1上

360截图18141215243349

实施

依然使用上面提及的gost软件

(注意:经过测试,gost_3.0.0-rc7配合tap设备只能跑到小于50Mbps的速度

在openwrt(AR1)上启动服务端,监听端口31071

1
./gost -L=tap://:31071

360截图18260726293362

在部署了应用的容器上启动客户端,同时设定tap网卡ip为192.168.1.1

1
./gost -L="tap://:0/192.168.77.1:31071?net=192.168.1.1/24&keepAlive=true"

360截图17380405787086

openwrt设置tap0网卡,绑定到lan1接口

360截图18750816558637

测试

访问http://192.168.1.1上的服务,访问成功

360截图18720117418487

tap设备绑定VLAN(openwrt)

如果需要把tap设备以aceess口的形式绑定到一个trunk口的某个vlan,只需要像下面这样新建device设备的配置即可

openwrt的配置文件位置在/etc/config/network

下面图片展示了绑定在vlan3259的tap0设备,类型为access口

360截图16930831364946


流量审计功能

流量审计功能一般应用于透明代理上

在一些公司里面的网络,往往存在这个功能

功能

  • 使用此功能可以记录客户端访问的网站,统计数据并绘制可视化图表,例如得知访问最多的网站,或查看某客户端的上网记录(一般来说https流量无法解密,管理者仅能看到客户端访问的网址、连接的服务器IP)
  • 控制客户端上网行为,例如禁止访问某些网址或某些软件

如何防御、绕过以上限制?

如果仅仅知道以上功能,却不想想怎么突破限制,是很没有意思的

当然以下方式并不能保证100%有效

方式一:多级代理(较安全,但速度会变慢)

再连接一个带有加密传输功能的自己的代理服务器或VPN

方式二:自建代理服务器(条件较难达成)

在内网一台能上网并且无流量审计(无流量审计是非必要的)的主机上搭建代理服务器,

然后再使用代理客户端连上这台主机的代理服务器

方式三:伪装流量(最麻烦)

在软件流量发送到代理服务器前修改其数据报文使其伪装为允许的数据报文

方式四:不认证(条件较难达成)

如果条件合适,可以善用前面提及的DNS隧道上网或ICMP隧道上网

方式N:放弃使用有限制的代理服务器上网(但有的公司不能带手机、网卡等设备)

直接使用移动网络、WIFI中继或卫星网络上网


反向代理服务器(frp)配合正向代理服务器(Socks5)

可以达到将内部代理服务器共享出去的效果,流程图如下

这就是“内网穿透”的一次应用示例,可以代替VPN服务器

360截图17960328577094


反向代理(nginx)配合反向代理服务器(frp)

比如我的Proxmox VE服务位于家里

360截图17290429221261

但是我想出门在外在使用移动网络等情况下也能访问这个服务,并且使用域名就能访问


首先在VPS上启动Frp服务器

服务端配置文件frps.ini

1
2
3
[common]
# Frp服务端的监听端口
bind_port = 8091

然后在VPS(有公网IP)上运行frp服务端

1
frps -c frps.ini

在这台搭建了Proxmox VE服务的主机上运行frp客户端

客户端配置文件frpc.ini

1
2
3
4
5
6
7
8
9
10
11
12
[common]
# 服务端ip地址
server_addr = lxscloud.top
# 服务端监听端口
server_port = 8091

[testweb]
type = tcp
# Proxmox VE服务是8006端口
local_port = 8006
local_ip = 127.0.0.1
remote_port = 8092

再启动frpc

1
frpc -c frpc.ini

然后配置nginx(为了安全还配置了ssl,使用https)

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
26
27
28
29
30
31
server {
listen 443;
# 设置域名为ser.lxscloud.top
server_name ser.lxscloud.top;
ssl on;
#ssl证书的pem文件路径
ssl_certificate /etc/nginx/ssl/1_ser.lxscloud.top_bundle.crt;
#ssl证书的key文件路径
ssl_certificate_key /etc/nginx/ssl/2_ser.lxscloud.top.key;
error_log /var/log/nginx/error_ser.log;
access_log /var/log/nginx/access_ser.log;

location / {
# 反向代理到127.0.0.1:8092
proxy_pass https://127.0.0.1:8092;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

### Set headers ####
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

### Most PHP, Python, Rails, Java App can use this header ###
proxy_set_header X-Forwarded-Proto https;

#WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

一切配置完成,重启nginx,

访问https://ser.lxscloud.top即可访问Proxmox VE服务

360截图176807299180112


反向代理服务器配合VPN客户端

作用是分享VPN内的资源给未授权的其它人(因为其它人没有账户不能连这个VPN)

启动VPN客户端,并连接

360截图17891229378177

可以见到VPN的虚拟网卡为”以太网 5”

360截图17661023546161

glider支持指定网络出口接口,所以这里使用glider演示

启动命令如下,监听8443端口,作为代理服务器,然后将出口流量转发给”以太网 5”

1
glider -verbose -listen :8443 direct://interface="以太网 5"

此时连接代理服务器的8443端口的设备都能访问VPN网络里的资源


反向代理服务器配合正向代理客户端(特殊网络环境)

拓扑图

如下简化版拓扑图所示,存在可上网区和不可上网区,PC2、PC3能ping通PC1

如果存在如下的网络环境,不可上网区要如何才能上网?

360截图18481113504276

解决方案

可按如下步骤操作

1)在可上网区的PC2或PC3上搭建一个正向代理服务器,这里假设选取了PC2,假设正向代理服务器端口为1080

2)在不可上网区的PC1上启动反向代理服务器(Frp等软件)

3)PC2上使用反向代理客户端连接PC1上的反向代理服务器,将正向代理服务器的端口1080反向代理到PC1上

4)PC1通过连接127.0.0.1:1080上网


代理转VPN客户端

Windows端

使用SSTap或Netch可以完成这个操作,详见下部分“游戏加速”


Linux端(以下为一个使用案例)

可考虑使用tun2socks,能将shadowsocks、socks5等代理协议转换为tun网卡设备(三层设备),

tun2socks官方设置样例:https://github.com/xjasonlyu/tun2socks/wiki/Examples

下载目标平台上的二进制文件即可使用,例如这里使用tun2socks-linux-amd64.zip作为演示

1
2
3
4
tun2socks-linux-amd64.zip
unzip tun2socks-linux-amd64.zip
mv tun2socks-linux-amd64 tun2socks
chmod +x tun2socks

360截图1825090585121105

拓扑

360截图169506148010881

实操

尝试运行

1
./tun2socks -h

如果有以下输出说明运行无误

360截图18430708759493

启动tun2socks,绑定虚拟网卡tun0(我的代理服务器运行在192.168.81.1:31091)

1
sudo ./tun2socks -device tun0 -proxy ss://aes-128-cfb:test@192.168.81.1:31091
配置tun设备

配置tun0设备的IP地址(198.168.123.2可以自己设置,和后面要对上)

1
sudo ip addr add 198.168.123.2/24 dev tun0

启动tun0网卡

1
sudo ip link set dev tun0 up
配置路由规则

设置通往代理服务器的路由(此台机器上网网卡的网关IP为192.168.1.3)

1
sudo ip route add 192.168.81.1/32 via 192.168.1.3

删除默认路由

1
sudo ip route del default

设置默认路由为tun0设备

1
sudo ip route add default via 198.168.123.2 dev tun0 metric 1

此时可以看看路由表有没有问题

1
route -n

360截图17331014677252

此时可以愉快的上网了,查看IP地址可以发现是代理服务器的IP地址

360截图17860601192818

下图是未配置tun2socks时的IP

360截图187705309299104


游戏加速

游戏加速的代理的搭建的要求比前面提及的玩法的搭建要复杂一些,

因为游戏对数据包收发的延时有要求,并且要求代理能转发UDP数据包,

有时候对所处网络的NAT类型、DNS请求、ICMP包的信息也有要求

一般可以把以下几个方面做足

服务器选择

  • 首要的就是确定代理的目的
    • 游戏服务器在哪个位置?
    • 游戏对区域的要求?
  • 在不影响游戏需求的情况下尽可能选择距离比较近的服务器
  • 选择稳定的机房、可靠的服务商(网络线路)

代理服务器软件的选择

推荐使用Shadowsocks或者ShadowsocksR(请注意本文尾处的“安全性”部分)

原因有以下两点(仅供参考):

  • Shadowsocks或者ShadowsocksR均支持加密传输,均支持TCP和UDP转发,ShadowsocksR还支持混淆,可以防止防火墙识别到非法流量而进行封锁限制
  • Socks5代理对游戏支持不太好(个人体验)

代理协议的选择

可选ss、ssr,支持的客户端\服务端软件多,自带加密,支持udp

可以在客户端保持服务端的NAT类型,例如服务端NAT类型为Full clone,客户端做透明代理后再检测NAT类型也为Full clone,对游戏友好,

  • 建议ss+kcp再tproxy透明代理
  • 实测tun2socks不支持Full clone NAT

KCP加速(可选,降低延时)

可以考虑在代理客户端与服务端之间采用KCP加速,牺牲带宽换取低延时

Github - KCP,KCP是一个传输层协议

KCP的介绍

KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 连时钟都需要外部传递进来,内部不会有任何一次系统调用。

KCP协议的原理

KCP协议是基于TCP/IP模型中传输层的UDP协议,再通过应用层来实现可靠性传输

由于UDP协议没有TCP协议的三次握手的特性,传输数据时延时会比TCP协议低,所以使用UDP协议传输数据可以降低延时

KCP协议的出发点主要就是为了让UDP变的可靠,那么如何让UDP变的可靠?
答案就是把TCP的可靠机制移植过来,可TCP的可靠机制是在传输层完成的,而UDP在传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。这就是KCP做法,也是其他UDP可靠算法的做法,在UDP身上套一个可靠机制算法,只不过使用上会有差异而已。


线路优化

线路优化这里指的是通过某些方式主动的修改连接过程中走的线路

慎用,因为存在许多不确定性,有时候会导致更差的效果,因机房、服务器而异(例如延迟变得更高、连接稳定性变差)


方法是先在一个可靠的机房搭一个代理,这时可以走kcp协议保证低延时

然后把这个代理作为跳板,再连接下一个用于加速的服务器

这样做的原因是直接连接到加速服务器可能会走比较拥挤的线路,因为我们使用的宽带网络都处于互联网的边缘,

而机房一般都是位于骨干网,有的机房走国际网络的线路还会有优化,我们如上的做法相当于自己主动选择了数据包的线路

选择有如下:

  • cloudflare warp
  • 自己的云服务器(例如国内的腾讯云、阿里云的云主机)

使用面向游戏的代理客户端

以下两款软件都支持转发TCP和UDP数据包,为游戏提供了较好的支持

Netch

推荐使用Netch,可以设置分应用代理,也可以全局代理

主界面如下

360截图1828050989134138

支持的连接方式如下

360截图18141217155745

支持的加密方式也非常多

360截图18200427397576

360截图16411207859073

可以进行规则定义

360截图17321123293550

SSTap

主界面如下

360截图16790523404550

支持的连接方式如下

360截图17290506465177

设置界面如下

360截图18220210589690


安全性

中间人攻击

中间人攻击的实施可以使用mitmproxy或者fiddle等工具,

利用上面提及的透明代理网关的方式,可以无感知(仅限于HTTP,HTTPS需要骗受害者安装你的根证书)的进行中间人攻击

中间人攻击可以截获、修改或者查看受害者发送的信息


模拟场景

使用fiddler模拟场景

启动fiddler,设置好代理端口

360截图17350804565498

受攻击者设置好代理(模拟)

360截图17420915165542

访问一个HTTP网站并得到响应

360截图16840926201865

此时查看Fiddler,可以看到请求的所有信息,还可以查看响应信息

360截图1843071063106115

防御方法

  • 尽量使用HTTPS
  • 不随意安装根证书
  • 上网时可以连上安全的VPN或挂上安全的代理
  • 使用移动网络上网

Shadowsocks重定向攻击

非libev版本的shadowsocks若使用Stream cipher进行加密则可能存在信息泄露的危险,

攻击者可以使用Redirect attack(重定向攻击)从ss-server解密消息,前提是能抓到使用者发送的tcp报文

利用

复现过程参见本博客文章:

Shadowsock重定向攻击复现


防御方法

换用Shadowsocks-libev同时使用AEAD的加密方式


Socks5重定向攻击(RealWorld-CTF-2021)

Personal Proxy

待补充


结束

感谢阅读,此文发布于https://blog.lxscloud.top