UDP 통신을 SSH 터널링 (TCP)으로 secure 통신을 하도록 하는 방법 Develop Tip

A 시스템에서 B 시스템으로 UDP 패킷을 보낸다고 가정합니다.

이를 netcat으로 해 보겠습니다.

A (10.31.1.176) 에서 B (10.31.1.177)로 UDP 패킷을 보내 보도록 하겠습니다.

서버 역할을 하는 B시스템에서,

B:~/$ nc -v -l -u 9200

위의 명령을 내리면
netcat을 이용하는 것인데 
  -v 설명모드로,
  -l 9200 포트를 listen 하고 있는데
  -u UDP 패킷을 대기하고 있음을 의미합니다.

이제 UDP를 보내는 A 시스템에서

A:~/$ date | nc -u -p 9000 10.31.1.177 9200

위의 명령을 내리면
date의 명령 결과를 nc 에서 받아
  -u 디폴트 TCP 대신 UDP 프로토콜로
  -p 9000 소스포트를 9000으로 박혀 보냅니다. 만약 이렇게 소스포트를 지정하지 않으면 
      서버쪽 nc 가 다른 UDP 세션일 경우 종료되는 문제가 nc 에 있더군요.
      nc 를 이용하여 ucp <=> tcp 작업을 하기에 위의 소스 포트 고정이 필요합니다.
      일반 C 등으로 작업하실 때도 소스 포트를 고정하면 되겠습니다.
  10.31.1.177 UDP로 보낼 서버 IP 주소이구요,
  9200 받는 포트 번호 입니다.

위의 명령을 내리면,

B: 시스템에서는

Connection from 10.31.1.176 port 9200 [udp/*] accepted
2015. 01. 16. (금) 18:43:22 KST

와 같이 결과가 잘 도착했음을 알 수 있습니다.

A의 정보를 보내고 나서 UDP라서 그런가 바로 끊기지는 않아 A에서 Control+C로 프로그램을 종료시켜 주었습니다.

위에 A의 명령을 다시 실행하면 B 시스템에서는,

2015. 01. 16. (금) 18:43:22 KST
2015. 01. 16. (금) 18:43:25 KST
2015. 01. 16. (금) 18:43:27 KST
...

와 같은 식으로 결과를 확인할 수 있습니다.

위의 결과는

UDP: 10.31.1.176:9000 ==> 10.31.1.177:9200
패킷이 보내진 것임을 확인할 수 있습니다.

A 시스템에서 tcpdump 로 해당 udp를 확인하고 있으면

A:~/$ sudo tcpdump -nn udp and port 9200
18:58:10.912170 IP 10.31.1.176.9000 > 10.31.1.177.9200: UDP, length 33

라고 나옵니다.


이제 본젹적으로 위와 같이 되어 있던 UDP 패킷을 터널로 보내는 것을 해 보겠습니다.

1) A에서 SSH 터널 맺기

A 시스템에서 B 시스템으로 터널을 맺습니다.

A:~/$ ssh -L 1337:localhost:1337 10.31.1.177 -N -f

위의 명령은 다음과 같습니다.
  -L 1337:localhost:1337 로컬 TCP 1337 포트로 오는 것을 원격 10.31.1.177 시스템의 1377 포트로  터널을 맺는데,
  10.31.1.177 원격 ssh 서버 주소로
  -N 원격 로그인을 실행하지 않습니다.
  -f 데몬으로 터널을 맺습니다.


2) A에서 netcat으로 UDP <=> TCP 변환

2.1) mkfifo

A:~/$ mkfifo /tmp/udp2tcp
UDP <=> TCP 연동을 위한 named pipe를 위와 같이 생성합니다.

2.2) netcat 연동

A:~/$ nc -v -l -u 9100 < /tmp/udp2tcp | nc localhost 1337 > /tmp/udp2tcp

nc -l -u 9100  < /tmp/udp2tcp
위의 명령은 UDP(-u) 패킷 9100포트를 listen(-l) 하여 들어오는 패킷을 stdout으로 출력하여,

nc localhost 1337 > /tmp/udp2tcp
로컬호스트의 TCP 1337 포트로 이전 명령의 결과를 보내는데,
1의 터널에 의하여 원격 서버의 1337 TCP port롤 SSH 터널을 통하여 가게됩니다.

반대로 1337 TCP 포트에서 오는 것은 /tmp/udp2tcp named pipe로 결과를 쓰고
이는 다시 첫번쨰 nc에 의하여 UDP 9100 패킷으로 받게 됩니다.

3) B에서 netcat으로 UDP <=> TCP 변환

2.1) mkfifo

B:~/$ mkfifo /tmp/tcp2udp
UDP <=> TCP 연동을 위한 named pipe를 위와 같이 생성합니다.

2.2) netcat 연동

B:~/$ nc -l 1337 < /tmp/tcp2udp | nc -u localhost 9200 > /tmp/tcp2udp

nc -l 1337  < /tmp/tcp2udp
위의 명령은 터널링 되어 온 TCP 패킷 1337 포트를 listen(-l) 하여 들어오는 패킷을 stdout으로 출력하여,

nc -u localhost 9200 > /tmp/tcp2udp
로컬호스트의 UDP(-u) 9200 포트로 이전 명령의 결과를 보냅니다.

반대로 9200 UDP 포트에서 오는 것은 /tmp/tcp2udp named pipe로 결과를 쓰고
이는 다시 첫번쨰 nc에 의하여 TCP 1337 패킷으로 받게 됩니다.

4) 테스트

B:~/$ nc -v -l -u 9200
위의 명령으로 대기하고 있고

A:~/$ date | nc -u -p 9000 127.0.0.1 9100
라고 명령을 주면

B의 결과로
Connection from 127.0.0.1 port 9200 [udp/*] accepted
2015. 01. 16. (금) 19:40:37 KST

라고 나옵니다.


어느분께는 도움이 되셨기를...



덧글

댓글 입력 영역

구글애드텍스트