Compare commits

..

No commits in common. "5e0abdebd4da97f6b10eea8d34279f9e9867928c" and "4bb07eebce9494d6694eea2619a5961be26ddf86" have entirely different histories.

48 changed files with 2269 additions and 1313 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/.idea/
/Istio/02-Traffic_management/XX-HTTPS-backend/

View File

@ -3,6 +3,8 @@ gitea: none
include_toc: true
---
# Istioctl analyze
`istioctl analyze` reviews the current configuration set.
@ -48,16 +50,13 @@ istioctl analyze
Warning [IST0104] (Gateway default/helloworld-gateway) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 81)
```
# Start the packet capture process on the istio-proxy container from a pod.
Target a pod and start a packet capture on the istio-proxy container.
This step requires istio to be installed with the flag `values.global.proxy.privileged=true`
This is very useful to confirm if the service is receiving any traffic, or which is the traffic received.
If mTLS is enabled and configured, the traffic received should be encrypted.
```shell
$ kubectl exec -n default "$(kubectl get pod -n default -l app=helloworld -o jsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80 -A
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode

View File

@ -107,7 +107,7 @@ helloworld-nginx 1/1 1 1 44s
### Get LB IP
```shell
$ kubectl get svc -l istio=ingressgateway -A
$ 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
```

View File

@ -176,6 +176,4 @@ 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
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol

View File

