远程登录家用电脑

我在家里有多台机器,我想在学校使用SSH和VNC访问它们。为了实现这一点,我给它们分配了静态IP地址:
  • 192.168.1.50:Windows
  • 192.168.1.51:Ubuntu
  • 192.168.1.52:Raspberry Pi / Raspbian
我知道SSH使用端口22,所以我可以将此端口转发到我的路由器上的192.168.1.51:22,但这样我将无法通过SSH连接到我的Raspberry Pi。有没有办法设置这个来同时访问这两台机器?

10你可以使用不同的SSH端口。我不知道在Windows上有多困难,但在Linux上非常容易更改为非标准端口。这样,你可以将端口22转发到Windows机器(无需更改),将另一个端口(非标准)转发到RaspberryPi。 - bistoco
@bistoco 另一方面也值得一提:为什么将SSH放在22端口以外是个坏主意 - Melebius
2@Melebius,这篇文章虽然有些陈旧,但仍然是一篇很好的阅读材料。对我来说,其中关键的部分是“我试图提出的基本论点:不要依赖安全性通过混淆来保护。” 这是关于需求和简单解决方案的问题。话虽如此,也许他不需要改变Ubuntu或树莓派的端口,只需将不同的路由器端口转发到每个22号机器的端口即可。 - bistoco
1@bistoco 同意。但是,OP打算将SSH访问暴露给外部世界,安全性在这种情况下必须始终被考虑到。此外,设置不同的计算机端口并不能解决OP的问题,因为他/她需要在路由器上启用不同的端口(即端口转发)。 - Melebius
有些供应商愿意以一小笔费用为您提供多个IPv4地址的L2TP服务。这就是我目前在家中使用的方式。 - André Borie
6@Melebius 话题有点偏离,但我从不使用22端口,因为自动化机器人会不断攻击我的服务器。虽然这不能阻止真正的攻击者(或写得好的脚本),但它确实减少了我的日志记录数量。 - Kaz Wolfe
4你可以直接连接其中一个(即公共可访问的),然后从这个连接使用本地地址连接其他的。 - tkausl
请注意:192.168.x.y的IP地址无法从外部世界访问。192.169和类似的地址是局域网内部使用的。您必须通过公共面向外部的IP地址进行连接,其他人可能提到的例如"whatismyip"。不确定之前的评论是否清楚表达了这一点。其他问题:如果以这种方式连接,您可能会违反与互联网服务提供商的用户协议。出于其他人提到的安全问题,我绝对不会这样做。 - user597253
1如果您将您的个人电脑暴露在互联网SSH访问之下,一种简单且安全的方法是禁用来自互联网的密码访问,并仅允许使用授权密钥进行访问,以确保只有您能够访问该设备。唯一的缺点(据我所知)是,您需要为每台您希望用于访问网络的外部计算机手动添加一个密钥(在家中)。 - sig_seg_v
如果你需要使用替代端口来保证安全性,那么这并不是真正的“安全通过混淆”。因为安全并不是你的限制条件,而是资源(端口号)。我建议使用denyhosts或fail2ban。除非你非常小心地保管好授权密钥,否则我不建议使用授权密钥,不要将其留在学校电脑上。无论如何,我总是在22号端口上设置一个诱饵,让机器人去找,同时限制这些端口的开放时间窗口。 - mckenzm
5个回答

如果您使用IPv6,您甚至不需要端口转发!只需获取您的永久IPv6地址(基于您的MAC地址,所以它保证保持不变,除非您的ISP不知道IPv6是如何工作的),然后使用它进行隧道连接。由于您的IPv6地址面向公众,并允许全球访问,无需经过本地NAT,因此您无需在任何地方启用端口转发。它会“自动运行”。
但请注意,全球仍然不完全支持IPv6,您的家庭互联网连接和远程互联网连接都需要完全支持IPv6才能实现此操作。
然而,如果您像大多数人一样只有IPv4,仍然有解决办法!某些路由器允许您将特定的源端口转发到特定的目标端口,操作方式如下:

enter image description here

在这个例子中,端口22直接传递到我的机器sheepdog,而端口292被转发到coyote上的端口22
最后,如果您的路由器没有此功能,您可以更改端口,因为SSH不仅限于在端口22上运行。您可以将其设置为任何您想要的(未被使用的)端口。
/etc/ssh/sshd_config文件中(需要root权限进行编辑,因此使用sudo nano /etc/ssh/sshd_config命令),文件顶部有一行:
# What ports, IPs and protocols we listen for
Port 22

将此更改为您想要的任何内容:

# What ports, IPs and protocols we listen for
Port 2992

重新启动SSH服务器,使用sudo service ssh restart命令,并在路由器上转发端口。
然而,对于这种使用情况,我会考虑一下是否使用SSH隧道是正确的选择。也许你应该在家庭网络上设置一个专用的VPN服务器?这将允许您从任何地方访问您的整个家庭网络,前提是您具备VPN所需的适当安全凭据。此外,使用VPN的开销稍微小一些;通常只需要转发一个端口给一台机器即可。

2如果您的互联网服务提供商不支持IPv6,您可以使用IPv6隧道代理来获取IPv6地址。 - André Borie
1你所说的“这个功能”,是指将一个端口转发到另一个端口吗? - Liu Siyuan
@LiuSiyuan 是的。我知道这很奇怪,但我见过一些路由器处理不了这个问题。我的旧的ISP提供的路由器甚至都无法尝试。 - Kaz Wolfe
没太明白IPv6那部分。我们可以假设所有提供IPv6地址的互联网服务提供商为网络上的每个设备提供一个(一致)不同的地址吗? - jjmontes
1@jjmontes 如果你的ISP很有能力,你将会获得一个完整的/64(或者可能更少,但仍足够为每台机器分配一个) - Kaz Wolfe

