Dovecot+Postfix

Введение

Решил на днях присмотреться к данному IMAP/POP3 серверу. Давно его советовали и рекомендовали, но как-то не хватало времени, чтобы изучить его. А тут как раз и Final Release 1.0 вышел (после 5 лет разработки).

Итак, почему именно dovecot? Думаю, прочитав документацию, поставляемую с dovecot, вы и сами поймете его плюсы и преимущества, к которым можно отнести следующее:

  • поддержка форматов maildir, maildir++, mailbox;
  • включает в себя как imap сервер, так и pop;
  • в качестве backend'ов может использовать mysql, postgresql, ldap;
  • может выступать в качестве сервера аутентификации для exim и postfix;
  • хорошая документация на сайте - http://wiki.dovecot.org/;
  • поддержка динамических модулей аутентификации;
  • поддержка динамических модулей pop3 и imap;
  • поддержка квот;
  • очень гибкий файл настроек с хорошими комментариями;
  • основной упор при написании автор делал на безопасность, за последние несколько лет не было найдено ни одной критической уязвимости;
  • поддерживает все основные механизмы аутентификации: PLAIN, LOGIN, DIGEST-MD5, CRAM-MD5, ANONYMOUS, NTLM, RPA, APOP, GSSAPI;
  • В отличие от courier-imap входит в поставку Red Hat, CentOS, Debian, SuSe что тоже является очень удобным при обновлении системы;
  • поддержка SSL/TLS, хотя сейчас этим, наверное, никого уже не удивишь, но у меня не получилось настроить courier-imap на одновременную корректную работы с SSL/TLS с наиболее распространенными MUA (The Bat, Outlook Express/Outlook, Thunderbird). Dovecot же заработал сразу без проблем;
  • так же очень понравилась возможность запрета использовать методы аутентификации, основанные на передаче пароля в открытом виде, т.н. plaintext, если не используется SSL/TLS;
  • одновременная поддержка системных и виртуальных пользователей, без необходимости делать дубликаты системных пользователей в БД виртуальных пользователей;

Думаю этих аргументов более чем достаточно для того, чтобы обратить свое внимание на данное ПО.

Но так как данное ПО предоставляет не только непосредственно функции IMAP/POP сервера, то почему бы не использовать его возможности на все 100%. Итак, в качестве MDA(Mail Delivery Agent)/LDA(Local Delivery Agent) совместно с постфикс мы будем использовать LDA dovecot, что позволит нам использовать язык фильтрации sieve. Dovecot также будет выступать в качестве сервера SASL (данная функция доступна только начиная с версии Postfix 2.3) и производить smtp аутентификацию.

Установка и настройка

Установку и настройку я буду производить на CentOS 5. На freebsd все как всегда устанавливаем из портов. Итак, в распоряжении у нас есть:

# uname -a
Linux gw.sys-adm.org.ua kernel-2.6.18-8.1.1.el5 #1 SMP Thu Mar 15 19:57:35 EDT 2007 i686 athlon i386 GNU/Linux

# cat /etc/redhat-release
CentOS release 5 (Final)

Как всегда устанавливаем из rpm пакета. Так же можно установить с помощью yum, кому как удобнее. К сожалению, версия dovecot, которая идет с дистрибутивом относительно старая (1.0.rc15), а также нет возможности собрать пакет dovecot-sieve, так как для его сборки требуется отсутствующий пакет dovecot-devel. Так что я рекомендую собрать эти два пакета самому из src.rpm. После того, как мы собрали rpm пакеты, устанавливаем их.

# rpm -ivh dovecot-1.0.0-8_56.i686.rpm dovecot-sieve-1.0.1-5.i686.rpm
Preparing...                ########################################### [100%]
   1:dovecot                ########################################### [ 50%]
   2:dovecot-sieve          ########################################### [100%]

Собственно на этом установка завершена. У dovecot один основной конфигурационный файл, который располагается в /etc/dovecot.conf. Вот его настройкой мы и займемся. Данный файл обладает большим количеством настроек и содержит хорошие комментарии. Так что я буду приводить лишь те параметры, значения которых я изменял, все остальные параметры имеют значения по умолчанию.

По умолчания dovecot.conf устанавливается в папку /etc, что на мой взгляд не очень удобно. Поэтому я поправил spec файл и теперь у меня все конфигурационные файлы находятся в папке /etc/dovecot.

