1

I need to use websockify as a proxy. The final setup will be:

  • a websocket on a webpage connects to websockify server on the same machine
  • websockify server initiates connection with a TCP socket program listening somewhere else (in this case, the same machine)
  • TCP socket receives information, performs computation, answers websockify
  • websockify gets the answer and sends the information to the socket on webpage
  • answer is presented in a user's browser

However, for some reason websockify refuses to pass the information further and receives FIN message sooner than expected. Websockify says "Unsupported: Unknown opcode 0x01".

To investigate this case, I have created a MWE and intercepted traffic with tcpdump.

The setup is as follows:

  • Firstly, I run netcat -v -v -l -p 40000 - that's the application we want to receive the information

  • Then, I run websockify --verbose 50000 localhost:40000 - that's the proxying command

  • Finally, I run wscat -c localhost:50000 - that's an app making a websocket connection to websockify proxy

As soon as I send something with wscat, wscat's connection is dropped with code 1003. Quoting RFC 6455:

1003 indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it receives a binary message).

Here is the visual representation of that setup (the erorr message 'disconnected because closed 1003' is written that way because I have manally altered the source to extract more information about disconnection):

enter image description here

Here is Wireshark's representation of the data: enter image description here

and here are the packets number 11,12,13 and 14 that caught my attention:

