Skip to content

Commit

Permalink
Added README and fine tunning of params
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomvalentim committed Jul 25, 2022
1 parent 9ac3784 commit 3e8070d
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

dist/
31 changes: 31 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
project_name: outsystemscc
before:
hooks:
- go mod tidy
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
dockers:
- image_templates: ["outsystems/{{ .ProjectName }}:{{ .Version }}"]
build_flag_templates:
- --platform=linux/amd64
- --label=org.opencontainers.image.title=OutSystems Cloud Connector
- --label=org.opencontainers.image.description=OutSystems Cloud Connector
- --label=org.opencontainers.image.url=https://github.com/outsystems/cloud-connector
- --label=org.opencontainers.image.source=https://github.com/outsystems/cloud-connector
- --label=org.opencontainers.image.version={{ .Version }}
- --label=org.opencontainers.image.created={{ .Date }}
- --label=org.opencontainers.image.revision={{ .FullCommit }}
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Dockerfile
FROM alpine
COPY outsystemscc /app
ENTRYPOINT ["/app"]
85 changes: 83 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,83 @@
# cloud-connector
OutSystems Cloud Connector
# OutSystems Cloud Connector

The OutSystems Cloud Connector (`outsystemscc`) allows applications running in the OutSystems cloud to securely access remote services running in a private network through the OutSystems Secure Gateway. It is based in the open source component [chisel](https://github.com/jpillora/chisel), which is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.

With `outsystemscc` you establish a secure tunnel from your private network (e.g. on-prem or private cloud) to the applications running in OutSystems cloud, while keeping full control and auditability of what it is exposed to your applications.

## Install

### Binaries
Download the latest release from the [releases page](https://github.com/OutSystems/cloud-connector/releases/latest).
Unzip/untar and copy the executable to the desired location, for example:
```sh
tar -xzf outsystemscc_1.0.0_linux_amd64.tar.gz
mv outsystemscc /usr/local/bin
./outsystemscc --help
```

### Docker

```sh
docker run --rm -it outsystems/outsystemscc --help
```

## Usage
```plain
Usage: outsystemscc [options] <server> <remote> [remote] [remote] ...
<server> is the URL to the server.
<remote>s are remote connections tunneled through the server, each of
which come in the form:
R:<local-port>:<remote-host>:<remote-port>
which does reverse port forwarding, sharing <remote-host>:<remote-port>
from the client to the server's <local-port>.
example remotes
R:2222:localhost:22
R:8080:10.0.0.1:80
Options:
--keepalive, An optional keepalive interval. Since the underlying
transport is HTTP, in many instances we'll be traversing through
proxies, often these proxies will close idle connections. You must
specify a time with a unit, for example '5s' or '2m'. Defaults
to '25s' (set to 0s to disable).
--max-retry-count, Maximum number of times to retry before exiting.
Defaults to unlimited.
--max-retry-interval, Maximum wait time before retrying after a
disconnection. Defaults to 5 minutes.
--proxy, An optional HTTP CONNECT or SOCKS5 proxy which will be
used to reach the server. Authentication can be specified
inside the URL.
For example, http://admin:[email protected]:8081
or: socks://admin:[email protected]:1080
--header, Set a custom header in the form "HeaderName: HeaderContent".
Can be used multiple times. (e.g --header "Foo: Bar" --header "Hello: World")
--hostname, Optionally set the 'Host' header (defaults to the host
found in the server url).
--pid Generate pid file in current working directory
-v, Enable verbose logging
--help, This help text
Signals:
The outsystemscc process is listening for:
a SIGUSR2 to print process stats, and
a SIGHUP to short-circuit the client reconnect timer
```

## License

[MIT](https://github.com/outsystems/cloud-connector/blob/master/LICENSE) © OutSystems
19 changes: 19 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/outsystems/cloud-connector

require github.com/jpillora/chisel v1.7.7

require (
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/jpillora/sizestr v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
)

replace github.com/jpillora/chisel => github.com/outsystems/chisel v1.7.7

go 1.18
35 changes: 35 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2/go.mod h1:jnzFpU88PccN/tPPhCpnNU8mZphvKxYM9lLNkd8e+os=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jpillora/ansi v1.0.2/go.mod h1:D2tT+6uzJvN1nBVQILYWkIdq7zG+b5gcFN5WI/VyjMY=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jpillora/requestlog v1.0.0/go.mod h1:HTWQb7QfDc2jtHnWe2XEIEeJB7gJPnVdpNn52HXPvy8=
github.com/jpillora/sizestr v1.0.0 h1:4tr0FLxs1Mtq3TnsLDV+GYUWG7Q26a6s+tV5Zfw2ygw=
github.com/jpillora/sizestr v1.0.0/go.mod h1:bUhLv4ctkknatr6gR42qPxirmd5+ds1u7mzD+MZ33f0=
github.com/outsystems/chisel v1.7.7 h1:igP2UIsbY7tKPUm8rfZWf99b8KiWTUnHz04rzYMIjvk=
github.com/outsystems/chisel v1.7.7/go.mod h1:X3ZzJDlOSlkMLVY3DMsdrd03rMtugLYk2IOUhvX0SXo=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
167 changes: 167 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package main

import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"runtime"
"strconv"
"strings"
"time"

chclient "github.com/jpillora/chisel/client"
"github.com/jpillora/chisel/share/cos"
)

var (
version = "dev" // Set by goreleaser
)

func main() {
client(os.Args[1:])
}

func generatePidFile() {
pid := []byte(strconv.Itoa(os.Getpid()))
if err := ioutil.WriteFile("outsystemscc.pid", pid, 0644); err != nil {
log.Fatal(err)
}
}

type headerFlags struct {
http.Header
}

func (flag *headerFlags) String() string {
out := ""
for k, v := range flag.Header {
out += fmt.Sprintf("%s: %s\n", k, v)
}
return out
}

func (flag *headerFlags) Set(arg string) error {
index := strings.Index(arg, ":")
if index < 0 {
return fmt.Errorf(`Invalid header (%s). Should be in the format "HeaderName: HeaderContent"`, arg)
}
if flag.Header == nil {
flag.Header = http.Header{}
}
key := arg[0:index]
value := arg[index+1:]
flag.Header.Set(key, strings.TrimSpace(value))
return nil
}

var clientHelp = `
Usage: outsystemscc [options] <server> <remote> [remote] [remote] ...
<server> is the URL to the server.
<remote>s are remote connections tunneled through the server, each of
which come in the form:
R:<local-port>:<remote-host>:<remote-port>
which does reverse port forwarding, sharing <remote-host>:<remote-port>
from the client to the server's <local-port>.
example remotes
R:2222:localhost:22
R:8080:10.0.0.1:80
Options:
--keepalive, An optional keepalive interval. Since the underlying
transport is HTTP, in many instances we'll be traversing through
proxies, often these proxies will close idle connections. You must
specify a time with a unit, for example '5s' or '2m'. Defaults
to '25s' (set to 0s to disable).
--max-retry-count, Maximum number of times to retry before exiting.
Defaults to unlimited.
--max-retry-interval, Maximum wait time before retrying after a
disconnection. Defaults to 5 minutes.
--proxy, An optional HTTP CONNECT or SOCKS5 proxy which will be
used to reach the server. Authentication can be specified
inside the URL.
For example, http://admin:[email protected]:8081
or: socks://admin:[email protected]:1080
--header, Set a custom header in the form "HeaderName: HeaderContent".
Can be used multiple times. (e.g --header "Foo: Bar" --header "Hello: World")
--hostname, Optionally set the 'Host' header (defaults to the host
found in the server url).
--pid Generate pid file in current working directory
-v, Enable verbose logging
--help, This help text
Signals:
The outsystemscc process is listening for:
a SIGUSR2 to print process stats, and
a SIGHUP to short-circuit the client reconnect timer
Version:
` + version + ` (` + runtime.Version() + `)
`

func client(args []string) {
flags := flag.NewFlagSet("client", flag.ContinueOnError)
config := chclient.Config{Headers: http.Header{}}
flags.DurationVar(&config.KeepAlive, "keepalive", 25*time.Second, "")
flags.IntVar(&config.MaxRetryCount, "max-retry-count", -1, "")
flags.DurationVar(&config.MaxRetryInterval, "max-retry-interval", 0, "")
flags.StringVar(&config.Proxy, "proxy", "", "")
flags.Var(&headerFlags{config.Headers}, "header", "")
hostname := flags.String("hostname", "", "")
pid := flags.Bool("pid", false, "")
verbose := flags.Bool("v", false, "")
flags.Usage = func() {
fmt.Print(clientHelp)
os.Exit(0)
}
flags.Parse(args)
//pull out options, put back remaining args
args = flags.Args()
if len(args) < 2 {
log.Fatalf("A server and least one remote is required")
}
config.Server = args[0]
config.Remotes = args[1:]
//default auth
if config.Auth == "" {
config.Auth = os.Getenv("AUTH")
}
//move hostname onto headers
if *hostname != "" {
config.Headers.Set("Host", *hostname)
}
//ready
c, err := chclient.NewClient(&config)
if err != nil {
log.Fatal(err)
}
c.Debug = *verbose
if *pid {
generatePidFile()
}
go cos.GoStats()
ctx := cos.InterruptContext()
if err := c.Start(ctx); err != nil {
log.Fatal(err)
}
if err := c.Wait(); err != nil {
log.Fatal(err)
}
}

0 comments on commit 3e8070d

Please sign in to comment.