자동 SSL 및 Let's Encrypt & Nginx

변경 로그에 대한 자세한 내용은 기사 하단의 업데이트 요약을 참조하십시오.
주: 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_HOSTLETSENCRYPT_EMAIL을 설정했습니다. 이 변수는 ACME 용기에서 가져오고 인증서를 받을 때 사용됩니다.참고로 두 호스트 이름은 항상 일치해야 합니다(VIRTUAL_HOSTLETSENCRYPT_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_CODEREDIRECT_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 용기를 통해 에이전트를 진행한다. 아래와 같다.
Fig F
나는 이것이 너에게 도움이 되기를 바란다.이 설정은 한 사이트 또는 여러 사이트에서 사용할 수 있습니다.대형 용기 플랫폼을 설치하는 것이 좀 지나친 상황에서 나는 그것을 사용할 것이다. (블로그의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자 그림을 실행할 때, 자신이 무엇을 하고 있는지 확실히 알아야 한다.

좋은 웹페이지 즐겨찾기