解决这个问题的简单方法是将路由器上的不同端口映射到您机器的22号端口。例如,您可以在路由器上进行以下设置(假设您的路由器IP为1.2.3.4):
1. 1.2.3.4:22   --> ubuntu:22
2. 1.2.3.4:8888 --> raspberrypi:22
3. 1.2.3.4:9999 --> windows:22 (or some other port)

然后当你使用ssh时,通过输入以下命令来指定要使用的端口
$ ssh <username>@<router ip> -p <your port>

现在你应该能够连接到你的所有机器了。

如果你知道你的一台电脑始终处于开机状态,你也可以将其用作ssh代理。假设你为你的外部IP地址设置了一个域名(例如myhome.dyndns.com或其他),你需要在一台电脑上连接(比如树莓派始终处于开机状态,并将端口从路由器转发到它),然后你的ssh连接将是这样的:
学校 --> (路由器,在此处透明) --> 树莓派 --> Ubuntu或Windows
现在,在你的~/.ssh/config文件中添加以下行:
Host ubuntu 192.168.1.51
    Hostname ubuntu (change to match your setup)
    User myraspberryuser  (change it ;-) )
    IdentityFile ~/.ssh/id_rsa   (The path to your private key, on the school computer, better on an usb key if public computer)
    ForwardAgent yes
    RequestTTY yes
    ProxyCommand ssh -W %h:%p %r@myhome.dyndns.com

连接的话:
ssh-add ~/.ssh/id_rsa # to do only once per session
ssh myuser@ubuntu (login without password)

从现在开始,如果你输入ssh ubuntu,计算机将首先连接到树莓派,然后启动一个ssh会话到ubuntu计算机。
我建议你,无论你选择哪个端口进行转发,在/etc/sshd.conf中禁用密码,只允许通过ssh密钥登录。这样,如果你在树莓派和ubuntu上设置了密钥,并使用参数'ForwardAgent',你只需要解锁密钥,就不需要密码连接。这样,即使有机器人试图登录你的ssh,他们也永远无法登录,因为你禁止了密码登录。
额外奖励,这也适用于scp,scp foo ubuntu:/tmp/foo将使用相同的设置,无需其他参数。 额外奖励2,这个设置不需要在家里做任何改变,如果明天你换了一台电脑,只需复制/粘贴代码到你的ssh配置文件中,更改主机和IP,就完成了,无需在路由器上打开新的端口。

使用机器作为SSH的中间件有什么不利之处吗?假设我使用我的树莓派连接网络内的其他计算机,它的性能会影响任务吗? - TSpark
1是的,树莓派可能限制吞吐量,因为它必须同时充当服务器和客户端。如果你有足够的信心,你可以通过SSH隧道实现相同的结果。这样,树莓派只作为服务器,但你的学校电脑必须扮演两个客户端的角色。 - potens

我这样做——我一直让树莓派保持开启并直接插入路由器(因为它是最省电的),然后通过SSH登录,再从树莓派跳转到其他设备——它几乎不需要太多关注。
还可以通过SSH管道VNC/RDP一个图形界面,有点有趣,或者转发一个端口,让你在桌面电脑上浏览服务器而保持私密性。
我之所以添加这个答案是给你一些建议。
1)使用与22端口不同的端口。你可以将树莓派上的端口保持为22,但是将路由器上的传入端口改为10,000以上的某个端口……否则,你每天会遭受数十到数百次攻击——一旦人们知道你在运行SSH主机,一旦发现漏洞,你就会被攻破。
2)使用证书而不是用户名/密码——完全禁用用户名/密码登录。
3)如果你的IP地址可能会变化,使用动态DNS服务获取一个DNS主机名(我使用noip,它是免费的,并且他们支持Linux客户端来更新你的IP地址——我想你现在可以在树莓派上通过apt-get安装)。还有一些其他公司也提供免费的这种服务。
4) 保持您的树莓派(或者您要通过ssh连接的任何设备)更新(使用sudo apt-get update命令)。我相信ssh现在已经经过了很好的验证,但是我之前也曾这样认为https...

在发布这个回答之前,我曾经犹豫过是否应该将其作为评论而不是回答。但无论如何,我还是决定在这里发布。
在你开始做这件事之前,有一些事情你应该考虑:
你将会把你的系统开放给互联网,所以最好确保它们已经打了补丁,并且你的安全配置已经加固(例如,不允许root登录,使用公钥而不是密码)。
你的公共IP地址(参见whatismyip.com)可能会变化,取决于你的ISP,它可能每天都会变化,也可能几乎不会变。这意味着你需要找到一种方法来确定你的公共IP地址。你可以每天从家庭网络访问whatismyip.com,创建一些应用程序,或者使用动态DNS(DynDNS)将你变化的公共IP映射到一个静态域名。
如果你想使用IPv6来避免与IPv4和NAT相关的所有麻烦,你的设备、路由器、ISP等都需要支持IPv6。当你的ISP不支持IPv6时,有一些服务可以帮助你,但你的设备和路由器无论如何都必须支持IPv6。
你向互联网开放的端口和设备越多,你的攻击面就越大。我建议在你的网络中使用一个跳板机,并只允许从互联网访问该设备的SSH。跳板机基本上是一个非常强化的系统,你通过路由器将其端口转发到互联网。一旦连接到该跳板机,你就可以通过它SSH到你的内部网络。跳板机基本上可以是另一个树莓派。我建议使用专用设备,以便尽可能加固它(包括尽可能少运行服务)。
(4a)除了使用跳板机进行SSH连接外,你还可以设置一个VPN服务器,允许你从学校的设备上浏览你的家庭网络(如果允许出站VPN连接)。