如何在单个 ssh 命令中结合使用 SSH 和 VPN?

如何在单个 ssh 命令中结合使用 SSH 和 VPN?

在我的设置中,首先我需要连接到 VPN,然后我需要通过 ssh 进入服务器。

目前我确实喜欢这个:

openvpn myconfig.ovpn
ssh myuser@myserver

这使得我的所有网络流量都通过该VPN。

然而,我确实不是希望我的所有数据流量都通过此 VPN。使用 GNU/Linux,我可以使用哪些工具仅在一个特定的 ssh 连接中使用 VPN?

也就是说,我可以使用哪些工具放入 Bash 脚本中来执行以下操作:

ssh-over-vpn.sh myuser.ovpn [email protected]

并仅将 vpn 配置用于 ssh 连接[电子邮件保护]

我当前的 myuser.ovpn 配置文件有:

client                                                                                                                                                                                        
dev tun
proto udp
sndbuf 0
rcvbuf 0
remote 200.200.200.18 443
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-GCM
setenv opt block-outside-dns
key-direction 1
verb 3
<ca> ... </ca> <cert> ...<key> ...<tls-auth> ...

答案1

但是,我不希望所有数据流量都通过此 VPN。使用 GNU/Linux,我可以使用哪些工具仅在一个特定的 ssh 连接中使用 VPN?

将您的 OpenVPN 客户端配置更改为不是从服务器拉取“默认”路线;而是仅指定所需的路线:

route-nopull
route 10.0.0.66 255.255.255.255 vpn_gateway

也就是说,我可以使用哪些工具放入 Bash 脚本中来执行以下操作:

可供选择的不多。对于 SOCKS 代理(例如 torify),类似的工具相对容易使用,因为传输层隧道直接映射到包装程序创建的套接字 - 它变得一点点IP 层隧道(VPN)更加困难,因为除了重新实现实际的 OpenVPN 协议之外,包装工具还需要重新实现大部分操作系统的网络堆栈(生成 IP 数据包、将接收到的数据包映射到模拟套接字......)。

最接近您可以使用的是网络命名空间(容器的构建块之一)为程序提供了一组完全独立的接口和路由表。使用unshare或创建网络命名空间ip netns并在其中运行程序很容易,但默认情况下它们是断开连接的(openvpn 客户端无法访问服务器),因此您还需要使用 veth 等将其链接到“主”命名空间。

所有这些命名空间设置最终都会重新实现 Docker/nspawn/etc 的部分内容,因此可能只需启动一个运行 OpenVPN 客户端和 SSH 客户端的 Docker 容器即可。

答案2

因此 VPN 本质上无法感知第三层以上的任何信息OSI 模型,这意味着他们看不到正在使用的端口或协议。也许可以通过一些防火墙魔法来实现所需的效果,但我建议您直接使用 SSH。

我假设所有涉及的系统和网络都由您拥有和管理。如果配置正确,SSH 是一种非常安全的协议,在互联网上使用应该和 openvpn 一样安全。有一些很棒的指南有关于“强化” openssh 的信息。其他一些安全建议:

  • 将服务器端口更改为不明显的端口。这实际上并没有使其本身更“安全”,但它确实减少了用失败的登录尝试充斥日志的网络抓取机器人的数量。几年前我这样做过,从那以后我再也没有见过一次尝试。
  • 查看 fail2ban。这是一个非常方便的软件,它可以监控登录尝试,并在多次失败后通过在 iptables 中添加防火墙规则来“禁止” IP 地址访问您的服务器。它非常棒。

完成后,您可以使用 openssh 中的 ProxyJump 配置选项将该连接用作 LAN 上其他连接的隧道。

希望这可以帮助!

相关内容