CA 발급자가 포함된 단순 PKI

이 워크샵에서는 PKI를 사용하여 보안 통신을 만드는 방법에 대한 시나리오를 시뮬레이션합니다. 터미널에서 작업하는 이 모든 세션은 단계별로 따라할 수 있습니다.

후반 세션에서는 쉬운 경우에 공개/개인 키를 사용하는 방법에 대해 배웠습니다.
솔루션을 구현하기 위해 워크샵을 설명했습니다. 그런 다음 고급 작업장으로 업그레이드합니다.
공개/사설 CA 중간 서버를 구현하는 방법을 이해합니다.
이전 항목을 읽지 않은 경우 다음으로 이동할 수 있습니다.


  • 전제 조건


  • OpenSSL
  • cURL
  • 도커
  • 트리

  • 루트 CA 인증서 생성



    먼저 다음 단계에 따라 간단한 자체 서명 루트 CA 인증서를 생성합니다.
  • SSL 개인 키 생성

  •    $ openssl genrsa -out rootCAkey.pem 4096
       Generating RSA private key, 4096 bit long modulus (2 primes)
       .........................................++++
       .........++++
       e is 65537 (0x010001)
    

    We generate random keys with 4,096 character and you can use other lengths like 1024, 2048, 8192, or ETC. You can increase or decrease your key length to optimize cpu power to process them.


  • 개인 키에서 인증서 만들기

  •    $ openssl req -x509 -sha256 -new -nodes -key rootCAkey.pem \
          -days 14 -out rootCAcert.pem
       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]:TH
       State or Province Name (full name) [Some-State]:Bangkok
       Locality Name (eg, city) []:BangKhea
       Organization Name (eg, company) [Internet Widgits Pty Ltd]:Opsta Thailand
       Organizational Unit Name (eg, section) []:DevOps
       Common Name (e.g. server FQDN or YOUR name) []:OpstaRootCA
       Email Address []:[email protected]
    

    For the previous command, I request a new certificate file with some information. I use the digest algorithm SHA-256 and set it to expire before 14 days. It shows a prompt on your terminal for adding more information. You can see an example above.


  • 이제 자체 루트 CA를 확인할 수 있습니다.

  •    openssl x509 -text -in rootCAcert.pem
    

    You can see your certificate information. Then go to the next step to create a chain certificate.


    발급자로 서버 인증서 생성


  • 동일한 단계 루트 CA로 임의의 개인 키 생성

  •    # You can replace rsaServerKey.pem to your name
       # And can change key size from 2048 to other length
       $ openssl genrsa -out rsaServerKey.pem 2048
       Generating RSA private key, 2048 bit long modulus (2 primes)
       ......................................................................+++++
       ...............+++++
       e is 65537 (0x010001)
    

  • CSR을 위한 메타 데이터를 제공하는 CNF 파일 생성

  •    # req.cnf
       [req]
       req_extensions = v3_req
       distinguished_name = dn
       prompt = no
    
       [dn]
       CN = ssl-lab.example.local
       C = TH
       L = Bangkok
       O = Opsta Thailand
       OU = DevOps
    
       [v3_req]
       subjectAltName = @san_names
    
       [san_names]
       DNS.1 = ssl-lab.example.local
       DNS.2 = localhost
       DNS.3 = 127.0.0.1
    

    Provide simple configuration to create CSR file. This file has SAN(Subject Alternative Name) with 3 names in [san_names]. For @san_names, I use for extend alternative name for server.


  • CSR 인증서 생성

  •    $ openssl req -new -out req.csr -key rsaServerKey.pem -sha256 -config req.cnf
       $ cat req.csr
       -----BEGIN CERTIFICATE REQUEST-----
       MIIC9zCCAd8CAQAwaTEeMBwGA1UEAwwVc3NsLWxhYi5leGFtcGxlLmxvY2FsMQsw
       CQYDVQQGEwJUSDEQMA4GA1UEBwwHQmFuZ2tvazEXMBUGA1UECgwOT3BzdGEgVGhh
       aWxhbmQxDzANBgNVBAsMBkRldk9wczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
       …
       k9jkEKhPeICqJgHLbyiEcEc9xaPTMPb35cBQT8irnUq1+WbQamhWDIBmwzDHCSyf
       jCK672ACRleQCj8kk5l+dOB0wzWEaDcCoQNwIwqg2RpfDKc1lHARroBzm1P/4grg
       NaF5EYJJWhXUXGKq68meHpCTGzgC7M06rwBdOR+8l0GIUZ5K25MvNg3+ZA==
       -----END CERTIFICATE REQUEST-----
    

  • CSR 정보를 확인하고 요청된 확장에 중점을 둡니다.

  •    $ openssl req -in req.csr -noout -text
       …
       Requested Extensions:
                   X509v3 Subject Alternative Name: 
                       DNS:ssl-lab.example.local, DNS:localhost, DNS:127.0.0.1
    

  • CSR 파일을 사용하여 루트 CA로 신뢰할 수 있는 인증서 생성

  •    $ openssl x509 -req -sha256 -in req.csr -CA ../rootCAcert.pem \
         -extfile <(printf "subjectAltName=DNS:ssl-lab.example.local,DNS:localhost") \
         -CAkey ../rootCAkey.pem -CAcreateserial -out CertServer.pem -days 7
       …
       Signature ok
       subject=CN = ssl-lab.example.local, C = TH, L = Bangkok, O = Opsta Thailand, OU = DevOps
       Getting CA Private Key
    

    We create trusted certificates with digest algorithm SHA-256 and create root CA serials that track how many certificates were issued with -CAcreateserial , so if not the first certificate you will use -CAserial instead. Then, this certificate will stay for 7 days only.


  • 발급자가 있어야 하는 인증서 정보 확인

  •    $ openssl x509 -text -in CertServer.pem
       …
       Issuer: C = TH, ST = Bangkok, L = BangKhea, O = Opsta Thailand, OU = DevOps, CN = OpstaRootCA, emailAddress = [email protected]
    

    We will see Issuer information under Certificate >> Data.


    데모 웹 서버 실행



    이제 이 인증서와 개인 키를 이전 세션(또한 topic name )으로 교체하고 다시 테스트할 수 있습니다. 단일 자체 서명 인증서와 CA 발급자가 있는 인증서 간의 차이를 확인하기 위해 사용자 지정 루트 CA를 브라우저나 시스템에 설치합니다.

    데모 웹 서버 실행



  • 간단한 구성으로 Dockerfile 만들기

    FROM nginx:1.20-alpine
    
    ADD default.conf /etc/nginx/conf.d/default.conf
    
    COPY ssl /etc/nginx/ssl
    
    RUN chown -R 0:0 /etc/nginx/ssl \
        && chown -R 0:0 /etc/nginx/conf.d/default.conf
    




  • 다음 코드에서 Nginx 사이트 구성 만들기

    server {
        listen       80;
        server_name  localhost ssl-lab.example.local;
        return 301 https://localhost:8443$request_uri;
    }
    server {
        listen              443 ssl;
        server_name         localhost ssl-lab.example.local;
        keepalive_timeout   70;
        ssl_certificate     /etc/nginx/ssl/CertServer.pem;
        ssl_certificate_key /etc/nginx/ssl/rsaServerKey.pem;
        ssl_protocols       TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers off;
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    




  • 기본 옵션으로 도커 시작

    docker build -t nginx-ca:demo .
    docker run -it --rm -p 8080:80 -p 8443:443 nginx-ca:demo
    




  • 자세한 인수와 함께 cUrl을 사용하여 확인

    $ curl -vIL --cacert ../rootCA/rootCAcert.pem -XGET https://localhost:8443
    
    *   Trying 127.0.0.1:8443...
    * Connected to localhost (127.0.0.1) port 8443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    *  CAfile: rootCA/rootCAcert.pem
    *  CApath: /etc/ssl/certs
    * TLSv1.0 (OUT), TLS header, Certificate Status (22):
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS header, Finished (20):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS header, Finished (20):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
    * ALPN, server accepted to use http/1.1
    * Server certificate:
    *  subject: CN=ssl-lab.example.local; C=TH; L=Bangkok; O=Opsta Thailand; OU=DevOps
    *  start date: Sep 16 06:36:23 2022 GMT
    *  expire date: Oct 16 06:36:23 2022 GMT
    *  subjectAltName: host "localhost" matched cert's "localhost"
    *  issuer: C=TH; ST=Bangkok; O=Opsta Thailand; OU=DevOps; CN=OpstaRootCA; [email protected]
    *  SSL certificate verify ok.
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    > GET / HTTP/1.1
    > Host: localhost:8443
    > User-Agent: curl/7.81.0
    > Accept: */*
    > 
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < Server: nginx/1.20.2
    Server: nginx/1.20.2
    < Date: Mon, 19 Sep 2022 02:57:09 GMT
    Date: Mon, 19 Sep 2022 02:57:09 GMT
    < Content-Type: text/html
    Content-Type: text/html
    < Content-Length: 612
    Content-Length: 612
    < Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
    Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
    < Connection: keep-alive
    Connection: keep-alive
    < ETag: "6193c877-264"
    ETag: "6193c877-264"
    < Accept-Ranges: bytes
    Accept-Ranges: bytes
    
    < 
    * Excess found: excess = 612 url = / (zero-length body)
    * Connection #0 to host localhost left intact
    


  • 좋은 웹페이지 즐겨찾기