我已经为正在摆弄的软件解决方案编写了一个 Java 服务器应用程序。
服务器使用多线程来处理套接字并使用 postgresql 作为数据库。我担心潜在的作恶者,因为现在,有人很容易通过快速反复连接来破坏我的服务器。
基本上,我正在寻找一种方法来仅接受过去一秒或更长时间未连接的计算机的连接。我想我可以注册所有连接并设置一个计时器,但我还发现服务器仍然可能因为必须同时检查许多连接而超载,尽管没有没有计时器时那么多。
我已经搜索了 stackoverflow 和 serverfault,但没有找到关于这个特定问题的结果 :/。
设置非常简单。所有连接都在主方法中接受并转发到相应的线程:
public static void main(String[] args) {
gui = new mainFrame();
try {
ServerSocket serverSock = new ServerSocket(80);
while (true) {
Socket sock = serverSock.accept();
new Thread(new listenThread(sock)).start();
}
} catch (IOException ex) {
methods.log("Couldn't create server");
ex.printStackTrace();
}
}
非常感激任何帮助。迈克。
答案1
您可以使用 iptables 在操作系统级别解决此问题。下面的几行取自 debian linux,YMMV。它将在 60 秒内将连接数限制为 3 个。
iptables -I INPUT -p tcp --dport 5432 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 5432 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
这假设您在端口 5432 上运行 postgresql 服务器,并且 eth0 是面向互联网的卡。
如果您希望限制其他端口,只需替换端口号即可。
来源和更多示例(对于 ssh,端口 22) http://www.debian-administration.org/articles/187
答案2
OSSEC 有一种称为“主动响应”的功能,它会查看服务器日志,如果某些规则被破坏,例如,用户尝试使用错误密码登录 SSH 超过 5 次,它将在一定时间内阻止 IP 地址。
您可以维护这样的列表,但正如您所指出的那样,它会变得非常冗长。一旦策略是为列表中的不同项目设置到期时间,那么您检查被阻止用户的列表就不会那么冗长。
这是高度概念性的,如果没有关于您的设置的更多详细信息,我无法为您提供更多帮助。
答案3
一个简单的解决方案是使用数据库服务器的连接池。这将成为限制数据库负载(进而限制服务器负载)的自然瓶颈。
或者将您的应用置于实现工作线程的基本 Web 服务器后面,并限制线程数量(或在您的应用中实现相同的操作)