LabHub
배우기 러닝패스 코스

Addresses, Subnets and Gateways

Build a Tool That Computes Addresses

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

주소와 마스크를 받아 네트워크 주소·브로드캐스트·쓸 수 있는 범위·호스트 수를 계산하는 도구를 파이썬으로 만들고, 그 도구로 같은 서브넷 판정과 대역 분류, 겹침 검사를 해 봅니다. 마지막에는 요구 호스트 수에 맞는 프리픽스를 골라 설계 메모를 남깁니다.

왜 중요한가

방화벽 규칙도 네트워크 정책도 VPC 설계도 전부 이 계산 위에 서 있습니다. 그런데 손으로 반복하면 언젠가 반드시 틀리고, 틀린 것은 대개 장애가 난 뒤에야 드러납니다. 그래서 한 번 만들어 두고 계속 쓰는 편이 낫습니다.

특히 /31/32 가 중요합니다. 호스트 수를 "전체에서 2를 뺀다" 로만 짜 두면 이 둘에서 0과 -1 이 나오는데, 도구는 아무 오류도 내지 않고 그 값을 그대로 돌려줍니다. 검사기가 잡아 주지 않는 종류의 거짓말이라, 예외를 아는 사람만 피할 수 있습니다.

단계

  1. 세 대역을 손으로 계산해 /root/cidr/01-hand.txt 에 한 줄씩 적으세요. 대역은 192.168.40.130/26, 10.10.6.75/20, 172.20.200.9/23 이고, 각 줄에 CIDR·네트워크 주소·브로드캐스트·첫 호스트·마지막 호스트·호스트 개수가 모두 들어가야 합니다.
  2. /root/cidr/subnet.py 를 만드세요. python3 subnet.py 203.0.113.77/28python3 subnet.py 203.0.113.77 255.255.255.240같은 답을 내야 하고, 출력은 prefix= network= broadcast= first= last= hosts= 여섯 줄입니다. 두 번 돌린 결과를 /root/cidr/02-tool.txt 에 저장하세요.
  3. 도구가 /31/32 를 옳게 다루도록 고치세요. 이 둘은 broadcast=none 이고, /31 은 두 주소가 모두 호스트(hosts=2), /32 는 자기 자신 하나(hosts=1)입니다. 10.0.0.5/3110.0.0.5/32 를 돌린 결과와 왜 그런지를 /root/cidr/03-edge.txt 에 적으세요.
  4. /root/cidr/same.py 를 만드세요. python3 same.py <주소/프리픽스> <상대주소>same 또는 different 한 낱말만 출력합니다. 다섯 쌍을 돌려 /root/cidr/04-same.txt주소/프리픽스 상대주소 판정 으로 저장하세요.
  5. /root/cidr/classify.py 를 만드세요. python3 classify.py <주소>private link-local loopback cgnat multicast public 중 하나를 출력합니다. 아홉 주소를 돌려 /root/cidr/05-class.txt주소 분류 로 저장하세요.
  6. 10.60.8.0/22/24 넷으로 쪼개 /root/cidr/06-split.txt 에 한 줄에 하나씩 네트워크/24 first= last= hosts= 로 적으세요.
  7. 기존 대역 넷과 겹치는지 판정해 /root/cidr/07-overlap.txt 에 적으세요. 겹치면 후보 overlap=겹치는대역, 안 겹치면 후보 free 입니다.
  8. /root/cidr/08-report.md 에 설계 메모를 쓰세요. 요구 호스트 수 셋(120대·600대·30대)에 맞는 최소 프리픽스, 대역을 연속으로 배치하면 무엇이 이득인지, /31/32 를 언제 쓰는지가 들어가야 합니다.

참고

세 대역을 손으로 계산한다

프리픽스가 8의 배수가 아닐 때가 실수가 나오는 자리입니다. 블록 크기(2의 호스트비트 제곱)를 구하고, 그 배수 중 주소가 들어가는 것을 찾으면 네트워크 주소입니다.

예를 들어 /26 은 블록 크기가 64 이므로 경계는 0, 64, 128, 192 입니다. 130 은 128 블록에 들어갑니다.

