Исправление запуска сервисов в Debian при загрузке системы
Сервисы в Debian (например, sshd или пользовательские скрипты) могут не запускаться автоматически при загрузке системы, хотя работают при ручном запуске. Это часто связано с тем, что сервис пытается стартовать раньше, че
Симптомы
- Сервис (например, sshd, apache2 или кастомный скрипт) не запускается после перезагрузки системы.
- При ручном запуске командой 'systemctl restart <service>' сервис работает без ошибок.
- При проверке статуса командой 'systemctl status <service>' видно, что сервис завершился с ошибкой (exit-code).
- В логах видны ошибки вроде 'Cannot assign requested address' или 'code=exited, status=2'.
Возможные причины
- Параллельный запуск сервисов: сервис стартует раньше, чем готов необходимый ресурс (интерфейс, файл, данные).
- Неправильная настройка зависимостей в systemd.
- Специфичная проблема с привязкой к IPv6-адресу после обновления до Debian 13.
- Скрипт ожидает данные, которых ещё нет в системе на этапе загрузки.
Пошаговое решение
Диагностика: Проверьте статус сервиса и логи
Первым делом нужно понять, почему сервис падает. Используйте стандартные инструменты systemd для диагностики. 1. **Проверьте статус сервиса**, чтобы увидеть код ошибки и последние строки логов: ```bash systemctl status <имя_сервиса>.service ``` Например, для sshd: `systemctl status ssh.service`. 2. **Просмотрите подробные логи** за текущую или прошлые загрузки, используя journalctl. Флаг `-u` указывает имя сервиса, а `--no-pager` выводит весь текст сразу. ```bash journalctl --no-pager -u <имя_сервиса>.service ``` Чтобы посмотреть логи за прошлую загрузку, добавьте флаг `-b -1`. 3. **Проверьте, включён ли сервис для автозапуска**. Если он отключен, система его не запустит при загрузке. ```bash systemctl is-enabled <имя_сервиса>.service ``` Если сервис отключен, включите его: ```bash systemctl enable <имя_сервиса>.service ``` **Результат:** Вы увидите конкретный код ошибки (например, `status=2/INVALIDARGUMENT` или `status=255/EXCEPTION`) и сообщение, которое подскажет причину (ошибка привязки к адресу, файл не найден и т.д.).
Решение 1: Исправление проблем с сетевой зависимостью (для IPv6 и не только)
Это решение подходит, если сервис (часто sshd) не может запуститься, потому что сетевой интерфейс ещё не получил нужный IP-адрес (например, из-за долгой настройки IPv6). **Проблема:** В Debian по умолчанию многие сервисы и сетевые службы запускаются параллельно. Сервис sshd может попытаться привязаться к IPv6-адресу, который ещё не назначен интерфейсу. **Вариант А: Измените конфигурацию sshd для привязки к любому адресу** 1. Откройте файл конфигурации: `sudo nano /etc/ssh/sshd_config`. 2. Найдите строку `ListenAddress` и установите значение `::` (вместо конкретного IPv6-адреса). Это заставит sshd слушать все доступные IPv6-адреса. 3. Перезапустите сервис: `sudo systemctl restart ssh.service`. **Вариант Б: Используйте сокет-активацию с дополнительной опцией** 1. Отредактируйте конфигурацию сокета: `sudo systemctl edit --full ssh.socket`. 2. В секции `[Socket]` укажите нужный адрес и добавьте строку `FreeBind=true`. Это разрешит системе привязаться к адресу, который пока недоступен. ```ini [Socket] ListenStream=[ваш_ipv6_адрес]:22 FreeBind=true ``` 3. Включите и запустите сокет: ```bash sudo systemctl enable ssh.socket sudo systemctl restart ssh.socket ``` **Вариант В: Явно добавьте зависимость от сети** Если проблема в порядке загрузки, укажите, что сервис должен ждать готовности сети. 1. Выполните команды для добавления зависимостей: ```bash sudo systemctl add-wants ssh.service network-online.target ``` 2. Если это не помогло, более надёжный способ — вручную отредактировать unit-файл сервиса: ```bash sudo systemctl edit ssh.service ``` 3. Добавьте строки, указывающие, что сервис должен ждать завершения работы сети (например, `networking.service` или `ifupdown.service`): ```ini [Unit] Requires=networking.service After=networking.service ``` **Результат:** Сервис sshd (или другой) будет дожидаться, пока нужный сетевой ресурс станет доступен, и успешно запустится.
Решение 2: Добавление ожидания в пользовательский скрипт
Это решение для пользовательских скриптов, которые падают при загрузке, потому что обращаются к данным, которых ещё нет (например, таблице ARP, файлам или сокетам). **Пример:** Скрипт пытается прочитать таблицу ARP (`/proc/net/arp`), но при загрузке она ещё пуста, и команда возвращает ошибку. **Как исправить:** Модифицируйте скрипт, добавив цикл ожидания в начале. 1. Откройте скрипт для редактирования: `sudo nano /путь/к/вашему_скрипту.sh`. 2. Вставьте в начало (после shebang `#!/bin/bash`) следующий блок. Он будет проверять наличие данных и ждать их появления (в данном случае — появления записей в ARP-таблице). ```bash # Ждем, пока ARP-таблица не станет непустой cmd=$(cat /proc/net/arp | wc -l | awk '{print $1}') while [ $cmd -eq 1 ] do sleep 1 cmd=$(cat /proc/net/arp | wc -l | awk '{print $1}') done ``` 3. Сохраните файл. 4. Убедитесь, что скрипт исполняемый: `chmod +x /путь/к/вашему_скрипту.sh`. **Результат:** Теперь скрипт будет повторять попытку чтения данных каждую секунду, пока они не появятся, а затем выполнится основная логика без ошибок.
Если сервис в Debian не запускается автоматически при загрузке, но работает после ручного перезапуска, начните с диагностики: проверьте статус через systemctl status и логи через journalctl. Типичные причины — конфликт порядка загрузки (сервис стартует раньше ресурса, который ему нужен) или ошибка в конфигурации самого сервиса.
Для сетевых сервисов, особенно sshd на IPv6, частая проблема — попытка привязаться к адресу, который ещё не назначен интерфейсу. Решение: либо изменить ListenAddress на :: для прослушивания всех адресов, либо настроить сокет-активацию с опцией FreeBind=true, либо явно добавить зависимость от сети в unit-файл сервиса.
Для пользовательских скриптов проблема часто в том, что они запускаются, когда нужные данные ещё не готовы. Здесь поможет добавление цикла ожидания в начало скрипта. Всегда проверяйте, что скрипт включен в автозапуск командой systemctl enable.
Диагностика проблемы загрузки
При проблемах с загрузкойLinuxсначала检查 system logs. Выполните journalctl -xb для просмотра логов последней загрузки. Обратите внимание на строки с [FAILED] или [ERROR]. Проверьте, какие службы не запустились: systemctl —failed. Это покажет точную причину незагрузки.
Восстановление через Live USB
Если система не загружается вообще, загрузитесь с Live USB. Смонтируйте корневой раздел: sudo mount /dev/sdaX /mnt. Проверьте файловую систему: sudo fsck /dev/sdaX. Переустановите загрузчик: sudo grub-install —root-directory=/mnt /dev/sda. Это восстановит GRUB после неудачного обновления.
Проверка конфигурации
Проверьте конфигурационные файлы: /etc/fstab (монтирование разделов), /etc/default/grub (параметры ядра), /etc/systemd/system.conf (systemd). Убедитесь, что UUID разделов в fstab совпадают с реальными: sudo blkid. Неправильный UUID — частая причина незагрузки после обновления или замены диска.
Исправление через chroot
Если нужен доступ к системе для исправления: sudo mount /dev/sdaX /mnt, sudo mount —bind /dev /mnt/dev, sudo mount —bind /proc /mnt/proc, sudo chroot /mnt. Теперь вы внутри системы и можете исправлять конфигурацию, переустанавливать пакеты или обновлятьinitramfs: update-initramfs -u.
Откат обновления
Если проблема возникла после обновления ядра или пакетов, загрузитесь с предыдущего ядра в меню GRUB. Затем выполните: sudo apt install —reinstall linux-image-$(uname -r) или sudo dnf downgrade kernel. Для автоматического отката: sudo apt-mark hold имя-пакета — запретит обновление этого пакета.
Источники
- unix.stackexchange.com — проверено 31.05.2026
- serverfault.com — проверено 31.05.2026
- stackoverflow.com — проверено 31.05.2026