Frame 11: 81 bytes on wire (648 bits), 81 bytes captured (648 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Sep 19, 2017 20:35:46.491762000 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1505846146.491762000 seconds
    [Time delta from previous captured frame: 3.788711000 seconds]
    [Time delta from previous displayed frame: 3.788711000 seconds]
    [Time since reference or first frame: 3.887638000 seconds]
    Frame Number: 11
    Frame Length: 81 bytes (648 bits)
    Capture Length: 81 bytes (648 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:tcp:http:websocket:data-text-lines]
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
    Destination: 00:00:00_00:00:00 (00:00:00:00:00:00)
        Address: 00:00:00_00:00:00 (00:00:00:00:00:00)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: 00:00:00_00:00:00 (00:00:00:00:00:00)
        Address: 00:00:00_00:00:00 (00:00:00:00:00:00)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 67
    Identification: 0x1581 (5505)
    Flags: 0x02 (Don't Fragment)
        0... .... = Reserved bit: Not set
        .1.. .... = Don't fragment: Set
        ..0. .... = More fragments: Not set
    Fragment offset: 0
    Time to live: 64
    Protocol: TCP (6)
    Header checksum: 0x2732 [validation disabled]
    [Header checksum status: Unverified]
    Source: 127.0.0.1
    Destination: 127.0.0.1
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
TCP Src Port: 53832, Dst Port: 50000, Seq: 225, Ack: 130, Len: 15
    Src Port: 53832
    Dest Port: 50000
    [Stream index: 0]
    [TCP Segment Len: 15]
    Sequence number: 225    (relative sequence number)
    [Next sequence number: 240    (relative sequence number)]
    Acknowledgment number: 130    (relative ack number)
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x018 (PSH, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 1... = Push: Set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······AP···]
    Window size value: 350
    [Calculated window size: 44800]
    [Window size scaling factor: 128]
    Checksum: 0xfe37 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - Timestamps: TSval 1764320477, TSecr 1764319312
            Kind: Time Stamp Option (8)
            Length: 10
            Timestamp value: 1764320477
            Timestamp echo reply: 1764319312
    [SEQ/ACK analysis]
        [iRTT: 0.000021000 seconds]
        [Bytes in flight: 15]
        [Bytes sent since last PSH flag: 15]
    TCP payload (15 bytes)
    [PDU Size: 15]
WebSocket
    1... .... = Fin: True
    .000 .... = Reserved: 0x0
    .... 0001 = Opcode: Text (1)
    1... .... = Mask: True
    .000 1001 = Payload length: 9
    Masking-Key: 2f0bda1c
    Masked payload
    Payload
Line-based text data
    alamakota

Frame 12: 102 bytes on wire (816 bits), 102 bytes captured (816 bits) Encapsulation type: Ethernet (1) Arrival Time: Sep 19, 2017 20:35:46.492378000 CEST [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1505846146.492378000 seconds [Time delta from previous captured frame: 0.000616000 seconds] [Time delta from previous displayed frame: 0.000616000 seconds] [Time since reference or first frame: 3.888254000 seconds] Frame Number: 12 Frame Length: 102 bytes (816 bits) Capture Length: 102 bytes (816 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ethertype:ip:tcp:http:websocket] Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Destination: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IPv4 (0x0800) Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 0100 .... = Version: 4 .... 0101 = Header Length: 20 bytes (5) Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 0000 00.. = Differentiated Services Codepoint: Default (0) .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0) Total Length: 88 Identification: 0xd42e (54318) Flags: 0x02 (Don't Fragment) 0... .... = Reserved bit: Not set .1.. .... = Don't fragment: Set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 64 Protocol: TCP (6) Header checksum: 0x686f [validation disabled] [Header checksum status: Unverified] Source: 127.0.0.1 Destination: 127.0.0.1 [Source GeoIP: Unknown] [Destination GeoIP: Unknown] TCP Src Port: 50000, Dst Port: 53832, Seq: 130, Ack: 240, Len: 36 Src Port: 50000 Dest Port: 53832 [Stream index: 0] [TCP Segment Len: 36] Sequence number: 130 (relative sequence number) [Next sequence number: 166 (relative sequence number)] Acknowledgment number: 240 (relative ack number) 1000 .... = Header Length: 32 bytes (8) Flags: 0x018 (PSH, ACK) 000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set .... .0.. .... = ECN-Echo: Not set .... ..0. .... = Urgent: Not set .... ...1 .... = Acknowledgment: Set .... .... 1... = Push: Set .... .... .0.. = Reset: Not set .... .... ..0. = Syn: Not set .... .... ...0 = Fin: Not set [TCP Flags: ·······AP···] Window size value: 350 [Calculated window size: 44800] [Window size scaling factor: 128] Checksum: 0xfe4c [unverified] [Checksum Status: Unverified] Urgent pointer: 0 Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - Timestamps: TSval 1764320478, TSecr 1764320477 Kind: Time Stamp Option (8) Length: 10 Timestamp value: 1764320478 Timestamp echo reply: 1764320477 [SEQ/ACK analysis] [This is an ACK to the segment in frame: 11] [The RTT to ACK the segment was: 0.000616000 seconds] [iRTT: 0.000021000 seconds] [Bytes in flight: 36] [Bytes sent since last PSH flag: 36] TCP payload (36 bytes) [PDU Size: 36] WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 1000 = Opcode: Connection Close (8) 0... .... = Mask: False .010 0010 = Payload length: 34 Payload Close Status code: Unsupported Data (1003) Reason: Unsupported: Unknown opcode 0x01

Frame 13: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) Encapsulation type: Ethernet (1) Arrival Time: Sep 19, 2017 20:35:46.492394000 CEST [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1505846146.492394000 seconds [Time delta from previous captured frame: 0.000016000 seconds] [Time delta from previous displayed frame: 0.000016000 seconds] [Time since reference or first frame: 3.888270000 seconds] Frame Number: 13 Frame Length: 66 bytes (528 bits) Capture Length: 66 bytes (528 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ethertype:ip:tcp] Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Destination: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IPv4 (0x0800) Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 0100 .... = Version: 4 .... 0101 = Header Length: 20 bytes (5) Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 0000 00.. = Differentiated Services Codepoint: Default (0) .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0) Total Length: 52 Identification: 0x1582 (5506) Flags: 0x02 (Don't Fragment) 0... .... = Reserved bit: Not set .1.. .... = Don't fragment: Set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 64 Protocol: TCP (6) Header checksum: 0x2740 [validation disabled] [Header checksum status: Unverified] Source: 127.0.0.1 Destination: 127.0.0.1 [Source GeoIP: Unknown] [Destination GeoIP: Unknown] TCP Src Port: 53832, Dst Port: 50000, Seq: 240, Ack: 166, Len: 0 Src Port: 53832 Dest Port: 50000 [Stream index: 0] [TCP Segment Len: 0] Sequence number: 240 (relative sequence number) Acknowledgment number: 166 (relative ack number) 1000 .... = Header Length: 32 bytes (8) Flags: 0x010 (ACK) 000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set .... .0.. .... = ECN-Echo: Not set .... ..0. .... = Urgent: Not set .... ...1 .... = Acknowledgment: Set .... .... 0... = Push: Not set .... .... .0.. = Reset: Not set .... .... ..0. = Syn: Not set .... .... ...0 = Fin: Not set [TCP Flags: ·······A····] Window size value: 350 [Calculated window size: 44800] [Window size scaling factor: 128] Checksum: 0xfe28 [unverified] [Checksum Status: Unverified] Urgent pointer: 0 Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - Timestamps: TSval 1764320478, TSecr 1764320478 Kind: Time Stamp Option (8) Length: 10 Timestamp value: 1764320478 Timestamp echo reply: 1764320478 [SEQ/ACK analysis] [This is an ACK to the segment in frame: 12] [The RTT to ACK the segment was: 0.000016000 seconds] [iRTT: 0.000021000 seconds]

Frame 14: 106 bytes on wire (848 bits), 106 bytes captured (848 bits) Encapsulation type: Ethernet (1) Arrival Time: Sep 19, 2017 20:35:46.494661000 CEST [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1505846146.494661000 seconds [Time delta from previous captured frame: 0.002267000 seconds] [Time delta from previous displayed frame: 0.002267000 seconds] [Time since reference or first frame: 3.890537000 seconds] Frame Number: 14 Frame Length: 106 bytes (848 bits) Capture Length: 106 bytes (848 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ethertype:ip:tcp:http:websocket] Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Destination: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IPv4 (0x0800) Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 0100 .... = Version: 4 .... 0101 = Header Length: 20 bytes (5) Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 0000 00.. = Differentiated Services Codepoint: Default (0) .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0) Total Length: 92 Identification: 0x1583 (5507) Flags: 0x02 (Don't Fragment) 0... .... = Reserved bit: Not set .1.. .... = Don't fragment: Set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 64 Protocol: TCP (6) Header checksum: 0x2717 [validation disabled] [Header checksum status: Unverified] Source: 127.0.0.1 Destination: 127.0.0.1 [Source GeoIP: Unknown] [Destination GeoIP: Unknown] TCP Src Port: 53832, Dst Port: 50000, Seq: 240, Ack: 166, Len: 40 Src Port: 53832 Dest Port: 50000 [Stream index: 0] [TCP Segment Len: 40] Sequence number: 240 (relative sequence number) [Next sequence number: 280 (relative sequence number)] Acknowledgment number: 166 (relative ack number) 1000 .... = Header Length: 32 bytes (8) Flags: 0x018 (PSH, ACK) 000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set .... .0.. .... = ECN-Echo: Not set .... ..0. .... = Urgent: Not set .... ...1 .... = Acknowledgment: Set .... .... 1... = Push: Set .... .... .0.. = Reset: Not set .... .... ..0. = Syn: Not set .... .... ...0 = Fin: Not set [TCP Flags: ·······AP···] Window size value: 350 [Calculated window size: 44800] [Window size scaling factor: 128] Checksum: 0xfe50 [unverified] [Checksum Status: Unverified] Urgent pointer: 0 Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - No-Operation (NOP) Kind: No-Operation (1) TCP Option - Timestamps: TSval 1764320478, TSecr 1764320478 Kind: Time Stamp Option (8) Length: 10 Timestamp value: 1764320478 Timestamp echo reply: 1764320478 [SEQ/ACK analysis] [iRTT: 0.000021000 seconds] [Bytes in flight: 40] [Bytes sent since last PSH flag: 40] TCP payload (40 bytes) [PDU Size: 40] WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 1000 = Opcode: Connection Close (8) 1... .... = Mask: True .010 0010 = Payload length: 34 Masking-Key: 3daec4d6 Masked payload Payload Close Status code: Unsupported Data (1003) Reason: Unsupported: Unknown opcode 0x01

It seems like wscat sends an opcode (0x1) which websockify understands as 0x01 and fails to recognize, but I don't know why.

How do I make this setup work? I have tried connecting to websockify with different programs (browser websocket implementation, wscat alternatives), but they all fail.

1 Answers1

3

I hit the same issue:

socket.send("hi"); // websockify chokes

... which got fixed by this:

b = new Blob(["hi", "\n"], {type: 'text/plain'});
socket.send(b); // works as expected