Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 

четверг, 13 января 2011 г.

Java for fun: Замечательный proxy-сервер на java

Хочу поделиться с очень простым, но в то же время полезным proxy server. Скачать его можно вот по этой ссылке. Лицензия, судя по внутренним инфо файлам GNU. Зашебись.

Всегда, когда мне нужно подглядеть за двумя программами общающимися по TCP/IP протоколу я использую вот эту проксю.

Я пользовался этой штукой для изменения sql запросов между драйвером jdbc и самой базой. Я пользовался этой штукой для изменения xml между вебсервисом и его клиентом. Да, занятие не простое - надо знать формат сообщений в каждом конкретном случае, но если тебе нравится разгадывать наскальные рисунки - то это самое то.  Читать дальше...

Исходники прилагаются, а потому можно изменить проксю под свои цели. Чаще всего я пользуюсь обработчиком src\java\com\intermediary\socketproxy\handler\DataPassThrough.java

/*
 * Proxy Server
 * Copyright (C) 2003, 2004 Healy Computer Systems 
 * www.intermediary.com
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.intermediary.socketproxy.handler;

import com.intermediary.socketproxy.IDataHandler;

/**
 * Sample/utility class that implements IDataHandler.
 * Passes data straight through without modification.
 */
public class DataPassThrough implements IDataHandler {

    /**
     *  Constructs DataPassThrough.
     */
    public DataPassThrough() {
        //do nothing on construction
    }

    /**
     * Pushes incoming byte array to custom handler class.
     * The incoming bytes are then available to handler
     * logic for inspection and/or modification.
     * 
     * @param bytes the inbound byte array
     * @return the original (or modified) array of bytes
     */
    public byte[] pushBytes(byte[] bytes) {
        //no action taken
        //simply return the byte array
        return bytes;
    }
}

Его метод pushBytes вызывается всякий раз, когда мимо прокси что-то происходит. Причем все проходит именно через метод pushBytes - ты должен вернуть массив байтов, которые передаются дальше. А можно немного пошалить и изменить что-то.

Конфигурируется тулза очень просто. В файле \cfg\properties.cfg все описано.
# port for the proxy server to listen on
# этот порт будет слушать прокси, т.е. все, что прийдет на этот порт данного компьютера - попадает на обработку прокси серверу. 
listen_port=7777

# forwarding destination
# на этот хост будет отправляться то, что ответит proxy (то, что мы return'ули в pushBytes)
destination_host=localhost

# destination port
# а это хост места назначения
destination_port=8787

# java class to process data entering the proxy server
# must be available in your classpath when the proxy server is started
# этот обрабочик будет обрабатывать входящие в прокси собщения
in_class=com.intermediary.socketproxy.handler.DataPassThrough

# java class to process data leaving the proxy server
# must be available in your classpath when the proxy server is started
# этот обрабочик будет обрабатывать исходящие из прокси собщения
out_class=com.intermediary.socketproxy.handler.DataPassThrough

# logging section

# log - general configuration
# максимальный размер файла лога
max_log_file_bytes=10000000

# максимально количество лог файлов. Если файлов в папке \logs больше столько сколько у казано тут, то при повторном запуске прокси самый старый лог удалится. 
log_file_count=5

# log - system information
# то где лог файлы хранятся и как именуются
system_log_file=../log/log%g_system.txt

# то, какого уровня лог сообщения будут записываться в файл
# допустимо: OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
system_log_level=ALL

# то, какого уровня лог сообщения будут выводится на экран
# допустимо: OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
system_console_level=INFO

# log - inbound data
# входящие данные логируются тут 
inbound_log_file=../log/log%g_inbound.txt
inbound_log_level=ALL

# log - outbound data
# исходящие данные логируются тут 
outbound_log_file=../log/log%g_outbound.txt
outbound_log_level=ALL

Запускается вызовом main метода класса
com.intermediary.socketproxy.ProxyServer
В качестве аргументов можно передать путь к config файлу. Если не передавать, то файл будут искать в корне.

Усе :)

