Initial commit

master
fangdingjun 9 years ago
commit 6ab42b01fd

3
.gitignore vendored

@ -0,0 +1,3 @@
gtunnel*
*~
*bak

@ -0,0 +1,41 @@
gtunnel
======
A stunnel like util write by golang
There are two work mode.
Client mode
==========
In this mode, listen for incoming plain connections and forward to server to use SSL/TLS connections
Server mode
===========
In this mode, listen for incoming SSL/TLS connections and forward to backend use plain connections
Build
====
go get github.com/fangdingjun/gtunnel
cd $GOPATH/src/github.com/fangdingjun/gtunnel
go build
Usage
====
server mode
./gtunnel --server --cert server.crt --key server.key --port 8001 --remote 127.0.0.1:80
listen for SSL/TLS connections on port 8001 and forward to 127.0.0.1:80
client mode
./gtunnel --client --port 8002 --remote www.example.com:8081
listen for plain connections on port 8002 and forward to www.example.com:8081 to use SSL/TLS connections
use `./gtunnel -h` see more options

@ -0,0 +1,53 @@
package main
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
)
//var server string = "www.ratafee.nl:443"
func local_main() {
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
log.Fatal(err)
}
log.Printf("Listen on %s...", l.Addr())
defer l.Close()
for {
c, err := l.Accept()
if err != nil {
log.Println(err)
continue
}
go handle_local(c)
}
}
func handle_local(c net.Conn) {
//defer c.Close()
log.Printf("accept connection from %s", c.RemoteAddr())
log.Printf("connect to %s...", remote)
s, err := tls.Dial("tcp", remote, nil)
if err != nil {
log.Printf("connect to %s failed: %s", remote, err.Error())
c.Close()
return
}
ch := make(chan int)
//defer s.Close()
go func() {
count, _ := io.Copy(s, c)
log.Printf("write %d bytes to %s", count, s.RemoteAddr())
s.Close()
ch <- 1
}()
co, _ := io.Copy(c, s)
log.Printf("write %d bytes to %s", co, c.RemoteAddr())
c.Close()
<-ch
}

@ -0,0 +1,39 @@
package main
import (
"flag"
"github.com/fangdingjun/iniflags"
"log"
)
var remote string
func main() {
var server, client bool
flag.StringVar(&remote, "remote", "", "remote server")
flag.IntVar(&port, "port", 8080, "the listen port")
flag.BoolVar(&server, "server", false, "tls server mode")
flag.BoolVar(&client, "client", false, "tls client mode")
flag.StringVar(&cert, "cert", "", "the certificate file")
flag.StringVar(&key, "key", "", "the private key")
iniflags.Parse()
if remote == "" {
log.Fatal("please use --remote to special the server")
}
if server {
if cert == "" || key == "" {
log.Fatal("in server mode, you must special the certificate and private key")
}
server_main()
return
}
if client {
local_main()
return
}
log.Fatal("please use --server or --client to special a work mode")
}

@ -0,0 +1,60 @@
package main
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
)
//var backend = "127.0.0.1:8080"
var cert = "server.crt"
var key = "server.key"
var port = 9000
func server_main() {
certificate, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
log.Fatal(err)
}
l, err := tls.Listen("tcp", fmt.Sprintf(":%d", port), &tls.Config{
Certificates: []tls.Certificate{certificate},
})
if err != nil {
log.Fatal(err)
}
defer l.Close()
for {
c, err := l.Accept()
if err != nil {
log.Println(err)
continue
}
go handle_server(c)
}
}
func handle_server(c net.Conn) {
log.Printf("accept connection from %s", c.RemoteAddr())
s, err := net.Dial("tcp", remote)
if err != nil {
log.Println(err)
c.Close()
return
}
ch := make(chan int)
go func() {
count, _ := io.Copy(s, c)
s.Close()
log.Printf("write %d bytes to %s", count, s.RemoteAddr())
ch <- 1
}()
co, _ := io.Copy(c, s)
c.Close()
log.Printf("write %d bytes to %s", co, c.RemoteAddr())
<-ch
}
Loading…
Cancel
Save