@ -15,8 +15,6 @@ The previous example was modified to limit and specify the maximum TLS version.
## Gateway
Gateway has been modified to limit the maximum TLS version to v1.2.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
@ -38,6 +36,7 @@ spec:
maxProtocolVersion: TLSV1_2
```
Gateway has been modified to limit the maximum TLS version to v1.2.
# Walkthrough
@ -173,6 +172,4 @@ 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
- https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings-TLSProtocol

View File

@ -1,343 +0,0 @@
---
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-apache-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).
## Virtual service
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](#virtual%20service) 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-apache-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](#destination%20rule) 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-Internal-Authentication/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
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
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode

View File

@ -1,43 +0,0 @@
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

@ -1,57 +0,0 @@
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

@ -1,240 +0,0 @@
---
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-apache-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-apache-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

@ -1,45 +0,0 @@
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

@ -1,220 +0,0 @@
---
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-apache-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-apache-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

@ -1,73 +0,0 @@
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

@ -1,37 +0,0 @@
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,304 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified set the gateway to enable for HTTP2 traffic.
https://stackoverflow.com/a/59610581
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http2
protocol: HTTP2
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
```
`<text>`
# 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
### http2
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http2
```
```text
http_version: 1.1
status_code: 200
```
### http1-web
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2
```
```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/#ServerTLSSettings-TLSProtocol
- https://stackoverflow.com/a/51279606
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-HTTPSettings-H2UpgradePolicy
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest -f Dockerfile
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest .
[+] Building 0.0s (0/0)
ERROR: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
---
## Create the Dockerfile
```bash
FROM ubuntu/apache2
RUN apt-get update && \
apt-get install apache2 openssl -y && \
a2ensite default-ssl && \
a2enmod ssl && \
echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN /usr/bin/printf "<VirtualHost *:80>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
</VirtualHost>\n\
<VirtualHost *:443>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
SSLEngine on\n\
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem\n\
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\
</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE' -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem
```
## Build the image
Due to my Kubernetes cluster environment, where I am using Orange 5, their architecture is arm7, and for such, I require to compile such images.
For my own commodity, I have used a raspberry pi 4 to build this images.
The images where pushed to a local registry server, and afterwards the Kubernetes cluster will pull such image.
```shell
docker build --tag https-demo:armv7 .
```
```text
docker build --tag https-demo:armv7 . --no-cache
[+] Building 16.5s (8/8) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.09kB 0.0s
=> [internal] load metadata for docker.io/ubuntu/apache2:latest 0.4s
=> CACHED [1/4] FROM docker.io/ubuntu/apache2@sha256:0a5e7179fa8fccf17843a8862e58ac783628b7d448cd68fda8fb1e 0.0s
=> [2/4] RUN apt-get update && apt-get install apache2 openssl -y && a2ensite default-ssl && a2enmod ssl & 12.0s
=> [3/4] RUN /usr/bin/printf "<VirtualHost *:80>\n ServerAdmin webmaster@localhost\n DocumentRoot /var/www/ 0.7s
=> [4/4] RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE' -newkey rsa:2048 -keyout 2.4s
=> exporting to image 1.0s
=> => exporting layers 1.0s
=> => writing image sha256:591c6d233100a48bf132eef7a792942cfd0b7057817c4ac5e156c1d33e24cd89 0.0s
=> => naming to docker.io/library/https-demo:armv7 0.0s
```
## Tag the image
```shell
docker image tag https-demo:armv7 registery.filter.home/https-demo:armv7
```
## Upload to the registery server
```text
docker image push registery.filter.home:5000/https-demo:armv7
The push refers to repository [registery.filter.home:5000/https-demo]
c6d858706b08: Pushed
9e077e0202f0: Pushed
6ffc708d0cf3: Pushed
69e01b4bf4d7: Pushed
17c5b30f3843: Pushed
0b9f60fbcaf1: Pushed
armv7: digest: sha256:d8c81c27f23bf3945ae8a794c82182f9e6c48ec927f388fdf4a88caa0e284bd1 size: 1578
```
## ?
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version numbe
---
Has apache2 installed with a default certificate.
Port 80 visible for HTTP
Port 443 visible for HTTPS.

View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDPTCCAiWgAwIBAgIUNR/VCRO6PPCYDZKIApOQ4n/d7OUwDQYJKoZIhvcNAQEL
BQAwLjEbMBkGA1UECgwSSW50ZXJuZXQgb2YgdGhpbmdzMQ8wDQYDVQQDDAZsYi5u
ZXQwHhcNMjMwNDIzMjI1NjE5WhcNMjQwNDIyMjI1NjE5WjAuMRswGQYDVQQKDBJJ
bnRlcm5ldCBvZiB0aGluZ3MxDzANBgNVBAMMBmxiLm5ldDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKKEn3TzyYjW3W/MLKCd18ygojKWgN12gxNxZcQF
BvghPTNsESt+aBuI1N1Xzj+Bvxs5Bs4FVcMXAkOmLtvwbd6A9owZwd8E9ODKrhau
Uk9eNQf6ZvSF2GeQoI39SFCL2NEKOzMmEYxGlf842yFaSxgrMx2GirSsqEEPhstS
LAEldjU77pQ9OniIHuYLfA6AamAz51hXPytpGiaRqAm/xIvRtPFuA9pXJHhREtUG
S/O6P2v980YAuP8hl3LIpOM9xUod4+x9EHfBXHI5iuPET5kjCnIF/45UmKPtwsga
RUN3fqYAknJSPyI+s+xnxulkxM9A1kmP8MvDeO/4hAMSA1MCAwEAAaNTMFEwHQYD
VR0OBBYEFACskVXLguvAreQgdla3hoZqlcxMMB8GA1UdIwQYMBaAFACskVXLguvA
reQgdla3hoZqlcxMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
AI3SNO84LwluCbTMBYthD+5cMnC6rARyrJBwkYoJfCqgu6j/h8Lcou5VSYVOR4J5
R3DiyTFutBKYnifnuZgHjNioI6l/uFphPRmoeH1I5zKghq5P2x6LE/Z6/0alzN9X
ZBgYPWQ5wenrilQ94yLJXX2kwgK5jbMinmTzw8SFHe+Qn5ZlJnAW+YR8vJ+Nu30Q
rhxSxbNqa2yFPOkV4qjc4zkJ+67bKv7yLJ5WKF6Mfafct69FBwSVVCROsY5mHg8c
xMyP3d6N01R7XXJATEHbyJHvUUXBtLgA41H8g3vwj1ugKdBhWijBeeBZEyz11U20
0j6OhMfBuYikiRQl1dfZltg=
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCihJ9088mI1t1v
zCygndfMoKIyloDddoMTcWXEBQb4IT0zbBErfmgbiNTdV84/gb8bOQbOBVXDFwJD
pi7b8G3egPaMGcHfBPTgyq4WrlJPXjUH+mb0hdhnkKCN/UhQi9jRCjszJhGMRpX/
ONshWksYKzMdhoq0rKhBD4bLUiwBJXY1O+6UPTp4iB7mC3wOgGpgM+dYVz8raRom
kagJv8SL0bTxbgPaVyR4URLVBkvzuj9r/fNGALj/IZdyyKTjPcVKHePsfRB3wVxy
OYrjxE+ZIwpyBf+OVJij7cLIGkVDd36mAJJyUj8iPrPsZ8bpZMTPQNZJj/DLw3jv
+IQDEgNTAgMBAAECggEAB33Pj+eQ+bLV4EpsIDdGdFNPRr+zTwIghqvqgf+tU5DM
rmsj23pnOCW1kkJy6nCDq7CURLjwPB76Zr3pWRAbMG+HbeveCPbEhvwwzDDa8Heq
QCTlzA3DbPq4u/LZ+4SGyRQMqI3vrySt02b+iuoLniCXqZvDFxMCaoVZtFOkXaUW
mYVkW3BtLdIqHUolql9Tt6kPf9Es7AQhce1ZGrvRSxhiG8xRU4Fmb5zRPXAd/Uzj
RHzJtcHTFbhjWn/fngtxVUdBNqSNx5z8Bhtex39hgWwULuAyf6jSQbwLtURdyuR8
WlaJjIV5uZ6ghkQ0mTWyEivuQzuaEUxOND05HgPi8QKBgQDXf8uZSZoCitjHCZ1i
1O1Xh40qzYYY6KrMc+rzA3BGsgLmQRw5oj0JlhlAPUjh7RmDz6nMEZpUJgKDtyvt
ktJz28l9ybF5qVjjHz1ZBHxaPC/bruO+4mUsYN6bK4tcIm0j6huuSO7igs7I33ZA
9bcLkUTtV4QmcKHhIu2UfLVR+QKBgQDBD8XC9alaJHuSjCizPQyrCmmgFHZqNMG9
IFKOtxXIAX5fJ8RZGyTfObuw2DJncsRGjX6XWr3xo91P/h0sF87FYQ92qz8ji6cg
rZ+rD9LY6DaVpAB+i0h97PAEgKwkFhXbuTEVDUCY8yFvwz4OGBeKTq19DrMgdeCj
tAIXq+bSqwKBgAPyIxg7cMZ7JF0AoBEfNPlVUhBmkv4BxJ7ZwIOSnIuu1r7AknO7
tMJoLS4v8RWx8bWoJ8PEzr6bs5AV2ogPGCtm6tmSx90ibK479DOdEWnVkErFeQYV
vySA4ZKVyYd2Wek+cCNQ0o7zNjYXYWLvHNrpXgm6gIDzrwMgUJlXbzqBAoGANZEy
xg1zl9dXkinhgRoHUc3p0MjcsktBFkDJp1+VY5FGhxB5ol+ts2JJeaADHEDzxL+t
yEEdQta8qV1QqtNQQ+PSbpLFSg+Np7uE+enCDv0faBXBLVtoGciMMDOjj7+xAO45
eCXdLpMHTANYTIDSx0VdTb2uZetPERz5F6hSu1ECgYAvBqCirwy2HHNuRD7KqpaF
vyiwIPRj4PK8z0IF4KAEgI9+WWyXLFi7QV3J1PErLlFzc6YW1Z427lfsgGZ9wBXy
D6Gk7u08FSU+5lyO+X43wlj+XefRFo7AVA52iYSNlz7WS618AYLJyWC4xBt6Ya/Z
49OKVGZRjHierSA2yZl5fQ==
-----END PRIVATE KEY-----

View File

@ -8,11 +8,12 @@ metadata:
spec:
ports:
- port: 8080
name: http-web
name: tcp-a
targetPort: 80
protocol: TCP
- port: 8443
name: https-web
name: tcp-b
targetPort: 443
protocol: TCP
selector:
@ -33,14 +34,16 @@ spec:
metadata:
labels:
app: helloworld
sidecar.istio.io/inject: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
# image: nginx
image: oriolfilter/https-apache-demo:armv7
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 80
- containerPort: 443

View File

@ -0,0 +1,83 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
# - port:
# number: 443
# name: secure-http2
# protocol: HTTP2
# hosts:
# - "*"
- port:
number: 80
name: tcp-2
protocol: TCP
hosts:
- "*"
- port:
number: 443
name: tcp-i
protocol: TCP
hosts:
- "*"
# tls:
# credentialName: my-tls-cert-secret
# minProtocolVersion: TLSV1_2
# mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- port: 80
# hosts:
# - "hello.si"
name: helloworld
route:
- destination:
host: helloworld
port:
number: 80
tcp:
- match:
- port: 80
route:
- destination:
host: helloworld
port:
number: 8080
- match:
- port: 443
route:
- destination:
host: helloworld
port:
number: 8443
#
# tls:
# - match:
# - port: 443
# sniHosts:
# - "hello.si"
## - uri:
## exact: /helloworld
# route:
# - destination:
# host: helloworld
# port:
# number: 8443
## protocol: HTTPS
## rewrite:
## uri: "/"

View File

@ -2,6 +2,11 @@ FROM nginx
ADD server.conf /etc/nginx/conf.d/default.conf
# RUN apt-get update && \
# apt-get install apache2 openssl -y && \
# a2ensite default-ssl && \
# a2enmod ssl && \
RUN mkdir -p /var/www/html
RUN echo "<h2>Howdy</h2>" | tee /var/www/html/index.html

View File

@ -40,7 +40,7 @@ spec:
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
image: oriolfilter/https-apache-demo:armv7
resources:
requests:
cpu: "100m"

View File

@ -1,5 +1,6 @@
server {
listen 80;
# rewrite ^ https://$server_name$request_uri? permanent;
server_name lb.net;

View File

@ -0,0 +1,311 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified set the gateway to enable for HTTP2 traffic.
https://stackoverflow.com/a/59610581
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http2
protocol: HTTP2
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
```
`<text>`
# 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
### http2
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http2
```
```text
http_version: 1.1
status_code: 200
```
### http1-web
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2
```
```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/#ServerTLSSettings-TLSProtocol
- https://stackoverflow.com/a/51279606
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-HTTPSettings-H2UpgradePolicy
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest -f Dockerfile
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest .
[+] Building 0.0s (0/0)
ERROR: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
---
## Create the Dockerfile
```bash
FROM ubuntu/apache2
RUN apt-get update && \
apt-get install apache2 openssl -y && \
a2ensite default-ssl && \
a2enmod ssl && \
echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN /usr/bin/printf "<VirtualHost *:80>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
</VirtualHost>\n\
<VirtualHost *:443>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
SSLEngine on\n\
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem\n\
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\
</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem
```
## Build the image
Due to my Kubernetes cluster environment, where I am using Orange 5, their architecture is arm7, and for such, I require to compile such images.
For my own commodity, I have used a raspberry pi 4 to build this images.
The images where pushed to a local registry server, and afterwards the Kubernetes cluster will pull such image.
```shell
docker build --tag https-demo:armv7 .
```
```text
docker build --tag https-demo:armv7 . --no-cache
[+] Building 16.5s (8/8) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.09kB 0.0s
=> [internal] load metadata for docker.io/ubuntu/apache2:latest 0.4s
=> CACHED [1/4] FROM docker.io/ubuntu/apache2@sha256:0a5e7179fa8fccf17843a8862e58ac783628b7d448cd68fda8fb1e 0.0s
=> [2/4] RUN apt-get update && apt-get install apache2 openssl -y && a2ensite default-ssl && a2enmod ssl & 12.0s
=> [3/4] RUN /usr/bin/printf "<VirtualHost *:80>\n ServerAdmin webmaster@localhost\n DocumentRoot /var/www/ 0.7s
=> [4/4] RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE' -newkey rsa:2048 -keyout 2.4s
=> exporting to image 1.0s
=> => exporting layers 1.0s
=> => writing image sha256:591c6d233100a48bf132eef7a792942cfd0b7057817c4ac5e156c1d33e24cd89 0.0s
=> => naming to docker.io/library/https-demo:armv7 0.0s
```
## Tag the image
```shell
docker image tag https-demo:armv7 registery.filter.home/https-demo:armv7
```
## Upload to the registery server
```text
docker image push registery.filter.home:5000/https-demo:armv7
The push refers to repository [registery.filter.home:5000/https-demo]
c6d858706b08: Pushed
9e077e0202f0: Pushed
6ffc708d0cf3: Pushed
69e01b4bf4d7: Pushed
17c5b30f3843: Pushed
0b9f60fbcaf1: Pushed
armv7: digest: sha256:d8c81c27f23bf3945ae8a794c82182f9e6c48ec927f388fdf4a88caa0e284bd1 size: 1578
```
## ?
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version numbe
---
Has apache2 installed with a default certificate.
Port 80 visible for HTTP
Port 443 visible for HTTPS.
curl https://192.168.1.2:8443 -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2 -k
http_version: 2
status_code: 200

View File

@ -8,10 +8,10 @@ metadata:
spec:
ports:
- port: 8080
name: http
name: http-s
targetPort: 80
protocol: TCP
appProtocol: http
appProtocol: HTTP
- port: 8443
name: https
@ -40,7 +40,7 @@ spec:
spec:
containers:
- name: helloworld
image: oriolfilter/https-nginx-demo
image: oriolfilter/https-apache-demo:armv7
resources:
requests:
cpu: "100m"
@ -68,6 +68,7 @@ spec:
app: nginx
version: v1
spec:
# serviceAccountName: istio-helloworld
containers:
- name: nginx
image: nginx

View File

@ -0,0 +1,118 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
# istio: myingressgateway
istio: ingressgateway
servers:
# - port:
# number: 443
# name: secure-http2
# protocol: HTTP2
# hosts:
# - "*"
- port:
number: 80
name: http2-i
protocol: HTTP2
hosts:
- "*"
- port:
number: 443
name: https-i
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
#
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- name: http-vs
match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
- name: https-vs
match:
- 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: 8080
tls:
mode: DISABLE
- port:
number: 8443
tls:
# credentialName: client-credential
mode: SIMPLE
# port:
# name: https-backend
# number: 8443
# protocol: HTTPS
# tls:
# credentialName: my-tls-cert-secret
# mode: SIMPLE
# tcp:
## - match:
## - port: 80
## route:
## - destination:
## host: helloworld
## port:
## number: 8080
## - match:
## - port: 443
# - route:
# - destination:
# host: helloworld
# port:
# number: 8443
#
# tls:
# - match:
# - port: 443
# sniHosts:
# - "hello.si"
## - uri:
## exact: /helloworld
# route:
# - destination:
# host: helloworld
# port:
# number: 8443
## protocol: HTTPS
## rewrite:
## uri: "/"

View File

@ -0,0 +1,13 @@
FROM nginx
ADD server.conf /etc/nginx/conf.d/default.conf
# RUN apt-get update && \
# apt-get install apache2 openssl -y && \
# a2ensite default-ssl && \
# a2enmod ssl && \
RUN mkdir -p /var/www/html
RUN echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /cert.key -out /cert.crt

View File

@ -0,0 +1,325 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified set the gateway to enable for HTTP2 traffic.
https://stackoverflow.com/a/59610581
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http2
protocol: HTTP2
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
```
`<text>`
# 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
### http2
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http2
```
```text
http_version: 1.1
status_code: 200
```
### http1-web
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2
```
```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/#ServerTLSSettings-TLSProtocol
- https://stackoverflow.com/a/51279606
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-HTTPSettings-H2UpgradePolicy
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest -f Dockerfile
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest .
[+] Building 0.0s (0/0)
ERROR: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
---
## Create the Dockerfile
```bash
FROM ubuntu/apache2
RUN apt-get update && \
apt-get install apache2 openssl -y && \
a2ensite default-ssl && \
a2enmod ssl && \
echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN /usr/bin/printf "<VirtualHost *:80>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
</VirtualHost>\n\
<VirtualHost *:443>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
SSLEngine on\n\
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem\n\
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\
</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem
```
## Build the image
Due to my Kubernetes cluster environment, where I am using Orange 5, their architecture is arm7, and for such, I require to compile such images.
For my own commodity, I have used a raspberry pi 4 to build this images.
The images where pushed to a local registry server, and afterwards the Kubernetes cluster will pull such image.
```shell
docker build --tag https-demo:armv7 .
```
```text
docker build --tag https-demo:armv7 . --no-cache
[+] Building 16.5s (8/8) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.09kB 0.0s
=> [internal] load metadata for docker.io/ubuntu/apache2:latest 0.4s
=> CACHED [1/4] FROM docker.io/ubuntu/apache2@sha256:0a5e7179fa8fccf17843a8862e58ac783628b7d448cd68fda8fb1e 0.0s
=> [2/4] RUN apt-get update && apt-get install apache2 openssl -y && a2ensite default-ssl && a2enmod ssl & 12.0s
=> [3/4] RUN /usr/bin/printf "<VirtualHost *:80>\n ServerAdmin webmaster@localhost\n DocumentRoot /var/www/ 0.7s
=> [4/4] RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE' -newkey rsa:2048 -keyout 2.4s
=> exporting to image 1.0s
=> => exporting layers 1.0s
=> => writing image sha256:591c6d233100a48bf132eef7a792942cfd0b7057817c4ac5e156c1d33e24cd89 0.0s
=> => naming to docker.io/library/https-demo:armv7 0.0s
```
## Tag the image
```shell
docker image tag https-demo:armv7 registery.filter.home/https-demo:armv7
```
## Upload to the registery server
```text
docker image push registery.filter.home:5000/https-demo:armv7
The push refers to repository [registery.filter.home:5000/https-demo]
c6d858706b08: Pushed
9e077e0202f0: Pushed
6ffc708d0cf3: Pushed
69e01b4bf4d7: Pushed
17c5b30f3843: Pushed
0b9f60fbcaf1: Pushed
armv7: digest: sha256:d8c81c27f23bf3945ae8a794c82182f9e6c48ec927f388fdf4a88caa0e284bd1 size: 1578
```
## ?
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version numbe
---
Has apache2 installed with a default certificate.
Port 80 visible for HTTP
Port 443 visible for HTTPS.
curl https://192.168.1.2:8443 -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2 -k
http_version: 2
status_code: 200
# Recv failure: Connection reset by peer
```shell
kubectl apply -f ./
```
```shell
curl --insecure --resolve lb.net:80:192.168.1.50 http://lb.net
```
```shell
curl --insecure --resolve lb.net:443:192.168.1.50 https://lb.net
```

View File

@ -6,3 +6,6 @@ metadata:
spec:
mtls:
mode: DISABLE
#curl -v --resolve ":$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert example_certs/example.com.crt "https://nginx.example.com:$SECURE_INGRESS_PORT"

View File

@ -0,0 +1,113 @@
#apiVersion: networking.istio.io/v1alpha3
#kind: Gateway
#metadata:
# name: helloworld-gateway
#spec:
# selector:
## istio: myingressgateway
# istio: ingressgateway
# servers:
# - hosts:
# ["lb.net","*.lb.net"]
# port:
# name: tls-443
# number: 443
# protocol: HTTPS
# tls:
# mode: SIMPLE
# credentialName: my-tls-cert-secret
# minProtocolVersion: TLSV1_2
#---
#apiVersion: networking.istio.io/v1alpha3
#kind: VirtualService
#metadata:
# name: helloworld-vs
#spec:
# hosts:
# - "*"
# gateways:
# - helloworld-gateway
# http:
## - name: http-vs
## match:
## - port: 80
## route:
## - destination:
## host: helloworld.default.svc.cluster.local
## port:
## number: 8080
# - name: https-vs
# match:
# - port: 443
# route:
# - destination:
# host: helloworld.default.svc.cluster.local
# port:
# number: 443
##
## tls:
## - match:
## - port: 443
## sniHosts: ["lb.net"]
## route:
## - destination:
## host: helloworld.default.svc.cluster.local
## port:
## number: 443
##---
##apiVersion: networking.istio.io/v1alpha3
##kind: DestinationRule
##metadata:
## name: helloworld
## namespace: default
##spec:
## host: helloworld.default.svc.cluster.local
## trafficPolicy:
## portLevelSettings:
## - port:
## number: 8080
## tls:
## mode: DISABLE
## - port:
## number: 8443
## tls:
## credentialName: client-credential
## mode: SIMPLE
## port:
## name: https-backend
## number: 8443
## protocol: HTTPS
## tls:
## credentialName: my-tls-cert-secret
## mode: SIMPLE
## tcp:
### - match:
### - port: 80
### route:
### - destination:
### host: helloworld
### port:
### number: 8080
### - match:
### - port: 443
## - route:
## - destination:
## host: helloworld
## port:
## number: 8443
##
## tls:
## - match:
## - port: 443
## sniHosts:
## - "hello.si"
### - uri:
### exact: /helloworld
## route:
## - destination:
## host: helloworld
## port:
## number: 8443
### protocol: HTTPS
### rewrite:
### uri: "/"

View File

@ -0,0 +1,80 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 8080
name: http-s
targetPort: 80
protocol: TCP
appProtocol: HTTP
- 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
sidecar.istio.io/inject: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-apache-demo:armv7
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,36 @@
#apiVersion: networking.istio.io/v1beta1
#kind: Gateway
#metadata:
# name: helloworld-gateway
#spec:
# selector:
# istio: ingressgateway
# servers:
# - hosts:
# - "*"
# port:
# name: https
# number: 443
# protocol: HTTPS
# tls:
# mode: PASSTHROUGH
#---
#apiVersion: networking.istio.io/v1beta1
#kind: VirtualService
#metadata:
# name: helloworld-vs
#spec:
# gateways:
# - helloworld-gateway
# hosts: ["lb.net","*.lb.net"]
## http:
## - route:
## - destination:
## host: helloworld.default.svc.cluster.local
##spec:
# tls:
# - match:
# - sniHosts: ["lb.net","*.lb.net"]
# route:
# - destination:
# host: helloworld.default.svc.cluster.local

View File

@ -0,0 +1,87 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
# istio: myingressgateway
istio: ingressgateway
servers:
# - port:
# number: 443
# name: secure-http2
# protocol: HTTP2
# hosts:
# - "*"
- port:
number: 80
name: http2-i
protocol: HTTP2
hosts:
- "*"
- port:
number: 443
name: https-i
protocol: HTTPS
hosts:
- "*"
tls:
# credentialName: my-tls-cert-secret
# minProtocolVersion: TLSV1_2
#
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "lb.net"
gateways:
- helloworld-gateway
http:
- name: http-vs
match:
- port: 80
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
# - name: https-vs
# match:
# - port: 443
# route:
# - destination:
# host: helloworld.default.svc.cluster.local
# port:
# number: 8443
tls:
- match:
- port: 443
sniHosts: ["lb.net"]
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: 8080
tls:
mode: DISABLE
- port:
number: 8443
tls:
mode: DISABLE

View File

@ -0,0 +1,29 @@
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:
istio: myingressgateway
k8s:
service:
ports:
- name: https-ingress
port: 443
protocol: TCP
targetPort: 1055
- name: http-ingress
port: 80
protocol: TCP
targetPort: 1085
values:
gateways:
istio-ingressgateway:
injectionTemplate: gateway

View File

@ -0,0 +1,37 @@
server {
listen 80;
# rewrite ^ https://$server_name$request_uri? permanent;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}
server {
listen 443 ssl default_server http2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
ssl on;
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}

View File

@ -0,0 +1,13 @@
FROM nginx
ADD server.conf /etc/nginx/conf.d/default.conf
# RUN apt-get update && \
# apt-get install apache2 openssl -y && \
# a2ensite default-ssl && \
# a2enmod ssl && \
RUN mkdir -p /var/www/html
RUN echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /cert.key -out /cert.crt

View File

@ -0,0 +1,313 @@
---
gitea: none
include_toc: true
---
# Based on
- [08a-HTTPS-min-TLS-version](../08a-HTTPS-min-TLS-version)
# Description
The previous example was modified set the gateway to enable for HTTP2 traffic.
https://stackoverflow.com/a/59610581
# Changelog
## Gateway
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: secure-http2
protocol: HTTP2
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
```
`<text>`
# 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
### http2
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http2.lb --http2
```
```text
http_version: 1.1
status_code: 200
```
### http1-web
#### Curl HTTP1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.0
```
```text
http_version: 1.1
status_code: 426
```
#### Curl HTTP1.1
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http1.1
```
```text
http_version: 1.1
status_code: 200
```
#### Curl HTTP2
```shell
curl 192.168.1.50/helloworld -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2
```
```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/#ServerTLSSettings-TLSProtocol
- https://stackoverflow.com/a/51279606
- https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings-HTTPSettings-H2UpgradePolicy
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest -f Dockerfile
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag registery.filter.home:5000/https-demo:latest .
[+] Building 0.0s (0/0)
ERROR: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
---
## Create the Dockerfile
```bash
FROM ubuntu/apache2
RUN apt-get update && \
apt-get install apache2 openssl -y && \
a2ensite default-ssl && \
a2enmod ssl && \
echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN /usr/bin/printf "<VirtualHost *:80>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
</VirtualHost>\n\
<VirtualHost *:443>\n\
ServerAdmin webmaster@localhost\n\
DocumentRoot /var/www/html\n\
ErrorLog \${APACHE_LOG_DIR}/error.log\n\
CustomLog \${APACHE_LOG_DIR}/access.log combined\n\
SSLEngine on\n\
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem\n\
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\
</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem
```
## Build the image
Due to my Kubernetes cluster environment, where I am using Orange 5, their architecture is arm7, and for such, I require to compile such images.
For my own commodity, I have used a raspberry pi 4 to build this images.
The images where pushed to a local registry server, and afterwards the Kubernetes cluster will pull such image.
```shell
docker build --tag https-demo:armv7 .
```
```text
docker build --tag https-demo:armv7 . --no-cache
[+] Building 16.5s (8/8) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.09kB 0.0s
=> [internal] load metadata for docker.io/ubuntu/apache2:latest 0.4s
=> CACHED [1/4] FROM docker.io/ubuntu/apache2@sha256:0a5e7179fa8fccf17843a8862e58ac783628b7d448cd68fda8fb1e 0.0s
=> [2/4] RUN apt-get update && apt-get install apache2 openssl -y && a2ensite default-ssl && a2enmod ssl & 12.0s
=> [3/4] RUN /usr/bin/printf "<VirtualHost *:80>\n ServerAdmin webmaster@localhost\n DocumentRoot /var/www/ 0.7s
=> [4/4] RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE' -newkey rsa:2048 -keyout 2.4s
=> exporting to image 1.0s
=> => exporting layers 1.0s
=> => writing image sha256:591c6d233100a48bf132eef7a792942cfd0b7057817c4ac5e156c1d33e24cd89 0.0s
=> => naming to docker.io/library/https-demo:armv7 0.0s
```
## Tag the image
```shell
docker image tag https-demo:armv7 registery.filter.home/https-demo:armv7
```
## Upload to the registery server
```text
docker image push registery.filter.home:5000/https-demo:armv7
The push refers to repository [registery.filter.home:5000/https-demo]
c6d858706b08: Pushed
9e077e0202f0: Pushed
6ffc708d0cf3: Pushed
69e01b4bf4d7: Pushed
17c5b30f3843: Pushed
0b9f60fbcaf1: Pushed
armv7: digest: sha256:d8c81c27f23bf3945ae8a794c82182f9e6c48ec927f388fdf4a88caa0e284bd1 size: 1578
```
## ?
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version numbe
---
Has apache2 installed with a default certificate.
Port 80 visible for HTTP
Port 443 visible for HTTPS.
curl https://192.168.1.2:8443 -s -o=/dev/null -w 'http_version: %{http_version}\nstatus_code: %{response_code}\n' -HHOST:http1.lb --http2 -k
http_version: 2
status_code: 200
# Recv failure: Connection reset by peer