#
# /etc/dovecot/dovecot.conf
#

# Протоколы, которые мы хотим поддерживать: imap imaps pop3 pop3s
# Если вы хотите использовать только dovecot-auth, вы можете задать "none".
protocols = pop3 pop3s

# IP или адрес хоста, где необходимо слушать соединения. В данный момент
# невозможно задать множество адресов. "*" прослушивает все IPv4 интерфейсы.
# "[::]" прослушивает все IPv6 интерфейсы, но так же может слушать все IPv4
# интерфейсы, зависит от операционной системы.
#
# Если вы хотите указать порты для каждого сервиса, вам необходимо настроить
# эти параметры внутри секции protocol imap/pop3 { ... }, таким образом вы
# сможете задать различные порты для IMAP/POP3. Например:
#   protocol imap {
#     listen = *:10143
#     ssl_listen = *:10943
#     ..
#   }
#   protocol pop3 {
#     listen = *:10100
#     ..
#   }
#listen = [::]

protocol pop3 {
         listen = *:110
         ssl_listen = *:995
}

# Отключает команду LOGIN и все остальные plaintext методы аутентификации пока
# не будет использован SSL/TLS. Примечание если удаленный ip соответствует
# локальному ip (например, вы подключаетесь с того же компьютера), соединение
# будет считаться безопасным и plaintext методы аутентификации будут разрешены.
disable_plaintext_auth = yes

##
## Logging
##

# Использовать этот log файл вместо syslog().
log_path = /var/log/dovecot.log

# Сохранять информационные сообщения в этот файл
info_log_path = /var/log/dovecot.log

##
## SSL settings
##

# Отключить поддержку SSL/TLS.
# no - поддержка SSL/TLS включена
# yes - поддержка SSL/TLS отключена
ssl_disable = no

# В данных параметрах задаются X.509 SSL/TLS сертификат и закрытый ключ,
# в формате PEM. Они считываются перед тем, как dovecot перестает работать
# с привилегиями root, так что права на чтение должен иметь только root.
# Как создать сертификат и ключ читаем - ssl-howto.
# установите права на этот файл - root:root 0444
ssl_cert_file = /etc/pki/dovecot/certs/gw.sys-adm.org.ua.crt
# установите права на этот файл - root:root 0400
ssl_key_file = /etc/pki/dovecot/private/gw.sys-adm.org.ua.key

# Задает периодичность регенерации файла SSL параметров. Во время процесса
# регенерации производится интенсивное использование центрального процессора,
# так что на слабых машинах не следует указывать слишком маленький интервал
# времени. На современных компьютерах время регенерации занимает всего
# несколько секунд. Значение задается в часах, 0 - полностью отключает
# регенерацию.
ssl_parameters_regenerate = 1

# Список используемых SSL протоколов. Полный список протоколов можно
# посмотреть по адресу - http://www.openssl.org/docs/apps/ciphers.html
ssl_cipher_list = ALL:!LOW:!SSLv2

# Показывать ошибки уровня протокола SSL. Полезно использовать только
# во время отладки, после этого лучше отключить.
verbose_ssl = yes

##
## Login processes
##

# Сообщение приветствия для клиентов
login_greeting = Welcome to sys-adm IMAP/POP3 server.

##
## Mailbox locations and namespaces
##

# Месторасположение пользовательских почтовых ящиков. Это такой же параметр
# как и старый default_mail_env. Значение по умолчанию отсутствует, это
# означает, что Dovecot попытается найти ящики автоматически. Это не будет
# работать, если у пользователя до сих пор нет никакой почты, поэтому вы
# должны непосредственно указать Dovecot полный путь к ящику.
#
# Если вы используете mbox, указание пути к INBOX файлу (например, /var/mail/%u)
# недостаточно. Вам также необходимо указать Dovecot где находятся другие ящики
# и где Dovecot может расположить файлы с индексами. Это называется "корневая
# почтовая директория", и она должна быть указана первой в параметре mail_location.
#
# Существует несколько специальных переменных, которые вы можете использовать:
#
#   %u - имя пользователя
#   %n - пользовательская часть в user@domain, то же самое что и %u
#   если не задана доменная часть
#   %d - доменая часть в user@domain, пустая, если не указан домен
#   %h - домашняя директория
#
# Смотрите doc/variables.txt для полного списка переменных.
#
# Некоторые примеры:
#   mail_location = maildir:~/Maildir
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
mail_location = maildir:/var/spool/mail/%d/%u

