您想在工作中使用 Linux,但您的公司 VPN 不允许吗? 那么这篇文章可能会有所帮助,尽管这还不确定。 我想提前警告您,我不太了解网络管理问题,因此有可能我做错了一切。 另一方面,我也有可能写出一个普通人可以理解的指南,所以我建议你尝试一下。
这篇文章包含很多不必要的信息,但如果没有这些知识,我将无法解决设置 VPN 时意外出现的问题。 我认为任何尝试使用本指南的人都会遇到我没有遇到的问题,我希望这些额外的信息将有助于他们自己解决这些问题。
本指南中使用的大多数命令都需要通过 sudo 执行,为简洁起见,已将其删除。 记住。
大多数IP地址都被严重混淆了,所以如果您看到像435.435.435.435这样的地址,那么那里一定有一些正常的IP,特定于您的情况。
我有 Ubuntu 18.04,但我认为只需稍加修改,该指南就可以应用于其他发行版。 然而,在本文中,Linux == Ubuntu。
Cisco Connect
使用 Windows 或 MacOS 的用户可以通过 Cisco Connect 连接到我们的企业 VPN,需要指定网关地址,并且每次连接时输入由固定部分和 Google Authenticator 生成的代码组成的密码。
就 Linux 而言,我无法运行 Cisco Connect,但我设法在 google 上搜索到了使用 openconnect 的建议,该建议是专门用来替代 Cisco Connect 的。
开放连接
理论上,Ubuntu有一个专门的openconnect图形界面,但它对我不起作用。 也许是为了更好。
在 Ubuntu 上,openconnect 是从包管理器安装的。
apt install openconnect
安装后,您可以立即尝试连接VPN
openconnect --user poxvuibr vpn.evilcorp.com
vpn.evilcorp.com 是虚构 VPN 的地址
poxvuibr - 虚构的用户名
openconnect 会要求您输入密码,我提醒您,该密码由固定部分和来自 Google Authenticator 的代码组成,然后它将尝试连接到 VPN。 如果它有效,那么恭喜你,你可以安全地跳过中间的过程,这很痛苦,然后继续讨论 openconnect 在后台运行的问题。 如果不起作用,那么您可以继续。 尽管如果它在连接时有效,例如,通过工作时的访客 Wi-Fi 连接,那么现在高兴可能还为时过早;您应该尝试在家中重复该过程。
证明书
很可能什么都不会启动,并且 openconnect 输出将如下所示:
POST https://vpn.evilcorp.com/
Connected to 777.777.777.777:443
SSL negotiation with vpn.evilcorp.com
Server certificate verify failed: signer not found
Certificate from VPN server "vpn.evilcorp.com" failed verification.
Reason: signer not found
To trust this server in future, perhaps add this to your command line:
--servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress
一方面,这是令人不快的,因为没有连接到 VPN,但另一方面,原则上如何解决这个问题是明确的。
在这里,服务器向我们发送了一个证书,通过该证书,我们可以确定连接是与我们本地公司的服务器建立的,而不是与邪恶的欺诈者建立的,并且该证书对于系统来说是未知的。 因此她无法检查服务器是否真实。 因此,为了以防万一,它会停止工作。
为了让 openconnect 连接到服务器,您需要使用 —servercert key 明确告诉它哪个证书应该来自 VPN 服务器
您可以从 openconnect 打印的内容中找到服务器直接发送给我们的证书。 这是这篇文章的内容:
To trust this server in future, perhaps add this to your command line:
--servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress
使用此命令您可以尝试再次连接
openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr vpn.evilcorp.com
也许现在它正在发挥作用,那么你就可以继续进行到底了。 但就个人而言,乌本塔向我展示了这种形式的无花果
POST https://vpn.evilcorp.com/
Connected to 777.777.777.777:443
SSL negotiation with vpn.evilcorp.com
Server certificate verify failed: signer not found
Connected to HTTPS on vpn.evilcorp.com
XML POST enabled
Please enter your username and password.
POST https://vpn.evilcorp.com/
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 300, Keepalive 30
Set up DTLS failed; using SSL instead
Connected as 192.168.333.222, using SSL
NOSSSSSHHHHHHHDDDDD
3
NOSSSSSHHHHHHHDDDDD
3
RTNETLINK answers: File exists
/etc/resolvconf/update.d/libc: Warning: /etc/resolv.conf is not a symbolic link to /run/resolvconf/resolv.conf
/ etc / resolv.conf中
# Generated by NetworkManager
search gst.evilcorpguest.com
nameserver 127.0.0.53
/run/resolvconf/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 192.168.430.534
nameserver 127.0.0.53
search evilcorp.com gst.publicevilcorp.com
habr.com 将会解决,但您将无法前往那里。 像 jira.evilcorp.com 这样的地址根本无法解析。
我不清楚这里发生了什么。 但实验表明,如果您将这一行添加到 /etc/resolv.conf
nameserver 192.168.430.534
然后 VPN 内的地址将开始神奇地解析,您可以浏览它们,也就是说,DNS 正在寻找的解析地址专门在 /etc/resolv.conf 中查找,而不是在其他地方。
您可以验证是否存在与 VPN 的连接并且它可以正常工作,而无需对 /etc/resolv.conf 进行任何更改;为此,只需在浏览器中输入其 IP 地址,而不是来自 VPN 的资源的符号名称
这样一来,就有两个问题
- 连接到 VPN 时,未获取其 dns
- 所有流量都通过VPN,不允许访问互联网
我会告诉你现在该怎么做,但首先是一点自动化。
自动输入密码的固定部分
到目前为止,您很可能已经输入了至少五次密码,而这个过程已经让您疲惫不堪。 一是因为密码长,二是因为输入时需要契合固定的时间段
该问题的最终解决方案并未包含在文章中,但您可以确保密码的固定部分不必输入多次。
假设密码的固定部分是fixedPassword,来自Google Authenticator的部分是567 987。可以使用参数 --passwd-on-stdin 通过标准输入将整个密码传递给 openconnect 。
echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr vpn.evilcorp.com --passwd-on-stdin
现在,您可以不断返回到最后输入的命令,并仅更改其中的部分 Google 身份验证器。
企业 VPN 不允许您上网。
一般来说,当你必须使用单独的计算机去哈布尔时,这并不是很不方便。 无法从 stackoverfow 进行复制粘贴通常会导致工作瘫痪,因此需要采取一些措施。
我们需要以某种方式组织它,以便当您需要从内部网络访问资源时,Linux 会转到 VPN,而当您需要访问 Habr 时,它会转到 Internet。
openconnect 在启动并与 vpn 建立连接后,会执行一个特殊的脚本,该脚本位于 /usr/share/vpnc-scripts/vpnc-script 中。 一些变量作为输入传递给脚本,并配置 VPN。 不幸的是,我无法弄清楚如何使用本机脚本在企业 VPN 和互联网其他部分之间分配流量。
显然,vpn-slice 实用程序是专门为像我这样的人开发的,它允许您通过两个通道发送流量,而无需手鼓跳舞。 嗯,也就是说,你必须跳舞,但你不必成为萨满。
使用 vpn-slice 进行流量分离
首先,你必须安装 vpn-slice,你必须自己解决这个问题。 如果评论里有问题,我会单独写一篇文章讨论这个问题。 但这是一个常规的Python程序,所以应该不会有任何困难。 我使用 virtualenv 安装。
然后必须使用 -script 开关应用该实用程序,指示 openconnect 需要使用 vpn-slice,而不是标准脚本
echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 192.168.430.0/24 " vpn.evilcorp.com
--script 传递一个字符串,其中包含需要调用的命令而不是脚本。 ./bin/vpn-slice - vpn-slice 可执行文件的路径 192.168.430.0/24 - vpn 中要访问的地址掩码。 这里,我们的意思是,如果地址以192.168.430开头,那么需要在VPN内部搜索该地址的资源
现在的情况应该差不多正常了。 几乎。 现在你去Habr可以通过ip去企业内部资源,但是不能通过符号名去企业内部资源。 如果您在主机中指定符号名称和地址之间的匹配,则一切都应该有效。 并一直工作直到ip改变。 Linux 现在可以访问 Internet 或 Intranet,具体取决于 IP。 但仍使用非企业 DNS 来确定地址。
问题还可以通过这种形式表现出来——在工作中一切都很好,但在家里你只能通过IP访问公司内部资源。 这是因为当您连接到公司 Wi-Fi 时,也会使用公司 DNS,并在其中解析来自 VPN 的符号地址,尽管事实上不使用 VPN 仍然无法访问此类地址。
自动修改hosts文件
如果礼貌地询问 vpn-slice,则在启动 VPN 后,它可以转到其 DNS,通过符号名称找到必要资源的 IP 地址,并将其输入到主机中。 关闭 VPN 后,这些地址将从主机中删除。 为此,您需要将符号名称作为参数传递给 vpn-slice。 像这样。
echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
现在一切都应该在办公室和海滩上都能正常工作。
在VPN给出的DNS中搜索所有子域的地址
如果网络内的地址很少,那么自动修改hosts文件的方法就很有效。 但如果网络上有很多资源,那么您将不断需要在脚本中添加像 zoidberg.test.evilcorp.com 这样的行,zoidberg 是其中一个测试平台的名称。
但现在我们已经了解了为什么可以消除这种需求了。
如果在启动 VPN 后,您查看 /etc/hosts,您可以看到这一行
192.168.430.534 dns0.tun0 # vpn-slice-tun0 自动创建
并在 resolv.conf 中添加了新行。 简而言之,vpn-slice 以某种方式确定了 vpn 的 dns 服务器所在的位置。
现在我们需要确保,为了找到以evillcorp.com 结尾的域名的IP 地址,Linux 会访问公司DNS,如果需要其他内容,则访问默认DNS。
我在 Google 上搜索了一段时间,发现 Ubuntu 中已经提供了这样的功能。 这意味着能够使用本地 DNS 服务器 dnsmasq 来解析名称。
也就是说,您可以确保Linux始终向本地DNS服务器查找IP地址,而本地DNS服务器又会根据域名在相应的外部DNS服务器上查找IP。
为了管理与网络和网络连接相关的所有内容,Ubuntu 使用 NetworkManager,而用于选择(例如 Wi-Fi 连接)的图形界面只是它的前端。
我们需要爬升它的配置。
- 在 /etc/NetworkManager/dnsmasq.d/evilcorp 中创建文件
地址=/.evilcorp.com/192.168.430.534
注意evilcorp前面的点。 它向 dnsmasq 发出信号,应在公司 dns 中搜索 evilcorp.com 的所有子域。
- 告诉 NetworkManager 使用 dnsmasq 进行名称解析
网络管理器配置位于 /etc/NetworkManager/NetworkManager.conf 您需要在那里添加:
[主要] dns=dnsmasq
- 重新启动网络管理器
service network-manager restart
现在,使用 openconnect 和 vpn-slice 连接到 VPN 后,即使您没有将符号地址添加到 vpnslice 的参数中,也会正常确定 IP。
如何通过VPN访问个人服务
成功连接VPN后,我高兴了两天,然后发现,如果我从办公室网络外连接VPN,那么邮件就不能用了。 这个症状很熟悉,不是吗?
我们的邮件位于mail.publicevilcorp.com,这意味着它不属于dnsmasq的规则,并且邮件服务器地址是通过公共DNS搜索的。
嗯,办公室仍然使用 DNS,其中包含这个地址。 和我想的一样。 事实上,将行添加到 dnsmasq 后
地址=/mail.publicevilcorp.com/192.168.430.534
情况根本没有改变。 ip保持不变。 我必须去上班。
后来,当我深入了解情况并稍微了解了问题后,一位聪明的人告诉我如何解决。 不仅需要通过VPN连接到邮件服务器
我使用 vpn-slice 通过 VPN 访问以 192.168.430 开头的地址。 而且邮件服务器不仅有一个不是evilcorp子域的符号地址,而且也没有以192.168.430开头的IP地址。 当然,他也不允许总网的人来找他。
为了让 Linux 通过 VPN 到达邮件服务器,您还需要将其添加到 vpn-slice。 假设邮寄者的地址是 555.555.555.555
echo "fixedPassword567987" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 555.555.555.555 192.168.430.0/24" vpn.evilcorp.com
通过一个参数提升 VPN 的脚本
当然,这一切并不是很方便。 是的,您可以将文本保存到文件中并将其复制粘贴到控制台中,而不是手动输入,但这仍然不是很愉快。 为了使该过程更容易,您可以将该命令包装在位于 PATH 中的脚本中。 然后您只需要输入从 Google Authenticator 收到的代码
#!/bin/sh
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444 --user poxvuibr --passwd-on-stdin
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
如果你把脚本放在 connect~evilcorp~ 中,你可以简单地在控制台中编写
connect_evil_corp 567987
但现在由于某种原因你仍然必须保持运行 openconnect 的控制台打开
在后台运行 openconnect
幸运的是,openconnect的作者很照顾我们,给程序添加了一个特殊的键——background,使得程序启动后在后台工作。 如果你像这样运行它,你可以在启动后关闭控制台
#!/bin/sh
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
--user poxvuibr
--passwd-on-stdin
--background
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
现在还不清楚日志去了哪里。 一般来说,我们并不真正需要日志,但你永远不知道。 openconnect 可以将它们重定向到 syslog,在那里它们将保持安全。 您需要将 –syslog 开关添加到命令中
#!/bin/sh
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
--user poxvuibr
--passwd-on-stdin
--background
--syslog
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
因此,事实证明 openconnect 正在后台某个地方工作,并且不会打扰任何人,但尚不清楚如何阻止它。 也就是说,您当然可以使用 grep 过滤 ps 输出并查找名称包含 openconnect 的进程,但这在某种程度上很乏味。 感谢也思考过这个问题的作者。 Openconnect 有一个关键的 -pid-file,使用它可以指示 openconnect 将其进程标识符写入文件。
#!/bin/sh
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
--user poxvuibr
--passwd-on-stdin
--background
--syslog
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
--pid-file ~/vpn-pid
现在您可以随时使用命令终止进程
kill $(cat ~/vpn-pid)
如果没有进程,kill会诅咒,但不会抛出错误。 如果该文件不存在,那么也不会发生任何不良情况,因此您可以安全地终止脚本第一行中的进程。
kill $(cat ~/vpn-pid)
#!/bin/sh
echo "fixedPassword$1" | openconnect --servercert sha256:4444444444444444444444444444444444444444444444444444444444444444
--user poxvuibr
--passwd-on-stdin
--background
--syslog
--script "./bin/vpn-slice 192.168.430.0/24 jira.vpn.evilcorp.com git.vpn.evilcorp.com " vpn.evilcorp.com
--pid-file ~/vpn-pid
现在您可以打开计算机,打开控制台并运行命令,并向其传递来自 Google Authenticator 的代码。 然后就可以固定控制台了。
没有 VPN 切片。 而不是后记
事实证明,很难理解如何在没有 VPN 切片的情况下生活。 我必须大量阅读和谷歌。 幸运的是,在花了这么多时间解决一个问题之后,技术手册甚至 man openconnect 读起来就像令人兴奋的小说一样。
结果,我发现 vpn-slice 和原生脚本一样,修改了路由表以分离网络。
路由表
简单来说,这是一个表,第一列包含Linux要经过的地址应该从什么开始,第二列包含该地址要经过哪个网络适配器。 其实发言者还多了,但这并没有改变本质。
为了查看路由表,需要运行 ip route 命令
default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600
192.168.430.0/24 dev tun0 scope link
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.534 metric 600
192.168.430.534 dev tun0 scope link
在这里,每一行负责您需要去哪里才能将消息发送到某个地址。 第一个是地址应该从哪里开始的描述。 为了了解如何确定 192.168.0.0/16 意味着该地址应该以 192.168 开头,您需要 google 什么是 IP 地址掩码。 dev 之后是消息应发送到的适配器的名称。
对于VPN,Linux制作了一个虚拟适配器——tun0。 该线路确保以 192.168 开头的所有地址的流量都经过它
192.168.0.0/16 dev tun0 scope link
您还可以使用以下命令查看路由表的当前状态 路线-n (IP 地址被巧妙地匿名化)该命令以不同的形式生成结果,并且通常已被弃用,但其输出通常可以在 Internet 上的手册中找到,并且您需要能够阅读它。
路由的 IP 地址应该从哪里开始可以通过 Destination 和 Genmask 列的组合来理解。 IP 地址中与 Genmask 中的数字 255 相对应的部分会被考虑在内,但 0 的部分则不会被考虑在内。 也就是说,Destination 192.168.0.0 和 Genmask 255.255.255.0 的组合意味着,如果地址以 192.168.0 开头,那么对其的请求将沿着这条路线进行。 如果目标地址为 192.168.0.0 但 Genmask 为 255.255.0.0,则对以 192.168 开头的地址的请求将沿着此路线进行
为了弄清楚 vpn-slice 实际做了什么,我决定查看前后表的状态
没开启VPN之前是这样的
route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 222.222.222.1 0.0.0.0 UG 600 0 0 wlp3s0
222.222.222.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp3s0
333.333.333.333 222.222.222.1 255.255.255.255 UGH 0 0 0 wlp3s0
在没有 vpn-slice 的情况下调用 openconnect 后,它变成了这样
route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 tun0
0.0.0.0 222.222.222.1 0.0.0.0 UG 600 0 0 wlp3s0
222.222.222.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp3s0
333.333.333.333 222.222.222.1 255.255.255.255 UGH 0 0 0 wlp3s0
192.168.430.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.430.534 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
在像这样与 vpn-slice 结合调用 openconnect 之后
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 222.222.222.1 0.0.0.0 UG 600 0 0 wlp3s0
222.222.222.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp3s0
333.333.333.333 222.222.222.1 255.255.255.255 UGH 0 0 0 wlp3s0
192.168.430.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.430.534 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
可以看到,如果不使用vpn-slice,那么openconnect明确写道,所有地址,除了特别指明的,都必须通过vpn访问。
这是:
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 tun0
在它旁边,立即指示另一条路径,如果 Linux 尝试通过的地址与表中的任何掩码都不匹配,则必须使用该路径。
0.0.0.0 222.222.222.1 0.0.0.0 UG 600 0 0 wlp3s0
这里已经写到,在这种情况下您需要使用标准的 Wi-Fi 适配器。
我相信使用了 VPN 路径,因为它是路由表中的第一个路径。
而且理论上,如果从路由表中删除这条默认路径,那么结合 dnsmasq openconnect 应该可以保证正常运行。
我试过了
route del default
一切顺利。
将请求路由到没有 VPN 切片的邮件服务器
但我还有一个地址为555.555.555.555的邮件服务器,也需要通过VPN访问。 到它的路由也需要手动添加。
ip route add 555.555.555.555 via dev tun0
现在一切都很好。 所以你可以不用 vpn-slice,但你需要清楚地知道你在做什么。 我现在正在考虑在本机 openconnect 脚本的最后一行中添加删除默认路由的功能,并在连接到 VPN 后为邮件程序添加一条路由,这样我的自行车中的移动部件就会更少。
也许,这篇后记足以让人们了解如何设置 VPN。 但是,当我试图了解做什么以及如何做时,我阅读了很多对作者有用的此类指南,但由于某种原因对我不起作用,我决定在这里添加我找到的所有内容。 我会对这样的事情感到非常高兴。
来源: habr.com