У меня довольно сложная ситуация, когда внешний сервер вне корпоративной сети разговаривает с сервером MSSQL внутри корпоративной сети. Цель состоит в том, чтобы загрузить данные из базы данных в реальном времени в облачное приложение для клиента. Я работаю на поставщика облачных приложений. Облачное приложение - это решение для аналитики «больших данных».
Клиент настаивает на хранении своей базы данных в стенах собственной сети, поэтому перенос всей БД в облако невозможен.
У нас есть следующие настройки:
Сервер 1) Виртуальный сервер Ubuntu, расположенный на AWS, запускает облачное приложение. Ожидается, что облачное приложение получит IP-адрес и порт сервера MSSQL. У нас есть root-доступ к этому.
Сервер 2) Физический сервер Ubuntu, находящийся внутри корпоративной сети. Мы добавили это для согласования данных маршрутизации с внешними облачными службами. У нас есть root-доступ к этому, и мы можем делать с ним все, что захотим
Сервер 3) Сервер базы данных MSSQL, находящийся внутри корпоративной сети. Этот сервер базы данных используется широким спектром клиентских бизнес-приложений, поэтому понятно, что корпоративный ИТ-отдел хочет, чтобы мы оставили это в покое. У нас нет корневого доступа к этому серверу. У нас есть учетная запись пользователя, доступная только для чтения, для подключения к базе данных.
| (Corporate network)
(Cloud provider) |
[Server 1] <=====(reverse SSH tunnel)===[Server 2]
| | (happily talking)
| [Server 3 (DB)]
По разным причинам нам не может быть предоставлен общедоступный IP-адрес для Сервера 2, и корпоративный ИТ-отдел не может перенаправить порты на Сервер 2. Единственный способ, которым мы действительно можем поговорить с Сервером 2 извне, что корпоративный ИТ-отдел сочло приемлемым, - через обратное SSH-туннелирование. При необходимости мы можем создать несколько обратных туннелей.
Обратное туннелирование работает нормально:
Server 2)# ssh -f -N -R 50022:localhost:22 reversessh@server_1.ip.address
И мы можем получить доступ к серверу 2 с сервера 1 с помощью:
Server 1)$ ssh my_user_on_server2@localhost -p 50022
Сервер 2 внутри сети может видеть Сервер 3 и может без проблем подключиться к серверу базы данных MSSQL, работающему на нем. FWIW Я использую unixodbc / FreeTDS для тестирования разговора с MSSQL Сервера 3.
Как я могу заставить клиента MSSQL на сервере 1 разговаривать с базой данных на сервере 3?
Принимая во внимание, что у нас есть полный контроль над Сервером 2, я попытался спроектировать переадресацию портов через UFW, чтобы пакеты, попадающие в порт 51433 на Сервере 2, отправлялись на порт 1433 Сервера 3. Но даже это, похоже, не работает (да, я '' отключил, затем включил UFW после добавления правил)
/etc/ufw/sysctl.conf
net/ipv4/ip_forward=1
/etc/ufw/before.rules
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 51433 -j DNAT --to-destination server_3.internal.ip.address:1433
COMMIT
Однако попытка подключиться к базе данных MSSQL на сервере 2 с помощью localhost: 51433 не работает.
Тогда я планировал создать еще один обратный SSH-туннель между Сервером 2 и Сервером 1:
Server 2)# ssh -f -N -R 1433:localhost:51433 reversessh@server_1.ip.address
Затем укажите «клиенту» MSSQL (облачное приложение) на localhost: 1433 на сервере 1.
Итак, имея в виду, что мы можем использовать только обратное SSH-туннелирование, чтобы получать трафик на наш сервер внутри ...
Как я могу заставить клиента MSSQL на сервере 1 разговаривать с базой данных на сервере 3?
Есть ли другой подход, который мы могли бы использовать с учетом ограничений корпоративной сети?
Рабочее решение, предложенное @ dave_thompson_085:
Server 2)# ssh -f -N -R 51433:server3:1433 user@server1