
서버의 포트로 들어오는 데이터는 정해진 주소(TARGET_IP:TARGET_PORT)로 데이터를 전달하고 응답 데이터는 클라이언트로 전달합니다.
+-----------------------------+ +---------------------------------------------+ +--------------------------------+
| OpenSSH Client | | Portforwarding Server | | OpenSSH Server |
+-----------------------------+ +----------------------+----------------------+ +--------------------------------+
| ssh root@127.0.0.1 -p 9999 |<------->| $ python main.py |<------->| 192.168.0.33:22(OpenSSH Server)|
+-----------------------------+ +---------------------------------------------+ +--------------------------------+
클라이언트가 접속할 때마다 포워딩할 서버로 접속하여 데이터를 중계해 주면 됩니다.
import socket
import threading
SERVER_IP = ""
SERVER_PORT = 9999
TARGET_IP = "192.168.0.38"
TARGET_PORT = 22
CLIENTS = []
def send_data(_src_socket:socket.socket, _dst_socket:socket.socket):
while True:
try:
data = _src_socket.recv(4096)
if len(data) > 0:
_dst_socket.sendall(data)
except Exception as exception:
print(f"Error : {exception}")
break
def work(_client_socket:socket.socket, _remote_addr:tuple):
target_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
try:
target_socket.connect((TARGET_IP, TARGET_PORT))
user = f"{_remote_addr[0]}:{_remote_addr[1]}"
print(f"[{user} -> {TARGET_IP}] Connected")
recv_thread = threading.Thread(target=send_data, args=(_client_socket, target_socket))
send_thread = threading.Thread(target=send_data, args=(target_socket, _client_socket))
recv_thread.start()
send_thread.start()
recv_thread.join()
send_thread.join()
except ConnectionRefusedError:
print(f"{TARGET_IP}:{TARGET_PORT} is die")
CLIENTS.remove(_client_socket)
target_socket.close()
proxy_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
proxy_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
proxy_socket.bind((SERVER_IP, SERVER_PORT))
proxy_socket.listen()
print("Proxy run")
while True:
try:
client_socket, remote_addr = proxy_socket.accept()
except KeyboardInterrupt:
print("Proxy stop")
break
CLIENTS.append(client_socket)
thread = threading.Thread(target=work, args=(client_socket, remote_addr))
thread.daemon = True
thread.start()
for client in CLIENTS:
client.close()
proxy_socket.close()