2020. 1. 11. 16:11ㆍProgramming/WebProgramming
들어가며
정말 오랜만의 포스팅입니다. 이번 글은 집에서 서버를 구축할 때, 유동 IP로 어떻게 하면 DNS를 설정할 수 있을지 그 방법에 대해서 작성해봤습니다. 들어가기 전에, 이 글은 이미 공유기에서 포트포워딩 설정이 끝나있으며, 서버 도메인을 하나 가지고 있다는 것을 가정하고 작성되었습니다. 포트포워딩에 대한 개념, 설정 방법은 검색하셔서 참고하시면 될 것 같습니다.
유동 IP의 한계
유동 IP란, 고정 IP의 반대되는 개념이며, 중간에 인터넷 공급자에 의해 언제든지 다른 IP로 바뀔 수 있는 IP를 말합니다. 현재 대세인 IPv4 체계로는 이론적으로 4,294,967,296개의 IP가 존재할 수 있으나, 어디까지나 이론일 뿐이고, 실제로는 이보다 더 적은 IP가 사용되고 있고, 현재 인터넷 이용량에 비하면 턱없이 모자란 공급량입니다.
그렇기 때문에 인터넷 공급자들은 기업이 아닌 일반 가정에는 웬만해서는 고정 IP가 아닌 유동 IP를 주고 있는데, 서버를 돌리는 환경에서 유동 IP는 매우 좋지 않습니다. 친구들한테 "내 홈페이지는 123.123.123.123 이야. 들어와!" 라고 말했는데 그 사이에 IP가 바뀌어서 들어간 곳에서 "똘똘이의 야동보관창고"라는 사이트가 나오면 당황스럽겠죠.
이 부분을 해결하기 위해서 일반 가정에서는 DDNS라는 선택지를 택할 수 있습니다.
DNS? DDNS?
DDNS는 Dynamic DNS의 줄임말입니다. 동적인 DNS란 소리인데, 그 전에 DNS가 무엇인지 알아보고 가는 게 좋을 것 같습니다.
DNS는 도메인 네임 시스템의 준말로, IP주소를 도메인 주소와 연결시키는 체계 그 자체를 지칭합니다. 이 세상에 존재하는 모든 서버는 IP를 가지고 있지만, 대부분은 IP가 아닌 도메인을 통해 접근됩니다. 왜냐하면
- IP는 숫자이기 때문에 외우기 어렵습니다. (123.59.111.78)
- 반면에 도메인은 뇌리에 잘 박힙니다. (www.easyname.com)
- IP는 어느 순간 변할 가능성이 있습니다. 이는 고정 IP일 때도 발생할 수 있습니다. (통신사 변경으로 123.59.111.78 -> 12.117.42.2 로 변경. 실제 IP 주소가 이렇게 극적으로 변하진 않습니다.)
- 도메인은 IP와 연결됩니다. 서버의 IP가 바뀌더라도 도메인에 연결된 IP만 바꾸면 도메인 자체는 그대로 남습니다. (easyname.com 에 연결된 정보를 123.59.111.78에서 12.117.42.2로 바꿈)
그렇기 때문에 테스트용이 아닌, 실제 서비스를 염두하고 있는 서버라면 당연히 DNS가 필요해집니다.
그러나 이 DNS 자체에 IP가 변경될 때에 자동으로 이를 감지하고 바꿔주는 기능은 없습니다. 고정 IP <-> 도메인 연결상태일 때에는 굳이 필요 없는 기능이기도 하구요. (고정 IP일 경우는 사용자가 직접 바꾸려고 할 때에만 바뀌므로 IP 변경 감지를 할 필요가 없습니다.)
이러한 부분을 해결하기 위한 해법이 바로 DDNS입니다.
앞서 언급했듯이 DDNS는 동적인 DNS입니다. 즉, IP 변동 등에도 유동적으로 대처할 수 있는 DNS를 의미합니다. DDNS는 아래와 같은 방식들이 있습니다.
- DDNS 제공 서비스에 가입을 해서 실제로 DDNS를 공급받는 경우
- 아이피타임같은 공유기에 내장된 기능을 통해 DDNS를 사용하는 경우
- DNS 서버를 수시로 조작해서 DDNS같이 사용하는 경우
특히 2번의 방식은 가장 흔히 쓰이는 DDNS 방식입니다. 이 또한 나중에 기회가 된다면 포스팅하도록 하겠습니다.
이 포스팅에서는 3번의 방식을 사용할 것입니다. 일반적인 경우는 아닙니다만, 내가 직접 구매한 도메인을 사용할 수 있다는 매우 강력한 이점이 있습니다.
Cloudflare를 네임서버로 사용하자
먼저 준비물로 자기만의 도메인이 필요합니다. 저는 zerobell.xyz 를 구매해서 지금까지 잘 사용해오고 있습니다.
그 다음, Cloudflare에 가입합니다. Cloudflare는 본래 CDN이지만, 제공하는 DNS 서버가 REST API를 통해 조작될 수도 있게 해줍니다.
가입 완료 후에는 site를 추가합니다. 자신이 사용하고자 하는 도메인을 입력하시면 됩니다. free plan으로 생성해도 무방합니다.
사이트 추가가 완료되었으니, 내 도메인의 네임서버를 Cloudflare로 바꿔줘야만 합니다. 저는 닷네임에서 구매한 도메인이므로, 닷네임에서 도메인의 네임서버를 Cloudflare로 바꿔줬습니다.
변경까지 끝났다면, 다시 Cloudflare로 이동하여 내 site의 DNS 설정에 들어가도록 합니다.
DNS 관리에서 Add record를 통해 정보를 추가할 수 있습니다. 여기에서는 Type A로 Name은 @(이렇게 할 경우 현재 site 이름이 default로 들어갑니다), IPv4 address에 자신의 서버 IP를 넣으면 됩니다.
이 과정까지 끝나고 나면 내 도메인이 Cloudflare를 통해 내 서버 IP에 연결된 것입니다.
참고 : 네임서버의 변경사항은 전파되는 데까지 최대 24시간 정도 걸립니다. 보통은 수 분 이내로 반영되지만, 아닐 수도 있으니 성급하게 '왜 안 되지?' 하지 마시고 조금만 더 기다려보세요.
더 나아가, 이제 IP 변경 때마다 이 네임서버 레코드가 바뀌도록 해봅시다.
Cloudflare를 DDNS처럼 사용하자
Zone ID, Global API Key 확인
앞서 언급했듯이, Cloudflare에서는 DNS를 REST API를 통해 조작할 수 있습니다. 그러기 위해서는 site의 zone ID와, Global API Key가 필요합니다.
Cloudflare에서 나의 사이트를 들어가 오른쪽 하단으로 스크롤을 내리다 보면, API 영역에 Zone ID가 있습니다. 이는 클라우드플레어가 site에 각자 부여해주는 ID입니다. 먼저 이걸 체크합니다.
그 다음, global API Token이 필요한데, 바로 아래의 Get your API Token을 눌러 이동해줍니다.
Global API Key는 Cloudflare의 모든 API에서 사용할 수 있는 만능 Key이므로 조심히 다뤄야만 합니다. View를 클릭하면 다시 한번 계정의 패스워드를 묻습니다. 여기에서 Global API Key를 확인하도록 합니다.
스크립트 돌리기
이제 마지막 단계입니다. ssh를 통해 라즈베리파이로 접속한 후에, repository 하나를 클론할 것입니다.
$ git clone https://github.com/zerobell-lee/cloudflare-update-ip
네, 이것은 제가 cloudflare를 dns로 쓰기 위해 만들어 놓은 제 파이썬 스크립트입니다.
정상적으로 clone이 이루어졌다면, 해당 디렉토리 안에 config-sample.json 파일이 하나 있을 것입니다. 이것을 다음과 같이 수정하면 됩니다.
{
"email": "${Cloudflare 로그인에 사용하는 email}",
"key": "${Global API Key}",
"zone": "${내 site의 zone ID}",
"ipdir": "/var/tmp"
}
ipdir는 "내 현재 ip를 어디에 기록해둘 것인가"를 지정하는 경로입니다. 라즈비안이라면 그냥 var tmp에 두셔도 무방합니다.
그 후, crontab을 이용해 스케줄러에 등록합니다.
$ sudo crontab -e
0 * * * * /${clone한 repository가 있는 경로}/update_ip.py > update_ip_result
crontab을 이용해 이렇게 스케줄을 등록하면, 1시간에 한번씩 update_ip.py가 실행되면서 자신의 ip의 변경 여부를 탐지하고, 변경되었을 때에 Cloudflare를 통해 직접 DNS 레코드를 수정하게 됩니다. (그리고 그 결과는 같은 디렉토리에 update_ip_result 라는 이름으로 저장됩니다.)
이렇게 한다면 유동 IP가 변경되더라도 DNS를 자동으로 수정되게 만들 수 있습니다.
python3과 requests 모듈이 설치되어 있어야만 합니다. 파이썬 설치 후에 pip3 install requests 를 통해 미리 설치해주세요.
crontab을 최초로 실행할 때에는 기본 에디터를 지정해야 합니다. nano나 vim 중 마음에 드는 쪽을 택하시고, 제일 아래에 저 cron 표현식을 붙여넣으시면 됩니다.