Refractoring and some documentation performed.

This commit is contained in:
savagebidoof
2023-05-01 01:06:33 +02:00
parent b48837e5c0
commit 03a604c91e
146 changed files with 1184 additions and 757 deletions

View File

@ -0,0 +1,11 @@
##### https://github.com/istio/istio/tree/master/samples/helloworld
https://istio.io/latest/blog/2017/0.1-canary/
# Note, VirtualService match rule order MATTERS
Leave the "default/wildcard" rule at the bottom
# Continues from
- 03-hello_world_1_service_1_deployment

View File

@ -0,0 +1,102 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v0
labels:
app: helloworld
version: v0
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v0
template:
metadata:
labels:
app: helloworld
version: v0
spec:
containers:
- name: helloworld
image: containous/whoami
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
labels:
app: helloworld
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
labels:
app: helloworld
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v2
template:
metadata:
labels:
app: helloworld
version: v2
spec:
containers:
- name: helloworld
image: httpd
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---

View File

@ -0,0 +1,85 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: firefox
match:
- uri:
exact: /helloworld
headers:
user-agent:
regex: '.*Firefox.*'
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
subset: nginx
rewrite:
uri: "/"
- name: curl
match:
- headers:
user-agent:
regex: '.*curl.*'
uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
subset: apache
rewrite:
uri: "/"
- name: default
match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
subset: default
rewrite:
uri: "/"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local # Destination that will "interject"
spec:
host: helloworld.default.svc.cluster.local # Full destination service, lil better for consistency
subsets:
- name: default
labels:
version: v0
- name: nginx
labels:
version: v1
- name: apache
labels:
version: v2

View File

@ -0,0 +1,7 @@
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPDirectResponse
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPBody
# Continues from
- 01-hello_world_1_service_1_deployment

View File

@ -0,0 +1,40 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,46 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: helloworld
match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
- name: default
directResponse:
status: 404
body:
string: "Page Not Found"
headers:
response:
set:
content-type: "text/plain"

View File

@ -0,0 +1,52 @@
# Continues from
- 01-hello_world_1_service_1_deployment
# There were no changes respective to that version
Through rewriting the URI we can point to the root directory from nginx.
```yaml
rewrite:
uri: "/"
```
## The idea is that this rewrite is handled "internally" by Istio, not by the Client that started the request
## Practical usages:
If we refactor our application, and for example we previously where hosting an API to the URL `/apiV1` and now it's being hosted in `/api/V1`, we can do the following rule:
```yaml
- match:
- uri:
exact: /apiV1
route:
- destination:
host: mynewapi # the service destination/target
port:
number: 80 # whatever port it is
rewrite:
uri: "/api/V1"
```
Or if we "upgraded" the API, and the new API (v2) is retro-compatible with the old API (v1), we could do the following to force all the usages from the old API to be handled by the newer version:
```yaml
- match:
- uri:
exact: /api/V1
route:
- destination:
host: mynewapi # the service destination/target
port:
number: 80 # whatever port it is
rewrite:
uri: "/api/V2"
```

View File

