Skip to content

Commit

Permalink
Merge pull request #52 from antoniomika/add_better_formatting
Browse files Browse the repository at this point in the history
Started work on new formatting
  • Loading branch information
antoniomika authored Nov 23, 2019
2 parents a68ab2d + 16c2a1a commit 0a13da2
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ ssl/*
sish
deploy/*
!deploy/docker-compose.yml
dist/
dist/
__debug_bin
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"-sish.forcerandomsubdomain=false",
"-sish.bindrandom=false",
"-sish.tcpalias=true",
"-sish.proxyprotoenabled=false"
"-sish.proxyprotoenabled=false",
"-sish.logtoclient=true"
]
}
]
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Builds are made automatically on Google Cloud Build and Dockerhub. Feel free to
1. Pull the Docker image
- `docker pull antoniomika/sish:latest`
2. Run the image

- ```bash
docker run -itd --name sish \
-v ~/sish/ssl:/ssl \
Expand All @@ -24,6 +25,7 @@ Builds are made automatically on Google Cloud Build and Dockerhub. Feel free to
-sish.pkloc=/keys/ssh_key \
-sish.bindrandom=false
```

3. SSH to your host to communicate with sish
- `ssh -p 2222 -R 80:localhost:8080 ssi.sh`

Expand All @@ -42,7 +44,7 @@ docker-compose -f deploy/docker-compose.yml up -d
SSH can normally forward local and remote ports. This service implements an SSH server that only does that and nothing else. The service supports multiplexing connections over HTTP/HTTPS with WebSocket support. Just assign a remote port as port `80` to proxy HTTP traffic and `443` to proxy HTTPS traffic. If you use any other remote port, the server will listen to the port for connections, but only if that port is available.
You can choose your own subdomain instead of relying on a randomly assigned one
by setting the `-sish.bindrandom` option to `false` and then selecting a
by setting the `-sish.forcerandomsubdomain` option to `false` and then selecting a
subdomain by prepending it to the remote port specifier:
`ssh -p 2222 -R foo:80:localhost:8080 ssi.sh`
Expand Down Expand Up @@ -107,18 +109,16 @@ Usage of ./sish:
Whether or not to force a random subdomain (default true)
-sish.http string
The address to listen for HTTP connections (default "localhost:80")
-sish.httpport int
The port for HTTP connections. This is only for output messages (default 80)
-sish.https string
The address to listen for HTTPS connections (default "localhost:443")
-sish.httpsenabled
Whether or not to listen for HTTPS connections
-sish.httpspems string
The location of pem files for HTTPS (fullchain.pem and privkey.pem) (default "ssl/")
-sish.httpsport int
The port for HTTPS connections. This is only for output messages (default 443)
-sish.keysdir string
Directory for public keys for pubkey auth (default "pubkeys/")
-sish.logtoclient
Whether or not to log http requests to the client
-sish.password string
Password to use for password auth (default "S3Cr3tP4$$W0rD")
-sish.pkloc string
Expand Down
Binary file removed __debug_bin
Binary file not shown.
5 changes: 3 additions & 2 deletions channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"strings"

"github.com/logrusorgru/aurora"
"golang.org/x/crypto/ssh"
)

Expand All @@ -28,7 +29,7 @@ func handleSession(newChannel ssh.NewChannel, sshConn *SSHConnection, state *Sta
select {
case c := <-sshConn.Messages:
_, err := connection.Write(append([]byte(c), []byte{'\r', '\n'}...))
if err != nil {
if err != nil && *debug {
log.Println("Error trying to write message to socket:", err)
}
case <-sshConn.Close:
Expand All @@ -37,7 +38,7 @@ func handleSession(newChannel ssh.NewChannel, sshConn *SSHConnection, state *Sta
}
}()

sshConn.Messages <- "Press Ctrl-C to close the session."
sshConn.Messages <- aurora.BgRed("Press Ctrl-C to close the session.").String()

go func() {
for {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/jpillora/ipfilter v1.0.0
github.com/json-iterator/go v1.1.8 // indirect
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/logrusorgru/aurora v0.0.0-20191116043053-66b7ad493a23
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/oschwald/maxminddb-golang v1.5.0 // indirect
github.com/pires/go-proxyproto v0.0.0-20190615163442-2c19fd512994
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46O
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn5wlyECw3iJrzi0AhIWg+AJUb4PlRQVW4/3XHH1LZA=
github.com/logrusorgru/aurora v0.0.0-20191116043053-66b7ad493a23 h1:Wp7NjqGKGN9te9N/rvXYRhlVcrulGdxnz8zadXWs7fc=
github.com/logrusorgru/aurora v0.0.0-20191116043053-66b7ad493a23/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
Expand Down
15 changes: 14 additions & 1 deletion http.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type ProxyHolder struct {
ProxyHost string
ProxyTo string
Scheme string
SSHConn *SSHConnection
}

func startHTTPHandler(state *State) {
Expand Down Expand Up @@ -51,7 +52,8 @@ func startHTTPHandler(state *State) {
// Truncate in a golang < 1.8 safe way
param.Latency = param.Latency - param.Latency%time.Second
}
return fmt.Sprintf("[GIN] %v | %s |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",

logLine := fmt.Sprintf("%v | %s |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
param.Request.Host,
statusColor, param.StatusCode, resetColor,
Expand All @@ -61,6 +63,17 @@ func startHTTPHandler(state *State) {
param.Path,
param.ErrorMessage,
)

if *logToClient {
hostname := strings.Split(param.Request.Host, ":")[0]
loc, ok := state.HTTPListeners.Load(hostname)
if ok {
proxyHolder := loc.(*ProxyHolder)
sendMessage(proxyHolder.SSHConn, strings.TrimSpace(logLine))
}
}

return logLine
}), gin.Recovery(), func(c *gin.Context) {
hostname := strings.Split(c.Request.Host, ":")[0]

Expand Down
33 changes: 30 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"runtime"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -40,11 +41,11 @@ var (
version = "dev"
commit = "none"
date = "unknown"
httpPort int
httpsPort int
serverAddr = flag.String("sish.addr", "localhost:2222", "The address to listen for SSH connections")
httpAddr = flag.String("sish.http", "localhost:80", "The address to listen for HTTP connections")
httpPort = flag.Int("sish.httpport", 80, "The port for HTTP connections. This is only for output messages")
httpsAddr = flag.String("sish.https", "localhost:443", "The address to listen for HTTPS connections")
httpsPort = flag.Int("sish.httpsport", 443, "The port for HTTPS connections. This is only for output messages")
verifyOrigin = flag.Bool("sish.verifyorigin", true, "Whether or not to verify origin on websocket connection")
verifySSL = flag.Bool("sish.verifyssl", true, "Whether or not to verify SSL on proxy connection")
httpsEnabled = flag.Bool("sish.httpsenabled", false, "Whether or not to listen for HTTPS connections")
Expand Down Expand Up @@ -73,15 +74,36 @@ var (
debug = flag.Bool("sish.debug", false, "Whether or not to print debug information")
versionCheck = flag.Bool("sish.version", false, "Print version and exit")
tcpAlias = flag.Bool("sish.tcpalias", false, "Whether or not to allow the use of TCP aliasing")
logToClient = flag.Bool("sish.logtoclient", false, "Whether or not to log http requests to the client")
bannedSubdomainList = []string{""}
filter *ipfilter.IPFilter
)

func main() {
flag.Parse()

_, httpPortString, err := net.SplitHostPort(*httpAddr)
if err != nil {
log.Fatalln("Error parsing address:", err)
}

_, httpsPortString, err := net.SplitHostPort(*httpsAddr)
if err != nil {
log.Fatalln("Error parsing address:", err)
}

httpPort, err = strconv.Atoi(httpPortString)
if err != nil {
log.Fatalln("Error parsing address:", err)
}

httpsPort, err = strconv.Atoi(httpsPortString)
if err != nil {
log.Fatalln("Error parsing address:", err)
}

if *versionCheck {
log.Printf("Version: %v\nCommit: %v\nDate: %v\n", version, commit, date)
log.Printf("\nVersion: %v\nCommit: %v\nDate: %v\n", version, commit, date)
os.Exit(0)
}

Expand Down Expand Up @@ -153,6 +175,11 @@ func main() {
log.Println(key, value)
return true
})
log.Println("===TCP Aliases====")
state.TCPListeners.Range(func(key, value interface{}) bool {
log.Println(key, value)
return true
})
log.Print("========End==========\n\n")

time.Sleep(2 * time.Second)
Expand Down
41 changes: 33 additions & 8 deletions requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sync"
"time"

"github.com/logrusorgru/aurora"
"github.com/pires/go-proxyproto"
"golang.org/x/crypto/ssh"
)
Expand Down Expand Up @@ -107,7 +108,7 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state
connType = "https"
}

requestMessages := fmt.Sprintf("\nStarting SSH Fowarding service for %s:%s. Forwarded connections can be accessed via the following methods:\r\n", connType, stringPort)
requestMessages := fmt.Sprintf("\nStarting SSH Fowarding service for %s. Forwarded connections can be accessed via the following methods:\r\n", aurora.Sprintf(aurora.Green("%s:%s"), connType, stringPort))

if stringPort == "80" || stringPort == "443" {
scheme := "http"
Expand All @@ -121,15 +122,28 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state
ProxyHost: host,
ProxyTo: chanListener.Addr().String(),
Scheme: scheme,
SSHConn: sshConn,
}

state.HTTPListeners.Store(host, pH)
defer state.HTTPListeners.Delete(host)

requestMessages += fmt.Sprintf("HTTP: http://%s:%d\r\n", host, *httpPort)
httpPortString := ""
if httpPort != 80 {
httpPortString = fmt.Sprintf(":%d", httpPort)
}

requestMessages += fmt.Sprintf("%s: http://%s%s\r\n", aurora.BgBlue("HTTP"), host, httpPortString)
log.Printf("%s forwarding started: http://%s%s -> %s for client: %s\n", aurora.BgBlue("HTTP"), host, httpPortString, chanListener.Addr().String(), sshConn.SSHConn.RemoteAddr().String())

if *httpsEnabled {
requestMessages += fmt.Sprintf("HTTPS: https://%s:%d", host, *httpsPort)
httpsPortString := ""
if httpsPort != 443 {
httpsPortString = fmt.Sprintf(":%d", httpsPort)
}

requestMessages += fmt.Sprintf("%s: https://%s%s", aurora.BgBlue("HTTPS"), host, httpsPortString)
log.Printf("%s forwarding started: https://%s%s -> %s for client: %s\n", aurora.BgBlue("HTTPS"), host, httpPortString, chanListener.Addr().String(), sshConn.SSHConn.RemoteAddr().String())
}
} else {
if handleTCPAliasing {
Expand All @@ -138,9 +152,11 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state
state.TCPListeners.Store(validAlias, chanListener.Addr().String())
defer state.TCPListeners.Delete(validAlias)

requestMessages += fmt.Sprintf("TCP Alias: %s", validAlias)
requestMessages += fmt.Sprintf("%s: %s", aurora.BgBlue("TCP Alias"), validAlias)
log.Printf("%s forwarding started: %s -> %s for client: %s\n", aurora.BgBlue("TCP Alias"), validAlias, chanListener.Addr().String(), sshConn.SSHConn.RemoteAddr().String())
} else {
requestMessages += fmt.Sprintf("TCP: %s:%d", *rootDomain, chanListener.Addr().(*net.TCPAddr).Port)
requestMessages += fmt.Sprintf("%s: %s:%d", aurora.BgBlue("TCP"), *rootDomain, chanListener.Addr().(*net.TCPAddr).Port)
log.Printf("%s forwarding started: %s:%d -> %s for client: %s\n", aurora.BgBlue("TCP"), *rootDomain, chanListener.Addr().(*net.TCPAddr).Port, chanListener.Addr().String(), sshConn.SSHConn.RemoteAddr().String())
}
}

Expand All @@ -159,6 +175,15 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state

defer cl.Close()

if connType == "tcp" {
logLine := fmt.Sprintf("Accepted connection from %s -> %s", cl.RemoteAddr().String(), sshConn.SSHConn.RemoteAddr().String())
log.Println(logLine)

if *logToClient {
sendMessage(sshConn, logLine)
}
}

resp := &forwardedTCPPayload{
Addr: check.Addr,
Port: check.Rport,
Expand Down Expand Up @@ -197,7 +222,7 @@ func handleRemoteForward(newRequest *ssh.Request, sshConn *SSHConnection, state
}

_, err := proxyProtoHeader.WriteTo(newChan)
if err != nil {
if err != nil && *debug {
log.Println("Error writing to channel:", err)
}
}
Expand Down Expand Up @@ -225,7 +250,7 @@ func copyBoth(writer net.Conn, reader ssh.Channel, wait bool) {
}

_, err := io.Copy(writer, reader)
if err != nil {
if err != nil && *debug {
log.Println("Error writing to reader:", err)
}
}()
Expand All @@ -237,7 +262,7 @@ func copyBoth(writer net.Conn, reader ssh.Channel, wait bool) {
}

_, err := io.Copy(reader, writer)
if err != nil {
if err != nil && *debug {
log.Println("Error writing to writer:", err)
}
if wait {
Expand Down

0 comments on commit 0a13da2

Please sign in to comment.