Только для локального хоста RMI? - PullRequest
3 голосов
/ 16 февраля 2012

У меня есть проект, который запускает вторую JVM.В настоящее время я использую RMI для общения между ними.Хорошо работает на моих компьютерах.

Мне нужно иметь возможность развернуть этот проект на машинах Windows 7, где у меня нет прав для изменения правил брандмауэра.

Реестр (запускается изнутрипервая JVM на высоком произвольном порту) блокируется от открытия сокета сервера на этих машинах.

Есть ли способ ограничить RMI только прослушиванием локальных соединений;такой, что брандмауэр Windows будет крут с ним?

В качестве альтернативы, есть ли хороший альтернативный подход IPC, который потребует небольших функциональных изменений?

Приветствия.

Ответы [ 3 ]

5 голосов
/ 22 февраля 2012

Это сложнее, чем кажется на первый взгляд. Требуется ограничить IP-адреса , которые прослушивает реестр, но не порт. Проблема заключается в том, что программа реализации реестра RMI (rmiregistry) фактически не предоставляет какого-либо механизма, ограничивающего прослушиваемые IP-адреса; он всегда прослушивает каждый доступный сетевой интерфейс. Есть только два практических механизма для ограничения этого:

  1. Используйте правило брандмауэра. Честно говоря, это обычный метод, но он требует настройки во время развертывания.
  2. Используйте специальную версию реестра RMI, которая применяет ограничение только к правильному IP-адресу (а именно localhost, 127.0.0.1), поскольку Windows не жалуется на сокеты, которые могут быть доступны только с локальной машины.

Этот второй вариант - то, что я набросаю. Это на самом деле довольно просто, поскольку вы можете делегировать большую часть сложности существующим классам.

import java.io.IOException;
import java.net.*;
import java.rmi.server.*;
import java.rmi.registry.LocateRegistry;

public class RestrictedRMIRegistry implements RMIServerSocketFactory {
    public static void main(String... args) throws IOException {
        int port = (args.length == 0 ? 1099 : Integer.parseInt(args[0], 10));
        RMIClientSocketFactory csf = RMISocketFactory.getDefaultSocketFactory();
        RMIServerSocketFactory ssf = new RestrictedRMIRegistry();

        LocateRegistry.createRegistry(port, csf, ssf);
    }

    public ServerSocket createServerSocket(int port) throws IOException {
        // Tricky bit; make a server socket with bound address
        return new ServerSocket(port, 0, InetAddress.getLocalHost());
    }
}

Единственная разница между этой и обычной реализацией rmiregistry заключается в том, что используются значения по умолчанию для и фабрики сокетов клиента и сервера.

0 голосов
/ 17 февраля 2012

Попробуйте установить для свойства java.rmi.server.hostname значение 127.0.0.1 при запуске реестра (или любого другого процесса Java, включенного в вашу схему).

0 голосов
/ 16 февраля 2012

Хорошая альтернатива называется веб-службой по HTTP, которая обычно открыта для исходящих соединений.

Проблема с входящими соединениями.Я считаю, что «правильная» архитектура - это когда процессы, развернутые за брандмауэром, общаются друг с другом через 3-ий процесс - сервер, который установлен где-то, где входящее соединение HTTP не ограничено.Итак, 2 компонента, которые находятся за брандмауэром, выполняют только исходящее HTTP-соединение с сервером.

...