Vncproxy - An RFB proxy, written in go that can save and replay FBS files

VncProxy CircleCI MIT Licensed

An RFB proxy, written in go that can save and replay FBS files

  • Supports all modern encodings & most useful pseudo-encodings
  • Supports multiple VNC client connections & multi servers (chosen by sessionId)
  • Supports being a "websockify" proxy (for web clients like NoVnc)
  • Produces FBS files compatible with tightvnc's rfb player (while using tight's default 3Byte color format)
  • Can also be used as:
    • A screen recorder vnc-client
    • A replay server to show fbs recordings to connecting clients
  • Tested on tight encoding with:
    • Tightvnc (client + java client + server)
    • FBS player (tightVnc Java player)
    • NoVnc(web client) => use -wsPort to open a websocket
    • ChickenOfTheVnc(client)
    • VineVnc(server)
    • TigerVnc(client)
    • Qemu vnc(server)

Executables (see releases)

  • proxy - the actual recording proxy, supports listening to tcp & ws ports and recording traffic to fbs files
  • recorder - connects to a vnc server as a client and records the screen
  • player - a toy player that will replay a given fbs file to all incoming connections

Usage:

recorder -recFile=./recording.rbs -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@
player -fbsFile=./myrec.fbs -tcpPort=5905
proxy -recDir=./recordings/ -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ -tcpPort=5903 -wsPort=5905 -vncPass=@!@!@!

Code usage examples

  • player/main.go (fbs recording vnc client)    * Connects as client, records to FBS file
  • proxy/proxy_test.go (vnc proxy with recording)
    • Listens to both Tcp and WS ports
    • Proxies connections to a hard-coded localhost vnc server
    • Records session to an FBS file
  • player/player_test.go (vnc replay server)
    • Listens to Tcp & WS ports
    • Replays a hard-coded FBS file in normal speed to all connecting vnc clients

Architecture

Image of Arch

Communication to vnc-server & vnc-client are done in the RFB binary protocol in the standard ways. Internal communication inside the proxy is done by listeners (a pub-sub system) that provide a stream of bytes, parsed by delimiters which provide information about RFB message start & type / rectangle start / communication closed, etc. This method allows for minimal delays in transfer, while retaining the ability to buffer and manipulate any part of the protocol.

For the client messages which are smaller, we send fully parsed messages going trough the same listener system. Currently client messages are used to determine the correct pixel format, since the client can change it by sending a SetPixelFormatMessage.

Tracking the bytes that are read from the actual vnc-server is made simple by using the RfbReadHelper (implements io.Reader) which sends the bytes to the listeners, this negates the need for manually keeping track of each byte read in order to write it into the recorder.

RFB Encoding-reader implementations do not decode pixel information, since this is not required for the proxy implementation.

