Почему сеть работает так медленно в cron?

У меня был опыт настройки автоматического получения сертификатов от Let's Encrypt, и я решил взять ещё один заказ. Я скопировал все соответствующие скрипты с другого сервера и протестировал их через командную строку. Затем настроил выполнение в cron на ближайшую дату. Однако в этот день старый сертификат не обновился. При запуске скрипта из командной строки сертификат успешно обновился. 

Чтобы выяснить, в чём причина разницы между запуском через командную строку и cron, я увеличил уровень детализации logs certbot. Но он долго не выдавал никаких сообщений. При перенаправлении потоков в файл создавались пустые записи, даже при использовании параметров debug и verbose. Я заметил, что certbot активируется, если его запускать из терминала, но в cron терминала нет. Я решил использовать screen, добавив в начало cron-скрипта следующее:

<pre><code class="bash">if [ -z "$STY" ]; then exec screen -dm -S Lets-Encrypt-Renewal /bin/bash "$0"; fi</code></pre>

После этого certbot начал выдавать сообщения об ошибках, и одним из них была: 
<blockquote>requests.exceptions.ConnectionError: HTTPSConnectionPool(host='acme-v02.api.letsencrypt.org', port=443): Max retries exceeded with url: /directory (Caused by NewConnectionError(': Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))</blockquote>

Я пытался подправить время в crontab, чтобы скрипт запускался несколько раз, но в журналах всё равно появлялось сообщение о временной ошибке разрешения имени. В результате остаётся мысль: нет ничего более постоянного, чем временное.
  • 14 сентября 2024 г. 11:23
Ответы на вопрос 2
Проблемы с медленной работой сети при запуске скриптов через cron могут быть вызваны различными факторами. Вот несколько возможных причин и решений для вашей ситуации:

1. **Сетевые настройки**: В cron могут отсутствовать те же сетевые настройки или окружение, что и в вашем терминале. Проверьте, что переменные окружения, включая DNS-серверы, правильные. Сравните переменные окружения, используемые в cron (можно вывести их в файл при запуске cron задачи, используя `env > /path/to/envfile`), с теми, что у вас в терминале.

2. **Проблемы с DNS**: Ошибка, которую вы получили, указывает на проблемы с разрешением имен. Возможно, cron выполняется с другой конфигурацией DNS. Убедитесь, что в системе прописаны правильные DNS-серверы. Проверьте файл `/etc/resolv.conf`, чтобы убедиться, что там указаны корректные DNS-серверы.

3. **Файлы конфигурации**: Убедитесь, что в скрипте вы используете абсолютные пути для всех исполняемых файлов и конфигураций, так как при запуске из cron может не срабатывать нужный контекст.

4. **Права доступа**: Проверьте, что у пользователя, от имени которого выполняется cron, есть необходимые права на выполнение скрипта и доступ к необходимым сетевым ресурсам.

5. **Сетевые ограничения**: Некоторые системы могут применять ограничения на соединения, особенно когда запросы исходят от cron. Убедитесь, что нет ограничений от фаерволов или сервисов на уровне сети.

6. **Журналирование и отладка**: Если начинается какая-то ошибка, убедитесь, что у вас есть логирование всех этапов выполнения скрипта, чтобы иметь возможность отследить, на каком именно этапе это происходит.

7. **Отладка с использованием `screen` или `tmux`**: Хотя вы уже пробовали использовать `screen`, вы можете рассмотреть возможность использования `tmux` или тестировать запуск с интерактивным терминалом, чтобы проверить, как это повлияет на выполнение скрипта.

Для решения вашей проблемы полезно сделать следующее:
- Начните с проверки DNS (например, попробуйте выполнить `nslookup acme-v02.api.letsencrypt.org` из cron).
- Проверьте все переменные окружения, используемые в вашем скрипте, и убедитесь, что они определены в cron.
- Попробуйте добавить некоторый `sleep` в начале скрипта, чтобы убедиться, что все сетевые службы успевают инициализироваться правильно перед тем, как certbot выполнит свои действия.

Если проблема сохраняется, возможна необходимость более глубокого мониторинга сети, такого как использование `tcpdump` или `strace`, чтобы отследить сетевые соединения и системные вызовы.
У меня встречный вопрос: для чего впихивать в крон невпихуемое, если для автообновления сертификатов есть специальный демон от certbot - snap.certbot.renew.service устанавливаемый штатно? К чему эти все упражнения?
Похожие вопросы