安全的内网穿透保姆级教程,使用nginx反向代理给内网设备实现双向ssl认证,阻止无证书用户暴力破解nas

安全的内网穿透保姆级教程,使用nginx反向代理给内网设备实现双向ssl认证,阻止无证书用户暴力破解nas
2022年05月23日 21:58 什么值得买

作者:geek玩物

前言

大家会不会有这样一个烦恼,使用内网穿透后自己位于家庭内网中nas等其他设备总是有不明ip企图暴力破解登陆。虽然你的强密码让它们无法登陆成功,但是总被攻击也不好。

最近我自己也要部署一个内网穿透环境,用来和我现在使用的虚拟网穿透构成互补。为了方便不会使用虚拟网工具的家里人。也就是直接在浏览器上,不需要添加其他操作就能直接访问的方案,比如nps穿透方案。这是一种直接暴露在公网的方式,任何人知道了域名都能访问到我家的内网,而域名又不是一个很好保密的东西。天天被不明ip暴力破解是一种非常不好的体验。

那有没有办法避免了?我们知道https可以通过证书来识别服务器的身份,这叫做ssl单向认证。既然有单向认证就有双向认证。在ssl双向认证中,服务器也会要求客户端出示证书,如果证书通过验证服务器和客户端就建立通信,如果没通过认证服务器则拒接客户端的连接请求。因此我们就可以通过配置ssl双向认证,让内允许的用户可以访问nas等,其他基于http的内网服务。而其他不被允许的用户则没有连接权限,从而一定程度上保护内网设备的安全。

需要准备的材料

1.域名一个,需要支持泛解析

2.公网ip,或者公网云服务器,或者其他内网穿透手段

3.一个能允许docker的内网设备,群晖,openwrt,unraid都行

4.一个ssl证书,自签的或者ca机构发的都行

教程开始

一,nginxwebui容器部署

nginxwebui是陈钇蒙大佬写的图形化nginx。通过图形化web管理界面配置nginx,非常方便新手入门。自带ssl证书自动申请和续签功能,极大的方便了我们这群内网穿透玩家。

本次教程使用的是docker版本的nginxwebui,为了能独占80和443端口。需要使用macvl nginxWEBUI一个独立的IP。

首先查看docker是否已经部署macvlan网络

输入下面命令

docker network ls

可以得到下面输出

root@Tower:~# docker network ls

NETWORK ID          NAME                DRIVER              SCOPE

c9b49d7dffff        br0                 macvlan             local

0464aacdffff       bridge              bridge              local

07c5c1d0ffff        host                host                local

a059f37effff        none                null                local

root@Tower:~# 

可以看到有一个名字叫做br0的macvlan网络

若是没有macvlan网络,要先创建一个macvlan网络。输入下列命令查看正在使用的网卡名称

ifconfig

获得以下输出,找到有你的后台管理界面ip的网卡,比如我的后台ip是10.100.50.5,有这个IP的网卡是br0,记住br0。

