起因

  最近放假回家了,但是人回家了并不能代表可以把学校的事情全抛了。因此就需要把以前的arch上部署EasyConnect需求重新提起来,还要额外增加一些要求。

需求

  EasyConnect是深信服开发的一款VPN工具,被许多公司和学校内网广泛使用。然而深信服作为一个安全公司,自己做的产品甚至烂到被自己人骂。尤其是对Linux的兼容性,我在之前折腾了许久对应的deb包,依然是不能够顺畅使用,当时也只好放弃暗暗骂一句

  现在重新思考这个问题,最后还是决定把EasyConnect关进windows虚拟机里吧。这样一方面,保证windows下EasyConnect是能够正常使用的,学校的VPN登陆跳转认证也能被外挂的客户端读到;另一方面,可以不用和闭源的EasyConnect的deb包斗智斗勇,保证自己的系统处于一个干净的状态。

最终,我期望的一个状态是:

所有和EasyConnect、学校VPN服务身份认证相关的东西,都完全扔进windows虚拟机,对外只暴露一个NAT ip 提供路由中转服务;在外面的Arch作为host,可以通过openssh,访问学校内网的任何服务,也可以将本地的服务映射到工位的主机上,对内网开放。

  这样一来,我可以直接在校外连接到组里提供的服务器,也可以在本地开一个服务,诸如vnc之类,映射到内网,让学校的ip能够访问到。

实现

Virt-manager

  我的YogaSlim7上虚拟机是使用kvm/qemu的,guest管理使用virsh/libvirt,GUI则是使用Virt-manager。目前来看,如果仅仅是使用虚拟机,一切繁杂的细节都被隐藏了,体验很棒。

virt-manager.png
virt-manager.png

  首先进入win11,需要给它两张网卡,分别分配到两个虚拟网络:

  一是Host-only(Isolate)网络,用来专门处理Host处需要访问校内网络的请求,将EasyConnect创建的虚拟工具网卡共享给这个网段对应的网卡,从而实现请求的转发;

Host-Only: The VM will be assigned a IP which is only accessible by the host machine where the VM is running on. Only the host machine can talk to the VM, no other host can access it.

  这里需要注意的是,这个网络需要给成192.168.137.0/24,因为windows下共享网络的默认ip为192.168.137.1,想要修改需要通过注册表或者其他一些比较麻烦的方式,而且目前来讲没有修改的需求,于是就将Host-only网段设成这个。

virtual_network.png
virtual_network.png

  二是NAT或者Bridge网络,这是EasyConnect的出口网络,请求直接到达学校的VPN入口;启动EasyConnect,登录上学校的认证系统,关闭windows的防火墙,虚拟机里面就准备好了。

shortcut_1.png
shortcut_1.png

Route Configuration

  在外部的host,需要将Host所有保留的私有地址10.0.0.0/8全部往网段192.168.137.1上发,同时包括学校的ip段202.117.56.0/24。这里直接通过修改路由表实现:

~
❯ sudo ip r list                                 
default via 192.168.0.1 dev wlp1s0 proto dhcp src 192.168.0.7 metric 600 
10.0.0.0/8 via 192.168.137.1 dev virbr1 linkdown 
192.168.0.0/24 dev wlp1s0 proto kernel scope link src 192.168.0.7 metric 600 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown 
192.168.137.0/24 dev virbr1 proto kernel scope link src 192.168.137.5 linkdown 
202.117.56.0/24 via 192.168.137.1 dev virbr1 linkdown 

  至此,已经可以实现在host直接通过内网ip地址访问到学校内部的服务器了~

OpenSSH

  SSH主要被用来作为远程控制工具使用,之前我还发现其实OpenSSH还是有很强大的端口服务映射功能。这里主要介绍两个十分好用的功能:

加密SOCKS通道

This is highly useful for laptop users connected to various unsafe wireless connections. The only thing you need is an SSH server running at a somewhat secure location, like your home or at work. It might be useful to use a dynamic DNS service like DynDNS so you do not have to remember your IP-address.

  说白了,就是当你拿着你的笔记本,在你不信任的网络环境里,可以通过SSH构建一个加密的安全通道,使用远程的服务器进行网络活动。特殊场景包括但不限于临时翻墙救急。

具体使用是通过OpenSSH的Dynamic Port Forwarding功能:

ssh -D localhost:8000 DEST_NAME:DEST_PORT

这个命令的意思就是在本地的8000端口建立到目标服务器的监听转发服务,把localhost改成"*"可以支持所有的SOCKET来源的请求,包括本地局域网。

Forwarding Ports

  在SOCKS之外,OpenSSH也可以加密任何基于TCP的通道,双向支持端口映射。也就是,本地的服务端口可以映射到远程,远程的端口也可以映射到本地。例如,通过加-L指示将对本地的端口的访问请求forward到远程服务器上对应的端口,-R则表示反过来的过程。本地和远程的端口指定的格式如:<tunnel address>:<tunnel port>:<destination address>:<destination port>

一个例子如:

ssh -L 5000:192.168.0.3:6000 user@localpotato

  就表示将本地localhost对5000的访问请求,通过ssh建立的安全信道,转发到192.168.0.3的6000端口上。

  -R选项常常用于服务器上没配置代理,但是又需要突破gfw,就可以通过opnssh临时走本地已经配置好的透明代理。另外,还有一个常用的场景是,笔记本连校园无线网,没有校内的静态ip,想要在本地向内网开启一个vnc服务实现协作,就可以将对应的vnc端口port到拥有静态ip的工位主机上。

  另外值得一说的是,在sshd server端,需要正确开启GatewayPorts,以便远端非localhost(同一网段的其他设备)可以访问到ssh维护的这个映射服务。

SSH Proxy

  最近学校网络收紧,SSLVPN入口只放行发给22和3389端口的请求,这个时候使用SSH的Dynamic Port Forwarding就很有用了,可以通过走ssh(22端口)的SOCKS代理来实现对校内资源的访问。

  与此同时,在校园网内不同的服务器机房也有网关限制,比如我就遇到了服务器不让22请求的出口访问这种情况。这时候就需要让SSH也走代理,具体方法是:

ssh USER@DEST_NAME -o ProxyCommand="nc -X connect -x PROXY_NAME:PROXY_PORT %h %p"

这里的connect可以换成45,分别是让nc走HTTP、SOCKS4、SOCK5协议的代理。