среда, 31 октября 2012 г.

Заметки о systemd, часть 6, xinetd

Об этой возможности systemd нужно написать особо и обязательно. Это тот механизм, который авторы systemd называют сокет-активация: запуск служб динамически, по требованию сетевого подключения снаружи. Это в точности то, что выполняют inetd и xinetd.

Есть такой PDF-документ (я не знаю оригинала цельным текстом, похоже, что отдельные главы разбросаны статьями в личном блоге Леннарта Поттеринга, а переводчиком собраны в единый текст), назван "systemd для администраторов":
Lennart Poettering (автор)
Сергей Пташник (русский перевод)
17 июля 2012 г.
И есть там такая глава: "11. Службы с активацией в стиле inetd". С неё и начнём изучение вопроса. Несколько вводных цитат:
Уже многие годы inetd считается одной из базовых служб Unix-систем.
...
Наиболее популярные из них — BSD inetd и xinetd. Хотя inetd во многих дистрибутивах до сих пор устанавливается по умолчанию, сейчас он уже редко используется для запуска сетевых служб
...
Одной из ключевых возможностей systemd (а также launchd от Apple) является сокет-активация — тот же самый механизм, давным-давно реализованный inetd,
...
Тем не менее, systemd ничуть не хуже inetd может запускать службы в ответ на входящие сетевые соединения.
Автор в описаниях показывает запуск сокет-активируемой службы SSH, проверить это "в натуре" я предполагаю, для начала, не отступая от его рекомендаций. Поэтому я сначала, для аналогий, подготовлю запуск такой службы средствами xinetd. Создаём новый конфигурационный файл вот с таким примерно содержимым:
# cat /etc/xinetd.d/my-sshd
service ssh
{
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/sbin/sshd
server_args = -i
}


Остановим все службы, которые могли бы представлять сервис SSH, и убедимся, что запросы SSH не обслуживаются (их некому обслуживать):
# systemctl stop sshd.service
# systemctl status xinetd.service
$ ssh 192.168.1.5

ssh: connect to host 192.168.1.5 port 22: Connection refused


Вот теперь мы можем запустить суперсервер xinetd и убедится, что в такой конфигурации он обеспечивает поддержку SSH:
# systemctl start xinetd.service
$ ssh 192.168.1.5olej@192.168.1.5's password:
Last login: Fri Oct 5 23:07:20 2012 from notebook.localdomain
$ who
olej :0 2012-10-24 16:40 (:0)
olej pts/0 2012-10-24 16:41 (:0.0)
olej pts/2 2012-10-24 17:10 (:0.0)
olej pts/4 2012-10-24 17:16 (:0.0)
olej pts/6 2012-10-24 17:26 (:0.0)
olej pts/8 2012-10-24 18:18 (:0.0)
olej pts/9 2012-10-24 19:35 (notebook.localdomain)


А это то, как запуск SSH для этой сессии выглядел в системном журнале:
# tail -n2 /var/log/messages
Oct 24 19:35:28 notebook xinetd[4587]: START: ssh pid=4606 from=::ffff:192.168.1.5
Oct 24 19:35:35 notebook systemd-logind[642]: New session 5 of user olej.

Это всё были вещи достаточно общеизвестные, но нужные нам для сравнения с альтернативной возможностью: использование для той же цели сокет-активация в systemd.