19 комментариев:

  1. Весьма интересно. Только не понятно с портами...Какие порты следует выбирать? и как сконфигурить браузер использовать прокси?

    ОтветитьУдалить
  2. можно ли его использовать для https протокола?

    ОтветитьУдалить
  3. 80 порт - http по умолчанию. Второй выбирается любой свободный - часто 8080. В настройках браузера есть где-то настройки подключения к интернету, там должна быть галочка "использовать прокси сервер" и поля ввода хоста и порта. Выбираем localhost и 8080.

    По второму вопросу:

    HTTPS это обычный HTTP, работающий через шифрованные транспортные механизмы SSL и TLS. Он обеспечивает защиту от атак, основанных на прослушивании сетевого соединения — от снифферских атак и атак типа man-in-the-middle при условии что будут использоваться шифрующие средства и сертификат сервера проверен и ему доверяют.

    По умолчанию HTTPS URL использует 443 TCP-порт (для незащищённого HTTP — 80).

    взято тут http://ru.wikipedia.org/wiki/HTTPS

    ОтветитьУдалить
  4. Спасибо за ответ. С портами разобрался, стучался на разные домены типа Google.com, vkontakte.ru, Но на google docs зайти не удается, поэтому и спрашивал насчет HTTPS. Не пробовали ли вы его использовать?

    ОтветитьУдалить
  5. Нет, таска была другая :) Я подслушивал как общается база данных с JDBC драйвером.

    ОтветитьУдалить
  6. Доброго времени суток.
    На 80-ом порту у меня локальный сервер висит. Рокси-сервер не заводится.
    Подскажите как мне скофирурить
    listen_port=
    destination_host=
    destination_port=
    За ранее спасибо

    ОтветитьУдалить
  7. Этот комментарий был удален автором.

    ОтветитьУдалить
  8. Уверен у вас уже были попытки что-то предпринять. Опишите, что вы уже сделали и что получилось в результате.

    ОтветитьУдалить
    Ответы
    1. Я запускаю прокси-сервер на своем компе (debian).
      Мои настройки:
      listen_port=7777
      destination_host=localhost
      destination_port=3128
      Далее:
      Chrome - параметры/дополнительные/Сеть(изменить настройки прокси-сервера)
      Выбираю ручная настройка прокси-сервера, отмечаю использовать общий прокси для всех протоколов
      Прокси для HTTP: localhost port 3128

      Набираю ya.ru
      И Chrome выдает:

      Не удается подключиться к прокси-серверу
      Прокси-сервер – это сервер, который действует как посредник между вашим компьютером и другими серверами. Сейчас в вашей системе выбрано использование прокси-сервера, но Google Chrome не может подключиться к нему.
      Вот несколько советов и рекомендаций:
      При использовании прокси-сервера проверьте его настройки или обратитесь к администратору сети, чтобы убедиться, работает ли прокси-сервер. Если прокси-сервер использовать необязательно, установите соответствующие настройки: Откройте меню инструментов > Настройки > Дополнительные > Изменить настройки прокси-сервера... и убедитесь, что выбран вариант без использования прокси-сервера или прямое подключение.
      Ошибка 130 (net::ERR_PROXY_CONNECTION_FAILED): Сбой при подключении к прокси-серверу

      Перепробовал все порты, не помогло.
      А, еще в закладке "Игнорируемые узлы" я убрал localhost и 127.0.0.1/8

      Спасибо.

      Удалить
    2. Ваша настройка говорит о следующем:
      если кто-то попытается присоединиться на порт 7777, то этот вызов будет залоггирован сервером, и перенаправлен на localhost:3128

      Удалить
    3. А какие правильно мне указать настройки?
      Я попробовал прокси-сервер rabbit, все работает без проблем.
      Но мне хотелось разобраться именно из Вашей статьи.

      Удалить
    4. Что удалось нарыть:
      1) Настройки такие:
      listen_port=8080
      destination_host=localhost
      destination_port=80
      in_class=com.intermediary.socketproxy.handler.DataPassThrough
      out_class=com.intermediary.socketproxy.handler.DataPassThrough
      2) в хроме в настройках/дополнительные/Сеть/изменить настройки прокси-сервера
      3) открывается виндовое диалоговое окно настроек интернета, там что-то типа:
      «Выбираю ручная настройка прокси-сервера, отмечаю использовать общий прокси для всех протоколов. Прокси для HTTP: localhost port 8080»
      3) запускаю сервак получаю
      "java.net.BindException: Address already in use: JVM_Bind:8080"
      4) выполняю в cmd
      netstat -ano | find "8080"
      5) получаю
      TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 435345
      6) нахожу процесс по его PID 435345 в Windows Task Manager и убиваю его
      7) снова запускаю сервак (в debug режиме, с брекпоинтом в методе pushBytes класса DataPassThrough, чтобы понять стучится ли браузер куда надо)
      8) обновляю страничку в хроме (mail.ru)
      9) заморгал IDE на TaskBar, что значит произошла остановка в breakpoint, а это в свою очередь, что браузер с прокси соединился, а это, что все конфиги правильные.
      9) отпускаю дебаггер
      10) получаю в хроме сообщение
      "Ошибка HTTP 501 (Not Implemented): Сервер не содержит всех функциональных возможностей, необходимых для выполнения этого запроса."

      Мои выводы:
      1) Вами неправильно использовались порты
      2) Наверное не такой уж классный прокси для работы между браузером и сетью (хотя не факт, я не копал дальше, а остановился на 2х часах – больше в это инвестировать не имею желания)
      3) Пока писал коммент, вспомнилось видео Саши Бындю http://blog.byndyu.ru/2010/05/agiledays-2010.html

      Удалить
    5. Спасибо.
      Удачных удач Вам.

      Удалить
    6. Удачных удач. Если будут интересные наработки в этой области, делитесь ими на своем блоге, а тут линк оставьте - любопытно.

      Удалить
  9. А будет ли приложение работать на Google App Engenee?

    Нагуглил 2 развернутых варианта:
    http://gproxyru.appspot.com/
    http://proxy2031.appspot.com/

    Лазить через них получается быстро (у меня провайдер счетает трафик до гугла, как локальную сеть).
    Но увы, эти 2 варианта не позволяют логиниться на сайтах.

    Попробую ваш вариант в попытках перехитрить провайдера :)

    ОтветитьУдалить
  10. Здравствуйте, вы не подскажете как вы правили пакеты для СУБД?

    ОтветитьУдалить
    Ответы
    1. К сожалению уже не вспомню. Слишком давно это было. 6 лет назад. Справитесь?

      Удалить
    2. Эх жалко :( придется городить огороды тогда) пытаюсь для диплома фаервол для бд написать, но вот не могу нагуглить, как выглядят пакеты, которые идут от клиента до бд и обратно)

      Удалить
  11. Подключиться к обмену не получается. init error: java.net.BindException: Address already in use: JVM_Bind
    порт уже занят программой. Какое есть решение в этом случае ?

    ОтветитьУдалить