DevOps/Kubernetes

[Kubernetes] Nginx HTTPs 서버 구성하기

TTOII 2022. 6. 1. 15:55
728x90

✔️ Nginx HTTPs 서버 구성

nginx 관련 파일은 다음과 같다.

 vagrant@k8s-node1  ~/configure/nginx-https  kubectl run nginx --image nginx                                        
pod/nginx created

 vagrant@k8s-node1  ~/configure/nginx-https  kubectl exec -it nginx -- bash                           
root@nginx:/# cd /usr/share/nginx/html/
root@nginx:/usr/share/nginx/html# ls
50x.html  index.html

root@nginx:/usr/share/nginx/html# cd /etc/nginx
root@nginx:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
  • Documentation Root : /usr/share/nginx/html/
  • Configuration File : /etc/nginx/conf.d

 vagrant@k8s-node1  ~/configure/nginx-https  ls
conf x509

conf에는 https를 사용하기 위한 설정이 들어가며 x509에는 인증서가 있어야 한다.

 

 vagrant@k8s-node1  ~/configure/nginx-https  cat conf/nginx-tls.conf
server {
    listen              80;
    listen              443 ssl; # ssl 기능을 킨다.
    server_name         myapp.example.com;
    ssl_certificate     /etc/nginx/ssl/tls.crt; # 인증서의 위치
    ssl_certificate_key /etc/nginx/ssl/tls.key; 
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    location / {
        root   /usr/share/nginx/html; # Documentation Root
        index  index.html;
    }
}

해당 파일을 configMap으로 만들어 파드에 제공하면 된다.

인증서를 만들어줘야 하는데 인증서는 비용이 들고 현재 테스트 환경이므로 SSC(Self Signed Certificate) : 자체 서명 인증서를 사용한다.

 

✔️ 인증서 생성 과정

 vagrant@k8s-node1  ~/configure/nginx-https/x509  openssl genrsa -out nginx-tls.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................+++++
.................................................................+++++
e is 65537 (0x010001)

openssl을 사용하여 private key를 만들어준다.

 

 vagrant@k8s-node1  ~/configure/nginx-https/x509  openssl rsa -in nginx-tls.key -pubout -out nginx-tls
writing RSA key

private key 파일을 넣어서 public key를 만들어준다.

 

 vagrant@k8s-node1  ~/configure/nginx-https/x509  openssl req -new -key nginx-tls.key -out nginx-tls.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sohui Inc.
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:www.sohui.com
Email Address []:skysohe@naver.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

 vagrant@k8s-node1  ~/configure/nginx-https/x509  ls
nginx-tls  nginx-tls.csr  nginx-tls.key

CSR (Certificate Signing Request) : 인증서 서명 요청 파일을 Let's encrypt로 보내거나 또는 서명할 수 있는 기관에 보낸다.

인증서에 LDAP Distinguished Name을 표시해서 인증서가 누구의 것인지 표시한다.

 

 vagrant@k8s-node1  ~/configure/nginx-https/x509  openssl req -x509 -days 3650 -key nginx-tls.key -in nginx-tls.csr -out nginx-tls.crt

 vagrant@k8s-node1  ~/configure/nginx-https/x509  ls
nginx-tls  nginx-tls.crt  nginx-tls.csr  nginx-tls.key

자체 서명을 한다. nginx-tls.crt인증서는 자체 서명을 했으므로 보안상 문제가 있다.

 


 

이제 설정 파일을 configMap으로 만들고 서명 인증서는 secret으로 등록해야 한다.

  • nginx-tls.conf
  • nginx-tls.key
  • nginx-tls.crt

kubernetes.io/tls 시크릿 타입을 사용해야 한다.
kubernetes.io/tls : TLS 클라이언트나 서버를 위한 데이터

apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
type: kubernetes.io/tls
data:
  # 본 예시를 위해 축약된 데이터임
  tls.crt: |
        MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
  tls.key: |
        MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...

YAML 파일 구조는 다음과 같을 것이다.

 

✔️ 리소스 생성

configMap 생성
nginx-tls-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-tls-config
data:
  nginx-tls.conf: |
    server {
      listen              80;
      listen              443 ssl;
      server_name         myapp.example.com;
      ssl_certificate     /etc/nginx/ssl/tls.crt;
      ssl_certificate_key /etc/nginx/ssl/tls.key;
      ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers         HIGH:!aNULL:!MD5;
      location / {
        root   /usr/share/nginx/html;
        index  index.html;
      }
    }

 

secret 생성
nginx-tls-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: nginx-tls-secret
type: kubernetes.io/tls
data:
  # base64 x509/nginx-tls.crt -w 0 # 파일 인코딩
  tls.crt: |
    LS0tLS1C...
  # base64 x509/nginx-tls.key -w 0
  tls.key: |
    LS0tLS1C...

base64로 인코딩한 값을 넣어준다.

 

파드 생성
nginx-https-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-https-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
      - name: nginx-config
        mountPath: /etc/nginx/conf.d
      - name: nginx-certs
        mountPath: /etc/nginx/ssl
  volumes:
    - name: nginx-config
      configMap:
        name: nginx-tls-config
    - name: nginx-certs
      secret:
        secretName: nginx-tls-secret

nginx-config 설정 파일을 가져가서 /etc/nginx/conf.d에 마운팅 시킨다.
nginx-certs/etc/nginx/ssl에 마운팅 시킨다.

 

서비스 생성
nginx-svc-lb.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-lb
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
 vagrant@k8s-node1  ~/configure/nginx-https  kubectl get cm     
NAME               DATA   AGE
kube-root-ca.crt   1      9d
mymessage          1      30h
nginx-tls-config   1      14s
 vagrant@k8s-node1  ~/configure/nginx-https  kubectl describe cm nginx-tls-config
Name:         nginx-tls-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx-tls.conf:
----
server {
  listen              80;
  listen              443 ssl;
  server_name         myapp.example.com;
  ssl_certificate     /etc/nginx/ssl/tls.crt;
  ssl_certificate_key /etc/nginx/ssl/tls.key;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;
  location / {
    root   /usr/share/nginx/html;
    index  index.html;
  }
}


BinaryData
====

Events:  <none>
 vagrant@k8s-node1  ~/configure/nginx-https  kubectl get secret                  
NAME                                 TYPE                                  DATA   AGE
default-token-h87sc                  kubernetes.io/service-account-token   3      9d
mydata                               Opaque                                2      29h
nfs-client-provisioner-token-xzr7h   kubernetes.io/service-account-token   3      31h
nginx-tls-secret                     kubernetes.io/tls                     2      69s
 vagrant@k8s-node1  ~/configure/nginx-https  kubectl describe secret nginx-tls-secret 
Name:         nginx-tls-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1432 bytes
tls.key:  1679 bytes
 vagrant@k8s-node1  ~/configure/nginx-https  kubectl get pod                       
NAME                                      READY   STATUS              RESTARTS     AGE
nfs-client-provisioner-758f8cd4d6-wpjbt   1/1     Running             0            31h
nginx-https-pod                           0/1     ContainerCreating   0            2s

모든 리소스가 정상적으로 생성됐음을 확인한다.

 

 vagrant@k8s-node1  ~/configure/nginx-https  curl -k https://192.168.100.241
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

자체 서명 인증서를 사용했으므로 curl로 테스트하기 위해서는 -k옵션을 붙여서 요청한다.

nginx의 기본 페이지를 응답하는 것을 확인할 수 있다.

 

인증서의 LDAP DN을 확인할 수 있다.

728x90