А теперь, освежив в памяти как оно работает, переходим к активации той же службы SSH средствами systemd (вместо использования xinetd). Пока мы работаем со службой SSH будем в точности следовать рекомендациям упоминаемой выше главы 11. Создаём и заполняем 2 файла (sshd.socket и sshd@.service), содержимое их легко понятно по аналогии с обсуждавшимся выше /etc/xinetd.d/my-sshd :
# touch sshd.socket
# touch sshd@.service
ls -l *ssh*
-rw-r--r--. 1 root root 283 апр. 6 2012 sshd.service
-rw-r--r-- 1 root root 106 окт. 25 14:52 sshd@.service
-rw-r--r-- 1 root root 128 окт. 25 14:50 sshd.socket
$ cat sshd.socket
[Unit]
Description=SSH Socket for Per-Connection Servers
[Socket]
ListenStream=22
Accept=yes
[Install]
WantedBy=sockets.target
$ cat sshd@.service
[Unit]
Description=SSH Per-Connection Server
[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket

Перед проверкой работоспособности обязательно убеждаемся, что у нас не запущен автономный сервер sshd или xinetd :
# service sshd stop
$ service sshd status

Redirecting to /bin/systemctl status sshd.service
sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: failed (Result: exit-code) since Thu, 25 Oct 2012 12:38:10 +0300; 2h 18min ago
Process: 758 ExecStart=/usr/sbin/sshd -D $OPTIONS (code=exited, status=255)
Process: 749 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
CGroup: name=systemd:/system/sshd.service
$ ps -A | grep xinetd
756 ? 00:00:00 xinetd
# service xinetd stop
Redirecting to /bin/systemctl stop xinetd.service
$ service xinetd status
Redirecting to /bin/systemctl status xinetd.service
xinetd.service - Xinetd A Powerful Replacement For Inetd
Loaded: loaded (/usr/lib/systemd/system/xinetd.service; enabled)
Active: inactive (dead) since Thu, 25 Oct 2012 15:02:19 +0300; 10s ago
Process: 750 ExecStart=/usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid $EXTRAOPTIONS (code=exited, status=0/SUCCESS)
Main PID: 756 (code=exited, status=0/SUCCESS)
CGroup: name=systemd:/system/xinetd.service


Вот теперь, когда мы поместим оба предложенных выше файла в каталог /etc/systemd/system, мы можем запустить его (то есть активировать в текущем сеансе работы):
# systemctl start sshd.socket
# systemctl status sshd.socket
sshd.socket - SSH Socket for Per-Connection Servers
Loaded: loaded (/usr/lib/systemd/system/sshd.socket; disabled)
Active: active (listening) since Thu, 25 Oct 2012 15:07:29 +0300; 6s ago
Accepted: 0; Connected: 0
CGroup: name=systemd:/system/sshd.socket

Для проверки делаем 2 отдельных подключения (сеансов SSH), 1-е из показанных - удалённое, а 2-е - локальное:

$ ssh 192.168.1.5
The authenticity of host '192.168.1.5 (192.168.1.5)' can't be established.
RSA key fingerprint is 45:32:32:17:bd:6f:9c:d5:19:09:d0:fa:e2:06:bb:41.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.5' (RSA) to the list of known hosts.
olej@192.168.1.5's password:
Last login: Thu Oct 25 14:57:15 2012 from localhost.localdomain
-bash-4.2$ cat /etc/system-release
RFRemix release 17 (Beefy Miracle)

$ ssh localhost
olej@localhost's password:
Last login: Thu Oct 25 15:09:33 2012 from atom

Как видно, оба сеанса SSH работоспособны, хотя предварительно (до вызова) сервер sshd и не был запущен (мы это предварительно проверили) ...
$ ps -A | grep ssh
4555 pts/6 00:00:00 ssh
4563 ? 00:00:00 sshd
4565 ? 00:00:00 sshd
4669 pts/3 00:00:00 ssh
4670 ? 00:00:00 sshd
4673 ? 00:00:00 sshd

А вот одно из самых интересных следствий - активные экземпляры служб, соответствующие открытым сеансам, обладают динамически образуемыми именами:
$ systemctl --full | grep ssh
sshd.service loaded failed failed OpenSSH server daemon
sshd@0-192.168.1.5:22-192.168.1.7:47966.service loaded active running SSH Per-Connection Server
sshd@1-127.0.0.1:22-127.0.0.1:56938.service loaded active running SSH Per-Connection Server
sshd.socket loaded active listening SSH Socket for Per-Connection Servers

Ну вот и всё.
Этого вполне достаточно, чтобы утверждать, что всё совершенно успешно работает.

вторник, 23 октября 2012 г.

Заметки о systemd, часть 5, документация

Документация и публикации


По systemd очень мало толковой документации (или, может, это мне так не везёт?). То есть понаписано о systemd - множество, за такой короткий срок существования проекта. Но понаписано это множество, преимущественно, единственным автором: Леннартом Поттеринга, самим автором проекта. И если о качестве программ, которые создаёт Леннарт Поттеринг есть разные противоречивые мнения, спорят и обсуждают, то уровень документации, которую он же пишет, должен квалифицироваться однозначно: "совершенно бездарно". Точнее, пишет он, возможно, и очень даже неплохо, но пишет он рекламные проспекты... по принципу: "с утра сам себя не похвалишь - весь день как оплёванный ходишь" ... выдаёт желаемое за действительное, задуманное за реализованное, и аргументирует очень сомнительного качества преимущества там, где видятся недостатки...

Но жить то как-то с systemd приходится? А жить без технической документации нельзя - что это за жизнь? Поэтому я в этой части буду составлять подборку ссылок на значащие публикации относительно systemd. Из этих ссылок те материалы, которые написаны самим Леннартом Поттерингом я ... буду выделять вот таким цветом, чтобы читатель сразу был готов это "разделить на 3".

Из некоторых публикаций я буду приводить самые краткие цитаты, которые содержат самые характерные высказывания, или просто показались мне особенно интересными.

Техническая документация

17 июля 2012 г., 58 стр.
Автор: Lennart Poettering
Русский перевод: Сергей Пташник
Оригиналы глав в блоге автора:  http://0pointer.de/blog
Начнем с небольшого исторического экскурса. Каталог /etc/sysconfig появился в
дистрибутивах Red Hat и SUSE задолго до того, как я присоединился к этим проектам — иными словами, это было очень давно. Некоторое время спустя, в Debian появился аналогичный по смыслу каталог /etc/default.
Мне показался очень любопытным этот пассаж в тексте: "... это было так давно, ещё до того, как Леннарт Поттеринг присоединился к проектам, поэтому это может быть выброшено из ...".


23 сентября 2012 г.
Wiki страница OpenSUSE
cgroups — это контрольные группы распределяющие между процессами ресурсы и позволяющие осуществлять контроль, приоритизацию и управление системными ресурсами. Контрольные группы организованы иерархически, где каждый процесс помещается в группу с именем родителя, породивший этот процесс. Это позволяет установить точное происхождение определенного процесса.
systemd-cgls — это утилита, позволяющая наглядно оценить принадлежность группы процессов к их службам или процессов вошедших в сеанс пользователя с помощью регистрации пользовательских сессий

Публикации в тему 


Это одни из первых сообщений о существе проекта:


Система инициализации Systemd. Часть I
1 сентября 2010 г.
Автор: Lennart Poettering
Поэтому налейте себе чашечку кофе, садитесь и читайте о том, что грядет.
История долгая, а для тех, кто не хочет читать целиком, скажу вкратце: мы экспериментируем с новой системой инициализации, и это весело!

Система инициализации Systemd. Часть II
3 сентября 2010 г.
Автор: Lennart Poettering
Кто основные разработчики?
Большая часть кодовой базы - моя собственная работа, Lennart Poettering (Red Hat). Однако, общий дизайн и его отдельные детали - это результат моего взаимодействия с Kay Sievers (Novell). Также в проекте участвуют Harald Hoyer (Red Hat), Dhaval Giani (бывший сотрудник IBM), и многие другие из таких компаний как Intel, SUSE and Nokia.


Независимые мнения:


Systemd’ова болезнь
2 июля 2012 г.
Автор: Алексей Федорчук
Я, конечно, не врач, но, кажется, совершил медицинское открытие: открыл совершенно новую болезнь. Поражает избирательно, только тех, кто тем или иным образом связан с разработкой systemd и сопряжённых служб. Но зато, похоже, с вероятностью, близкой к стопроцентной…
Симптомов этой болезни пока выявляется три. Первый симптом — не-чтение ранее написанного, выраженное в хронической форме. Типичную клиническую картину этого можно видеть знаменитом Откровении Леннарта Поттеринга, которое под именем systemd Optimizations не так давно обошло всю сеть (имеется и в русском полупереводе-полупересказе).
Второй симптом — безудержное восхваление всего, что хоть каким-то боком связано с systemd.

systemd и штрих-коды: созданы друг для друга…
9 октября 2012 г.
Автор: Алексей Федорчук
Вслед за этим Петер Робинсон (Peter Robinson) высказался в том смысле, что хорошо бы иметь возможность отказаться от установки компонентов, которые пользователь полагает необязательными.
На это Леннарт ответил, что он и сам всей душой за возможность минимальной инсталляции, и готов делать всё в этом направлении, но хотел бы всё оставить по прежнему.
...
Пара слов в заключение. Быстро, однако, прошла та пара-тройка лет, когда Fedora, казалось, действительно была повёрнута лицом к пользователю. Или это просто казалось тем, кто применял её отечественный вариант — RFRemix? Ныне она, увы, вернулась на круги своя: быть кружком юных техников, результаты которых потом используют (или не используют) взрослые дяди из корпоратива.
  

Заметки о systemd, часть 4, системный журнал


Системный журнал


Ещё одно новшество от разработчиков и адаптаторов systemd (Леннарта Поттеринга, и тех, возможно, кто помогает ему в этой затее, и майнтеймеров свежих дистрибутивов) - это новая система ведения системного журнала Journal.

В одном из ранних сообщений о Journal утверждается следующее:
Journal будет частью systemd и не сможет использоваться обособленно. Все логи будут проиндексированы и хранится в специальной БД, к которой к сожалению будут неприменимы стандартные утилиты обработки текстовых файлов, такие как grep. Тем не менее, Journal не исключает параллельное использование традиционных syslog-служб, таких как rsyslog и syslog-ng.

Первым релизом, где осмелились опробовать Journal, как мне кажется, есть Fedora 17. Но и здесь интеграторам хватило здравого смысла (или не хватило смелости?) оставить работать две параллельно системы ведения журнала:

$ ps -A | grep journal
348 ? 00:00:00 systemd-journal

$ ps -A | grep log
...
667 ? 00:00:00 rsyslogd
...

Вот как видит соответствующие выполняющиеся сервисы сам systemd:

$ service rsyslog status
Redirecting to /bin/systemctl status  rsyslog.service
rsyslog.service - System Logging Service
 Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled)
 Active: active (running) since Tue, 23 Oct 2012 11:27:32 +0300; 1h 47min ago