View File

@ -6,3 +6,6 @@ metadata:
spec:
mtls:
mode: DISABLE
#curl -v --resolve ":$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert example_certs/example.com.crt "https://nginx.example.com:$SECURE_INGRESS_PORT"

View File

@ -0,0 +1,117 @@
#apiVersion: networking.istio.io/v1alpha3
#kind: Gateway
#metadata:
# name: helloworld-gateway
#spec:
# selector:
## istio: myingressgateway
# istio: ingressgateway
# servers:
# - hosts:
# ["lb.net","*.lb.net"]
# port:
# name: tls-443
# number: 443
# protocol: HTTPS
# tls:
# mode: SIMPLE
# credentialName: my-tls-cert-secret
# minProtocolVersion: TLSV1_2
#---
#apiVersion: networking.istio.io/v1alpha3
#kind: VirtualService
#metadata:
# name: helloworld-vs
#spec:
# hosts:
# - "*"
# gateways:
# - helloworld-gateway
# http:
## - name: http-vs
## match:
## - port: 80
## route:
## - destination:
## host: helloworld.default.svc.cluster.local
## port:
## number: 8080
# - name: https-vs
# match:
# - port: 443
# route:
# - destination:
# host: helloworld.default.svc.cluster.local
# port:
# number: 443
##
## tls:
## - match:
## - port: 443
## sniHosts: ["lb.net"]
## route:
## - destination:
## host: helloworld.default.svc.cluster.local
## port:
## number: 443
#
##---
##apiVersion: networking.istio.io/v1alpha3
##kind: DestinationRule
##metadata:
## name: helloworld
## namespace: default
##spec:
## host: helloworld.default.svc.cluster.local
## trafficPolicy:
## portLevelSettings:
## - port:
## number: 8080
## tls:
## mode: DISABLE
#
## - port:
## number: 8443
## tls:
## credentialName: client-credential
## mode: SIMPLE
#
#
## port:
## name: https-backend
## number: 8443
## protocol: HTTPS
## tls:
## credentialName: my-tls-cert-secret
## mode: SIMPLE
## tcp:
### - match:
### - port: 80
### route:
### - destination:
### host: helloworld
### port:
### number: 8080
### - match:
### - port: 443
## - route:
## - destination:
## host: helloworld
## port:
## number: 8443
##
## tls:
## - match:
## - port: 443
## sniHosts:
## - "hello.si"
### - uri:
### exact: /helloworld
## route:
## - destination:
## host: helloworld
## port:
## number: 8443
### protocol: HTTPS
### rewrite:
### uri: "/"

