ActiveDirectory/PostfixDovecot: различия между версиями

Материал из ALT Linux Wiki
(Новая страница: «{{Шаблон:Stub}} Настройка Postfix для аутентификации пользователей в Active Directory. == Ссылки == * http...»)
 
(→‎ad_mail_groups.cf: Посылать письмо только членам группы (не посылать самой группе))
 
(не показано 49 промежуточных версий 5 участников)
Строка 1: Строка 1:
{{Шаблон:Stub}}
Настройка Postfix и Dovecot для аутентификации пользователей в [[Active Directory]].


Настройка Postfix для аутентификации пользователей в [[Active Directory]].
== Задача ==


Настроить почтовую систему на базе {{pkg|Postfix}} и {{pkg|Dovecot}} для работы с базой пользователей [[ActiveDirectory|Active Directory]].
{|class="standard"
!Параметр
!Значение
|-
|Имя домена||'''test.alt'''
|-
|Размещение почты||{{path|/var/mail/<имя домена>/<имя пользователя>}} (формат maildir)
|-
|Доступ на чтение почты||IMAP (порт 993), SSL
|-
|Доступ на отправку почты||SMTP (порт 465), SSL/STARTTLS
|-
|Данные аутентификации:||Полный email с доменом (например, petrov@test.alt) или имя пользователя
|-
|Журнал работы||{{path|/var/log/maillog}}
|}
=== Принятые ограничения ===
* В текущей конфигурации не рассматриваются многодоменные конфигурации;
* Доступ к службам реализован только с помощью SSL по соображениям безопасности;
* Уровень домена и леса Active Directory должен быть не выше Windows 2008 R2;
* В данной версии инструкции не рассматривается конфигурация для подключения Microsoft Exchange на основе MAPI или EWS;
* Для подключения в данной конфигурации можно использовать Microsoft Outlook версии, начиная с 2003 в режиме подключения почты по IMAP;
* {{Attention|Доступ к серверу LDAP осуществляется по протоколу ldap без шифрования. Для [[SambaDC]] отключите обязательный ldaps в {{path|/etc/samba/smb.conf}} в секции [global]: <source lang="ini">ldap server require strong auth = no</source>}}
== Подготовка ==
=== Создание пользователя в Active Directory ===
Создаётся пользователь {{term|vmail}} с не истекающей учётной записью:
samba-tool user create -W Users vmail
samba-tool user setexpiry vmail --noexpiry
== Настройка Postfix ==
apt-get install postfix-ldap
=== Изменение файлов ===
В каталоге {{path|/etc/postfix}} изменяем файлы для домена {{term|test.alt}}:
==== main.cf ====
<source lang="ini"># Global Postfix configuration file.  This file lists only a small subset
# of all parameters.  For the syntax, and for a complete parameter list,
# see the postconf(5) manual page.  For a commented and more complete
# version of this file see /etc/postfix/main.cf.dist
mailbox_command = /usr/libexec/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
inet_protocols = ipv4
# Mappings
virtual_mailbox_base = /var/mail
virtual_mailbox_domains = test.alt
virtual_mailbox_maps = ldap:/etc/postfix/ad_local_recipients.cf
virtual_alias_maps = ldap:/etc/postfix/ad_mail_groups.cf
virtual_transport = dovecot
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
# SSL/TLS
smtpd_use_tls = yes
smtpd_tls_security_level = encrypt
#smtpd_tls_security_level = may
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = test.alt
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_sender_login_maps = ldap:/etc/postfix/ad_sender_login.cf
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /var/lib/ssl/certs/dovecot.cert
smtpd_tls_key_file = /var/lib/ssl/private/dovecot.key
smtpd_tls_CAfile = /var/lib/ssl/certs/dovecot.pem
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, permit_sasl_authenticated, reject
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch
default_destination_recipient_limit = 1
</source>
{{Attention|Файл {{path|/etc/postfix/mydestination}} должен быть пустым}}
==== master.cf ====
В файл {{path|master.cf}} необходимо добавить:
<source lang="text">dovecot  unix  -      n      n      -      -      pipe
  flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -d ${recipient}
