도커 컨테이너 안에서 urllib3
로 외부 HTTP 요청시 다음과 같은 SSL 에러가 발생하였다.
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='어떤 호스트', port=443):
Max retries exceeded with url: 어떤 URL (Caused by SSLError)
SSLCertVerificationError certificate verify failed:
self signed certificate in certificate chain
또는
unable to get local issuer certificate
urllib3
에서 HTTPS 요청 수행을 위해 HTTPSConnectionPool
을 만드는 과정에서 호스트로부터 certificate 정보를 가져오는데 실패하는 문제에서 비롯되었다.
삽질 끝에 해결하는데 이 스택오버플로우 글이 큰 도움이 되었다.
일부 도커 베이스 이미지에서는 ca-certificates
패키지가 구식인 경우가 있다. 이 경우 urllib3가 제대로 인증서 정보를 가져오지 못한다. 도커파일 안에 다음 구문을 추가해 최신버젼으로 업데이트하면 해결된다.
# for SSL
RUN apt-get update && apt-get install -y ca-certificates
여전히 에러가 발생한다면 ca-certificates
에 수작업으로 인증 정보(crt 파일)를 등록해야한다. letsencrypt
를 사용하는 경우엔 발급된 cert.pem
파일에 해당한다. 도커를 실행하는 호스트 서버 상에서 다음 명령을 실행한다.
sudo cp /etc/letsencrypt/live/{도메인명}/cert.pem /usr/local/share/ca-certificates/my-ca.crt
sudo update-ca-certificates
다음과 같이 나타나면 성공이다.
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
에러만 빨리 없애야 하는경우 다음과 같이 설정해 ssl을 조용하게 할 수 있으나 보안 문제를 야기할 수 있다. 스택오버플로우 글 참조
import ssl
import urllib3
http = urllib3.PoolManager(cert_reqs=ssl.CERT_NONE)
http.request(...)