View File

@ -0,0 +1,74 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- name: p1
port: 80
protocol: TCP
- name: https
port: 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
sidecar.istio.io/inject: "true"
spec:
containers:
- name: helloworld
image: oriolfilter/https-apache-demo:armv7
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- 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,36 @@
#apiVersion: networking.istio.io/v1beta1
#kind: Gateway
#metadata:
# name: helloworld-gateway
#spec:
# selector:
# istio: ingressgateway
# servers:
# - hosts:
# - "*"
# port:
# name: https
# number: 443
# protocol: HTTPS
# tls:
# mode: PASSTHROUGH
#---
#apiVersion: networking.istio.io/v1beta1
#kind: VirtualService
#metadata:
# name: helloworld-vs
#spec:
# gateways:
# - helloworld-gateway
# hosts: ["lb.net","*.lb.net"]
## http:
## - route:
## - destination:
## host: helloworld.default.svc.cluster.local
##spec:
# tls:
# - match:
# - sniHosts: ["lb.net","*.lb.net"]
# route:
# - destination:
# host: helloworld.default.svc.cluster.local

View File

@ -4,23 +4,31 @@ metadata:
name: helloworld-gateway
spec:
selector:
# istio: myingressgateway
istio: ingressgateway
servers:
# - port:
# number: 443
# name: secure-http2
# protocol: HTTP2
# hosts:
# - "*"
- port:
number: 80
name: http
protocol: HTTP
name: http2-i
protocol: HTTP2
hosts:
- "*"
- port:
number: 443
name: https
name: https-i
protocol: HTTPS
hosts:
- "*"
tls:
credentialName: my-tls-cert-secret
minProtocolVersion: TLSV1_2
#
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
@ -28,8 +36,7 @@ kind: VirtualService
metadata:
name: helloworld-vs
spec:
hosts:
- "*"
hosts: ["lb.net"]
gateways:
- helloworld-gateway
http:
@ -40,15 +47,22 @@ spec:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8080
number: 80
- name: https-vs
match:
- port: 443
sniHosts: ["lb.net"]
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8443
number: 443
# tls:
# - match:
# - sniHosts: ["lb.net"]
# route:
# - destination:
# host: helloworld.default.svc.cluster.local
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
@ -56,15 +70,16 @@ metadata:
name: helloworld
namespace: default
spec:
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8080
tls:
mode: SIMPLE
- port:
number: 8443
tls:
mode: SIMPLE
host: helloworld.default.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 8080
tls:
mode: DISABLE
#
- port:
number: 443
tls:
credentialName: client-credential
mode: DISABLE

