![]() |
|
||
Session limitationThe Dante server has support for limiting the number of active TCP or UDP session and the rate at which new sessions can be established. This page describes how the session functionality can be configured. Note that the session syntax and functionality described here is found only in Dante versions 1.4.0 and later, replaces the similar session limit functionality that is available as a commercial module for previous versions of Dante. Session control functionalityThe Dante server supports several keywords that can be used to control the number of active sessions. A session is essentially any active traffic mapping present in the SOCKS server, corresponding to a single SOCKS client control connection. These keywords can be used in any rule type (client/hostid/socks). The keywords fall into two groups: those that specify a total limit for all clients matching the rule the keywords are used in, and those that specify a limit on any unique client IP-address matching the rule. Limits can be enforced on both TCP and UDP sessions.The session.max and session.throttle keywords specify total limits for a rule:
The session.state.key, session.state.key.hostindex and session.state.max, and session.state.throttle keywords enforce similar limits, but apply control per client IP-address, rather than simply for all sessions matching the rule. In other words, each unique client IP-address will be allowed to create the specified number of sessions, at the specified rate, and the sessions created by one client IP-address will not affect other clients. Per client IP-address limits can be combined with global limits, in which case both limits will be enforced.
In addition, there is a keyword that determines whether the session limit that applies to a client should follow the client to access rules higher up in the hierarchy, or apply only at the level the session limit is specified:
Quick-start exampleThe following example illustrates how the session keywords can be used in a typical configuration. The session keywords in the rule limit the total number of sessions to 10000 and specify that a maximum of 100 new sessions can be created each second. In addition there is a limit on the maximum number of sessions that can come from a single source IP-address: at most 100 sessions are allowed from each IP-address, and at most 10 new sessions every two seconds can be created from a single IP-address. #pass all requests but limit the number of sessions and connect rate client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error #limit for all clients session.max: 10000 session.throttle: 100/1 #per-ip limit session.state.key: from session.state.max: 100 session.state.throttle: 10/2 } socks pass { from: 0.0.0.0/0 to: 10.0.0.0/8 log: connect disconnect error } Each connection that is accepted is checked both against the per IP-address limits for the client source address (session.state.max and session.state.throttle) and against the combined limit for all clients (session.max and session.throttle). Since the default value (yes) for session.inheritable is used and the subsequent socks-rule does not override the session values, the session limits from the client-rule will apply to all connections that are received, regardless of whether they are in the SOCKS protocol negotiation phase or have completed this and are actively doing I/O. Session log formatWhen a connection is blocked due to a session limit this will be indicated in the log output from Dante (provided the Dante configuration specifies that connections should be logged). There are four possible descriptions used in the log lines, one for each of the session.max, session.throttle, session.state.max, and session.state.throttle limits. The descriptions have the following format:
The above messages are used in the part of the block log entries that describe the reason why a request has been blocked. In a log file, the resulting full log message can look like the following, which corresponds to a per IP-address throttle limit of 3 having been reached: info: block(1): tcp/accept ]: 10.0.0.1.34639 172.16.0.27.7877: per-key session rate limit reached (already accepted 3 new clients during the last 1s. Current client count: 3)Session limit configuration approachesAs long as the session limits can be enforced in either client-rules or hostid-rules, it is possible to set limits in the relatively simple way described above, without having to consider in too much detail how the rule processing in Dante works or what protocols are used. However, if it is necessary to set limits based on information that is only available after SOCKS negotiation has completed and the target destination is known, it is useful to know how the request processing in Dante works. The requests processing in Dante is basically performed in these steps:
When the client and hostid-rules are evaluated, the following information is available:
If the above information is sufficient to determine how the session limits should be set, it is recommended that session limits are always set in either the client-rules or hostid-rules, and not in the socks-rules. If this is not possible, session limits can also be set in the socks-rules, which are evaluated after SOCKS processing. When the socks-rules are evaluated, the following additional information is available:
Limits that are set in socks-rules can only be applied after SOCKS request processing has completed, meaning that no session limits will be enforced on clients until SOCKS negotiation has completed, unless session limits are also specified in client-rules or hostid-rules. Rule evaluation, session limits and inheritanceSession limits that are set in a client-rule or hostid-rule will by default be inherited by the matching socks-rule, and thus apply to all matching clients, regardless of where these clients are in the request evaluation process. The limits set at one stage, e.g., the client-rule stage, will in other words not be reset when the client enters the next stage, e.g., the socks-rule stage. This behavior can be controlled by the session.inheritable keyword, which by default has the value yes. A session being inheritable results in the specified session limitations applying to the connection for its entire lifetime, unless explicitly overridden by a limit in a later, higher level, rule. Thus if session.inheritable is set to yes in a client-rule, it will apply in any subsequently matching hostid-rules or socks-rules, unless any of those rules also have session limits specified. If the keyword is set in a hostid-rule, it will apply in any subsequently matching socks-rules, unless the socks-rule also has session limits specified. Setting the session.inheritable this keyword in a socks-rule would have no meaning, as socks-rules are the last rules in the chain. Only one session limitation can apply to a client at a time; a session limit set in a client-rule will be overridden by any session limit set in a matching hostid-rule or socks-rule. The session limits are inherited on a all-or-nothing basis; either all the session limits specified for a client in a lower-level rule are inherited by the higher-level rule, or none of them are. For example, in the client-rule below, a session limit is set that specifies both max limits and per IP-address limits. The first socks pass-rule, matching connections to the 10/8 network, does not specify a new session limit, which will cause the session limits from the client-rule to continue to be used. For connections to the server www.example.org however, a new limit is specified and this limit overrides any session limits from the client-rule, including the session values that are not specified in the new limit (such as the session.state values that are only set in the client-rule). During SOCKS negotiation, the client-rule limits apply, but after Dante has completed request processing and found the matching socks-rule, the session limits in the socks-rule are used instead. This essentially means that there is one session limit that applies to both clients in the SOCKS protocol negotiation phase and clients that are communicating with hosts in the 10-network, and a different session limit that applies to clients that have completed the SOCKS protocol negotiation phase and are communicating with the server www.example.org. client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 #limit for all clients session.max: 100 session.throttle: 10/1 #per-IP limit session.state.key: from session.state.max: 10 session.state.throttle: 10/2 } #connections to the 10-network socks pass { from: 0.0.0.0/0 to: 10.0.0.0/8 #no limits } #connections to the server www.example.org socks pass { from: 0.0.0.0/0 to: www.example.org #limit for all clients session.max: 10 session.throttle: 10/1 } If session.inheritable is set to no in a client-rule or a hostid-rule, the session limitations will not be inherited and will only apply to clients that have not yet entered the socks-rule stage (this corresponds to the behavior of the original Dante session module). One usage scenario where not using session inheritance could be useful is for a Dante SOCKS server accessible from the public Internet, where it might be desirable to carefully limit the number of connections that can be made to the SOCKS server by any random user, but where there might be less strict, or no, limitations on users that have successfully completed SOCKS negotiation. The following configuration would achieve this by having limits set in the client-rule, but disabling inheritance of the limits so that they would not apply to the subsequent socks-rule (i.e., after SOCKS negotiation has completed). client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 #combined limit for all clients session.max: 100 session.throttle: 10/1 #per-IP limit session.state.key: from session.state.max: 10 session.state.throttle: 10/2 #limit should only apply until SOCKS negotiation has completed session.inheritable: no } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 #no limits } Usage exampleBelow is a fairly complex example that combines the functionality for handling hostid values with session limits. The server is assumed to not communicate directly with clients but receive connections from a trusted proxy, with the IP-address 192.168.1.1. Only connections from this address are accepted, and the connections are required to have a hostid value set. Additional restrictions are placed by the hostid-rule, which will only accept connections with a hostid value from the 172.16/12 network. The socks-rule only accepts connection requests to the 10-network. In addition to this, there are session limits on both the maximum number of connections that will be accepted (5000), and the rate at which new connections will be accepted (50 connections per second). For any given hostid address, there are also limits on the max number of connections (10) and the rate of new connections (10 per every 2 seconds). These session limitations will be applied to all requests, regardless of whether they have finished SOCKS processing or not. #always add client IP on outgoing connections, keeping the existing value. external.tcp.hostid: add-client #pass client connections from the trusted server 192.168.1.1, but require #them to have a hostid set. client pass { from: 192.168.1.1/32 to: 0.0.0.0/0 #require that hostid values are set hostid: 0.0.0.0/0 #limit for all clients session.max: 5000 session.throttle: 50/1 #per-IP limit, using hostid IP address session.state.key: hostid session.state.key.hostindex: 1 #use first hostid value, default session.state.max: 10 session.state.throttle: 10/2 session.inheritable: yes #apply also in hostid/socks-rules, default } #only clients with a hostid from the 172.16-net are accepted. hostid pass { from: 172.16.0.0/12 to: 0.0.0.0/0 hostindex: 1 #only match first value, default } #allow accepted clients to connect to the internal 10-net. socks pass { from: 0.0.0.0/0 to: 10.0.0.0/8 } Special notesLimits are enforced on both TCP and UDP sessions, but they are not enforced on individual UDP packets. In the case of UDP sessions, the limit of a socks-rule will be enforced based on the address of client's TCP control connection, and not based on the client's UDP address or target. |