Main PID: 639 (rsyslogd)
 CGroup: name=systemd:/system/rsyslog.service
 └ 639 /sbin/rsyslogd -n -c 5

$ service systemd-journald status
Redirecting to /bin/systemctl status  systemd-journald.service
systemd-journald.service - Journal Service
 Loaded: loaded (/usr/lib/systemd/system/systemd-journald.service; static)
 Active: active (running) since Tue, 23 Oct 2012 11:27:14 +0300; 1h 49min ago
   Docs: man:systemd-journald.service(8)
         man:systemd-journald.conf(5)
Main PID: 317 (systemd-journal)
 Status: "Processing requests..."
 CGroup: name=systemd:/system/systemd-journald.service
 └ 317 /usr/lib/systemd/systemd-journald

Служба system-journald при старте системы запущена существенно раньше традиционной rsyslog (PID). Система ведения журнала Journal записывает базу данных журнала (как теперь это называют разработчики) в формате, который теперь а).не текстовый и б).криптографированный. Если вы предварительно создадите каталог с именем /var/log/journal, то системный журнал будет записываться туда. Если такого каталога нет, то системный журнал будет записываться в /run/log/journal :

$ tree /run/log/journal
/run/log/journal
`-- dec47daacc0345f98702c28782126e50
    `-- system.journal

1 directory, 1 file

$ ls -l /run/log/journal/dec47daacc0345f98702c28782126e50/system.journal
-rw-r----- 1 root adm 413696 окт.  23 13:01 /run/log/journal/dec47daacc0345f98702c28782126e50/system.journal

