主机和客户端 Ubuntu 19.04。开放SSH
我的家庭 LAN 中有一个 SSH 服务器,我使用 LAN 网络地址将其安装到我的笔记本电脑上。当我在周末度假时,我必须更改 fstab 以通过路由器的外部 IP 地址进行安装。
我的路由器不支持环回,因此当我在 LAN 中时无法使用外部 IP。
我的方法是在 fstab 中保留两个部分。一种用于 LAN,一种用于外部 IP。然后我注释掉 fstab 行以适合我的位置。
我想知道是否有更好的方法。
我能将两个部分保持打开状态。我使用该nofail
选项,因此启动过程不会中止,但启动速度非常慢。我尝试添加ConnectionTimeout=5
sshfs 选项,但这并不能改善启动时间。
显然这不是一个关键问题,只是一个可有可无的问题。一些有条件的安装?或者也许设置超时并不像我想象的那么简单。
后来:经过一些查看:
根据Archemar和muru的建议,我正在研究systemd初始化以创建一个fork来指导安装过程。
我的理论(纯粹是基于阅读文档的推测——没有实验)是mount
通过--fstab
选项将命令引导到该位置的 fstab。
建立位置的一种方法是读取网络设备 IP。我的 LAN DHCP 将分配 10.0.0.120。任何其他 IP 地址都强烈表明我正在连接到 LAN 以外的某个网络。不完全可靠,但对于非关键应用来说足够好。如果有更可靠的方法我很高兴听到。
我现在陷入了定位 systemd 挂载服务以及在 systemd init 中调用该服务的位置。
我先看在/lib/systemd/
.该目录主要包含 systemd 可执行文件和一些目录。这些目录之一system-generators
包含一个有前途的文件systemd-fstab-generator
。这是一个可执行文件,所以我正在寻找,我猜测conf
为此的文件。
这是我到目前为止所得到的。我稍后会回来发布更多内容,但与此同时,我会感谢任何提示、警告、警报......
答案1
我没有等效的设置来测试,但我想象该设置的工作方式如下。
首先,拆下该安装座的线路/etc/fstab
。
然后,每个服务和安装都会有几个,如下所示。
对于内部网络:
/etc/systemd/system/int-ip-check.service
:[Unit] Description=Check for internal network Type=oneshot Requires=NetworkManager-wait-online.service After=NetworkManager-wait-online.service OnFailure=ext-ip-check.service Conflicts=ext-ip-check.service Wants=int-ip.mount Before=int-ip.mount [Service] ExecStartPre=<command to check for internal network> RemainAfterExit=yes [Install] WantedBy=default.target
/etc/systemd/system/int-ip.mount
:[Unit] Documentation=SSHFS mount (internal IP) PartOf=int-ip-check.service [Mount] Where=/some/path What=user@int-ip:/some/path Type=fuse.sshfs Options=noauto,_netdev,...
对于外部网络:
/etc/systemd/system/ext-ip-check.service
:[Unit] Description=Check for external network Type=oneshot Requires=NetworkManager-wait-online.service After=NetworkManager-wait-online.service Wants=ext-ip.mount Before=ext-ip.mount [Service] ExecStartPre=<command to check for external network> RemainAfterExit=yes
/etc/systemd/system/ext-ip.mount
:[Unit] Documentation=SSHFS mount (external IP) PartOf=ext-ip-check.service [Mount] Where=/some/path What=user@int-ip:/some/path Type=fuse.sshfs Options=noauto,_netdev,...
所以这里的排序是这样的:
- 两个挂载点都是
PartOf
各自的检查服务。因此,如果检查服务停止或重新启动,安装也会停止或重新启动。 - 两个检查服务都需要各自的挂载(因此启动它们也会导致挂载启动),但在启动后才启动挂载。
- 两个检查服务都需要并在之后启动
NetworkManager-wait-online
- 在 Ubuntu 上,这应该使它们等待某个网络设备在线。 - 检查服务互相冲突(如果启动一个,则停止另一个)。
- 如果第一个检查失败,则启动另一个检查。
- 内部网络检查默认设置为启动(
WantedBy=default.target
) - 两个检查都具有
RemainAfterExit=yes
,以便在检查命令退出后它们保持活动状态(并且不会停止)(在本例中需要这样做Type=oneshot
)。他们必须失败或停止才能停止坐骑。
那么流程应该如下所示:
- 网络上线后,内部 IP 检查开始。
- 如果成功完成,内部安装应该启动并运行良好(否则它将因
PartOf
)而停止。 - 如果失败,则开始外部 IP 检查。相应地,外部挂载应在检查后启动并运行。
当您切换网络时,您可能能够启动相应的检查服务以卸载其他服务。
您必须在这里处理依赖项,但希望这将是一个不错的起点。
一个潜在的变化:您可能想要使用or来代替Type=oneshot
and ,并且可能有一个命令定期检查网络是否正确(例如 shell 循环)。RemainAfterExit
Type=simple
Type=forking
答案2
您可以对挂载级别透明地执行此操作,并在~/.ssh/config
级别上执行到 2 个不同主机名的网络重定向。
对于~/.ssh/config
安装用户:
Match host MyServerAlias exec "<shell command to return true if in local LAN>"
Hostname Local.IP.or.hostname
Host MyServerAlias
Hostname external.hostname
Port <External Port for SSH-Forward on Home Router>
这样,在安装时,您只需使用一行主机名MyServerAlias
,ssh 层就会自动连接到正确的 ssh URI。
神奇之处在于Match
关键字,它可以链接一系列 shell 命令,并且仅当 shell 链返回时才应用后面块的行true
。
您可以在匹配行中使用egexec "timeout 0.4 nc -z %h %p 2>/dev/null"
来检查MyServerAlias的本地IP和端口是否可达。
自从ssh
有了match
.
通过afuse+sshfs
自动安装程序设置Systemd 用户单元(或者通过~/.profile)非常适合在笔记本电脑上使用。 (并且没有摆弄fstab
)