##
## Mail processes
##

# Включает отладку, очень полезно при первоначальной настройке и поиске
# неисправностей. После настройки лучше отключать.
mail_debug = yes

# Допустимый интервал UID для пользователей, по умолчанию 500 и выше.
# Это сделано для того, чтобы быть увереным в том, что пользователи
# не смогут войти как демоны или другие системные пользователи.
# Примечание запрет входа root встроен в бинарник dovecot и не может
# быть изменен, даже если установить first_valid_uid в 0.
# 1981 - uid и gid пользователя и группы virtual соответственно,
# которых мы создавали в Mail Howto
first_valid_uid = 1981
last_valid_uid = 1981

# Valid GID range for users, defaults to non-root/wheel. Users having
# non-valid GID as primary group ID aren't allowed to log in. If user
# belongs to supplementary groups with non-valid GIDs, those groups are
# not set.
first_valid_gid = 1981
last_valid_gid = 1981

##
## LDA specific settings
##

protocol lda {
  # Адрес, используемый при отправке отклоненной почты.
  # Например, при превышении пользователем квоты.
  # Address to use when sending rejection mails
  postmaster_address = postmaster@sys-adm.org.ua

  # Поддержка динамически загружаемых плагинов. Параметр mail_plugins
  # задает разделенный пробелами список плагинов, которые будут загружены.
  mail_plugins = cmusieve
  mail_plugin_dir = /usr/lib/dovecot/lda

  # Имя хоста, используемое в различных частях отсылаемой почты,
  # например Message-Id. По умолчанию действительное имя хоста.
  hostname = gw.sys-adm.org.ua
}

##
## Authentication processes
##

#
# Следующих три параметра следует использовать только во мремя настройки
# и отладки dovecot. После этого их лучше отключить.
#

# Более высокий уровень информативности. Полезно использовать при поиске
# ошибок, связанных с аутентификацией.
auth_verbose = yes

# Более высокий уровень информативности, используется в целях отладки.
# Например, показывает SQL запросы.
auth_debug = yes

# В случае несовпадения пароля, отображает пароли и испоьзуемую схему
# хранения пароля. Требует, чтобы был установлен auth_debug=yes.
auth_debug_passwords = yes

auth default {
  # Разделенный пробелами список, используемых механизмов аутентификации:
  # plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi
  mechanisms = plain login cram-md5

  #
  # База данных паролей используется для проверки паролей пользователей
  # (и ничего более). Вы можете использовать множество passdbs и userdbs.
  # Это полезно, если вы хотите позволить обоим - системным пользователям и
  # (/etc/passwd) и виртуальным пользователям входить без необходимости
  # делать дубликаты системных пользователей в БД виртуальных пользователей.
  #
  # http://wiki.dovecot.org/PasswordDatabase
  #
  # Пользователи могут быть временно отключены с помощью добавления deny=yes
  # в passdb. Если пользователь найден в БД, аутентификация потерпит неудачу.
  # БД с отключенными пользователями всегда должна быть указана перед остальными,
  # так как ее проверка идет первой.

  # SQL database
  passdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }

  #
  # База данных пользователей указывает месторасположение почтовых ящиков
  # и пользователя/группу владеющего этим ящиком.
  #
  # http://wiki.dovecot.org/UserDatabase
  #

  # SQL database
  # http://wiki.dovecot.org/AuthDatabase/SQL
  userdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }

  # Пользователь, от имени которого будет работать процесс. Этот пользователь
  # должен иметь доступ только к БД пользователей и паролей и никуда больше.
  # Только shadow и pam аутентификация требует пользователя root, так что по
  # возможности используйте пользователя отличного от root . Примечание:
  # этот пользователь НЕ ИСПОЛЬЗУЕТСЯ для доступа к почте. Для доступа
  # к почте используется пользователь заданный выше в userdb.
  user = virtual

  socket listen {
    master {
      # Данный сокет обычно используется, чтобы дать доступ dovecot LDA
      # к userdb, для того, чтобы он мог найти информацию о месторасположении
      # почтовых ящиков пользователей. Данный сокет может также использоваться
      # для обычной аутентификации пользователей.
      # ПРЕДУПРЕЖДЕНИЕ: Не давайте права доступа к этому сокету недоверенным
      # пользователям. Это может привести к нарушению безопасности системы.
      # По возможности ограничьте доступ к данному сокету.
      path = /var/run/dovecot/auth-master
      mode = 0600
      user = virtual
      group = virtual
    }
    client {
      # Обычно безопасно давать полный доступ к данному сокету.
      # Как правило, данный сокет используют SMTP сервера для того, чтобы
      # производить smtp аутентификацию.
      path = /var/spool/postfix/private/dovecot-smtp-auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}

Мне было лень переводить весь конфигурационный файл ;). Так что если вас интересуют все настройки и их значение можете посмотреть полный перевод dovecot.conf, который сделал мой знакомый - Алексей Кеда aka Lissyara. Единственное замечание, в данной статье приводилось описание конфигурационного файла dovecot версии 0.9x, а в своей статье я использую dovecot версии 1.0, между этими версиями есть небольшие отличия в конфигурационных файлах, обращайте на это внимание.