View File

@ -0,0 +1,29 @@
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:
istio: myingressgateway
k8s:
service:
ports:
- name: https-ingress
port: 443
protocol: TCP
targetPort: 1055
- name: http-ingress
port: 80
protocol: TCP
targetPort: 1085
values:
gateways:
istio-ingressgateway:
injectionTemplate: gateway

View File

@ -0,0 +1,37 @@
server {
listen 80;
# rewrite ^ https://$server_name$request_uri? permanent;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}
server {
listen 443 ssl default_server http2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
ssl on;
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}

View File

@ -1,6 +0,0 @@
# Based on
- [02-Traffic_management/09-HTTPS-backend (pending document)](../../02-Traffic_management/09-HTTPS-backend%20(pending%20document))
On the previous example only uses a HTTPS backend, here boards both HTTP and HTTPS backends.

View File

@ -1,209 +0,0 @@
# Description
This image was intended to be used on configuration tests or troubleshooting.
URL: [`docker.io/oriolfilter/https-nginx-demo:latest`](https://hub.docker.com/r/oriolfilter/https-nginx-demo)
---
## Breakdown
### Capabilities
- Multi arch
- HTTP
- HTTPS (with built-in certificate)
- HTTP2
- Nginx
### Platforms it was build on:
- linux/amd64
- linux/arm64
- linux/arm/v7
### Dockerfile
The orders given are very simple:
1. Grab the nginx image as a base/template (this allows me to forget about the entrypoint configuration).
2. Take the file `server.conf` and place it in the path `/etc/nginx/conf.d/default.conf` from the container/image.
3. Create the directory `/var/www/html`, and afterwards create a simple index.
4. Create a certificate and a key that will be used on the Nginx to allow HTTPS traffic requests.
```Dockerfile
FROM nginx
ADD server.conf /etc/nginx/conf.d/default.conf
RUN mkdir -p /var/www/html
RUN echo "<h2>Howdy</h2>" | tee /var/www/html/index.html
RUN openssl req -x509 -sha256 -nodes -days 358000 -subj '/O=SSL EXAMPLE/CN=lb.net' -newkey rsa:2048 -keyout /cert.key -out /cert.crt
```
### server.conf
Read it if you please.
The port listens to both port 80 and port 443, for HTTP and HTTPS traffic.
Port 443 has enabled http2.
Could have configured HTTP to HTTPS forwarding, yet this way I can verify the status of the service or configurations through HTTP requests. (also the HTTP to HTTPS forwarding should be handled by the Load Balancer / Ingress)
It uses the certificates generated previously.
```nginx
server {
listen 80;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}
server {
listen 443 ssl default_server http2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;
server_name lb.net;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
ssl on;
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=7200";
root /var/www/html;
index index.html;
}
```
# Build it yourself
[Used this guide through this process](https://docs.docker.com/build/building/multi-platform/)
# Yes
As far I understood, runs this as privileged to install certain packages / architectures / platforms to your device.
```shell
docker run --privileged --rm tonistiigi/binfmt --install all
```
```text
Unable to find image 'tonistiigi/binfmt:latest' locally
latest: Pulling from tonistiigi/binfmt
8d4d64c318a5: Pull complete
e9c608ddc3cb: Pull complete
Digest: sha256:66e11bea77a5ea9d6f0fe79b57cd2b189b5d15b93a2bdb925be22949232e4e55
Status: Downloaded newer image for tonistiigi/binfmt:latest
installing: arm OK
installing: mips64le OK
installing: mips64 OK
installing: arm64 OK
installing: riscv64 OK
installing: s390x OK
installing: ppc64le OK
{
"supported": [
"linux/amd64",
"linux/arm64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64le",
"linux/mips64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-aarch64",
"qemu-arm",
"qemu-mips64",
"qemu-mips64el",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x"
]
}
```
## Create builder profile
```shell
docker buildx create --name mybuilder --driver docker-container --bootstrap
```
```text
[+] Building 2.0s (1/1) FINISHED
=> [internal] booting buildkit 2.0s
=> => pulling image moby/buildkit:buildx-stable-1 1.2s
=> => creating container buildx_buildkit_mybuilder0 0.8s
mybuilder
```
## Use created buildx profile
```shell
docker buildx use mybuilder
```
## Inspect selected buildx profile
```shell
docker buildx inspect
```
```text
Name: mybuilder
Driver: docker-container
Last Activity: 2023-04-25 00:33:29 +0000 UTC
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Status: running
Buildkit: v0.11.5
Platforms: linux/amd64, linux/amd64/v2, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
```
## Build, tag and push
I am targeting the repo directly, but any registry can be targeted.
```shell
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t oriolfilter/https-nginx-demo:latest . --push
```
```text
[+] Building 11.0s (24/24) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 383B 0.0s
=> [linux/arm/v7 internal] load metadata for docker.io/library/nginx:latest 0.8s
=> [linux/arm64 internal] load metadata for docker.io/library/nginx:latest 0.8s
=> [linux/amd64 internal] load metadata for docker.io/library/nginx:latest 0.8s
...
<> Building sounds intensifies <>
...
=> [auth] oriolfilter/https-nginx-demo:pull,push token for registry-1.docker.io
```