老E的博客

  • 首页
  • 关于
  • 技术应用
    • VPS相关
    • AI相关
    • 盒子相关
    • 其他
  • 订阅Youtube频道
  • 网络加速
    • expressvpnNo.1 ExpressVPN
    • 最佳免费VPN-PrivadoVPN
    • NordVPN
    • 廉价王者-Surfshark
    • PrivateInternetAccess
    • 解锁一切-PrivateVPN
  • 公益资源
    • AI导航
    • 工具下载
    • Docker镜像加速
  • 友情链接
    • tickcloudTickcloud
老E的博客
专注记录并分享跨境技术应用及随想
  1. 首页
  2. 技术应用
  3. VPS相关
  4. 正文

精悍的工具-Stunnel搭建跨境加密隧道及代理实现

2023年10月12日 4978次阅读 4条评论
clawcloud
expressvpn best vpn
privado vpn
surfshark vpn
private vpn
pia vpn
nord vpn

Stunnel历史悠久、精悍通用,是不可多得的跨境加密隧道建立及代理转发工具,支持的应用层协议众多,包括HTTP/1.1 CONNECT over TLS。官网介绍简明扼要:一个设计用于TLS加密的代理。

Stunnel is a proxy designed to add TLS encryption functionality to existing clients and servers without any changes in the programs' code. Its architecture is optimized for security, portability, and scalability (including load-balancing), making it suitable for large deployments.
Stunnel是一个代理,旨在向现有客户端和服务器添加 TLS 加密功能,而无需对程序代码进行任何更改。其体系结构针对安全性、可移植性和可伸缩性(包括负载平衡)进行了优化,使其适用于大型部署。

不管新旧、好用最重要,更何况运营商(不仅国内)对UDP及其上的Wireguard、QUIC等很难有根本性的策略变化,那我们就用Stunnel这个精悍的工具来搭建基于TCP的跨境通道和机场。Stunnel用于加密隧道建立及转发代理,现有的“教程”多半是不对的、误人子弟的。

1.必备条件

首先以及最后,一台境外VPS,可访问受限站点和服务。

Stunnel可以部署在Linux(包括OpenWRT)、Windows、Android等系统上,所以除了具备公网IP的VPS作为服务端外,对客户端没有要求。由于其采用标准化协议,服务端部署上线后,移动端App(ShadowRocket、Clash等)可以直接添加Socks over TLS等标准化协议节点,无需插件、无需顾虑支持问题。同时,作为采用了OpenSSL的“标准化组件”,Stunnel可直接使用apt、apt-get和yum、opkg通过官方源安装即可,无需下载、编译,OpenWRT中luci 也可直接安装,本体大小不足80k。所以,仅仅用精悍来形容stunnel是过于保守了。

2.VPS上部署stunnel服务端

2.1 安装与环境检查

本文以debian/ubuntu为例。首先,使用apt安装stunnel4。

apt install stunnel4 -y
#apt install stunnel -y #与上一命令等效

stunnel4为stunnel的“新版本”,stunnel在系统中仅仅保留为stunnel4的软链接,所有守护进程名称及服务标识均为stunnel4,如stunnel4.service。

安装完成后,需要检查一下/etc/sysctl.conf和/etc/default/stunnel4两个文件。其中,/etc/sysctl.conf为检查ipv4转发是否开启,取消注释并将设为1后,使用sysctl -p命令即时永久生效。

/etc/default/stunnel4则修改ENABLE=0为ENABLE=1,该文件仅Ubuntu 18.04以下需要检查,较新版本无需操作。

# Julien LEMOINE <speedblue@debian.org>
# September 2003

FILES="/etc/stunnel/*.conf"
OPTIONS=""

# Change to one to enable ppp restart scripts
PPP_RESTART=0

# Change to enable the setting of limits on the stunnel instances
# For example, to set a large limit on file descriptors (to enable
# more simultaneous client connections), set RLIMITS="-n 4096"
# More than one resource limit may be modified at the same time,
# e.g. RLIMITS="-n 4096 -d unlimited"
RLIMITS=""

2.2 配置stunnel服务端

stunnel配置文件位于/etc/stunnel/目录下(/etc/default/stunnel4文件已有指明),一般采用stunnel.conf以便于记忆管理。配置文件中的选项和值的定义、说明请参阅老E的前文「stunnel配置文件主要选项」,不再重复。对应于不同的验证方式选择,分别分享两份样例配置文件。

证书验证方式

采用证书验证配置方式,需要使用OpenSSL生成自签名证书和私钥,stunnel支持pem和p12(pkcs12)两种证书格式,一般我们采用PEM格式,ACSII编码方式便于拷贝粘贴、密钥交换。