В первом случае (/var/log/journal) журнал будет перманентным и будет сохраняться между сессиями перезагрузки, во втором (/run/log/journal - по умолчанию) журнал будет уничтожаться при завершении сессии.

P.S. Вообще то, отказ от текстового формата файла журнала - нарушение философии UNIX, где всегда считалось большим преимуществом текстовый формат всех конфигурационных и протокольных файлов. Подход Journal своей философией вызывает в памяти переход в Windows переход от набора файлов конфигураций к системному реестру.

Не пытайтесь непосредственно просматривать содержимое журнального файла, созданного Journal! Для просмотра и управления системным журналом созданы специальные утилиты, например systemd-journalctl (но, поскольку система находится в фазе активного развития и всё зыбко, то, наверняка, будут и другие средства) : 

# systemd-journalctl | tail -n5
Oct 19 17:01:01 notebook run-parts(/etc/cron.hourly)[6386]: finished mcelog.cron
Oct 19 17:11:30 notebook dbus-daemon[709]: dbus[709]: [system] Activating se...)
Oct 19 17:11:30 notebook dbus[709]: [system] Activating service name='org.f...r)
Oct 19 17:11:30 notebook dbus-daemon[709]: dbus[709]: [system] Successfully ...'
Oct 19 17:11:30 notebook dbus[709]: [system] Successfully activated service...t'


А поскольку у нас в системе работают две параллельные и независимые системы ведения системного журнала, то они создают очень похожий, но не идентичный набор записей журнала (в /var/log/messages нет записи с меткой 17:01:01 - /etc/cron.hourly):

# cat /var/log/messages | tail -n5
Oct 19 16:23:29 notebook dbus-daemon[709]: ** Message: No devices in use, exit
Oct 19 17:11:30 notebook dbus-daemon[709]: dbus[709]: [system] Activating service name='org.freedesktop.PackageKit' (using servicehelper)
Oct 19 17:11:30 notebook dbus[709]: [system] Activating service name='org.freedesktop.PackageKit' (using servicehelper)
Oct 19 17:11:30 notebook dbus-daemon[709]: dbus[709]: [system] Successfully activated service 'org.freedesktop.PackageKit'
Oct 19 17:11:30 notebook dbus[709]: [system] Successfully activated service 'org.freedesktop.PackageKit'


Журнал с точки зрения программного кода


Напишем простейшую тестовую программу для проверки работы с системным журналом из программного кода:

#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>

int main( int argc, char **argv, char **envp ) {
   int i;
   openlog( argv[ 0 ], LOG_NDELAY, LOG_USER );
   // LOG_EMERG=0, LOG_ALERT=1, LOG_CRIT=2, LOG_ERR= 3
   // LOG_WARNING=4, LOG_NOTICE=5, LOG_INFO=6, LOG_DEBUG=7
   for( i = LOG_EMERG; i <= LOG_DEBUG; i++ ) {
      syslog( i, "log. level = %d", i );
      printf( "done: log. level = %d\n", i );
   }
   closelog();
   return( EXIT_SUCCESS );
}

Предварительно скомпилировав, выполним эту программу:

$ ./mylogs 
done: log. level = 0
done: log. level = 1
done: log. level = 2
done: log. level = 3
done: log. level = 4
done: log. level = 5
done: log. level = 6
done: log. level = 7

Message from syslogd@notebook at Oct 23 21:44:16 ...
 ./mylogs: log. level = 0

И вот что мы обнаружим в двух журналах, формируемых двумя различными механизмами (сервисами):

$ sudo systemd-journalctl | tail -n9 
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 0
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 1
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 2
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 3
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 4
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 5
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 6
Oct 23 21:44:16 notebook ./mylogs[8227]: log. level = 7
Oct 23 21:44:56 notebook sudo[8234]: olej : TTY=pts/5 ; PWD=/home/olej/2012...tl

$ sudo cat /var/log/messages | tail -n7
Oct 23 21:44:16 notebook ./mylogs: log. level = 0
Oct 23 21:44:16 notebook ./mylogs: log. level = 1
Oct 23 21:44:16 notebook ./mylogs: log. level = 2
Oct 23 21:44:16 notebook ./mylogs: log. level = 3
Oct 23 21:44:16 notebook ./mylogs: log. level = 4
Oct 23 21:44:16 notebook ./mylogs: log. level = 5
Oct 23 21:44:16 notebook ./mylogs: log. level = 6

Как видно, результат программного вызова syslog() поступает в обе журнальные системы, но обрабатывается ними несколько по-разному:
  • сообщение уровня 0 (LOG_EMERG) на терминал задублировано только журнальным сервисом rsyslog;
  • порог занесения сообщений в журнал 6 (LOG_INFO), установленный для rsyslog (в конфигурационном файле /etc/rsyslog.conf) не действует для systemd-journald;

понедельник, 22 октября 2012 г.

Заметки о systemd, часть 3, проблемы и решения

Возникающие затруднения и их решения


Здесь я опишу перечислением те проблемы, которые возникли после установки Fedora 17 под системой инициализации systemd, которые пришлось специально разрешать, и те способы, которыми это было решено.

Q: Не удаётся запустить сервер SSH.

A: Во многих дистрибутивах, и в более ранних версиях Fedora (14, 15) сервер SSH запускается сразу после установки его средствами пакетной системы этого дистрибутива. Это одна из самых необходимых для работы служб, и всегда было привычно, что она под рукой. Но после установки c помощью yum пакета SSH сервер не стартует, попытка подключения с внешнего хоста заканчивается неудачей:

