Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 787e648

Browse files
committed
Add proxy IP to audit log
1 parent 677510a commit 787e648

28 files changed

Lines changed: 117 additions & 72 deletions

auditlog/message/connect.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package message
22

33
// PayloadConnect is the payload for TypeConnect messages.
44
type PayloadConnect struct {
5-
RemoteAddr string `json:"remoteAddr" yaml:"remoteAddr"` // RemoteAddr contains the IP address of the connecting user.
6-
Country string `json:"country" yaml:"country"` // Country contains the country code looked up from the IP address. Contains "XX" if the lookup failed.
5+
RemoteAddr string `json:"remoteAddr" yaml:"remoteAddr"` // RemoteAddr contains the IP address of the connecting user.
6+
ProxyAddr string `json:"proxyAddr,omitempty" yaml:"proxyAddr"` // ProxyAddr contains the IP adress of the proxy used (if behind a load balancer)
7+
Country string `json:"country" yaml:"country"` // Country contains the country code looked up from the IP address. Contains "XX" if the lookup failed.
78
}
89

910
// Equals compares two PayloadConnect datasets.

internal/auditlog/codec/asciinema/encoder.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func (e *encoder) Encode(messages <-chan message.Message, storage storage.Writer
6262
startTime := int64(0)
6363
headerWritten := false
6464
var ip = ""
65+
var proxy *string
6566
var username *string
6667
const shell = "/bin/sh"
6768
for {
@@ -70,11 +71,12 @@ func (e *encoder) Encode(messages <-chan message.Message, storage storage.Writer
7071
break
7172
}
7273
var err error
73-
startTime, headerWritten, ip, username, err = e.encodeMessage(
74+
startTime, headerWritten, ip, proxy, username, err = e.encodeMessage(
7475
startTime,
7576
msg,
7677
&asciicastHeader,
7778
ip,
79+
proxy,
7880
storage,
7981
username,
8082
headerWritten,
@@ -106,11 +108,12 @@ func (e *encoder) encodeMessage(
106108
msg message.Message,
107109
asciicastHeader *Header,
108110
ip string,
111+
proxy *string,
109112
storage storage.Writer,
110113
username *string,
111114
headerWritten bool,
112115
shell string,
113-
) (int64, bool, string, *string, error) {
116+
) (int64, bool, string, *string, *string, error) {
114117
if msg.MessageType == message.TypeConnect {
115118
startTime = msg.Timestamp
116119
asciicastHeader.Timestamp = int(startTime / 1000000000)
@@ -121,11 +124,11 @@ func (e *encoder) encodeMessage(
121124
case message.TypeConnect:
122125
ip, username = e.handleConnect(storage, msg, startTime, country, username)
123126
case message.TypeAuthPasswordSuccessful:
124-
ip, username = e.handleAuthPasswordSuccessful(storage, msg, startTime, ip, country)
127+
ip, username = e.handleAuthPasswordSuccessful(storage, msg, startTime, ip, proxy, country)
125128
case message.TypeAuthPubKeySuccessful:
126-
ip, username = e.handleAuthPubkeySuccessful(storage, msg, startTime, ip, country)
129+
ip, username = e.handleAuthPubkeySuccessful(storage, msg, startTime, ip, proxy, country)
127130
case message.TypeHandshakeSuccessful:
128-
ip, username = e.handleHandshakeSuccessful(storage, msg, startTime, ip, country)
131+
ip, username = e.handleHandshakeSuccessful(storage, msg, startTime, ip, proxy, country)
129132
case message.TypeChannelRequestSetEnv:
130133
payload := msg.Payload.(message.PayloadChannelRequestSetEnv)
131134
asciicastHeader.Env[payload.Name] = payload.Value
@@ -142,36 +145,40 @@ func (e *encoder) encodeMessage(
142145
startTime, headerWritten, err = e.handleIO(startTime, msg, asciicastHeader, headerWritten, shell, storage)
143146
}
144147
if err != nil {
145-
return startTime, headerWritten, ip, username, err
148+
return startTime, headerWritten, ip, proxy, username, err
146149
}
147-
return startTime, headerWritten, ip, username, nil
150+
return startTime, headerWritten, ip, proxy, username, nil
148151
}
149152

150153
func (e *encoder) handleConnect(storage storage.Writer, msg message.Message, startTime int64, country string, username *string) (string, *string) {
151154
payload := msg.Payload.(message.PayloadConnect)
152155
ip := payload.RemoteAddr
153-
storage.SetMetadata(startTime/1000000000, ip, country, username)
156+
var proxy *string
157+
if payload.ProxyAddr != "" {
158+
proxy = &payload.ProxyAddr
159+
}
160+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
154161
return ip, username
155162
}
156163

157-
func (e *encoder) handleAuthPasswordSuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, country string) (string, *string) {
164+
func (e *encoder) handleAuthPasswordSuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, proxy *string, country string) (string, *string) {
158165
payload := msg.Payload.(message.PayloadAuthPassword)
159166
username := &payload.Username
160-
storage.SetMetadata(startTime/1000000000, ip, country, username)
167+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
161168
return ip, username
162169
}
163170

164-
func (e *encoder) handleAuthPubkeySuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, country string) (string, *string) {
171+
func (e *encoder) handleAuthPubkeySuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, proxy *string, country string) (string, *string) {
165172
payload := msg.Payload.(message.PayloadAuthPubKey)
166173
username := &payload.Username
167-
storage.SetMetadata(startTime/1000000000, ip, country, username)
174+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
168175
return ip, username
169176
}
170177

171-
func (e *encoder) handleHandshakeSuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, country string) (string, *string) {
178+
func (e *encoder) handleHandshakeSuccessful(storage storage.Writer, msg message.Message, startTime int64, ip string, proxy *string, country string) (string, *string) {
172179
payload := msg.Payload.(message.PayloadHandshakeSuccessful)
173180
username := &payload.Username
174-
storage.SetMetadata(startTime/1000000000, ip, country, username)
181+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
175182
return ip, username
176183
}
177184

internal/auditlog/codec/asciinema/encoder_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type writer struct {
1919
data bytes.Buffer
2020
startTime int64
2121
sourceIP string
22+
proxyIP *string
2223
username *string
2324
wait chan bool
2425
country string
@@ -43,9 +44,10 @@ func (w *writer) waitForClose() {
4344
<-w.wait
4445
}
4546

46-
func (w *writer) SetMetadata(startTime int64, sourceIP string, country string, username *string) {
47+
func (w *writer) SetMetadata(startTime int64, sourceIP string, proxyIP *string, country string, username *string) {
4748
w.startTime = startTime
4849
w.sourceIP = sourceIP
50+
w.proxyIP = proxyIP
4951
w.username = username
5052
w.country = country
5153
}

internal/auditlog/codec/binary/encode.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func (e *encoder) Encode(messages <-chan message.Message, storage storage.Writer
4848

4949
startTime := int64(0)
5050
var ip = ""
51+
var proxy *string
5152
var country = "XX"
5253
var username *string
5354
for {
@@ -58,7 +59,7 @@ func (e *encoder) Encode(messages <-chan message.Message, storage storage.Writer
5859
if startTime == 0 {
5960
startTime = msg.Timestamp
6061
}
61-
ip, country, username = e.storeMetadata(msg, storage, startTime, ip, country, username)
62+
ip, proxy, country, username = e.storeMetadata(msg, storage, startTime, ip, proxy, country, username)
6263
if err := encoder.Encode(&msg); err != nil {
6364
return fmt.Errorf("failed to encode audit log message (%w)", err)
6465
}
@@ -83,28 +84,32 @@ func (e *encoder) storeMetadata(
8384
storage storage.Writer,
8485
startTime int64,
8586
ip string,
87+
proxy *string,
8688
country string,
8789
username *string,
88-
) (string, string, *string) {
90+
) (string, *string, string, *string) {
8991
switch msg.MessageType {
9092
case message.TypeConnect:
91-
remoteAddr := msg.Payload.(message.PayloadConnect).RemoteAddr
92-
ip = remoteAddr
93+
payload := msg.Payload.(message.PayloadConnect)
94+
ip = payload.RemoteAddr
95+
if payload.ProxyAddr != "" {
96+
proxy = &payload.ProxyAddr
97+
}
9398
country := e.geoIPProvider.Lookup(net.ParseIP(ip))
94-
storage.SetMetadata(startTime/1000000000, ip, country, username)
99+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
95100
case message.TypeAuthPasswordSuccessful:
96101
u := msg.Payload.(message.PayloadAuthPassword).Username
97102
username = &u
98-
storage.SetMetadata(startTime/1000000000, ip, country, username)
103+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
99104
case message.TypeAuthPubKeySuccessful:
100105
payload := msg.Payload.(message.PayloadAuthPubKey)
101106
username = &payload.Username
102-
storage.SetMetadata(startTime/1000000000, ip, country, username)
107+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
103108
case message.TypeHandshakeSuccessful:
104109
payload := msg.Payload.(message.PayloadHandshakeSuccessful)
105110
username = &payload.Username
106-
storage.SetMetadata(startTime/1000000000, ip, country, username)
111+
storage.SetMetadata(startTime/1000000000, ip, proxy, country, username)
107112
}
108113

109-
return ip, country, username
114+
return ip, proxy, country, username
110115
}

internal/auditlog/codec/proxy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ func (s *storageWriterProxy) Close() error {
2323
return s.backend.Close()
2424
}
2525

26-
func (s *storageWriterProxy) SetMetadata(_ int64, _ string, _ string, _ *string) {
26+
func (s *storageWriterProxy) SetMetadata(_ int64, _ string, _ *string, _ string, _ *string) {
2727
// No metadata storage
2828
}

internal/auditlog/logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
type Logger interface {
1313
// OnConnect creates an audit log message for a new connection and simultaneously returns a connection object for
1414
// connection-specific messages
15-
OnConnect(connectionID message.ConnectionID, ip net.TCPAddr) (Connection, error)
15+
OnConnect(connectionID message.ConnectionID, ip net.TCPAddr, proxy *net.TCPAddr) (Connection, error)
1616
// Shutdown triggers all failing uploads to cancel, waits for all currently running uploads to finish, then returns.
1717
// When the shutdownContext expires it will do its best to immediately upload any running background processes.
1818
Shutdown(shutdownContext context.Context)

internal/auditlog/logger_empty.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (e *empty) OnNewChannelSuccess(_ message.ChannelID, _ string) Channel {
9595
return e
9696
}
9797

98-
func (e *empty) OnConnect(_ message.ConnectionID, _ net.TCPAddr) (Connection, error) {
98+
func (e *empty) OnConnect(_ message.ConnectionID, _ net.TCPAddr, _ *net.TCPAddr) (Connection, error) {
9999
return e, nil
100100
}
101101

internal/auditlog/logger_impl.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (l *loggerImplementation) Shutdown(shutdownContext context.Context) {
5555

5656
//region Connection
5757

58-
func (l *loggerImplementation) OnConnect(connectionID message.ConnectionID, ip net.TCPAddr) (Connection, error) {
58+
func (l *loggerImplementation) OnConnect(connectionID message.ConnectionID, ip net.TCPAddr, proxy *net.TCPAddr) (Connection, error) {
5959
name := string(connectionID)
6060
writer, err := l.storage.OpenWriter(name)
6161
if err != nil {
@@ -76,12 +76,17 @@ func (l *loggerImplementation) OnConnect(connectionID message.ConnectionID, ip n
7676
l.logger.Emergency(err)
7777
}
7878
}()
79+
proxyAddr := ""
80+
if proxy != nil {
81+
proxyAddr = proxy.IP.String()
82+
}
7983
conn.log(message.Message{
8084
ConnectionID: connectionID,
8185
Timestamp: time.Now().UnixNano(),
8286
MessageType: message.TypeConnect,
8387
Payload: message.PayloadConnect{
8488
RemoteAddr: ip.IP.String(),
89+
ProxyAddr: proxyAddr,
8590
Country: l.geoIPLookup.Lookup(ip.IP),
8691
},
8792
ChannelID: nil,

internal/auditlog/logger_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ func TestConnect(t *testing.T) {
203203
Port: 2222,
204204
Zone: "",
205205
},
206+
nil,
206207
)
207208
if err != nil {
208209
assert.Fail(t, "failed to send connect message to logger", err)
@@ -246,6 +247,7 @@ func TestAuth(t *testing.T) {
246247
Port: 2222,
247248
Zone: "",
248249
},
250+
nil,
249251
)
250252
assert.Nil(t, err)
251253
connection.OnAuthPassword("foo", []byte("bar"))

internal/auditlog/storage/file/struct.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ func (w *writer) Close() error {
7474
return w.file.Close()
7575
}
7676

77-
func (w *writer) SetMetadata(_ int64, _ string, _ string, _ *string) {
77+
func (w *writer) SetMetadata(_ int64, _ string, _ *string, _ string, _ *string) {
7878
}

0 commit comments

Comments
 (0)