bond0: flags=5443  mtu 1500

        inet6 fe80::2f1:ffff:fef0:5aba  prefixlen 64  scopeid 0x20

        ether 00:ff:ff:ff:ff:ff  txqueuelen 1000  (Ethernet)

        RX packets 15361454  bytes 5485436605 (5.1 GiB)

        RX errors 0  dropped 773911  overruns 0  frame 0

        TX packets 14499561  bytes 9878246997 (9.1 GiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

br0: flags=4163  mtu 1500

        inet 10.100.50.5  netmask 255.255.255.0  broadcast 0.0.0.0

        inet6 fe80::2f1:ffff:fef0:5aba  prefixlen 64  scopeid 0x20

        inet6 123f:fff:fff:acc0:2f1:ffff:fef0:5aba  prefixlen 64  scopeid 0x0

输入下面命令开启网卡混杂,注意我这里的网卡名字叫做br0,如果你的不是br0 请将命令中的br0更改为你的网卡名称。

ip link set eth0 promisc on docker

创建一个名字为vlan1的macvlan网络,网卡名称,网关和网段请自行更改为自己使用的,我的网卡是br0,我家网络的网段是10.100.50.0/24 网关10.100.50.1

docker network create -d macvlan --subnet=10.100.50.0/24 --gateway=10.100.50.1 -o parent=br0 vlan1

拉取nginxwebgui容器镜像

docker pull cym1102/nginxwebui:latest

启动容器,这里给容器指定一个上一步创建的名为“vlan1”的macvlan网络并配置ip地址。根据自己的实际情况修改命令,不能照抄。

docker run -itd -v /home/nginxWebUI:/home/nginxWebUI -e BOOT_OPTIONS="--server.port=8080" --privileged=true --net=vlan1 --ip=10.100.50.81 cym1102/nginxwebui:latest

容器启动后,直接访问http://ip:8080。就可以打开nginxwebui的管理界面。

当然我们先不着急设置nginxwebui,还需要做很多准备工作才能让ngixwebui变的更好用。

二,配置容器网络,允许nginxwebui容器和宿主机通信

由于docker的安全机制,使用macvlan的的容器是没有办法和宿主机通信的。毕竟很多all in one用户会安装一下功能型容器,比如emby媒体服务器等。这种容器一般采用宿主机端口转发的模式,使用的是宿主机的ip地址,因此也没办法访问到这些容器。这不是穿透了个寂寞吗?

所以这节内容是解决macvlan网络访问宿主机的问题。

宿主机和使用macvlan的容器无法相互通信,即是在同一个网段也不行。但是macvlan容器之间可以互相通信,因此我们可以给宿主机追加一个macvlan虚拟网卡,通过这个虚拟网卡和macvlan容器通信。

我的宿主机的网卡名称是br0,ip是10.100.50.5,容器的ip是10.100.50.81。在宿主机中输入下列命令创建了一个名为“macvlan2”虚拟网卡,并分配给宿主机使用

ip link add macvlan2 link br0 type macvlan mode bridge

分配一个ip给虚拟网卡

ip addr add 10.100.50.3 dev macvlan2

启动虚拟网卡

ip link set macvlan2 up

设置路由规则,通过这个虚拟网卡和容器通信,有几个需要通信的容器就设置几条路由规则

ip route add 10.100.50.81 dev macvlan2     #目标ip地址根据实际情况修改

这样我们就可以使容器和宿主机通信了,宿主机通过容器的ip访问容器,容器通过宿主机的macvlan2访问宿主机。比如在这里容器要ping宿主机,就是ping 10.100.50.3。

三,配置nginxwebui和openssl自签ssl证书

1.oepnssl自签名证书和申请免费ssl证书

在这里我们需要配置两个证书,一个服务器的ssl证书。这个可以从ssl证书签发机构弄来,比如阿里云,或者用openssl配置自签名证书。客户端的证书需要自己通过openssl配置自签名

先开始配置服务器的ssl证书,分机构签发和opessl自签名两个

(1).机构签发——以阿里云为例子

    首先要建立一个阿里云的ram访问用户,用于申请和自动更新ssl证书。打开阿里云的控制台,把鼠标放在右上角头像处会出现下图的菜单,点击进入accesskey管理,进入以后他会提示你建立一个子ram用户。

之后我们就打开了ram子用户管理界面,点击新增一个用户,设置用户名并勾选openapi选项。之后子用户就建立好了,这时候你就可以看到子用户的AccessKey ID和AccessKey。不过还不能直接使用,还得给子用户添加相应的权限才行。我们需要给子用户添加三个权限“管理云盾证书服务的权限”“管理云解析(DNS)的权限”“管理域名服务的权限”。此时ram子用户配置完成。

将一步的到子用户id和key填入到nginxwebui的证书管理中就就可以自动申请证书和自动续签了。

(2)openssl自签名证书

nginxwebui的是自带了openssl工具的,所以我们直接在容器中自签就行了。首先我们要连接到nginxwebui的终端,对于unraid。在容器管理中选择连接终端就可以了,对于群晖和openwrt就需要Portainer。由于篇幅有限这里简单的说一下Portainer的部署

docker pull 6053537/portainer-ce   #拉取汉化版portainer容器镜像

ocker run -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /portainer_data:/data -d 6053537/portainer-ce  #运行portainer镜像,并设置9000端口访问。登陆ip:9000就可以访问Portainer后台。

openssl自签服务证书使用起来很麻烦,所以我不建议各位使用,这里就简单的说一下自签证书的过程

打开/home/nginxWebUI,这个目标是映射到宿主机的/home目录中的,然后新建一个文件夹openssl,并进入改文件夹.

cd /home/nginxWebUI

mkdir openssl

cd openssl

生成ca私钥,生成ca根证书

openssl genrsa -out ca.key 4096

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

在建立ca证书的时候会输入一些必要信息

国家名称://随便输入,最多两位字母

省或州的名称://随便输入

城市名字://随便输入

组织名称://随便输入

组织单位名称://随便输入

Common Name://随便输入

邮箱://随便输入

这样ca证书就创建好了,建立服务器的证书和私钥

openssl genrsa -out server.key 4096

openssl req -new -key server.key -out server.csr

建立服务器证书和建立ca根证书的流程差不多

Common Name:这个选项不能随便填,这里要写服务器的域名或者ip。泛域名为*.你的域名。

输入完邮箱后要是一个“A challenge password”,这是要求给ca证书建立一个密码。不要输入任何内容回车跳过

然后输入下面的命令给服务器证书签名

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

这时候服务器证书已经签名好了,把服务器的证书和私钥传到nginxwebui,把自签名的ca根证书安装到需要的设备上就行了。

(3)客户端证书制作

和上面自签服务器证书差不过,本次采用上一步上次的ca私钥和ca根证书来签名客户端证书。如果是使用机构签发ssl证书跳过服务自签名证书的同学,可以参考上一步生产ca私钥和ca根证书。

openssl genrsa -out client.key 4096

openssl req -new -key client.key -out client.csr

步骤和生成根证书一样,输入一些必要信息

输入完邮箱后要是一个“A challenge password”,这是要求给ca证书建立一个密码。不要输入任何内容回车跳过

输入下列命令给客户端证书签名

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650

输入下列命令将客户端证书和私钥打包为p12格式

openssl pkcs12 -export -inkey ssl/client.key -in ssl/client.crt -out ssl/client.pfx   //下一步会要求给p12证书设置一个密码

生成的所有文件都会在宿主机的/home/nginxWebUI中.

2.配置nginxwebui反向代理和ssl双向认证

首次登陆后会有账户密码的设置界面,设置好以后登陆到nginxwebui的管理界面

第一步选择http参数配置,第二步选择简易配置向导,之后会打开配置界面,使用默认的配置就可以了

然后打开反向代理选项卡,在这个界面上可以看的到已经配置的反向代理,点击添加反向代理按钮。之后会开发新建反向代理的界面。

因为我们这篇教程是需要使用https,所以在开启ssl选项上选择是,监听端口443,开启htpp2,开启http转https,跳转端口80。这样子我们就可以浏览器直接输入域名跳转到https。

接下来就是重点内通了,域名监听设置。首先我们申请的域名一般都是这种格式“b.a”。我们一般都不会直接使用顶级域名,一般会弄一个二级域名用于解析ip,比如说“c.b.a”这个域名解析给“1.1.1.1”,“d.b.a”给“1.1.1.2”。有些时候需要整一级域名解析给一个ip,就是泛解析。记为"*.b.a",二级域名泛解析则为“*.f.b.a”。

对于阿里云的设置,在解析记录的主机记录上写上“*.”那么所有“c.b.a" , "d.b.a".........."z.b.a"都会解解析给同一个ip。在解析记录的主机记录上写上“*.home”,那么所有的“a.home.b.a" , "b.home.b.a"........"z.home.b.a"都会解析给同一个ip

因为nginx的http反向代理是通过域名来识别目标的,所以我们需要把一个域名泛解析给nginx。我在这里用一个二级域名解析给nginx。所有的“*home.b.a”都会解析给nginx,然后nginx在根据完整的域名代理访问内网的主机。

比如我的群晖管理后台的完整域名为“ds.home.b.a”,nginx就会根据这个完整域名找到内网中的群晖主机。

同理openwrt的完整域名是“rope.home.b.a”,nginx就是根据这个完整域名找到内网中的openwrt主机。

域名监听设置好以后,我们需要在添加一个代理目标,让nginx可以找到内网的主机。

监控路径不用管,http代理类型选择“动态http”,目标路径和端口根据实际选择。比如我的群晖IP是“10.100.50.200”端口为“5000”,那么目标地址就为“http://10.100.50.200:5000",比如我群晖上的seaflie网盘的ip为“10.100.50.200”端口为“8000”,那么目标地址就为“http://10.100.50.200:8000”。比如我的openwrt的ip是“10.100.50.15”端口默认为“80”,那么目标地址就为“http://10.100.50.15:80”。

注意一个域名的代理目标是可以添加多个的,但是在这里不建议。最好一个域名对应一个代理ip:端口,比如群晖管理是一个域名,sea file是一个域名,openwrt是一域名,这样才不会导致解析错误。

接下来配置https使用的ssl证书,对于已经申请ssl证书只需要在中选择即可。对于自签证书就需要主机上传证书和私钥。配置以后点击“提交”一个带有ssl的http转https的反向代理就配置成功过了,下一步就是使配置生效。

在侧边栏选择启用配置选项卡,之后后打开下图的界面。先点击“检验文件”选项卡,检验成功后。选择“停止nginx”选项卡,依次“替换文件”,“启动nginx”。这样的反向代理就启动成功了,可以直接使用了。

如果要配置双向ssl,要将下面这两条配置插入到相应反向代理配置文件中,插入位置如下图。比如我这里插入的是群晖的反向代理配置中。每一方向代理域名都需要单独配置,并插入到对应的位置中。

“ssl_client_certificate /home/nginxWebUI/openssl2/ca.crt;”中的“/home/nginxWebUI/openssl2/ca.crt”是刚才openssl生成的自签名ssl ca证书,可以根据自己的实际情况的进行配置。

配置好以后重复上一步:“检验文件” “停止nginx”的步骤。就配置好ssl双向认证了

ssl_client_certificate /home/nginxWebUI/openssl2/ca.crt;

ssl_verify_client on;

好了,现在可以在浏览器上访问刚才配置好的网址,然后直接看到了下面的提示。这是因为没有配置好客户端的ssl证书和私钥,服务器没有正确验证客户端证书,所以直接拒绝了链接。

3.设备配置客户端证书

1.Windows

先要安装openssl自签的ca证书,然后安装打包好的p12证书和私钥,并输入打包p12时的密码。要是不安装ca证书会提示p12证书未进过验证。之后访问对应需要的双向认证的网页,选择对应的客户端证书就可以了

2.安卓

安卓直接安装p12证书就可以了。之后访问对应需要的双向认证的网页,选择对应的客户端证书就可以了

3.macos

和Windows一样需要先安装自签名的ca证书,然后在安装p12证书。macos在安装完ca证书后,需要在“钥匙串访问”——“系统钥匙串-系统”——“证书“双击刚才安装的ca证书,在新打开的窗口选择“信任“选项卡——勾选始终信任。这样子p12证书和自签名的ca证书就生效了。之后访问对应需要的双向认证的网页,选择对应的客户端证书就可以了

4.ios

也要先安装openssl的自签ca证书,当然ios安装ca证书和p12证书比较麻烦。我的解决办法就是将ca证书和p12客户端证书传到群晖或者unraid上,用它们充当简单的http下载服务器。在ios自带的safari登陆群晖在file station上选中证书,长按打开菜单选择下载就可以安装描述文件。对于unraid就更简单了,打开存储证书的磁盘,找到证书存储的位置直接击就可以下载安装描述文件。

ios要先安装ca证书,然后在“设置”——“通用”——“描述文件和设备管理”——验证刚才安装的ca证书。然后在“通用”——“关于本机”——“证书信任设置”信任刚才的ca证书

然后安装p12证书,输入密码安装成功后,也要在“设置”——“通用”——“描述文件和设备管理”——验证刚才安装的p12客户证书。

不过ios有限制,只有自带的safari浏览器才能使用ssl双向验证。打开需要的双向ssl的网页时,浏览器就会跳出客户端证书选择界面,选择对应的证书就可以访问了,就不会出现nginx 400错误。

至此nginx反向代理和双向ssl认证教程结束了

PS:配置ssl双向认证以后,只能通过浏览器访问,app不支持ssl双向认证会提示无法连接。

财经自媒体联盟更多自媒体作者

新浪首页 语音播报 相关新闻 返回顶部