Networking

[NSX] WebSocket 서버 구성 및 Client 접속 테스트

haewon83 2024. 6. 21. 20:48

 

 

NSX Load Balancer는 WebSocket을 위한 HTTP Upgrade를 지원합니다.

Supported Load Balancer Features

https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/administration/GUID-91F2D574-F469-481A-AA39-CD6DBC9682CA.html

• HTTP upgrade - 
For applications using HTTP upgrade such as WebSocket, the client or server requests for HTTP Upgrade, which is supported. 
By default, NSX-T Data Center supports and accepts HTTPS upgrade client request using the HTTP application profile.

 

오늘은 이 WebSocket을 NSX Load Balancer에서 테스트 하기 위해 우선 WebSocket Server와 Client 환경을 구성하고, 접속 테스트를 진행하면서 Packet을 확인해보겠습니다.

 

1. WebSocket 서버 구성
아래 링크에 Python으로 작성된 Sample Code가 있습니다.
A Simple Websocket Server written in Python
https://github.com/dpallot/simple-websocket-server

 

테스트 환경에서는 위 Code를 이용하여 CentOS에서 WebSocket 서버 실행합니다.
※ Sample Code는 Listening Port로 8000번으로 지정되어 있으나, 변경 가능

[root@localhost ~]# cd simple-websocket-server-master
[root@localhost simple-websocket-server-master]# ls
MANIFEST.in  README.md  setup.py  SimpleWebSocketServer
 
[root@localhost simple-websocket-server-master]# python setup.py install
/usr/lib64/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'long_description_content_type'
  warnings.warn(msg)
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/SimpleWebSocketServer
copying SimpleWebSocketServer/SimpleExampleServer.py -> build/lib/SimpleWebSocketServer
copying SimpleWebSocketServer/SimpleHTTPSServer.py -> build/lib/SimpleWebSocketServer
copying SimpleWebSocketServer/SimpleWebSocketServer.py -> build/lib/SimpleWebSocketServer
copying SimpleWebSocketServer/__init__.py -> build/lib/SimpleWebSocketServer
running install_lib
creating /usr/lib/python2.7/site-packages/SimpleWebSocketServer
copying build/lib/SimpleWebSocketServer/SimpleExampleServer.py -> /usr/lib/python2.7/site-packages/SimpleWebSocketServer
copying build/lib/SimpleWebSocketServer/SimpleHTTPSServer.py -> /usr/lib/python2.7/site-packages/SimpleWebSocketServer
copying build/lib/SimpleWebSocketServer/SimpleWebSocketServer.py -> /usr/lib/python2.7/site-packages/SimpleWebSocketServer
copying build/lib/SimpleWebSocketServer/__init__.py -> /usr/lib/python2.7/site-packages/SimpleWebSocketServer
byte-compiling /usr/lib/python2.7/site-packages/SimpleWebSocketServer/SimpleExampleServer.py to SimpleExampleServer.pyc
byte-compiling /usr/lib/python2.7/site-packages/SimpleWebSocketServer/SimpleHTTPSServer.py to SimpleHTTPSServer.pyc
byte-compiling /usr/lib/python2.7/site-packages/SimpleWebSocketServer/SimpleWebSocketServer.py to SimpleWebSocketServer.pyc
byte-compiling /usr/lib/python2.7/site-packages/SimpleWebSocketServer/__init__.py to __init__.pyc
running install_egg_info
Writing /usr/lib/python2.7/site-packages/SimpleWebSocketServer-0.1.1-py2.7.egg-info
 
[root@localhost SimpleWebSocketServer]# pwd
/root/simple-websocket-server-master/build/lib/SimpleWebSocketServer
 
[root@localhost SimpleWebSocketServer]# ls -al
total 36
drwxr-xr-x. 2 root root   115 Jun 11 04:25 .
drwxr-xr-x. 3 root root    35 Jun 11 04:25 ..
-rw-r--r--. 1 root root    67 Jun 11 04:23 __init__.py
-rw-r--r--. 1 root root  2392 Jun 11 04:23 SimpleExampleServer.py
-rw-r--r--. 1 root root   656 Jun 11 04:23 SimpleHTTPSServer.py
-rw-r--r--. 1 root root 23141 Jun 11 04:23 SimpleWebSocketServer.py
 
[root@localhost SimpleWebSocketServer]# python SimpleExampleServer.py --example=echo
<running 중>

 

2. Client 용 wscat 도구 설치 및 연결 테스트(Windows 환경)
https://nodejs.org/ko/download/ 에서 node download 및 설치하고, https://www.npmjs.com/package/wscat 을 참고하여 wscat 설치합니다.
설치된 wscat을 이용하여, WebSocket 서버에 연결 테스트 할 수 있습니다.
아래 테스트 예제에서 WebSocket 서버 주소는 NSX Load Balancer의 VIP입니다.

echo 모드로 WebSocket 서버를 띄웠기 때문에 Client에서 입력한 값을 그대로 다시 반환해줍니다.

C:\Users\Administrator.AD>wscat --connect ws://172.31.1.71:8000
Connected (press CTRL+C to quit)
> test
< test

 

3. 테스트 중 수집된 Packet

TCP-3 way Handshake > HTTP Upgrade 그리고 WebSocket Protocol을 확인할 수 있습니다.

