如何确定传入连接来自本地计算机
Posted
技术标签:
【中文标题】如何确定传入连接来自本地计算机【英文标题】:How to determine an incoming connection is from local machine 【发布时间】:2010-12-05 06:32:50 【问题描述】:我有一个接受传入连接的 SocketServer。出于安全原因,我应该只允许本地连接(来自运行服务器的机器的连接)。
如何确定传入连接是否来自另一台计算机?以下代码对此是否安全?
Socket socket = someServerSocket.accept();
String remoteAddress = socket .getInetAddress().getHostAddress();
if (!fromThisMachine(remoteAddress))
// Not from this machine.
而fromThisMachine()
方法是这样的:
public boolean fromThisMachine(String remoteAddress)
try
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements())
NetworkInterface networkInterface = interfaces.nextElement();
Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
while (addresses.hasMoreElements())
InetAddress inetAddress = addresses.nextElement();
String hostName = inetAddress.getHostName();
String hostAddr = inetAddress.getHostAddress();
if (hostName.equals(remoteAddress) || hostAddr.equals(remoteAddress))
return true;
catch (Exception e)
e.printStackTrace();
return false;
log("Unauthorized request to server from: " + remoteAddress);
return false;
谢谢, 莫森
【问题讨论】:
【参考方案1】:InetAddress.getByName( null ) 总是返回环回地址。见javadoc
int port = .....
SocketAddress socketAddress =
new InetSocketAddress( InetAddress.getByName( null ), port);
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(socketAddress);
serverSocket.accept();
【讨论】:
不错的一个。希望我早点知道这一点。我非常困惑。 这是功能蠕变最糟糕的例子之一。提供InetAddress.getLoopbackAddress()
会更干净。我只是偶然发现了这一点。我的应用程序中的地址字符串在某些情况下被清空,而不是 NPE,我的应用程序仍然单独运行。这教会了仔细和全神贯注地阅读 Java API 是很有价值的一课。
@AlexanderPogrebnyak,愚蠢的问题...InetAddress.isLoopbackAddress() 呢?
@吉利。 OPs 最初的问题是关于只接受来自本地主机的连接。 isLoopbackAddress
不会帮你获取本地IP地址。
会提供IP4或IP6协议的环回地址吗?请不要编写仅 IP4 的代码。我们需要尽快切换到 IP6。【参考方案2】:
如果您想限制来自 localhost 的连接,请在打开 ServerSocket 时指定。如果你只在 localhost 上监听,那么你只会从 localhost 获得连接。
int port = .....
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1", port);
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(socketAddress);
serverSocket.accept();
【讨论】:
它不起作用。请参阅:我在 192.168.0.1 上,其他人在 192.168.0.2 上。我想拒绝他访问我在 192.168.0.1:port 上监听的服务器套接字,但这个解决方案不起作用。它只是导致连接到 127.0.0.1:port 在我自己的机器上不起作用。 这不是问题的答案。为什么标记不正确。在这种情况下,其他答案也是错误的,对于提出相同问题的所有其他人,它应该保持开放和无人回答。【参考方案3】:谢谢斯卡夫曼。下面的代码进行了一些操作(硬编码 127.0.0.1)。
int port = .....
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1", port);
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(socketAddress);
serverSocket.accept();
如果我从 InetAddress.getLocalHost() 读取本地地址,同一子网上的其他网络用户仍然可以看到我的服务器。
莫森。
【讨论】:
D'oh,是的,我忘记了InetAddess.getLocalHost()
没有给你 127.0.0.1,它给出了该本地主机的外部 IP 地址。我的错。
是的,我发现 InetAddress.getLocalHost() 也没有按预期工作。
请注意,“我正在监听 127.0.0.1,因此只有本地用户可以连接到我”假设有时会失败 - 例如,如果您的计算机上运行了可以强制连接的代理代表远程用户到 127.0.0.1。以上是关于如何确定传入连接来自本地计算机的主要内容,如果未能解决你的问题,请参考以下文章