4
4
"context"
5
5
"fmt"
6
6
"log"
7
+ "log/slog"
7
8
"net"
8
9
"net/netip"
9
10
"os"
@@ -25,7 +26,7 @@ type Server struct {
25
26
SSHConfig * ssh.ServerConfig
26
27
ProxyUpstreams []netip.Prefix
27
28
Authenticator Authenticator
28
- Logger Logger
29
+ LogWriter * net. Conn
29
30
UsernamePolicy UsernamePolicyConfig
30
31
PasswordPolicy PasswordPolicyConfig
31
32
}
@@ -54,13 +55,21 @@ func makeServer(config Config) (*Server, error) {
54
55
}
55
56
proxyUpstreams = append (proxyUpstreams , network )
56
57
}
58
+ var loggerEndpoint * net.Conn = nil
59
+ if config .Logger != "" {
60
+ conn , err := net .Dial ("udp" , config .Logger )
61
+ if err != nil {
62
+ log .Fatalf ("Logger Dial failed: %s\n " , err )
63
+ }
64
+ loggerEndpoint = & conn
65
+ }
57
66
sshmux := & Server {
58
67
Address : config .Address ,
59
68
Banner : config .Banner ,
60
69
SSHConfig : sshConfig ,
61
70
ProxyUpstreams : proxyUpstreams ,
62
71
Authenticator : makeAuthenticator (config ),
63
- Logger : makeLogger ( config . Logger ) ,
72
+ LogWriter : loggerEndpoint ,
64
73
UsernamePolicy : UsernamePolicyConfig {
65
74
InvalidUsername : config .InvalidUsername ,
66
75
InvalidUsernameMessage : config .InvalidUsernameMessage ,
@@ -105,22 +114,28 @@ func (s *Server) handler(conn net.Conn) {
105
114
}
106
115
defer session .Close ()
107
116
108
- logMessage := LogMessage {
109
- ConnectTime : time .Now ().Unix (),
110
- ClientIp : conn .RemoteAddr ().String (),
111
- Username : "" , // should be provided by API server
112
- ClientType : "SSH" ,
113
- Authenticated : true ,
117
+ var logger * slog.Logger = nil
118
+ if s .LogWriter != nil {
119
+ logger = slog .New (slog .NewJSONHandler (* s .LogWriter , nil ))
114
120
}
115
- defer s .Logger .SendLog (& logMessage )
121
+ logger = logger .With (
122
+ slog .Int64 ("connect_time" , time .Now ().Unix ()),
123
+ slog .String ("remote_ip" , conn .RemoteAddr ().String ()),
124
+ slog .String ("client_type" , "SSH" ),
125
+ )
126
+ defer logger .Info ("SSH proxy session" , slog .Int64 ("disconnect_time" , time .Now ().Unix ()))
116
127
117
128
select {
118
129
case <- s .ctx .Done ():
119
130
return
120
131
default :
121
- if err := s .RunPipeSession (session , & logMessage ); err != nil {
132
+ attrs , err := s .RunPipeSession (session )
133
+ if err != nil {
122
134
log .Println ("runPipeSession:" , err )
123
135
}
136
+ for _ , attr := range attrs {
137
+ logger = logger .With (attr )
138
+ }
124
139
}
125
140
}
126
141
@@ -282,6 +297,19 @@ func (s *Server) Handshake(session *ssh.PipeSession) error {
282
297
}
283
298
}
284
299
300
+ func (s * Server ) RunPipeSession (session * ssh.PipeSession ) ([]slog.Attr , error ) {
301
+ err := s .Handshake (session )
302
+ if err != nil {
303
+ return make ([]slog.Attr , 0 ), err
304
+ }
305
+ attrs := []slog.Attr {
306
+ slog .String ("username" , session .Downstream .User ()),
307
+ slog .String ("host_ip" , session .Upstream .RemoteAddr ().String ()),
308
+ slog .Bool ("authenticated" , true ),
309
+ }
310
+ return attrs , session .RunPipe ()
311
+ }
312
+
285
313
func (s * Server ) Start () error {
286
314
// set up TCP listener
287
315
listener , err := net .Listen ("tcp" , s .Address )
@@ -333,13 +361,3 @@ func (s *Server) Shutdown() {
333
361
}
334
362
s .wg .Wait ()
335
363
}
336
-
337
- func (s * Server ) RunPipeSession (session * ssh.PipeSession , logMessage * LogMessage ) error {
338
- err := s .Handshake (session )
339
- if err != nil {
340
- return err
341
- }
342
- logMessage .Username = session .Downstream .User ()
343
- logMessage .HostIp = session .Upstream .RemoteAddr ().String ()
344
- return session .RunPipe ()
345
- }
0 commit comments