Securing Gateways with HTTPS
任务描述了如何去配置HTTPS ingress访问一个HTTP服务;此案例描述了如何配置HTTPS ingress访问一个HTTPS服务。 例如,配置于个ingress gateway去执行SNI穿透,而不是在进入的请求那里执行TLS终结。
在这里的案例只是使用简单的NGINX 服务器。 所以先在kubernetes集群中部署一个NGINX服务。 然后你配置gateway,通过host 的nginx.example.com
访问服务 。
1. 产生客户端和服务器的证书及key
- 创建一个根证书和私有Key,去给服务签署证书
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
- 针对nginx.example.com创建证书和私有key
$ openssl req -out nginx.example.com.csr -newkey rsa:2048 -nodes -keyout nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization"
$ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in nginx.example.com.csr -out nginx.example.com.crt
2. 部署NGINX 服务器
- 创建一个kubernetes Secret,该Secret拥有服务器证书
$ kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt
- 创建针对NGINX服务器的配置文件
$ cat <<EOF > ./nginx.conf
events {
}
http {
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
server {
listen 443 ssl;
root /usr/share/nginx/html;
index index.html;
server_name nginx.example.com;
ssl_certificate /etc/nginx-server-certs/tls.crt;
ssl_certificate_key /etc/nginx-server-certs/tls.key;
}
}
EOF
- 创建一个针对拥有NGINX 服务器配置的
ConfigMap
$ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf
- 部署NGINX server.
$ cat <<EOF | istioctl kube-inject -f - | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 443
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 443
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx
readOnly: true
- name: nginx-server-certs
mountPath: /etc/nginx-server-certs
readOnly: true
volumes:
- name: nginx-config
configMap:
name: nginx-configmap
- name: nginx-server-certs
secret:
secretName: nginx-server-certs
EOF
- 在不检查服务器证书的请况下,从它的sidecar proxy发送一个请求到服务,来测试nginx服务器是否部署成功。确保服务器的证书成功打印,比如
common name
是nginx.example.com
$ kubectl exec -it $(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com
3. 配置ingress gateway
- 定义针对端口443的Gateway。 注意那个
PASSTHROUGH
TLS模式告诉gateway去传输Ingress的流量,而不需要终止TLS
.
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: PASSTHROUGH
hosts:
- nginx.example.com
EOF
- 针对经过Gateway进入的流量配置路由
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- nginx.example.com
gateways:
- mygateway
tls:
- match:
- port: 443
sniHosts:
- nginx.example.com
route:
- destination:
host: my-nginx
port:
number: 443
EOF
- 确定Ingress的IP和端口号
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
- 从集群外部访问NGINX服务,注意返回回来的正确证书
$
4. 清除本次实验
- 移除创建的kubernetes资源
$ kubectl delete secret nginx-server-certs
$ kubectl delete configmap nginx-configmap
$ kubectl delete service my-nginx
$ kubectl delete deployment my-nginx
$ kubectl delete gateway mygateway
$ kubectl delete virtualservice nginx
- 删除证书和key
$ rm example.com.crt example.com.key nginx.example.com.crt nginx.example.com.key nginx.example.com.csr
- 删除产生的配置文件
$ rm ./nginx.conf