This listener system was chosen over direct use of channels, since it allows the listening side to decide whether or not it wants to run in parallel, in contrast having channels inside the server/client objects which require you to create go routines (this creates problems when using go's native websocket implementation)

The Recorder uses channels and runs in parallel to avoid hampering the communication through the proxy.

Image of Arch

The code is based on several implementations of go-vnc including the original one by Mitchell Hashimoto, and the recentely active fork by Vasiliy Tolstov.

Owner
Amit Bezalel
I am a System Architect since 2007, a professional programmer since 2000, software development for me is a never-ending adventure, code the ultimate tool.
Amit Bezalel
Comments
  • Problem with websockets/noVNC

    Problem with websockets/noVNC

    Hi

    I'm facing a similar issue than #4 but since it's a bit different I prefer to open a dedicated issue.

    Using vncproxy I'm successfully managing to connect to a proxified local qemu VNC display using noVNC (i.e. it prints the VM display OK), but as soon as I type something into the viewport the connection closes and the proxy prints this error message:

    [Error] WriteTo.Consume (ServerUpdater SegmentBytes): problem writing to port: write tcp 172.16.24.134:5001->172.16.24.1:50732: use of closed network connection
    [Error] WriteTo.Consume (ServerUpdater SegmentBytes): problem writing to port: write tcp 172.16.24.134:5001->172.16.24.1:50732: use of closed network connection
    [Error] ClientConn.MainLoop: error parsing message, write tcp 172.16.24.134:5001->172.16.24.1:50732: use of closed network connection
    [Warn ] ClientConn.MainLoop: exiting!
    

    Note that it works OK using the RFB protocol via vncproxy, it looks like it's specific to the websocket protocol. Here is my configuration:

    • qemu: qemu-system-x86_64 [...lots of irrelevant options...] -display vnc=127.0.0.1:0
    • proxy (version linux-amd64-v1.02): ./vncproxy -targHost 127.0.0.1 -targPort 5900 -tcpPort 5901 -wsPort 5001
    • noVNC Websockets settings:
      • Host: 172.16.24.134
      • Port: 5001
      • Path:

    Am I doing something wrong?

  • Can you give me a more detail about how to use this vncproxy in my project

    Can you give me a more detail about how to use this vncproxy in my project

    If I have a VM create by KVM,and support VNC connect。 my VNC Server ip is 8.11.192.3, vncport of the VM is 5908.

    how to use this vncproxy, that I can view this VM by tigerVNC? image

  • Recording stops immediately

    Recording stops immediately

    I'm trying to record a session of TightVNC server with the recorder executable. I don't get any error, and the console is not quitting, it looks like it working but the file is not getting any bigger. When I'm trying to watch the file with the player executable it shows the first screen and throw error about EOF

    I'm using the latest release (1.0.2). Tested on Tight VNC Server on windows 7 and 10, recorder with ubuntu 16 and windows 10. Same results.

  • Regarding client-to-server messages

    Regarding client-to-server messages

    Hello, thank you very much for building this. I had a query - how do I explicitly separate client-to-server messages recorded, from server-to-client messages? I have a setup where I need to convert mouse and keyboard messages recorded from the client into pyautogui events. Any help appreciated, thanks.

  • Mouse and keyboards events recording

    Mouse and keyboards events recording

    Hello!

    I read vncproxy is able to record VNC session. Is this recorded video file such as MP4 or similar?

    If not it could be nice to add this feature. and I think it is very nice to add also the feature to record mouse and keyboard events as flat file "human readable" (or that can be parsed from 3rd party tools).

    My opinion is that this feature is really useful for smart-working solutions. In this way, IT admins are able to provide a tool to employees or consultants for accessing to internal servers by VPN and at the same time record everything they do for security reasons. This is a MUST for forensic analysis

    Regards, Mark

  • bad message type, 248 with noVNC 1.1.0

    bad message type, 248 with noVNC 1.1.0

    Hi,

    Im trying to use noVNC 1.1.0 with vncproxy 1.11 but I got this error:

    [Info ] FBS recording is turned off [Info ] running two listeners: tcp port: :5900, ws url: http://0.0.0.0:5001/ [Error] ClientConn.MainLoop: bad message type, 248 [Warn ] ClientConn.MainLoop: exiting! [Error] ClientUpdater.Consume (vnc-server-bound, SegmentFullyParsedClientMessage): problem writing to port: write tcp 192.168.0.201:54262->192.168.0.112:5900: use of closed network connection [Error] IServerConn.Handle: listener consume err write tcp 192.168.0.201:54262->192.168.0.112:5900: use of closed network connection

    my cmdline:

    proxy -targHost=192.168.0.112 -targPort=5900 -targPass=111111 -tcpPort=5900 -wsPort=5001 -vncPass=111

    rfbproxy works well with this cmdline

    ./rfbproxy -recFile=./recording.rbs -targHost=192.168.0.112 -targPort=5900 -targPass=111111

    Here is my information: vnc server: tigervnc-1.10.0 (default setting) noVNC Websockets settings: Host: 192.168.0.201 Port: 5001 Path:

    Am I doing something wrong? Thank you

  • Issue/ Usage Question with Player

    Issue/ Usage Question with Player

    Hello Amitbet,

    I am new to vncproxy and go. Hoping you can help with an issue I am having.

    I ran the recorder

    [root@localhost recordings]# recorder -recFile=./recordingj4.rbs -targHost=192.168.0.123 -targPort=5900 -targPass=123456

    Cntrl-C to stop it. (was this right?) ^C

    Then I ran the player

    [root@localhost recordings]# player -fbsFile=./recordingj4.rbs -tcpPort=5905

    It runs until a viewer connects. It shows the first frame to the viewer then crashes.

    Log level set to: info


    *** This is a toy server that replays a single FBS file to all clients ***


    [Info ] running tcp listener on port: 5905 panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5242bb]

    goroutine 35 [running]: github.com/amitbet/vncproxy/common.(*MultiListener).AddListener(...) /root/src/github.com/amitbet/vncproxy/common/multi-listener.go:8 github.com/amitbet/vncproxy/client.(*MsgServerCutText).CopyTo(0xc000096cf0, 0x742ec0, 0xc0000bca00, 0x742f00, 0xc00012e000, 0x7f36e9a62000, 0xc0000bca00, 0x0, 0xc00028b0f8) /root/src/github.com/amitbet/vncproxy/client/server-messages.go:254 +0xbb github.com/amitbet/vncproxy/player.(*FBSPlayListener).sendFbsMessage(0xc00009af00) /root/src/github.com/amitbet/vncproxy/player/fbs-play-listener.go:104 +0x390 github.com/amitbet/vncproxy/player.(*FBSPlayListener).Consume(0xc00009af00, 0xc0002bb6c0, 0x40d7c8, 0x40) /root/src/github.com/amitbet/vncproxy/player/fbs-play-listener.go:74 +0x114 github.com/amitbet/vncproxy/common.(*MultiListener).Consume(0xc0000b6380, 0xc0002bb6c0, 0xc0000efe00, 0x2) /root/src/github.com/amitbet/vncproxy/common/multi-listener.go:14 +0x6f github.com/amitbet/vncproxy/server.(*ServerConn).handle(0xc00012e000, 0x0, 0x0) /root/src/github.com/amitbet/vncproxy/server/server-conn.go:210 +0x57d github.com/amitbet/vncproxy/server.attachNewServerConn(0x7f36e9c0b0f8, 0xc0000a2038, 0xc00012a000, 0x6fa084, 0xc, 0x0, 0xc0000f3dd0) /root/src/github.com/amitbet/vncproxy/server/server.go:116 +0x27e created by github.com/amitbet/vncproxy/server.TcpServe /root/src/github.com/amitbet/vncproxy/server/server.go:69 +0x125

    Any ideas?

  • Problem with noVNC

    Problem with noVNC

    Hi,

    Im trying to use noVNC 1.0 (the latest) with vncproxy 1.0.2 but I got this error:

    [Error] ClientConn.MainLoop: bad message type, 250 [Warn ] ClientConn.MainLoop: exiting! [Error] ClientUpdater.Consume (vnc-server-bound, SegmentFullyParsedClientMessage): problem writing to port: write tcp 127.0.0.1:34908->127.0.0.1:5900: use of closed network connection [Error] IServerConn.Handle: listener consume err write tcp 127.0.0.1:34908->127.0.0.1:5900: use of closed network connection

    cmdline:

    ./proxy -recDir=./recordings/ -targHost=127.0.0.1 -targPort=5900 -tcpPort=5001

    rfbproxy works well with this cmdline

    ./rfbproxy --record --server localhost:0 rfb.log

    Thank you

  • Fix nil reference error for color map message

    Fix nil reference error for color map message

    I got an nil reference error with color map message processing on: github.com/amitbet/vncproxy v0.0.0-20191219055600-1c052273de0c due to reader.Listeners is not initialized.

    goroutine 8 [running]:
    testing.tRunner.func1(0xc0000e2200)
            /go/src/testing/testing.go:874 +0x3a3
    panic(0x706380, 0x9d7bc0)
            /go/src/runtime/panic.go:679 +0x1b2
    github.com/amitbet/vncproxy/common.(*MultiListener).AddListener(...)
            /vncproxy/common/multi-listener.go:8
    github.com/amitbet/vncproxy/client.(*MsgSetColorMapEntries).CopyTo(0xc0001441e0, 0x7d5680, 0xc0000fe120, 0x7d5700, 0xc000120000, 0x7f5bfb9ff398, 0xc0000fe120, 0xc0000b8690, 0x100) 
            /vncproxy/client/server-messages.go:134 +0xae
    github.com/amitbet/vncproxy/player.(*FBSPlayListener).sendFbsMessage(0xc000122150)
            /vncproxy/player/fbs-play-listener.go:107 +0x3a9
    github.com/amitbet/vncproxy/player.(*FBSPlayListener).Consume(0xc000122150, 0xc0003d3d00, 0x40e428, 0x40)
            /vncproxy/player/fbs-play-listener.go:77 +0x183
    github.com/amitbet/vncproxy/common.(*MultiListener).Consume(0xc00011a020, 0xc0003d3d00, 0x2c, 0xc000115bc0)
            /vncproxy/common/multi-listener.go:14 +0x6f
    
  • Fix recording bug in proxy

    Fix recording bug in proxy

    This change fixes a bug in the proxy session recording management, where the proxy would record sessions even if the user didn't provide a value for the -recDir CLI flag.

  • Bad message type 50

    Bad message type 50

    Hi,

    I can't connect from a Siemens HMI to Siemens HMI. UltraVNC to the Siemens HMI works. Need this because the direct connection isn't supported anymore.

    PS C:\Users\Andi\Downloads\vncproxy-windows-amd64-v1.12> .\proxy.exe -tcpPort 5900 -target 10.11.10.121:5900 -targPass vog -vncPass vog -logLevel debug
    Log level set to:  debug
    [Info ] FBS recording is turned off
    [Info ] running tcp listener on port: :5900
    [Debug] WriteTo.Consume (ServerUpdater): got segment type=SegmentServerInitMessage, object type:0
    [Debug] Server.ServerServerInitHandler initMessage: &{640 480 {16 16 0 1 31 63 31 11 5 0} 8 [119 111 114 107 68 101 115 107]}
    [Debug] ServerConn.handle: got messagetype, 0
    [Debug] ServerConn.handle: found message type, true
    [Debug] ServerConn.handle: got parsed messagetype, &{[0 0 0] {16 16 0 1 31 63 31 11 5 0} [0 0 0]}
    [Debug] ClientUpdater.Consume: updating pixel format
    [Debug] IServerConn.Handle got ClientMessage: SetPixelFormat, &{[0 0 0] {16 16 0 1 31 63 31 11 5 0} [0 0 0]}
    [Debug] ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=SetPixelFormat
    [Debug] ClientUpdater.Consume: updating pixel format
    [Debug] ServerConn.handle: got messagetype, 2
    [Debug] ServerConn.handle: found message type, true
    [Debug] ServerConn.handle: got parsed messagetype, &{[0] 16 [EncHextile EncZRLE EncZlib EncZlibHex EncCoRRE EncRRE EncCopyRect EncRaw  EncCursorPseudo EncPointerPosPseudo EncDesktopSizePseudo EncLastRectPseudo   EncJPEGQualityLevelPseudo7]}
    [Debug] IServerConn.Handle got ClientMessage: SetEncodings, &{[0] 16 [EncHextile EncZRLE EncZlib EncZlibHex EncCoRRE EncRRE EncCopyRect EncRaw  EncCursorPseudo EncPointerPosPseudo EncDesktopSizePseudo EncLastRectPseudo   EncJPEGQualityLevelPseudo7]}
    [Debug] ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=SetEncodings
    [Error] ClientConn.MainLoop: bad message type, 50
    [Warn ] ClientConn.MainLoop: exiting!
    [Debug] WriteTo.Consume (ServerUpdater): got segment type=SegmentConnectionClosed, object type:0
    [Debug] ServerConn.handle: got messagetype, 3
    [Debug] ServerConn.handle: found message type, true
    [Debug] ServerConn.handle: got parsed messagetype, &{0 0 0 640 480}
    [Debug] IServerConn.Handle got ClientMessage: FramebufferUpdateRequest, &{0 0 0 640 480}
    [Debug] ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=FramebufferUpdateRequest
    [Error] ClientUpdater.Consume (vnc-server-bound, SegmentFullyParsedClientMessage): problem writing to port: write tcp 172.30.0.244:31286->10.11.10.121:5900: use of closed network connection
    [Error] IServerConn.Handle: listener consume err write tcp 172.30.0.244:31286->10.11.10.121:5900: use of closed network connection
    

    Thanks

  • Issue with websockets/noVNC

    Issue with websockets/noVNC

    Hello,

    I'm facing an issue with vncproxy version v1.11 and noVNC v1.3.0 when I try to proxy a vnc unix socket from Qemu 6.2.0 running within Ubuntu Jammy. To reproduce, you have to install qemu-system-x86. Then you can fetch a Jammy cloud image from here 1 and run qemu with the following parameters:

        qemu-system-x86_64 -machine accel=kvm,type=q35 \ 
                   -cpu host -m 2048 \ 
                   -vnc vnc=unix:/var/run/qemu/testing.sock  \ 
                   -drive file=jammy-server-cloudimg-amd64.img,format=qcow2,if=virtio \
                   -nographic
    

    On the same machine, you can run noVNC, fetched from GitHub 2 - pick the tag you prefer - and, along with it, vncproxy. In my environment, I'm using noVNC tag/v1.3.0. I'm running vncproxy with the following command:

        ./proxy -target /var/run/qemu/testing.sock -wsPort 5980 -tcpPort 5900 -logLevel debug
    

    To expose noVNC, you can use a webserver of choice; in my case, I'm using the following command:

        python3 -m http.server --directory ~/noVNC 6080
    

    At this point, you can point your browser to http://localhost:6080/vnc_lite.html?host=localhost&port=5980&path=testing&encrypt=True.

    When I open the browser, noVNC presents the login, but it remains stuck forever;

    Screenshot 2022-11-29 at 19-04-21 noVNC

    I cannot send any input, whereas if I use Remmina 3 (a vnc client), I can connect and interact with the virtualized operating system without any issues.

    As you can see, I'm running vncproxy with -logLevel debug; you'll find attached the log to this issue.

    Do you have any idea why it breaks over the WebSocket?

    proxy.log

  • VNC username parameter?

    VNC username parameter?

    I have a question. Proxy argument has targPass which assumes VNC connection protected by a password. What if I need to provide username as well? Is there anyway to supply targUser or something as part of the proxy arguments?

    Thanks

  • Aten iKVM Support / encoding

    Aten iKVM Support / encoding

    Hey,

    I wanted to use the proxy but I got the following error when connecting with NoVNC to it. The upstream VNC server is a DELL iDRAC 8 KVM VNC server.

    When connecting the VNC Proxy closes with this message:

    [Error] ClientConn.MainLoop: bad message type, 250
    [Warn ] ClientConn.MainLoop: exiting!
    [Error] ClientUpdater.Consume (vnc-server-bound, SegmentFullyParsedClientMessage): problem writing to port: write tcp 10.10.16.2:38510->10.10.16.10:5901: use of closed network connection
    [Error] IServerConn.Handle: listener consume err write tcp 10.10.16.2:38510->10.10.16.10:5901: use of closed network connection
    

    Even If a ignore this message type 250 with continue (just testing) it continues the connection but fails then with:

    [Error] MsgFramebufferUpdate.Read: unsupported encoding type: 134219775, 
    [Error] ClientConn.MainLoop: error parsing message, MsgFramebufferUpdate.Read: unsupported encoding type: 134219775, 
    [Warn ] ClientConn.MainLoop: exiting!
    [Error] ServerConn.handle error: EOF
    

    It seems "Aten iKVM" isn't supported, can we add this to the project? Sadly I am not familiar with the VNC protocol at all and I would give you any information I can provide or even giving access to a test server.

    There are projects out there which are doing the encoding / translating already:

    • https://github.com/thefloweringash/aten-proxy
    • https://github.com/kelleyk/noVNC/tree/bmc-support/core/ast2100

    I have also seen you have another project vnc2video which also supports Aten KVM.

  • reMarkable 2.10 authentication support

    reMarkable 2.10 authentication support

    reMarkable 2.10 adds a Screen Sharing feature which uses VNC protocol (only 16-bit color + ZRLE). The authentication works via UDP broadcast and the requires the connecting device to send a correct response to a challenge. This adds support in VNC proxy to perform that function, so one can use a standard VNC client to connect (through the proxy).

