systemd:在网络真正启动后启动服务(用于 WoL 目的)

问题描述 投票:0回答:4

我工作时有一台计算机,有时我会从家里唤醒它以访问它,但是当启动并从我们的 DHCP 服务器获取另一个 IP 地址时,我该如何访问它?

情况和我的“工作流程”如下:

  • 我从家里的电脑连接到办公室的 VPN
  • ssh 到办公室 LAN 中的专用服务器(它有固定的 IP 地址)
  • 在该服务器上,我调用一个脚本,该脚本使用我办公室 PC 的 MAC 地址广播 WoL 数据包
  • 我的办公室电脑启动了(确实如此,当然!)

现在理论上,只要我知道办公室电脑的 IP 地址,我就能通过 SSH 连接到它。 有时它会变得相同,有时会发生变化。 为了避免这个问题,我有以下想法:

  • 启动后,我的办公室电脑通过 SSH 连接到办公室服务器,并将自己的 IP 地址写入服务器上的某个文本文件中
  • 我检查服务器上的该文件(由于其固定 IP,我可以连接到该文件),找到我办公室 PC 的 IP 地址,然后可以从我的家庭 PC 到我的办公室 PC

所有计算机都运行Linux;家里的 Ubuntu 14.04,办公室服务器上的 SLES,办公室 PC 上的 OpenSUSE 13.1。这一切都不是问题。

为了使这一切正常工作,我只需要在我的办公室 PC 上有一个在启动时运行的脚本 当网络启动并运行时

我的脚本(publish_ip.sh)如下:

# get own IP address:
ip=$(ip addr show | awk '$1=="inet" && $2 !~ /127\.0\.0\.1/ { split($2, a, "/"); print a[1]}');

# SSH to the office server (10.64.5.84) and write own IP address to a file there:
ssh -x -e none 10.64.5.84 "echo $(date) $ip >> office_pc_address.txt"

为了在启动时运行此脚本,我为我的办公室 PC 创建了一个 systemd 服务文件,publish-ip.service:

[Unit]
Description=publishes own IP address
Wants=network.target
After=network.target

[Service]
Type=oneshot
ExecStartPre=/usr/bin/sleep 30
ExecStart=/home/perldog/bin/publish_ip.sh
User=perldog

[Install]
WantedBy=multi-user.target

但这就是我在办公室电脑上总是得到的:

linux-tz7m:/usr/lib/systemd/system # systemctl status publish-ip.service
publish-ip.service - publishes own IP address
   Loaded: loaded (/usr/lib/systemd/system/publish-ip.service; enabled)
   Active: failed (Result: exit-code) since Mon 2016-02-29 12:17:34 CET; 4 days ago
  Process: 1688 ExecStart=/home/perldog/bin/publish_ip.sh (code=exited, status=255)
  Process: 1016 ExecStartPre=/usr/bin/sleep 30 (code=exited, status=0/SUCCESS)
 Main PID: 1688 (code=exited, status=255)

Feb 29 12:17:34 linux-tz7m publish_ip.sh[1688]: ssh: connect to host 10.64.5.84 port 22: Network is unreachable

显然我的服务启动并调用了我的脚本,但该脚本中的 SSH 命令失败并显示

Network is unreachable

我尝试了服务文件中的所有内容,以便它仅在网络启动后运行,但我不明白。我试过Wants=network.target

After=network.target
WantedBy=multi-user.target
,甚至还插入了
ExecStartPre=/usr/bin/sleep 30
。什么都没起作用。 当我的脚本被调用并尝试通过 SSH 连接到办公室服务器时,我总是会得到
Network is unreachable
问题:我的服务文件中需要进行哪些设置才能使其仅在

可通过 SSH 访问办公室服务器之后运行?

注意:当我在办公室并且我的办公室 PC 已启动并运行时,我的脚本和服务都完美运行,即 systemctl start publish-ip.service

运行没有任何错误。


我尝试了所有这些目标,它们都在 DHCP 获得 IP 地址之前到达。去图:
linux networking ssh systemd
4个回答
22
投票

network-online.target
  • remote-fs.target
  • nfs-client.target
  • dbus.service
  • 
    
    所做的工作是启用这两个:
systemctl enable systemd-networkd.service systemd-networkd-wait-online.service

然后设置

After=systemd-networkd-wait-online.service Wants=systemd-networkd-wait-online.service

现在它开始了
之后
DHCP 获得了 IP 地址。 (在我的情况下是一个

安装点,但也可能是您的服务) (在 debian9/stretch 上)

您可以通过添加 ping 循环作为 ExecStartPre 脚本来延迟作业的启动:

22
投票
[Service] ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'

在这里找到

不是完整的解决方案,但我在计算机启动后设置了 SSH 隧道;它每 5 秒重新启动一次,以防止在网络仍处于关闭状态时因发送垃圾邮件而被杀死;如果您可以使用固定 IP 系统作为堡垒主机,您可以将类似的东西与您的 WOL 搭配使用:

3
投票
[Unit] Description=Keep open a reverse tunnel to my home server After=network.target [Service] ExecStart=/usr/bin/ssh -NT hometunnel RestartSec=5 Restart=always [Install] WantedBy=multi-user.target

root的.ssh/config的相关部分:

Host hometunnel HostName <redacted> IdentityFile /root/.ssh/<redacted> User <redacted> RemoteForward <redacted> localhost:22 ExitOnForwardFailure yes ServerAliveInterval 60 ServerAliveCountMax 5

曾经有一个名为 arpwatch 的工具,它会记录所有联网设备的 IP 地址和 MAC 地址,因此您可以简单地 grep 计算机的 MAC 并获取 IP。 

0
投票
还有一个名为 arping 的工具,您可以通过 grep 来查找 MAC 地址的输出。

另一种选择是在计算机上保持一个随机端口打开,并使用 nmap 扫描整个网络以查找该特定端口,或者 nmap 整个网络以查找已启动的主机并 grep 查找您的 MAC 地址...

nmap -sP 192.168.1.0/24


© www.soinside.com 2019 - 2024. All rights reserved.