Ubuntu 24.04 self-signed 인증서 생성 및 설정 방법
Ubuntu 24.04에서 Chrome이 신뢰하는 self-signed TLS 인증서를 생성합니다. OpenSSL 3.0.x 기반의 SAN 설정부터 nginx 및 Apache 연동, curl -k 없이 인증서를 신뢰하도록 만드는 방법까지 상세히 다룹니다.
구축 목표
최신 브라우저와 클라이언트가 수용 가능한 self-signed TLS 인증서를 구축합니다. 올바른 subjectAltName 설정, 적절한 key 권한, nginx 또는 Apache 연동을 포함합니다. 또한 대부분의 가이드에서 생략하는 핵심 요소인, 클라이언트가 경고를 무시하거나 스크립트에 curl -k를 하드코딩하는 대신 인증서를 올바르게 신뢰하도록 만드는 방법을 다룹니다. 최종적으로는 내부 서비스가 늘어날 때 사용할 수 있는 5개의 명령어로 구성된 private CA를 구축합니다.
먼저 결정이 필요합니다. self-signed 인증서는 실제 사용 사례보다 과하게 사용되는 경우가 많기 때문입니다. 서비스가 실제 DNS 이름을 통해 공용 인터넷에서 접근 가능하다면, 이 글을 읽는 것을 중단하고 nginx에서 certbot을 사용한 무료 Let's Encrypt 인증서 또는 Apache용 대체 방법을 사용하십시오. 비용이 들지 않고 자동으로 갱신되며, 모든 브라우저가 이미 이를 신뢰합니다. 공용 사이트에서 self-signed 인증서를 사용하는 것은 사용자에게 보안 경고를 무시하는 습관을 길러주며, 이는 일반 HTTP를 사용하는 것보다 더 나쁜 습관입니다.
self-signed 방식은 공용 인터넷을 사용할 수 없는 환경에서 적합합니다. VPS의 WireGuard 터널 주소에 연결된 관리 패널, 프라이빗 네트워크의 staging 서버, 백엔드 간의 service-to-service 트래픽, 홈랩 장치, 또는 Webmin이 port 10000에서 자체 생성하는 임시 인증서 대체 등이 해당됩니다. Let's Encrypt는 10.8.0.1 또는 git.internal.lan에 대해 인증서를 발급할 수 없습니다. 어떤 공용 CA도 인증서에 프라이빗 IP나 임의의 TLD를 포함하지 않습니다. 이러한 도메인에 대해서는 사용자가 직접 CA가 되어야 합니다.
이하의 모든 과정은 OpenSSL 3.0.x(openssl version로 확인)가 설치된 신규 Ubuntu 24.04 환경에서 진행됩니다. 인터넷 연결은 필요하지 않으며, air-gapped 환경에서도 작동합니다.
기존의 한 줄 명령어가 Chrome에서 거부되는 이유
2017년 이전의 모든 튜토리얼에서 제공하는 명령어는 다음과 같습니다:
# Do not run this — shown so you recognise it in old guides
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout selfsigned.key -out selfsigned.crt이 명령어는 일련의 대화형 질문을 수행하며, Common Name 필드에 hostname을 입력합니다. 또한 subjectAltName 확장자가 없는 인증서를 생성합니다. 해당 인증서는 사용할 수 없습니다. Chrome은 2017년 4월 버전 58부터 Common Name를 읽지 않습니다. RFC 2818은 이미 2000년에 CN 매칭 방식을 폐기했습니다. Firefox, Safari, curl, Python도 동일하게 동작합니다. 인증서는 SAN 확장을 통해 서버를 식별하며, 그렇지 않으면 식별할 수 없습니다. 브라우저는 다음과 같은 메시지를 표시합니다:
NET::ERR_CERT_COMMON_NAME_INVALID
This server could not prove that it is git.internal.lan; its security
certificate does not specify Subject Alternative Names.신뢰 저장소(trust-store)를 수정해도 이 오류는 해결되지 않습니다. 인증서에 이름 정보가 없기 때문입니다. 현재 NET::ERR_CERT_COMMON_NAME_INVALID 오류를 보고 있다면, 인증서에 SAN이 없거나 잘못된 SAN이 포함된 것입니다. 따라서 새 인증서를 생성해야 합니다. 다행히 해결 방법은 명령어 하나로 가능합니다.
브라우저가 수락하는 인증서 생성: 한 줄 명령어
OpenSSL 1.1.1에서 -addext flag가 추가되었습니다. 이제 SAN을 삽입하기 위해 기존 가이드에서 사용하던 복잡한 config-file 설정이 필요하지 않습니다. Ubuntu 24.04 기준 예시는 다음과 같습니다:
sudo openssl req -x509 -newkey rsa:4096 -sha256 -days 730 -noenc \
-keyout /etc/ssl/private/git.internal.key \
-out /etc/ssl/certs/git.internal.crt \
-subj "/CN=git.internal.lan" \
-addext "subjectAltName=DNS:git.internal.lan,IP:10.8.0.1"각 flag의 역할:
-x509은 인증서 서명 요청(CSR) 대신 자가 서명 인증서를 직접 생성합니다.-newkey rsa:4096은 동일한 단계에서 새로운 키를 생성합니다. RSA 4096은 구형 클라이언트와도 호환됩니다. 모든 연결 대상이 최신 사양이라면-newkey ec -pkeyopt ec_paramgen_curve:P-256이 크기가 더 작고 속도가 빠릅니다.-noenc은 기존-nodes의 OpenSSL 3.x 표기법입니다. 키에 passphrase를 설정하지 않습니다. 두 표기법 모두 작동합니다. passphrase가 설정된 키는 nginx가 부팅될 때마다 입력을 기다리며 멈추게 되므로, 서버용 키에는 이 옵션이 필요합니다.-days 730은 유효 기간인 2년을 의미합니다. 자세한 내용은 만료 섹션을 참조하십시오.-subj은 대화형 질문에 자동으로 응답합니다. CN은 현재 장식적인 용도이지만, 가급적 기본 이름을 설정하십시오. 일부 도구에서 이를 표시합니다.-addext "subjectAltName=..."은 가장 중요한 flag입니다. 클라이언트가 입력할 모든 이름과 모든 IP를 나열하십시오: 호스트 이름용DNS:항목(DNS:*.internal.lan와 같은 wildcard 허용), 주소용IP:항목. 만약 사용자가https://10.8.0.1으로 접속한다면, 반드시IP:10.8.0.1항목이 포함되어야 합니다. DNS 전용 SAN만 설정하면NET::ERR_CERT_COMMON_NAME_INVALID오류가 다시 발생합니다.
설정을 적용하기 전에 SAN이 제대로 포함되었는지 확인하십시오:
openssl x509 -in /etc/ssl/certs/git.internal.crt -noout -ext subjectAltName올바른 출력 결과:
X509v3 Subject Alternative Name:
DNS:git.internal.lan, IP Address:10.8.0.1만약 No extensions in certificate이 출력된다면, 해당 인증서에는 SAN이 없는 것이며 브라우저가 이를 거부합니다. 계속 진행하지 말고 인증서를 다시 생성하십시오.
키 보안 설정
시스템의 모든 사용자가 읽을 수 있는 private key는 더 이상 private key가 아닙니다. Ubuntu에서 /etc/ssl/private은(는) 이미 710 root:ssl-cert 상태이므로 일반적인 노출은 방지되지만, 파일 권한을 명시적으로 설정하십시오.
sudo chown root:root /etc/ssl/private/git.internal.key
sudo chmod 600 /etc/ssl/private/git.internal.keynginx와 Apache는 권한을 낮추기 전에 root 권한으로 인증서를 읽습니다. 따라서 이 서비스들에는 root:root 모드 600이 적합합니다. 만약 키가 자체 사용자 권한으로 실행되는 서비스(Node app, Gitea, Python daemon 등)에서 직접 로드하는 용도라면, 해당 서비스 사용자에게 chown 하십시오. 이때도 모드는 600으로 설정해야 합니다. 절대 해서는 안 되는 작업은 다음과 같습니다: 모드를 644로 설정하는 것, git repository에 복사하는 것, 또는 /tmp에 복사하는 것입니다.
nginx에 연결하기
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name git.internal.lan;
ssl_certificate /etc/ssl/certs/git.internal.crt;
ssl_certificate_key /etc/ssl/private/git.internal.key;
location / {
proxy_pass http://127.0.0.1:3000;
}
}sudo nginx -t && sudo systemctl reload nginxnginx -t은(는) reload가 실행되기 전에 syntax is ok 및 test is successful을(를) 출력해야 합니다. 만약 SSL_CTX_use_PrivateKey_file() failed ... key values mismatch이(가) 출력된다면, 인증서와 키가 서로 다른 생성 주기에 만들어진 것입니다. 자세한 내용은 failure-modes 섹션을 참조하십시오.
Wire it into Apache
sudo a2enmod ssl proxy proxy_http이 단계에서는 ssl만으로는 부족합니다. 아래의 vhost는 ProxyPass을 사용합니다. mod_proxy와 mod_proxy_http이 없으면 설정 테스트 시 Invalid command 'ProxyPass', perhaps misspelled or defined by a module not included in the server configuration 오류가 발생합니다. vhost를 /etc/apache2/sites-available/git-internal.conf으로 저장하십시오.
<VirtualHost *:443>
ServerName git.internal.lan
SSLEngine on
SSLCertificateFile /etc/ssl/certs/git.internal.crt
SSLCertificateKeyFile /etc/ssl/private/git.internal.key
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>sudo a2ensite git-internal
sudo apache2ctl configtest && sudo systemctl reload apache2configtest은 Syntax OK에 응답해야 합니다. 이제 클라이언트 머신에서 테스트를 수행하십시오.
curl -v https://git.internal.lan/그러면 다음과 같은 오류가 발생합니다.
curl: (60) SSL certificate problem: self-signed certificate이는 버그가 아닙니다. TLS가 정상 작동하고 있다는 의미입니다. curl은 해당 인증서를 알지 못하므로 인증할 수 없는 서버와의 통신을 거부합니다. 다음 섹션에서 실제 해결 방법을 다룹니다. 이 방법은 현재 인터넷상의 많은 사용자가 사용하는 방식과는 다릅니다.
클라이언트가 신뢰하도록 설정하기 — 피해야 할 안티 패턴
잘못된 해결 방법들을 먼저 나열합니다. 스크립트에 포함된 curl -k (또는 --insecure), Python requests의 verify=False, Node의 NODE_TLS_REJECT_UNAUTHORIZED=0 모두 인증서를 신뢰하게 만들지 못합니다. 이러한 방식은 인증서 검증을 비활성화합니다. 즉, 클라이언트가 공격자가 삽입한 인증서를 포함하여 모든 인증서를 제시하는 어떤 서버와도 통신하게 됩니다. TLS의 오버헤드는 그대로 유지하면서, TLS의 목적인 인증 기능은 상실하게 됩니다. 더 심각한 문제는 이러한 플래그가 확산된다는 점입니다. 하나의 cron job에 붙여넣어지면, 배포 스크립트로, 다시 운영 코드(production code)로 전파되어 결국 어떤 연결이 임시용이었는지 아무도 알 수 없게 됩니다. 만약 verify=False가 디버깅 세션 이후에도 남아 있다면, 설계가 잘못된 것입니다.
올바른 해결 방법은 각 클라이언트 OS에 이 인증서가 신뢰할 수 있는 루트(trusted root)임을 알려주는 것입니다. Ubuntu 및 Debian 클라이언트의 경우:
sudo cp git.internal.crt /usr/local/share/ca-certificates/git.internal.crt
sudo update-ca-certificates출력 내용 중 중요한 줄입니다 (이후에 Running hooks in /etc/ca-certificates/update.d... 블록이 이어집니다):
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.이 줄에는 두 가지 주의 사항이 있습니다. 파일은 반드시 .crt로 끝나야 합니다. .pem 확장자는 무시되며, 오류 메시지 없이 0 added이 발생합니다. 또한 콘텐츠는 PEM 형식이어야 합니다. 파일은 -----BEGIN CERTIFICATE-----으로 시작해야 합니다. DER 바이너리는 openssl x509 -inform der -in file.der -out file.crt을 사용하여 먼저 변환하십시오. 셀프 사인(self-signed) 인증서 자체를 루트로 추가하는 방식은 유효합니다. 셀프 사인 인증서는 그 자체로 루트이기 때문입니다.
이 작업을 완료하면 curl, wget, git, apt 및 시스템 번들을 사용하여 OpenSSL을 사용하는 모든 도구는 플래그 없이도 서버를 신뢰합니다. 일부 클라이언트는 자체 신뢰 저장소(trust stores)를 사용하므로 개별 처리가 필요합니다:
- Linux의 Chrome/Chromium은 시스템 저장소가 아닌 NSS 데이터베이스를 읽습니다:
sudo apt install libnss3-tools, 그 다음 사용자별로certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "git.internal" -i git.internal.crt를 수행합니다. - Firefox는 자체 저장소를 가집니다: Settings → Privacy & Security → Certificates → Import를 사용하거나,
about:config에서security.enterprise_roots.enabled를true으로 변경하여 시스템 저장소를 읽도록 설정합니다. - Python requests는 자체 CA 번들(certifi)을 포함하며 시스템 저장소를 무시합니다:
verify="/usr/local/share/ca-certificates/git.internal.crt"을 전달하거나REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt를 내보냅니다(export). - Node.js:
NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/git.internal.crt를 내보냅니다(export).
Windows 클라이언트에서는 .crt을 더블 클릭한 후 Trusted Root Certification Authorities에 설치하십시오. macOS에서는 Keychain Access의 System 키체인에 추가하고 Always Trust로 설정하십시오.
One root for many services: a small private CA
인증서별로 신뢰를 설정하면 확장이 불가능합니다. 서비스 6개와 클라이언트 4대만 있어도 24번의 신뢰 설치 작업이 필요하며, 서비스가 추가될 때마다 작업량은 늘어납니다. 해결책은 private CA를 사용하는 것입니다. 클라이언트는 하나의 root를 신뢰하며, 각 서비스의 인증서는 이 root로 서명합니다.
간편한 옵션은 mkcert입니다. 이 패키지는 Ubuntu 24.04 레포지토리에 포함되어 있으며, update-ca-certificates이 처리하지 못하는 NSS store(Chrome, Firefox)를 관리합니다.
sudo apt install -y mkcert libnss3-tools
mkcert -install
mkcert git.internal.lan "*.internal.lan" 10.8.0.1mkcert -install는 root를 생성하고 해당 머신의 모든 trust store에 등록합니다. 세 번째 명령은 git.internal.lan+2.pem와 git.internal.lan+2-key.pem을 생성하며, 이는 위에서 설명한 nginx 또는 Apache 설정에 바로 사용할 수 있습니다. 이 도구는 개발용 머신을 상정하여 설계되었습니다. root key는 -install을 실행한 머신에 저장되므로, 개발용 노트북에는 적합하지만 서버 군(fleet)에는 적합하지 않습니다.
서버의 경우, 일반 OpenSSL을 사용하여 5개의 명령으로 CA를 구축할 수 있습니다.
openssl genrsa -out lab-ca.key 4096
openssl req -x509 -new -key lab-ca.key -sha256 -days 3650 \
-out lab-ca.crt -subj "/CN=Lab Internal CA" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
openssl genrsa -out git.key 2048
openssl req -new -key git.key -out git.csr -subj "/CN=git.internal.lan" \
-addext "subjectAltName=DNS:git.internal.lan,IP:10.8.0.1"
openssl x509 -req -in git.csr -CA lab-ca.crt -CAkey lab-ca.key \
-CAcreateserial -days 730 -sha256 -copy_extensions copy -out git.crt마지막 명령에 주의하십시오. openssl x509 -req은 기본적으로 CSR에서 모든 extension을 제거합니다. 여기에는 사용자가 추가한 SAN도 포함됩니다. -copy_extensions copy(OpenSSL 3.x 옵션이므로 24.04에서 작동함)를 사용하면 extension을 유지할 수 있습니다. 이 옵션을 생략하면 서명된 인증서에 SAN이 포함되지 않으며, Chrome에서 다시 NET::ERR_CERT_COMMON_NAME_INVALID 오류가 발생합니다. 이전과 동일하게 openssl x509 -noout -ext subjectAltName 명령으로 확인하십시오.
위의 trust-store 단계를 통해 클라이언트에 lab-ca.crt를 배포하십시오. 머신당 한 번만 수행하면 됩니다. 이제 보물처럼 lab-ca.key을 보호해야 합니다. 권한은 600으로 설정하고, 가급적 서명 대상인 서버가 아닌 별도의 머신에 보관하십시오. 해당 키를 가진 사람은 클라이언트가 신뢰할 수 있는 모든 이름에 대해 인증서를 생성할 수 있기 때문입니다.
Expiry and rotation
Public CA 인증서의 유효 기간이 단축되고 있습니다. CA/Browser Forum은 2026년 3월에 신규 발행되는 공인 인증서의 유효 기간을 398일에서 200일로 제한했습니다. 이 기간은 2027년에는 100일로, 2029년 3월에는 47일로 줄어들 예정입니다. 하지만 이 규칙은 공인(publicly trusted) CA에만 적용됩니다. 사설 CA는 이 규칙의 적용을 받지 않으며, 브라우저도 수동으로 설치된 루트 인증서에 대해 이 규칙을 강제하지 않습니다. 다만 한 가지 실제 사례가 있습니다. Apple 플랫폼은 발행 주체와 상관없이 유효 기간이 825일을 초과하는 TLS 서버 인증서를 거부합니다. 따라서 iPhone이나 Mac과의 연결이 필요하다면, leaf certificate의 유효 기간을 2년 이하로 유지하십시오. -days 730를 사용하면 모든 환경에서 이 기준을 충족할 수 있습니다. 10년 유효 기간의 root와 2년 유효 기간의 leaf 조합은 내부망에서 안정적인 구성입니다.
유효 기간이 긴 인증서는 한 가지 방식으로 문제를 일으킵니다. 아무도 선택한 적 없는 날짜에 모든 인증서가 동시에, 조용히 만료됩니다. 현재 상태를 확인하십시오:
openssl x509 -in /etc/ssl/certs/git.internal.crt -noout -enddate갱신 일정을 실제 달력에 기록하거나, cron을 사용하여 30일 전에 알림을 받도록 설정하십시오. openssl x509 -checkend 2592000 -in cert.crt는 만료까지 남은 시간이 해당 초(seconds) 이내이면 0이 아닌 값을 반환하며 종료됩니다. 이미 Uptime Kuma를 상태 모니터링용으로 사용 중이라면, HTTPS 모니터링 기능을 통해 인증서 만료 임박 알림을 무료로 받을 수 있습니다.
사설 CA를 이용한 인증서 교체(Rotation) 과정은 매우 단순합니다. CSR 생성 및 서명 명령어를 다시 실행하고, 파일을 교체한 뒤, 웹 서버를 재시작하십시오. Root 인증서가 변경되지 않았으므로 클라이언트 측에서는 아무런 변화를 감지하지 못합니다.
Failure modes, with the strings you will see
NET::ERR_CERT_AUTHORITY_INVALID — 인증서를 설치하기 전의 정상적인 상태이며, 인증서 결함이 아닙니다. 루트 인증서를 설치한 후에도 이 상태가 지속된다면 다음 원인을 확인하십시오: Linux의 경우 Chrome은 시스템 저장소 대신 NSS를 사용합니다 (certutil 단계 참조). 또는 복사된 파일이 .crt으로 끝나지 않았고 update-ca-certificates에서 0 added이 발생한 경우입니다. 혹은 서버가 신뢰 설정한 인증서와 다른 인증서를 제시하는 경우입니다. openssl s_client -connect git.internal.lan:443 </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256을 사용하여 지문(fingerprint)을 비교하십시오.
NET::ERR_CERT_COMMON_NAME_INVALID — 인증서에 SAN이 없거나, SAN에 포함된 이름이 주소창의 이름과 일치하지 않습니다. 대표적인 사례는 SAN에는 DNS:git.internal.lan이 포함되어 있으나 사용자가 https://10.8.0.1으로 접속하는 경우입니다. 신뢰 저장소(trust-store) 변경으로는 해결할 수 없으며, 누락된 항목을 포함하여 인증서를 재발급해야 합니다.
curl: (60) SSL certificate problem: self-signed certificate — curl이 인증서를 신뢰하지 않습니다. 사설 CA로 서명된 인증서의 경우 self-signed certificate in certificate chain 오류도 동일한 의미입니다. 일시적인 해결 방법은 curl --cacert lab-ca.crt https://...을 사용하는 것이며, 영구적인 해결 방법은 신뢰 저장소에 등록하는 것입니다. -k은 해결 방법이 아닙니다.
unable to load certificate ... Expecting: TRUSTED CERTIFICATE (또는 Expecting: CERTIFICATE REQUEST, 또는 no start line) — PEM 형식 오류입니다. OpenSSL에 잘못된 형식의 파일을 제공한 경우입니다. 인증서가 필요한 위치에 key 또는 CSR을 입력했거나, PEM이 필요한 위치에 DER 바이너리를 입력했습니다. head -1 filename을 통해 실제 파일 형식을 확인할 수 있습니다. 인증서는 -----BEGIN CERTIFICATE-----으로 시작합니다. DER 형식은 openssl x509 -inform der -in file.der -out file.crt를 사용하여 변환하십시오.
nginx: [emerg] SSL_CTX_use_PrivateKey_file(...) failed (SSL: error ... key values mismatch) — 인증서와 키가 서로 일치하지 않습니다. 대개 생성 명령어를 두 번 실행하여 파일이 섞였을 때 발생합니다. openssl x509 -in git.internal.crt -noout -pubkey | sha256sum과 openssl pkey -in git.internal.key -pubout | sha256sum을 비교하여 확인하십시오. 해시 값이 일치하면 동일한 쌍입니다. 해시 값이 다르면 두 파일을 함께 다시 생성하십시오.
FAQ
self-signed certificate를 생성한 후에도 Chrome에서 "Not secure"라고 표시되는 이유는 무엇입니까?
오류 코드가 NET::ERR_CERT_AUTHORITY_INVALID인 경우 인증서는 정상입니다. Chrome이 해당 인증서를 신뢰할 근거가 없기 때문입니다. 인증서(또는 개인 CA root)를 클라이언트의 trust store에 설치하십시오. Linux에서 Chrome은 시스템 store가 아닌 certutil를 통한 NSS database를 사용한다는 점에 유의하십시오. 오류 코드가 NET::ERR_CERT_COMMON_NAME_INVALID인 경우, 인증서에 URL과 일치하는 Subject Alternative Name이 누락된 것입니다. -addext "subjectAltName=..."를 사용하여 인증서를 재발급해야 합니다.
-k 옵션 없이 curl이 self-signed certificate를 신뢰하게 하려면 어떻게 합니까?
인증서(PEM 형식, .crt 확장자)를 /usr/local/share/ca-certificates/로 복사한 후 sudo update-ca-certificates를 실행하십시오. 출력 결과에 1 added가 표시되어야 합니다. 이후 curl은 일반 공인 인증서와 동일하게 해당 인증서를 검증합니다. 시스템을 수정하지 않고 일회성 요청을 수행하려면 curl --cacert /path/to/cert.crt를 사용하여 해당 파일만 검증하십시오. -k는 검증을 완전히 비활성화하며, 스크립트 작성 시 사용해서는 안 됩니다.
self-signed certificate의 유효 기간은 얼마나 길게 설정할 수 있습니까?
기술적으로는 원하는 만큼 길게 설정할 수 있습니다. CA/Browser Forum의 제한(현재 200일, 2029년까지 47일)은 공인 CA에 적용되며, 개인 신뢰 체계에는 적용되지 않습니다. 실제 운영 시에는 서버 인증서 기간을 825일로 제한하십시오. Apple 기기는 발행자와 관계없이 이보다 긴 인증서를 거부합니다. 10년 유효한 private root와 2년 유효한(-days 730) leaf certificate 조합이 권장되는 기본 설정입니다. 내부 인증서가 만료되면 아무도 모르는 날짜에 모든 서비스가 중단되므로 갱신 일정을 반드시 관리하십시오.
self-signed certificate를 사용해야 합니까, 아니면 Let's Encrypt를 사용해야 합니까?
서비스가 공인 DNS 이름을 가지고 인터넷에서 접속 가능하다면 항상 Let's Encrypt를 사용하십시오. 무료이며 자동화되어 있고 모든 클라이언트가 이미 신뢰합니다. self-signed(또는 private CA)는 Let's Encrypt가 발급할 수 없는 경우에 사용합니다. 예로는 private IP, .lan와 같은 내부 전용 호스트 이름, air-gapped 네트워크, VPN 뒤에 의도적으로 숨겨진 서비스 등이 있습니다. 결정 기준은 보안 강도가 아니라 도달 가능성과 네이밍입니다. 암호화 수준은 동일합니다.
/usr/local/share/ca-certificates에 인증서를 추가했는데도 거부되는 이유는 무엇입니까?
다음 세 가지를 확인하십시오. 파일 확장자가 .crt이어야 합니다. .pem 확장자는 무시되며 update-ca-certificates에서 0 added 오류가 보고됩니다. 파일 내용은 DER 바이너리가 아닌 -----BEGIN CERTIFICATE-----로 시작하는 PEM 텍스트여야 합니다. 마지막으로, 애플리케이션이 실제로 시스템 store를 사용하는지 확인하십시오. Linux의 Chrome, Firefox, Python requests, Node.js, Java는 각각 별도의 trust store를 사용하므로 인증서를 각각 따로 추가해야 합니다.