smtps    inet  n      -      n      -      -      smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject</source>
==== ad_local_recipients.cf ====
<source lang="ini">version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
scope = sub
query_filter = (&(|(mail=%s)(otherMailbox=%u@%d))(sAMAccountType=805306368))
result_filter = %s
result_attribute = mail
special_result_attribute = member
bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word</source>
==== ad_mail_groups.cf ====
<source lang="ini">version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
timeout = 3
scope = sub
query_filter = (&(mail=%s)(sAMAccountType=268435456))
result_filter = %s
leaf_result_attribute = mail
special_result_attribute = member
bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word
</source>
==== ad_sender_login.cf ====
<source lang="ini">version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
scope = sub
query_filter = (&(objectClass=user)(|(sAMAccountName=%s)(mail=%s)))
result_attribute = mail
bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word
</source>
=== Тестируем работу ===
Проверка конфигурации Postfix (не должно быть никаких сообщений:
# postconf >/dev/null
Проверка пользователя почты {{term|petrov}}:
<source lang="text"># postmap -q petrov@test.alt ldap:/etc/postfix/ad_local_recipients.cf
petrov@test.alt</source>
Проверка входа:
<source lang="text"># postmap -q petrov@test.alt ldap:/etc/postfix/ad_sender_login.cf
petrov@test.alt</source>
Проверка общего адреса e-mail:
<source lang="text"># samba-tool group add --mail-address=sales@test.alt Sales
Added group Sales
# samba-tool group addmembers Sales ivanov,petrov
Added members to group Sales
# postmap -q sales@test.alt ldap:/etc/postfix/ad_mail_groups.cf
sales@test.alt,ivanov@test.alt,petrov@test.alt</source>
=== Перезапуск службы ===
Перезапускаем службу {{cmd|postfix}}:
service postfix restart
== Настройка Dovecot ==
Устанавливаем Dovecot:
apt-get install dovecot
=== Изменение файлов ===
==== dovecot-ldap.conf.ext ====
Создаём файл {{path|/etc/dovecot/dovecot-ldap.conf.ext}}
<source lang="ini">hosts            = test.alt:3268
ldap_version    = 3
auth_bind        = yes
dn              = cn=vmail,cn=Users,dc=test,dc=alt
dnpass          = Pa$$word
base            = cn=Users,dc=test,dc=alt
scope            = subtree
deref            = never
user_filter = (&(objectClass=user)(|(mail=%Lu)(sAMAccountName=%Lu)))
user_attrs  = =uid=8,gid=12,mail=user
pass_filter = (&(objectClass=user)(|(mail=%Lu)(sAMAccountName=%Lu)))
pass_attrs = mail=user</source>
{{Attention|Значение '''base''' не должно содержать только значения dc, иначе при попытке использования будет 'Operation error'.}}
В каталоге {{path|/etc/dovecot/conf.d}} изменяем файлы для домена {{term|test.alt}}:
==== 10-auth.conf ====
<source lang="ini">#auth_username_format = %Lu
#auth_gssapi_hostname = "$ALL"
#auth_krb5_keytab = /etc/dovecot/dovecot.keytab
#auth_use_winbind = no
#auth_winbind_helper_path = /usr/bin/ntlm_auth
#auth_failure_delay = 2 secs
auth_mechanisms = plain
!include auth-ldap.conf.ext</source>
==== 10-mail.conf ====
<source lang="ini">mail_location = maildir:/var/mail/%d/%n:UTF-8:INBOX=/var/mail/%d/%n/Inbox
mail_uid = mail
mail_gid = mail
first_valid_uid = 5
first_valid_gid = 5</source>
==== 10-master.conf ====
<source lang="ini">service imap-login {
  inet_listener imap {
    port = 0
  }
  inet_listener imaps {
  }
}
service pop3-login {
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    port = 0
  }
}
service lmtp {
  unix_listener lmtp {
  }
}
service imap {
}
service pop3 {
}
service auth {
  unix_listener auth-userdb {
  }
  unix_listener /var/spool/postfix/private/auth {
    mode = 0600
    user = postfix
    group = postfix
  }
}
service auth-worker {
}
service dict {
  unix_listener dict {
  }
}</source>
==== 15-lda.conf ====
<source lang="ini">protocol lda {
  hostname = test.alt
  postmaster_address = administrator@test.alt
}</source>
==== 15-mailboxes.conf ====
<source lang="ini">namespace inbox {
  inbox = yes
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
}</source>
=== Проверка конфигурации ===
Выполните
doveconf >/dev/null
Если конфигурация правильная, ничего не должно вывестись.
После правки конфигурации может вывестись:
doveconf: Error: t_readlink(/var/run/dovecot//dovecot.conf) failed: readlink() failed: No such file or directory
В этом случае перезапустите службу, как описано в следующем шаге, повторите ввод команды и уже ориентируйтесь на вывод после перезапуска службы.
=== Перезапуск службы ===
Перезапускаем службу {{cmd|dovecot}} и включаем её в автозапуск:
chkconfig dovecot on
service dovecot restart
== Безопасность ==
В связи с тем, что конфигурационные файлы содержат пароль пользователя LDAP, их необходимо сделать недоступным для чтения прочим пользователям:
chown dovecot:root /etc/dovecot/dovecot-ldap.conf.ext
chmod 0640 /etc/dovecot/dovecot-ldap.conf.ext
chown root:postfix /etc/postfix/ad_local_recipients.cf /etc/postfix/ad_mail_groups.cf /etc/postfix/ad_sender_login.cf
chmod 0640 /etc/postfix/ad_local_recipients.cf /etc/postfix/ad_mail_groups.cf /etc/postfix/ad_sender_login.cf
Перезапустите службы:
service dovecot restart
service postfix restart
== Отладка ==
{{Attention|Журнал работы Postfix и Dovecot ведётся в файле {{path|/var/log/maillog}}}}
Для Postfix в файле {{path|/etc/postfix/master.cf}} добавьте параметр -v — вместо
smtps    inet  n      -      n      -      -      smtpd
должно быть
smtps    inet  n      -      n      -      -      smtpd -v
Для Dovecot добавьте в {{path|/etc/dovecot/conf.d/10-logging.conf}}
<source lang="ini">auth_verbose = yes
auth_debug = yes
mail_debug = yes</source>
=== Отладка SMTP ===
<source lang="text" highlight="1,2"># date | mail -s test petrov@test.alt
# mailq
Mail queue is empty</source>
=== Отладка IMAP ===
<source lang="text" highlight="1,3,5"># openssl s_client -crlf -connect test.alt:993
...
tag login petrov@test.alt Pa$$word
tag OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE] Logged in
* STATUS INBOX (MESSAGES 0)
tag OK [CLIENTBUG] Status on selected mailbox completed (0.001 + 0.000 secs).</source>
''Примечание:'' выход по Ctrl+D


