Вопрос или проблема
Я пишу скрипт на Python, который будет выполнять функцию, когда VPN отключен. Могу ли я создать unit systemd, который будет уведомлять меня, если интерфейс tun0 (vpn) отключен, вместо того чтобы проверять ifconfig tun0 каждую секунду? Я имею в виду внезапное отключение, потому что я видел много примеров уведомлений, когда интерфейс включен.
Я хочу решение без необходимости опрашивать ifconfig каждую секунду.
UPD: Я пытаюсь написать unit, как:
[Unit]
Description=Слушать, когда интерфейс отключен
After=network.target
After=sys-devices-virtual-net-tun0.device
[Service]
Type=simple
Restart=on-failure
ExecStart=/path/to/run.sh
[Install]
WantedBy=multi-user.target
Но этот скрипт запускается только когда сетевой интерфейс ВКЛЮЧЕН. А мне нужно решение, когда этот интерфейс ОТКЛЮЧЕН. Не проверять, если tun0 отключен в момент времени, а ждать события, если он отключен, и выполнять работу.
Ответ или решение
Для реализации вашей задачи и создания Systemd-юнита, который будет срабатывать при отключении сетевого интерфейса tun0
, необходимо использовать сокетные и служебные единицы, которые могут реагировать на события системы, а не просто периодически проверять состояние интерфейса.
Шаг 1: Создание служебного юнита
- Создайте файл юнита для вашей службы, например
/etc/systemd/system/vpn-notify.service
:
[Unit]
Description=Notify when VPN interface tun0 is down
After=network.target
[Service]
Type=simple
ExecStart=/path/to/run.sh
[Install]
WantedBy=multi-user.target
Шаг 2: Создание юнита для сокета
- Создайте файл сокетного юнита
/etc/systemd/system/vpn-notify.socket
:
[Unit]
Description=Socket for VPN status notification
[Socket]
ListenDatagram=/run/vpn-status.sock
[Install]
WantedBy=sockets.target
Шаг 3: Модификация вашего скрипта
- В вашем скрипте
run.sh
вы можете добавить обработчик, который будет проверять состояние интерфейса и выполнять необходимые действия. Например:
#!/bin/bash
if ! ip link show tun0 up; then
# Здесь вставьте ваш код для уведомления
notify-send "VPN отключен" "Интерфейс tun0 отключен"
fi
Не забудьте сделать скрипт исполняемым:
chmod +x /path/to/run.sh
Шаг 4: Включение и перезапуск Systemd
- Активируйте и запустите сокетный юнит:
sudo systemctl enable vpn-notify.socket
sudo systemctl start vpn-notify.socket
- Перезагрузите Systemd для применения изменений:
sudo systemctl daemon-reload
Шаг 5: Обновление интерфейса на события
- Теперь чтобы сокет юнит реагировал на события, создайте файл правила
udev
, который будет отправлять сигнал сокету при изменениях состояния интерфейсаtun0
. Создайте файл/etc/udev/rules.d/99-tun0.rules
с содержимым:
SUBSYSTEM=="net", ACTION=="down", KERNEL=="tun0", RUN+="/bin/systemctl restart vpn-notify.service"
Заключение
Теперь у вас есть полностью функционирующая система, которая будет уведомлять вас при отключении интерфейса tun0
. Таким образом, вы избегаете избыточного опрашивания состояния интерфейса и получаете событие только при его изменении.