среда, 9 июля 2008 г.

Проблемы с cron

Преамбула.
У меня дома есть сервер, который подключен к интернету и раздаёт его в локальную сеть из 2 компов (мой и моего roommate). Сам сервер доступа в интернет не имеет, а только форвардит и считает траффик. В целях безопасности и правильного учёта трафика, так сказать. Но, поскольку по ночам у нас анлим, то часто я оставлял свой ноутбук включенным на всю ночь с целью что-то скачать. Но он шумит зараза, кушает электроэнергию и вообще ведёт себя неприлично. И я решил, что ночные закачки вполне может взять на себя сервер. Создал специального пользователя inetuser, написал скрипт, добавляющий пару правил для iptables, которые разрешали исходящий трафик только от этого пользователя. Теперь надо было запускать его в 01:05, но тут возникла

Проблема №1
В логе cron-а значилось, что скрипт выполнен, но правила не добавлялись. Если же запустить скриптик руками - всё срабатывало как надо.
Загадка.... Вскрылась она довольно быстро. Оказалось iptables лежит в /sbin, которого нет в PATH прои запуске cron-ом.
Так-так. Небольшое правило
*/1 * * * * env > cron-env
через пару минут создало файлик /root/cron-env, в котором я смог посмотреть с каким же окружением запускаются программы из-под крона:
SHELL=/bin/sh
USER=root
PATH=/usr/bin:/bin
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env
Да, PATH несколько хиловат... Модифицировал скрипт:
#!/bin/bash
PATH=$PATH:/sbin
iptables -I ....
Теперь всё заработало!
Итак, в час ночи inetuser получает доступ в интернет.

Следующим шагом было написание простого скрипта для скачивания файлов по списку. Написал и положил его в /home/sazarkevich/ndnl-download.sh. А так-же создал символьную ссылку /bin/ndnl-download.sh -> /home/sazarkevich/ndnl-download.sh
(всё это для того что-бы и скрипт не потерялся при переинсталяции сервера, и в PATH был доступен всем. Даже злосчастному cron-у)
Теперь оставалось только запускать этот скрипт в фоне, под пользователем inetuser в 01:10. Но тут появилась

Проблема №2
Надо сразу сказать, что хотя я проблему и решил, но причину не понял.
Итак, добавляем запись в crontab:
10 1 * * * su inetuser ndnl-download.sh &
Но, ничего не происходит.
Ладно, мы хитрые:
10 1 * * * su inetuser ndnl-download.sh > /tmp/ndnl-log 2>&1 &
Смотрим в лог и видим, что лох... То есть видим загадочную строку
/bin/bash: Access denied.
Што за фак? Ладно, учёные, не впервой. Создаём консоль с окружением совпадающим как у cron-а. Но, тут всё работает...
Значит дело не в переменных окружения. Нужно методом тыка пробовать различные командные строки. Но это долго: 1 проба занимает где-то 2 минуты. Пока пропишешь новое правило, пока оно сработает. Пока убедишься, что нифига не сработало. И тут я придумал вот что:
Надо поработать в консоли, которую создаст cron. Там и покрутить разные варианты.
Для этого я нашёл утилиту screen. screen как бы создаёт виртуальную консоль, от которой можно отключится, а затем подключится снова.
Были найдены нужные ключи. Следующая команда
screen -d -m
запускает новый сеанс и тут же отключается от него. Сеанс как бы висит в система и ждёт, когда к нему подключусь я - хитрый перец.
Замечательно, создаём правило
23 2 * * * screen -d -m
(02:23 - было ближайшее время срабатывания)
Ждём, проверяем:
# screen -list
13834..leela (Detached)
1 Socket in /var/run/screen/S-root
Оно! Набираем
# screen -r
и оказываемся в консоли, запущенной cron-ом. Тут же проверяем, воспроизводится ли проблема:
# su inetuser ndnl-download.sh
/bin/bash: Access denied.
Грандиозно. Воспроизводится.
Методом тыка приходим, что работает варианты
# su inetuser -с 'ndnl-download.sh'
# su inetuser /bin/ndnl-download.sh
выбираю второй, вписываю правило в crontab:
10 1 * * * su inetuser -c 'ndnl-download.sh > /tmp/ndnl-log 2>&1 &'
Всё работает! Уря.

Заключение.
Хочу ещё рассказать, как этого inetuser-а остановить, чтоб он не зарвался и не стал качать днём. Предусмотрено аж 3 'стопора':
1. В 8:50 с особым цинизмом убиваем все процессы пользователя inetuser:
killall -u inetuser
2. В 8:55 правила iptables очищаются, и снова запрещают интернет на сервере
/etc/init.d/iptables restart
3 Наконец, в 9:00 интерфейс eth0, который смотрит в интернет останавливается:
/etc/init.d/net.eth0 stop
Последнее скорее для забывчивых пользователей, которые всю ночь качали порево и утомлённые заснули на клавиатуре. Ну и проворонили резкое подорожание трафика в 9:00

P.S. Разобрался что за сообщение /bin/bash: access denied.
Оказывается скрипт запускался из /root директории, но от имени пользователя, который в этой директории не имел никаких прав. Видимо bash пытался найти исполняемый скрипт на месте, и тут его обламывали.

4 комментария:

ERROOORR комментирует...

Привет!вижу ты много понимаешь в Линуксах!
У меня просьба,думаю и ты был когда то начинающим и тоже многово не понимал )) по етому не суди строго!
У меня проблемма с CRON! скачал кучу манов по крону но толком не могу понять как с ним работать!А именно - есть Ubuntu надо сделать лишь одно обьяснить 1.куда класть скрипты для крона? 2.что писать в етих скриптах кроме времени исполнения? 3. пусть примером будет echo "привет" 4.чем отличаеться crontab -e в консоли от /etc/crontab? (то есть если есть возможность скинь ссылочку либо на грамотный ман по пунктам либо ответь на ети вопросы сам если будет время)!будем знакомы я костя ))..... заранее спасибо

ERROOORR комментирует...
Этот комментарий был удален администратором блога.
Анонимный комментирует...

Отличный и безопасный сайт, http://www.pi7.ru
есть всё! Чего нет. Создадим по вашей проcьбе.


[url=http://www.pi7.ru/forum/]форум[/url]


:) и Анекдот от недосыпа Проводится опрос среди студентов разных стран. Кто за сколько может выучить японский язык? Первого спросили американца. Тот на компьютере пощелкал и говорит:
-Один год и восемь месяцев.
Спросили француза, тот сбегал в библиотеку, просмотрел там каталоги и пообещал выучить за год.
Следующим в списке шел русский студент. Нашли его в курилке, задали свой животрепещущий вопрос. Студент:
-А методичка есть?
Дали ему методичку, он ее в момент пролистал:
-Ща докурю, пойду сдавать.

private-seo-soft комментирует...

Вот детальное описание процесса настройки крона
вручную и через панельку DirectAdmin http://private-seo-soft.blogspot.com/2010/04/crontab.html