Related tags
Swiss Army knife Proxy tool for HTTP/HTTPS traffic capture, manipulation, and replay on the go.
Swiss Army knife Proxy tool for HTTP/HTTPS traffic capture, manipulation, and replay on the go.

Features • Installation • Usage • Running Proxify • Installing SSL Certificate • Applications of Proxify • Join Discord Swiss Army Knife Proxy for rap

Jan 8, 2023
View, edit, and save text files via http to the file system.

go-wiki View, edit, and save text files via http to the file system. (DONE) https://golang.org/doc/articles/wiki/ Instructions go run main.go In a web

Nov 25, 2021
Record and replay a go net.Conn, mosting for testing.

fakeconn Record and replay a go net.Conn, mostly for testing and debugging. This package isn't finished, so you probably shouldn't use it. Recording f

Dec 5, 2021
HTTP proxy written in Go. COW can automatically identify blocked sites and use parent proxies to access.

COW (Climb Over the Wall) proxy COW 是一个简化穿墙的 HTTP 代理服务器。它能自动检测被墙网站,仅对这些网站使用二级代理。 English README. 当前版本:0.9.8 CHANGELOG 欢迎在 develop branch 进行开发并发送 pull

Jan 9, 2023
An experimental Tor-Proxy serivce written in Go using Go-proxy and Go-libtor.

