Objective
Demonstrate end-to-end HTTPS using SNI where traffic flows:
Client → HTTPS → AWS WAF → AWS ALB → HTTPS (SNI) → NGINX → application
The ALB terminates TLS for WAF inspection and re-encrypts traffic to the NGINX backend using HTTPS. NGINX presents its own certificate and routes based on SNI/Host header.
Architecture
Traffic flow:
Client
│ HTTPS (SNI nginx.test.example.com)
▼
AWS WAF
│
▼
ALB
│ HTTPS re-encryption
▼
Worker Node
│ NodePort 30443
▼
NGINX
│
▼
Application
TLS sessions:
- Client ↔ ALB: ACM certificate
- ALB ↔ NGINX: Kubernetes TLS secret
Host header and SNI are preserved end-to-end.
Prerequisites
Generate Certificates
Certificates:
Located in ../certs/ directory:
- wildcard.test.example.com.crt
- wildcard.test.example.com.key
Tools required:
Variables used in examples:
export REGION=eu-central-1
export DOMAIN=nginx.test.example.com
1 Import Certificate into AWS ACM
ALB requires certificates from ACM.
cd ../certs
aws acm import-certificate \
--certificate fileb://wildcard.test.example.com.crt \
--private-key fileb://wildcard.test.example.com.key \
--region $REGION
Save returned ARN:
export CERT_ARN=<returned-arn>
2 Create Kubernetes TLS Secret
Used by NGINX backend.
kubectl create secret tls nginx-tls \
--cert=../certs/wildcard.test.example.com.crt \
--key=../certs/wildcard.test.example.com.key
3 Create AWS WAF WebACL
Create WebACL:
aws wafv2 create-web-acl \
--name eks-waf-test \
--scope REGIONAL \
--default-action Allow={} \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=waf-test \
--region $REGION
Add AWS managed rule set (example from AWS blog):
aws wafv2 create-rule-group
Common managed rules typically used:
AWSManagedRulesCommonRuleSet
AWSManagedRulesKnownBadInputsRuleSet
AWSManagedRulesSQLiRuleSet
Capture returned ARN:
export WAF_ARN=<web-acl-arn>
4 Create NGINX ConfigMap
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |
events {}
http {
server {
listen 443 ssl;
server_name nginx.test.example.com;
ssl_certificate /etc/nginx/tls/tls.crt;
ssl_certificate_key /etc/nginx/tls/tls.key;
location / {
return 200 "Hello from NGINX TLS backend\n";
}
}
}
EOF
5 Create NGINX Deployment
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 443
volumeMounts:
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: tls
mountPath: /etc/nginx/tls
volumes:
- name: config
configMap:
name: nginx-conf
- name: tls
secret:
secretName: nginx-tls
EOF
6 Create NGINX Service
NodePort required for instance target type.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 443
targetPort: 443
nodePort: 30443
EOF
7 Create ALB Ingress
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/backend-protocol: HTTPS
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/certificate-arn: "$CERT_ARN"
alb.ingress.kubernetes.io/wafv2-acl-arn: "$WAF_ARN"
spec:
ingressClassName: alb
rules:
- host: nginx.test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 443
EOF
8 Retrieve ALB Address
export ALB_DNS=$(kubectl get ingress nginx-alb -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
echo "ALB DNS: $ALB_DNS"
Example output:
k8s-default-nginx-123456.eu-central-1.elb.amazonaws.com
9 Local Testing via /etc/hosts
Resolve ALB IP:
Edit hosts:
Add:
<ALB_IP> nginx.test.example.com
10 Test HTTPS + SNI
curl -k https://nginx.test.example.com
Expected response:
Hello from NGINX TLS backend
Result
This POC demonstrates:
- WAF inspection at ALB
- End-to-end HTTPS
- SNI based routing
- Kubernetes backend using NodePort
- Integration of ALB with Kubernetes ingress controller
Debug Commands
Check ingress:
Check ingress details:
kubectl describe ingress nginx-alb
Check NGINX pods:
kubectl get pods -l app=nginx
Check NGINX logs:
kubectl logs -l app=nginx
Check ALB target groups (via AWS Console or CLI):
aws elbv2 describe-target-health --target-group-arn <target-group-arn> --region $REGION
Objective
Demonstrate end-to-end HTTPS using SNI where traffic flows:
Client → HTTPS → AWS WAF → AWS ALB → HTTPS (SNI) → NGINX → application
The ALB terminates TLS for WAF inspection and re-encrypts traffic to the NGINX backend using HTTPS. NGINX presents its own certificate and routes based on SNI/Host header.
Architecture
Traffic flow:
TLS sessions:
Host header and SNI are preserved end-to-end.
Prerequisites
Generate Certificates
Certificates:
Located in
../certs/directory:Tools required:
Variables used in examples:
1 Import Certificate into AWS ACM
ALB requires certificates from ACM.
Save returned ARN:
2 Create Kubernetes TLS Secret
Used by NGINX backend.
3 Create AWS WAF WebACL
Create WebACL:
aws wafv2 create-web-acl \ --name eks-waf-test \ --scope REGIONAL \ --default-action Allow={} \ --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=waf-test \ --region $REGIONAdd AWS managed rule set (example from AWS blog):
Common managed rules typically used:
Capture returned ARN:
4 Create NGINX ConfigMap
5 Create NGINX Deployment
6 Create NGINX Service
NodePort required for instance target type.
7 Create ALB Ingress
8 Retrieve ALB Address
Example output:
9 Local Testing via /etc/hosts
Resolve ALB IP:
dig $ALB_DNS +shortEdit hosts:
Add:
10 Test HTTPS + SNI
Expected response:
Result
This POC demonstrates:
Debug Commands
Check ingress:
Check ingress details:
Check NGINX pods:
Check NGINX logs:
Check ALB target groups (via AWS Console or CLI):