-
Notifications
You must be signed in to change notification settings - Fork 818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection filter interface for IP Bans #747
base: main
Are you sure you want to change the base?
Connection filter interface for IP Bans #747
Conversation
Take a look at |
Thank you for your reply. I have an All interceptor methods:
All
I am aware. An IP ban will be an escalation with a relatively short TTL. I am additionally seeking lighter means of action before this, such as kicking the client ID a few times, looking for things like many clients per IP that exhibit bad behavior, etc before even instituting an IP ban. But please understand that we have an internet-reachable broker up maybe a few months where we already see behaviors clearly identifiable as malicious brute force attempts and it just doesn't make sense to entertain any connections from these addresses for at least a few minutes/hours/days. Additionally we are looking at updating our clients (IoT devices, the ones we can reach) to be more secure, but as mentioned cannot easily make changes server-side that will break the ability of legacy clients to connect. Those client rely on messaging to be notified of the updates we are trying to distribute. Thanks again. |
Of course, this should be used to identify the problem, but not to eliminate it. I'm just trying to push the thoughts to the bit different direction - instead of relying on very low level of networking it might be desirable to identify a problem connection and, for example, to disconnect it and to lock its authorization. We have accumulated a huge negative experience of banning by IP as a first shot - there are a lot of instances running on clouds or using dynamically allocated gateways to reach the broker. So, I just warned you to be honest. Never mind. |
Understandable. And its preferable to avoid banning good clients using legitimate services, VPNs, etc. I don't think its bad advice at all. We do currently lack the ability to disconnect a client, something I noticed your PR does try to address. Thank you! |
FYI #744 has been merged into the |
Hi @kazetsukaimiko
We have some minor PRs such as #699 and #630, plus I have the idea to create a DSL to simplify the creation of the server configuration (instances of IConfig) to make embedding smoother. Then I'll cut the
I see value in this feature, have to check carefully the PR, because adding another argument to the |
Then perhaps solve the DSL and config builder problems first, and I'll resolve any conflicts after, would be my proposition. Also, switch to Optional where appropriate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left some comments.
I think we can annotate the new interface also as FunctionInterface, so that in some cases, maybe some test we can leverage some goodies provided by Java 8+
@@ -275,6 +277,7 @@ public void startServer(IConfig config, List<? extends InterceptHandler> handler | |||
initialized = true; | |||
} | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -472,6 +475,16 @@ private IAuthorizatorPolicy initializeAuthorizatorPolicy(IAuthorizatorPolicy aut | |||
return authorizatorPolicy; | |||
} | |||
|
|||
private IConnectionFilter initializeConnectionFilter(IConnectionFilter connectionFilter, IConfig props) { | |||
LOG.debug("Configuring MQTT Connection Filter"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Debug log should carry some useful information like, the connectionFilterClassName
String connectionFilterClassName = props.getProperty(BrokerConstants.CONNECTION_FILTER_CLASS_NAME, ""); | ||
|
||
if (connectionFilter == null && !connectionFilterClassName.isEmpty()) { | ||
connectionFilter = loadClass(connectionFilterClassName, IConnectionFilter.class, IConfig.class, props); | ||
} | ||
return connectionFilter; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is a copy and paste of the initial part of initializeAuthenticator
and initializeAuthorizatorPolicy
, so maybe could be extracted in a separate method and reused.
@@ -94,7 +96,7 @@ private MQTTConnection createMQTTConnection(BrokerConfiguration config, Channel | |||
sessionRegistry = new SessionRegistry(subscriptions, memorySessionsRepository(), queueRepository, permitAll, scheduler, loopsGroup); | |||
final PostOffice postOffice = new PostOffice(subscriptions, | |||
new MemoryRetainedRepository(), sessionRegistry, ConnectionTestUtils.NO_OBSERVERS_INTERCEPTOR, permitAll, loopsGroup); | |||
return new MQTTConnection(channel, config, mockAuthenticator, sessionRegistry, postOffice); | |||
return new MQTTConnection(channel, config, mockAuthenticator, connectionFilter, sessionRegistry, postOffice); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that in this test we don't use the filter we could inline it, without creating an used variable:
return new MQTTConnection(channel, config, mockAuthenticator, new MockConnectionFilter(), sessionRegistry, postOffice);
Or better, given that it's a pass-all filter, a more explicit implementation could be used for such cases:
public class AcceptAllFilter implements IConnectionFilter {
@Override
public boolean allowConnection(ClientDescriptor clientDescriptor) {
return true;
}
}
In all test places where special filtering logic is not needed we can use:
return new MQTTConnection(channel, config, mockAuthenticator, new AcceptAllFilter(), sessionRegistry, postOffice);
This comment is valid also for other places where the MockConnectionFilter is used with the same intention.
I'm doing an integration with an application server (Quarkus). Due to some legacy support requirements, we do need to leave some endpoints rather open to abuse, so we are monitoring client connections, message counts and payloads to watch for DoS attempts.
If their message count for a given topic far exceeds a normal threshold, or their payloads balloon in size, or they start sending us garbage, I'd like to ban the clients by IP. This is a shot at making an interface similar to the
IAuthenticator
interface for vetoing client connections.Suggestions welcome. It is currently possible for me to work around the need for this using dependency injection, but that creates a circular dependency between the broker (
Server::listConnectedClients
) and theIAuthenticator
.