tor-proxy An experimental standalone tor-proxy service built with Go, using go-proxy, go-libtor and bine. This is a simple replacement to Tor's origin

Nov 9, 2022
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Sep 27, 2022
IP2Proxy Go package allows users to query an IP address to determine if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.

IP2Proxy Go Package This package allows user to query an IP address if it was being used as VPN anonymizer, open proxies, web proxies, Tor exits, data

Sep 15, 2022
Battlesnake-logging-proxy - A little proxy between the internet and your battlesnake

battlesnake-logging-proxy a little proxy between the internet and your battlesna

Feb 11, 2022
Simple HTTP/HTTPS proxy - designed to be distributed as a self-contained binary that can be dropped in anywhere and run.

Simple Proxy This is a simple HTTP/HTTPS proxy - designed to be distributed as a self-contained binary that can be dropped in anywhere and run. Code b

Jan 7, 2023
Sep 23, 2022
mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together

mt-multiserver-proxy mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together. It is the successor to multiserv

Nov 17, 2022
A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/s2h@master Docker 用户 docker pull m

Jan 2, 2023
Tcp-proxy - A dead simple reverse proxy server.

tcp-proxy A proxy that forwords from a host to another. Building go build -ldflags="-X 'main.Version=$(git describe --tags $(git rev-list --tags --max

Jan 2, 2022
Proxy - Minimalistic TCP relay proxy.

Proxy Minimalistic TCP relay proxy. Installation ensure you have go >= 1.17 installed clone the repo cd proxy go install main.go Examples Listen on po

May 22, 2022
Http-logging-proxy - A HTTP Logging Proxy For Golang

http-logging-proxy HTTP Logging Proxy Description This project builds a simple r

Aug 1, 2022
Mauliasproxy - a simple room alias proxy that can respond to the federation alias query endpoint

Mauliasproxy - a simple room alias proxy that can respond to the federation alias query endpoint

Dec 22, 2022
Charmedring - A smart TCP proxy to replicate and backup Charm FS files
Charmedring - A smart TCP proxy to replicate and backup Charm FS files

Charmed ?? Ring A smart TCP proxy to replicate and backup Charm FS files. Overvi

Dec 15, 2022
A deployable proxy server and tunnel written in go

Tunnelify Tunnelify is a deployable proxy server and tunnel written in go Installing | Quickstart | Configuration Installing Direct download You can i

Dec 11, 2022