[python] aws endpoint dns 레코드 값 추출

Seunghyun Moon·2022년 10월 12일
0

python

목록 보기
1/4
post-thumbnail

회사에서 특명이 떨어졌다.
고객사에서 자사 솔루션을 도입하기로 결정했는데, 방화벽 정책 등록을 무려 ip 기반으로 해야한다는 것.

보통의 경우는 우리 회사 내부로 들어온다든지 하면 우리 공인 ip만 주면 되는데.. 문제는 우리 솔루션이 클라우드(aws, azure, ncp 등)의 api와 통신을 해야한다는 점.
여기서 문제가 생긴다. 실제 ip를 제공해야한다! 그리고 우리 솔루션은 100개 이상의 api endpoints와 통신해야한다...

자연스럽게 팀 내 가장 유능한 직원인 내가 소환됐다.
지령 내용

도메인 목록 줄테니 nslookup 해서 address 부분을 수집하고 테스트 및 문서화까지 하라.(아래 화면을 보여주며)

다른 할 일도 많다. 얼른 끝내자. 마음을 다잡고 노가다 준비하고 와서 시작,,,

복병 발견. 조회 값이 매번 다르다. 그리고 경우의 수가 너무 많다.
그리고 이 반복 노동을(안그랬으면좋겠지만) 또 노가다 할 수 없다.

코드를 짜기로 했다.
쉽게 쓸 수 있는 패키지도 많고 가장 익숙한 python으로 결정

사용 라이브러리

import pandas as pd
import subprocess
import re
import ipaddress

pandas

ip, domain을 매핑하고 dataframe의 기능을 쓰려고 사용

subprocess

조회하는 환경과 같은(이 경우엔 리눅스 서버) dns 서버에 질의하기 위해서 사용
고객사 환경에서도 작동해야했기 때문에 변수를 줄이고 싶었다. 예를 들어 aws상의 ec2에서 azure쪽에 쿼리를 했을 때와 azure의 vm에서 azure endpoint에 쿼리를 했을 때 레코드 값이 약간 달랐다.

re

텍스트 레코드에서 주는 ip 값을 파싱하려고 사용

ipaddress

유효한 ip 포맷인지 확인 용

쿼리 질의 방식

dns 응답을 규칙을 찾아내려고 다양한 레코드를 요청해봤는데, 다행히도 대부분의 endpoint는 text 레코드에서 모든 endpoint의 정보를 주는것 같아 보였다.

조회 및 검증

res 값에 nslookup 값을 가져오고, 가져온 값을 전처리 해준다.
그리고 처리된 ip가 ip포맷인지 확인한다.

try except는 두번 넣었는데, 첫번째는 text 레코드 전처리 시에 어떤 값을 뱉는지 보려고 넣었다.
두번째는 text 레코드 값을 안주는 도메인을 파악하려고 했다.꽤나 있어서 따로 처리해줘야 했다.

for url in test:

    try:
        res=subprocess.getstatusoutput("nslookup -query=txt "+url)[1]

        res=res[res.find("text = ")+7:].replace('"','').replace(' n1\n\nAuthoritative answers can be found from:\n','')
        res=re.sub(r'c[0-9]{,3}', '', res)
        res=re.sub(r'e[0-9]{,1}', '', res)

        for ip in res.split(' '):
            try:
                ipaddress.IPv4Network(ip)
                testresult.append((url, ip))
            except:
                print("first except: ",url)
                print("and the ip looks like this: ",ip)

    except:
        print("second except: ",url)

csv 파일로 저장

리스트로 처리한 ip-domain 을 dataframe으로 변환, csv파일로 저장하는 부분이다.

print("done looping")

df = pd.DataFrame(testresult,columns=['url','ip'])
df.to_csv("somefilename.csv", mode='w')
print("done converting")

예외 처리

모든 도메인이 텍스트 레코드를 주진 않았다. 그래서, 컴퓨터에게 중노동을 시켰다.

awsiam=['iam.amazonaws.com','iam-fips.amazonaws.com','iam.us-gov.amazonaws.com']

for i in range(2000):
    if i%10==0:
        print(i,'th loop done')

    for url in test:
        try:
            testresult.append((url,socket.gethostbyname(url)))
        except:
            print(url)

결론

무식한 방법이다. 결론적으로 이렇게 나온 ip들로 내부 테스트를 진행했을 때는 whitelist 방식의 방화벽 정책으로도 우리 솔루션 운영에 문제가 없었다.(aws sg(보안그룹)에서 800개의 ip를 자동으로 만드는 부분은 다른 글에서 다루겠다.)

profile
I live fullest

0개의 댓글