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