Thank you for reading this post, don't forget to subscribe!
Включение скрипта оболочки rc.local в systemd при загрузке системы Linux
Совместимость с /etc/rc.local достигается через systemd с помощью специальной службы под названием rc-local.service.
Этот модуль автоматически вызывается в multi-user.target системой systemd-rc-local-generator, если /etc/rc.local является исполняемым.
Выполнение скрипта оболочки rc.local во время загрузки с использованием systemd
Естественно, создайте или обновите/отредактируйте файл с именем /etc/rc.local с помощью вашего любимого текстового редактора.
Я собираюсь использовать команду vim:
$ sudo vim /etc/rc.local
## RHEL/CentOS/Fedora Linux отредактируйте файл /etc/rc.d/rc.local ##
$ sudo vim /etc/rc.d/rc.local
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
#!/bin/sh # add your commands # call your scripts here # let us set stuff for my wifi /sbin/iw phy0 wowlan enable magic-packet disconnect # last line must be exit 0 exit 0 |
[/codesyntax]
Убедитесь, что вы установили права на исполнение файла с помощью команды chmod:
$ sudo chmod -v +x /etc/rc.local
Настройка rc-local.service в Linux, когда systemd запускается
Все, что нам нужно сделать, это ввести следующую команду systemctl:
$ sudo systemctl enable rc-local.service
$ sudo reboot
$ sudo systemctl status rc-local.service
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="amp-wp-981e973" data-amp-original-style="color: rgb(0, 153, 0);">●</span> rc-local.service - /etc/rc.local Compatibility Loaded: loaded (/etc/systemd/system/rc-local.service; enabled-runtime; ven> Drop-In: /usr/lib/systemd/system/rc-local.service.d └─debian.conf Active: <span class="amp-wp-981e973" data-amp-original-style="color: rgb(0, 153, 0);">active (exited)</span> since Wed 2020-11-04 13:29:54 IST; 1h 59min ago Docs: man:systemd-rc-local-generator(8) Tasks: 0 (limit: 37939) Memory: 0B CGroup: /system.slice/rc-local.service Nov 04 13:29:54 itsecforu systemd[1]: Starting /etc/rc.local Compatibility Nov 04 13:29:54 itsecforu systemd[1]: Started /etc/rc.local Compatibility. |
Как посмотреть конфигурацию сервиса
Откройте приложение терминал и введите:
$ sudo systemctl cat rc-local.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# /etc/systemd/system/rc-local.service # SPDX-License-Identifier: LGPL-<span class="nu0">2.1</span>+ # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version <span class="nu0">2.1</span> of the License, or # <span class="br0">(</span>at your option<span class="br0">)</span> any later version. # This unit gets pulled automatically into multi-user.target by # systemd-rc-local-generator if /etc/rc.local is executable. <span class="re0"><span class="br0">[</span>Unit<span class="br0">]</span></span> <span class="re1">Description</span><span class="sy0">=</span><span class="re2">/etc/rc.local Compatibility</span> <span class="re1">Documentation</span><span class="sy0">=</span><span class="re2">man:systemd-rc-local-generator<span class="br0">(</span>8<span class="br0">)</span></span> <span class="re1">ConditionFileIsExecutable</span><span class="sy0">=</span><span class="re2">/etc/rc.local</span> <span class="re1">After</span><span class="sy0">=</span><span class="re2">network.target</span> <span class="re0"><span class="br0">[</span>Service<span class="br0">]</span></span> <span class="re1">Type</span><span class="sy0">=</span><span class="re2">forking</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/etc/rc.local start</span> <span class="re1">TimeoutSec</span><span class="sy0">=</span><span class="re2">0</span> <span class="re1">RemainAfterExit</span><span class="sy0">=</span><span class="re2">yes</span> <span class="re1">GuessMainPID</span><span class="sy0">=</span><span class="re2">no</span> # /usr/lib/systemd/system/rc-local.service.d/debian.conf <span class="re0"><span class="br0">[</span>Unit<span class="br0">]</span></span> # not specified by LSB, but has been behaving that way in Debian under SysV # init and upstart <span class="re1">After</span><span class="sy0">=</span><span class="re2">network-online.target</span> # Often contains status messages which users expect to see on the console # during boot <span class="re0"><span class="br0">[</span>Service<span class="br0">]</span></span> <span class="re1">StandardOutput</span><span class="sy0">=</span><span class="re2">journal+console</span> <span class="re1">StandardError</span><span class="sy0">=</span><span class="re2">journal+console</span> |
Примечание. Запустите sudo SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/system-generators/systemd-rc-local-generator для отладки проблем с /etc/rc.local, когда скрипт не загружается.
Информация об уровнях выполнения Linux
Когда по умолчанию использовался init, у нас были следующие уровни запуска:
- S – загрузить систему Linux
- 0 – выключить Linux
- 6 – Перезагрузить Linux
- 1 – Однопользовательский режим Linux, используемый для восстановления системы Linux в аварийном режиме
- 2–5 – Обычная многопользовательская система, поддерживающая как CLI, так и GUI, а также полную сетевую связь
Застую дистрибутивы Linux и система Unix изменяли эти значения уровней выполнения в соответствии со своими потребностями.
Тем не менее, /etc/rc.local вызывается, когда система входит в многопользовательский режим через уровни запуска от 2 до 5.
Однако это значение по умолчанию было удалено, когда большая часть дистрибутивов Linux переключилась на systemd.
Поэтому я написал это краткое руководство для разработчиков Linux и системных администраторов.
Создать свой собственный сервис легко с systemd на Linux
Вместо скрипта оболочки в /etc/rc.d/ или вызова /etc/rc.local мы сделаем это по другому.
Он работает только в Linux, но не в других вариантах Unix. Тогда просто сделайте:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# /etc/systemd/system/my-service-name-goes-here.service # # Sample template to call your script or command when systemd boots into multi user mode # <span class="re0"><span class="br0">[</span>Unit<span class="br0">]</span></span> <span class="re1">Before</span><span class="sy0">=</span><span class="re2">network.target</span> <span class="re0"><span class="br0">[</span>Service<span class="br0">]</span></span> <span class="re1">Type</span><span class="sy0">=</span><span class="re2">oneshot</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/path/to/command</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/path/to/script arg1 arg2</span> <span class="re1">RemainAfterExit</span><span class="sy0">=</span><span class="re2">yes</span> <span class="re0"><span class="br0">[</span>Install<span class="br0">]</span></span> <span class="re1">WantedBy</span><span class="sy0">=</span><span class="re2">multi-user.target</span> |
Например, вот как мы можем установить правила Wireguard или openvpn iptables:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# /etc/systemd/system/wireguard-iptables.service <span class="re0"><span class="br0">[</span>Unit<span class="br0">]</span></span> <span class="re1">Before</span><span class="sy0">=</span><span class="re2">network.target</span> <span class="re0"><span class="br0">[</span>Service<span class="br0">]</span></span> <span class="re1">Type</span><span class="sy0">=</span><span class="re2">oneshot</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.1.0/24 ! -d 10.8.1.0/24 -j SNAT --to 123.x.x.x</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -I INPUT -p udp --dport 1194 -j ACCEPT</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -I FORWARD -s 10.8.1.0/24 -j ACCEPT</span> <span class="re1">ExecStart</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT</span> <span class="re1">ExecStop</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.1.0/24 ! -d 10.8.1.0/24 -j SNAT --to 123.x.x.x</span> <span class="re1">ExecStop</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -D INPUT -p udp --dport 1194 -j ACCEPT</span> <span class="re1">ExecStop</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -D FORWARD -s 10.8.1.0/24 -j ACCEPT</span> <span class="re1">ExecStop</span><span class="sy0">=</span><span class="re2">/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT</span> <span class="re1">RemainAfterExit</span><span class="sy0">=</span><span class="re2">yes</span> <span class="re0"><span class="br0">[</span>Install<span class="br0">]</span></span> <span class="re1">WantedBy</span><span class="sy0">=</span><span class="re2">multi-user.target</span> |
А потом:
$ sudo systemctl enable wireguard-iptables.service
$ sudo systemctl start wireguard-iptables.service
$ sudo systemctl stop wireguard-iptables.service