Skip to content

Commit

Permalink
Implement STDIOTunnel
Browse files Browse the repository at this point in the history
  • Loading branch information
kubrickfr committed Jun 11, 2023
1 parent b0a405a commit 0e5a590
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ Target = play.cubecraft.net:25565
ListenPort = 3422
Target = localhost:25545
# STDIOTunnel is a tunnel connecting the standard input and output of the wireproxy
# process to the specified TCP target via wireguard.
# This is especially useful to use wireproxy as a ProxyCommand parameter in openssh
# For example:
# ssh -o ProxyCommand='wireproxy -c myconfig.conf' ssh.myserver.net
# Flow:
# Piped command -->(wireguard)--> ssh.myserver.net:22
[STDIOTunnel]
Target = ssh.myserver.net:22
# Socks5 creates a socks5 proxy on your LAN, and all traffic would be routed via wireguard.
[Socks5]
BindAddress = 127.0.0.1:25344
Expand Down
5 changes: 5 additions & 0 deletions cmd/wireproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"os"
"os/exec"
"syscall"

"github.com/akamensky/argparse"
"github.com/octeep/wireproxy"
Expand Down Expand Up @@ -116,6 +117,10 @@ func main() {
return
}

// Wireguard doesn't allow configuring which FD to use for logging
// https://github.com/WireGuard/wireguard-go/blob/master/device/logger.go#L39
// so redirect STDOUT to STDERR, we don't want to print anything to STDOUT anyways
os.Stdout = os.NewFile(uintptr(syscall.Stderr), "/dev/stderr")
logLevel := device.LogLevelVerbose
if *silent {
logLevel = device.LogLevelSilent
Expand Down
20 changes: 20 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ type TCPClientTunnelConfig struct {
Target string
}

type STDIOTunnelConfig struct {
Target string
}

type TCPServerTunnelConfig struct {
ListenPort int
Target string
Expand Down Expand Up @@ -300,6 +304,17 @@ func parseTCPClientTunnelConfig(section *ini.Section) (RoutineSpawner, error) {
return config, nil
}

func parseSTDIOTunnelConfig(section *ini.Section) (RoutineSpawner, error) {
config := &STDIOTunnelConfig{}
targetSection, err := parseString(section, "Target")
if err != nil {
return nil, err
}
config.Target = targetSection

return config, nil
}

func parseTCPServerTunnelConfig(section *ini.Section) (RoutineSpawner, error) {
config := &TCPServerTunnelConfig{}

Expand Down Expand Up @@ -418,6 +433,11 @@ func ParseConfig(path string) (*Configuration, error) {
return nil, err
}

err = parseRoutinesConfig(&routinesSpawners, cfg, "STDIOTunnel", parseSTDIOTunnelConfig)
if err != nil {
return nil, err
}

err = parseRoutinesConfig(&routinesSpawners, cfg, "TCPServerTunnel", parseTCPServerTunnelConfig)
if err != nil {
return nil, err
Expand Down
36 changes: 36 additions & 0 deletions routine.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,32 @@ func tcpClientForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) {
go connForward(1024, conn, sconn)
}

// STDIOTcpForward starts a new connection via wireguard and forward traffic from `conn`
func STDIOTcpForward(vt *VirtualTun, raddr *addressPort) {
target, err := vt.resolveToAddrPort(raddr)
if err != nil {
errorLogger.Printf("Name resolution error for %s: %s\n", raddr.address, err.Error())
return
}

// os.Stdout has previously been remapped to stderr, se we can't use it
stdout, err := os.OpenFile("/dev/stdout", os.O_WRONLY, 0)
if err != nil {
errorLogger.Printf("Failed to open /dev/stdout: %s\n", err.Error())
return
}

tcpAddr := TCPAddrFromAddrPort(*target)
sconn, err := vt.Tnet.DialTCP(tcpAddr)
if err != nil {
errorLogger.Printf("TCP Client Tunnel to %s (%s): %s\n", target, tcpAddr, err.Error())
return
}

go connForward(1024, os.Stdin, sconn)
go connForward(1024, sconn, stdout)
}

// SpawnRoutine spawns a local TCP server which acts as a proxy to the specified target
func (conf *TCPClientTunnelConfig) SpawnRoutine(vt *VirtualTun) {
raddr, err := parseAddressPort(conf.Target)
Expand All @@ -213,6 +239,16 @@ func (conf *TCPClientTunnelConfig) SpawnRoutine(vt *VirtualTun) {
}
}

// SpawnRoutine connects to the specified target and plumbs it to STDIN / STDOUT
func (conf *STDIOTunnelConfig) SpawnRoutine(vt *VirtualTun) {
raddr, err := parseAddressPort(conf.Target)
if err != nil {
log.Fatal(err)
}

go STDIOTcpForward(vt, raddr)
}

// tcpServerForward starts a new connection locally and forward traffic from `conn`
func tcpServerForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) {
target, err := vt.resolveToAddrPort(raddr)
Expand Down

0 comments on commit 0e5a590

Please sign in to comment.