#
# /etc/dovecot/dovecot-mysql.conf
#
# Этот файл открывается от имени пользователя root, поэтому его владельцем
# должен быть root, а права на файл должны быть 0600.
#
# Для sql модуля passdb, вам необходима БД с таблицей, содержащей по
# крайней мере поля userid и password. Если вы хотите использовать
# синтаксис user@domain, возможно вы захотите использовать отдельное
# поле, содержащее имя домена.
#
# В качестве структуры БД используем БД из postfixadmin.

# Драйвер базы данных: mysql, pgsql, sqlite
driver = mysql

# Строка соединения с БД. Данный параметр зависит от драйвера.
#
# mysql:
#   Базовые настройки повторяют опции PostgreSQL:
#     host, port, user, password, dbname
#
#   Но также имеют некоторые новые параметры:
#     client_flags        - Смотрите руководства пользователя MySQL
#     ssl_ca, ssl_ca_path - Set either one or both to enable SSL
#     ssl_cert, ssl_key   - Для отправки клиентского сертификата серверу
#     ssl_cipher          - Задает минимально разрешенный уровень безопасности
#
#   Вы можете соединиться с сокетом UNIX используя : host=/var/run/mysql.sock
#   Примечания: В данный момент вы не можете использовать пробелы в параметрах.
#
#
# Примеры:
#   connect = host=192.168.1.1 dbname=users
#   connect = host=sql.example.com dbname=virtual user=virtual password=blarg
#   connect = /etc/dovecot/authdb.sqlite
#
#connect = dbname=virtual user=virtual
connect = host=/var/lib/mysql/mysql.sock dbname=postfix user=postfix password=postfix

# Схема хранения паролей по умолчанию
#
# Список поддерживаемых схем приведен в
# http://wiki.dovecot.org/Authentication/PasswordSchemes
#
default_pass_scheme = PLAIN

# Запрос для получения пароля.
#
# Этот запрос должен возвращать только одну строку с полями "user" и "password".
# Этот запрос также может возвращать другие поля, которые имеют специальное
# значение, смотрите http://wiki.dovecot.org/PasswordDatabase/ExtraFields
#
# The "user" column is needed to make sure the username gets used with exactly
# the same casing as it's in the database. Note that if you store username and
# domain in separate fields, you most likely want to return a combination of
# them as the "user" column, otherwise the domain gets stripped.
#
# Commonly used available substitutions (see
# http://wiki.dovecot.org/Variables for full list):
#   %u = entire userid
#   %n = user part of user@domain
#   %d = domain part of user@domain
#
# Note that these can be used only as input to SQL query. If the query outputs
# any of these substitutions, they're not touched. Otherwise it would be
# difficult to have eg. usernames containing '%' characters.
#
# Example:
#   password_query = SELECT password FROM users WHERE userid = '%n' AND domain = '%d'
#   password_query = SELECT pw AS password FROM users WHERE userid = '%u' AND active = 'Y'
#
#password_query = SELECT userid as user, password FROM users WHERE userid = '%u'
password_query = SELECT username as user, password \
FROM mailbox WHERE username = '%u' and active='1'