== Ссылки ==
== Ссылки ==
* https://www.howtoforge.com/postfix-dovecot-authentication-against-active-directory-on-centos-5.x
* https://www.howtoforge.com/postfix-dovecot-authentication-against-active-directory-on-centos-5.x
* http://help.ubuntu.ru/wiki/почтовый_сервер_с_интеграцией_с_ad
* http://help.ubuntu.ru/wiki/почтовый_сервер_с_интеграцией_с_ad
* http://www.bubnov.su/stati/ustanovka-poctovogo-servera-postfix-dovecot-s-avtorizaciej-v-active-directory
* https://qmail.jms1.net/test-auth.shtml
* https://wiki.dovecot.org/Authentication/Kerberos - настройка аутентификации с помощью GSSAPI


[[Категория:Active Directory]]
[[Категория:Active Directory]]

Текущая версия от 11:46, 30 сентября 2023

Настройка Postfix и Dovecot для аутентификации пользователей в Active Directory.

Задача

Настроить почтовую систему на базе Postfix и Dovecot для работы с базой пользователей Active Directory.

Параметр Значение
Имя домена test.alt
Размещение почты /var/mail/<имя домена>/<имя пользователя> (формат maildir)
Доступ на чтение почты IMAP (порт 993), SSL
Доступ на отправку почты SMTP (порт 465), SSL/STARTTLS
Данные аутентификации: Полный email с доменом (например, petrov@test.alt) или имя пользователя
Журнал работы /var/log/maillog