## TCP 3-way Handshake
82  2024-06-12 10:59:49.159385  192.168.1.2 172.31.1.71 TCP 66  59731 → 8000 [SYN, ECN, CWR] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
83  2024-06-12 10:59:49.164136  172.31.1.71 192.168.1.2 TCP 66  8000 → 59731 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1460 SACK_PERM=1 WS=256
84  2024-06-12 10:59:49.164268  192.168.1.2 172.31.1.71 TCP 54  59731 → 8000 [ACK] Seq=1 Ack=1 Win=262656 Len=0
 
## HTTP Upgrade
85  2024-06-12 10:59:49.165125  192.168.1.2 172.31.1.71 HTTP    279 GET / HTTP/1.1
 
Frame 85: 279 bytes on wire (2232 bits), 279 bytes captured (2232 bits) on interface \Device\NPF_{FF69533E-FA39-45AE-896D-C78BFBF04F56}, id 0
Ethernet II, Src: VMware_01:8c:58 (00:50:56:01:8c:58), Dst: VMware_a6:de:28 (00:50:56:a6:de:28)
Internet Protocol Version 4, Src: 192.168.1.2, Dst: 172.31.1.71
Transmission Control Protocol, Src Port: 59731, Dst Port: 8000, Seq: 1, Ack: 1, Len: 225
Hypertext Transfer Protocol
    GET / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
            [GET / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    Sec-WebSocket-Version: 13\r\n
    Sec-WebSocket-Key: vwY2IBcicLkVwu3GkC9KxQ==\r\n
    Connection: Upgrade\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    Upgrade: websocket\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n
    Host: 172.31.1.71:8000\r\n
    \r\n
    [Full request URI: http://172.31.1.71:8000/]
    [HTTP request 1/1]
    [Response in frame: 87]
 
86  2024-06-12 10:59:49.168596  172.31.1.71 192.168.1.2 TCP 60  8000 → 59731 [ACK] Seq=1 Ack=226 Win=64256 Len=0
87  2024-06-12 10:59:49.180086  172.31.1.71 192.168.1.2 HTTP    220 HTTP/1.1 101 Switching Protocols
 
Frame 87: 220 bytes on wire (1760 bits), 220 bytes captured (1760 bits) on interface \Device\NPF_{FF69533E-FA39-45AE-896D-C78BFBF04F56}, id 0
Ethernet II, Src: VMware_a6:de:28 (00:50:56:a6:de:28), Dst: VMware_01:8c:58 (00:50:56:01:8c:58)
Internet Protocol Version 4, Src: 172.31.1.71, Dst: 192.168.1.2
Transmission Control Protocol, Src Port: 8000, Dst Port: 59731, Seq: 1, Ack: 226, Len: 166
Hypertext Transfer Protocol
    HTTP/1.1 101 Switching Protocols\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 101 Switching Protocols\r\n]
            [HTTP/1.1 101 Switching Protocols\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Response Version: HTTP/1.1
        Status Code: 101
        [Status Code Description: Switching Protocols]
        Response Phrase: Switching Protocols
    Date: Wed, 12 Jun 2024 10:59:33 GMT\r\n
    Connection: upgrade\r\n
    Upgrade: WebSocket\r\n
    Sec-WebSocket-Accept: mBVob19CTSoMER2nCze2vKKC0QE=\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.014961000 seconds]
    [Request in frame: 85]
    [Request URI: http://172.31.1.71:8000/]
 
88  2024-06-12 10:59:49.245554  192.168.1.2 172.31.1.71 TCP 54  59731 → 8000 [ACK] Seq=226 Ack=167 Win=262400 Len=0
 
## WebSocket Echo
136 2024-06-12 10:59:56.301322  192.168.1.2 172.31.1.71 WebSocket   64  WebSocket Text [FIN] [MASKED]
 
Frame 136: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface \Device\NPF_{FF69533E-FA39-45AE-896D-C78BFBF04F56}, id 0
Ethernet II, Src: VMware_01:8c:58 (00:50:56:01:8c:58), Dst: VMware_a6:de:28 (00:50:56:a6:de:28)
Internet Protocol Version 4, Src: 192.168.1.2, Dst: 172.31.1.71
Transmission Control Protocol, Src Port: 59731, Dst Port: 8000, Seq: 226, Ack: 167, Len: 10
WebSocket
    1... .... = Fin: True
    .000 .... = Reserved: 0x0
    .... 0001 = Opcode: Text (1)
    1... .... = Mask: True
    .000 0100 = Payload length: 4
    Masking-Key: ac2ab0bb
    Masked payload
    Payload
Line-based text data (1 lines)
    test
 
137 2024-06-12 10:59:56.313957  172.31.1.71 192.168.1.2 WebSocket   60  WebSocket Text [FIN]
 
Frame 137: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface \Device\NPF_{FF69533E-FA39-45AE-896D-C78BFBF04F56}, id 0
Ethernet II, Src: VMware_a6:de:28 (00:50:56:a6:de:28), Dst: VMware_01:8c:58 (00:50:56:01:8c:58)
Internet Protocol Version 4, Src: 172.31.1.71, Dst: 192.168.1.2
Transmission Control Protocol, Src Port: 8000, Dst Port: 59731, Seq: 167, Ack: 236, Len: 6
WebSocket
    1... .... = Fin: True
    .000 .... = Reserved: 0x0
    .... 0001 = Opcode: Text (1)
    0... .... = Mask: False
    .000 0100 = Payload length: 4
    Payload
Line-based text data (1 lines)
    test

 

NSX Load Balancer에서 Virtual Server에 HTTP Application Profile을 이용하면, WebSocket을 Client/Server 기반으로 사용하는데 다른 추가 설정 사항이 없음을 알 수 있습니다.