Sshトンネルを維持するためにautosshを開始するこのsystemdサービスファイルが見つかりました: https://Gist.github.com/thomasfr/9707568
[Unit]
Description=Keeps a tunnel to 'remote.example.com' open
After=network.target
[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa
[Install]
WantedBy=multi-user.target
oneサービスで複数のトンネルを開始するようにsystemdを設定する方法はありますか?.
コピーと貼り付けを避けたいので、N個のシステムサービスファイルを作成したくありません。
「remote.example.com」が他のホスト名で置き換えられることを除いて、すべてのサービスファイルは同一です。
約1.5年前にこの質問をしました。
私の心は変わった。はい、それはいいです。systemdでこれを行うことができますが、将来は構成管理を使用します。
Systemdがテンプレート言語を実装して%hを置き換える必要があるのはなぜですか? ..それは意味がないと思います。
数か月後、このループとテンプレート化は別のレベルで解決する必要があると思います。今は、AnsibleまたはTerraFormを使用します。
まあ、only単位ファイルごとに変化するものが_remote.example.com
_の部分であると仮定すると、 Instantiated を使用できます サービス 。
_systemd.unit
_ manページから:
オプションで、実行時にテンプレートファイルからユニットをインスタンス化できます。これにより、単一の構成ファイルから複数のユニットを作成できます。 systemdがユニット構成ファイルを検索する場合、最初にファイルシステムでリテラルユニット名を検索します。それが成功せず、ユニット名に「@」文字が含まれている場合、systemdは同じ名前を共有するが、インスタンス文字列(つまり、「@」文字とサフィックスの間の部分)が削除されたユニットテンプレートを探します。例:サービス[email protected]が要求され、その名前のファイルが見つからない場合、systemdはgetty @ .serviceを探し、見つかった場合はその構成ファイルからサービスをインスタンス化します。
基本的に、変数が含まれる単一のユニットファイルを作成します。通常は_%i
_)で違いが発生し、そのサービスを「有効」にするとリンクされます。
たとえば、次のような_/etc/systemd/system/[email protected]
_というユニットファイルがあります。
_[Unit]
Description=AutoSSH service for ServiceABC on %i
After=network.target
[Service]
Environment=AUTOSSH_GATETIME=30 AUTOSSH_LOGFILE=/var/log/autossh/%i.log AUTOSSH_PIDFILE=/var/run/autossh.%i.pid
PIDFile=/var/run/autossh.%i.pid
#Type=forking
ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i
[Install]
WantedBy=multi-user.target
_
次に有効にしたもの
_[user@anotherhost ~]$ Sudo systemctl enable [email protected]
ln -s '/etc/systemd/system/[email protected]' '/etc/systemd/system/multi-user.target.wants/[email protected]'
_
そしてと相互作用することができます
_[user@anotherhost ~]$ Sudo systemctl start [email protected]
[user@anotherhost ~]$ Sudo systemctl status [email protected]
[email protected] - AutoSSH service for ServiceABC on somehost.example
Loaded: loaded (/etc/systemd/system/[email protected]; enabled)
Active: active (running) since Tue 2015-10-20 13:19:01 EDT; 17s ago
Main PID: 32524 (autossh)
CGroup: /system.slice/system-autossh.slice/[email protected]
├─32524 /usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
└─32525 /usr/bin/ssh -L 40000:127.0.0.1:40000 -R 40000:127.0.0.1:40001 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
[user@anotherhost ~]$ Sudo systemctl status [email protected]
[user@anotherhost ~]$ Sudo systemctl status [email protected]
[email protected] - AutoSSH service for ServiceABC on somehost.example.com
Loaded: loaded (/etc/systemd/system/[email protected]; enabled)
Active: inactive (dead) since Tue 2015-10-20 13:24:10 EDT; 2s ago
Process: 32524 ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i (code=exited, status=0/SUCCESS)
Main PID: 32524 (code=exited, status=0/SUCCESS)
Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopping AutoSSH service for ServiceABC on somehost.example.com...
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopped AutoSSH service for ServiceABC on somehost.example.com.
_
ご覧のとおり、ユニットファイル内の_%i
_のすべてのインスタンスは_somehost.example.com
_に置き換えられます。
ユニットファイルで使用できる specifiers が他にもたくさんありますが、このような場合に_%i
_が最適に機能することがわかりました。
ここにpythonの例があります。これは私が探していたものです。サービスファイル名の_@
_を使用すると、Nプロセスを開始できます。
_$ cat /etc/systemd/system/[email protected]
[Unit]
Description=manages my worker service, instance %i
After=multi-user.target
[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10
_
たとえば、さまざまなカウントを有効にします。
30人のワーカーを有効にする:
_Sudo systemctl enable my-worker\@{1..30}.service
_
2つのワーカーを有効にする:
_Sudo systemctl enable my-worker\@{1..2}.service
_
その後、必ずリロードしてください:
_Sudo systemctl daemon-reload
_
これで、さまざまな方法で開始/停止できます。
開始1:
_Sudo systemctl start [email protected]
_
複数開始:
_Sudo systemctl start my-worker@{1..2}
_
複数停止:
_Sudo systemctl stop my-worker@{1..2}
_
ステータスを確認:
_Sudo systemctl status my-worker@1
_
[〜#〜] update [〜#〜]:インスタンスを1つのサービスとして管理するには、次のようにします。
/etc/systemd/system/[email protected]:
_[Unit]
Description=manage worker instances as a service, instance %i
Requires=some-worker.service
Before=some-worker.service
BindsTo=some-worker.service
[Service]
PermissionsStartOnly=true
Type=idle
User=root
#EnvironmentFile=/etc/profile.d/optional_envvars.sh
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=some-worker.service
_
/usr/bin/some-worker-start.sh:
_#!/bin/bash
systemctl start some-worker@{1..10}
_
/etc/systemd/system/some-worker.service:
_[Unit]
Description=manages some worker instances as a service, instance
[Service]
Type=oneshot
ExecStart=/usr/bin/sh /usr/bin/some-worker-start.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
_
そして今、あなたはSudo systemctl some-worker (start|restart|stop)
ですべてのインスタンスを管理することができます
_script.py
_のボイラープレートは次のとおりです。
_#!/usr/bin/env python
import logging
def worker_loop():
shutdown = False
while True:
try:
if shutdown:
break
# Your execution logic here.
# Common logic - i.e. consume from a queue, perform some work, ack message
print("hello world")
except (IOError, KeyboardInterrupt):
shutdown = True
logging.info("shutdown received - processing will halt when jobs complete")
except Exception as e:
logging.exception("unhandled exception on shutdown. {}".format(e))
if __name__ == '__main__':
worker_loop()
_
GregLの答えは私を大いに助けました。上記のギアマンジョブサーバーの例を使用してコードで使用したユニットテンプレートの例を次に示します。この1つのテンプレートを使用してX個の「ワーカー」を作成できるシェルスクリプトを作成しました。
[Unit]
Description=az gearman worker
After=gearman-job-server.service
[Service]
PIDFile=/var/run/gearman_worker_az%i.pid
Type=simple
User=www-data
WorkingDirectory=/var/www/mysite.com/jobs/
ExecStart=/usr/bin/php -f gearman_worker_az.php > /dev/null 2>&1
Restart=on-success
KillMode=process
[Install]
WantedBy=multi-user.target
私は同様のタスクの解決策を検索し、実際に1つ見つけました。それは達成する方が簡単だと思いますが、 hacky であるはずです。 (ここでは言及されていません)
VPNがトンネルを作成した後に複数のssh接続を作成する必要があったので、tunデバイスに依存し、適切なコマンドでシェルスクリプトを呼び出すサービスを作成しました。
サービス/etc/systemd/system/ssh_tunnel.service:
[Unit]
Description=Reverse SSH Service to access hidden services
ConditionPathExists=|/usr/bin
Wants=sys-devices-virtual-net-tun0.device
After=network.target sys-devices-virtual-net-tun0.device
[Service]
Type=forking
ExecStart=/bin/sh /etc/openvpn/ssh_tunnels.sh
RemainAfterExit=yes
TimeoutSec=0
GuessMainPID=no
[Install]
WantedBy=multi-user.target
/etc/openvpn/ssh_tunnels.sh:
!/bin/bash
#sleep 15
echo 'Tunelling some ports'
killall -HUP ssh
su - user -c 'ssh -f [email protected] -p 9999 -L :3690:svn.newbox.ru:3690 -L :8888:10.1.20.55:80 -L :8181:10.1.10.10:80 -N -vvv'
ssh -i /home/user/.ssh/id_rsa -f [email protected] -p 9999 -L :587:mail.domain.ru:587 -L :995:mail.newbox.ru:995 -L :22:10.1.2.1:22 -N -vvv &
exit 0
結果:
# systemctl status ssh_tunnel.service
● ssh_smartex.service - Reverse SSH Service to access hidden services
Loaded: loaded (/etc/systemd/system/ssh_tunnel.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2020-03-20 16:01:07 UTC; 22min ago
Process: 156 ExecStart=/bin/sh /etc/openvpn/ssh_tunnel.sh (code=exited, status=0/SUC>
Tasks: 2 (limit: 4915)
Memory: 3.8M
CGroup: /system.slice/ssh_tunnel.service
├─166 ssh -f [email protected] -p 9999 -L :3690:svn.newbox.ru:3690 -L :8888:10.1.20.55:80 ->
└─168 ssh -i /home/user/.ssh/id_rsa -f [email protected] -p 9999 -L :587:mail.newbox.ru:5>
...
しかし、私はまだ確認していません、それがどのようにvpnの再起動に耐えられるかを確認していませんが、それは別のトピックです。