# Query to retrieve the user information.
#
# The query must return only one row. Commonly returned columns are:
#   uid - System UID
#   gid - System GID
#   home - Home directory
#   mail - Mail location
#
# Either home or mail is required. uid and gid are required. If more than one
# row is returned or there are missing fields, the login will fail. For a list
# of all fields that can be returned, see
# http://wiki.dovecot.org/UserDatabase/ExtraFields
#
# Примеры
# user_query = SELECT home, uid, gid FROM users WHERE userid = '%n' AND domain = '%d'
# user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u'
#
#user_query = SELECT home, uid, gid FROM users WHERE userid = '%u'
user_query = SELECT maildir, 1981 AS uid, 1981 AS gid \
FROM mailbox WHERE username = '%u' and active='1'

# ПРИМЕЧАНИЕ: dovecot не поддерживает перенос строки при помощи символа - '\',
# так что запросы в user_query и password_query необходимо писать в одну строку.

Настройка dovecot LDA

Для того, чтобы в качестве транспорта использовать dovecot LDA нам необходимо внести небольшие изменения в два файла: master.cf и main.cf. В первом файле мы должны непосредственно описать сам транспорт, а во втором указать postfix, использовать этот транспорт для всех виртуальных доменов, а также использовать dovecot в качестве SASL сервера.

#
# /etc/postfix/main.cf
#

# Здесь я лишь указываю изменения в файле main.cf по сравнению с
# версией приведенной в FreeBSD Mail Howto

# Указываем postfix какой использовать транспорт для виртуальных
# доменов (по умолчанию - virtual). Если вы используете postfixadmin
# для управления доменами, то транспорт необходимо задавать непосредственно
# в самом postfixadmin, а не через параметр virtual_transport.
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

# Указываем postfix что SASL авторизацию будет производить dovecot,
# а также указываем путь к сокету. Примечание: путь к сокету задан
# относительно папки /var/spool/postfix
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/dovecot-smtp-auth

А теперь описываем сам транспорт в файле master.cf. Для этого в самый конец файла добавляем следующие строки.

#
# /etc/postfix/master.cf
#

# Dovecot LDA
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=virtual:virtual argv=/usr/libexec/dovecot/deliver -d ${recipient}

Тестирование

Теперь у нас все готово к тестированию нашей связки. Запускаем dovecot, но перед этим не забываем создать log-файл.

# touch /var/log/dovecot.log
# chown dovecot:virtual /var/log/dovecot.log
# service dovecot start
Starting Dovecot Imap:                                     [  OK  ]
# cat /var/log/dovecot.log
dovecot: May 10 04:03:11 Info: Dovecot v1.0.0 starting up
dovecot: May 10 04:03:11 Info: auth-worker(default): mysql: Connected to /var/lib/mysql/mysql.sock (postfix)

Как видно из сообщения, dovecot успешно запустился. Теперь попробуем с помощью любимого MUA получить почту.

dovecot: May 10 04:10:42 Info: pop3-login: Login failed: Plaintext authentication disabled: rip=212.42.65.90, lip=212.42.65.15
dovecot: May 10 04:10:42 Info: pop3-login: Disconnected: rip=212.42.65.90, lip=212.42.65.15

Как видно из сообщения, если не используется SSL/TLS, то plaintext аутентификация запрещена. Теперь включаем шифрованное соединение (используем 995 порт) и пробуем еще раз.

dovecot: May 10 04:12:32 Info: pop3-login: Login: user=, method=PLAIN, rip=212.42.65.90, lip=212.42.65.15, TLS
dovecot: May 10 04:12:32 Info: POP3(alex@sys-adm.org.ua): Disconnected: Logged out top=0/0, retr=3/2942, del=3/3, size=2893

Как видно из логов мы использовали метод PLAIN, как и в первом случае, но теперь соединение было зашифровано, о чем свидетельствуют буквы TLS.

Теперь проверим, как dovecot производит SASL аутентификацию. Для этого запускаем postfix.

# service postfix start
Starting postfix:                                          [  OK  ]

И для наглядности с помощью telnet эмулируем smtp сессию.

