|
| 1 | +// Module included in the following assemblies: |
| 2 | +// |
| 3 | +// * networking/configuring-ingress-controller |
| 4 | + |
| 5 | +[id="using-wildcard-routes_{context}"] |
| 6 | += Using wildcard routes |
| 7 | + |
| 8 | +The HAProxy Ingress Controller has support for wildcard routes. The Ingress Operator uses `wildcardPolicy` to configure the `ROUTER_ALLOW_WILDCARD_ROUTES` environment variable of the Ingress Controller. |
| 9 | + |
| 10 | +The default behavior of the Ingress Controller is to admit routes with a wildcard policy of `None`, which is backwards compatible with existing `IngressController` resources. |
| 11 | + |
| 12 | +.Procedure |
| 13 | + |
| 14 | +. Configure the wildcard policy. |
| 15 | +.. Use the following command to edit the `IngressController` resource: |
| 16 | ++ |
| 17 | +---- |
| 18 | +$ oc edit IngressController |
| 19 | +---- |
| 20 | ++ |
| 21 | +.. Under `spec`, set the `wildcardPolicy` field to `WildcardsDisallowed` or `WildcardsAllowed`: |
| 22 | ++ |
| 23 | +[source,yaml] |
| 24 | +---- |
| 25 | +spec: |
| 26 | + routeAdmission: |
| 27 | + wildcardPolicy: WildcardsDisallowed # or WildcardsAllowed |
| 28 | +---- |
| 29 | + |
| 30 | +//// |
| 31 | +.Samples for using a secure wildcard edge terminated route |
| 32 | +
|
| 33 | +This example reflects TLS termination occurring on the Ingress Controller before traffic is proxied to the destination. Traffic sent to any hosts in the subdomain |
| 34 | +`example.test` (`*.example.test`) is proxied to the exposed service. |
| 35 | +
|
| 36 | +The secure edge terminated route specifies the TLS certificate and key |
| 37 | +information. The TLS certificate is served by the Ingress Controller front end for all hosts that match the subdomain (`*.example.test`). |
| 38 | +
|
| 39 | +. Configure the wildcard policy. |
| 40 | +
|
| 41 | +. Create a private key, certificate signing request (CSR), and certificate for the |
| 42 | +edge secured route. |
| 43 | ++ |
| 44 | +The instructions on how to do this are specific to your certificate authority and provider. The following example is a simple self-signed certificate for a domain named `*.example.test`: |
| 45 | ++ |
| 46 | +---- |
| 47 | +# sudo openssl genrsa -out example-test.key 2048 |
| 48 | +# |
| 49 | +# sudo openssl req -new -key example-test.key -out example-test.csr \ |
| 50 | + -subj "/C=US/ST=CA/L=Mountain View/O=OS3/OU=Eng/CN=*.example.test" |
| 51 | +# |
| 52 | +# sudo openssl x509 -req -days 366 -in example-test.csr \ |
| 53 | + -signkey example-test.key -out example-test.crt |
| 54 | +---- |
| 55 | +
|
| 56 | +. Generate a wildcard route using the certificate and key: |
| 57 | ++ |
| 58 | +---- |
| 59 | +$ cat > route.yaml <<REOF |
| 60 | +apiVersion: v1 |
| 61 | +kind: Route |
| 62 | +metadata: |
| 63 | + name: my-service |
| 64 | +spec: |
| 65 | + host: www.example.test |
| 66 | + wildcardPolicy: Subdomain |
| 67 | + to: |
| 68 | + kind: Service |
| 69 | + name: my-service |
| 70 | + tls: |
| 71 | + termination: edge |
| 72 | + key: "$(perl -pe 's/\n/\\n/' example-test.key)" |
| 73 | + certificate: "$(perl -pe 's/\n/\\n/' example-test.cert)" |
| 74 | +REOF |
| 75 | +$ oc create -f route.yaml |
| 76 | +---- |
| 77 | ++ |
| 78 | +Ensure your DNS entry for `*.example.test` points to your Ingress Controller instances and the route to your domain is available. |
| 79 | ++ |
| 80 | +This example uses `curl` with a local resolver to simulate the DNS lookup: |
| 81 | ++ |
| 82 | +---- |
| 83 | +# routerip="4.1.1.1" # replace with IP address of one of your router instances. |
| 84 | +# curl -k --resolve www.example.test:443:$routerip https://www.example.test/ |
| 85 | +# curl -k --resolve abc.example.test:443:$routerip https://abc.example.test/ |
| 86 | +# curl -k --resolve anyname.example.test:443:$routerip https://anyname.example.test/ |
| 87 | +---- |
| 88 | +
|
| 89 | +For Ingress Controllers that allow wildcard routes, configure the wildcard policy, there are some caveats to the ownership of a subdomain associated with a wildcard route. |
| 90 | +
|
| 91 | +Prior to wildcard routes, ownership was based on the claims made for a host name with the namespace with the oldest route winning against any other claimants. |
| 92 | +For example, route `r1` in namespace `ns1` with a claim for `one.example.test` |
| 93 | +would win over another route `r2` in namespace `ns2` for the same host name |
| 94 | +`one.example.test` if route `r1` was older than route `r2`. |
| 95 | +
|
| 96 | +In addition, routes in other namespaces were allowed to claim non-overlapping |
| 97 | +hostnames. For example, route `rone` in namespace `ns1` could claim |
| 98 | +`www.example.test` and another route `rtwo` in namespace `d2` could claim |
| 99 | +`c3po.example.test`. |
| 100 | +
|
| 101 | +This is still the case if there are _no_ wildcard routes claiming that same |
| 102 | +subdomain, such as `example.test` in the previous example. |
| 103 | +
|
| 104 | +However, a wildcard route needs to claim all of the host names within a |
| 105 | +subdomain, host names of the form `\*.example.test`. A wildcard route's claim |
| 106 | +is allowed or denied based on whether or not the oldest route for that subdomain |
| 107 | +(`example.test`) is in the same namespace as the wildcard route. The oldest |
| 108 | +route can be either a regular route or a wildcard route. |
| 109 | +
|
| 110 | +For example, if there is already a route `eldest` that exists in the `ns1` |
| 111 | +namespace that claimed a host named `owner.example.test` and, if at a later |
| 112 | +point in time, a new wildcard route `wildthing` requesting for routes in that |
| 113 | +subdomain (`example.test`) is added, the claim by the wildcard route will only |
| 114 | +be allowed if it is the same namespace (`ns1`) as the owning route. |
| 115 | +
|
| 116 | +The following examples illustrate various scenarios in which claims for wildcard |
| 117 | +routes will succeed or fail. |
| 118 | +
|
| 119 | +In the following example, a Ingress Controller that allows wildcard routes will allow non-overlapping claims for hosts in the subdomain `example.test` as long as a |
| 120 | +wildcard route has not claimed a subdomain. |
| 121 | +
|
| 122 | +---- |
| 123 | +$ oc project ns1 |
| 124 | +$ oc expose service myservice --hostname=owner.example.test |
| 125 | +$ oc expose service myservice --hostname=aname.example.test |
| 126 | +$ oc expose service myservice --hostname=bname.example.test |
| 127 | +
|
| 128 | +$ oc project ns2 |
| 129 | +$ oc expose service anotherservice --hostname=second.example.test |
| 130 | +$ oc expose service anotherservice --hostname=cname.example.test |
| 131 | +
|
| 132 | +$ oc project otherns |
| 133 | +$ oc expose service thirdservice --hostname=emmy.example.test |
| 134 | +$ oc expose service thirdservice --hostname=webby.example.test |
| 135 | +---- |
| 136 | +
|
| 137 | +In the following example, a Ingress Controller that allows wildcard routes will not allow the claim for `owner.example.test` or `aname.example.test` to succeed since the owning namespace is `ns1`. |
| 138 | +
|
| 139 | +---- |
| 140 | +$ oc project ns1 |
| 141 | +$ oc expose service myservice --hostname=owner.example.test |
| 142 | +$ oc expose service myservice --hostname=aname.example.test |
| 143 | +
|
| 144 | +$ oc project ns2 |
| 145 | +$ oc expose service secondservice --hostname=bname.example.test |
| 146 | +$ oc expose service secondservice --hostname=cname.example.test |
| 147 | +
|
| 148 | +$ # Router will not allow this claim with a different path name `/p1` as |
| 149 | +$ # namespace `ns1` has an older route claiming host `aname.example.test`. |
| 150 | +$ oc expose service secondservice --hostname=aname.example.test --path="/p1" |
| 151 | +
|
| 152 | +$ # Router will not allow this claim as namespace `ns1` has an older route |
| 153 | +$ # claiming host name `owner.example.test`. |
| 154 | +$ oc expose service secondservice --hostname=owner.example.test |
| 155 | +
|
| 156 | +$ oc project otherns |
| 157 | +
|
| 158 | +$ # Router will not allow this claim as namespace `ns1` has an older route |
| 159 | +$ # claiming host name `aname.example.test`. |
| 160 | +$ oc expose service thirdservice --hostname=aname.example.test |
| 161 | +---- |
| 162 | +
|
| 163 | +In the following example, a Ingress Controller that allows wildcard routes will allow the claim for `\*.example.test` to succeed since the owning namespace is `ns1` and the wildcard route belongs to that same namespace. |
| 164 | +
|
| 165 | +---- |
| 166 | +$ oc project ns1 |
| 167 | +$ oc expose service myservice --hostname=owner.example.test |
| 168 | +
|
| 169 | +$ # Reusing the route.yaml from the previous example. |
| 170 | +$ # spec: |
| 171 | +$ # host: www.example.test |
| 172 | +$ # wildcardPolicy: Subdomain |
| 173 | +
|
| 174 | +$ oc create -f route.yaml # router will allow this claim. |
| 175 | +---- |
| 176 | +
|
| 177 | +In the following example, a Ingress Controller that allows wildcard routes will not allow the claim for \*.example.test` to succeed since the owning namespace is `ns1` and the wildcard route belongs to another namespace `cyclone`. |
| 178 | +
|
| 179 | +---- |
| 180 | +$ oc project ns1 |
| 181 | +$ oc expose service myservice --hostname=owner.example.test |
| 182 | +
|
| 183 | +$ # Switch to a different namespace/project. |
| 184 | +$ oc project cyclone |
| 185 | +
|
| 186 | +$ # Reusing the route.yaml from a prior example. |
| 187 | +$ # spec: |
| 188 | +$ # host: www.example.test |
| 189 | +$ # wildcardPolicy: Subdomain |
| 190 | +
|
| 191 | +$ oc create -f route.yaml # router will deny (_NOT_ allow) this claim. |
| 192 | +---- |
| 193 | +
|
| 194 | +Similarly, once a namespace with a wildcard route claims a subdomain, only |
| 195 | +routes within that namespace can claim any hosts in that same subdomain. |
| 196 | +
|
| 197 | +In the following example, once a route in namespace `ns1` with a wildcard route |
| 198 | +claims subdomain `example.test`, only routes in the namespace `ns1` are allowed |
| 199 | +to claim any hosts in that same subdomain. |
| 200 | +
|
| 201 | +---- |
| 202 | +$ oc project ns1 |
| 203 | +$ oc expose service myservice --hostname=owner.example.test |
| 204 | +
|
| 205 | +$ oc project otherns |
| 206 | +
|
| 207 | +$ # namespace `otherns` is allowed to claim for other.example.test |
| 208 | +$ oc expose service otherservice --hostname=other.example.test |
| 209 | +
|
| 210 | +$ oc project ns1 |
| 211 | +
|
| 212 | +$ # Reusing the route.yaml from the previous example. |
| 213 | +$ # spec: |
| 214 | +$ # host: www.example.test |
| 215 | +$ # wildcardPolicy: Subdomain |
| 216 | +
|
| 217 | +$ oc create -f route.yaml # Router will allow this claim. |
| 218 | +
|
| 219 | +$ # In addition, route in namespace otherns will lose its claim to host |
| 220 | +$ # `other.example.test` due to the wildcard route claiming the subdomain. |
| 221 | +
|
| 222 | +$ # namespace `ns1` is allowed to claim for deux.example.test |
| 223 | +$ oc expose service mysecondservice --hostname=deux.example.test |
| 224 | +
|
| 225 | +$ # namespace `ns1` is allowed to claim for deux.example.test with path /p1 |
| 226 | +$ oc expose service mythirdservice --hostname=deux.example.test --path="/p1" |
| 227 | +
|
| 228 | +$ oc project otherns |
| 229 | +
|
| 230 | +$ # namespace `otherns` is not allowed to claim for deux.example.test |
| 231 | +$ # with a different path '/otherpath' |
| 232 | +$ oc expose service otherservice --hostname=deux.example.test --path="/otherpath" |
| 233 | +
|
| 234 | +$ # namespace `otherns` is not allowed to claim for owner.example.test |
| 235 | +$ oc expose service yetanotherservice --hostname=owner.example.test |
| 236 | +
|
| 237 | +$ # namespace `otherns` is not allowed to claim for unclaimed.example.test |
| 238 | +$ oc expose service yetanotherservice --hostname=unclaimed.example.test |
| 239 | +---- |
| 240 | +
|
| 241 | +In the following example, different scenarios are shown in which the owner routes |
| 242 | +are deleted and ownership is passed within and across namespaces. While a route |
| 243 | +claiming host `eldest.example.test` in the namespace `ns1` exists, wildcard |
| 244 | +routes in that namespace can claim subdomain `example.test`. When the route for |
| 245 | +host `eldest.example.test` is deleted, the next oldest route |
| 246 | +`senior.example.test` would become the oldest route and would not affect any |
| 247 | +other routes. Once the route for host `senior.example.test` is deleted, the next |
| 248 | +oldest route `junior.example.test` becomes the oldest route and block the |
| 249 | +wildcard route claimant. |
| 250 | +
|
| 251 | +---- |
| 252 | +$ oc project ns1 |
| 253 | +$ oc expose service myservice --hostname=eldest.example.test |
| 254 | +$ oc expose service seniorservice --hostname=senior.example.test |
| 255 | +
|
| 256 | +$ oc project otherns |
| 257 | +
|
| 258 | +$ # namespace `otherns` is allowed to claim for other.example.test |
| 259 | +$ oc expose service juniorservice --hostname=junior.example.test |
| 260 | +
|
| 261 | +$ oc project ns1 |
| 262 | +
|
| 263 | +$ # Reusing the route.yaml from the previous example. |
| 264 | +$ # spec: |
| 265 | +$ # host: www.example.test |
| 266 | +$ # wildcardPolicy: Subdomain |
| 267 | +
|
| 268 | +$ oc create -f route.yaml # Router will allow this claim. |
| 269 | +
|
| 270 | +$ # In addition, route in namespace otherns will lose its claim to host |
| 271 | +$ # `junior.example.test` due to the wildcard route claiming the subdomain. |
| 272 | +
|
| 273 | +$ # namespace `ns1` is allowed to claim for dos.example.test |
| 274 | +$ oc expose service mysecondservice --hostname=dos.example.test |
| 275 | +
|
| 276 | +$ # Delete route for host `eldest.example.test`, the next oldest route is |
| 277 | +$ # the one claiming `senior.example.test`, so route claims are unaffacted. |
| 278 | +$ oc delete route myservice |
| 279 | +
|
| 280 | +$ # Delete route for host `senior.example.test`, the next oldest route is |
| 281 | +$ # the one claiming `junior.example.test` in another namespace, so claims |
| 282 | +$ # for a wildcard route would be affected. The route for the host |
| 283 | +$ # `dos.example.test` would be unaffected as there are no other wildcard |
| 284 | +$ # claimants blocking it. |
| 285 | +$ oc delete route seniorservice |
| 286 | +---- |
| 287 | +//// |
0 commit comments