Принятые ограничения

  • В текущей конфигурации не рассматриваются многодоменные конфигурации;
  • Доступ к службам реализован только с помощью SSL по соображениям безопасности;
  • Уровень домена и леса Active Directory должен быть не выше Windows 2008 R2;
  • В данной версии инструкции не рассматривается конфигурация для подключения Microsoft Exchange на основе MAPI или EWS;
  • Для подключения в данной конфигурации можно использовать Microsoft Outlook версии, начиная с 2003 в режиме подключения почты по IMAP;
  • Внимание! Доступ к серверу LDAP осуществляется по протоколу ldap без шифрования. Для SambaDC отключите обязательный ldaps в /etc/samba/smb.conf в секции [global]:
    ldap server require strong auth = no
    


Подготовка

Создание пользователя в Active Directory

Создаётся пользователь vmail с не истекающей учётной записью:

samba-tool user create -W Users vmail
samba-tool user setexpiry vmail --noexpiry

Настройка Postfix

apt-get install postfix-ldap

Изменение файлов

В каталоге /etc/postfix изменяем файлы для домена test.alt:

main.cf

# Global Postfix configuration file.  This file lists only a small subset
# of all parameters.  For the syntax, and for a complete parameter list,
# see the postconf(5) manual page.  For a commented and more complete
# version of this file see /etc/postfix/main.cf.dist
mailbox_command = /usr/libexec/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
inet_protocols = ipv4

# Mappings
virtual_mailbox_base = /var/mail
virtual_mailbox_domains = test.alt
virtual_mailbox_maps = ldap:/etc/postfix/ad_local_recipients.cf
virtual_alias_maps = ldap:/etc/postfix/ad_mail_groups.cf
virtual_transport = dovecot
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps

# SSL/TLS
smtpd_use_tls = yes
smtpd_tls_security_level = encrypt
#smtpd_tls_security_level = may
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = test.alt
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_sender_login_maps = ldap:/etc/postfix/ad_sender_login.cf
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /var/lib/ssl/certs/dovecot.cert
smtpd_tls_key_file = /var/lib/ssl/private/dovecot.key
smtpd_tls_CAfile = /var/lib/ssl/certs/dovecot.pem

smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, permit_sasl_authenticated, reject
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch
default_destination_recipient_limit = 1
Внимание! Файл /etc/postfix/mydestination должен быть пустым


master.cf

В файл master.cf необходимо добавить:

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -d ${recipient}
smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

ad_local_recipients.cf

version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
scope = sub
query_filter = (&(|(mail=%s)(otherMailbox=%u@%d))(sAMAccountType=805306368))
result_filter = %s
result_attribute = mail
special_result_attribute = member

bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word

ad_mail_groups.cf

version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
timeout = 3
scope = sub
query_filter = (&(mail=%s)(sAMAccountType=268435456))
result_filter = %s
leaf_result_attribute = mail
special_result_attribute = member

bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word

ad_sender_login.cf

version = 3
server_host = test.alt:389
search_base = dc=test,dc=alt
scope = sub
query_filter = (&(objectClass=user)(|(sAMAccountName=%s)(mail=%s)))
result_attribute = mail

bind = yes
bind_dn = cn=vmail,cn=users,dc=test,dc=alt
bind_pw = Pa$$word

Тестируем работу