$ ssh olej@192.168.1.5
ssh: connect to host 192.168.1.5 port 22: Connection refused


Сервер SSH хоть и инсталлирован, но не активен, демона sshd здесь нет:

$ ps -A | grep ssh
$


$ service sshd status

Redirecting to /bin/systemctl status  sshd.service
sshd.service - OpenSSH server daemon
  Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
  Active: inactive (dead) since Tue, 23 Oct 2012 19:56:39 +0300; 5s ago
 Process: 756 ExecStart=/usr/sbin/sshd -D $OPTIONS (code=exited, status=0/SUCCESS)
 Process: 723 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
  CGroup: name=systemd:/system/sshd.service

После установки OpenSSH запрещён (disabled) системой инициализации systemd. С помощью  его же  средств и запустим этот сервер:

# service sshd start
Redirecting to /bin/systemctl start sshd.service


$ service sshd status
Redirecting to /bin/systemctl status  sshd.service
sshd.service - OpenSSH server daemon
 Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
 Active: active (running) since Tue, 23 Oct 2012 19:58:05 +0300; 2s ago
Process: 7354 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
Main PID: 7360 (sshd)
 CGroup: name=systemd:/system/sshd.service
 └ 7360 /usr/sbin/sshd -D

Oct 23 19:58:05 notebook sshd[7360]: Server listening on 0.0.0.0 port 22.
Oct 23 19:58:05 notebook sshd[7360]: Server listening on :: port 22.

Проверяем результат с внешнего хоста LAN и убеждаемся, что теперь сервер работает:

$ ssh olej@192.168.1.5
The authenticity of host '192.168.1.5 (192.168.1.5)' can't be established.
RSA key fingerprint is 45:32:32:17:bd:6f:9c:d5:19:09:d0:fa:e2:06:bb:41.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.5' (RSA) to the list of known hosts.
Nasty PTR record "192.168.1.5" is set up for 192.168.1.5, ignoring
olej@192.168.1.5's password:
-bash-4.2$ cat /etc/system-release
RFRemix release 17 (Beefy Miracle)

...

Но вам, наверное, хочется, чтобы сервер SSH был запущен не вручную, разово, а стартовал бы при каждой загрузке системы? Достигаем этого так:

# systemctl enable sshd.service
ln -s '/usr/lib/systemd/system/sshd.service' '/etc/systemd/system/multi-user.target.wants/sshd.service'


И при следующей перезагрузке системы:

$ ps -A | grep ssh
7389 ? 00:00:00 sshd



Q: Как запустить FTP сервер?

A: Многие годы в SysV это делалось элементарно, но под systemd это порождает новые проблемы! Под  systemd это может оказаться связанным с тем, что в умалчиваемой инсталляции он запускает  суперсервер xinetd, для которого некорректные настройки его FTP сервиса препятствуют старту сервиса (так происходит, например, в инсталляции Fedora 17 по умолчанию):

$ systemctl status xinetd.service
xinetd.service - Xinetd A Powerful Replacement For Inetd
 Loaded: loaded (/usr/lib/systemd/system/xinetd.service; enabled)
 Active: active (running) since Mon, 22 Oct 2012 14:46:17 +0300; 34min ago
Process: 705 ExecStart=/usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid $EXTRAOPTIONS (code=exited, status=0/SUCCESS)
Main PID: 709 (xinetd)
 CGroup: name=systemd:/system/xinetd.service
 └ 709 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid

$ ps -A | grep xinetd
709 ? 00:00:00 xinetd

Попытка подключения из удалённого узла:

$ ftp 192.168.1.5
Connected to 192.168.1.5 (192.168.1.5).
421 Service not available, remote server has closed connection
ftp> ...

В принципе, суперсервер по такому запросу должен поднять сервис xproftpd:

$ ls -w 100 /etc/xinetd.d
chargen-dgram daytime-stream echo-dgram   rlogin  tcpmux-server  time-stream
chargen-stream discard-dgram echo-stream  rsh     telnet    xproftpd
daytime-dgram discard-stream rexec     rsync   time-dgram

Что он благополучно и делает, но стартовавший сервис тут же завершается из-за ошибок настройки:

# tail -n 5 /var/log/messages
Oct 22 15:41:27 notebook xinetd[709]: START: ftp pid=3032 from=::ffff:192.168.1.5
Oct 22 15:41:32 notebook proftpd[3033]: 192.168.1.5 - Failed binding to ::, port 21: Адрес уже используется
Oct 22 15:41:32 notebook xinetd[709]: EXIT: ftp status=0 pid=3032 duration=5(sec)
Oct 22 15:41:32 notebook proftpd[3033]: 192.168.1.5 - Check the ServerType directive to ensure you are configured correctly.
Oct 22 15:41:32 notebook proftpd[3033]: 192.168.1.5 - Unable to start proftpd; check logs for more details

Я не стану описывать настройку xinetd, это отдельный предмет для будущих заметок - мы просто остановим суперсервер, и отдельно запустим сервер proftp (такой сервер установлен как сервис в Fedora 17 по умолчанию, но может быть использована любая другая реализация) ...

# systemctl stop xinetd.service

$ systemctl status xinetd.service

