initial commit

This commit is contained in:
Garionion 2023-01-19 00:18:34 +01:00
commit c37412b58c
Signed by: garionion
SSH key fingerprint: SHA256:6uQQGh4dHIdYnrR+qeLdgx5SDmbttGp2HusA73563QA
5 changed files with 158 additions and 0 deletions

41
fly.toml Normal file
View file

@ -0,0 +1,41 @@
# fly.toml file generated for fly-tls-proxy on 2023-01-18T21:56:58+01:00
app = "fly-tls-proxy"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[build]
builder = "paketobuildpacks/builder:base"
buildpacks = ["gcr.io/paketo-buildpacks/go"]
[env]
PORT = "8443"
[experimental]
auto_rollback = true
[[services]]
http_checks = []
internal_port = 8443
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = true
handlers = ["http"]
port = 80
[[services.ports]]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"

10
go.mod Normal file
View file

@ -0,0 +1,10 @@
module fly-tls-proxy
go 1.19
require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/rs/zerolog v1.28.0 // indirect
golang.org/x/sys v0.4.0 // indirect
)

18
go.sum Normal file
View file

@ -0,0 +1,18 @@
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

42
main.go Normal file
View file

@ -0,0 +1,42 @@
package main
import (
"net"
"os"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
// Create a new listener
listener, err := net.Listen("tcp", ":8443")
if err != nil {
log.Panic().Err(err).Msg("Failed to create listener")
}
// Accept connections
for {
conn, err := listener.Accept()
if err != nil {
log.Err(err).Msg("Failed to accept connection")
continue
}
go func(conn net.Conn) {
defer conn.Close()
serverName, _, err := getServerNameExtension(conn)
if err != nil {
log.Err(err).Msg("Failed to read client hello")
return
}
log.Info().Str("SNI", serverName).Msg("Accepted connection")
}(conn)
}
}

47
sni-preread.go Normal file
View file

@ -0,0 +1,47 @@
package main
import (
"bytes"
"crypto/tls"
"io"
"net"
"time"
)
func getServerNameExtension(connection net.Conn) (string, io.Reader, error) {
peekedBytes := new(bytes.Buffer)
sni, err := readServerNameExtension(io.TeeReader(connection, peekedBytes))
if err != nil {
return "", nil, err
}
return sni, io.MultiReader(peekedBytes, connection), nil
}
type readOnlyConn struct {
reader io.Reader
}
func (conn readOnlyConn) Read(p []byte) (int, error) { return conn.reader.Read(p) }
func (conn readOnlyConn) Write(p []byte) (int, error) { return 0, io.ErrClosedPipe }
func (conn readOnlyConn) Close() error { return nil }
func (conn readOnlyConn) LocalAddr() net.Addr { return nil }
func (conn readOnlyConn) RemoteAddr() net.Addr { return nil }
func (conn readOnlyConn) SetDeadline(t time.Time) error { return nil }
func (conn readOnlyConn) SetReadDeadline(t time.Time) error { return nil }
func (conn readOnlyConn) SetWriteDeadline(t time.Time) error { return nil }
func readServerNameExtension(reader io.Reader) (string, error) {
var sni string
if err := tls.Server(readOnlyConn{reader: reader}, &tls.Config{
GetConfigForClient: func(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
sni = clientHello.ServerName
return nil, nil
},
}).Handshake(); sni == "" {
return "", err
}
return sni, nil
}