Skip to content

Instantly share code, notes, and snippets.

@Romern
Created February 25, 2025 14:53
Show Gist options
  • Save Romern/bd270471571cc56d3c6d8ffcf1d71673 to your computer and use it in GitHub Desktop.
Save Romern/bd270471571cc56d3c6d8ffcf1d71673 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
"github.com/hexasant/go-hexdump"
)
const (
localAddr = "0.0.0.0:8443" // Listening address for incoming TLS
remoteAddr = "example.com:443" // Remote TLS server to forward to
bufferSize = 4096 // Buffer size
)
// TLS certificate and key (replace with valid certs in production)
const certFile = "server.crt"
const keyFile = "server.key"
// handleConnection processes each TLS client connection.
func handleConnection(clientConn net.Conn) {
defer clientConn.Close()
fmt.Println("New TLS connection accepted from:", clientConn.RemoteAddr())
// Establish outgoing TLS connection
conf := &tls.Config{InsecureSkipVerify: true} // Use real CA in production
tlsConn, err := tls.Dial("tcp", remoteAddr, conf)
if err != nil {
log.Println("Failed to connect to remote TLS server:", err)
return
}
defer tlsConn.Close()
// Function to copy, dump data, and relay it
copyAndDump := func(src net.Conn, dst net.Conn, direction string) {
buffer := make([]byte, bufferSize)
for {
n, err := src.Read(buffer)
if n > 0 {
fmt.Printf("\n%s:\n%s\n", direction, hexdump.Dump(buffer[:n]))
_, writeErr := dst.Write(buffer[:n])
if writeErr != nil {
log.Println("Write error:", writeErr)
return
}
}
if err != nil {
if err != io.EOF {
log.Println("Read error:", err)
}
return
}
}
}
// Run bidirectional copying
go copyAndDump(clientConn, tlsConn, "Client -> Server")
go copyAndDump(tlsConn, clientConn, "Server -> Client")
// Wait for either side to close
select {}
}
func main() {
// Load TLS certificate
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal("Failed to load TLS certificate:", err)
}
// Configure TLS listener
tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}}
listener, err := tls.Listen("tcp", localAddr, tlsConfig)
if err != nil {
log.Fatal("Error starting TLS listener:", err)
}
defer listener.Close()
log.Println("TLS Proxy listening on", localAddr, "-> Forwarding to", remoteAddr)
for {
conn, err := listener.Accept()
if err != nil {
log.Println("Accept error:", err)
continue
}
go handleConnection(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment