I am building a zitified windows RDP proxy. I need to find out what is the ziti ip of incomming connection.
Setup: Ubuntu host(runs ziti controller/router and also tunneler, etc) and windows 11 pro virtualbox vm(runs zitified proxy program).
ziti service “rdp” with intercept config 99.12.99.12 with port 1212
Ubuntu tunneler identity has #rdp.dial attr
Windows vm rdp.json has #rdp.bind attr
Problem is that conn does not return IP address of incomming connection:
log.Printf("remote addr: %s", conn.RemoteAddr())
log.Printf("local addr: %s", conn.LocalAddr().String())
// Output:
// remote addr: ziti-edge-router connId=2147483648, logical=ziti-sdk[router=tls:ziti-edge-router:80]
// locla addr: zitiConn connId=2147483648 svcId= sourceIdentity=admin1@gmail.com
However, when i call windows api - WTSEnumerateSessionsW and WTSQuerySessionInformationW i get this output:
2025/09/18 14:35:55 ------------------------------------------
<unsupported-family> / <none> -> 0
100.64.0.1 / carlo -> 1
<unsupported-family> / <none> -> 3
<unsupported-family> / <none> -> 65536
and on my ubuntu witch hold ziti controller, router, tunneler, etc, i have:
$ ip addr show | grep 100.64
inet 100.64.0.1/32 scope global ziti0
So windows session list knows the ziti IP.
Questions:
-
How can i know incoming connections IP address
-
if i have multiple incoming connections trough ziti, will the ip address always be the same
100.64.0.1or will each have a unique IP address.
Full example code:
package main
import (
"io"
"log"
"net"
"sync"
"time"
"github.com/openziti/sdk-golang/ziti"
)
const (
targetAddr = "127.0.0.1:3389" // local RDP service
)
func main() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
// Get identity config
cfg, err := ziti.NewConfigFromFile("rdp.json")
if err != nil {
panic(err)
}
// Get service name (defaults to "chat")
serviceName := "rdp"
options := ziti.ListenOptions{
ConnectTimeout: 5 * time.Minute,
MaxConnections: 3,
}
ctx, err := ziti.NewContext(cfg)
if err != nil {
panic(err)
}
listener, err := ctx.ListenWithOptions(serviceName, &options)
if err != nil {
panic(err)
}
for {
conn, err := listener.Accept()
if err != nil {
panic(err)
}
log.Printf("network: %s", conn.LocalAddr().Network())
log.Printf("remote addr: %s", conn.RemoteAddr())
log.Printf("local addr: %s", conn.LocalAddr().String())
go handleClient(conn)
}
}
func handleClient(client net.Conn) {
defer client.Close()
log.Printf("incoming from %s", client.RemoteAddr())
backend, err := net.Dial("tcp", targetAddr)
if err != nil {
log.Printf("dial backend %s: %v", targetAddr, err)
return
}
defer backend.Close()
// copy data in both directions
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
_, err := io.Copy(backend, client) // client -> backend
if err != nil {
log.Printf("copy client->backend: %v", err)
}
// signal EOF to backend write side if possible
if tc, ok := backend.(*net.TCPConn); ok {
tc.CloseWrite()
}
}()
go func() {
defer wg.Done()
_, err := io.Copy(client, backend) // backend -> client
if err != nil {
log.Printf("copy backend->client: %v", err)
}
// signal EOF to client write side if possible
if tc, ok := client.(*net.TCPConn); ok {
tc.CloseWrite()
}
}()
wg.Wait()
log.Printf("connection closed for %s", client.RemoteAddr())
/// we end screen control here
}
Note, use GitHub - openziti/sdk-golang: Ziti SDK for Golang v1.2.2. when i tried v1.2.4, it has the session issue from my previous post.