openssl req -nodes -new -days 365 -newkey rsa:2048 -x509 -keyout /etc/stunnel/2048key.pem -out /etc/stunnel/2048cert.pem
cd /etc/stunnel && openssl pkcs12 -export -in 2048cert.pem -inkey 2048key.pem -out 2048pks.p12
base64 2048pks.p12 > 2048pks.base64

生成自签名证书后,配置stunnel.conf文件如下:

syslog = no
debug = 3
output = /var/log/stunnel4/stunnel.log
pid = /var/run/stunnel4.pid

[stproxy]
;client = no

;connect = [host:]port
accept = 8443

cert = /etc/stunnel/2048cert.pem
key = /etc/stunnel/2048key.pem

;requireCert = yes
;CAfile = /etc/stunnel/ccert.pem

;CApath = /etc/stunnel/certs

protocol = socks

Stunnel配置文件中至少应包含一项服务/service,用封号(;)作行注释。这里的“[stproxy]”即指定了一项服务,“[stproxy]”以上的为全局配置选项,以下的为stproxy服务配置选项。client指定了该服务是否为客户端,默认为no,因此服务端可直接忽略或删除该行。accept、connect分别指定服务监听地址和端口、链接上级(代理服务端)的监听地址和端口,省略地址表示在所有接口的指定端口上监听,这里我们不使用connect行,由stunnel直接进行socks代理转发。下面两行,在不使用CApath选项的前提下,cert、key分别采用绝对路径指定了证书和私钥文件。

重要:拷贝2048cert.pem文件或其内容,以供客户端对服务端进行验证。TLS体制下,首先是对服务端的验证以避免身份仿冒,其次服务端对客户端的验证是可选的,默认情况下,stunnel关闭了客户端验证,需要通过显式定义requireCert=yes以开启。

最后一行的protocol指定了采用socks协议,我们的目标是搭建socks VPN,因其工作在应用层之下,标准化且适配广泛。以上配置完成后即可启动stunnel4服务。

systemctl start stunnel4.service
#service stunnel4 start
#systemctl status stunnel4.service

PSK预共享密钥验证方式

stunnel同样支持PSK预共享密钥验证方式,除身份验证外,PSK主要用于密钥生成前的数据加密、密钥生成及密钥交换,对应的配置文件中通过ciphers加以指定。

syslog = no 
debug = 3 
output = /var/log/stunnel4/stunnel.log 
pid = /var/run/stunnel4.pid 

[stproxy] 
;client = no 
;connect = [host:]port 
accept = 8443 

ciphers = PSK
PSKsecrets = /etc/stunnel/pskexample.txt

protocol = socks

和证书验证方式相比较,仅仅是更改了两行,ciphers=PSK指定了验证方式为PSK,PSKsecrets则以绝对路径方式指定了存储验证信息的psk文件。psk文件/etc/stunnel/pskexample.txt内容如下:

useridentity:aaabbb...111fff

psk文件内容为identity:presharedkey格式,预共享密钥不能少于32个16进制字符(0-f),最长不超过64个16进制字符。如果存在非16进制字符,stunnel会自动过滤排除。

2.3 误区

  • 服务端模式下,connect选项不是必要的,stunnel具备socks代理转发功能,因此也无需”tun2socks“类的额外工具;
  • 部分服务配置选项也可以作为全局配置选项,作用范围不同,但不能将connect等仅服务选项写到全局模块中(第一个方括号以上);
  • 默认安全等级为2,因此不可使用2048位以下的RSA/DSA密钥;
  • stunnel默认支持双栈,省略IP/HOST时使用”:::port“即开启双栈监听;
  • verify虽然仍可使用,但官方早已申明弃用,应使用verifyPeer、verifyChain以及requireCert;
  • 新手和小白不要随意修改样例文件中的全局配置,如pid等,除非你熟练掌握linux,老E不回答任何相关问题。

3.安装、配置stunnel windows客户端

官方网站下载「stunnel windows x64安装程序」,双击安装。stunnel会请求输入信息以生成证书,每一行都直接回车使用提供的默认值,第一行国家代码默认就是PL,表明了stunnel的“国籍”。安装完成并启动后,stunnel会驻守任务栏,点开任务栏图标,选择『Edit Configuration』即可打开配置文件。

Windows下,stunnel配置文件就位于其安装目录下的config目录下,除配置文件外,还有stunnel预置的和生成的证书文件,以及openssl主配置文件。所有可执行exe、动态链接库文件均位于安装目录下,没有系统盘存留。

配置文件中,除预留开启了gmail相关的服务外,其他均作为示例以分号注释。我们只需在文件末尾添加服务块内容即可。首先,需要将服务端证书拷贝至配置文件同目录下,这里使用了4096cert.pem的文件名称。然后,编辑添加以下服务块内容。

[socksproxy]
client = yes
accept = 10088
connect = server_ip_or_name:8443

;cert = stunnel.pem
;key = stunnel.pem

