자동 SSL 및 Let's Encrypt & Nginx
11524 단어 securityarchitecturetutorialdocker
주: 2020년 12월에
letsencrypt-nginx-proxy-companion
프로젝트의 v2가 발표되었습니다.이 점을 반영하기 위해 이 글을 업데이트했지만, 페이지 밑에 오래된 v1 코드를 보존할 것입니다.기존 시스템을 현재 위치에서 업그레이드해야 하는 경우 nginx-proxy/docker-letsencrypt-nginx-proxy-companion 저장소를 참조하십시오.2016년 이후 인증서 발급기관인 렛's Encrypt는 암호화 통신이 네트워크에 없는 곳이 없도록 무료 SSL/TLS 인증서를 제공했다.만약 당신이 증서를 구매한 적이 있다면, 증서는 보통 매우 비싸다는 것을 알게 될 것이다. 증서를 검증하는 과정은 엉덩이 근육의 고통이고, 그 증서는 휴가를 보낼 때 기한이 지나 정지된다는 것을 알게 될 것이다.
Let's Encrypt가 있으면 모든 문제가 사라집니다. 이것은 자동화 인증서 관리 환경(ACME) 프로토콜 덕분입니다. 이 프로토콜은 인증서의 검증과 배치를 자동화하여 자금과 시간을 절약할 수 있습니다.ACME 자체가 흥미로운 화제입니다. 다양한 검증 방법 (도전이라고 함) here에 대한 정보를 더 많이 읽을 수 있지만, 오늘은 자동 인증서 생성, 검증, 배치를 통해 역방향 에이전트를 쉽게 설정할 수 있는 방법을 보여 드리겠습니다.
우리가 해야 할 첫 번째 일은 user defined bridge network이라는
service-network
을 만드는 것이다.나는 사물에 이름을 붙이는 것을 잘하지 못하지만, 이것은 적용되는 것 같다.docker network create --subnet 10.10.0.0/24 service-network
다음에 우리는 역방향 에이전트를 설정할 것이다.역방향 에이전트는 요청만 받아들이고 루트 규칙 (예를 들어 어떤 호스트 이름이 어떤 서비스 용기로 옮겨야 하는지) 에 따라 다른 서비스로 에이전트합니다.나는 그것이 약간 이렇게 보인다고 생각한다.
Jason Wilder 이미지 jwilder/nginx-proxy을 사용하겠습니다.이것은 유지 보수가 좋은 프로젝트로 많은 문서가 있다.포트 80과 443을 컨테이너에 매핑하여 HTTP 및 HTTPS 연결을 처리합니다.우리도 많은 볼륨이 있는데, 세 개는 표준 docker 볼륨이고, 하나는 docker daemon UNIX socket이다.
스크립트에서 긴 형식 파라미터를 자주 사용하는 것을 알 수 있습니다.비록 우리는 쉽게 공간을 절약하고 그것을 한 줄에 놓을 수 있지만, 이것은 장래에 스크립트를 유지해야 할 다른 사람들에게 도움이 되지 않을 것이다.
docker run \
--detach \
--restart always \
--publish 80:80 \
--publish 443:443 \
--name nginx-proxy \
--network service-network \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
--volume nginx-certs:/etc/nginx/certs \
--volume nginx-vhost:/etc/nginx/vhost.d \
--volume nginx-html:/usr/share/nginx/html \
jwilder/nginx-proxy
이제 리버스 에이전트가 생겼습니다. 다음은 Let's Encrypt companion을 설정해야 합니다. Yves Blusseau의 이미지 jrcs/letsencrypt-nginx-proxy-companion을 사용할 것입니다.나는 그것을 거의 1년 동안 완벽하게 사용했다.
우리는 같은 볼륨을 이 용기에 비추지만, 어떤 포트도 발표하지 않았다.우리는
NGINX_PROXY_CONTAINER
환경 변수를 프록시 용기의 이름과 일치하도록 설정합니다. 단지 이것뿐입니다.새 서비스 용기가 검출될 때마다 이 용기는 프로세스를 실행하고 인증서를 생성하며 최신으로 유지합니다.docker run \
--detach \
--restart always \
--name nginx-proxy-letsencrypt \
--network service-network \
--volumes-from nginx-proxy \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
--volume /etc/acme.sh \
--env "[email protected]" \
jrcs/letsencrypt-nginx-proxy-companion
마지막으로 서비스 용기를 추가할 때가 되었다.우리는
tutum/hello-world
이미지를 사용할 것이다. 이것은 매우 유행하는 테스트 이미지이다.이를 위해서는 DNS의 호스트 이름을 구성해야 합니다.우리는 hello-world.example.com
을 사용하는 척하고 이 서버의 IP 주소를 가리키는 A
기록을 설정한 척할 것입니다.docker run \
--detach \
--restart always \
--name hello-world \
--network service-network \
--env VIRTUAL_HOST=hello-world.example.com \
--env LETSENCRYPT_HOST=hello-world.example.com \
--env LETSENCRYPT_EMAIL="[email protected]" \
tutum/hello-world
여기서 무슨 일이 일어났는지 봅시다.우리는 감청 포트 80과 443을 위한 에이전트 용기를 설치했다.그런 다음 인증서를 관리하는 ACME 인증서 컨테이너를 설정합니다.그리고 우리는 Hello World 용기를 만들었다.환경 변수
VIRTUAL_HOST
을 호스트 이름으로 설정합니다. 이 용기에 요청한 루트를 요청할 수 있도록 에이전트가 가져옵니다.사용자 정의 브리지 service-network
을 통해 라우팅을 요청합니다.또한 환경 변수 LETSENCRYPT_HOST
과 LETSENCRYPT_EMAIL
을 설정했습니다. 이 변수는 ACME 용기에서 가져오고 인증서를 받을 때 사용됩니다.참고로 두 호스트 이름은 항상 일치해야 합니다(VIRTUAL_HOST
및 LETSENCRYPT_HOST
).우리가 해야 할 일은 이 세 변수를 하나의 용기에 추가하는 것이다. 에이전트와 ACME 용기는 그것을 검출하고, 곧 작동할 것이다.
지금 몇 가지 주의해야 할 일이 있다.포트 검색 - 에이전트는 어떤 포트를 사용해야 하는지 어떻게 알 수 있습니까?우리가 사용하는 Helloworld 이미지는 Dockerfile의 포트가
EXPOSE 80
이라는 것을 보여 줍니다.이것은 항상 우선이기 때문에 이미지에 노출된 포트가 있으면 그것을 사용합니다.단, Dockerfile에 공개된 포트가 정의되어 있지 않거나, 실행할 때 환경 변수 (예: HTTP_PORT=8000
) 를 사용하여 포트를 설정할 수 있다면, --expose
인자를 사용하여 에이전트에게 어떤 포트를 사용할 것인지 알 수 있습니다.사용 가능한 포트가 여러 개인 경우 환경 변수 VIRTUAL_PORT
과 함께 사용할 포트를 지정할 수 있습니다.다시 한 번 말씀드리지만, Dockerfile
EXPOSE
은 --expose
매개 변수보다 우선합니다.현재,
https://hello-world.example.com
을 눌렀을 때, DNS 서버는 공공 IP가 있는 A 기록을 되돌려주고, 브라우저는 포트 443의 IP 주소에 연결한 다음, 호스트는 이 연결을 nginx-proxy
용기에 연결합니다.SSL을 종료하고 요청을 일반 HTTP 요청 에이전트로 hello-world
컨테이너에 프록시합니다.마지막으로 우리는 또 다른 일을 할 수 있다.HTTP에서 HTTPS로의 업그레이드를 프록시로 처리합니다. 이것은 좋지만, 때때로 www/apex 영역을 다시 지정해야 합니다.일부 도메인 등록기 제어판에서 구성할 수 있지만 호스트 이름은 다른 IP 주소를 사용합니다.
이번에 우리가 사용할 이미지는 사실상 나의 것이다. adamkdean/redirect.
그것의 작업 방식은 매우 간단하다.
VIRTUAL_HOST
을 바꿀 영역으로 설정하고 다른 용기의 목표를 설정하십시오.예를 들어 우리는 example.com
이 있는데, 우리는 그것이 항상 www.example.com
으로 바뀌기를 바란다. 왜냐하면 우리는 www를 좋아하기 때문이다.우리의 주요 이미지는
www.example.com
으로 연결되어 있습니다.docker run \
--detach \
--restart always \
--name example-website \
--network service-network \
--env VIRTUAL_HOST=www.example.com \
example/website
그 다음에 우리는 컨테이너를 다시 만들어 example.com
에 귀속시키고 환경 변수 REDIRECT_LOCATION
을 우리의 첫 번째 목표로 설정하며 REDIRECT_STATUS_CODE
을 적용되는 목표로 설정합니다.docker run \
--detach \
--restart always \
--name example-redirect \
--network service-network \
--env VIRTUAL_HOST=example.com \
--env REDIRECT_LOCATION="http://www.example.com" \
--env REDIRECT_STATUS_CODE=301 \
adamkdean/redirect
현재 발생한 것은 example.com
에 대한 요청이 이 리셋 용기에 맞았고 REDIRECT_STATUS_CODE
과 REDIRECT_LOCATION
으로 응답했다.우리는 당연히 Let's Encrypt with the this를 사용할 수 있습니다.
docker run \
--detach \
--restart always \
--name example-website \
--network service-network \
--env VIRTUAL_HOST=www.example.com \
--env LETSENCRYPT_HOST=www.example.com \
--env LETSENCRYPT_EMAIL="[email protected]" \
example/website
docker run \
--detach \
--restart always \
--name example-redirect \
--network service-network \
--env VIRTUAL_HOST=example.com \
--env LETSENCRYPT_HOST=example.com \
--env LETSENCRYPT_EMAIL="[email protected]" \
--env REDIRECT_LOCATION="https://www.example.com" \
--env REDIRECT_STATUS_CODE=301 \
adamkdean/redirect
이 경우 example.com
의 초기 요청 명중 에이전트에 대해 에이전트는 SSL을 중지하고 example-redirect
용기에 에이전트를 주고 이 용기는 301에서 www.example.com
으로 응답한다.현재 www.example.com
의 다음 요청에 대해 에이전트를 클릭하고 example-website
용기를 통해 에이전트를 진행한다. 아래와 같다.나는 이것이 너에게 도움이 되기를 바란다.이 설정은 한 사이트 또는 여러 사이트에서 사용할 수 있습니다.대형 용기 플랫폼을 설치하는 것이 좀 지나친 상황에서 나는 그것을 사용할 것이다. (블로그의kubernetes는 매우 좋다. 그렇지?)
그것은 매우 쉽게 갱신되고 배치되며, 이미 사용된 지 1년이 넘었고, 매우 잘 일한다.읽어주셔서 감사합니다.
업데이트(2020년 2월 21일): 요구에 따라
docker-compose.yml
버전이 있습니다.version: "3"
services:
web:
image: example/website
expose:
- 8000
environment:
HTTP_PORT: 8000
VIRTUAL_HOST: www.example.com
LETSENCRYPT_HOST: www.example.com
LETSENCRYPT_EMAIL: "[email protected]"
networks:
service_network:
web-redirect:
image: adamkdean/redirect
environment:
VIRTUAL_HOST: example.com
LETSENCRYPT_HOST: example.com
LETSENCRYPT_EMAIL: "[email protected]"
REDIRECT_LOCATION: "https://www.example.com"
networks:
service_network:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
container_name: nginx-proxy
networks:
service_network:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- nginx-certs:/etc/nginx/certs
- nginx-vhost:/etc/nginx/vhost.d
- nginx-html:/usr/share/nginx/html
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
environment:
NGINX_PROXY_CONTAINER: "nginx-proxy"
networks:
service_network:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- nginx-certs:/etc/nginx/certs
- nginx-vhost:/etc/nginx/vhost.d
- nginx-html:/usr/share/nginx/html
networks:
service_network:
volumes:
nginx-certs:
nginx-vhost:
nginx-html:
업데이트(2020년 2월 28일):나는 내가
VIRTUAL_PORT
에 대해 이야기할 때 잘못을 저질렀다는 것을 깨달았다.문서를 업데이트했지만, 에이전트가 Docker 파일의 EXPOSE
명령과 Docker 명령줄 인터페이스의 --expose
매개 변수에서 어떤 포트를 사용하는지 알려주고 싶을 뿐입니다.노출된 포트가 여러 개인 경우 VIRTUAL_PORT
환경 변수를 사용하여 노출된 포트를 표시할 수 있습니다.헷갈려서 미안해!
업데이트(2020년 4월 22일):
보안 리디렉션 세션에 부족한 반사봉이 추가되었습니다.아이구!
업데이트(2020년 12월 11일):
letsencrypt nginx proxy companion의 v1 코드입니다.
docker run \
--detach \
--restart always \
--name nginx-proxy-letsencrypt \
--network service-network \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
--volume nginx-certs:/etc/nginx/certs \
--volume nginx-vhost:/etc/nginx/vhost.d \
--volume nginx-html:/usr/share/nginx/html \
--env NGINX_PROXY_CONTAINER="nginx-proxy" \
jrcs/letsencrypt-nginx-proxy-companion:v1.13.1
만약 네가 이 글을 좋아한다면, 너는 나의 다음 글을 좋아할 것이다. 우리는 몇 가지 방법을 깊이 있게 연구할 것이다. 너는 우리가 용기라고 부르는 블랙박스 안에서 도대체 무슨 일이 일어났는지 이해할 수 있다.docker에 대한 설명입니다.sock: docker 수호 프로세스 UNIX 플러그인 (/var/run/docker.sock) 은 docker에 대한 접근을 제공합니다. 다시 말하면 루트 접근입니다.제3자 그림을 실행할 때, 자신이 무엇을 하고 있는지 확실히 알아야 한다.
Reference
이 문제에 관하여(자동 SSL 및 Let's Encrypt & Nginx), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/adamkdean/automatic-ssl-with-let-s-encrypt-nginx-4nfk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)