xinetd.service - Xinetd A Powerful Replacement For Inetd
Loaded: loaded (/usr/lib/systemd/system/xinetd.service; enabled)
Active: inactive (dead) since Fri, 10 Aug 2012 14:58:07 +0300; 1s ago
Main PID: 733 (code=exited, status=0/SUCCESS)
CGroup: name=systemd:/system/xinetd.service

Aug 10 12:07:24 notebook xinetd[733]: removing exec
Aug 10 12:07:24 notebook xinetd[733]: removing login
Aug 10 12:07:24 notebook xinetd[733]: removing shell
Aug 10 12:07:24 notebook xinetd[733]: removing rsync
Aug 10 12:07:24 notebook xinetd[733]: removing tcpmux
Aug 10 12:07:24 notebook xinetd[733]: removing telnet
Aug 10 12:07:24 notebook xinetd[733]: removing time
Aug 10 12:07:24 notebook xinetd[733]: removing time
Aug 10 12:07:24 notebook xinetd[733]: xinetd Version 2.3.15 started with libwrap loadavg labeled-networking options...ed in.
Aug 10 12:07:24 notebook xinetd[733]: Started working: 1 available service

К этому времени xinetd остановлен и может быть запущен автономный сервис FTP:

# systemctl start proftpd.service

$ ps -A | grep ftp
3228 ? 00:00:00 proftpd


Всё! Можно подсоединяться.


Q: А если помимо FTP нужен для обслуживания других сервисов и xinetd?

A: Тогда можно службу FTP просто вывести из-под контроля xinetd. Для этого в конфигурационном файле /etc/xinetd.d/xproftpd заменим в одной строке yes на no:

$ cat /etc/xinetd.d/xproftpd
service ftp
{
disable = no

...

Теперь после перезапуска xinetd сообщение об отказе соединения поменяет вид (сравните с показанным выше) - порт просто не обслуживается:

$ ftp 192.168.1.5
ftp: connect: В соединении отказано
ftp> ...

Теперь можно точно так же, как в показанном ранее случае, запустить сервис proftpd не останавливая суперсервера xinetd, теперь они не будут конфликтовать.

воскресенье, 21 октября 2012 г.

Заметки о systemd, часть 2, управление

Как ним управлять?


Сразу переходим к частностям. Почему к частностям? Потому, что внедрение systemd в дистрибутивы идёт опережающими темпами (опережающими развитие самого проекта systemd, опережающими наличие технических описаний на компоненты systemd ... -  так сильно спешим). И если пользователь установит на сегодня свежий дистрибутив Fedora или OpenSUSE (а кто ставит не свежий дистрибутив?), то очень скоро столкнётся с сугубо конкретным вопросом, типа: "А почему у меня не запускается SSH сервер?" ... и ни в одном из руководств последних 20-ти лет не найдёт верного ответа. Поэтому, пока сосредоточимся только на том, как решить конкретные проблемы пользователя (непосредственно те, с которыми я сам столкнулся в инсталляции Fedora 17).

Итак, вперёд к обузданию systemd. Некоторые вещи я буду описывать как это делается в FAQ: вопрос - ответ...

Управление загруженными сервисами


Управление сервисами делаем, естественно, только с правами root.

Прежде каких-либо действий, разумно поинтересоваться тем, какие вообще сервисы находятся под управлением systemd, ведь это, в значительной степени, зависит от предыстории ваших инсталляций:

$ cd /lib/systemd/system/
$ ls -w120 *.service
abrt-ccpp.service halt-local.service     rpcbind.service
abrtd.service halt.service     rpcgssd.service
abrt-oops.service hibernate.service     rpcidmapd.service
abrt-vmcore.service instperf.service     rpcsvcgssd.service
accounts-daemon.service ip6tables.service     rsyslog.service
alsa-restore.service iptables.service     rtkit-daemon.service
alsa-store.service irda.service     saslauthd.service
anaconda@.service irqbalance.service     sendmail.service
anaconda-shell@.service jetty.service     serial-getty@.service
apg@.service kexec.service     single.service
arp-ethers.service ksm.service     smb.service
atd.service ksmtuned.service     sm-client.service
auditd.service lldpad.service     sshd.service
autovt@.service lvm2-monitor.service     sssd.service
avahi-daemon.service mcelog.service     suspend.service
bluetooth.service mdmonitor.service     svnserve.service
canberra-system-bootup.service mdmonitor-takeover.service     systemd-ask-password-console.service
canberra-system-shutdown-reboot.service  messagebus.service     systemd-ask-password-plymouth.service
canberra-system-shutdown.service multipathd.service     systemd-ask-password-wall.service
chronyd.service named.service     systemd-binfmt.service
chrony-wait.service NetworkManager.service     systemd-debug-shell.service
colord-sane.service NetworkManager-wait-online.service  systemd-hostnamed.service
colord.service nfs-blkmap.service     systemd-initctl.service
console-getty.service nfs-idmap.service     systemd-journald.service
console-shell.service nfs-lock.service     systemd-localed.service
cpupower.service nfslock.service     systemd-logind.service
crond.service nfs-mountd.service     systemd-modules-load.service
cups.service nfs-rquotad.service     systemd-random-seed-load.service
cvs@.service nfs-secure-server.service     systemd-random-seed-save.service
dbus-org.freedesktop.hostname1.service nfs-secure.service     systemd-readahead-collect.service
dbus-org.freedesktop.locale1.service nfs-server.service     systemd-readahead-done.service
dbus-org.freedesktop.login1.service nfs.service     systemd-readahead-replay.service
dbus-org.freedesktop.timedate1.service nmb.service     systemd-remount-fs.service
dbus.service openvpn@.service     systemd-shutdownd.service
display-manager.service plymouth-halt.service     systemd-sysctl.service
dm-event.service plymouth-kexec.service     systemd-timedated.service
dnsmasq.service plymouth-poweroff.service     systemd-tmpfiles-clean.service
dnssec-triggerd-keygen.service plymouth-quit.service     systemd-tmpfiles-setup.service
dnssec-triggerd.service plymouth-quit-wait.service     systemd-update-utmp-runlevel.service
dracut-shutdown.service plymouth-read-write.service     systemd-update-utmp-shutdown.service
emergency.service plymouth-reboot.service     systemd-user-sessions.service
fcoe.service plymouth-start.service     systemd-vconsole-setup.service
fedora-autorelabel-mark.service poweroff.service     system-setup-keyboard.service
fedora-autorelabel.service pppoe-server.service     udev-configure-printer.service
fedora-configure.service prefdm.service     udev.service
fedora-import-state.service proftpd.service     udev-settle.service
fedora-loadmodules.service psacct.service     udev-trigger.service
fedora-readonly.service qemu-guest-agent.service     udisks2.service
fedora-storage-init-late.service quotacheck.service     unbound-keygen.service
fedora-storage-init.service quotaon.service     unbound.service
fedora-wait-storage.service rc-local.service     upower.service
firstboot-graphical.service rdisc.service     user@.service
fsck-root.service reboot.service     wpa_supplicant.service
fsck@.service rescue.service     xinetd.service
getty@.service restorecond.service     yum-updatesd.service
gpm.service rngd.service     zvbid.service

Немало!

Первейшее, что нас должно интересовать, это диагностика того, в каком текущем состоянии находится тот или иной из этих сервисов. Вот как выглядит диагностика для сервиса, например, /usr/lib/systemd/system/dnsmasq.service когда он активный (выполняющийся) и остановленный, соответственно:

$ service dnsmasq status
Redirecting to /bin/systemctl status  dnsmasq.service
dnsmasq.service - DNS caching server.
 Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; enabled)
 Active: active (running) since Tue, 23 Oct 2012 11:27:42 +0300; 8h ago
