своей работе.
Среди других, эту задачу сумела решить компания "Крипто-Про", разработавшая и внедрившая криптографические средства, реализующие в соответствии со стандартом Microsoft CSP российские криптографические алгоритмы. Их разработки (криптопровайдер "КриптоПРО CSP" и модуль поддержки сетевой аутентификации "КриптоПро TLS") полностью соответствуют требованиям Microsoft и работают под различными операционными системами Windows. К стандартным приложениям, которые теперь могут использовать российские алгоритмы электронной цифровой подписи и шифрования, относятся: Microsoft CryptoAPI 2.0. Microsoft Certification Authority. Microsoft Outlook Express и Microsoft Outlook. Microsoft Authenticode. Криптопровайдер "КриптоПРО CSP" был также перенесен и под операционную систему Sun Solaris, а к концу года должна появиться версия и для Linux. Но только сам криптопровайдер. А модули, аналогичные "КриптоПро TLS" и реализующие функции сетевой аутентификации, создания защищенных соединений для веб-серверов, работающих под этими операционными системами, разработала компания Digt. Разработанный ею продукт Digt Trusted TLS является криптографическим инструментом для веб-сервера Apache, используемого в различных серверах приложений (например, Oracle9iAS). Продукт может использоваться в качестве замены имеющегося крипто-модуля веб-сервера и применяться для построения систем, использующих сертифицированные по российским стандартам средства криптозащиты информации (СКЗИ). Digt Trusted TLS работает через протоколы TLS/SSL с помощью набора инструментов OpenSSL. Он поставляется как динамически загружаемая библиотека, в состав которой входит еще один продукт фирмы - Digt Trusted Crypto Toolkit. Он в свою очередь представляет собой набор библиотек, разработанных для поддержки кросс-платформенных серверных приложений, обеспечивающих их безопасность. Приложения, построенные на основе Digt Trusted Crypto Toolkit, могут поддерживать протоколы TLS/SSL, сертификаты X.509 и другие стандарты безопасности. Модуль Digt Trusted TLS встраивается взамен имеющегося модуля mod_ssl веб-сервера Apache, работающего под операционными системами Linux, Solaris, Windows. Без использования криптопровайдера "КриптоПРО CSP" модуль полностью обеспечивает все функции аутентификации и криптографии с использованием RSA и Diffie-Hellman шифров. Установка криптопровайдера позволяет применять и сертифицированные алгоритмы шифрования. Таким образом, у интернет-провайдеров появляется возможность расширения оказываемых услуг за счет предоставления сертифицированных российских средств аутентификации и защиты информации. Разработанные приложения для защиты доступа к веб-серверу, обеспечения аутентификации и шифрования позволили расширить возможности сервера Apache и придали ему дополнительную функциональность. Продукт, получившийся в результате доработки Apache, был назван Digt Trusted Web Server. Он распространяется co всеми стандартными модулями, которые входят в состав сервера Apache. Digt Trusted Web Server использует 256-битное шифрование по ГОСТ 28147-89, сертифицированное ФАПСИ для бизнес-приложений. Он реализует аутентификацию, построенную на X.509 сертификатах, как для клиента, так и для сервера. Имеется возможность использовать сертифицированные ФАПСИ алгоритмы ГОСТ Р 34.10-94, ГОСТ Р 34.11-94 для генерации сертификатов.
Защищенные сети и SSL Есть и другой подход. Я много говорил в предыдущих статьях о SSL. Мы создали веб-сервер который общался с клиентом по протоколу HTTPS, а теперь ответьте сами себе разве существует принципиальная разница что защищать: то ли трафик HTTP, то ли любую другую информацию передаваемую по сети. Однако следует четко понимать, что раз мы находимся выше чем третий уровень, то прикладные приложения должны догадываться о нашем существовании и сотрудничать с кодом VPN. Ладно, не будем пытаться пробить головой бетонную стену, мы пойдем другим путем. Поставим перед собой задачу создать механизм туннелирования о котором клиент должен, пожалуй, знать, знать только что такой механизм есть, и чтобы пользоваться его услугами надо выполнить следующий ряд волшебных манипуляций, но клиент не должен в общем случае ничего знать о том каким способом выполняется преобразование передаваемых данных и как выполняется проверка того, что соединение может быть установлено. В качестве основы для разрабатываемой системы будет лежать как вы уже наверное догадались тот самый https сервер который нам удалось создать в предыдущей статье серии. Веб-сервер предоставлял клиенту свой сертификат и защищал трафик. Совсем не сложно было бы добавить требование со стороны сервера в том, чтобы клиент также представился для начала взаимодействия. Технически это осуществляется с помощью вызова метода: SSLServerSocket serverSocket = (SSLServerSocket) ssfa.createServerSocket(localPort); // ssfa --- javax.net.ssl.SSLSocketFactory serverSocket.setNeedClientAuth(true); Однако не забывайте, что я поставил требование к разрабатываемой системе. Клиенты не должны иметь представления о таких технических деталях как сертификаты, SSL, в идеале они должны верить что взаимодейсвуют как по открытому каналу. Поэтому необходимо будет создать слой который будет играть роль посредника между ничего не знающим клиентом и тем слоем который выполняет непосредственно защиту трафика. Однако давайте мы сначала сосредоточимся на решении подзадачи - создании приложения для перенаправления сетевых вызовов. Пример кода. Туннель для сетевых вызовов Сначала я разработаю приложение, единственное назначение которого будет выполнять туннелирование запросов от одной машины сети к другой. В общем случае клиент обращается на определенный порт сервера, а его запрос максимально прозрачно перенаправляют на другой адрес IP, и на другой номер порта. Разумеется, что в ряде ситуаций подобный ход не удастся, особенно в том случае, если адресат проверяет информацию о том, кто отправил данное сообщение, или идет попытка выполнить встречное соединение, при этом адресат ничего не знает о туннелировании, но, к сожалению, все эти задачи средствами только Java реализовать нельзя. Если вы найдете решение, то я буду только рад.
Рисунок 2. Обратите внимание на картинку, я на ней привел пример не только среды JBuilder, но и окно браузера в котором открыт поисковик Google. Но посмотрите на адресную строку, смею вас уверить, что я работаю не в Google, и на самом деле запрос, который я послал локальной машине на порт 2088, был перенаправлен в интернет на сайт Google. Кстати, если вы внимательно посмотреть на скриншот, то можно увидеть лог пересылаемых данных по туннелю. По крайней мере, я думаю, что начало любого запроса http “GET / HTTP 1.1” увидеть можно. Вот исходный код примера, обратите внимание на то, что для хранения информации я использую файлы xml и анализ данного файла выполняю с помощью того же вспомогательного класса XTools, который я применял и для создания веб-сервера. Схема работы приложения очень проста: я создаю серверный сокет ServerSocket и жду входящих соединений на определенный порт, номер которого указывается в файле конфигурации. Затем после поступления запроса создается соответствующий клиентский сокет для чтения запросов от инициирующей связь стороны и сразу же создается сокетное соединение с тем хостом и портом на который входящий запрос должен быть перенаправлен. Дальнейшие действия просты и очевидны: необходимо каждый байт приходящий от стороны инициирующей соединение, (давайте для определенности будем называть ее сторона “A”) перенаправлять к стороне “B” (информация о ней находится в файле конфигурации)) и соответственно каждый байт который посылает нам сторона “B” должна быть направлена стороне “A”. Разумеется что данные действия должны выполняться асинхронно и независимо друг от друга, поэтому лучшего решения чем создать два класса потока, класса производных от Thread и перекрыть в нем метод run так чтобы в цикле читать байт из входного потока и писать в выходной поток. И цикл должен будет продолжаться до тех пор пока сокетное соединение не будет закрыто. Следующим шагом будет добавление защиты пересылаемой информации, для этого на обоих сторонах соединения необходимо будет пользоваться для пересылки информации не обычными сокетами, а сокетами SSL и, внимание, нам необходимо будет затребовать аутентификацию клиента делающего соединение к серверу. Однако это будет после а пока я привожу файл конфигурации необходимый для работы просто "Redirector"-а. Давайте кратко рассмотрим основные моменты работы программы: Информация о перенаправлениях хранится в файле конфигурации, каждый элемент Route задает порт локальной машины, который будет слушаться на предмет входящих запросов, а также соответственно адрес и порт удаленной машины, куда запрос должен быть переправлен. Для хранения подобных учетных записей перенаправления был создан вспомогательный класс Route содержащий три поля, служащих для хранения информации, которую я назвал шагом раньше. При вызове конструктора класса AbstractRedirector в качестве параметра передается имя файла настроек. Из данного файла читаются все элементы Route и помещаются в специальный массив. После создания объекта класса для начала непосредственно обслуживания должна быть вызвана функция synchroRun. Данная функция создает набор экземпляров безымянного класса производного от Thread в данном классе перекрыта функция run, которая в цикле читает побайтно информацию из сокета входящего запроса и отправляет его в поток вывода для сокета исходящего соединения. Данный цикл прекращается, когда сокетное соединение с любой из двух сторон будет прервано. Как демонстрацию принципов работы данного приложения привожу следующую СЛС.
Рисунок 3.
Рисунок 4. Код примера. Защищаем сетевой туннель. А теперь давайте добавим возможность выполнения туннелирования через протокол SSL. Общая схема реализованного приложения практически идентична общей схеме создания VPN которую я приводил ранее. Небольшие отличия я привожу в виде следующей СЛС
Рисунок 5. Разумеется что для работы следующего кода нам потребуется внести изменения в файл конфигурации. Необходимо будет добавить новый элемент "SSL-section". <SSL-section> <Keystore-path>E:mdocskolyacbuilder_projects httpd-sslstore</Keystore-path> <Keystore-password>bigsecret</Keystore-password> <Alias-password>bigsecret</Alias-password> </SSL-section> И, наконец, я привожу исходный код примера. Обратите внимание на то что в классе SSLRedirector порожденном от AbstractRedirector я перекрыл метод initForRun добавив в него чтение "SSL" секции файла конфигурации, теперь каждому элементу Route необходимо будет добавить как характеристику признак того следует ли выполнять защиту описываемого туннеля. И следовательно мне пришлось расширить класс Route, создав класс SSLRoute и добавив в него булевскую переменную, выполняющую роль признака надо или нет выполнять защиту туннеля. Разумеется, что изменения также затронули и ключевые методы getServerSocket и getClientSocket. Теперь эти методы способны в зависимости от настроек переданного им в качестве параметра объкта SSLRoute создать или просто ServerSocket и соответственно Socket или же если поле plainToSecret установлено в true, то будет создан SSLSocket-ы. |