verifyPeer = yes
CAfile = 2048cert.pem

其中,client=yes表明这是客户端(默认为no),accept为监听地址和端口,connect指定连接的远程服务端地址和端口。验证模块中,verifyPeer=yes表示需要对服务端(对端)进行验证,CAfile指定了相对路径的对端证书文件。

确保正确编辑、添加配置后,保存配置文件,在任务栏点开stunnel菜单,选择『Reload Configuration』,这是应该就已经连接成功了。还是使用curl -x 请求google网站进行测试,国家码应该是VPS所在地,本例中是ja。

如有问题,可通过stunnel任务栏菜单选择『Show Log Windows』查阅日志进行分析。

4.客户端直连

这里以iOS ShadowRocket为例,在配置好服务端后就可以直连上网。打开小火箭,点击右上角『+』加号添加节点,点击『类型』(默认为shadowsocks),在协议类型中选择『Socks5 over TLS』后自动返回到『添加节点』,填入stunnel服务端的ip地址、端口后,点击『保存』。这时,移动端就可以直连stunnel服务端了。

这,就是标准化。如果你的app不支持,卸了吧。

5.安全增强

我们可以分析得出在使用证书验证方式时存在很大的安全隐患,如果有人知道了服务端的ip和端口,就可以通过任何支持Socks over TLS的客户端连接服务端,况且总有无聊透顶的人不是?问题的根源在于我们没有配置对客户端的验证。因此,我们需要取消服务端配置文件中以下两行的注释,开启服务端对客户端的验证。

;requireCert = yes 
;CAfile = /etc/stunnel/ccert.pem

同时,需要生成客户端证书和私钥,并上传/拷贝客户端证书至服务端服务端配置文件指定的目录下,并保证文件绝对路径、名称与配置文件指定一致。Shadowrocket支持base64编码的PKCS12格式证书以及证书密码,因此,对于移动端尤其是Shadowrocket有需求的,可在第一步服务端部署即直接采用p12证书,stunnel确定是支持的。

对于证书验证方式下的客户端身份验证,不再展开,仅补充三点:

  • Windows下安装Stunnel过程中会创建证书文件stunnel.pem,可直接使用,取消客户端配置样例文件中的注释后重新加载配置即可;
  • Stunnel配置文件中可采用CApath选项指定对端(们)证书目录,将所有对端证书存储于该目录下并以"证书Hash.0"命名,需注意采用的hash算法应与securityLevel要求匹配;
  • Shadowrocket可在『https解密』处生成2048位CA证书/密钥,系统『通用』下对文件描述确认后安装导入,将该base64编码的p12证书导出后可提取公钥pem,当然也可不提取转为p12格式直接完整拷贝使用。

当然,换成PKS预共享密钥也是可以的,32-64个16进制字符在一定时期内足够强壮,如果混杂0-f之外的无效字符(stunnel会自动剔除),可以为家庭和soho用户提供足够的安全保障,但是,老E发现目前SR尚不支持Stunnel socks over TLS的PSK验证,坚持协议和app选择,就需要放弃移动端直连服务端的功能。

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
标签: stunnel 代理 翻墙 隧道
最后更新:2024年5月27日

老E

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

  • 沐纪

    麻烦请教一下,我的curl可以访问,但浏览器打不开对应网址是怎么回事呢?

    2023年10月19日
    回复
    • 老E

      @沐纪 该不会没有安装插件吧 插件协议选择socks5 指向客户端暴露的ip:port ,stunnel只是对外暴露了一个端口做socks5转发和加密,默认不是全局。如果安装了插件并做了相应的配置,那再看下防火墙,如果还不行的,麻烦tg @without_answer 再详细交流分析

      2023年10月20日
      回复
  • Vim

    请问一下,如果只用移动端连接,是不是不能服务器对客户端认证了?

    2023年10月26日
    回复
    • 老E

      @Vim 也可以 主要是建立私有CA 两边使用同一个CA颁发的证书就行 比较麻烦

      2023年10月27日
      回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    站内搜索
    归档
    • 2025 年 5 月
    • 2025 年 4 月
    • 2025 年 3 月
    • 2025 年 2 月
    • 2025 年 1 月
    • 2024 年 12 月
    • 2024 年 11 月
    • 2024 年 10 月
    • 2024 年 9 月
    • 2024 年 8 月
    • 2024 年 7 月
    • 2024 年 6 月
    • 2024 年 5 月
    • 2024 年 4 月
    • 2024 年 3 月
    • 2024 年 2 月
    • 2024 年 1 月
    • 2023 年 12 月
    • 2023 年 11 月
    • 2023 年 10 月
    • 2023 年 9 月
    • 2023 年 8 月
    • 2023 年 7 月
    • 2023 年 6 月

    Copyright ©2023-2025 Appscross. All Rights Reserved.