Process: 729 ExecStart=/usr/sbin/dnsmasq -s $HOSTNAME (code=exited, status=0/SUCCESS)
Main PID: 754 (dnsmasq)
 CGroup: name=systemd:/system/dnsmasq.service
 └ 754 /usr/sbin/dnsmasq -s notebook

Oct 23 11:27:42 notebook dnsmasq[754]: started, version 2.63rc6 cachesize 150
Oct 23 11:27:42 notebook dnsmasq[754]: compile time options: IPv6 GNU-getopt DBus no-i18n no-IDN DHCP DHCPv6 n...track
Oct 23 11:27:42 notebook dnsmasq-dhcp[754]: DHCP, IP range 192.168.1.120 -- 192.168.1.159, lease time 12h
Oct 23 11:27:42 notebook dnsmasq[754]: using nameserver 4.2.2.6#53
Oct 23 11:27:42 notebook dnsmasq[754]: using nameserver 8.8.4.4#53
Oct 23 11:27:42 notebook dnsmasq[754]: using nameserver 192.168.1.1#53
Oct 23 11:27:42 notebook dnsmasq[754]: cleared cache

# service dnsmasq status
Redirecting to /bin/systemctl status  dnsmasq.service
dnsmasq.service - DNS caching server.
 Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; enabled)
 Active: inactive (dead) since Tue, 23 Oct 2012 19:38:40 +0300; 3s ago
Process: 729 ExecStart=/usr/sbin/dnsmasq -s $HOSTNAME (code=exited, status=0/SUCCESS)
Main PID: 754 (code=exited, status=0/SUCCESS)
 CGroup: name=systemd:/system/dnsmasq.service

Запуск, остановку и перезапуск этого сервера делаем командами:

# service dnsmasq stop
Redirecting to /bin/systemctl stop dnsmasq.service

# service dnsmasq start
Redirecting to /bin/systemctl start dnsmasq.service

# service dnsmasq restart
Redirecting to /bin/systemctl restart dnsmasq.service

Из листинга команд уже понятно, что команда service делает всего лишь переадресацию к команде systemctl, поэтому прямая форма обсуждаемых действий могла бы выглядеть как-то так:

# systemctl stop dnsmasq.service

$ systemctl status dnsmasq.service
dnsmasq.service - DNS caching server.
 Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; enabled)
 Active: inactive (dead) since Tue, 23 Oct 2012 19:46:28 +0300; 24s ago
Process: 7190 ExecStart=/usr/sbin/dnsmasq -s $HOSTNAME (code=exited, status=0/SUCCESS)
Main PID: 7192 (code=exited, status=0/SUCCESS)
 CGroup: name=systemd:/system/dnsmasq.service

# systemctl start dnsmasq.service

$ systemctl status dnsmasq.service
dnsmasq.service - DNS caching server.
 Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; enabled)
 Active: active (running) since Tue, 23 Oct 2012 19:48:29 +0300; 2s ago
Process: 7249 ExecStart=/usr/sbin/dnsmasq -s $HOSTNAME (code=exited, status=0/SUCCESS)
Main PID: 7251 (dnsmasq)
 CGroup: name=systemd:/system/dnsmasq.service
 └ 7251 /usr/sbin/dnsmasq -s notebook

