@@ -231,6 +231,8 @@ public function doAction()
231
231
foreach ($ item ['spec ' ]['rules ' ] as $ ruleKey => $ rule ) {
232
232
$ aclName = $ frontend ['name ' ].'-rule- ' .$ ruleKey ;
233
233
$ host = $ rule ['host ' ];
234
+ //$host = "*.${host}"; // for testing purposes only
235
+ //$host = ""; // for testing purposes only
234
236
if (!$ this ->shouldCreateRule ($ rule )) {
235
237
continue ;
236
238
}
@@ -258,12 +260,76 @@ public function doAction()
258
260
// ssl_fc_sni (this can be used only with type http)
259
261
switch ($ sharedFrontend ['type ' ]) {
260
262
case "http " :
261
- $ acl ['value ' ] = "hdr(host) -i $ {host} path_beg -i $ {path}" ;
263
+ // https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards
264
+ // https://serverfault.com/questions/388937/how-do-i-match-a-wildcard-host-in-acl-lists-in-haproxy
265
+ $ hostACL = "" ;
266
+ if (substr ($ host , 0 , 2 ) == "*. " ) {
267
+ // hdr(host) -m reg -i ^[^\.]+\.example\.org$
268
+ // hdr(host) -m reg -i ^[^\.]+\.example\.org(:[0-9]+)?$
269
+ $ hostACL = "hdr(host) -m reg -i ^[^\.]+ " .str_replace (". " , "\. " , substr ($ host , 1 ))."(:[0-9]+)?$ " ;
270
+ } else {
271
+ $ hostACL = "hdr(host) -m reg -i ^ " .str_replace (". " , "\. " , $ host )."(:[0-9]+)?$ " ;
272
+ }
273
+
274
+ // https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types
275
+ // https://www.haproxy.com/documentation/hapee/latest/configuration/acls/syntax/
276
+ $ pathType = $ path ['pathType ' ] ?? null ;
277
+ $ pathACL = "" ;
278
+ switch ($ pathType ) {
279
+ case "Exact " :
280
+ /**
281
+ * Matches the URL path exactly and with case sensitivity.
282
+ */
283
+ $ pathACL = "path -m str $ {path}" ;
284
+ break ;
285
+ case "Prefix " :
286
+ /**
287
+ * Matches based on a URL path prefix split by /.
288
+ * Matching is case sensitive and done on a path element by element basis.
289
+ * A path element refers to the list of labels in the path split by the / separator.
290
+ * A request is a match for path p if every p is an element-wise prefix of p of the request path.
291
+ */
292
+ $ pathACL = "path -m beg $ {path}" ;
293
+ break ;
294
+ case "ImplementationSpecific " :
295
+ /**
296
+ * With this path type, matching is up to the IngressClass.
297
+ * Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types.
298
+ */
299
+ $ pathACL = "path -m beg $ {path}" ;
300
+ break ;
301
+ default :
302
+ $ pathACL = "path -m beg $ {path}" ;
303
+ break ;
304
+ }
305
+
306
+ if (empty ($ host )) {
307
+ $ hostACL = "" ;
308
+ }
309
+ $ acl ['value ' ] = trim ("$ {hostACL} $ {pathACL}" );
262
310
$ frontend ['ha_acls ' ]['item ' ][] = $ acl ;
263
311
break ;
264
312
case "https " :
265
313
$ this ->log ("WARN unexpected behavior may occur when using a shared frontend of type https, path-based routing will not work " );
266
- $ acl ['value ' ] = "req_ssl_sni -i $ {host}" ;
314
+
315
+ // https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards
316
+ // https://serverfault.com/questions/388937/how-do-i-match-a-wildcard-host-in-acl-lists-in-haproxy
317
+ $ hostACL = "" ;
318
+ if (substr ($ host , 0 , 2 ) == "*. " ) {
319
+ // hdr(host) -m reg -i ^[^\.]+\.example\.org$
320
+ // hdr(host) -m reg -i ^[^\.]+\.example\.org(:[0-9]+)?$
321
+ // sni should never have the port on the end as the host header may have
322
+ $ hostACL = "req_ssl_sni -m reg -i ^[^\.]+ " .str_replace (". " , "\. " , substr ($ host , 1 ));
323
+ } else {
324
+ $ hostACL = "req_ssl_sni -m str -i $ {host}" ; // exact match case-insensitive
325
+ }
326
+
327
+ if (empty ($ host )) {
328
+ $ hostACL = "" ;
329
+ $ this ->log ("WARN cannot create rule for $ {frontendName} because host is required for parent frontends of type: " .$ sharedFrontend ['type ' ]);
330
+ continue 3 ;
331
+ }
332
+ $ acl ['value ' ] = trim ("$ {hostACL}" );
267
333
$ frontend ['ha_acls ' ]['item ' ][] = $ acl ;
268
334
break ;
269
335
default :
0 commit comments