태그 보관물: Let’s Encrypt

VMware ESXi7 인증서 변경

최초 vSphere 설치시에는 웹콘솔 접근을 위한 vmware installer인증서가 적용된 private 인증서가 기본 설치 되어 있습니다.

사용상에는 대단히 큰 불편은 아니지만 주기적으로 안전하지 않은 페이지를 눌러줘야 되는 번거로움이 있고 할당된 도메인과 public 인증서를 활용할 수 있도록 해보겠습니다.

구성 환경
– 인증서 보관 경로 : /etc/vmware/ssl
– root 인증서 : castore.pem
– public key : rui.crt
– private key : rui.key
– 인증서 발급 기관 : Let’s Encrypt(RSA 키 발급)

기존 인증서 백업

    $ cd /etc/vmware/ssl
    
    # 원복을 위한 root 인증서, public key, private key 백업
    $ cp castore.pem castore.pem.bak
    $ cp rui.crt rui.crt.bak
    $ cp rui.key rui.key.bak

    Let’s Encrypt 인증서 적용 및 웹서비스 재기동

    $ cd /etc/vmware/ssl
    
    # root 인증서 다운로드 및 적용
    $ curl https://letsencrypt.org/certs/isrgrootx1.pem.txt -o castore.pem
    
    # Let's Encrypt 인증서 파일(fullchain.pem, privkey.pem) /etc/vmware/ssl 사전 복사 처리 후 진행
    $ openssl x509 -inform PEM -in fullchain.pem -out rui.crt
    $ cp privkey.pem rui.key
    
    # 웹서비스 재기동
    $ /etc/init.d/hostd restart

    서비스 재기동 완료 후 브라우저에서 할당된 도메인으로 정상 접속되면 완료 입니다.

    Let’s Encrypt 인증서 생성 실패

    certbot을 통해 Let’s Encrypt 인증서 생성을 진행할 때 인증서 생성이 실패하는 경우가 있습니다.

    다양한 경우의 수가 있겠지만 이 경우는 selinux의 차단으로 인해 발생하는 경우입니다.

    [root@test ~]# sudo certbot certonly --cert-name sierracloud.kro.kr -d www.sierracloud.kro.kr
    
    2025-01-01 01:13:22,268:DEBUG:certbot._internal.main:certbot version: 2.11.0
    2025-01-01 01:13:22,268:DEBUG:certbot._internal.main:Location of certbot entry point: /bin/certbot
    2025-01-01 01:13:22,268:DEBUG:certbot._internal.main:Arguments: ['--cert-name', 'sierracloud.kro.kr', '-d', 'www.sierracloud.kro.kr', '-v']
    2025-01-01 01:13:22,268:DEBUG:certbot._internal.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
    2025-01-01 01:13:22,275:DEBUG:certbot._internal.log:Root logging level set at 20
    2025-01-01 01:13:22,276:DEBUG:certbot._internal.plugins.selection:Requested authenticator None and installer None
    2025-01-01 01:13:22,276:DEBUG:certbot._internal.plugins.selection:Multiple candidate plugins: * standalone
    Description: Runs an HTTP server locally which serves the necessary validation files under the /.well-known/acme-challenge/ request path. Suitable if there is no HTTP server already running. HTTP challenge only (wildcards not supported).
    Interfaces: Authenticator, Plugin
    Entry point: EntryPoint(name='standalone', value='certbot._internal.plugins.standalone:Authenticator', group='certbot.plugins')
    Initialized: <certbot._internal.plugins.standalone.Authenticator object at 0x7f1c2f226fa0>
    Prep: True
    ......
    2025-01-01 01:13:43,818:DEBUG:certbot.display.ops:Validator rejected "" when prompting for "Input the webroot for www.sierracloud.kro.kr:"
    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/certbot/display/ops.py", line 339, in _get_validated
        validator(raw)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 343, in _validate_webroot
        raise errors.PluginError(webroot_path + " does not exist or is not a directory")
    certbot.errors.PluginError:  does not exist or is not a directory
    2025-01-01 01:13:43,820:DEBUG:certbot._internal.display.obj:Notifying user:  does not exist or is not a directory
    2025-01-01 01:13:52,401:DEBUG:certbot._internal.error_handler:Encountered exception:
    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/certbot/_internal/auth_handler.py", line 88, in handle_authorizations
        resps = self.auth.perform(achalls)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 112, in perform
        self._set_webroots(achalls)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 129, in _set_webroots
        new_webroot = self._prompt_for_webroot(achall.domain,
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 151, in _prompt_for_webroot
        webroot = self._prompt_for_new_webroot(domain, True)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 178, in _prompt_for_new_webroot
        raise errors.PluginError(
    certbot.errors.PluginError: Every requested domain must have a webroot when using the webroot plugin.
    
    2025-01-01 01:13:52,401:DEBUG:certbot._internal.error_handler:Calling registered functions
    2025-01-01 01:13:52,401:INFO:certbot._internal.auth_handler:Cleaning up challenges
    2025-01-01 01:13:52,402:DEBUG:certbot._internal.plugins.webroot:All challenges cleaned up
    2025-01-01 01:13:52,402:DEBUG:certbot._internal.log:Exiting abnormally:
    Traceback (most recent call last):
      File "/bin/certbot", line 8, in <module>
        sys.exit(main())
      File "/usr/lib/python3.9/site-packages/certbot/main.py", line 19, in main
        return internal_main.main(cli_args)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 1894, in main
        return config.func(config, plugins)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 1600, in certonly
        lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 143, in _get_and_save_cert
        lineage = le_client.obtain_and_enroll_certificate(domains, certname)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 517, in obtain_and_enroll_certificate
        cert, chain, key, _ = self.obtain_certificate(domains)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 428, in obtain_certificate
        orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 496, in _get_order_and_authorizations
        authzr = self.auth_handler.handle_authorizations(orderr, self.config, best_effort)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/auth_handler.py", line 88, in handle_authorizations
        resps = self.auth.perform(achalls)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 112, in perform
        self._set_webroots(achalls)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 129, in _set_webroots
        new_webroot = self._prompt_for_webroot(achall.domain,
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 151, in _prompt_for_webroot
        webroot = self._prompt_for_new_webroot(domain, True)
      File "/usr/lib/python3.9/site-packages/certbot/_internal/plugins/webroot.py", line 178, in _prompt_for_new_webroot
        raise errors.PluginError(
    certbot.errors.PluginError: Every requested domain must have a webroot when using the webroot plugin.
    2025-01-01 01:13:52,404:ERROR:certbot._internal.log:Every requested domain must have a webroot when using the webroot plugin.

    사용중인 Apache의 경우 설치시 selinux의 정책에 자동으로 추가 되어 허용 되었지만 certbot이 도메인 인증시 사용되는 80, 443 포트용 프로세스는 selinux에 정책이 등록 되지 않아 차단 되는 것으로 보입니다.
    정책 추가보다는 selinux를 통한 제어가 불필요 하기 때문에 비활성화 처리 하도록 하겠습니다.

    [root@test ~]# vi /etc/sysconfig/selinux
    SELINUX=disabled
    
    [root@test ~]# init 6
    
    # 재기동 이후 selinux 상태 확인
    [root@test ~]# sestatus -v
    SELinux status:                 disabled

    certbot을 통해 Let’s Encrypt 인증서 재생성을 진행해보도록 하겠습니다.

    [root@test ~]# sudo certbot certonly --cert-name sierracloud.kro.kr -d www.sierracloud.kro.kr
    
    2025-01-01 01:15:55,925:DEBUG:certbot._internal.main:certbot version: 2.11.0
    2025-01-01 01:15:55,926:DEBUG:certbot._internal.main:Location of certbot entry point: /bin/certbot
    2025-01-01 01:15:55,926:DEBUG:certbot._internal.main:Arguments: ['--cert-name', 'sierracloud.kro.kr', '-d', 'www.sierracloud.kro.kr', '-v']
    2025-01-01 01:15:55,926:DEBUG:certbot._internal.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
    2025-01-01 01:15:55,932:DEBUG:certbot._internal.log:Root logging level set at 20
    2025-01-01 01:15:55,933:DEBUG:certbot._internal.plugins.selection:Requested authenticator None and installer None
    2025-01-01 01:15:55,933:DEBUG:certbot._internal.plugins.selection:Multiple candidate plugins: * standalone
    Description: Runs an HTTP server locally which serves the necessary validation files under the /.well-known/acme-challenge/ request path. Suitable if there is no HTTP server already running. HTTP challenge only (wildcards not supported).
    Interfaces: Authenticator, Plugin
    Entry point: EntryPoint(name='standalone', value='certbot._internal.plugins.standalone:Authenticator', group='certbot.plugins')
    Initialized: <certbot._internal.plugins.standalone.Authenticator object at 0x7fbbdcb02fa0>
    Prep: True
    ......
    2025-01-01 01:16:06,980:DEBUG:certbot._internal.display.obj:Notifying user:
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/sierracloud.kro.kr/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/sierracloud.kro.kr/privkey.pem
    This certificate expires on 2025-03-31.
    These files will be updated when the certificate renews.
    Certbot has set up a scheduled task to automatically renew this certificate in the background.
    2025-01-01 01:16:06,982:DEBUG:certbot._internal.display.obj:Notifying user: If you like Certbot, please consider supporting our work by:
     * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
     * Donating to EFF:                    https://eff.org/donate-le
    2025-01-01 01:16:36,715:DEBUG:certbot._internal.main:certbot version: 2.11.0
    2025-01-01 01:16:36,715:DEBUG:certbot._internal.main:Location of certbot entry point: /bin/certbot
    2025-01-01 01:16:36,715:DEBUG:certbot._internal.main:Arguments: []
    2025-01-01 01:16:36,715:DEBUG:certbot._internal.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
    2025-01-01 01:16:36,722:DEBUG:certbot._internal.log:Root logging level set at 30
    2025-01-01 01:16:36,735:DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): e5.o.lencr.org:80
    2025-01-01 01:16:36,925:DEBUG:urllib3.connectionpool:http://e5.o.lencr.org:80 "POST / HTTP/1.1" 200 345
    2025-01-01 01:16:36,926:DEBUG:certbot.ocsp:OCSP response for certificate /etc/letsencrypt/live/sierracloud.kro.kr/cert.pem is signed by the certificate's issuer.
    2025-01-01 01:16:36,927:DEBUG:certbot.ocsp:OCSP certificate status for /etc/letsencrypt/live/sierracloud.kro.kr/cert.pem is: OCSPCertStatus.GOOD
    2025-01-01 01:16:36,929:DEBUG:certbot._internal.display.obj:Notifying user: Found the following certs:
      Certificate Name: sierracloud.kro.kr
        Serial Number: 31398fee84f098d5790169b382cc7eb2878
        Key Type: ECDSA
        Domains: www.sierracloud.kro.kr
        Expiry Date: 2025-03-31 15:17:34+00:00 (VALID: 89 days)
        Certificate Path: /etc/letsencrypt/live/sierracloud.kro.kr/fullchain.pem
        Private Key Path: /etc/letsencrypt/live/sierracloud.kro.kr/privkey.pem

    실패 없이 완료 되었습니다!