fstab 中的 sshfs:通过不同网络寻址同一服务器

fstab 中的 sshfs:通过不同网络寻址同一服务器

主机和客户端 Ubuntu 19.04。开放SSH

我的家庭 LAN 中有一个 SSH 服务器,我使用 LAN 网络地址将其安装到我的笔记本电脑上。当我在周末度假时,我必须更改 fstab 以通过路由器的外部 IP 地址进行安装。

我的路由器不支持环回,因此当我在 LAN 中时无法使用外部 IP。

我的方法是在 fstab 中保留两个部分。一种用于 LAN,一种用于外部 IP。然后我注释掉 fstab 行以适合我的位置。

我想知道是否有更好的方法。

将两个部分保持打开状态。我使用该nofail选项,因此启动过程不会中止,但启动速度非常慢。我尝试添加ConnectionTimeout=5sshfs 选项,但这并不能改善启动时间。

显然这不是一个关键问题,只是一个可有可无的问题。一些有条件的安装?或者也许设置超时并不像我想象的那么简单。

后来:经过一些查看:

根据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

然后,每个服务和安装都会有几个,如下所示。

  1. 对于内部网络:

    /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,...
    
  2. 对于外部网络:

    /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,...
    

所以这里的排序是这样的:

  1. 两个挂载点都是PartOf各自的检查服务。因此,如果检查服务停止或重新启动,安装也会停止或重新启动。
  2. 两个检查服务都需要各自的挂载(因此启动它们也会导致挂载启动),但在启动后才启动挂载。
  3. 两个检查服务都需要并在之后启动NetworkManager-wait-online- 在 Ubuntu 上,这应该使它们等待某个网络设备在线。
  4. 检查服务互相冲突(如果启动一个,则停止另一个)。
  5. 如果第一个检查失败,则启动另一个检查。
  6. 内部网络检查默认设置为启动(WantedBy=default.target
  7. 两个检查都具有RemainAfterExit=yes,以便在检查命令退出后它们保持活动状态(并且不会停止)(在本例中需要这样做Type=oneshot)。他们必须失败或停止才能停止坐骑。

那么流程应该如下所示:

  1. 网络上线后,内部 IP 检查开始。
  2. 如果成功完成,内部安装应该启动并运行良好(否则它将因PartOf)而停止。
  3. 如果失败,则开始外部 IP 检查。相应地,外部挂载应在检查后启动并运行。

当您切换网络时,您可能能够启动相应的检查服务以卸载其他服务。

您必须在这里处理依赖项,但希望这将是一个不错的起点。

一个潜在的变化:您可能想要使用or来代替Type=oneshotand ,并且可能有一个命令定期检查网络是否正确(例如 shell 循环)。RemainAfterExitType=simpleType=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

这是一篇博客文章,其中包含有关该Match关键字的更多信息

相关内容