1 | This patch (20060126) makes tcpserver from DJB's ucspi-tcp-0.88 package (see |
---|
2 | http://cr.yp.to/ucspi-tcp.html) to modify its behavior if some environment |
---|
3 | variables are present. |
---|
4 | |
---|
5 | The variables can be preset before starting tcpserver (thus acting as |
---|
6 | default for all connections), or, if you use 'tcpserver -x xxx.cdb', they |
---|
7 | can be set (or overridden) from xxx.cdb. If none of the variables are set, |
---|
8 | tcpserver behaves same as non patched version (except for negligible |
---|
9 | performance loss). Any or all variables can be set, as soon as first limit |
---|
10 | is reached the connection is dropped. I'd recommend using .cdb files |
---|
11 | exclusively though, as you can then modify configuration without killing |
---|
12 | tcpserver. |
---|
13 | |
---|
14 | The variables are: |
---|
15 | |
---|
16 | (1) MAXLOAD |
---|
17 | maximum 1-minute load average * 100. For example, if you have line |
---|
18 | :allow,MAXLOAD="350" |
---|
19 | in your rules file from which you created .cdb, the connection will be |
---|
20 | accepted only if load average is below 3.50 |
---|
21 | |
---|
22 | See COMPILING instructions above for info on supported systems. |
---|
23 | |
---|
24 | (2) MAXCONNIP |
---|
25 | maximum connections from one IP address. tcpserver's -c flag defines |
---|
26 | maximum number of allowed connections, but it can be abused if |
---|
27 | just one host goes wild and eats all the connections - no other host |
---|
28 | would be able to connect then. If you created your .cdb with: |
---|
29 | :allow,MAXCONNIP="5" |
---|
30 | and run tcpserver -c 50, then each IP address would be able to have at |
---|
31 | most 5 concurrent connections, while there still could connect 50 |
---|
32 | clients total. |
---|
33 | 0 is valid value and means 'always reject' |
---|
34 | |
---|
35 | (3) MAXCONNC |
---|
36 | |
---|
37 | maximum connections from whole C-class (256 addresses). Extension of |
---|
38 | MAXCONNIP, as sometimes the problematic client has a whole farm of |
---|
39 | client machines with different IP addresses instead of just one IP |
---|
40 | address, and they all try to connect. It might have been more useful to |
---|
41 | be able to specify CIDR block than C-class, but I've decided to KISS. |
---|
42 | |
---|
43 | for example tcpserver -c 200, and .cdb with: |
---|
44 | :allow,MAXCONNC="15" |
---|
45 | will allow at most 15 host from any x.y.z.0/24 address block, while |
---|
46 | still allowing up to 200 total connections. |
---|
47 | 0 is valid value and means 'always reject' |
---|
48 | |
---|
49 | (4) DIEMSG |
---|
50 | |
---|
51 | if set and one of the above limits is exceeded, this is the message |
---|
52 | to be sent to client (CRLF is always added to the text) before terminating |
---|
53 | connection. If unset, the connection simply terminates (after 1 sec delay) |
---|
54 | if limit is exceeded. |
---|
55 | |
---|
56 | For example: |
---|
57 | DIEMSG="421 example.com Service temporarily not available, closing |
---|
58 | transmission channel" |
---|
59 | |
---|
60 | (5) DIEMSG_MAXLOAD |
---|
61 | |
---|
62 | If set, and a connection is denied because the MAXLOAD limit is exceeded, |
---|
63 | this value will be used instead of DIEMSG. |
---|
64 | |
---|
65 | For example: |
---|
66 | DIEMSG_MAXLOAD="421 example.com Server busy, try again later." |
---|
67 | |
---|
68 | (6) DIEMSG_MAXCONNIP |
---|
69 | |
---|
70 | If set, and a connection is denied because the MAXCONNIP limit is exceeded, |
---|
71 | this value will be used instead of DIEMSG. |
---|
72 | |
---|
73 | For example: |
---|
74 | DIEMSG_MAXCONNIP="421 example.com Too many connections from your IP." |
---|
75 | |
---|
76 | (7) DIEMSG_MAXCONNC |
---|
77 | |
---|
78 | If set, and a connection is denied because the MAXCONNC limit is exceeded, |
---|
79 | this value will be used instead of DIEMSG. |
---|
80 | |
---|
81 | For example: |
---|
82 | DIEMSG_MAXCONNC="421 example.com Too many connections from your network." |
---|
83 | |
---|
84 | Notes: |
---|
85 | |
---|
86 | - if a connection is dropped due to some of those variables set, it will be |
---|
87 | flagged (if you run tcpserver -v) with "MAXLOAD:", "MAXCONNIP:" or |
---|
88 | "MAXCONNC:" at the end of the "tcpserver: deny" line. If that bothers you |
---|
89 | (eg. you have a strict log parsers), don't apply that chunk of the patch. |
---|
90 | |
---|
91 | - the idea for this patch came from my previous experience with xinetd, and |
---|
92 | need to limit incoming bursts of virus/spam SMTP connections, since I was |
---|
93 | running qmail-scanner to scan incoming and outgoing messages for viruses |
---|
94 | and spam. |
---|
95 | |
---|
96 | When you make changes, please check that they work as expected. |
---|
97 | |
---|
98 | Examples (for tcprules created .cdb) |
---|
99 | (a) 192.168.:allow,MAXLOAD="1000" |
---|
100 | :allow,MAXCONNIP="3" |
---|
101 | |
---|
102 | this would allow any connection from your local LAN (192.168.*.* |
---|
103 | addresses) if system load is less than 10.00. non-LAN connections would |
---|
104 | be accepted only if clients from that IP address have not already opened |
---|
105 | more than 2 connections (as your connection would be last allowed -- 3rd) |
---|
106 | |
---|
107 | (b) 192.168.:allow |
---|
108 | 5.6.7.8:allow,MAXCONNIP="3" |
---|
109 | 1.2.:allow,MAXLOAD="500",MAXCONNIP="1",MAXCONNC="5" |
---|
110 | :allow,MAXLOAD="1000",MAXCONNIP="3",DIEMSG="421 example.com unavailable" |
---|
111 | |
---|
112 | if client connects from 192.168.*.* (ex: your LAN), it is allowed. |
---|
113 | if it connects from 5.6.7.8 (ex: little abusive customer of yours), |
---|
114 | it is allowed unless there are already 3active connections from 5.6.7.8 |
---|
115 | to this service |
---|
116 | if it connects from 1.2.*.* (ex: some problematic networks which caused |
---|
117 | you grief in the past) it will connect only if load is less than 5.0, |
---|
118 | there is less than 5 active connections from whole C class |
---|
119 | (1.2.*.0/24), and if that specific IP address does not already have |
---|
120 | connection open. |
---|
121 | in all other cases, the client will be permitted to connect if load is |
---|
122 | less than 10.00 and client has 2 or less connections open. If load is |
---|
123 | higher than 10.00 or there are 3 or more connections open from this |
---|
124 | client, the message "421 example.com unavailable" will be returned to |
---|
125 | the client and connection terminated. |
---|
126 | |
---|
127 | |
---|
128 | Any bugs introduced are ours, do not bother DJB with them. |
---|
129 | If you find any, or have neat ideas, or better documentation, or whatever, |
---|
130 | contact me. |
---|
131 | |
---|
132 | the 2006-01-26 version of the patch can be found at: |
---|
133 | http://linux.voyager.hr/ucspi-tcp/ |
---|
134 | |
---|
135 | the 2007-12-22 version of the patch can be found at: |
---|
136 | http://qmail.jms1.net/ucspi-tcp/ |
---|
137 | |
---|
138 | Enjoy, |
---|
139 | Matija Nalis < mnalis-tcpserver _at_ voyager.hr > |
---|
140 | John Simpson <jms1@jms1.net> (2007-12-22 version) |
---|