Проверка конфигурации Postfix (не должно быть никаких сообщений:

# postconf >/dev/null

Проверка пользователя почты petrov:

# postmap -q petrov@test.alt ldap:/etc/postfix/ad_local_recipients.cf
petrov@test.alt

Проверка входа:

# postmap -q petrov@test.alt ldap:/etc/postfix/ad_sender_login.cf
petrov@test.alt

Проверка общего адреса e-mail:

# samba-tool group add --mail-address=sales@test.alt Sales
Added group Sales
# samba-tool group addmembers Sales ivanov,petrov
Added members to group Sales
# postmap -q sales@test.alt ldap:/etc/postfix/ad_mail_groups.cf
sales@test.alt,ivanov@test.alt,petrov@test.alt

Перезапуск службы

Перезапускаем службу postfix:

service postfix restart

Настройка Dovecot

Устанавливаем Dovecot:

apt-get install dovecot

Изменение файлов

dovecot-ldap.conf.ext

Создаём файл /etc/dovecot/dovecot-ldap.conf.ext

hosts            = test.alt:3268
ldap_version     = 3
auth_bind        = yes
dn               = cn=vmail,cn=Users,dc=test,dc=alt
dnpass           = Pa$$word
base             = cn=Users,dc=test,dc=alt
scope            = subtree
deref            = never

user_filter = (&(objectClass=user)(|(mail=%Lu)(sAMAccountName=%Lu)))
user_attrs  = =uid=8,gid=12,mail=user
pass_filter = (&(objectClass=user)(|(mail=%Lu)(sAMAccountName=%Lu)))
pass_attrs = mail=user
Внимание! Значение base не должно содержать только значения dc, иначе при попытке использования будет 'Operation error'.


В каталоге /etc/dovecot/conf.d изменяем файлы для домена test.alt:

10-auth.conf

#auth_username_format = %Lu
#auth_gssapi_hostname = "$ALL"
#auth_krb5_keytab = /etc/dovecot/dovecot.keytab
#auth_use_winbind = no
#auth_winbind_helper_path = /usr/bin/ntlm_auth
#auth_failure_delay = 2 secs
auth_mechanisms = plain
!include auth-ldap.conf.ext

10-mail.conf

mail_location = maildir:/var/mail/%d/%n:UTF-8:INBOX=/var/mail/%d/%n/Inbox
mail_uid = mail
mail_gid = mail
first_valid_uid = 5
first_valid_gid = 5

10-master.conf

service imap-login {
  inet_listener imap {
    port = 0
  }
  inet_listener imaps {
  }
}
service pop3-login {
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    port = 0
  }
}
service lmtp {
  unix_listener lmtp {
  }
}
service imap {
}
service pop3 {
}
service auth {
  unix_listener auth-userdb {
  }
  unix_listener /var/spool/postfix/private/auth {
    mode = 0600
    user = postfix
    group = postfix
  }
}
service auth-worker {
}
service dict {
  unix_listener dict {
  }
}

15-lda.conf

protocol lda {
  hostname = test.alt
  postmaster_address = administrator@test.alt
}

15-mailboxes.conf

namespace inbox {
  inbox = yes
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
}

Проверка конфигурации

Выполните

doveconf >/dev/null

Если конфигурация правильная, ничего не должно вывестись.

После правки конфигурации может вывестись:

doveconf: Error: t_readlink(/var/run/dovecot//dovecot.conf) failed: readlink() failed: No such file or directory

В этом случае перезапустите службу, как описано в следующем шаге, повторите ввод команды и уже ориентируйтесь на вывод после перезапуска службы.

Перезапуск службы

Перезапускаем службу dovecot и включаем её в автозапуск:

chkconfig dovecot on
service dovecot restart

Безопасность

В связи с тем, что конфигурационные файлы содержат пароль пользователя LDAP, их необходимо сделать недоступным для чтения прочим пользователям:

chown dovecot:root /etc/dovecot/dovecot-ldap.conf.ext
chmod 0640 /etc/dovecot/dovecot-ldap.conf.ext
chown root:postfix /etc/postfix/ad_local_recipients.cf /etc/postfix/ad_mail_groups.cf /etc/postfix/ad_sender_login.cf
chmod 0640 /etc/postfix/ad_local_recipients.cf /etc/postfix/ad_mail_groups.cf /etc/postfix/ad_sender_login.cf

Перезапустите службы:

service dovecot restart
service postfix restart

Отладка

Внимание! Журнал работы Postfix и Dovecot ведётся в файле /var/log/maillog


Для Postfix в файле /etc/postfix/master.cf добавьте параметр -v — вместо

smtps     inet  n       -       n       -       -       smtpd

должно быть

smtps     inet  n       -       n       -       -       smtpd -v

Для Dovecot добавьте в /etc/dovecot/conf.d/10-logging.conf

auth_verbose = yes
auth_debug = yes
mail_debug = yes

Отладка SMTP

# date | mail -s test petrov@test.alt
# mailq
Mail queue is empty

Отладка IMAP

# openssl s_client -crlf -connect test.alt:993
...
tag login petrov@test.alt Pa$$word
tag OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE] Logged in
* STATUS INBOX (MESSAGES 0)
tag OK [CLIENTBUG] Status on selected mailbox completed (0.001 + 0.000 secs).

Примечание: выход по Ctrl+D

Ссылки