systemd:在网络真正启动后在启动时启动服务(用于 WoL 目的)
systemd: start service at boot time after network is really up (for WoL purpose)
我有一台工作中的计算机,有时我会从家里醒来以访问它,但是当启动并从我们的 DHCP 服务器获取另一个 IP 地址时,我该如何访问它?
情况和我的“工作流程”如下:
- 我从家里的 PC 连接到办公室的 VPN
- ssh 到办公室 LAN 中的专用服务器(它具有固定的 IP 地址)
- 在那台服务器上,我调用了一个脚本,该脚本使用我办公室 PC 的 MAC 地址
广播 WoL 数据包
- 我的办公室 PC 启动了(它真的启动了,当然!)
现在理论上,只要我知道它的 IP 地址,我就可以通过 SSH 连接到我办公室的 PC。
有时它变得相同,有时它会改变。
为了避免这种情况,我有以下想法:
- 在启动我的办公室 PC 后,通过 SSH 连接到办公室服务器并将其自己的 IP 地址写入服务器上的某个文本文件
- 我检查了服务器上的那个文件(由于它的固定 IP,我可以连接到它),找到我办公室 PC 的 IP 地址,然后可以从我的家用 PC SSH 到我办公室的 PC
所有计算机运行Linux; Ubuntu 家里 14.04,办公室服务器上的 SLES,我办公室 PC 上的 OpenSUSE 13.1。这都不是问题。
为了让这一切正常工作,我只需要在我的办公室 PC 上安装一个脚本,在启动时 运行s 当网络启动并且 运行ning.
我的脚本(publish_ip.sh)如下:
# get own IP address:
ip=$(ip addr show | awk '=="inet" && !~ /127\.0\.0\.1/ { split(, 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"
为了 运行 这个脚本在启动时我创建了一个 systemd 服务文件,publish-ip.service,用于我的办公室 PC:
[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
但这是我在办公室 PC 上经常看到的:
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 处于启动状态时 运行ning,我的脚本和服务都可以完美运行,即 systemctl start publish-ip.service
工作没有任何错误。
曾经有一个名为 arpwatch 的工具可以记录所有联网设备的 IP 地址和 MAC 地址,因此您可以简单地 grep 查找计算机的 MAC 并获取 IP .
还有一个叫做arping的工具,你可以grep通过MAC地址的输出。
另一种选择是在您的计算机上保持一个随机端口打开并使用 nmap 扫描整个网络以获取该特定端口,或者 nmap 整个网络以查找已启动的主机并为您的 MAC地址...
nmap -sP 192.168.1.0/24
这不是一个完整的解决方案,但我在计算机启动后设置了一个 SSH 隧道;它每 5 秒重新启动一次,以防止在网络仍处于关闭状态时因发送垃圾邮件而被杀死;如果您可以将固定 IP 系统用作堡垒主机,则可以将类似的东西与您的 WOL 搭配使用:
[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
我尝试了所有这些目标,它们都在 DHCP 获得 IP 地址之前就达到了。去图:
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 地址后开始。 (A mount point in my case,但也可以为您服务)
(在 debian9/stretch)
您可以通过将 ping 循环添加为 ExecStartPre 脚本来延迟作业的启动:
[Service]
ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'
我有一台工作中的计算机,有时我会从家里醒来以访问它,但是当启动并从我们的 DHCP 服务器获取另一个 IP 地址时,我该如何访问它?
情况和我的“工作流程”如下:
- 我从家里的 PC 连接到办公室的 VPN
- ssh 到办公室 LAN 中的专用服务器(它具有固定的 IP 地址)
- 在那台服务器上,我调用了一个脚本,该脚本使用我办公室 PC 的 MAC 地址 广播 WoL 数据包
- 我的办公室 PC 启动了(它真的启动了,当然!)
现在理论上,只要我知道它的 IP 地址,我就可以通过 SSH 连接到我办公室的 PC。 有时它变得相同,有时它会改变。 为了避免这种情况,我有以下想法:
- 在启动我的办公室 PC 后,通过 SSH 连接到办公室服务器并将其自己的 IP 地址写入服务器上的某个文本文件
- 我检查了服务器上的那个文件(由于它的固定 IP,我可以连接到它),找到我办公室 PC 的 IP 地址,然后可以从我的家用 PC SSH 到我办公室的 PC
所有计算机运行Linux; Ubuntu 家里 14.04,办公室服务器上的 SLES,我办公室 PC 上的 OpenSUSE 13.1。这都不是问题。
为了让这一切正常工作,我只需要在我的办公室 PC 上安装一个脚本,在启动时 运行s 当网络启动并且 运行ning.
我的脚本(publish_ip.sh)如下:
# get own IP address:
ip=$(ip addr show | awk '=="inet" && !~ /127\.0\.0\.1/ { split(, 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"
为了 运行 这个脚本在启动时我创建了一个 systemd 服务文件,publish-ip.service,用于我的办公室 PC:
[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
但这是我在办公室 PC 上经常看到的:
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 处于启动状态时 运行ning,我的脚本和服务都可以完美运行,即 systemctl start publish-ip.service
工作没有任何错误。
曾经有一个名为 arpwatch 的工具可以记录所有联网设备的 IP 地址和 MAC 地址,因此您可以简单地 grep 查找计算机的 MAC 并获取 IP .
还有一个叫做arping的工具,你可以grep通过MAC地址的输出。
另一种选择是在您的计算机上保持一个随机端口打开并使用 nmap 扫描整个网络以获取该特定端口,或者 nmap 整个网络以查找已启动的主机并为您的 MAC地址...
nmap -sP 192.168.1.0/24
这不是一个完整的解决方案,但我在计算机启动后设置了一个 SSH 隧道;它每 5 秒重新启动一次,以防止在网络仍处于关闭状态时因发送垃圾邮件而被杀死;如果您可以将固定 IP 系统用作堡垒主机,则可以将类似的东西与您的 WOL 搭配使用:
[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
我尝试了所有这些目标,它们都在 DHCP 获得 IP 地址之前就达到了。去图:
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 地址后开始。 (A mount point in my case,但也可以为您服务)
(在 debian9/stretch)
您可以通过将 ping 循环添加为 ExecStartPre 脚本来延迟作业的启动:
[Service]
ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'