При запуске и остановке сервиса выводятся последние строки системного журнала, относящиеся непосредственно к обслуживаемому сервису.

Такие действия (запуск, останов) носят однократный характер, то есть относятся только к текущему сеансу. Это ручное управление сервисом. Если же мы хотим, чтобы сервис подымался автоматом при каждой загрузке системы, то пользуемся другой формой команды управления:  

# service dnsmasq enable

Redirecting to /bin/systemctl enable dnsmasq.service
ln -s '/usr/lib/systemd/system/dnsmasq.service' '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'

# service dnsmasq disable
Redirecting to /bin/systemctl disable dnsmasq.service
rm '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'


Как легко видеть, в такой форме команда также переадресуется к команде systemctl, но та просто создаёт ссылку из каталога (/etc/systemd/system/multi-user.target.wants) конфигурации нужного уровня загрузки (см. далее) на файл сервиса. В принципе, вы можете это сделать и вручную.

Замечания о совместимости


Команда service существовала и в прежней системе инициализации System V, но смысл её был другой: она выполняла инициализирующие скрипты для сервисов, расположенные в каталоге  /etc/init.d. Поле команды (3-й параметр service) определяется конкретным сервисом, но, как минимум, включает возможности start и stop.

Таким образом, выполнение команды service совместимо по синтаксису с привычным и при использовании systemd, однако ссылаемые командой сервисы описываются совсем в другом каталоге (/lib/systemd/system/). И если только сервис не найден в числе управляемых systemd, для совместимости осуществляется обработка сервисов (небольшого числа), оставшихся в /etc/init.d, например:

$ ls /etc/init.d
ceph  functions  hsqldb  ipsec livesys  livesys-late  netconsole  network  puppet  rfremixconf  spice-vdagentd  tcsd  wine

# service wine stop
Stopping wine (via systemctl):                             [  OK  ]

# service wine start
Starting wine (via systemctl):                             [  OK  ]

$ service wine status
Обработчики двоичного формата Wine зарегистрированы.

Уровни загрузки


В традиционной (System V) схеме инициализации в процессе загрузки, после инициализации ядра, ядро запускает /sbin/init как первый процесс пользовательского режима. init отвечает за всю дальнейшую загрузку системы. В операционных системах UNIX/Linux с помощью init можно изменить уровень инициализации. Уровень инициализации — степень загрузки операционной системы. При этом процесс init запускается и анализирует файл /etc/inittab. Это то, что мы могли выполнять командами вида:

# init 3

При переходе к systemd файл /etc/inittab игнорируется, а концепция уровней загрузки - отменяется, вместо неё вводится понятие цели (target). Какие цели доступны systemd смотрим там же:

$ cd /lib/systemd/system/

$ ls -w120 *.target
anaconda.target      halt.target nss-lookup.target runlevel1.target  sockets.target
basic.target     hibernate.target nss-user-lookup.target  runlevel2.target  sound.target
bluetooth.target     http-daemon.target poweroff.target runlevel3.target  suspend.target
cryptsetup.target    kexec.target printer.target runlevel4.target  swap.target
ctrl-alt-del.target  local-fs-pre.target reboot.target runlevel5.target  sysinit.target
default.target     local-fs.target remote-fs-pre.target runlevel6.target  syslog.target
emergency.target     mail-transfer-agent.target  remote-fs.target shutdown.target   systemd-timedated-ntp.target
final.target     multi-user.target rescue.target sigpwr.target   time-sync.target
getty.target     network.target rpcbind.target sleep.target   umount.target
graphical.target     nfs.target runlevel0.target smartcard.target


Уровень загрузки для сеанса мог быть только единый (например: 2 - загрузка в многопользовательском режиме без поддержки сети, 3 - загрузка в многопользовательском режиме с поддержкой сети, 5 - загрузка в многопользовательском режиме с поддержкой сети и графического входа в систему). Целей же, при инициализации сеанса, может быть несколько.

Теперь для того, чтобы переключиться на 3-й уровень загрузки, выполняем команду:

# systemctl enable multi-user.target
...


А для того, чтобы переключиться на 5-й уровень загрузки:

# systemctl enable graphical.target
...

Для достижения каждой цели systemd хранит зависимости других целей и сервисов, необходимых для инициализации требуемой цели. Вот как можно рассмотреть зависимости, требуемые для достижения цели multi-user.target : 

$ systemctl show -p "Wants" multi-user.target
Wants=systemd-update-utmp-runlevel.service crond.service gpm.service ksmtuned.service NetworkManager.service sm-client.service atd.service ksm.service abrtd.service abrt-oops.service multipathd.service sshd.service auditd.service cups.path remote-fs.target rpcbind.service rsyslog.service chronyd.service abrt-ccpp.service xinetd.service mdmonitor.service avahi-daemon.service irqbalance.service mcelog.service sendmail.service arp-ethers.service abrt-vmcore.service nfs-lock.service dnsmasq.service plymouth-quit.service
 bus.service systemd-logind.service systemd-ask-password-wall.path systemd-user-essions.service getty.target plymouth-quit-wait.service tcsd.service wine.service livesys.service livesys-late.service

P.S. Весь этот вывод осуществляется единой чудовищно длинной строкой, поэтому для изучения его нужно куда-то (в файл) переадресовать.