-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8839e9c
Showing
7 changed files
with
596 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Edge Proxy Daemon | ||
|
||
This is a TCP reverse proxy for edge services behind firewalls. | ||
|
||
## How It Works | ||
|
||
The Edge Proxy Daemon must run somewhere it's able to open a TCP port on the network | ||
that services are being exposed to (e.g. Internet). The edge services connect to | ||
this proxy via SSH remote port forwarding. Here's an example: | ||
|
||
- Run Edge Proxy Daemon on Internet, with DNS name epd.example.com; | ||
- A web server is running behind firewall, and it's listening on `localhost:8080`; | ||
- On the same machine as the web server is running, run `ssh -N -R www.example.com:80:localhost:8080 user@epd.example.com` | ||
|
||
Now open the browser to access `http://www.example.com`, it should reach the web server running behind the firewall. | ||
The Edge Proxy Daemon doesn't expose the exact port requested by the SSH client, | ||
instead, it opens a random port on localhost, and relies on a endpoint setup script | ||
to configure another reverse proxy for forwarding the connection on the requested DNS to this local port. | ||
|
||
## Usage | ||
|
||
Launch `epd` without arguments to use default configurations: | ||
|
||
- `-addr=:2022`: listen on `:2022` as SSH server address; | ||
- Use host keys from `/etc/ssh`; | ||
- Use `~/.ssh/authorized_keys` for authorized keys; | ||
- `-bind-addr=localhost`: open random TCP port as requested on `localhost`; | ||
|
||
In addition to that, specifying `-endpoint-exec=PROGRAM` to use `PROGRAM` for setting up a DNS based reverse proxy. | ||
|
||
For example, when using [traefik](https://github.com/containous/traefik), a shell script can be used to configure it | ||
for forwarding the request on a specific DNS to a localhost port. | ||
The `PROGRAM` is invoked as: | ||
|
||
``` | ||
PROGRAM open|close hostname local-port | ||
``` | ||
|
||
When `local-port` is opened for `hostname` (request on the client side as `ssh -R hostname:anyport:host:port`), | ||
`open` is used. | ||
When the forwarding request is canceled, `close` is used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"os" | ||
"os/signal" | ||
"strings" | ||
"syscall" | ||
|
||
"github.com/evo-cloud/epd/pkg/endpoint" | ||
"github.com/evo-cloud/epd/pkg/ssh" | ||
"github.com/golang/glog" | ||
) | ||
|
||
var ( | ||
listenAddr = flag.String("addr", ":2022", "Listening address") | ||
bindAddr = flag.String("bind-addr", "localhost", "Bind address for remote forwarding ports") | ||
endpointExec = flag.String("endpoint-exec", "", "Endpoint setup executable") | ||
hostKeyFiles = flag.String("host-key-files", "", "Comma-separated host key files") | ||
) | ||
|
||
func init() { | ||
flag.StringVar(&ssh.AuthorizedKeysFile, "authorized-keys-file", ssh.AuthorizedKeysFile, "SSH authorized_keys file") | ||
} | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
if *hostKeyFiles != "" { | ||
ssh.HostKeyFiles = strings.Split(*hostKeyFiles, ",") | ||
} | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
server := ssh.NewServer() | ||
if err := server.DefaultConfig(); err != nil { | ||
glog.Exitf("Load config error: %v", err) | ||
} | ||
server.BindAddress = *bindAddr | ||
|
||
if *endpointExec != "" { | ||
configurator := &endpoint.Exec{Program: *endpointExec} | ||
server.ListenCallback = configurator.ListenCallback(server.BindAddress) | ||
} | ||
|
||
sigCh := make(chan os.Signal, 1) | ||
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) | ||
go func() { | ||
<-sigCh | ||
cancel() | ||
<-sigCh | ||
os.Exit(1) | ||
}() | ||
|
||
if err := server.ListenAndServe(ctx, *listenAddr); err != nil { | ||
glog.Exitf("Server start error: %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module github.com/evo-cloud/epd | ||
|
||
go 1.14 | ||
|
||
require ( | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b | ||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig= | ||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package endpoint | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
|
||
"github.com/evo-cloud/epd/pkg/ssh" | ||
) | ||
|
||
// Exec invokes external program for setting up an endpoint. | ||
type Exec struct { | ||
Program string | ||
} | ||
|
||
// ListenCallback returns a ssh.ListenCallback to invoke the external program. | ||
func (x *Exec) ListenCallback(bindAddr string) ssh.ListenCallbackFunc { | ||
return func(ctx context.Context, host string, port int, on bool) error { | ||
action := "open" | ||
if !on { | ||
action = "close" | ||
} | ||
backend := bindAddr + fmt.Sprintf(":%d", port) | ||
return x.invoke(ctx, action, host, backend) | ||
} | ||
} | ||
|
||
func (x *Exec) invoke(ctx context.Context, action, name, addr string) error { | ||
cmd := exec.CommandContext(ctx, x.Program, action, name, addr) | ||
cmd.Env = os.Environ() | ||
cmd.Stdout = os.Stdout | ||
cmd.Stderr = os.Stderr | ||
return cmd.Run() | ||
} |
Oops, something went wrong.