Бывает ситуация, когда нужно отдебажить сложный кейс на удаленной машине, но доступ к серверу есть только под VPN с ограничениями по открытым портам. В статье хочу поделиться с коллегами небольшим «ресерчем» на тему удаленной отладки через SSH под VPN, дабы сэкономить драгоценное время на настройке. Сочту миссию выполненной, если кому-то пригодится данный ман.
Итак, есть удаленный сервер за защищенным контуром. На сервере в докере поднят микросервис с включенным xdebug. Есть доступ снаружи только по SSH и через VPN.
Цель: запустить удаленную отладку микросервиса локально через xdebug.
Поехали…
Первое на что следует обратить внимание — необходимо настроить sshd на сервере так, чтобы он разрешал принимать соединения с любых IP, а не только с 127.0.0.1. По умолчанию эта опция выключена.
Вот здесь нужен root. Будем считать, что он у Вас есть :-)
Поскольку xdebug запускается в докере и подключается сам к локальной машине (а в моем случае этот IP не резолвится, т.к. подключение под VPN), полезно узнать IP хостовой машины в сети docker. Это можно сделать с помощью команды (выполняем на сервере):
Предположим команда выдала «172.17.0.1»
Пример замены через sed, но можно и ручками в редакторе, кому как удобнее:
Не отходя от кассы прописываем «правильный» порт для отладки. В моем случае микросервис поднят на связке nginx & php-fpm и обычно порт 9000 занят под php-fpm, в связи с чем использую для отладки порт 9001.
Здесь же стоит проверить, что удаленная отладка, в принципе, включена: «xdebug.remote_enable=1»
Обычно эти настройки зашиваются в Dockerfile или маунтятся через volume.
На сервере все готово. Теперь переносимся на локальную машину строить тоннель.
Тоннель поднимается командой (выполняем на локальной машине):
В этом месте звучит магическая музыка. Основная настройка выполнена, дальше только отладочная среда.
Обычно я использую vscode, поэтому отладчик через port listening запускается без проблем. Приведу пример конфига для vscode (просто добавьте узел в launch.json):
«pathMappings» — правило мэппинга директорий локальной и удаленной машин, где "/repo" — директория с отлаживаемым кодом в докере. Нужно, чтобы отладчик смог сориентироваться в файлах и точках останова.
Запускаем на локальной машине неткат и прислушиваемся:
Запускаем в докере однолинейный скрипт и печатем:
На локальной машине мы должны увидеть позывные xdebug:
Ура! Все готово.
Теперь можно в IDE отлаживать любимый код на удаленной машине. В описанном методе есть очевидный минус: реконфигурация sshd на сервере. Возможно, есть более «тихий» способ. В любом случае буду рад вашим комментариям и советам.
Спасибо за внимание!
Спойлер
Сервер был развернут на Ubuntu, соответственно далее все серверные настройки будут под Ubuntu. На локальной машине — Mac, но здесь нам понадобится только SSH-клиент и IDE с отладчиком под xdebug, поэтому настройки относительно универсальные.
Вводные
Итак, есть удаленный сервер за защищенным контуром. На сервере в докере поднят микросервис с включенным xdebug. Есть доступ снаружи только по SSH и через VPN.
Цель
Цель: запустить удаленную отладку микросервиса локально через xdebug.
Поехали…
1. Настраиваем sshd на удаленном сервере
Первое на что следует обратить внимание — необходимо настроить sshd на сервере так, чтобы он разрешал принимать соединения с любых IP, а не только с 127.0.0.1. По умолчанию эта опция выключена.
Вот здесь нужен root. Будем считать, что он у Вас есть :-)
sudo echo "GatewayPorts yes" >> /etc/ssh/sshd_config
sudo service ssh restart
2. Узнаем адрес хостовой машины в сети docker
Поскольку xdebug запускается в докере и подключается сам к локальной машине (а в моем случае этот IP не резолвится, т.к. подключение под VPN), полезно узнать IP хостовой машины в сети docker. Это можно сделать с помощью команды (выполняем на сервере):
ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+'
Предположим команда выдала «172.17.0.1»
3. Прописываем IP удаленного хоста в настройки xdebug в контейнере
Пример замены через sed, но можно и ручками в редакторе, кому как удобнее:
sed -i 's/xdebug.remote_host=.*/xdebug.remote_host=172.17.0.1/' /usr/local/etc/php/conf.d/xdebug.ini
Не отходя от кассы прописываем «правильный» порт для отладки. В моем случае микросервис поднят на связке nginx & php-fpm и обычно порт 9000 занят под php-fpm, в связи с чем использую для отладки порт 9001.
sed -i 's/xdebug.remote_port=.*/xdebug.remote_port=9001/' /usr/local/etc/php/conf.d/xdebug.ini
Здесь же стоит проверить, что удаленная отладка, в принципе, включена: «xdebug.remote_enable=1»
grep xdebug.remote_enable /usr/local/etc/php/conf.d/xdebug.ini
Обычно эти настройки зашиваются в Dockerfile или маунтятся через volume.
На сервере все готово. Теперь переносимся на локальную машину строить тоннель.
4. Пробрасываем SSH-тоннель на удаленный сервер
Тоннель поднимается командой (выполняем на локальной машине):
SSH -R 9001:0.0.0.0:9001 user@remote_server
В этом месте звучит магическая музыка. Основная настройка выполнена, дальше только отладочная среда.
Настрока IDE
Обычно я использую vscode, поэтому отладчик через port listening запускается без проблем. Приведу пример конфига для vscode (просто добавьте узел в launch.json):
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9001,
"cwd": "${workspaceFolder}",
"pathMappings": {
"/repo": "${workspaceRoot}"
}
},
«pathMappings» — правило мэппинга директорий локальной и удаленной машин, где "/repo" — директория с отлаживаемым кодом в докере. Нужно, чтобы отладчик смог сориентироваться в файлах и точках останова.
P.S. Ну что, потестим?
Запускаем на локальной машине неткат и прислушиваемся:
nc -l 9001
Запускаем в докере однолинейный скрипт и печатем:
php -r 'print("Hi!" . PHP_EOL);'
На локальной машине мы должны увидеть позывные xdebug:
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug"...
Ура! Все готово.
Теперь можно в IDE отлаживать любимый код на удаленной машине. В описанном методе есть очевидный минус: реконфигурация sshd на сервере. Возможно, есть более «тихий» способ. В любом случае буду рад вашим комментариям и советам.
Спасибо за внимание!