blob: 510ada68e82759983d5e438762e2effeb033c942 [file] [log] [blame]
Willy Tarreaud1142aa2007-01-07 13:03:59 +01001Prévoir des commandes en plusieurs mots clés.
2Par exemple :
3
4 timeout connection XXX
5 connection scale XXX
6
7On doit aussi accepter les préfixes :
8
9 tim co XXX
10 co sca XXX
11
12Prévoir de ranger les combinaisons dans un tableau. On doit même
13pouvoir effectuer un mapping simplifiant le parseur.
14
15
16Pour les filtres :
17
18
19 <direction> <where> <what> <operator> <pattern> <action> [ <args>* ]
20
21 <direction> = [ req | rsp ]
22 <where> = [ in | out ]
23 <what> = [ line | LINE | METH | URI | h(hdr) | H(hdr) | c(cookie) | C(cookie) ]
24 <operator> = [ == | =~ | =* | =^ | =/ | != | !~ | !* | !^ | !/ ]
25 <pattern> = "<string>"
26 <action> = [ allow | permit | deny | delete | replace | switch | add | set | redir ]
27 <args> = optionnal action args
28
29 exemples:
30
31 req in URI =^ "/images" switch images
32 req in h(host) =* ".mydomain.com" switch mydomain
33 req in h(host) =~ "localhost(.*)" replace "www\1"
34
35 alternative :
36
37 <direction> <where> <action> [not] <what> [<operator> <pattern> [ <args>* ]]
38
39 req in switch URI =^ "/images" images
40 req in switch h(host) =* ".mydomain.com" mydomain
41 req in replace h(host) =~ "localhost(.*)" "www\1"
42 req in delete h(Connection)
43 req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
44 req out set h(Connection) "close"
45 req out add line "Server: truc"
46
47
48 <direction> <action> <where> [not] <what> [<operator> <pattern> [ <args>* ]] ';' <action2> <what2>
49
50 req in switch URI =^ "/images/" images ; replace "/"
51 req in switch h(host) =* ".mydomain.com" mydomain
52 req in replace h(host) =~ "localhost(.*)" "www\1"
53 req in delete h(Connection)
54 req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
55 req out set h(Connection) "close"
56 req out add line == "Server: truc"
57
58
59Extension avec des ACL :
60
61 req in acl(meth_valid) METH =~ "(GET|POST|HEAD|OPTIONS)"
62 req in acl(meth_options) METH == "OPTIONS"
63 req in acl(uri_slash) URI =^ "/"
64 req in acl(uri_star) URI == "*"
65
66 req in deny acl !(meth_options && uri_star || meth_valid && uri_slash)
67
68Peut-être plus simplement :
69
70 acl meth_valid METH =~ "(GET|POST|HEAD|OPTIONS)"
71 acl meth_options METH == "OPTIONS"
72 acl uri_slash URI =^ "/"
73 acl uri_star URI == "*"
74
75 req in deny not acl(meth_options uri_star, meth_valid uri_slash)
76
77 req in switch URI =^ "/images/" images ; replace "/"
78 req in switch h(host) =* ".mydomain.com" mydomain
79 req in replace h(host) =~ "localhost(.*)" "www\1"
80 req in delete h(Connection)
81 req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
82 req out set h(Connection) "close"
83 req out add line == "Server: truc"
84
85Prévoir le cas du "if" pour exécuter plusieurs actions :
86
87 req in if URI =^ "/images/" then replace "/" ; switch images
88
89Utiliser les noms en majuscules/minuscules pour indiquer si on veut prendre
90en compte la casse ou non :
91
92 if uri =^ "/watch/" setbe watch rebase "/watch/" "/"
93 if uri =* ".jpg" setbe images
94 if uri =~ ".*dll.*" deny
95 if HOST =* ".mydomain.com" setbe mydomain
96 etc...
97
98Another solution would be to have a dedicated keyword to URI remapping. It
99would both rewrite the URI and optionally switch to another backend.
100
101 uriremap "/watch/" "/" watch
102 uriremap "/chat/" "/" chat
103 uriremap "/event/" "/event/" event
104
105Or better :
106
107 uriremap "/watch/" watch "/"
108 uriremap "/chat/" chat "/"
109 uriremap "/event/" event
110
111For the URI, using a regex is sometimes useful (eg: providing a set of possible prefixes.
112
113
114Sinon, peut-être que le "switch" peut prendre un paramètre de mapping pour la partie matchée :
115
116 req in switch URI =^ "/images/" images:"/"
117
Willy Tarreau985fc562007-04-01 09:44:10 +0200118
1192007/03/31 - Besoins plus précis.
120
1211) aucune extension de branchement ou autre dans les "listen", c'est trop complexe.
122
123Distinguer les données entrantes (in) et sortantes (out).
124
125Le frontend ne voit que les requetes entrantes et les réponses sortantes.
126Le backend voir les requêtes in/out et les réponses in/out.
127Le frontend permet les branchements d'ensembles de filtres de requêtes vers
128d'autres. Le frontend et les ensembles de filtres de requêtes peuvent brancher
129vers un backend.
130
131-----------+--------+----------+----------+---------+----------+
132 \ Where | | | | | |
133 \______ | Listen | Frontend | ReqRules | Backend | RspRules |
134 \| | | | | |
135Capability | | | | | |
136-----------+--------+----------+----------+---------+----------+
137Frontend | X | X | | | |
138-----------+--------+----------+----------+---------+----------+
139FiltReqIn | X | X | X | X | |
140-----------+--------+----------+----------+---------+----------+
141JumpFiltReq| X | X | X | | | \
142-----------+--------+----------+----------+---------+----------+ > = ReqJump
143SetBackend | X | X | X | | | /
144-----------+--------+----------+----------+---------+----------+
145FiltReqOut | | | | X | |
146-----------+--------+----------+----------+---------+----------+
147FiltRspIn | X | | | X | X |
148-----------+--------+----------+----------+---------+----------+
149JumpFiltRsp| | | | X | X |
150-----------+--------+----------+----------+---------+----------+
151FiltRspOut | | X | | X | X |
152-----------+--------+----------+----------+---------+----------+
153Backend | X | | | X | |
154-----------+--------+----------+----------+---------+----------+
155
156En conclusion
157-------------
158
159Il y a au moins besoin de distinguer 8 fonctionnalités de base :
160 - capacité à recevoir des connexions (frontend)
161 - capacité à filtrer les requêtes entrantes
162 - capacité à brancher vers un backend ou un ensemble de règles de requêtes
163 - capacité à filtrer les requêtes sortantes
164 - capacité à filtrer les réponses entrantes
165 - capacité à brancher vers un autre ensemble de règles de réponses
166 - capacité à filtrer la réponse sortante
167 - capacité à gérer des serveurs (backend)
168
169Remarque
170--------
171 - on a souvent besoin de pouvoir appliquer un petit traitement sur un ensemble
172 host/uri/autre. Le petit traitement peut consister en quelques filtres ainsi
173 qu'une réécriture du couple (host,uri).
174
175
176Proposition : ACL
177
178Syntaxe :
179---------
180
181 acl <name> <what> <operator> <value> ...
182
183Ceci créera une acl référencée sous le nom <name> qui sera validée si
184l'application d'au moins une des valeurs <value> avec l'opérateur <operator>
185sur le sujet <what> est validée.
186
187Opérateurs :
188------------
189
190Toujours 2 caractères :
191
192 [=!][~=*^%/.]
193
194Premier caractère :
195 '=' : OK si test valide
196 '!' : OK si test échoué.
197
198Second caractère :
199 '~' : compare avec une regex
200 '=' : compare chaîne à chaîne
201 '*' : compare la fin de la chaîne (ex: =* ".mydomain.com")
202 '^' : compare le début de la chaîne (ex: =^ "/images/")
203 '%' : recherche une sous-chaîne
204 '/' : compare avec un mot entier en acceptant le '/' comme délimiteur
205 '.' : compare avec un mot entier en acceptant el '.' comme délimiteur
206
207Ensuite on exécute une action de manière conditionnelle si l'ensemble des ACLs
208mentionnées sont validées (ou invalidées pour celles précédées d'un "!") :
209
210 <what> <where> <action> on [!]<aclname> ...
211
212
213Exemple :
214---------
215
216 acl www_pub host =. www www01 dev preprod
217 acl imghost host =. images
218 acl imgdir uri =/ img
219 acl imagedir uri =/ images
220 acl msie h(user-agent) =% "MSIE"
221
222 set_host "images" on www_pub imgdir
223 remap_uri "/img" "/" on www_pub imgdir
224 remap_uri "/images" "/" on www_pub imagedir
225 setbe images on imghost
226 reqdel "Cookie" on all
227
228
229
230Actions possibles :
231
232 req {in|out} {append|delete|rem|add|set|rep|mapuri|rewrite|reqline|deny|allow|setbe|tarpit}
233 resp {in|out} {append|delete|rem|add|set|rep|maploc|rewrite|stsline|deny|allow}
234
235 req in append <line>
236 req in delete <line_regex>
237 req in rem <header>
238 req in add <header> <new_value>
239 req in set <header> <new_value>
240 req in rep <header> <old_value> <new_value>
241 req in mapuri <old_uri_prefix> <new_uri_prefix>
242 req in rewrite <old_uri_regex> <new_uri>
243 req in reqline <old_req_regex> <new_req>
244 req in deny
245 req in allow
246 req in tarpit
247 req in setbe <backend>
248
249 resp out maploc <old_location_prefix> <new_loc_prefix>
250 resp out stsline <old_sts_regex> <new_sts_regex>
251
252Les chaînes doivent être délimitées par un même caractère au début et à la fin,
253qui doit être échappé s'il est présent dans la chaîne. Tout ce qui se trouve
254entre le caractère de fin et les premiers espace est considéré comme des
255options passées au traitement. Par exemple :
256
257 req in rep host /www/i /www/
258 req in rep connection /keep-alive/i "close"
259
260Il serait pratique de pouvoir effectuer un remap en même temps qu'un setbe.
261
262Captures: les séparer en in/out. Les rendre conditionnelles ?