-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
128 lines (110 loc) · 3.56 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"crypto/tls"
"encoding/json"
"fmt"
"github.com/noneymous/PgProxy/pgproxy"
scanUtils "github.com/siemens/GoScans/utils"
"log"
"strings"
"time"
)
// Example SNI configuration with a single SNI and target database
var snis = []pgproxy.Sni{
{
CertPath: "./keys/localhost_dev.crt", // Example self-signed certificate to be presented to the client
KeyPath: "./keys/localhost_dev.key", // Example self-signed certificate to be presented to the client
Database: pgproxy.Database{
Host: "postgres.domain.tld", // The database host to proxy the client to
Port: 5432, // The database port to proxy the client to
SslMode: "prefer", // one out of pgproxy.SslModes
},
AllowedOrigins: nil, // Option to restrict access to SNI for a list of origin IPs
},
}
func main() {
// Initialize logger
logger := new(Logger)
// Print final message on exit
defer func() {
logger.Debugf("PgProxy terminated.")
}()
// Catch potential panics to log issue
defer func() {
if r := recover(); r != nil {
logger.Errorf(fmt.Sprintf("Panic: %s", r))
}
}()
// Prepare some reasonable TLS config
tlsConf := &tls.Config{
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS13,
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
CipherSuites: []uint16{
// Limit cipher suites to secure ones https://ciphersuite.info/cs/
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
},
}
// Initialize PgProxy
pgProxy, errPgProxy := pgproxy.Init(logger, 54321, tlsConf, false, true)
if errPgProxy != nil {
logger.Errorf("Could not initialize PgProxy: %s.", errPgProxy)
return
}
// Register monitoring function (optional)
pgProxy.RegisterMonitoring(func(
loggerClient scanUtils.Logger, // Internal logger from PgProxy, within the context of a client connection
dbName string,
dbUser string,
dbTables []string,
query string,
queryResults int,
queryStart time.Time,
queryEndExec time.Time,
queryEndTotal time.Time,
clientName string,
) error {
// Indent lines
logMsg := " " + strings.Join(strings.Split(query, "\n"), "\n ")
// Log query with stats
logger.Debugf("Query of user '%s' ran %s and returned %d row(s) in %s: \n%s", dbUser, queryEndExec.Sub(queryStart), queryResults, queryEndTotal.Sub(queryStart), logMsg)
// Return from monitoring function
return nil
})
// Make sure core gets shut down gracefully
defer pgProxy.Stop()
// Load certificates from paths into memory
for i, sni := range snis {
jsn, _ := json.Marshal(sni)
_ = snis[i].UnmarshalJSON(jsn)
}
// Register proxy interfaces and routes
errAdd := pgProxy.RegisterSni(snis...)
if errAdd != nil {
logger.Errorf("Could not add PgProxy SNI: %s.", errAdd)
return
}
// Listen and serve connections
logger.Debugf("PgProxy running.")
pgProxy.Serve()
}
// Logger is a wrapper around Golang's log module fulfilling interface required by PgProxy
type Logger struct {
}
func (l Logger) Debugf(format string, v ...interface{}) {
log.Printf("DEBUG\t"+format, v...)
}
func (l Logger) Infof(format string, v ...interface{}) {
log.Printf("INFO\t"+format, v...)
}
func (l Logger) Warningf(format string, v ...interface{}) {
log.Printf("WARN\t"+format, v...)
}
func (l Logger) Errorf(format string, v ...interface{}) {
log.Printf("ERROR\t"+format, v...)
}