diff --git a/Dockerfile b/Dockerfile index 044d660..7f096ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,12 @@ RUN apk-install git RUN apk-install go ENV GOPATH /go -ENV PATH $GOPATH/bin:$PATH +ENV PATH /go/bin:$PATH + +COPY bin/proxy-link /usr/bin/proxy-link WORKDIR /go/src/github.com/convox/proxy COPY . /go/src/github.com/convox/proxy RUN go install ./... -ENTRYPOINT ["proxy"] +ENTRYPOINT ["proxy-link"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f9973ba --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +all: build + +build: + docker build --no-cache -t convox/proxy . + +test: + go test -cover -v ./... + +release: build + docker push convox/proxy diff --git a/bin/proxy-link b/bin/proxy-link new file mode 100755 index 0000000..ab41bce --- /dev/null +++ b/bin/proxy-link @@ -0,0 +1,11 @@ +#!/bin/sh + +from=${1} +shift +toport=${1} +shift +args=${@} + +eval to="\$HOST_PORT_${toport}_TCP_ADDR:\$HOST_PORT_${toport}_TCP_PORT" + +exec proxy $from $to $args diff --git a/main.go b/main.go index 49b1d62..c01b1ce 100644 --- a/main.go +++ b/main.go @@ -18,13 +18,17 @@ import ( ) func die(err error) { - fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) + warn(err) os.Exit(1) } +func warn(err error) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) +} + func main() { if len(os.Args) < 4 { - fmt.Fprintf(os.Stderr, "usage: proxy \n") + fmt.Fprintf(os.Stderr, "usage: proxy [options]\n") os.Exit(1) } @@ -32,9 +36,17 @@ func main() { to := os.Args[2] protocol := os.Args[3] proxy := false - - if len(os.Args) > 4 && os.Args[4] == "proxy" { - proxy = true + secure := false + + if len(os.Args) > 4 { + for _, option := range os.Args[4:] { + switch option { + case "proxy": + proxy = true + case "secure": + secure = true + } + } } ln, err := net.Listen("tcp", fmt.Sprintf(":%s", from)) @@ -68,42 +80,56 @@ func main() { } if proxy { - go handleProxyConnection(conn, to) + go handleProxyConnection(conn, to, secure) } else { - go handleTcpConnection(conn, to) + go handleTcpConnection(conn, to, secure) } } } -func handleProxyConnection(in net.Conn, to string) { +func handleProxyConnection(in net.Conn, to string, secure bool) { rp := strings.SplitN(in.RemoteAddr().String(), ":", 2) top := strings.SplitN(to, ":", 2) - fmt.Printf("proxy %s:%s -> %s:%s\n", rp[0], rp[1], top[0], top[1]) + fmt.Printf("proxy %s:%s -> %s:%s secure=%t\n", rp[0], rp[1], top[0], top[1], secure) out, err := net.DialTimeout("tcp", to, 5*time.Second) if err != nil { - die(err) + warn(err) + return } header := fmt.Sprintf("PROXY TCP4 %s 127.0.0.1 %s %s\r\n", rp[0], rp[1], top[1]) out.Write([]byte(header)) + if secure { + out = tls.Client(out, &tls.Config{ + InsecureSkipVerify: true, + }) + } + pipe(in, out) } -func handleTcpConnection(in net.Conn, to string) { +func handleTcpConnection(in net.Conn, to string, secure bool) { rp := strings.SplitN(in.RemoteAddr().String(), ":", 2) top := strings.SplitN(to, ":", 2) - fmt.Printf("tcp %s:%s -> %s:%s\n", rp[0], rp[1], top[0], top[1]) + fmt.Printf("tcp %s:%s -> %s:%s secure=%t\n", rp[0], rp[1], top[0], top[1], secure) out, err := net.DialTimeout("tcp", to, 5*time.Second) if err != nil { - die(err) + warn(err) + return + } + + if secure { + out = tls.Client(out, &tls.Config{ + InsecureSkipVerify: true, + }) } pipe(in, out)