Jetty Hook用于TCP / IP连接的早期撤销(避免接受())

时间:2015-06-28 20:23:33

标签: security jetty hook tcp-ip connector

我正在寻找一个Hook,允许我告诉/指示ServerConnector(或Jetty架构中的任何其他对象,这将是一个更合适的钩点)不接受Web服务器端口上的传入TCP / IP连接(例如:80或443)基于远程方的IP地址(因为这是在调用accept()之前可用的所有信息,之前,接受后的LATER,HTTP数据可从TCP / IP帧获得& #39; s有效载荷)。

我的想法是,我将附加一个软件的和平软件,每个传入的连接可以说:接受/撤销。 撤消传入连接将是IGNORED,套接字将保持关闭状态,避免Jetty容器在其上执行更多工作/使用资源。

它还可以在某些服务器端口之后通过仅接受本地地址(10.32 ....)等来保护系统功能(例如特殊管理菜单)。它本来会更好也可以到达连接设备的MAC地址,只有在MAC地址在授权列表中时才允许访问(=用户有物理访问LAN连接他的设备,否则他的MAC地址永远不会是在LAN上可以看到,因为如果不在同一个LAN上,则没有对等MAC地址交换。)

通过这种方式,我打算防止恶意连接消耗CPU,带宽和套接字,只是为了向他们发送主要的'攻击期间的页面并迫使他们等待超时。同时,它还允许基于物理本地访问来保护对非公共功能的访问。钩子软件甚至可以撤销部分IP地址的连接,例如中文IP地址范围等。

我在ServerConnector类上找到了典型的TCP / IP套接字接口(打开/关闭/接受/ ...),但我找不到可以注册pre-accept()挂钩的地方或者打回来。我还查看了ServerConnector的类祖先,但我也没有看到任何类型的东西。我从org.eclipse.jetty.server Class ServerConnector

开始

为了清楚起见,对于那些与代码更加坦诚相关的人来说,这将在概念上代表我所寻找的内容。

...setup Jetty server, Factories, etc

ServerConnector http2=new ServerConnector(this.oServer,sslF,alpnF,h2F,https2F);
http2.setPort(8443);

http2.setPreAcceptHook(8843, oMyHook); <---INVENTED line

this.oServer.addConnector(http2);

钩子是MyHook对象的一个​​简单方法,返回true或false。

boolean AcceptRevoke(IP, Port) <--return true=accept, false=revoke

我欢迎提供任何关于查看方向(类名称左右)或确认此类功能不可用或不可用的提示,因此永远不可用。容器设计中可能存在约束,这些约束不允许预先接受的撤销,就像那些可以用套接字库做的那样,我不知道,因此会寻找不可能。

非常感谢。

产品和版本信息: Jetty 9.3.0(v20150612) alpn-boot-8.1.3(v20150130) JRE 8(Oracle 1.8.0 Build 45 - b15)

2 个答案:

答案 0 :(得分:1)

你有很多工作

要做到这一点,您基本上必须为Java提供自己的Socket实现层。在Jetty中没有可以挂钩的层,可以让你做任何你提到的事情。您想要做的事情的级别要低得多,有些是JVM和/或OS级别。

您需要处理java.net.Socketjava.net.ServerSocketjava.nio.channels.ServerSocketChannel

这意味着您将为常规套接字编写自己的javax.net.ServerSocketFactoryjavax.net.SocketFactoryjava.net.SocketImpljava.net.SocketImplFactory

对于SSL / TLS,您需要编写/处理/管理自己的javax.net.ssl.SSLSocketjavax.net.ssl.SSLServerSocketjavax.net.ssl.SSLSocketFactoryjavax.net.ssl.SSLServerSocketFactory

并且不要忘记获取标准OpenJDK SSL库的所有jetty-alpn代码添加内容,以便您也可以使HTTP / 2正常工作(因为您显然正在使用它,基于你的问题详情)

在Jetty上测试之前,请在简单的ServerSocket和ServerSocketChannel设置上测试您的实现。

确认它完成了你想要的后,你需要将它连接到Jetty。对于普通的ServerSocket / ServerSocketChannel,您必须使用系统范围java.nio.channels.spi.SelectorProvider

对于SSLServerSocket / SSLServerSocketChannel,您可以通过自己的自定义/覆盖org.eclipse.jetty.util.ssl.SslContextFactory实现连接它。

或......

您可以使用后接受逻辑(内置于Jetty)和连接的OS级别管理(例如iptables)的组合,这将更加简单。

您声明可以使用Java服务器挂接到接受点之前的要求,但这是扩展核心Java网络和Socket行为的一种特殊工作。

答案 1 :(得分:0)

作为替代方案,您可能只需覆盖ServerConnector的configure(套接字套接字)方法。如果要拒绝套接字,只需关闭连接即可。这可能会导致一些奇怪的异常,如果是这样,我们会在bugzilla中报告它们,我们会清理它们。

Alternate或者,打开一个bugzilla,要求我们保护接受的(套接字套接字)方法而不是私有方法,你可以在那里拒绝。

请注意,对于其中任何一个,客户端将看到连接已接受,然后立即关闭。