[파이썬] socket 소켓을 이용한 포트 스캐닝

포트 스캐닝(port scanning)은 네트워크 시스템에서 열려있는 포트를 찾아내는 작업입니다. 소켓(socket)은 네트워크 통신을 담당하는 도구로, 파이썬에서는 socket 모듈을 사용하여 소켓 프로그래밍을 할 수 있습니다. 이번 블로그에서는 소켓을 이용하여 파이썬으로 포트 스캐닝을 하는 방법을 알아보겠습니다.

소켓 프로그래밍 소개

소켓 프로그래밍은 클라이언트와 서버 간의 네트워크 통신을 가능하게 해주는 방법입니다. 클라이언트는 특정 포트에 연결하여 서버와 통신하고, 서버는 해당 포트에서 클라이언트의 요청을 받아 응답합니다.

파이썬에서 소켓 프로그래밍을 위해서는 socket 모듈을 import 해야 합니다. 다음은 기본적인 소켓 생성과 클라이언트의 요청 전송 예시입니다.

import socket

# 소켓 생성
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 서버의 IP와 포트 설정
server_address = ('localhost', 8080)

# 서버에 연결
sock.connect(server_address)

# 서버에 요청 전송
message = 'Hello, Server!'
sock.sendall(message.encode('utf-8'))

# 응답 받기
response = sock.recv(1024).decode('utf-8')

# 응답 출력
print('Response:', response)

# 소켓 닫기
sock.close()

위 코드에서 socket.socket(sock.AF_INET, sock.SOCK_STREAM)은 IPv4와 TCP 소켓을 생성한다는 의미입니다. sock.connect(server_address)를 통해 서버에 연결하고, sock.sendall(message.encode('utf-8'))로 서버에 요청을 전송합니다. 그리고 sock.recv(1024).decode('utf-8')를 통해 서버로부터의 응답을 받아옵니다. 마지막으로, sock.close()로 소켓을 닫습니다.

포트 스캐닝 예시

이제 소켓 프로그래밍을 사용하여 포트 스캐닝을 하는 방법을 알아보겠습니다. 포트 스캐닝은 특정 호스트의 특정 포트가 열려 있는지 아닌지를 확인하는 작업입니다.

import socket

def scan_port(host, port):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(1)
        result = sock.connect_ex((host, port))
        if result == 0:
            print(f"Port {port} 열려 있음")
        else:
            print(f"Port {port} 닫혀 있음")
        sock.close()
    except socket.error as e:
        print(f"에러 발생: {e}")

# 스캔할 호스트와 포트 설정
host = 'localhost'
ports = [80, 443, 8080, 3306]

# 지정한 포트들에 대해 스캔 실행
for port in ports:
    scan_port(host, port)

위 코드에서는 scan_port라는 함수를 정의하여 스캐닝 작업을 수행합니다. 소켓을 생성한 후 sock.connect_ex((host, port))를 통해 해당 포트로 연결을 시도합니다. connect_ex 함수의 반환 값이 0이면 포트가 열려 있음을 의미합니다. 그렇지 않다면 포트가 닫혀 있다는 의미입니다.

host 변수에는 스캔할 호스트의 IP 주소나 도메인을 설정하고, ports 리스트에는 스캔할 포트들을 설정합니다. 이후 scan_port 함수를 호출하면서 호스트와 포트를 매개변수로 전달해주면 해당 포트에 대한 스캔 결과를 출력합니다.

이렇게 파이썬의 소켓을 이용하여 포트 스캐닝을 할 수 있습니다. 포트 스캐닝은 네트워크 보안 분석이나 서비스 상태 모니터링에 유용하게 사용될 수 있습니다.