검산은 python3 -c "import ipaddress; n=ipaddress.ip_network('192.168.40.130/26', strict=False); print(n.network_address, n.broadcast_address, n.num_addresses-2)" 로 합니다.

계산 도구를 만든다

/26255.255.255.192 는 같은 말입니다. 인자가 두 개로 들어오면 주소/마스크 로 이어 붙여 같은 함수에 넘기면 됩니다.

ipaddress.ip_network("203.0.113.77 255.255.255.240".replace(' ', '/'), strict=False) 처럼요.

출력의 키 이름(prefix= network= broadcast= first= last= hosts=)은 채점기가 그대로 찾으니 바꾸지 마세요. 호스트 개수는 전체 주소 수에서 네트워크 주소와 브로드캐스트 주소 둘을 뺀 값입니다.

/31 과 /32 의 예외를 다룬다

num_addresses - 2/31 에서 0, /32 에서 -1 이 됩니다. 도구는 오류를 내지 않고 그 값을 그대로 돌려주므로, 예외를 아는 사람만 피할 수 있습니다.

프리픽스가 31 이상이면 다른 가지로 보내세요. 그 가지에서는 브로드캐스트 주소를 두지 않고(broadcast=none), 첫 호스트는 네트워크 주소 그대로, 마지막 호스트는 대역의 마지막 주소, 호스트 개수는 전체 주소 수입니다.

설명 파일에는 어느 RFC 가 어떤 링크에 한해 이것을 허용했는지를 적으세요.

같은 서브넷인지 판정한다

판정은 한 줄로 끝납니다 — 상대 주소가 내 대역 안에 있는가. ipaddress.ip_address(other) in ipaddress.ip_network(mine, strict=False) 입니다.

앞 두 쌍은 주소가 같고 마스크만 다릅니다. 마스크 하나를 틀리면 옆자리 컴퓨터가 지구 반대편이 되는 것이 여기서 보입니다.

출력은 same 또는 different 한 낱말이어야 합니다. 채점기가 지시문에 없는 쌍으로도 한 번 더 물어봅니다.

대역의 성격을 분류한다

규칙 목록을 만들어 위에서부터 맞는 것을 찾고, 아무 데도 안 걸리면 public 입니다.

필요한 대역은 이렇습니다 — 루프백 127.0.0.0/8, 링크 로컬 169.254.0.0/16, CGNAT 100.64.0.0/10, 멀티캐스트 224.0.0.0/4, 사설 10.0.0.0/8·172.16.0.0/12·192.168.0.0/16.

172.32.0.1100.100.5.5 가 함정입니다. 172 사설 대역은 /12 라 172.16 부터 172.31 까지이고, 100.64.0.0/10 은 통신사가 가입자에게 나눠 주는 주소라 사설도 공인도 아닙니다.

대역을 잘게 나눈다

/22/24 로 자르면 2의 (24-22)제곱, 즉 넷이 나옵니다. ipaddress.ip_network("10.60.8.0/22").subnets(new_prefix=24) 가 그 넷을 차례로 줍니다.

각 줄에 네트워크(프리픽스 포함)·첫 호스트·마지막 호스트·호스트 개수를 담으세요. 조각마다 호스트는 254개입니다.

대역이 겹치는지 본다

겹침은 눈으로 보면 반드시 틀립니다. ipaddressoverlaps() 가 두 대역이 한 주소라도 공유하는지 알려 줍니다.

172.17.0.0/16 이 목록에 있는 이유가 있습니다. 도커의 기본 브리지가 그 대역이라, 사내망이 172.17 을 쓰면 컨테이너에서 사내 서버로 못 갑니다.

겹치면 후보 overlap=겹치는대역, 안 겹치면 후보 free 로 적으세요.

설계 메모를 남긴다

필요한 호스트 수에 2를 더한 값이 들어가는 가장 작은 2의 거듭제곱을 찾으면 됩니다. 120대라면 122 이상이 필요하니 128, 즉 호스트 비트 7개이고 프리픽스는 /25 입니다.

연속 배치 이야기는 인접한 대역을 하나로 합쳐 광고할 수 있다는 것입니다. 그것이 클래스가 사라진 실질적 이유이기도 합니다.

클라우드에서는 예약 주소를 더 빼야 한다는 것도 함께 적어 두면 좋습니다.