@ -0,0 +1,40 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,36 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,61 @@
# Continues from
- 01-hello_world_1_service_1_deployment
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect
## The idea is that this rewrite is handled "externally" by the client, not by Istio.
## Practical examples
### HTTP to HTTPS redirect.
The following Virtual Service configuration will redirect all the incoming traffic from the gateway `my-gateway` that uses the http protocol, to the https protocol.
In this example, it would forward all the `http` traffic without taking into account which port is used.
```
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: to-https-vs
spec:
hosts:
- "*"
gateways:
- my-gateway
http:
- match:
- name: to_https
match:
scheme: http
redirect:
scheme: https
```
### Migrated from a domain
The following will update the requests coming "to" the domain `old.domain.com` and rewrite the URL to use the "new" `new.domain.com`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: update-domain-vs
spec:
hosts:
- "old.domain.com"
gateways:
- helloworld-gateway
http:
- name: forward-to-new-domain
redirect:
authority: "new.domain.com"
```

View File

@ -0,0 +1,40 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,58 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 80
rewrite:
uri: "/"
- name: to_https
match:
- uri:
exact: /https
scheme: http
redirect:
scheme: "https"
- name: wikipedia
match:
- uri:
exact: "/wiki"
redirect:
uri: "/"
scheme: "https"
authority: "en.wikipedia.org"
- name: wikipedia_search
match:
- uri:
prefix: "/wiki/"
redirect:
scheme: "https"
authority: "en.wikipedia.org"

View File

@ -0,0 +1,204 @@
# Description
This example uses a resource `ServiceEntry` to "integrate" external resources into our `Istio Service Mesh`.
It also explores the different behaviors between specifying the destination URL on the headers or not.
The following page has been used for testing purposes:
- info.cern.ch
> **Quick disclaimer**:\
> I have no relation with that page.
# Configuration
## ServiceEntry
This `ServiceEntry` resource, defines as a destination the URL `info.cern.ch`.
Note that location is set to `MESH_EXTERNAL` and that the resolution is set to `DNS`, this means that the resource is external to ou `Istio Service Mesh`, and the URL will be resolved through `DNS`
Bear in mind that when Istio is communicating with resources externals to the mesh, `mTLS` is disabled.
Also, policy enforcement is performed in the client side instead of the server side.
> **Note:**/
> For more information regarding the `resolution` field or the `location` field, refer to the following official Istio documentations:
> [ServiceEntry.Location](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location)
> [ServiceEntry.Resolution](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Resolution)
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-cern-service
spec:
hosts:
- info.cern.ch
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
```
## Gateway
Listens for `HTTP` traffic at the port `80` without limiting to any host.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
There has been configured 2 paths:
- "/external"
- "/external-noh"
Both routes will forward the request towards the destination URL `info.cern.ch`.
Highlight that the destination is `info.cern.ch`, which is the same as the contents set on the field `host` from the [ServiceEntry resource configured above](#serviceentry).
The difference between `/external` and `/external-noh` is that the first path will contain a header named `HOST`, with the contents set to `info.cern.ch`, it being the URL from the external service.
On the [Walkthrough](#walkthrough) section we will observe the different behaviors of these paths, being the only difference the header attributed.
Also, we have set a timeout of 3 seconds towards the external services.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
headers:
request:
set:
HOST: "info.cern.ch"
- name: https-external-service-without-headers
timeout: 3s
match:
- uri:
exact: "/external-noh"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
serviceentry.networking.istio.io/external-cern-service created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```shell
$ kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### /external
We can visualize the page contents without issues, nothing to highlight.
```shell
curl 192.168.1.50/external
```
```text
<html><head></head><body><header>
<title>http://info.cern.ch</title>
</header>
<h1>http://info.cern.ch - home of the first website</h1>
<p>From here you can:</p>
<ul>
<li><a href="http://info.cern.ch/hypertext/WWW/TheProject.html">Browse the first website</a></li>
<li><a href="http://line-mode.cern.ch/www/hypertext/WWW/TheProject.html">Browse the first website using the line-mode browser simulator</a></li>
<li><a href="http://home.web.cern.ch/topics/birth-web">Learn about the birth of the web</a></li>
<li><a href="http://home.web.cern.ch/about">Learn about CERN, the physics laboratory where the web was born</a></li>
</ul>
</body></html>
```
### /external-noh
We don't receive any output.
This could be due, even if we resolve the destination IP for the URL `info.cern.ch`, the destination might have a Reverse Proxy or any other ingress resource that could condition handling this request.
Due to the `HOST` field not being modified after we set the request, it might not be able to pass the filtering set, weather it is security wise, for example, requiring such field to allow the request; or it being a routing condition, which due not having this field specified, it's not able to route the request towards the destination desired.
```shell
curl 192.168.1.50/external-noh
```
```text
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
serviceentry.networking.istio.io "external-cern-service" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of interest:
- https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location

View File

@ -0,0 +1,13 @@
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-cern-service
spec:
hosts:
- info.cern.ch
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL

View File

@ -0,0 +1,54 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"
headers:
request:
set:
HOST: "info.cern.ch"
- name: https-external-service-without-headers
timeout: 3s
match:
- uri:
exact: "/external-noh"
route:
- destination:
host: info.cern.ch
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,7 @@
# Continues from
- 01-hello_world_1_service_1_deployment
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Delay

View File

@ -0,0 +1,40 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,41 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
fault:
delay:
percentage:
value: 90
fixedDelay: 10s

View File

@ -0,0 +1,11 @@
# Continues from
- 05a-FaultInjection-delay
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Abort
curl 192.168.1.50/helloworld -I

View File

@ -0,0 +1,40 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,41 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
fault:
abort:
percentage:
value: 90
httpStatus: 503

View File

@ -0,0 +1,188 @@
# Description
This example configures an `ServiceEntry` service pointing to a URL external to our `Istio Service Mesh`.
The main difference with the previous example, is that on this example the resource selected requires `HTTPS` communication.
The page used as a destination is my own [GitHub page](https://github.com/).
# Based on
- [05-hello_world_1_Service_Entry](../05-hello_world_1_Service_Entry)
# Configuration
## ServiceEntry
This `ServiceEntry` resource, defines as a destination the URL `github.com`.
Note that location is set to `MESH_EXTERNAL` and that the resolution is set to `DNS`, this means that the resource is external to ou `Istio Service Mesh`, and the URL will be resolved through `DNS`
This resource listens for the port `8443`, and will connect to its destination with the port `443`, intending to handle `HTTPS` protocol traffic.
Bear in mind that when Istio is communicating with resources externals to the mesh, `mTLS` is disabled.
Also, policy enforcement is performed in the client side instead of the server side.
> **Note:**/
> For more information regarding the `resolution` field or the `location` field, refer to the following official Istio documentations:
> [ServiceEntry.Location](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location)
> [ServiceEntry.Resolution](https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Resolution)
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-github-service
spec:
hosts:
- github.com
ports:
- number: 8443
name: https
protocol: HTTPS
targetPort: 443
resolution: DNS
location: MESH_EXTERNAL
```
## Gateway
Listens for `HTTP` traffic at the port `80` without limiting to any host.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## VirtualService
The path `/external` will forward the request towards the destination URL `github.com`, and path `/OriolFilter`.
Highlight that the destination is `github.com`, which is the same as the contents set on the field `host` from the [ServiceEntry resource configured above](#serviceentry).
As seen [in the previous example, where the host that didn't have the `HOST` header wasn't able to receive a response by the destination](../05-hello_world_1_Service_Entry/#external-noh), we configured the `HOST` header to match the URL from the external service.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: "github.com"
port:
number: 8443
rewrite:
uri: "/OriolFilter/"
headers:
request:
set:
HOST: "github.com"
```
## DestinationRule
As seen in the example [02-Traffic_management/09-HTTPS-backend](../09-HTTPS-backend), where we configure Istio to use an `HTTPS` backend, the same configuration is applied on this case (yes, I am aware that a `ServiceEntry` is also a backend).
For such, we deploy a `DestinationRule` setting to expect to terminate the TLS traffic, for the traffic with resource destination `github.com`, and port `8443`, which matches the settings set in our [ServiceEntry](#serviceentry) deployed.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: github.com
namespace: default
spec:
host: github.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
serviceentry.networking.istio.io/external-github-service created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/github.com created
```
## Test the service
### Get LB IP
```shell
$ kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### /external
We can visualize the page contents without issues, nothing to highlight.
```shell
curl 192.168.1.50/external
```
```text
...
I mean, we can use curl but it's certainly quite an ugly output, it works tho.
...
```
As performing the test through `curl` is ugly, here is a screenshot of the setting working correctly.
![github-screenshot.png](src/github-screenshot.png)
## Cleanup
```shell
kubectl delete -f ./
```
```text
serviceentry.networking.istio.io "external-github-service" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "github.com" deleted
```
# Links of interest:
- https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry-Location

View File

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-github-service
spec:
hosts:
- github.com
ports:
- number: 8443
name: https
protocol: HTTPS
targetPort: 443
resolution: DNS
location: MESH_EXTERNAL

View File

@ -0,0 +1,55 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-external-service
timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: "github.com"
port:
number: 8443
rewrite:
uri: "/OriolFilter/"
headers:
request:
set:
HOST: "github.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: github.com
namespace: default
spec:
host: github.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -0,0 +1,181 @@
---
gitea: none
include_toc: true
---
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
## Description
Nowadays, by default, Istio will have mTLS automatically enabled, allowing the Istio Sidecars to **automatically** negotiate the TLS traffic between them.encrypted.
More information about that topic in the [following documentation](https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#auto-mutual-tls).
To avoid this behavior, the pod requires to not have an Istio Sidecar set to that pod, for that reason on this example we set up 2 deployments, 1 with a sidecar, and a second without a sidecar.
From the Kiali dashboard we will review the mTLS label displayed
> **Note:**\
> If the PeerAuthentication is deployed in the `istio-system` namespace, it will affect all the namespaces in the cluster.
# Changelog
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
````
```txt
peerauthentication.security.istio.io/default-mtls created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
deployment.apps/byeworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Install telemetry addons
[Source Folder](https://github.com/istio/istio/tree/master/samples/addons)
```shell
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/addons/grafana.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/addons/kiali.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/addons/prometheus.yaml
```
## Wait for deployments to be ready
```shell
kubectl get pods -A -w
```
## Kiali
## Access the Kiali dashboard
The following command will tunnel from this device, towards the Kiali dashboard running, automatically accessing through the default browser.
```shell
istioctl dashboard kiali
```
## Display services menu
![Kiali menu, displaying 3 services. helloworld, byeworld and kubernetes](../src/06-kiali-services.png)
> **Highlight:**\
> On the column located at the right, we can notice a note saying `Missing Sidecar`
> **Note:**\
> If there are no resources being displayed, at the top left, select the corresponding namespaces where the resources are located.
> On my case, it's the `default` namespace.
### Byeworld
On the service `byeworld` (reminder that it's pods had the Istio sidecar injection disabled), it displays the message `No mTLS`, meaning that mTLS (Mutual TLS between Istio sidecards) is not available.
![byeworld displays the message `No mTLS`](../src/06-kiali-services-byeworld.png)
### Helloworld
On the service `helloworld`, it displays the message `mTLS`
![helloworld displays the message `mTLS`](../src/06-kiali-services-helloworld.png)
## Test resources
### Curl / LB requests / requests from external traffic
#### Get LB IP
```shell
kubectl get svc istio-ingressgateway -n istio-system
```
```txt
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
#### helloworld
The service works as intended as we can reach the `helloworld` service.
```shell
curl 192.168.1.50/helloworld -s | grep "<title>.*</title>"
```
```txt
<title>Welcome to nginx!</title>
```
#### byeworld
The `byeworld` service also seems to work, even tho the deployment has no sidecar enabled, and for such the `PeerAuthentication` rule is not being maintained. \
Yet, as there is no sidecar, this rule is not applied, and for such the traffic is allowed towards the service and pod.
```shell
curl 192.168.1.50/byeworld -s | grep "<title>.*</title>"
```
```txt
<title>Welcome to nginx!</title>
```
### Connectivity between the deployments
#### helloworld towards byeworld
It works.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.default.svc.cluster.local:9090 | grep "<title>.*</title>"
```
```txt
<title>Welcome to nginx!</title>
```
#### byeworld towards helloworld
It fails.
Currently, the rule from `PeerAuthentication` that requires the traffic to use mTLS, is currently being applied by the Istio sidecar from the `helloworld` pod.
As `byeworld` pods don't have the Istio sidecar enabled, the mTLS traffic is not being managed, and for such, it fails to obvey the rule set by the `PeerAuthentication` configuration set, resulted on this issue.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080
```
```txt
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56
```
## Delete the PeerAuthentication configuration set
```shell
kubectl delete peerauthentications.security.istio.io default-mtls
```
### connectivity between byeworld towards helloworld
As the rule is no longer being set, and for such not being applied, the traffic from `byeworld` is able to reach the service `helloworld` without having the need to using mTLS.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080 | grep "<title>.*</title>"
```
```txt
<title>Welcome to nginx!</title>
```
# Links of interest
- https://istio.io/latest/docs/concepts/security/#authentication-policies
- https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication
- https://istio.io/latest/docs/tasks/security/authentication/mtls-migration/

View File

@ -0,0 +1,8 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: default
spec:
mtls:
mode: STRICT

View File

@ -0,0 +1,40 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,41 @@
apiVersion: v1
kind: Service
metadata:
name: byeworld
labels:
app: byeworld
service: byeworld
spec:
ports:
- port: 9090
name: http
targetPort: 80
selector:
app: byeworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: byeworld-nginx
labels:
app: byeworld
spec:
replicas: 1
selector:
matchLabels:
app: byeworld
template:
metadata:
labels:
app: byeworld
sidecar.istio.io/inject: "false"
spec:
containers:
- name: byeworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,45 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
- match:
- uri:
exact: /byeworld
route:
- destination:
host: byeworld.default.svc.cluster.local
port:
number: 9090
rewrite:
uri: "/"

View File

@ -0,0 +1,196 @@
---
gitea: none
include_toc: true
---
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
# Description
On this example, we generate a TLS configuration, and afterwards we attach such to a `Gateway` resource listening to the port `443` for `HTTPS` traffic.
> **Note:** \
> This was based on the information from the following Istio documentation:
> - [Secure Gateways](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/)
# Configuration applied
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
```
- Gateway is listening to the port `443` and `HTTPS` protocol.
- Allows for all hosts.
- The TLS configuration is set to simple, and the credentials (the object that contains the certificates/TLS configuration) is set to `my-tls-cert-secret`.
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
[//]: # (```shell)
[//]: # (curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net/helloworld)
[//]: # (```)
```shell
curl --insecure https://192.168.1.50/helloworld -I
```
```text
HTTP/2 200
server: istio-envoy
date: Sun, 23 Apr 2023 05:06:47 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 96
```
## Cleanup
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
rm -rv certfolder/
```
```text
removed 'certfolder/istio.cert.key'
removed 'certfolder/istio.cert.crt'
removed directory 'certfolder/'
```
# Troubleshooting.
## curl: (7) Failed to connect to 192.168.1.51 port 443 after 2 ms: Couldn't connect to server
- Ensure that the gateway is listening to the right port, in this case, the port 443.
- Refer to the troubleshooting documentation, specifically the `Logs>Ingress`. \
Check if it displays any log activity that could facilitate the troubleshooting / investigation.
## curl: (35) Recv failure: Connection reset by peer
- Refer to the troubleshooting documentation, specifically the `Logs>Ingress`. \
Check if it displays any log activity that could facilitate the troubleshooting / investigation.
## 404
Ensure the URL used to thest the connectivity, matches the host and path rules applied, both in the `Gateway` and `VirtualService` resources.
# Links of Interest
- https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,38 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,181 @@
---
gitea: none
include_toc: true
---
# Based on
- [07-HTTPS-Gateway-Simple-TLS](../07-HTTPS-Gateway-Simple-TLS)
# Description
The previous example was modified to limit and specify the minimum TLS version.
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_3
```
Gateway has been modified to limit the minimum TLS version to v1.3.
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
[//]: # (```shell)
[//]: # (curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net/helloworld)
[//]: # (```)
### Curl TLS 1.2
It fails as intended.
As the TLS v1.2 is smaller than the TLS v1.3 set as a minimal TLS version accepted, it doesn't allow us to proceed with the request.
```shell
curl --insecure https://192.168.1.50/helloworld -I --tlsv1.2 --tls-max 1.2
```
```text
curl: (35) OpenSSL/3.0.8: error:0A00042E:SSL routines::tlsv1 alert protocol version
```
### Curl TLS 1.3
It works as intended due respecting the minimal TLS version set.
```shell
curl --insecure https://192.168.1.50/helloworld -I --tlsv1.3 --tls-max 1.3
```
```text
HTTP/2 200
server: istio-envoy
date: Sun, 23 Apr 2023 05:43:18 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 13
```
## Cleanup
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
rm -rv certfolder/
```
```text
removed 'certfolder/istio.cert.key'
removed 'certfolder/istio.cert.crt'
removed directory 'certfolder/'
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://discuss.istio.io/t/minimum-tls-version/5541/3

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,39 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_3
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,178 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified to limit and specify the maximum TLS version.
# Changelog
## Gateway
Gateway has been modified to limit the maximum TLS version to v1.2.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
maxProtocolVersion: TLSV1_2
```
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Curl TLS 1.2
It fails as intended.
As the TLS v1.2 is smaller than the TLS v1.3 set as a minimal TLS version accepted, it doesn't allow us to proceed with the request.
```shell
curl --insecure https://192.168.1.50/helloworld -I --tlsv1.2 --tls-max 1.2
```
```text
HTTP/2 200
server: istio-envoy
date: Sun, 23 Apr 2023 05:48:04 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 7
```
### Curl TLS 1.3
It works as intended due respecting the minimal TLS version set.
```shell
curl --insecure https://192.168.1.50/helloworld -I --tlsv1.3 --tls-max 1.3
```
```text
curl: (35) OpenSSL/3.0.8: error:0A00042E:SSL routines::tlsv1 alert protocol version
```
## Cleanup
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
rm -rv certfolder/
```
```text
removed 'certfolder/istio.cert.key'
removed 'certfolder/istio.cert.crt'
removed directory 'certfolder/'
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol
- https://discuss.istio.io/t/minimum-tls-version/5541/3

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,39 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
maxProtocolVersion: TLSV1_2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,345 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
This example contains a backend that serves HTTPS traffic and can be accessed from both `HTTP` and `HTTPS` requests through the gateway resource.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway is configured to listen to the port `80` for `HTTP` traffic, and to the port `443` for `HTTPS` traffic.
The TLS configuration is set to `simple`, and the credentials (the object that contains the certificates/TLS configuration) is set to `my-tls-cert-secret`.
Any of the configured ports has limited the hosts.
```shell
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
mode: SIMPLE
```
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
## VirtualService
The rule that contains, will receive traffic from the port `443` and `80`.
This traffic will be directed towards destination of such is the service `helloworld.default.svc.cluster.local`, with port destination 8443.
This destination is the service that contains the `HTTPS` deployment, running over the port `8443`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-vs
match:
- port: 80
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## DestinationRule
This DestinationRule, will interject the traffic destined to the service `helloworld.default.svc.cluster.local` with port `8443`.
As mentioned in the [Virtual Service](#virtualservice) section, the destination is the `HTTPS` service.
By default, the call would be made with `HTTP` protocol, yet, as the destination is an `HTTPS` service, the request would result in the status code `400 Bad Request`, due sending HTTP traffic to an HTTPS service.
To avoid this, we need to specify that the destination handles HTTPS traffic.
By setting the `tls.mode` field with `simple`, it means that there will be an attempt to initialize a TLS handshake.
> **Note:**
> For more information about the TLS mode, refer to the [Istio official documentation from the DestinationRule object regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode).
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE
```
## Service
The service will forward incoming TCP traffic from the port `8443`, towards the deployment port `443`.
It's been specified the protocol expected to service, it being `HTTPS`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- name: https
port: 8443
targetPort: 443
protocol: TCP
appProtocol: HTTPS
selector:
app: helloworld
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentication
Due to the deployment having an `HTTPS`, and already initializing a TLS termination towards that service, we need to disable the **mTLS** tool for that specific service/deployment.
On the [Destination Rule](#destinationrule) section we set the `tls` to `simple`, meaning that the service is expecting to receive `HTTPS` traffic, if `mTLS` is enabled, it will perform the handshake with the `mTLS` service, instead of with the destination `HTTPS` service.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: default
spec:
mtls:
mode: DISABLE
```
> **Note**:\
> As this configuration is very board, and targets the whole namespace, I would strongly recommend referring to the following example [06-Internal-Authentication/02-target-service-accounts](../../06-AuthorizationPolicy/02-target-service-accounts), which shows how to target service accounts set to resources, limiting the scope of this rule set.
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
peerauthentication.security.istio.io/default-mtls created
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld created
```
## Test the service
### Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### curl HTTP gateway
Well, it works as expected.
```shell
curl --insecure 192.168.1.50 -I
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Tue, 25 Apr 2023 04:41:19 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
x-envoy-upstream-service-time: 28
```
### curl HTTPS gateway
Well, it works as expected.
```shell
curl --insecure https://192.168.1.50 -I
```
```text
HTTP/2 200
server: istio-envoy
date: Tue, 25 Apr 2023 04:42:07 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
x-envoy-upstream-service-time: 13
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
peerauthentication.security.istio.io "default-mtls" deleted
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#Gateway
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode

View File

@ -0,0 +1,8 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: default
spec:
mtls:
mode: DISABLE

View File

@ -0,0 +1,43 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,57 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: https-vs
match:
- port: 80
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE

View File

@ -0,0 +1,240 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified to set TCP forwarding towards the backend (HTTP and HTTPS backend).
The backend contains an HTTPS service, which is used to demonstrate how the TCP forwarding is working as intended (aka doesn't disturb HTTP traffic).
The same backend also contains the same service but running as HTTP, and for such has also been set in the gateway to display both working as intended.
Additionally, the backend used, has HTTP2 enable, which also will be used to confirm that it's working as intended.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway has been configured to listen both ports `80` and `443` through the TCP protocol, without any host specified.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp-1
protocol: TCP
hosts:
- "*"
- port:
number: 443
name: tcp-2
protocol: TCP
hosts:
- "*"
```
## Virtual service
Virtual service have 2 rules that perform the same behavior, on different ports.
The rules will receive the traffic and forward it to the destination service and port.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
tcp:
- match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- match:
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## Service
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentication
```yaml
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### curl HTTP
```shell
curl http://192.168.1.50 -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n'
```
```text
http_version: 1.1
status_code: 426
```
#### curl HTTPS
This already confirms that `HTTP2` is working as intended.
```shell
curl https://192.168.1.50 -ks -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http1.1
```
```text
http_version: 2
status_code: 200
```
#### Curl HTTP2
The previous example already displayed that `HTTP2` is working as intended.
This example is maintained due being explicitly to confirm the `HTTP2` feature.
```shell
curl https://192.168.1.50 -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http2 -sk -o=/dev/null
```
```text
http_version: 2
status_code: 200
```
#### Curl HTTP1.1
We can confirm that `HTTP1.1` also works over `TCP forwarding`.
```shell
curl https://192.168.1.50 -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' --http1.1 -sk -o=/dev/null
```
```text
http_version: 1.1
status_code: 200
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#Gateway

View File

@ -0,0 +1,46 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http-web
targetPort: 80
protocol: TCP
- port: 8443
name: https-web
targetPort: 443
protocol: TCP
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,45 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp-1
protocol: TCP
hosts:
- "*"
- port:
number: 443
name: tcp-2
protocol: TCP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
tcp:
- match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- match:
- port: 443
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443

View File

@ -0,0 +1,221 @@
---
gitea: none
include_toc: true
---
# Based on
- [10-TCP-FORWARDING](../10-TCP-FORWARDING)
# Description
The previous example was modified set TLS Forwarding for the HTTPS, meaning that the TLS will be terminated by the backend containing a service capable of such.
This requires a deployment with a service HTTPS (as it will need to handle the TLS termination ...).
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
The gateway was configured to listen the port `443` for `HTTPS` traffic protocol.
The tls was configured as `PASSTHROUGH`
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: PASSTHROUGH
```
## Virtual service
Virtual service expected to receive traffic with designation, the host `lb.net`.
The rule that contains, will receive traffic from the port `443`, with host destination `lb.net`.
The destination of such is the service `helloworld.default.svc.cluster.local`, with port destination 8443.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "lb.net"
gateways:
- helloworld-gateway
tls:
- match:
- port: 443
sniHosts: ["lb.net"]
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
```
## Service
The service will forward incoming TCP traffic from the port `8443`, towards the deployment port `443`.
It's been specified the protocol expected to service, it being `HTTPS`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- name: https
port: 8443
targetPort: 443
protocol: TCP
appProtocol: HTTPS
selector:
app: helloworld
```
## Deployment
Deployment listens to port 80 and 443.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test the service
### Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### curl HTTPS
Well, it just works.
The `--resolve` flag it's used to "fake" the traffic to match the filters we specified in the `Virtual Service`, specifically the `host` and `hostSNI` fields.
```shell
curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net
```
```text
<h2>Howdy</h2>
```
### curl HTTPS (HEAD)
Here we can spot the following sentence:
- `server: nginx/1.23.4`
This means that the TLS was handled by Nginx (verifying that the `TLS Passthrough` was performed correctly).
If it had been managed by Istio, it would say:
- `server: istio-envoy`
```shell
curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net --HEAD
```
```text
HTTP/2 200
server: nginx/1.23.4
date: Tue, 25 Apr 2023 02:49:33 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#Gateway
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode

View File

@ -0,0 +1,73 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- name: https
port: 8443
targetPort: 443
protocol: TCP
appProtocol: HTTPS
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: Always #Always
ports:
- containerPort: 80
- containerPort: 443
#---
#apiVersion: apps/v1
#kind: Deployment
#metadata:
# name: nginx
# labels:
# app: nginx
# version: v1
#spec:
# replicas: 1
# selector:
# matchLabels:
# app: nginx
# version: v1
# template:
# metadata:
# labels:
# app: nginx
# version: v1
# spec:
# # serviceAccountName: istio-helloworld
# containers:
# - name: nginx
# image: nginx
# resources:
# requests:
# cpu: "100m"
# imagePullPolicy: IfNotPresent
# ports:
# - containerPort: 80

View File

@ -0,0 +1,37 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- "lb.net"
gateways:
- helloworld-gateway
tls:
- match:
- port: 443
sniHosts: ["lb.net"]
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443

View File

@ -0,0 +1,218 @@
---
gitea: none
include_toc: true
---
# Based on
- [07-HTTPS-Gateway-Simple-TLS](../07-HTTPS-Gateway-Simple-TLS)
# Description
This example adds `HTTP` to `HTTPS` redirect at the port `80` of the gateway, which listens for HTTP traffic.
Also contains a listens for `HTTPS` traffic at the port 443, with a self-signed certificate. This will be used to ensure that the redirect is working correctly.
> **NOTE:**\
> This example is kept at minimal, without the need of containing a `Virtual Service`, a `Service` nor a `Deployment/Pod`.
# Configuration applied
## Gateway
The port `80` listens for any host, expecting `HTTP` traffic.\
As `tls.httpsRedirect` is set to `true`, the incoming traffic will be redirected to `HTTPS`, effectively enabling the `HTTP` to `HTTPS` redirect.
The port `443` is expecting traffic that use the `HTTPS` protocol, without being limited to specific hosts.\
The TLS configuration is set to simple, and the credentials (the object that contains the certificates/TLS configuration) is set to `my-tls-cert-secret`.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
```
> **Note:**\
> The credentials resource is created further bellow through the [Walkthrough](#walkthrough) steps.
> **Note:**\
> For more information regarding the TLS mode configuration, refer to the following [Istio documentation regarding the TLS mode field](https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSmode).
# Walkthrough
## Generate client and server certificate and key files
First step will be to generate the certificate and key files to be able to set them to the Gateway resource.
### Create a folder to store files.
Create the folder to contain the files that will be generated.
```shell
mkdir certfolder
```
### Create a certificate and a private key.
```shell
openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt
```
The files generated are the following:
```yaml
private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt
```
The information set to the certificate generated is the following:
```yaml
Organization-name: Internet of things
CN: lb.net
```
### Create a TLS secret
At this step we create the tls secret `my-tls-cert-secret` on the namespace `istio-system`.
```shell
kubectl create -n istio-system secret tls my-tls-cert-secret \
--key=certfolder/istio.cert.key \
--cert=certfolder/istio.cert.crt
```
```text
secret/my-tls-cert-secret created
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
> **Note:**\
> It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the `istio-system`, but it will vary based on the environment.
## Deploy resources
```shell
kubectl apply -f ./
```
```text
gateway.networking.istio.io/helloworld-gateway created
```
## Test the service
### Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### Curl --HEAD
We receive the status message `301 Moved Permanently`.
This points that we are being redirected somewhere. By default, `curl` doesn't follow the redirects.
To confirm the redirect is being performed towards the `HTTPS` service, we allow `curl` to follow redirects.
```shell
curl http://192.168.1.50 -I
```
```text
HTTP/1.1 301 Moved Permanently
location: https://192.168.1.50/
date: Tue, 25 Apr 2023 23:59:34 GMT
server: istio-envoy
transfer-encoding: chunked
```
### Curl --HEAD follow redirects
Allowing `curl` to follow redirects, we notice the following output:
- First we receive the same message from before, as we connected to the same service.
- Afterwards we are met with a status code `404`, which is expected as we don't have any service configured behind this gateway.
> **NOTE:**\
> Due using a self-signed certificate, had to allow accessing "insecure" `HTTPS` destinations.
```shell
curl http://192.168.1.50 -I -L -k
```
```text
HTTP/1.1 301 Moved Permanently
location: https://192.168.1.50/
date: Wed, 26 Apr 2023 00:05:24 GMT
server: istio-envoy
transfer-encoding: chunked
HTTP/2 404
date: Wed, 26 Apr 2023 00:05:24 GMT
server: istio-envoy
```
## Cleanup
```shell
kubectl delete -n istio-system secret my-tls-cert-secret
```
```text
secret "my-tls-cert-secret" deleted
```
```shell
kubectl delete -f ./
```
```text
gateway.networking.istio.io "helloworld-gateway" deleted
```
```shell
rm -rv certfolder/
```
```text
removed 'certfolder/istio.cert.key'
removed 'certfolder/istio.cert.crt'
removed directory 'certfolder/'
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings

View File

@ -0,0 +1,25 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https-web
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret

View File

@ -0,0 +1,23 @@
# Examples
(almost) ALL NEEDS DOCUMENTATION / REVIEW
- 01-2_deployments_method
- 02-DirectResponse-HTTP-Body
- 03-HTTPRewrite
- 04-HTTPRedirect
- 05a-FaultInjection-delay
- 05b-FaultInjection-abort
- 06-mTLS (would need some documentation review, mainly go over the differences respective to the template/prior configuration used)
- 07-HTTPS-Gateway-Simple-TLS <- Doesn't respect the changelog format.
- 08a-HTTPS-min-TLS-version
- 08b-HTTPS-max-TLS-version
- 09-HTTPS-backend
- 10-TCP-FORWARDING
- 11-TLS-PASSTHROUGH
- 12-HTTP-to-HTTPS-traffic-redirect -> Documented.
This will need some reorganization.

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,172 @@
# Continues from
- 01-hello_world_1_service_1_deployment
# TO TRAFFIC PATH DIAGRAM
`etc -> "POD" -> sidecar -> service container`
# Description
This example configures the sidecar proxy on the pods created, to forward the traffic incoming from the port `8080` to the port `80`
## Files
- deployment.yaml
- gateway.yaml
- sidecar.yaml
> Added the `sidecar.yaml` file.
## deployment.yaml
### Creates
#### Service
- helloworld
#### Deployments
- helloworld-nginx (Nginx container)
## gateway.yaml
### Creates
#### Gateway
##### helloworld-gateway
###### Configuration
```yml
...
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
#### VirtualService
##### helloworld-vs
###### Configuration
```yaml
...
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
```
- On this example, we are using the port `8080` as a destination.
## sidecar.yaml
### creates
#### sidecar
##### helloworld-sidecar
###### Configuration
```yaml
...
spec:
workloadSelector:
labels:
app: helloworld
ingress:
- port:
number: 8080
protocol: HTTP
name: ingressport
defaultEndpoint: 127.0.0.1:80
````
workloadSelector:
> `workloadSelector` is used to target the `PODS`, on which apply this sidecar configuration. \
> Bear in mind that this configuration doesn't target kinds `Service`, nor `Deployment`, it's applied to a kind `Pod` or `ServiceEntry` \
> If there is no `workloadSelector` specified, it will be used as default configuration for the namespace on which was created. \
> More info in the [Istio documentation for workloadSelector](https://istio.io/latest/docs/reference/config/networking/sidecar/#WorkloadSelector)
ingress:
> Configure the behavior of the ingress traffic.\
> On this "grabs"/targets the ingress traffic with port 8080, and forwards it to the port IP `127.0.0.1` (loopback) respective to the destination pod, with the destination port set to 80, which is the port that the service is currently listening to.
# Run example
## Deploy resources
```shell
$ kubectl apply -f ./
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
sidecar.networking.istio.io/helloworld-sidecar created
```
## Wait for the pods to be ready
```shell
$ kubectl get deployment helloworld-nginx -w
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld-nginx 1/1 1 1 39s
```
## Test the service
### Get LB IP
```shell
$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### Curl
```shell
$ curl 192.168.1.50/helloworld -s | grep "<title>.*</title>"
<title>Welcome to nginx!</title>
```
### Delete the sidecar configuration to force failure.
```shell
$ kubectl delete sidecars.networking.istio.io helloworld-sidecar
sidecar.networking.istio.io "helloworld-sidecar" deleted
```
### Curl again
```shell
$ curl 192.168.1.50/helloworld -s
upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: delayed connect error: 111
```

View File

@ -0,0 +1,39 @@
## https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
ports:
- port: 8080
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,35 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"

View File

@ -0,0 +1,14 @@
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: helloworld-sidecar
spec:
workloadSelector:
labels:
app: helloworld
ingress:
- port:
number: 8080
protocol: HTTP
name: ingressport
defaultEndpoint: 127.0.0.1:80

157
OLD/03-Sidecar/README.md Executable file
View File

@ -0,0 +1,157 @@
## Examples
- 01-ingress-proxy-forwarding
-
Duplicate 01, and show how it also affects traffic between services.00
egress from (pod to pod)
mtls
examples showing application priority (root < namespace < workload)
istioctl install profile=default --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
```shell
$ kubectl get istiooperators.install.istio.io -n istio-system
NAME REVISION STATUS AGE
installed-state 8d
```
kubectl patch istiooperators installed-state -n istio-system --patch-file patch.txt
kubectl patch istiooperators installed-state -n istio-system --patch-file patch.yaml --type merge
---
Set the default behavior of the sidecar for handling outbound traffic from the application. If your application uses one or more external services that are not known apriori, setting the policy to ALLOW_ANY will cause the sidecars to route any unknown traffic originating from the application to its requested destination.
---
https://stackoverflow.com/questions/75093144/istio-sidecar-is-not-restricting-pod-connections-as-desired
https://github.com/istio/istio/issues/33387
https://gist.github.com/GregHanson/3567f5a23bcd58ad1a8acf2a4d1155eb
https://istio.io/latest/docs/tasks/traffic-management/egress/egress-control/?_ga=2.259114634.1481027401.1681916557-32589553.1681916557#change-to-the-blocking-by-default-policy
https://docs.tetrate.io/service-bridge/1.6.x/en-us/operations ?
https://istio.io/latest/docs/reference/config/networking/sidecar/
https://istio.io/latest/docs/reference/glossary/#workload
I am not very sure on how or why to use this...
NOT HOW TO TRIGGER / UNTRIGGER IT
```yaml
apiVersion:
networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default
namespace: foo
spec:
egress:
- hosts:
- "./*"
- "istio-system/*"
```
whats this again??
istio operator right? ye, but what is it again? I think I checked this time ago when doing something about creating a new ingress
kubectl get io -A
2023-04-17T00:08:00.086475Z info validationController Not ready to switch validation to fail-closed: dummy invalid config not rejected
2023-04-17T00:08:04.012630Z info validationServer configuration is invalid: gateway must have at least one server
kubectl logs -f deployments/istiod -n istio-system
https://istio.io/latest/docs/reference/config/networking/sidecar/
egress:
- port:
number: 8080
protocol: HTTP
hosts:
- "staging/*"
With the YAML above, the sidecar proxies the traffic thats bound for port 8080 for services running in the staging namespace.
- Confirm pod ingress port forwarding
- Confirm it can reach other places / namespaces / resources (pod egress)
- mtls (somehow)
# Ingress
Does stuff
# Egress
What is "bind"
# CaptureMode
Not my problem rn

View File

@ -0,0 +1,42 @@
https://github.com/istio/istio/wiki/EnvoyFilter-Samples
https://stackoverflow.com/questions/73262158/how-to-apply-envoyfilter-to-sidecar-inbound-and-gateway
https://istio.io/latest/docs/reference/config/networking/envoy-filter/
https://discuss.istio.io/t/adding-custom-response-headers-using-istios-1-6-0-envoy-lua-filter/7494
https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter
> kubectl logs -f deployments/istiod -n istio-system
This somewhat is monitoring, can do cool stuff I don't know how or what to do
enable export access logs to stdout
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout
https://istio.io/latest/docs/ops/diagnostic-tools/component-logging/
https://dev.to/aws-builders/understanding-istio-access-logs-2k5o
```yaml
Note: Here I am using request_handle:logCritical method because default logLevel is WARN for Istio components. request_handle:logInfo can be used, if logLevel is set to Info.
```
https://youtu.be/yOtEG1luTwU

View File

@ -0,0 +1,43 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
# annotations:
# sidecar.istio.io/componentLogLevel: info
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
annotations:
sidecar.istio.io/componentLogLevel: lua:info
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,33 @@
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: envoy-add-response-header
namespace: default
spec:
priority: 30
workloadSelector:
labels:
app: helloworld
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_response(response_handle)
response_handle:headers():add("numbers", "lots of numbers")
response_handle:logInfo("Added header `numbers`")
response_handle:logInfo(">>>> Executed `envoy-add-response-header` <<<<")
end

View File

@ -0,0 +1,38 @@
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: envoy-add-response-header2
namespace: default
spec:
priority: 40
workloadSelector:
labels:
app: helloworld
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_response(response_handle)
response_handle:headers():add("fruit", "watermelons")
response_handle:logCritical("Critical: Added header `fruit`")
response_handle:logErr("Error: Added header `fruit`")
response_handle:logWarn("Warning: Added header `fruit`")
response_handle:logInfo("Info: Added header `fruit`")
response_handle:logDebug("Debug: Added header `fruit`")
response_handle:logTrace("Trace: Added header `fruit`")
response_handle:logInfo(">>>> Executed `envoy-add-response-header2` <<<<")
end

View File

@ -0,0 +1,36 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

6
OLD/04-Envoy/README.md Executable file
View File

@ -0,0 +1,6 @@
https://youtu.be/yOtEG1luTwU
Rate Limit:
https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/

View File

@ -0,0 +1,102 @@
# Continues from
- 05-hello_world_1_Service_Entry
# Description
On this example compares the behavior between setting up the MeshConfig `OutboundTrafficPolicy.mode` setting to `REGISTRY_ONLY` and `ALLOW_ANY`.
- ALLOW_ANY: Allows all egress/outbound traffic from the mesh.
- REGISTRY_ONLY: Restricted to services that figure in the service registry a and the ServiceEntry objects.
More info regarding this configuration at the pertintent documentation (https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode)
## Runthrough
### Set ALLOW_ANY outbound traffic policy
```shell
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
```
### Deploy resources
```shell
$ kubectl apply -f ./
service/helloworld created
deployment.apps/helloworld-nginx created
serviceentry.networking.istio.io/external-svc created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
### Get LB IP
```shell
$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
### Test deployments
```shell
$ curl 192.168.1.50/helloworld -I
HTTP/1.1 200 OK
server: istio-envoy
date: Thu, 20 Apr 2023 18:03:18 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 73
```
```shell
$ curl 192.168.1.50/external -I
HTTP/1.1 200 OK
date: Thu, 20 Apr 2023 18:03:24 GMT
content-type: text/html
content-length: 5186
last-modified: Mon, 17 Mar 2014 17:25:03 GMT
expires: Thu, 31 Dec 2037 23:55:55 GMT
cache-control: max-age=315360000
x-envoy-upstream-service-time: 228
server: istio-envoy
```
### Test egress the helloworld deployment
It returns a 301 code, meaning that it was able to reach the destination and it was attempted to redirect the traffic from HTTP to HTTPS.
```shell
$ kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl wikipedia.com -I
HTTP/1.1 301 Moved Permanently
server: envoy
date: Thu, 20 Apr 2023 18:06:57 GMT
content-type: text/html
content-length: 169
location: https://wikipedia.com/
x-envoy-upstream-service-time: 65
```
### Set REGISTRY_ONLY outbound traffic policy
```shell
istioctl install --set profile=default -y --set meshConfig.accessLogFile=/dev/stdout --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
```
### Test (again) egress the helloworld deployment
It returns a 502 code, meaning that it wasn't able to reach the destination.
```shell
$ kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl wikipedia.com -I
HTTP/1.1 502 Bad Gateway
date: Thu, 20 Apr 2023 18:08:37 GMT
server: envoy
transfer-encoding: chunked
```

View File

@ -0,0 +1,57 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc
spec:
hosts:
- help.websiteos.com
# /websiteos/example_of_a_simple_html_page.htm
# - http://help.websiteos.com/websiteos/example_of_a_simple_html_page.htm
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
---

View File

@ -0,0 +1,52 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"
- timeout: 3s
match:
- uri:
exact: "/external"
route:
- destination:
host: help.websiteos.com
port:
number: 80
rewrite:
uri: "/websiteos/example_of_a_simple_html_page.htm"
headers:
request:
set:
HOST: "help.websiteos.com"

View File

@ -0,0 +1,10 @@
# Examples
- 01-Outboud-Traffic-Policy
## Additional
https://istio.io/latest/docs/tasks/observability/distributed-tracing/mesh-and-proxy-config/

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: foo
labels:
istio-injection: "enabled"
---

View File

@ -0,0 +1,293 @@
---
gitea: none
include_toc: true
---
# Continues from
- [06-mTLS](../../02-Traffic_management/06-mTLS)
## Description
Bla bla bla
Configuration targeting namespaces
# Configuration
## Authentication configuration deployed
### default namespace
#### Allow nothing
If the action is not specified, it will deploy the rule as "ALLOW".
Here we are deploying a rule that allows the traffic that it matches, yet as it has no conditions, it will never match.
```yaml
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
```
Citing the [Authorization Policy documentation from Istio](https://istio.io/latest/docs/reference/config/security/authorization-policy), regarding the evaluation behavior of these rules:
1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.
2. If there are any DENY policies that match the request, deny the request.
3. If there are no ALLOW policies for the workload, allow the request.
4. If any of the ALLOW policies match the request, allow the request.
5. Deny the request.
On this scenario, as we don't have any DENY or CUSTOM rule, we skip right into the 3rd scenario.
This rule is being applied to the workload (due being a rule that affects the whole namespace), and for such the 3rd scenario is not being applied either.
On the 4rth, scenario, as the rule deployed, even if it's on ALLOW mode, has no conditions, it won't allow the traffic either.
And finally, as any of the above scenarios allowed the traffic of the request, it ends getting denied.
For such, the creation of this "empty" rule, has set the authorization mode on the not explicitly allowed request to "DENY ALL".
### foo namespace
#### Allow nothing
Same behavior as above, this time applied to the namespace `foo`
```yaml
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
```
#### allow-from-istio-system
As we have a service deployed, and the traffic will come through the Istio Load Balancer (at least on my environment). I have set a rule that will allow all the traffic coming from a resource located in the namespace `istio-system`.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-from-istio-system
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
```
#### allow-get-from-default
As an additional example, I have set a new rule, that will allow the traffic coming from the namespace `default`, as long the method used is `HEAD` and is not targeting the path `/secret`.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-get-from-default
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
namespace/foo created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-from-istio-system created
authorizationpolicy.security.istio.io/allow-head-from-default created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
deployment.apps/byeworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test resources
### Curl / LB requests / requests from external traffic
#### Get LB IP
```shell
kubectl get svc istio-ingressgateway -n istio-system
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
#### helloworld
Due to the rule `allow-nothing` created on the namespace `default`, we are not hitting any rule that explicitly allows us, and for such, the traffic is being denied.
For such we receive the status code `403` (**Forbidden**)
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 02:00:34 GMT
server: istio-envoy
x-envoy-upstream-service-time: 11
```
#### byeworld
As we created the rule `allow-from-istio-system` created in the namespace `foo`, which allows all the traffic coming from a resource located in the namespace `istio-system`, and the load balancer used is located in the namespace `istio-system`, the traffic is allowed.
For such we receive the code `200`.
```shell
curl 192.168.1.50/byeworld --head
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 22 Apr 2023 02:01:48 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 91
```
### Connectivity between the deployments
> **NOTE:**\
> The command `curl`, when uses the flag `--head` or `-I`, the request sent will be a `HEAD` request.
>
> It's important to be aware of that due the rule configured, where one of the targets was the method used, specifically targeted the method `HEAD`.
>
> On this example, all request will be done with the method `HEAD` unless specified otherwise.
#### helloworld towards byeworld
It works.
Due to the rule `allow-head-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, the request is allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090 --head
```
```text
HTTP/1.1 200 OK
server: envoy
date: Sat, 22 Apr 2023 02:08:56 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 6
```
#### helloworld towards byeworld (GET REQUEST)
This example is made on base on the last comand executed, where the request sent uses the `HEAD` method.
On this example the flag `--head` is removed, which causes the command `curl` to send a request of method `GET`.
As the rule created required the method to be `HEAD`, it causes the request to not be allowed, and finally as there are no rules that allow this request, it results in failure.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090
```
```text
RBAC: access denied%
```
#### byeworld towards helloworld
It fails.
As expected, like when accessing through the Load Balancer, we receive the status code `403` (**Forbidden**).
The `HEAD` request is irrelevant on this scenario, yet using it as I like this output more.
```shell
kubectl exec -i -n foo -t "$(kubectl get pod -n foo -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080 --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 02:06:21 GMT
server: envoy
x-envoy-upstream-service-time: 65
```
#### helloworld towards byeworld/secret
Due to the configuration set on the rule `allow-head-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
This causes the traffic to not be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/secret --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 02:40:30 GMT
server: envoy
x-envoy-upstream-service-time: 3
```
#### helloworld towards byeworld/not-found
On this example, we can notice how even if the request was allowed due meeting all the requirements, it still results in the error code `404` (Not Found).
This 404 error is raised by the destination service, yet before being able to handle such request, firstly the traffic required to be allowed, meaning that even if we target as a destination path a non-existent resource, we will need to match the requirements for the traffic to be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/not-found --head
```
```text
HTTP/1.1 404 Not Found
server: envoy
date: Sat, 22 Apr 2023 06:09:59 GMT
content-type: text/html
content-length: 153
x-envoy-upstream-service-time: 67
```
# Links of interest
- https://istio.io/latest/docs/reference/config/security/authorization-policy/

View File

@ -0,0 +1,45 @@
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
---
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-from-istio-system
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-head-from-default
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]

View File

@ -0,0 +1,40 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,42 @@
apiVersion: v1
kind: Service
metadata:
name: byeworld
labels:
app: byeworld
service: byeworld
namespace: foo
spec:
ports:
- port: 9090
name: http
targetPort: 80
selector:
app: byeworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: byeworld-nginx
labels:
app: byeworld
namespace: foo
spec:
replicas: 1
selector:
matchLabels:
app: byeworld
template:
metadata:
labels:
app: byeworld
spec:
containers:
- name: byeworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,45 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
- match:
- uri:
exact: /byeworld
route:
- destination:
host: byeworld.foo.svc.cluster.local
port:
number: 9090
rewrite:
uri: "/"

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: foo
labels:
istio-injection: "enabled"
---

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: istio-helloworld-sa
labels:
app: helloworld
---

View File

@ -0,0 +1,338 @@
---
gitea: none
include_toc: true
---
# Continues from
[//]: # (- [01-hello_world_1_service_1_deployment]&#40;../../01-simple/01-hello_world_1_service_1_deployment&#41;)
- [01-target-namespaces](../01-target-namespaces)
> **Note:**\
> On this example there is minimal changes to the configuration to involve targeting service accounts.
## Description
Bla bla bla
Configuration targeting service accounts (among others)
By default, when a pod is deployed, if a service account has not been specified, it will be given the service account `default` from that namespace.
# Changelog
## Service Account
### default namespace
#### istio-helloworld-sa
Created a service account named `istio-helloworld-sa`.
The label was set cause it made sense, yet it's not used on this example.
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: istio-helloworld-sa
labels:
app: helloworld
```
## Authentication configuration deployed
### default namespace
#### Allow nothing
```yaml
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
```
Citing the [Authorization Policy documentation from Istio](https://istio.io/latest/docs/reference/config/security/authorization-policy), regarding the evaluation behavior of these rules:
1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.
2. If there are any DENY policies that match the request, deny the request.
3. If there are no ALLOW policies for the workload, allow the request.
4. If any of the ALLOW policies match the request, allow the request.
5. Deny the request.
On this scenario, as we don't have any DENY or CUSTOM rule, we skip right into the 3rd scenario.
This rule is being applied to the workload (due being a rule that affects the whole namespace), and for such the 3rd scenario is not being applied either.
On the 4rth, scenario, as the rule deployed, even if it's on ALLOW mode, has no conditions, it won't allow the traffic either.
And finally, as any of the above scenarios allowed the traffic of the request, it ends getting denied.
For such, the creation of this "empty" rule, has set the authorization mode on the not explicitly allowed request to "DENY ALL".
### foo namespace
#### Allow nothing
Same behavior as above, this time applied to the namespace `foo`
```yaml
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
```
#### allow-from-istio-system
As we have a service deployed, and the traffic will come through the Istio Load Balancer (at least on my environment).
I have set a rule that will allow all the traffic coming from a resource located in the namespace `istio-system` AND also uses the service account `istio-ingressgateway-service-account` from that namespace.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-from-istio-system
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
- source:
principals: ["cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
```
This service account is the account set to the ingress gateway resource currently set.
For reference, I have check it through the following command.
```shell
kubectl get pod -n istio-system istio-ingressgateway-864db96c47-mj5r2 -o jsonpath='{.spec.serviceAccount}'
```
```text
istio-ingressgateway-service-account%
```
#### allow-get-from-default
As an additional example, I have set a new rule, that will allow the traffic coming from the namespace `default`, as long the method used is `HEAD` and is not targeting the path `/secret`.\
Additionally, it requires that the requester uses the service account `istio-helloworld-sa` that we created.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-from-istio-system
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["default"]
- source:
principals: ["cluster.local/ns/default/sa/istio-helloworld-sa"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]
```
Citing the [`rule.source.namespaces` field from the Authorization Policy documentation from Istio](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Source):
> This field requires mTLS enabled and is the same as the source.namespace attribute.
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
namespace/foo created
serviceaccount/istio-helloworld-sa created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/allow-from-istio-system created
authorizationpolicy.security.istio.io/allow-head-from-default created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
deployment.apps/byeworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
## Test resources
### Curl / LB requests / requests from external traffic
#### Get LB IP
```shell
kubectl get svc istio-ingressgateway -n istio-system
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.173.231 192.168.1.50 15021:31277/TCP,80:30603/TCP,443:30290/TCP 34h
```
#### helloworld
Due to the rule `allow-nothing` created on the namespace `default`, we are not hitting any rule that explicitly allows us, and for such, the traffic is being denied.
For such we receive the status code `403` (**Forbidden**)
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 05:56:00 GMT
server: istio-envoy
x-envoy-upstream-service-time: 102
```
#### byeworld
We created the rule `allow-from-istio-system` created in the namespace `foo`, which allows all the traffic coming from a resource located in the namespace `istio-system`, and the load balancer used is located in the namespace `istio-system`.
On top of that, the Istio ingress being used, has the service account `istio-ingressgateway-service-account` from the namespace `istio-system` set, which is the current target of the rule.
For such we receive the code `200`.
```shell
curl 192.168.1.50/byeworld --head
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 22 Apr 2023 06:01:00 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 10
```
### Connectivity between the deployments
> **NOTE:**\
> The command `curl`, when uses the flag `--head` or `-I`, the request sent will be a `HEAD` request.
>
> It's important to be aware of that due the rule configured, where one of the targets was the method used, specifically targeted the method `HEAD`.
#### helloworld towards byeworld (HEAD REQUEST)
It works.
Due to the rule `allow-get-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, and, the deployment `helloworld` being using the service account `istio-helloworld-sa`, which is the target configured on the network rule, the request is allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090 --head
```
```text
HTTP/1.1 200 OK
server: envoy
date: Sat, 22 Apr 2023 06:01:08 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 4
```
#### helloworld towards byeworld (GET REQUEST)
This example is made on base on the last comand executed, where the request sent uses the `HEAD` method.
On this example the flag `--head` is removed, which causes the command `curl` to send a request of method `GET`.
As the rule created required the method to be `HEAD`, it causes the request to not be allowed, and finally as there are no rules that allow this request, it results in failure.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090
```
```text
RBAC: access denied%
```
#### byeworld towards helloworld
It fails.
As expected, like when accessing through the Load Balancer, we receive the status code `403` (**Forbidden**).
The `HEAD` request is irrelevant on this scenario, yet using it as I like this output more.
```shell
kubectl exec -i -n foo -t "$(kubectl get pod -n foo -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080 --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 06:06:13 GMT
server: envoy
x-envoy-upstream-service-time: 99
```
#### helloworld towards byeworld/secret
Due to the configuration set on the rule `allow-get-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
This causes the traffic to not be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/secret --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Sat, 22 Apr 2023 06:15:38 GMT
server: envoy
x-envoy-upstream-service-time: 3
```
#### helloworld towards byeworld/not-found
On this example, we can notice how even if the request was allowed due meeting all the requirements, it still results in the error code `404` (Not Found).
This 404 error is raised by the destination service, yet before being able to handle such request, firstly the traffic required to be allowed, meaning that even if we target as a destination path a non-existent resource, we will need to match the requirements for the traffic to be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/not-found --head
```
```text
HTTP/1.1 404 Not Found
server: envoy
date: Sat, 22 Apr 2023 06:15:29 GMT
content-type: text/html
content-length: 153
x-envoy-upstream-service-time: 28
```
# Links of interest
- https://istio.io/latest/docs/reference/config/security/authorization-policy/

View File

@ -0,0 +1,50 @@
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
---
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-from-istio-system
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-ingress"]
- source:
principals: ["cluster.local/ns/istio-ingress/sa/myistio-ingressgateway-service-account%"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-head-from-default
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["default"]
- source:
principals: ["cluster.local/ns/default/sa/istio-helloworld-sa"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]
---

View File

@ -0,0 +1,41 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
serviceAccountName: istio-helloworld-sa
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,42 @@
apiVersion: v1
kind: Service
metadata:
name: byeworld
labels:
app: byeworld
service: byeworld
namespace: foo
spec:
ports:
- port: 9090
name: http
targetPort: 80
selector:
app: byeworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: byeworld-nginx
labels:
app: byeworld
namespace: foo
spec:
replicas: 1
selector:
matchLabels:
app: byeworld
template:
metadata:
labels:
app: byeworld
spec:
containers:
- name: byeworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,46 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
# istio: ingressgateway # use istio default controller
istio: myingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
- match:
- uri:
exact: /byeworld
route:
- destination:
host: byeworld.foo.svc.cluster.local
port:
number: 9090
rewrite:
uri: "/"

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: foo
labels:
istio-injection: "enabled"
---

View File

@ -0,0 +1,382 @@
---
gitea: none
include_toc: true
---
# Continues from
- [01-target-namespaces](../01-target-namespaces)
> **Note:**\
> On this example there is minimal changes to the configuration to involve targeting the deployment resources through label filtering.
## Description
Bla bla bla
In this example we will be targeting the labels set to the deployments, while keeping part of the previous AuthorizationPolicy configuration to maintain its behavior.
[//]: # (For such, it's important to check the labels set in the Istio ingress that we will be using.)
[//]: # ()
[//]: # (On my case, in the gateway I will be targeting/using the Istio ingress `ingressgateway`.)
[//]: # ()
[//]: # (I would **strongly** recommend checking yours through the following command, as to proceed we should be aware of which are our possible labels options.)
[//]: # ()
[//]: # (```shell)
[//]: # (kubectl get deployments -A -l istio=ingressgateway -o jsonpath='{.items[].spec.template.metadata.labels}'| jq)
[//]: # (```)
[//]: # (```json)
[//]: # ({)
[//]: # ( "app": "istio-ingressgateway",)
[//]: # ( "chart": "gateways",)
[//]: # ( "heritage": "Tiller",)
[//]: # ( "install.operator.istio.io/owning-resource": "unknown",)
[//]: # ( "istio": "ingressgateway",)
[//]: # ( "istio.io/rev": "default",)
[//]: # ( "operator.istio.io/component": "IngressGateways",)
[//]: # ( "release": "istio",)
[//]: # ( "service.istio.io/canonical-name": "istio-ingressgateway",)
[//]: # ( "service.istio.io/canonical-revision": "latest",)
[//]: # ( "sidecar.istio.io/inject": "false")
[//]: # (})
[//]: # (```)
[//]: # ()
[//]: # (Based on the list displayed, I would suggest focusing on the following options:)
[//]: # ()
[//]: # (```json)
[//]: # ({)
[//]: # ("istio": "ingressgateway",)
[//]: # ("operator.istio.io/component": "IngressGateways",)
[//]: # ("app": "istio-ingressgateway",)
[//]: # (})
[//]: # (```)
[//]: # ()
[//]: # (The label `"service.istio.io/canonical-revision": "latest"` could be reasonable to use, in very specific situations, as depending on the implementation/environment or procedures that we might use in the future, it's something to keep in mind in case of being configured.)
[//]: # ()
[//]: # ()
# Configuration
## AuthorizationPolicy
### Allow nothing (deny all not matched)
#### default namespace
If the action is not specified, it will deploy the rule as "ALLOW".
Here we are deploying a rule that allows the traffic that it matches, yet as it has no conditions, it will never match.
```yaml
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
```
Citing the [Authorization Policy documentation from Istio](https://istio.io/latest/docs/reference/config/security/authorization-policy), regarding the evaluation behavior of these rules:
1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.
2. If there are any DENY policies that match the request, deny the request.
3. If there are no ALLOW policies for the workload, allow the request.
4. If any of the ALLOW policies match the request, allow the request.
5. Deny the request.
On this scenario, as we don't have any DENY or CUSTOM rule, we skip right into the 3rd scenario.
This rule is being applied to the workload (due being a rule that affects the whole namespace), and for such the 3rd scenario is not being applied either.
On the 4rth, scenario, as the rule deployed, even if it's on ALLOW mode, has no conditions, it won't allow the traffic either.
And finally, as any of the above scenarios allowed the traffic of the request, it ends getting denied.
For such, the creation of this "empty" rule, has set the authorization mode on the not explicitly allowed request to "DENY ALL".
#### foo namespace
Same behavior as above, this time applied to the namespace `foo`
```yaml
# Deny all requests to namespace foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: foo
spec:
{}
```
## ALLOW
#### byeworld-allow-from-istio-system
As we have a service deployed, and the traffic will come through the Istio Load Balancer (at least on my environment). I have set a rule that will allow all the traffic coming from a resource located in the namespace `istio-system`.
This rule will be applied to the deployments that have set the following label `app: byeworld`, and deployed in the namespace `istio-system`.
> **Note:**\
> As this rule will be deployed in the root namespace `istio-system` (it's my root namespace in **MY** environment, review your Istio configuration to ensure which is **YOUR** root namespace).\
> By deploying the rule in the root namespace, it gets applied to all namespaces, I have set this to ensure that there are minor differences on the configuration in comparison on which example this is based on. As well this will allow us to confirm tha the labels are being applied correctly.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-from-istio-system
namespace: istio-system
spec:
selector:
matchLabels:
app: byeworld
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
```
#### byeworld-allow-head-from-default
I have set a new rule, that will allow the traffic coming from the namespace `default`, as long the method used is `HEAD` and is not targeting the path `/secret`.
This rule will be applied to the deployments that have set the following label `app: byeworld`, and deployed in the namespace `istio-system`.
> **Note:**\
> This will be deployed in the root namespace `istio-system` (it's my root namespace in **MY** environment, review your Istio configuration to ensure which is **YOUR** root namespace).\
> By deploying the rule in the root namespace, it gets applied to all namespaces, I have set this to ensure that there are minor differences on the configuration in comparison on which example this is based on. As well this will allow us to confirm tha the labels are being applied correctly.
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-head-from-default
namespace: istio-system
spec:
action: ALLOW
selector:
matchLabels:
app: byeworld
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]
```
# Walkthrough
## Deploy the resources
```shell
kubectl apply -f ./
```
```text
namespace/foo created
authorizationpolicy.security.istio.io/allow-nothing created
authorizationpolicy.security.istio.io/byeworld-allow-from-istio-system created
authorizationpolicy.security.istio.io/byeworld-allow-head-from-default created
service/helloworld created
deployment.apps/helloworld-nginx created
service/byeworld created
deployment.apps/byeworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs create
```
## Test resources
### Curl / LB requests / requests from external traffic
#### Get LB IP
```shell
kubectl get svc istio-ingressgateway -n istio-system
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
#### helloworld
Due to the rule `allow-nothing` created on the namespace `istio-system`, which is being applied to all the namespaces, we are not hitting any rule that explicitly allows us, and for such, the traffic is being denied.
For such we receive the status code `403` (**Forbidden**)
```shell
curl 192.168.1.50/helloworld -I
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:20:06 GMT
server: istio-envoy
x-envoy-upstream-service-time: 108
```
#### byeworld
As we created the rule `byeworld-allow-from-istio-system` created in the namespace `foo`, which allows all the traffic coming from a resource located in the namespace `istio-system`, and the load balancer used is located in the namespace `istio-system`, the traffic is allowed.
For such we receive the code `200`.
```shell
curl 192.168.1.50/byeworld --head
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Thu, 27 Apr 2023 01:20:49 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 104
```
### Connectivity between the deployments
> **NOTE:**\
> The command `curl`, when uses the flag `--head` or `-I`, the request sent will be a `HEAD` request.
>
> It's important to be aware of that due the rule configured, where one of the targets was the method used, specifically targeted the method `HEAD`.
>
> On this example, all request will be done with the method `HEAD` unless specified otherwise.
#### helloworld towards byeworld
It works.
Due to the rule `byeworld-allow-head-from-default` deployed on the namespace `foo`, which allowed the traffic coming from the namespace `default` as long it used the method `HEAD` and wasn't targeting the path `/secret`, the request is allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090 --head
```
```text
HTTP/1.1 200 OK
server: envoy
date: Thu, 27 Apr 2023 01:20:58 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 86
```
#### helloworld towards byeworld (GET REQUEST)
This example is made on base on the last comand executed, where the request sent uses the `HEAD` method.
On this example the flag `--head` is removed, which causes the command `curl` to send a request of method `GET`.
As the rule created required the method to be `HEAD`, it causes the request to not be allowed, and finally as there are no rules that allow this request, it results in failure.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090
```
```text
RBAC: access denied%
```
#### byeworld towards helloworld
It fails.
As expected, like when accessing through the Load Balancer, we receive the status code `403` (**Forbidden**).
The `HEAD` request is irrelevant on this scenario, yet using it as I like this output more.
```shell
kubectl exec -i -n foo -t "$(kubectl get pod -n foo -l app=byeworld | tail -n 1 | awk '{print $1}')" -- curl http://helloworld.default.svc.cluster.local:8080 --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:21:10 GMT
server: envoy
x-envoy-upstream-service-time: 96
```
#### helloworld towards byeworld/secret
Due to the configuration set on the rule `byeworld-allow-head-from-default`, one of the conditions for it to allow the traffic, was to not access the path/match the prefix expression `/secret*`.
This causes the traffic to not be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/secret --head
```
```text
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Thu, 27 Apr 2023 01:21:18 GMT
server: envoy
x-envoy-upstream-service-time: 3
```
#### helloworld towards byeworld/not-found
On this example, we can notice how even if the request was allowed due meeting all the requirements, it still results in the error code `404` (Not Found).
This 404 error is raised by the destination service, yet before being able to handle such request, firstly the traffic required to be allowed, meaning that even if we target as a destination path a non-existent resource, we will need to match the requirements for the traffic to be allowed.
```shell
kubectl exec -i -t "$(kubectl get pod -l app=helloworld | tail -n 1 | awk '{print $1}')" -- curl http://byeworld.foo.svc.cluster.local:9090/not-found --head
```
```text
HTTP/1.1 404 Not Found
server: envoy
date: Thu, 27 Apr 2023 01:21:31 GMT
content-type: text/html
content-length: 153
x-envoy-upstream-service-time: 56
```
# Links of interest
- https://istio.io/latest/docs/reference/config/security/authorization-policy/

View File

@ -0,0 +1,43 @@
---
# Deny all requests to namespace default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-from-istio-system
namespace: istio-system
spec:
selector:
matchLabels:
app: byeworld
action: ALLOW
rules:
- from:
- source:
namespaces: ["istio-system"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: byeworld-allow-head-from-default
namespace: istio-system
spec:
action: ALLOW
selector:
matchLabels:
app: byeworld
rules:
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["HEAD"]
notPaths: ["/secret*"]

View File

@ -0,0 +1,40 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,42 @@
apiVersion: v1
kind: Service
metadata:
name: byeworld
labels:
app: byeworld
service: byeworld
namespace: foo
spec:
ports:
- port: 9090
name: http
targetPort: 80
selector:
app: byeworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: byeworld-nginx
labels:
app: byeworld
namespace: foo
spec:
replicas: 1
selector:
matchLabels:
app: byeworld
template:
metadata:
labels:
app: byeworld
spec:
containers:
- name: byeworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,45 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
rewrite:
uri: "/"
- match:
- uri:
exact: /byeworld
route:
- destination:
host: byeworld.foo.svc.cluster.local
port:
number: 9090
rewrite:
uri: "/"

View File

@ -0,0 +1,24 @@
## Authentication
- Based on namespaces (done)
- Based on method (somewhat done, so I will mark it as valid)
- Based on service account(s) (somewhat done)
- Custom action (it's in alpha feature, should not focus on it for now)
- Audit / logs (should be the 3th)
JWT seems important, refer to source.requestPrincipals
https://istio.io/latest/docs/tasks/security/authentication/
Per deployment:
```yaml
selector:
matchLabels:
app: myapi
```

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: istio-ingress
labels:
istio-injection: "enabled"
---

View File

@ -0,0 +1,196 @@
---
gitea: none
include_toc: true
---
# Based on
- [01-hello_world_1_service_1_deployment](../../01-Getting%20Started/01-hello_world_1_service_1_deployment)
# Description
On this example, a new Istio Ingress Load Balancer is deployed.
The previous example has been modified to utilize the Ingress resource just deployed.
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: myingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
The selector `Istio` has been updated to `myingressgateway`, to match the selector of the Istio Ingress Load Balancer that will be created.
## Namespace
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: istio-ingress
labels:
istio-injection: "enabled"
```
The namespace `istio-ingress` will have the label `istio-injection` with the contents set to `enabled` to allow Istio to automatically inject the Istio sidecars to the resources within that namespace, unless specified otherwise.
## IstioOperator
```yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: ingress
spec:
profile: empty # Do not install CRDs or the control plane
components:
ingressGateways:
- name: myistio-ingressgateway
namespace: istio-ingress
enabled: true
label:
# Set a unique label for the gateway. This is required to ensure Gateways
# can select this workload
istio: myingressgateway
values:
gateways:
istio-ingressgateway:
# Enable gateway injection
injectionTemplate: gateway
```
The following configuration will create an Istio Ingress Load Balancer named `myistio-ingressgateway`, located at the namespace `istio-ingress`.
The label `istio`, refers to the selector that the `Gateway` resources will use to specify the targeted Istio resource.
# Walkthrough
## Deploy resources
### Create namespace
```shell
kubectl apply -f 01-namespace.yaml
```
```text
namespace/istio-ingress created
```
### Create / Install the Istio Ingress resource
```shell
istioctl install -f ingress.yaml
```
```text
This will install the Istio 1.17.2 empty profile into the cluster. Proceed? (y/N) y
✔ Ingress gateways installed
✔ Installation complete
Thank you for installing Istio 1.17. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/hMHGiwZHPU7UQRWe9
```
### Deploy gateway
```shell
kubectl apply -f gateway.yaml
```
```text
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
```
### Deploy deployment
```shell
kubectl apply -f deployment-nomtls.yaml
```
```text
service/helloworld created
deployment.apps/helloworld-nginx created
```
## Testing deployment
### Get Load Balancer IP
```shell
kubectl get svc -n istio-ingress
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myistio-ingressgateway LoadBalancer 10.102.158.128 192.168.1.51 15021:31181/TCP,80:30090/TCP,443:31285/TCP 5m10s
```
### Curl
The request results in status code `200`, meaning a correct handling of the request.
```shell
curl 192.168.1.51/helloworld -I
```
```text
HTTP/1.1 200 OK
server: istio-envoy
date: Sun, 23 Apr 2023 06:40:57 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Mar 2023 15:01:54 GMT
etag: "64230162-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 15
```
# Cleanup
[Yeah no idea, gl with that.](https://stackoverflow.com/a/55731730)
```shell
kubectl delete -f ./deployment-nomtls.yaml
kubectl delete -f ./gateway.yaml
```
```text
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
```
```shell
istioctl uninstall --purge
```
Also read that "just removing" the namespace works to purge the config/remove resources.
Meanwhile, I did that (and seems like it performed correctly), I am not entirely sure about it. I'm not bothered myself as the environment where I am performing the tests is intended to be destroyed anytime and recreated, yet in a production environment I am not sure how this would need to be approached.
Maybe with a `kubectl get all -A` and through `grep` and `less` find resources and configurations, and delete them manually.
```shell
kubectl delete namespace istio-ingress
```
# Troubleshooting
## curl: (7) Failed to connect to 192.168.1.51 port 80 after 2 ms: Couldn't connect to server
Ensure that the gateway is using the correct `selector` to target the Istio Ingress Load Balancer created.
# Links of interest
- https://istio.io/latest/docs/setup/additional-setup/gateway/#deploying-a-gateway

View File

@ -0,0 +1,48 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 80
name: http
selector:
app: helloworld
---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
# name: istio-helloworld
# labels:
# account:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nginx
labels:
app: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
labels:
app: helloworld
spec:
# serviceAccountName: istio-helloworld
containers:
- name: helloworld
image: nginx
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80

View File

@ -0,0 +1,36 @@
# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: myingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: helloworld
port:
number: 80
rewrite:
uri: "/"

View File

@ -0,0 +1,20 @@
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: ingress
spec:
profile: empty # Do not install CRDs or the control plane
components:
ingressGateways:
- name: myistio-ingressgateway
namespace: istio-ingress
enabled: true
label:
# Set a unique label for the gateway. This is required to ensure Gateways
# can select this workload
istio: myingressgateway
values:
gateways:
istio-ingressgateway:
# Enable gateway injection
injectionTemplate: gateway

View File

@ -0,0 +1,637 @@
---
gitea: none
include_toc: true
---
# Description
On this example we disable the mTLS for the service deployed, and observe which is the behavior, and one possible environment where it might be required to disable mTLS.
This example uses the `selector` field to target labels set to the deployments.
Also explores the behavior of accessing an `HTTPS` backend using the tls `STRICT` mode, when using `mTLS` and when `mTLS` is disabled.
To explore the different behaviors, [2 deployments](#deployments) where used, both under the same [Service](#service), and the traffic will be distributed through subsets in the [Destination Rule](#destination-rule) set.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
# Configuration
## Gateway
Listens for `HTTP` traffic without limiting any host.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
```
## Virtual Service
Without limiting to any host, listens for traffic at port 80, and only has a very specific URL paths available to match.
- /http-mTLS
- /https-mTLS
- /http-no-mTLS
- /https-no-mTLS
Depending on the path used, the traffic will be distributed between 2 subsets from the same service:
- mtls
- nomtls
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: mtls
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 80
uri:
exact: "/https-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: mtls
rewrite:
uri: "/"
- name: http-no-mTLS
match:
- port: 80
uri:
exact: "/http-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: nomtls
rewrite:
uri: "/"
- name: https-no-mTLS
match:
- port: 80
uri:
exact: "/https-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: nomtls
rewrite:
uri: "/"
```
## Destination Rule
Interfering with the service URL `helloworld.default.svc.cluster.local`, it specifies 2 subsets:
- mtls
- nomtls
Additionally, specifies that the traffic with port destination 8443, will attempt to proceed with TLS termination, as it is required to connect with an `HTTPS` backend.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
subsets:
- name: mtls
labels:
mtls: "true"
- name: nomtls
labels:
mtls: "false"
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend
```
## Service
The service will forward incoming traffic from the service port `8443`, that will be forwarded towards the port `443` from the deployment, which contains an `HTTPS` service.
Also listens for `HTTP` traffic at the port `8080`, and will be forwarded to the deployment port `80`.
```yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
```
## Deployments
There's been configured 2 deployments with the same service and settings, besides the label `mtls`, which will contain `true` or `false` based on the deployment.
This label is used for the [Destination Rule](#destination-rule) to distribute the traffic between the 2 deployments under the same service.
> **Note:**\
> For more information about the image used refer to [here](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
### helloworld-mtls
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-mtls
labels:
app: helloworld
mtls: "true"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "true"
template:
metadata:
labels:
app: helloworld
mtls: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
### helloworld-nomtls
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nomtls
labels:
app: helloworld
mtls: "false"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "false"
template:
metadata:
labels:
app: helloworld
mtls: "false"
spec:
containers:
- name: helloworld-nomtls
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
```
## PeerAuthentications
Deployed 2 Peer Authentication rules, which use the `selector` field to target the deployments.
Both point to the same application, yet also specify the `mtls` label set in the deployments above, allowing the rules to target each deployment individually.
These rules are deployed in the `default` namespace.
### disable-mtls
This rule will disable `mTLS` for that deployment.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: disable-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "false"
mtls:
mode: DISABLE
```
### force-mtls
This rule forces the deployment to communicate exclusively through `mTLS`, in case this rule is not endorsed, the traffic won't be allowed to proceed further.
```yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: force-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "true"
mtls:
mode: STRICT
```
# Walkthrough
## Deploy resources
```shell
kubectl apply -f ./
```
```text
service/helloworld created
peerauthentication.security.istio.io/disable-mtls created
peerauthentication.security.istio.io/force-mtls created
deployment.apps/helloworld-mtls created
deployment.apps/helloworld-nomtls created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld.default.svc.cluster.local created
```
## Get LB IP
```shell
kubectl get svc -l istio=ingressgateway -A
```
```text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.97.47.216 192.168.1.50 15021:31316/TCP,80:32012/TCP,443:32486/TCP 39h
```
## Analyze the different behaviours
> **DISCLAIMER**:\
> For some reason, during the packet captures, I required to execute the curl 2 times in order for the output to be updated.\
> During the tests, feel free to perform the curl twice in a row.
This steps will be structured on 3 parts:
- Starting the packet capture.
- Using `curl` to send a request to the destination. This step can also be performed through a web browser.
- Observing the information captured in the packet capture.
All this steps will be performed for each one of the environments, each environment being formed by 2 backend destinations.
Environments:
- mTLS disabled
- mTLS enabled
Backend destinations in each one of the environments:
- HTTP
- HTTPS
### mTLS disabled
#### HTTP
##### Start the packet capture for the port 80
Start the packet capture and proceed with another shell or browser to send traffic requests to the right destination.
```shell
PORT=80 && MTLS="false" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
Nothing to higlight so far, we can access the service.
```shell
curl 192.168.1.50/http-no-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to having the mTLS disabled, the traffic is not encrypted, and for such we can see its context in plain text.
This scenario should be avoided unless it is required due the application being used, as mTLS allows an extra layer of security.
```text
04:25:47.757900 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.60966 > helloworld-nomtls-66d8499c5c-298vw.http: Flags [P.], seq 3134140617:3134142280, ack 2649160847, win 501, options [nop,nop,TS val 1425864700 ecr 2534833629], length 1663: HTTP: GET / HTTP/1.1
E....t@.?.....yX..yx.&.P..0.........Q......
T.....}.GET / HTTP/1.1
host: 192.168.1.50
user-agent: curl/8.0.1
accept: */*
x-forwarded-for: 192.168.1.10
x-forwarded-proto: http
x-envoy-internal: true
x-request-id: 65b60be7-da98-48f3-9ed6-13112cdd14f0
x-envoy-decorator-operation: helloworld.default.svc.cluster.local:8080/http-no-mTLS
x-envoy-peer-metadata: ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgwaCkt1YmVybmV0ZXMKHwoMSU5TVEFOQ0VfSVBTEg8aDTE3Mi4xNy4xMjEuODgKGQoNSVNUSU9fVkVSU0lPThIIGgYxLjE3LjIKnAMKBkxBQkVMUxKRAyqOAwodCgNhcHASFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKEwoFY2hhcnQSChoIZ2F0ZXdheXMKFAoIaGVyaXRhZ2USCBoGVGlsbGVyCjYKKWluc3RhbGwub3BlcmF0b3IuaXN0aW8uaW8vb3duaW5nLXJlc291cmNlEgkaB3Vua25vd24KGQoFaXN0aW8SEBoOaW5ncmVzc2dhdGV3YXkKGQoMaXN0aW8uaW8vcmV2EgkaB2RlZmF1bHQKMAobb3BlcmF0b3IuaXN0aW8uaW8vY29tcG9uZW50EhEaD0luZ3Jlc3NHYXRld2F5cwoSCgdyZWxlYXNlEgcaBWlzdGlvCjkKH3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLW5hbWUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0CiIKF3NpZGVjYXIuaXN0aW8uaW8vaW5qZWN0EgcaBWZhbHNlChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAovCgROQU1FEicaJWlzdGlvLWluZ3Jlc3NnYXRld2F5LTg2NGRiOTZjNDctZjZscWQKGwoJTkFNRVNQQUNFEg4aDGlzdGlvLXN5c3RlbQpdCgVPV05FUhJUGlJrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvaXN0aW8tc3lzdGVtL2RlcGxveW1lbnRzL2lzdGlvLWluZ3Jlc3NnYXRld2F5ChcKEVBMQVRGT1JNX01FVEFEQVRBEgIqAAonCg1XT1JLTE9BRF9OQU1FEhYaFGlzdGlvLWluZ3Jlc3NnYXRld2F5
x-envoy-peer-metadata-id: router~172.17.121.88~istio-ingressgateway-864db96c47-f6lqd.istio-system~istio-system.svc.cluster.local
x-envoy-attempt-count: 1
x-envoy-original-path: /http-no-mTLS
x-b3-traceid: 36e7d48757f2ce26eaa6e1959f3b1221
x-b3-spanid: eaa6e1959f3b1221
x-b3-sampled: 0
```
#### HTTPS
##### Start the packet capture for the port 443
```shell
PORT=443 && MTLS="false" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
So good so far.
```shell
curl 192.168.1.50/https-no-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to the configuration set in the [Destination Rule](#destination-rule), where we set the `tls.mode` setting to `SIMPLE`, the traffic will be TLS terminated with the backend.
For such, the traffic captured is encrypted, even tho we displayed the `mTLS` configuration for this deployment.
Yet, there are still a couple readable lines, where we can see that the request was initialized by the host `stio-ingressgateway.istio-system.svc.cluster.local`, through the egress port `39884`, using as destination `helloworld-nomtls-66d8499c5c-298vw`, and the port defined with name `https`, which, if we reviewed the configuration from the [Service](#service), we would observe that it was the port `8443`.
```text
k 496, win 505, options [nop,nop,TS val 1425943341 ecr 2534945802], length 0
E..4..@.?.....yX..yx.......;........K......
T.+-..4
04:27:06.400101 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39884 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 809, win 503, options [nop,nop,TS val 1425943342 ecr 2534945803], length 0
E..4..@.?.....yX..yx.......;........K......
T.+...4.
04:27:13.439290 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39826 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [P.], seq 1997:3684, ack 2200, win 501, options [nop,nop,TS val 1425950381 ecr 2534942622], length 1687
E.....@.?..+..yX..yx....pI.+,U+.....Q......
T.F...'......,.SuD..a....`..]....j..v[tF$y.<......&..m.E.p.Y.-....w..V..T.....g..a~$.Q'.c#......qj..8.|......M.J.....\".>...R...M..k|..f^,.....E.....+.Y.6..].u.g<r...0.eE...QSM 0Q...05......y......h6fbW.HdFp....../..(F\.U.pSn...2 .-.X/.8...P....~4anH.h....e....../.3@(....x...{.4.j@[.....P.6.......%.M.EGo.Q~@.
Z............/$..@....&.8..... f...ip.z]....p..}.....f.=......'......Koz.3..d.@..;....)}...>.m....Z..~o.IL.......D.]h.G.... .....F/..V......}.v.^N.P.C.G.......1..T.....w....?..]:........D...;q?...W..cI.).O......3..X14P..B.).',.N...B.../q..)\.. GW.".... .`.....[9.IS......1y.J]...d..}...B.n...C.........e6..B..[w.\.3.l.HU....5%......p.irW.@s..!1\u./.~..[.g..W.........'W..,m};._../S2\..c.9..8..rg"f..35a.A.;..T....>`..Zv.L.8....hZ".*r...0..*.%K.?.. .P]DKve/E.J.....\....t.e.9#-..3.$).....Q.Z.....m].". q. *.OW...f.=l...K.o:.D.......+.a..h?{h.?..T.....7\N.....M.`..Ob1`.....3d.aq..0...q.r.*j....KE./.O...T%..r.......'..9.W1J^^TU8.$...Y."~..~ZH.......G..?......Q4..=|.{.d/..^_....`.pjJ+p.........R."..Y-.`1....{....k...]ib.+m.....6..k...U.P.T........wU...}......`.z..#..[1.@9.z+R.3pAW).......m...Px4..9^ X..ux.EVO.o.%./+.....|4..!s......g.1...9%.... B.....{.6..].-?.../..n..y...2..sLc..|x.
,.t..'...7.............|...........?..&}........@...=.|#.+...........u.3....m.X..... QrW?............u`-k....Q.o^{........$..h.....R.#...k...o.7~.*.tE.C...I<"......k..czN.DJ.y...R.....hx.he.r}0.82....6.J...)..3.f.G=Ky|f.L.).=.hlN!..D..J..g.V.?.......#...fQ..d.......9.9.-....j..O...Pd..E.da/..b} .}.Qx.......I..[+....>.5....p.9....K2M s(.a..K6.]..m.?...%..</.S.9......[.P./.1.I. ...k.'.`V........^O.....q.. <...H..=mZZ...........@.VR..x.....U..t....s!.......M.m.........u...:.....V.1X...2.T..~...
04:27:13.440468 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.39826 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 2513, win 501, options [nop,nop,TS val 1425950382 ecr 2534952843], length 0
E..4..@.?.....yX..yx....pI..,U,.....K......
T.F...O.
04:27:20.932653 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [S], seq 3645561416, win 64800, options [mss 1440,sackOK,TS val 1425957874 ecr 0,nop,wscale 7], length 0
E..<..@.?.f>..yX..yx.....J.H....... K".........
T.c.........
04:27:20.933038 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [.], ack 840930767, win 507, options [nop,nop,TS val 1425957875 ecr 2534960336], length 0
E..4..@.?.fE..yX..yx.....J.I2.......K......
T.c...l.
04:27:20.933916 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40126 > helloworld-nomtls-66d8499c5c-298vw.https: Flags [P.], seq 0:517, ack 1, win 507, options [nop,nop,TS val 1425957876 ecr 2534960336], length 517
E..9..@.?.d?..yX..yx.....J.I2.......M......
T.c...l..............#.."H..\..\A*...5.../m.....wV. ;.......>..`..k.t.b.O.U
e(?.X...........+.../...,.0..............
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... J7.y.............
..<.Ma.v}.*3LI.-.....+........................)......./.....`.............3.. .[....N.,......i.9;.9V9A..1..J.......W.....o.%.%.<uep.Z"X...6...;|.........f.5AyieJ...+..q...T......x....jO.T$.D!x.pe.....D,.P1.. .a..t..r.x#.J.z...y.q...i:....43..3[/;..P0..\*>#ev..f.....! ........FHc..r...6...e.'J.&..T.p
04:27:20.937464 IP 172-17-1
```
### mTLS enabled
#### HTTP
##### Start the packet capture for the port 80
```shell
PORT=80 && MTLS="true" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
We can access the service.
```shell
curl 192.168.1.50/http-mTLS
```
```text
<h2>Howdy</h2>
```
##### Reviewing pcap output
Due to mTLS being enabled, the traffic captured is encrypted, and for such we cannot explore the contents of such.
We can notice the following lines `outbound_.8080_.mtls_.helloworld.default.svc.cluster.local`, and further deep in the sea of text `1.1.istio.http/1.1` referring that `mTLS` termination was performed through the HTTP version `HTTP1.1`.
```text
04:21:48.543118 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [S], seq 4217286528, win 64800, options [mss 1440,sackOK,TS val 1478647369 ecr 0,nop,wscale 7], length 0
E..<..@.>..x..yX...,. .P.^......... ...........
X"^I........
04:21:48.544529 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [.], ack 3797925086, win 507, options [nop,nop,TS val 1478647370 ecr 861329182], length 0
E..4..@.>.....yX...,. .P.^..._.............
X"^J3V..
04:21:48.545045 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 0:2216, ack 1, win 507, options [nop,nop,TS val 1478647371 ecr 861329182], length 2216: HTTP
E.....@.>.....yX...,. .P.^..._.......v.....
X"^K3V................~5pO...T`.|..{. .........Q..e .}..,....q...n....=...'.a7....=r.........+.../...,.0...D...?.=..:outbound_.8080_.mtls_.helloworld.default.svc.cluster.local..........
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... #.g....m............l....`.KE.>J.-.....+........).k.F.@O..)z.l.....8b......}.2....77.?.......J..T0....]..\....R.W.]....x..W....;.[....x...."Wy.Q.{.c.Fo..W%7....
. .].m..>......2\V._(&........;.....&K.b..};R.._A.$)s....2.gC.....d..>Q.x{.uw...s....<|O.:T...d.........j..O...d2..;...S.&. s.l..v..G........B..|g..!....@6fdG..]....=e..>.2..*}%*..>..u..y.B....vq99:....IT..)I5........`......BG...[5m.../7..
v........R.1...l.S2W{M.7.._w..D....j.,.....O-;6.q....<..P....s
..0..:.....Oq..cX..=.k`Q.X.x.E.E`T.<...Y..tPG.:..z.#p.)$..)@...W..g]Q..W......I..:....~..... .....;Y.YG....+.o.,.....8t...l.q.&.........1..w.{.[.U..B...]a up..8:\....:5......../o.5..[.,+xA(.........
...`.M...>...mor.o........`x\.1......:..s.h..r....Mm*..w.Q. ..d..W..&..0[bi.u.F}4...SP=....j\.H._1....6..f....=.\.$.. pD1.6@.>..4YT.D..e".}=.c..,O..M.eC*?...w..R..LZ..f.._.q..bR.t.-I..=,....%"...*...].m..d5..W...3.k...k.s...[ANc._.....V ...z._.b{I...(r.)..v......H.?......*|./h A|.l.(2..&-..} ...V....D..........g.vA.P/@...._`...M...}..}kF..g.,.rs7...^.0.:W"....8.(.Rr.O{..#I.d.CL....(.D.....L..4..)I3.F.l..kD..`.x<8Z.`..a'.u.
_.^RMn.w.. ..?y...R.T.P.c...9...Q.....w.._.T..;...... .l...?..w!.T.._.,...p
..I.zG....x.^p.........X......7v.'.pp..u....ab^Q_
pS.........B...6....s;......
. ..Q....nRw.\HG.H]......l.....G._..4% .{.<...a..p.5\...0......86..Al........&..;....\.V....d.U.......-.Y.<WH...^..."4..... .._ .ov....V....;.h..d.C.0.&.3...s...-....9.....>....B..v.9...k...]S.)....V]C8.<....0..V..fP.oe..{........ .....8:.{tU..`]...@_.H.t.a...9.}......eE...F..6........!S=....)..W4.;...?..C.... ....t.D..IU....RU.X'V.....t...M.j.'-...^p..1...S.9. ...o.J..8v..C2..%..d.T..GU..-.?...F"`....z.../........s.N....$I..F'0....#........B.4..S.M...#..)...Sx.....E....f.).....m.k.G1..I..$=.Q..^n.[..tn..y4.g.}.7...&..}..JXRk..<...S%r..."]#.......O..;.Rt......2.v..~e.E.{t.F.b...4..-:......6..CrE#.....^]~.k5.@..*.^.K..G.k..(dc.#L..z...L..8..._........d..gXl.......! |r?....%Z&!]n....C7...c.([6u....
04:21:48.550098 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [.], ack 219, win 506, options [nop,nop,TS val 1478647376 ecr 861329188], length 0
E..4..@.>..|..yX...,. .P.^.)._.............
X"^P3V.$
04:21:48.551427 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 2216:2280, ack 219, win 506, options [nop,nop,TS val 1478647378 ecr 861329188], length 64: HTTP
E..t..@.>..;..yX...,. .P.^.)._.......7.....
X"^R3V.$..........5k)...o...^D......3..........WC.|...@...zwS...z.@yA.c
04:21:48.551870 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.40224 > helloworld-mtls-7998d9646b-sv7hp.http: Flags [P.], seq 2280:3959, ack 219, win 506, options [nop,nop,TS val 1478647378 ecr 861329188], length 1679: HTTP
E.....@.>.....yX...,. .P.^.i._.......].....
X"^R3V.$......zb5...o.....x.....a..-....B^4...K.m.
..Z..z..(.f3aG......r...$9
```
#### HTTPS
##### Start the packet capture for the port 443
```shell
PORT=443 && MTLS="true" && kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -l mtls=${MTLS} -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port ${PORT} -A
```
```text
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
```
##### Curl
On this scenario, we met a fatal error, not allowing us to access the service, unlike the previous attempts.
From my understanding, not only from this interaction, but from investigating through Istio forums (yet I don't have the link handy, so take this words with some grains of salt), **the traffic cannot be double terminated**, for such if we have an `HTTPS` backend, we might require to disable `mTLS` in order to communicate with it. We also would need to set a [Destination Rule like we did further above](#destination-rule), to specify that the traffic must be terminated with the backend (`tls.mode: STRICT`).
Yet this depends on which would be our architecture, due also being able to set up [TLS Passthrough](../../02-Traffic_management/11-TLS-PASSTHROUGH), or use a [TCP Forwarding](../../02-Traffic_management/10-TCP-FORWARDING).
```shell
curl 192.168.1.50/https-mTLS
```
```text
upstream connect error or disconnect/reset before headers. reset reason: connection termination
```
##### Reviewing pcap output
Not much to highlight as there isn't much available text for us to be able to read.
```text
04:22:15.813163 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [S], seq 693161527, win 64800, options [mss 1440,sackOK,TS val 1478674639 ecr 0,nop,wscale 7], length 0
E..<..@.>.}Z..yX...,....)P.7....... ...........
X"..........
04:22:15.814619 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 609580424, win 507, options [nop,nop,TS val 1478674641 ecr 861356452], length 0
E..4..@.>.}a..yX...,....)P.8$Uu......x.....
X"..3WA.
04:22:15.815126 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 0:246, ack 1, win 507, options [nop,nop,TS val 1478674641 ecr 861356452], length 246
E..*..@.>.|j..yX...,....)P.8$Uu............
X"..3WA.............#j..S..(.j....4\v.h_ N......S.O e....U.....oM.j.....l...t......T.........+.../...,.0..............
...............#..... ...istio-http/1.1.istio.http/1.1.........................3.&.$... ..t.i.=..1...[i..
FQF.....8d..}..-.....+.......
04:22:15.831747 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 2165, win 499, options [nop,nop,TS val 1478674658 ecr 861356470], length 0
E..4..@.>.}_..yX...,....)P..$U}............
X"..3WA.
04:22:15.834886 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 246:318, ack 2165, win 501, options [nop,nop,TS val 1478674661 ecr 861356470], length 72
E..|..@.>.}...yX...,....)P..$U}.....+......
X"..3WA...........=d..Vv.s..."..Dc.p...T...s...3........i.'-Sc..0p|)...!. T~...)
04:22:15.835307 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [P.], seq 318:1999, ack 2165, win 501, options [nop,nop,TS val 1478674661 ecr 861356470], length 1681
E.....@.>.v...yX...,....)P.v$U}......_.....
X"..3WA.......7..t...*.U.....,...]...l..=.x....jH..*......[..._...._..l..+......T..9.}$CO.[...b.Fx0...X.2.......V.U.%.^.%.}?... ...$..G.\0G..=.9.X....jA...ks^r.H.*H.....2H........Im
...........@..D!O0...a..G.i/1..W-.....A..yd..`...h.'Y...&.Po..T.4..B........$..t...M.....D..Y..6z.....8I-....e.3.....4.$Y.C_R...'V......C...&.\....."...U.[T....nW..}......!......L..j..ov...~.....r..
B..B.gRp
R..xLTm..af_.X.2.......|.,.Wi.....F@.0.'...
.>.8.'t.....r.Xi....#*..l.bO.V.......G.[:....7.2.(U....R,#.>!..<.o..w..R|.T..:_..i.. iJs.-.>...B..~.mOH0+N.....-.b...5.._.9%....u&..y.S...8A...*.=....MJS.m........u..Ic....s}Y....{.8d.....<..P-;V[......\.....+..S.8k..r&...dT..K..y].t..3..BU,.<......:IH......-..\j.g...\:..[........(.S......"..0|-.p"Z..:..>6..b..x.....M..;K2AT|Ah.....3z.+..><.&........)E.C ..4....X1.p} .@...@n.........\..R...H........5...+h-...q.|.(....]o.. jw..(....=..
..+(nY{......6..@..c.^.........o..:.V|..0.... N*..e*...G.,{...wb...-y..g.k7...,tI.|..........H....4E.2..!b........K..&q1..0.us|z...he/.T+6b.}.L........q...F....nTs.Vp!.........W.F..j...X
./.gIv..6G(Ze.h`.......<..w...........@!E..N.>..^.[..IO$T.]6.D..K%m.....LD @.
.......f!O....5 ...K...Y..}.I.o.]q0`..H&...d.aZ.1...P.......R.. C.jfM....;9........y.h.E)...r.....B....#.\......Q..fX..~....ixh ..t.q.y....BkR.nr.k5.`@.8..Z5_Gl.l.
...'t....q...... ....t8......_`.....:4>.H....S.e/=!.V.. .6...X.o..K.H...S@.3...a.....].j-.$Q.6..{..kr.....=a.....-.......-2....D.....&......:..y.DJQ.0....E....,Uc......H..6.`.u.....).f..R.xp.H....(.c.9..a.*.P$d..KD..;.x.$,....L.......`..x...p.[..d...z.,jV.[0....j.r."\..._....[......].o..5.Q*.Y.....b0.......-..B...^..)9....S.l...Ek?..~9......`....^...../G{Q14......7......SVV.A.>8..].
04:22:15.835726 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.50576 > helloworld-mtls-7998d9646b-sv7hp.https: Flags [.], ack 2189, win 501, options [nop,nop,TS val 1478674662 ecr 861356474], length 0
E..4..@.>.}[..yX...,....)P..$U~............
X"..3WA.
04:22:15.835912 IP 172-17-121-88.istio-ingressgateway.istio-system.svc.cluster.local.505
```
## Cleanup
```shell
kubectl delete -f ./
```
```text
service "helloworld" deleted
peerauthentication.security.istio.io "disable-mtls" deleted
peerauthentication.security.istio.io "force-mtls" deleted
deployment.apps "helloworld-mtls" deleted
deployment.apps "helloworld-nomtls" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld.default.svc.cluster.local" deleted
```
# Links of Interest
- https://istio.io/latest/docs/reference/config/security/peer_authentication/#PeerAuthentication-MutualTLS-Mode
- https://istio.io/latest/docs/tasks/security/authentication/mtls-migration/
- https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication
- https://istio.io/latest/docs/reference/config/security/peer_authentication/

View File

@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http
targetPort: 80
protocol: TCP
appProtocol: http
- port: 8443
name: https
targetPort: 443
protocol: TCP
appProtocol: https
selector:
app: helloworld
---

View File

@ -0,0 +1,25 @@
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: disable-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "false"
mtls:
mode: DISABLE
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: force-mtls
namespace: default
spec:
selector:
matchLabels:
app: helloworld
mtls: "true"
mtls:
mode: STRICT

View File

@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-mtls
labels:
app: helloworld
mtls: "true"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "true"
template:
metadata:
labels:
app: helloworld
mtls: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-nomtls
labels:
app: helloworld
mtls: "false"
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
mtls: "false"
template:
metadata:
labels:
app: helloworld
mtls: "false"
spec:
containers:
- name: helloworld-nomtls
image: oriolfilter/https-nginx-demo
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,100 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-mTLS
match:
- port: 80
uri:
exact: "/http-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: mtls
rewrite:
uri: "/"
- name: https-mTLS
match:
- port: 80
uri:
exact: "/https-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: mtls
rewrite:
uri: "/"
- name: http-no-mTLS
match:
- port: 80
uri:
exact: "/http-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
subset: nomtls
rewrite:
uri: "/"
- name: https-no-mTLS
match:
- port: 80
uri:
exact: "/https-no-mTLS"
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
subset: nomtls
rewrite:
uri: "/"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld.default.svc.cluster.local
spec:
host: helloworld.default.svc.cluster.local
subsets:
- name: mtls
labels:
mtls: "true"
- name: nomtls
labels:
mtls: "false"
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
mode: SIMPLE # Required for https backend
---

Some files were not shown because too many files have changed in this diff Show More