Debian 10에서 Docker를 사용하여 동적 DNS 서버를 배포하는 방법


이 페이지에서

  1. 요구 사항\n
  2. DNS 레코드 생성.
  3. 설치
    1. 1단계: 종속성 업데이트 및 설치.
    2. 2단계: Docker CE를 설치합니다.\n
    3. 3단계: docker-ddns 다운로드 및 빌드
    4. 4단계: Systemd 서비스(선택사항)\n
    5. 5단계: 서버 테스트
    6. 6단계: 리버스 프록시\n
    7. 7단계: 클라이언트 구성

    동적 DNS는 도메인 이름을 동적(임시, 자주 변경되는) IP 주소에 매핑하기 위한 네트워크 서비스입니다. SOHO(Small Office/Home Office) 네트워크와 같이 고정 IP 주소가 없는 컴퓨터에 액세스하는 데 사용되며 종종 NAT 방화벽 뒤에 있는 시스템에 액세스하기 위해 포트 포워딩과 함께 사용됩니다. 이 문서는 필요한 DNS 레코드 설정, Nginx HTTPS 역방향 프록시 뒤에 관리 API 배치, 클라이언트 측 DNS 자동화를 포함하여 Debian 10 시스템의 Docker 컨테이너에 동적 DNS 서버를 설정하는 전체 과정을 안내합니다. 기록 업데이트.

    요구 사항

    • 선택적으로 IPv6 연결이 가능한 단일 Debian 10 서버. (192.0.2.2 및 2001:0db8::0db9는 각각 IPv4 및 IPv6 서버의 자리 표시자로 사용됩니다.)\n
    • 루트 사용자 또는 sudo 권한이 있는 사용자에 대한 액세스.\n
    • 호스트에서 tcp/53 및 udp/53 포트를 사용할 수 있어야 합니다.\n
    • 등록된 도메인 이름 및 해당 이름 서버/영역 파일에 대한 액세스. 다음 섹션에 표시된 대로 이 도메인에 대한 DNS 레코드를 만듭니다.\n
    • $EDITOR 환경 변수를 설정해야 합니다.\n
    • 선택적으로 모든 Linux/Unix 클라이언트 시스템은 자동 DNS 레코드 업데이트를 설정합니다.\n

    DNS 레코드 생성.

    동적 DNS 서버가 작동하려면 최소 2개의 DNS 레코드를 생성해야 합니다. 먼저 서버 IPv4 주소를 가리키는 ns1.your_domain과 같은 하위 도메인을 선택합니다. 둘째, ns1.your_domain에 위임될 ddns.your_domain과 같은 하위 도메인을 선택합니다.

    동적 DNS 서버는 ddns.your_domain 아래의 모든 레코드를 처리합니다. AAAA 유형의 세 번째 레코드는 선택 사항입니다. 해당 레코드는 다음과 같습니다.

    ns1.your_domain A 192.0.2.2
    ddns.your_domain NS ns1.your_domain
    ns1.your_domain AAAA 2001:0db8::0db9 (optional)
    
    
    

    도메인 등록 기관 제어판에서 이러한 레코드를 만들어야 합니다. 이러한 레코드가 제대로 전파되는 데 최대 24시간이 걸릴 수 있지만 일반적으로 몇 분 정도 걸립니다.

    설치

    루트 사용자를 사용하지 않는 경우 이 가이드에 표시된 대부분의 명령에는 상승된 권한이 필요하므로 임시 루트 셸을 시작하는 것이 좋습니다. 루트 셸을 시작하려면 다음 명령 중 하나를 사용합니다.

    sudo su - root
    sudo -s

    1단계: 종속성 업데이트 및 설치.

    항상 먼저 시스템을 업데이트하는 것이 좋습니다.

    apt update
    apt upgrade -y
    reboot

    재부팅 후 이 설정에 필요한 소프트웨어 패키지를 설치합니다.

    • certbot은 SSL/TLS 인증서를 얻는 데 사용됩니다.
    • make는 DDNS 서버가 실행될 도커 이미지를 빌드하는 데 필요합니다.\n
    • 도커 저장소와 해당 GPG 키를 설치하려면 apt-transport-https, ca-certificates, curl, gnupg2 및 software-properties-common이 필요합니다.\n
    • dnsutils는 테스트에 사용될 dig를 제공합니다.\n

    apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

    2단계: Docker CE를 설치합니다.

    Dockers GPG 키 추가:

    curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

    도커 저장소를 설치합니다.

    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"

    Debians 리포지토리 캐시를 업데이트한 다음 docker 및 해당 종속성을 설치합니다.

    apt update
    apt install -y docker-ce docker-ce-cli containerd.io

    설치가 완료되면 다음과 같이 docker 서비스가 활성화되고 실행 중인지 확인하십시오.

    systemctl enable --now docker.service

    3단계: docker-ddns 다운로드 및 빌드

    우리의 동적 DNS 서버는 Bind를 DNS 서버로 사용하는 도커 컨테이너와 Go로 작성된 관리 API로 구동됩니다. 먼저 Github 리포지토리를 복제하고 다음 명령을 사용하여 컨테이너 이미지를 빌드합니다.

    git clone https://github.com/dprandzioch/docker-ddns.git
    cd docker-ddns
    make image

    프로세스가 완료될 때까지 기다린 후(시간이 걸릴 수 있음) 텍스트 편집기로 envfile 파일을 엽니다.

    $EDITOR envfile

    그리고 다음을 입력합니다.

    SHARED_SECRET=your_secret 
    ZONE=ddns.your_domain
    RECORD_TTL=60

    공유 비밀은 관리 API로 인증하는 데 사용되는 암호입니다. ZONE은 서버가 담당할 DNS 영역을 나타내고 레코드 TTL은 DNS 레코드를 캐시할 수 있는 기간을 지정합니다. 자주 변경되는 동적 IP의 경우 60초의 TTL이 권장됩니다.

    필요한 경우 다음 명령을 사용하여 암호에 대해 임의의 40자 문자열을 생성할 수 있습니다.

    cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 40 | head -1

    이제 컨테이너를 만들 수 있습니다.

    docker create -it -p 127.0.0.1:8080:8080 -p 53:53 -p 53:53/udp --env-file envfile -v /mnt/ddns-data:/var/cache/bind --name ddns-server davd/docker-ddns

    이 명령은 이전에 빌드한 이미지에서 ddns-server라는 컨테이너를 생성하고 호스트에서 컨테이너로 포트 8080/tcp, 53/tcp 및 53/udp를 매핑합니다. 또한 호스트의 /mnt/ddns-data 디렉토리를 컨테이너 파일 시스템의 /var/cache/bind에 마운트합니다. 이는 컨테이너 재생성에서 DNS 데이터를 유지하는 데 사용됩니다.

    다음 명령으로 컨테이너가 생성되었는지 확인합니다.

    docker container ls -a
    

    ddns-server라는 이름으로 단일 항목이 출력되어야 합니다.

    4단계: Systemd 서비스(선택 사항)

    이 단계는 보다 간단한 관리를 위한 것이지만 반드시 필요한 것은 아닙니다. systemd 서비스를 사용하지 않기로 선택한 경우 컨테이너를 수동으로 관리하거나 다른 관리 솔루션을 사용해야 합니다. 더 크고 복잡한 컨테이너 배포의 경우 Kubernetes 또는 Docker Swarm과 같은 오케스트레이션 솔루션이 권장됩니다. 이 경우 단일 컨테이너만 실행하므로 systemd 서비스가 완벽하게 적합합니다.

    이 컨테이너를 시스템 서비스로 관리하려면 systemd 단위로 잘 포장하십시오. 텍스트 편집기로 /etc/systemd/system/ddns-server-ct.service 파일을 만듭니다.

    $EDITOR /etc/systemd/system/ddns-server-ct.service
    

    그리고 다음을 추가합니다.

    [Unit]
    Description=DDNS Server Docker Container
    After=docker.service
    Requires=docker.service
    Requires=network.target
    [Service]
    Type=oneshot
    TimeoutStartSec=240
    Restart=no
    RemainAfterExit=yes
    ExecStart=/usr/bin/docker start ddns-server
    ExecStop=/usr/bin/docker stop ddns-server
    [Install]
    WantedBy=multi-user.target

    저장하고 종료한 다음 이 장치 파일에 올바른 권한을 설정하십시오.

    chmod 664 /etc/systemd/system/ddns-server-ct.service

    다음 명령을 사용하여 새 서비스 파일을 로드합니다.

    systemctl daemon-reload

    이제 systemctl을 다른 시스템 서비스로 사용하여 이 컨테이너를 시작하고 중지할 수 있습니다.

    시스템 부팅 시 DDNS 서버를 자동으로 시작하려면 다음을 실행하십시오.

    systemctl enable ddns-server-ct.service

    5단계: 서버 테스트

    설정을 진행하기 전에 로컬에서 관리 API를 잘 테스트하십시오. 컨테이너를 시작합니다.

    systemctl start ddns-server-ct.service

    API에 GET 요청을 보내 새 레코드를 만듭니다.

    참고: API는 현재 로컬에서만(즉, localhost에서) 액세스할 수 있습니다.

    curl "http://127.0.0.1:8080/update?secret=your_secret&domain=test1&addr=1.1.1.1"

    Curl은 다음 응답을 반환해야 합니다.

    {"Success":true,"Message":"Updated A record for test1 to IP address 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}

    참고: 도메인 test1은 test1.ddns.your_domain을 나타냅니다. 서버가 ddns.your_domain을 처리하고 있기 때문입니다. 존.

    DNS 조회를 수행하여 레코드가 실제로 생성되었는지 확인하고 DNS 확인을 테스트합니다.

    dig +short -t A test1.ddns.your_domain @127.0.0.1

    출력은 1.1.1.1이어야 합니다.

    6단계: 리버스 프록시

    API는 HTTP를 통해 작동하므로 네트워크를 통해 요청을 보낼 때마다 인증 비밀이 스니핑될 수 있습니다. 그런 다음 공격자는 비밀을 사용하여 DNS 레코드를 조작할 수 있습니다. Nginx를 사용하여 리버스 프록시를 설정하고 HTTPS를 사용하여 보호하십시오. 먼저 certbot을 사용하여 Lets Encrypt에서 SSL 인증서를 얻습니다.

    certbot certonly --standalone --agree-tos -m  -d ns1.your_domain

    도메인 소유권이 확인되고 인증서가 발급됩니다. 다음으로 Nginx를 설치하고 활성화되어 실행 중인지 확인합니다.

    apt install -y nginx systemctl enable --now nginx.service

    그런 다음 필요하지 않은 기본 서버 블록 파일을 비활성화합니다.

    unlink /etc/nginx/sites-enabled/default

    이제 리버스 프록시에 대한 새 구성 파일을 생성합니다. 예를 들면 다음과 같습니다.

    $EDITOR /etc/nginx/sites-available/ddns-api-proxy.conf

    그리고 다음을 붙여넣고 IP 주소와 도메인 이름을 자신의 이름으로 바꾸십시오.

    server {
    listen 192.0.2.2:8080;
    server_name ns1.your_domain;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/ns1.your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ns1.your_domain/privkey.pem;

    location /update {
    proxy_pass http://127.0.0.1:8080;
    }
    location / {
    return 404;
    }
    access_log /var/log/nginx/ddns-api-access.log;
    error_log /var/log/nginx/ddns-api-error.log;
    }

    옵션: IPv6을 통해 API에 액세스할 수 있게 하려면 기존 청취 지시문 뒤에 다음 행을 추가하십시오.

    listen [2001:0db8::0db9]:8080;

    이 구성을 활성화하고 Nginx를 다시 로드하여 변경 사항을 적용합니다.

    ln -s /etc/nginx/sites-available/ddns-api-proxy.conf /etc/nginx/sites-enabled/
    systemctl reload nginx.service

    이제 인터넷을 통해 API에 액세스할 수 있으며 HTTPS 연결만 수락합니다. 테스트하려면 다음 명령을 실행하십시오.

    curl "https://ns1.your_domain:8080/update?secret=your_secret&domain=test2&addr=1.1.1.2"

    다음을 반환해야 합니다.

    {"Success":true,"Message":"Updated A record for test2 to IP address 1.1.1.2","Domain":"test2","Domains":["test2"],"Address":"1.1.1.2","AddrType":"A"}

    7단계: 클라이언트 구성

    Pfsense와 같은 사용자 지정 동적 DNS 공급자를 지원하는 모든 라우터에서 자동 레코드 업데이트를 설정할 수 있습니다. 사무실이나 홈 네트워크에 있는 대부분의 다른 장치에도 설정할 수 있습니다. 레코드를 업데이트하거나 생성하려면 GET 요청을 다음 엔드포인트로 보내야 합니다.

    https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address

    단일 요청으로 여러 하위 도메인의 레코드를 업데이트할 수도 있습니다. 예를 들어 IP 주소가 198.51.100.100인 sub1.ddns.your_domain 및 sub2.ddns.your_domain에 대한 레코드를 생성/업데이트하려면 다음 URL에 GET 요청을 보냅니다.

    https://translate.google.com/translate?hl=ru&sl=en&tl=ko&u=https://ns1.your_domain:8080/update?secret=your_secret&domain=sub1,sub2&addr=198.51.100.100

    addr 매개변수는 IPv6 주소를 보유하여 AAAA DNS 레코드를 생성/업데이트할 수도 있습니다. 예를 들면 다음과 같습니다.

    https://ns1.your_domain:8080/update?secret=your_secret&domain=cheese&addr=2001:0db8:aaaa::

    Linux 클라이언트에서 이러한 업데이트를 자동화하려면 다음 bash 스크립트를 /opt/ddns-update.sh로 저장합니다.

    #!/bin/bash

    while [ -z $CURRENTIP ] do
    CURRENTIP=`dig -r +short myip.opendns.com @resolver1.opendns.com 2>/dev/null`
    sleep 1
    done
    curl -s "https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=${CURRENTIP}"

    이 스크립트는 클라이언트 공용 IP 주소를 가져와 변수에 저장하는 dig 명령을 둘러싼 while 루프를 사용합니다. 루프는 퍼블릭 IP를 올바르게 가져왔는지 확인합니다. 그런 다음 cURL을 사용하여 새로 가져온 이 IP로 DNS 레코드를 업데이트하기 위한 API 요청을 보냅니다. your_secret 및 your_subdomain의 값을 바꾸었는지 확인하십시오.

    다음으로 이 스크립트를 실행 가능하게 만듭니다.

    chmod +x /opt/ddns-update.sh

    그런 다음 crontab 편집기를 시작합니다.

    crontab -e

    crontab 끝에 다음 줄을 추가합니다.

    */2 * * * * /opt/ddns-update.sh

    저장 및 종료. 이제 스크립트가 2분마다 실행되어 클라이언트의 최신 공용 IP 주소로 동적 DNS 레코드를 최신 상태로 유지합니다.

    추가 자료

    • 동적 DNS Wikipedia 기사
    • Github의 docker-ddns