Безопасное выполнение exec() с правами root из php.

В этой статье я рассказывал, как собрать rpm-пакет. Основой приложения служили php скрипты, которые создавали OpenVPN-сервер, клиентов и могли выслать сертификаты на email. Попробуем прикрутить их к бэкэнду веб-сервера.

Для работы из консоли использовался массив $argv с параметрами команда:ключ. Такой формат записи удобен для форматирования в json. Т.о. чтобы превратить наш core_v1.php в web-api (core_web.php) все что нам нужно — это написать две строчки:

По факту чего мы получим тот же массив $command, который формировали из $argv. Также добавим хидер:

Полный текст скрипта core_wep.php:

Т.к. нам нужно работать с системными папками /etc/openvpn с правом записи и возможностью добавлять и удалять сервисы в ОС есть два простых варианта это осуществить:
1) запустить веб-сервер от root
2) запустить собственный веб-сервер php
Первый вариант более, чем не безопасен. Потому я выбрал второй вариант. Создаю веб-сервер с каталогом, в котором лежит core_web.php. Т.к. данный скрипт к каталогу не привязан, можно разместить его в любом месте ОС. Запуск веб-сервера осуществляется командой:

Здесь важно запустить веб-сервер локально, т.е. в firewall доступ к данному порту закрыт или выброшен в другое место для зоны с интерфейсом сетевой карты. Для интерфейса lo (localhost или 127.0.0.1) открываем порт по средствам привязки данного интерфейса к доверенной зоне (ну или разрешив соединения на порту 999 для текущего случая).
Общаться с внутренним веб-сервером будет внешний, например на apache. Для этого добавим скрипт, который будет перебрасывать запросы/ответы:

Итого получили веб-сервер на Apache, который пробрасывает команды внутреннему веб-серверу с полными правами работы в ОС.
Сами команды мы уже разбирали в предыдущей статье, они аналогичны консольным, отформатированным в json.

Создать/удалить OpenVPN сервер:

Создать/удалить сертификат клиента:

Отправить сертификат на email: