Skip to content
Snippets Groups Projects
Verified Commit c47128a8 authored by Frank Sauerburger's avatar Frank Sauerburger
Browse files

Add MVP

parents
No related branches found
No related tags found
No related merge requests found
FROM golang:1.21.4-alpine3.18 AS builder
RUN apk update && apk add --no-cache git
WORKDIR $GOPATH/src/sshway
COPY . .
RUN go get -d -v
RUN go build -ldflags="-w -s" -o /go/bin/sshway
FROM alpine:3.18
COPY --from=builder /go/bin/sshway /bin/sshway
CMD ["/bin/sshway"]
\ No newline at end of file
go.mod 0 → 100644
module gitlab.sauerburger.com/frank/sshway
go 1.20
require golang.org/x/crypto v0.15.0
require golang.org/x/sys v0.14.0 // indirect
main.go 0 → 100644
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
"io"
"log"
"net"
"os"
)
var user string
var knownHostKey ssh.PublicKey
var localAddr string
var remoteAddr string
var sshHost string
var signer ssh.Signer
func main() {
var keyBuffer []byte
keyBuffer = []byte(os.Getenv("SSHWAY_PRIVATE_KEY"))
if len(keyBuffer) == 0 {
log.Fatalf("SSHWAY_PRIVATE_KEY is empty")
}
// Create the Signer for this private key.
var err error
signer, err = ssh.ParsePrivateKey(keyBuffer)
if err != nil {
log.Fatalf("Unable to parse private key: %v", err)
}
user = os.Getenv("SSHWAY_USER")
if len(user) == 0 {
log.Fatalf("SSHWAY_USER is empty")
}
knownHostBuffer := []byte(os.Getenv("SSHWAY_KNOWN_HOST"))
if len(knownHostBuffer) == 0 {
log.Fatalf("SSHWAY_KNOWN_HOST is empty")
}
knownHostKey, _, _, _, err = ssh.ParseAuthorizedKey(knownHostBuffer)
if err != nil {
log.Fatalf("Unable to parse known host key %v: %v", knownHostBuffer, err)
}
localAddr = os.Getenv("SSHWAY_LOCAL")
if len(localAddr) == 0 {
log.Fatalf("SSHWAY_LOCAL is empty")
}
remoteAddr = os.Getenv("SSHWAY_REMOTE")
if len(remoteAddr) == 0 {
log.Fatalf("SSHWAY_REMOTE is empty")
}
sshHost = os.Getenv("SSHWAY_SSH_HOST")
if len(sshHost) == 0 {
log.Fatalf("SSHWAY_SSH_HOST is empty")
}
server, err := net.Listen("tcp", localAddr)
if err != nil {
log.Fatal("Error listening:", err.Error())
}
fmt.Printf("Listening on %s\n", localAddr)
defer server.Close()
for {
connection, err := server.Accept()
if err != nil {
log.Fatalf("Error accepting local client: %v\n", err)
}
fmt.Printf("client connected %s\n", connection.RemoteAddr().String())
go handleClient(connection)
}
}
func handleClient(localSock net.Conn) {
defer localSock.Close()
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.FixedHostKey(knownHostKey),
// HostKeyAlgorithms: []string{"ssh-ed25519"},
}
conn, err := ssh.Dial("tcp", sshHost, config)
if err != nil {
log.Printf("SSH connection failed: %v\n", err)
return
}
defer conn.Close()
forwardClient, err := conn.Dial("tcp", remoteAddr)
if err != nil {
log.Printf("Port forward failed: %v\n", err)
return
}
go func() {
io.Copy(localSock, forwardClient)
}()
io.Copy(forwardClient, localSock)
log.Printf("Disconnected: %v\n", localSock)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment