Скрипт для создания почтового ящика в iRedMail (MySQL)
В iRedMail Pro есть API для управления почтовыми ящиками. Мы же рассмотрим процесс создания почтового ящика с помощью своего скрипта в бесплатной версии почтового сервера. В статье будет описан случай, когда учетные записи для почты хранятся в СУБД (MariaDB).
Мы рассмотрим отдельно SQL-запрос для создания почтового ящика в базе данных, а после — скрипт на php, из которого можно будет сделать свой мини API.
Описание запроса в базу данных
Пример скрипта на PHP
Предварительная настройка СУБД
Листинг скрипта
Применение скрипта, как API
Запрос SQL
По умолчанию, почтовые ящики iRedMail хранятся в базе данных vmail, таблице mailbox. Чтобы создать новый, нужно просто выполнить SQL-запрос на вставку новой записи. В самой таблице более 50 полей, но нам нужно заполнить всего 6:
- username — имя учетной записи в виде адреса электронной почты.
- password — пароль с указанием хэша. По умолчанию используется SSHA512. Процесс генерации из командной строки будет показан ниже.
- language — язык по умолчанию. На самом деле, можно оставить и пустым — на запрос это не повлияет, но для удобства лучше сразу указать язык.
- maildir — путь к каталогу для хранения почты. Данный путь собирается из домена, первых 3-х букв в имени пользователя, а также даты и времени создания почтового ящика.
- domain — домен, для которого создается почта.
- created — дата и время создания почтового ящика.
Остальные поля можно не указывать — значения для них по умолчанию нас, вполне, устроят.
И так, чтобы получить хэш для пароля нового почтового ящика в командной строке на сервере iRedmail выполняем команду:
doveadm pw -s 'ssha512' -p 'password123'
* где doveadm — административная утилита dovecot, которая устанавливается вместе с iredmail; ssha512 — указание алгоритма шифрования; password123 — наш пароль.
В результате выполнения команды мы получим что-то на подобие:
{SSHA512}iNX3KgDLYVvA+nQKlJf4GUVOTLwiyxYpBoAD1NBs1CK0rIG4XVbPXWWeN5lRrMXljQD16s9q9ny+EO8iX7SpnbH/+K0=
Это и будет хэш пароля, который мы будем использовать для запроса.
И так, синтаксис самого запроса SQL выглядит так:
INSERT INTO mailbox (`username`, `password`, `language`, `maildir`, `domain`, `created`) VALUES ('<username>', '<password>', '<language>', '<maildir>', '<domain>', '<created>');
Пример запроса:
INSERT INTO mailbox (`username`, `password`, `language`, `maildir`, `domain`, `created`) VALUES ('testmaster@dmosk.ru', '{SSHA512}iNX3KgDLYVvA+nQKlJf4GUVOTLwiyxYpBoAD1NBs1CK0rIG4XVbPXWWeN5lRrMXljQD16s9q9ny+EO8iX7SpnbH/+K0=', 'ru_RU', 'dmosk.ru/t/e/s/testmaster-2020.02.25.22.52.53/', 'dmosk.ru', '2020-02-25 22:53:50');
* в данном запросе мы добавим почтовый ящик testmaster@dmosk.ru с паролем password123 (хэш мы генерировали выше), по умолчанию для пользователя будет использоваться русский язык. Обратите внимание на каталог для почты dmosk.ru/t/e/s/testmaster-2020.02.25.22.52.53 — как и говорилось выше, его путь собран из домена, первых 3-х букв в имени пользователя, а также даты и времени создания почтового ящика.
Данный запрос можно выполнить в phpmyadmin или командной консоли mysql — для подключения к ней на почтовом сервере вводим:
mysql -uroot -p
... и вводим пароль пользователя root от СУБД. После подключаемся к базе vmail:
> use vmail
Можно выполнять запросы.
После можно проверить работоспособность почтовых ящиков с помощью roundcube или другого почтового клиента.
Скрипт на PHP
Разобравшись с процессом создания записи в базе данных, создадим скрипт, который будет проверять нет ли уже такой учетной записи и сложность ее пароля. Разобьем процесс на подготовку базы данных и написание самого скрипта.
Подготовка базы данных
Для того, чтобы максимально обезопасить работу с данными, мы создадим отдельного пользователя в MariaDB / MySQL, который будет иметь доступ на чтение и запись только в таблицу mailbox.
На сервере заходим в командную оболочку SQL:
mysql -uroot -p
Создаем пользователя, от которого будет вестись работа с таблицей mailbox:
> GRANT SELECT, UPDATE, INSERT ON vmail.mailbox TO 'apiuser'@'localhost' IDENTIFIED BY '123password!';
* в данном примере мы создаем пользователя apiuser, который сможет подключиться к базе только с локального сервера (предполагается, что скрипт будет работать на сервере iRedMail). Пароль пользователя будет 123password!, а доступ ограничен только на запросы SELECT, UPDATE, INSERT и только на таблицу mailbox базы vmail.
Подробнее процесс создания пользователя в СУБД на базе MySQL описан в инструкции Создание пользователей MySQL/MariaDB и предоставление прав доступа.
После настройки привилегий, можно приступить к написанию самого скрипта.
Пример скрипта на PHP
И так, сам скрипт будет выглядеть так:
- <?php
- function mysql_conn() {
- $mi_conn = mysqli_connect('localhost', 'apiuser', '123password!', 'vmail') or die("MySQL connect error");
- mysqli_query($mi_conn, "SET NAMES 'utf8'");
- return $mi_conn;
- }
- function check_mailbox($username) {
- // Проверяем на наличие в базе
- global $mi_conn;
- $result = mysqli_query($mi_conn, "SELECT * FROM mailbox WHERE `username`='{$username}'");
- $mass = mysqli_fetch_array($result);
- if ($mass['username']) {
- return "Почтовый ящик уже существует.";
- }
- // Проверяем на правильность формата (учетная запись должна быть в виде email)
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- return "Адрес {$username} указан не верно.";
- }
- }
- function check_password($password) {
- // Проверка сложности на количество символов
- global $password_min_length;
- $length = mb_strlen($password, 'UTF-8');
- if ($length < $password_min_length) {
- return "Пароль должен быть более {$password_min_length} символов.";
- }
- // Проверка сложности на наличие цифр и букв
- preg_match('/\d/', $password, $d_matches);
- preg_match('/\w/', $password, $w_matches);
- if (!$d_matches[0] || !$w_matches[0]) {
- return "Пароль должен содержать буквы и цифры.";
- }
- }
- function create_mailbox($username, $password) {
- // Проверка учетной записи на наличие в базе и правильность формата
- $result_check_mailbox = check_mailbox($username);
- if ($result_check_mailbox) {
- return "Ошибка при создании учетной записи. {$result_check_mailbox}";
- }
- // Проверка пароля на сложность
- $result_check_password = check_password($password);
- if ($result_check_password) {
- return "Ошибка при создании учетной записи. {$result_check_password}";
- }
- // Создаем почтовую учетную запись
- global $mi_conn;
- $username_arr = explode("@", $username);
- $user = $username_arr[0];
- $domain = $username_arr[1];
- $username_3char = str_replace('.', '_', implode('/', str_split(mb_substr($user, 0, 3))));
- $username_createdate = date("Y.m.d.H.i.s");
- $createdate = date("Y-m-d H:i:s");
- $password_hash = exec("doveadm pw -s 'ssha512' -p '{$password}'");
- $username_path = "{$domain}/{$username_3char}/{$user}-{$username_createdate}/";
- if (mysqli_query($mi_conn, "INSERT INTO mailbox (`username`, `password`, `language`, `maildir`, `domain`, `created`) VALUES ('{$username}', '{$password_hash}', 'ru_RU', '{$username_path}', '{$domain}', '{$createdate}')")) {
- return "Учетная запись создана";
- } else {
- return "Ошибка sql-запроса";
- }
- }
- $username = $_POST[username];
- $password = $_POST[password];
- $password_min_length = 8;
- $mi_conn = mysql_conn();
- $result = create_mailbox($username, $password);
- echo $result;
- ?>
Описание скрипта:
Строки | Описание |
---|---|
3-7 | Функция подключения к базе данных. в данном примере идет соединение от учетной записи, которую мы создали при настройке MySQL выше. В итоге, функция возвращает переменную со ссылкой подключения к базе. |
9-22 | Данная функция проверяет корректность добавляемого пользователя. Сначала мы проверяем, есть ли уже такой пользователь в базе, и если есть — возвращаем ошибку. После мы проверяем формат введенного email адреса. |
24-37 | Проверяем пароль на сложность. В первую очередь мы проверяем, что пароль более 7 символов. Во вторую — что в пароле есть и символы и цифры. |
39-67 | Данная функция, собственно, создает учетную запись. Сначала мы вызываем функцию проверки на наличие в базе и правильности формата введенного имени создаваемой записи, затем проверяем пароль. Если проверки не вернули ошибку, мы выполняем запрос SQL на вставку записи. |
69 | Задаем переменную с именем учетной записи. В качестве значения мы принимаем переменную, отправленную в виде запроса POST. |
70 | Задаем переменную с паролем. В качестве значения мы принимаем переменную, отправленную в виде запроса POST. |
71 | Указываем минимальную длину пароля, который должен задаваться учетной записи. |
73 | Вызываем функцию подключения к базе, результат заносим в переменную. |
74 | Вызываем функцию создания учетной записи. Результат ее работы заносим в переменную $result. |
76 | Выводим содержимое переменной $result. |
API
Полученный нами скрипт нужно скопировать на веб-сервер — мы получим возможность отправлять на него запросы POST, что позволит говорить о создании примитивного API по созданию почтовых учетных записей на сервере iRedMail.
Для запуска написанного нами скрипта нужно отправить POST запрос на http-сервер. Пример скрипта на PHP, который это делает:
- <?php
- function my_curl_uni($url, $postfields) {
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
- $return = curl_exec($curl);
- curl_close($curl);
- return $return;
- }
- $url = "http://api.dmosk.ru";
- $postfields = array('username'=>'test@dmosk.ru', 'password'=>'test123test');
- $result = my_curl_uni($url, $postfields);
- print_r($result);
- ?>
Описание скрипта:
Строки | Описание |
---|---|
3-15 | Функция отправки POST запроса с помощью CURL. В качестве аргументов она принимает http-адрес, на который нужно отправить запрос и массив данных. Возвращает функция ответ нашего скрипта. |
17 | Задаем переменную с адресом, на который будет отправлен запрос. В моем примере это api.dmosk.ru — от будет запускать написанный нами скрипт для создания почтового ящика. |
18 | Создаем массив данных — в качестве первого элемента передаем username, второго — password. |
19 | Вызываем нашу функцию по отправке запроса POST. Результат передаем в переменную $result. |
20 | Выводим на экран содержимое ответа (переменная $result). |