Java — подключиться к веб-странице с помощью туннелирования SSH

товарищи программисты Java. Недавно передо мной встала интересная задача — создать программу, которая бы использовала SSH-туннель в качестве прокси для просмотра веб-страниц (через HTTPS). После прочтения некоторых документов по JSCH (http://www.jcraft.com/jsch/, Java Библиотека туннелирования SSH), в которой все давали в качестве примера подключения к базе данных, я решил попробовать сам. Вот код подключения, который я скопировал из http://kahimyang.info/kauswagan/code-blogs/1337/ssh-tunneling-with-java-a-database-connection-example

int assigned_port;   
    int local_port=3309;

    // Remote host and port
    int remote_port=3306;
    String remote_host = "<SSH host goes here>";
    String login = "<SSH login goes here>";
    String password = "<SSH password goes here>";

    try {
        JSch jsch = new JSch(); 

        // Create SSH session.  Port 22 is your SSH port which
        // is open in your firewall setup.
        Session session = jsch.getSession(login, remote_host, 22);
        session.setPassword(password);

        // Additional SSH options.  See your ssh_config manual for
        // more options.  Set options according to your requirements.
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        config.put("Compression", "yes");
        config.put("ConnectionAttempts","2");

        session.setConfig(config);

        // Connect
        session.connect();            

        // Create the tunnel through port forwarding.  
        // This is basically instructing jsch session to send 
        // data received from local_port in the local machine to 
        // remote_port of the remote_host
        // assigned_port is the port assigned by jsch for use,
        // it may not always be the same as
        // local_port.

        assigned_port = session.setPortForwardingL(local_port, 
                remote_host, remote_port);

    } catch (JSchException e) {            
        System.out.println("JSch:" + e.getMessage());
        return;
    }

    if (assigned_port == 0) {
        System.out.println("Port forwarding failed!"); 
        return;
    }

Теперь я не совсем разбираюсь во всех вещах с переадресацией портов, но, если я правильно понимаю, код должен перенаправлять все входящие соединения на 127.0.0.1:3309 (или любой другой назначенный_порт) через сервер SSH. Теперь я застрял. Как мне отправить HttpsURLConnection через 127.0.0.1:3309? Я попытался определить его как прокси-сервер HTTP, HTTPS или SOCKS, но ни один из них не работает. Кто-нибудь может мне помочь?


person Mints97    schedule 19.05.2014    source источник
comment
Если это не обязательно должно быть кросс-платформенным, вам лучше использовать стандартные операции командной строки ssh для этого. В любом случае обязательно потренируйтесь с клиентом ssh, прежде чем пытаться сделать это на Java.   -  person artbristol    schedule 19.05.2014
comment
В качестве подсказки вы можете использовать ssh -D1080 <remote host>, который создаст прокси-сервер SOCKS5 на локальном хосте. Затем настройте клиент HTTPS на использование этого прокси.   -  person artbristol    schedule 19.05.2014
comment
@artbristol: я хочу, чтобы программа была кроссплатформенной, и я хочу, чтобы ее можно было запускать в Windows, в которой нет большинства причудливых команд Linux cmd. Между прочим, у меня не установлен Linux, поэтому мне было бы трудно попробовать то, что вы рекомендуете из командной строки. Есть ли способ использовать ssh -D1080 ‹удаленный хост› в jsch?   -  person Mints97    schedule 19.05.2014
comment
Если у вас есть замазка, эквивалентно выбрать «Динамический» при настройке переадресации портов.   -  person artbristol    schedule 19.05.2014
comment
@artbristol: я гуглил динамическую переадресацию портов на JSCH, и, к сожалению, ее не хватает. Я проверю code.google.com/p/ssh-persistent-tunnel/source/browse/src/org/, который, по-видимому, является опцией динамической переадресации портов, построенной поверх JSCH, что, я почти уверен, совсем неэффективно.   -  person Mints97    schedule 19.05.2014
comment
Если вы не можете использовать SOCKS, вам необходимо настроить прокси-сервер HTTP на удаленном хосте и перенаправить локальный порт на удаленный порт, который прослушивает прокси-сервер.   -  person artbristol    schedule 19.05.2014
comment
@artbristol: настроить что-либо на удаленном хосте, к сожалению, невозможно   -  person Mints97    schedule 19.05.2014
comment
К сожалению, локальный SOCKS или туннельно-удаленный HTTP-прокси — это единственный способ сделать то, что вы хотите.   -  person artbristol    schedule 19.05.2014
comment
@artbristol: Хорошо, я попробую настроить локальный сервер SOCKS. Спасибо за ваши полезные ответы.   -  person Mints97    schedule 19.05.2014
comment
Я пытаюсь добиться того же. Вам когда-нибудь удавалось добиться этого с помощью Java?   -  person Arya    schedule 12.10.2017
comment
@Arya: сейчас у меня нет доступа к исходному коду, и я не помню, но, возможно, это поможет: stackoverflow.com/questions/23791014/   -  person Mints97    schedule 16.10.2017


Ответы (1)


Размещенный вами код будет перенаправлять весь трафик с 127.0.0.1:3309 на порт 3306 на SSH-сервере, к которому вы подключились.

При использовании переадресации портов вы обрабатываете адрес прослушивания: порт, как если бы это был фактический пункт назначения. Поэтому, если вам нужно использовать HttpsURLConnection, вы должны создать его с URL-адресом

https://127.0.0.1:3309/

Очевидно, вам также необходимо добавить путь к URL-адресу в зависимости от того, чего вы пытаетесь достичь. Я бы предложил изменить ваш код, чтобы использовать больше стандартных портов HTTP, сначала попробуйте HTTP, а когда он заработает, перейдите на HTTPS.

int local_port=8080;
// Remote host and port
int remote_port=80;

URL-адрес выше будет

http://127.0.0.1:8080

Вы всегда можете проверить URL-адрес, вставив его в браузер.

Одной из проблем, с которой вы можете столкнуться при использовании HTTPS, является проверка сертификата, поэтому я предлагаю сначала протестировать простой HTTP, чтобы убедиться, что ваш код работает.

person LeeDavidPainter    schedule 19.05.2014
comment
Спасибо, я знаю, как решать проблемы с проверкой сертификата, для этого у меня есть готовый код. Однако я не очень понимаю ваш ответ. Если я установлю HttpsURLConnection на 127.0.0.1, как я смогу использовать переадресацию портов для работы в Интернете? - person Mints97; 19.05.2014
comment
В вашем сообщении конкретно упоминается HttpsURLConnection, я предположил, что вы хотите подключить его к туннелю, который вы настроили с помощью Jsch. Похоже, вам нужен динамический прокси. Существует коммерческий API, поддерживающий это, J2SSH Maverick ссылка. - person LeeDavidPainter; 20.05.2014