# telnet 212.42.65.15 25
Trying 212.42.65.15...
Connected to 212.42.65.15 (212.42.65.15).
Escape character is '^]'.
220 mail.sys-adm.org.ua ESMTP
--> ehlo gw.sys-adm.org.ua
250-mail.sys-adm.org.ua
250-PIPELINING
250-SIZE 5242880
250-ETRN
250-AUTH PLAIN LOGIN CRAM-MD5
250-AUTH=PLAIN LOGIN CRAM-MD5
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
--> auth plain
334
--> AGFsZXhAYWtrby5jb20udWEAMTIz
235 2.0.0 Authentication successful
--> mail from:<alex@sys-adm.org.ua>
250 2.1.0 Ok
--> rcpt to:<root@sys-adm.org.ua>
250 2.1.5 Ok
--> data
354 End data <CR><LF>.<CR><LF>
--> Hello world
--> .
250 2.0.0 Ok: queued as 3F62F511A9
--> quit
221 2.0.0 Bye
Connection closed by foreign host.

Как видно из самой сессии аутентификация прошла успешно, а список методов аутентификации - 250-AUTH PLAIN LOGIN CRAM-MD5 действительно совпадает с тем, что мы задали в файле dovecot.conf в параметре mechanisms в разделе auth default. А теперь посмотрим что же у нас в log-файл.

# cat maillog | grep 3F62F511A9
May 13 23:55:26 net postfix/smtpd[3072]: connect from gw.sys-adm.org.ua[212.42.65.15]
May 13 23:55:46 net postfix/smtpd[3072]: 3F62F511A9: client=gw.sys-adm.org.ua[212.42.65.15], sasl_method=plain, sasl_username=alex@sys-adm.org.ua
May 13 23:55:50 net postfix/cleanup[3126]: 3F62F511A9: message-id=<20070513205546.3F62F511A9@mail.sys-adm.org.ua>
May 13 23:55:50 net postfix/qmgr[2731]: 3F62F511A9: from=<alex@sys-adm.org.ua>, size=352, nrcpt=1 (queue active)
May 13 23:55:50 net postfix/pipe[3128]: 3F62F511A9: to=<root@sys-adm.org.ua>, relay=dovecot, delay=11, delays=11/0.03/0/0.05, dsn=2.0.0, status=sent (delivered via dovecot service)
May 13 23:55:50 net postfix/qmgr[2731]: 3F62F511A9: removed
May 13 23:55:51 net postfix/smtpd[3072]: disconnect from gw.sys-adm.org.ua[212.42.65.15]

Итак, как мы видим, аутентификация успешно прошла с использованием метода PLAIN и письмо было доставлено пользователю в ящик с использованием dovecot lda, о чем свидетельствует строка - delivered via dovecot service.

Фото автора
Артем Ведун
ИТ-специалист, исследователь цифровой гармонии

Более 15 лет работаю в сфере информационных технологий — от системного администрирования и DevOps до анализа сетевой безопасности. В какой-то момент понял, что цифровые процессы и числа — не только про технологии, но и про закономерности, которые управляют жизнью.

Так начался мой путь в прикладную нумерологию и изучение того, как числа влияют на решения, инфраструктуру и даже ИТ-проекты.

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

Верю, что в мире нет случайных чисел — даже в логах сервера.

Последние Статьи

Как выбрать частного SEO‑специалиста в Киеве: практическое руководство

Как выбрать частного SEO‑специалиста в Киеве: практическое руководство

В Киеве существует множество SEO‑услуг: крупные агентства, маленькие студии и частники, с разными подходами и ценами. Для бизнеса важно найти того специалиста, который пониманием задач, прозрачностью ..

Что предлагает KupiFanove.bg? для соц.сетей (smm)

Что предлагает KupiFanove.bg? для соц.сетей (smm)

KupiFanove.bg специализируется на предоставлении услуг по увеличению числа подписчиков и лайков в следующих социальных сетях: Instagram: Покупка подписчиков для повышения авторитета и доверия к ваш..

Почему вам нужен список SEO компаний в Варне?

Почему вам нужен список SEO компаний в Варне?

Сегодня Google обрабатывает более 40 000 поисковых запросов каждую секунду! С такими ошеломляющими цифрами выделиться среди жесткой конкуренции требует профессионального опыта от опытной SEO-команды. ..

Время 02:02 на часах: ангельская нумерология

Время 02:02 на часах: ангельская нумерология

Когда вы в очередной раз случайно бросаете взгляд на часы, и там застыли 02:02, это может быть не просто цифра — это тонкий знак от невидимого мира. Такие зеркальные времена не приходят в жизнь без пр..

Подписаться на рассылку