Клиент недавно спросил меня, можно ли использовать FireDAC для подключения к базе данных через туннель SSH. Краткий ответ — да, конечно. Но давайте лучше разберемся, что такое SSH-туннель и как легко достичь этой цели при использовании Delphi и FireDAC.
Table of Contents
SSH туннели
Secure Shell (ssh) — это стандартный инструмент, включенный в большинство «сетевых» операционных систем, то есть Linux, UNIX, MacOS, а теперь и в Windows (на собственном языке). Если вы когда-нибудь в жизни использовали PuTTY для подключения к удаленному интерфейсу командной строки, как правило, к системе Linux, для этого использовался протокол SSH.
Таким образом, ключевым моментом при использовании FireDAC через безопасный интерфейс SSH является понимание того, что FireDAC (или любая другая структура доступа к базе данных) не имеет к этому никакого отношения. Вам нужно установить постоянный SSH-туннель, а затем правильно настроить соединение с базой данных.
Мы увидим два способа установить SSH-туннель: один с использованием внешнего инструмента (PuTTY), а второй, напрямую закодированный в вашем приложении.
SSH-серверы
Цель этой статьи не в том, чтобы научить создавать SSH-сервер, но мне пришлось создать его, чтобы протестировать свое решение, поэтому вот что я использую. В основном у меня есть виртуальная машина Linux с базой данных PostgreSQL (это база данных, которую клиент хотел бы подключить, но решение не зависит от базы данных), и поверх нее я установил и запустил SSH-сервер, следуя этому руководству:
https://docs.oracle.com/cd/E37670_01/E41138/html/ch25s03.html
Это для Oracle Linux (это то, что я использую из-за еще одного доказательства концепции, которое мне пришлось сделать на прошлой неделе), но вы найдете аналогичные руководства для предпочитаемого вами варианта Linux.
Тестирование соединения
Прежде чем пытаться установить соединение с FireDAC, рекомендуется проверить соединение, используя только инструменты командной строки, которые являются неотъемлемой частью операционных систем, чтобы вы знали, работает что-то или нет.
Итак, если и SSH-сервер, и экземпляр базы данных (в моем случае PostgreSQL) открыты и работают в Linux, мы можем попробовать первое соединение из Windows с помощью любого клиентского терминала SSH. Windows 10 имеет собственный клиент после «октябрьского обновления» 1809 года, но я буду придерживаться PuTTY, поскольку это основная утилита для системных администраторов.
Это мои конфигурации Putty. На странице сеанса необходимо указать IP-адрес сервера и порт SSH (по умолчанию — 22):
А на странице конфигурации SSH / Tunnels вы указываете, как будет создан туннель:
Что говорит эта конфигурация? В основном, чтобы создать туннель SSH, вы должны указать порт источника (любой доступный / неиспользуемый номер порта, который у вас есть в вашей системе) и IP-адрес / порт назначения (в данном случае IP-адрес сервера Linux и порт, где находится экземпляр PostgreSQL. прослушивание — 5432 — порт PostgreSQL по умолчанию). Конечно, исходный IP-адрес всегда будет «localhost», что означает, что ваше соединение с базой данных будет указывать на localhost / 63333, и туннель будет творить чудеса, отправляя команды на сервер и получая результаты.
Наконец, открыв соединение PuTTY и предоставив действующего пользователя Linux и пароль (рекомендуется создать конкретного пользователя только для использования SSH), вы увидите что-то похожее на это ниже. Я знаю, некрасиво. Вы можете протестировать на нем некоторые команды Linux, например «ls -l»:
Время кодирования!
Правильно настроив и протестировав инфраструктуру, давайте настроим соединение с базой данных FireDAC и протестируем его. Как вы можете видеть ниже, это стандартное соединение FireDAC с использованием драйвера PostgreSQL, единственная нетривиальная вещь — это сервер / порт, указывающий на туннель, созданный через PuTTY:
Теперь, как правило, вы хотите сделать это «прозрачным» для конечного пользователя, что означает отсутствие необходимости настраивать PuTTY или какой-либо другой сторонний инструмент. Для этого вам необходимо рассмотреть реализацию клиента SSH для Delphi, который в основном создаст этот туннель для вас, но изнутри вашего приложения. Для этого доступно множество сторонних компонентов, а также несколько замечательных реализаций с открытым исходным кодом, которые вы можете найти, выполнив поиск в GitHub.
Я выбрал библиотеку Ssh-Pascal. Он очень полный и был построен отцом PyScript (одна из лучших IDE Python с открытым исходным кодом — полностью сделана на Delphi), поэтому заслуживает дополнительной похвалы.😉
https://github.com/pyscripter/Ssh-Pascal
Реализация основана на libssh2 , хорошо известной реализации SSH, которая присутствует во многих языках и фреймворках. Что касается установки, это просто вопрос добавления источников библиотеки в ваш проект и ее использования, без компонентов или внешних зависимостей. Для развертывания libssh2.dll должен быть доступен вместе с исполняемым файлом.
Ваш собственный SSH-туннель
Ниже у нас есть то, что я построил для этого доказательства концепции. Пожалуйста, учтите, что это просто проверка концепции, а не полная реализация, что означает, что есть много улучшений, которые можно сделать.
Некоторые детали:
- Конфигурация подключения PostgreSQL точно такая же, как и ранее.
- Кнопки Open / Close database отвечают, ну, за открытие и закрытие соединения с базой данных.
- Код открытия / закрытия туннеля можно найти ниже (обратите внимание, что все параметры жестко запрограммированы, поскольку это всего лишь пример, пожалуйста, не воспринимайте это как пример хорошей практики кодирования ни в коем случае)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
procedure TMainForm.butOpenTunnelClick(Sender: TObject); Var Host: string; UserName: string; Password: string; begin Host := '192.168.56.106'; UserName := 'oracle'; Password := 'oracle'; Session := CreateSession(Host, 22); Session.Connect; if not Session.UserAuthPass(UserName, Password) then begin ShowMessage('Authorization Failure'); Exit; end; SshTunnel := CreateSshTunnel(Session); Thread := TThread.CreateAnonymousThread( procedure begin SshTunnel.ForwardLocalPort(63333, '192.168.56.106', 5432); end); Thread.FreeOnTerminate := True; Thread.Start; end; |
1 2 3 4 5 6 7 8 9 10 |
procedure TMainForm.butCloseTunnelClick(Sender: TObject); begin Thread.Terminate; SshTunnel.Cancel; if not Thread.Finished then begin Thread.WaitFor; Thread.Free; end; end; |
И, наконец, у нас есть запущенное приложение, отображающее некоторые данные PostgreSQL. Опять же, это можно сделать для любой базы данных — пока кто-нибудь не пришлет мне сообщение о том, что что-то не работает.😉
Полный исходный код можно найти здесь, в моем GitHub , вместе с некоторыми другими демонстрационными проектами.
Не стесняйтесь оставлять свои комментарии, проблемы, варианты использования и т. Д., Мы будем очень признательны!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition