|
@@ -88,13 +88,6 @@ func (nl *NetListener) Stop() error {
|
88
|
88
|
return nl.listener.Close()
|
89
|
89
|
}
|
90
|
90
|
|
91
|
|
-// ensure that any IP we got from the PROXY line is trustworthy (otherwise, clear it)
|
92
|
|
-func validateProxiedIP(conn *utils.WrappedConn, config *Config) {
|
93
|
|
- if !utils.IPInNets(utils.AddrToIP(conn.RemoteAddr()), config.Server.proxyAllowedFromNets) {
|
94
|
|
- conn.ProxiedIP = nil
|
95
|
|
- }
|
96
|
|
-}
|
97
|
|
-
|
98
|
91
|
func (nl *NetListener) serve() {
|
99
|
92
|
for {
|
100
|
93
|
conn, err := nl.listener.Accept()
|
|
@@ -103,9 +96,7 @@ func (nl *NetListener) serve() {
|
103
|
96
|
// hand off the connection
|
104
|
97
|
wConn, ok := conn.(*utils.WrappedConn)
|
105
|
98
|
if ok {
|
106
|
|
- if wConn.ProxiedIP != nil {
|
107
|
|
- validateProxiedIP(wConn, nl.server.Config())
|
108
|
|
- }
|
|
99
|
+ confirmProxyData(wConn, "", "", "", nl.server.Config())
|
109
|
100
|
go nl.server.RunClient(NewIRCStreamConn(wConn))
|
110
|
101
|
} else {
|
111
|
102
|
nl.server.logger.Error("internal", "invalid connection type", nl.addr)
|
|
@@ -159,8 +150,9 @@ func (wl *WSListener) Stop() error {
|
159
|
150
|
|
160
|
151
|
func (wl *WSListener) handle(w http.ResponseWriter, r *http.Request) {
|
161
|
152
|
config := wl.server.Config()
|
162
|
|
- proxyAllowedFrom := config.Server.proxyAllowedFromNets
|
163
|
|
- proxiedIP := utils.HandleXForwardedFor(r.RemoteAddr, r.Header.Get("X-Forwarded-For"), proxyAllowedFrom)
|
|
153
|
+ remoteAddr := r.RemoteAddr
|
|
154
|
+ xff := r.Header.Get("X-Forwarded-For")
|
|
155
|
+ xfp := r.Header.Get("X-Forwarded-Proto")
|
164
|
156
|
|
165
|
157
|
wsUpgrader := websocket.Upgrader{
|
166
|
158
|
CheckOrigin: func(r *http.Request) bool {
|
|
@@ -192,18 +184,39 @@ func (wl *WSListener) handle(w http.ResponseWriter, r *http.Request) {
|
192
|
184
|
conn.Close()
|
193
|
185
|
return
|
194
|
186
|
}
|
195
|
|
- if wConn.ProxiedIP != nil {
|
196
|
|
- validateProxiedIP(wConn, config)
|
197
|
|
- } else {
|
198
|
|
- // if there was no PROXY protocol IP, use the validated X-Forwarded-For IP instead,
|
199
|
|
- // unless it is redundant
|
200
|
|
- if proxiedIP != nil && !proxiedIP.Equal(utils.AddrToIP(wConn.RemoteAddr())) {
|
201
|
|
- wConn.ProxiedIP = proxiedIP
|
202
|
|
- }
|
203
|
|
- }
|
|
187
|
+
|
|
188
|
+ confirmProxyData(wConn, remoteAddr, xff, xfp, config)
|
204
|
189
|
|
205
|
190
|
// avoid a DoS attack from buffering excessively large messages:
|
206
|
191
|
conn.SetReadLimit(maxReadQBytes)
|
207
|
192
|
|
208
|
193
|
go wl.server.RunClient(NewIRCWSConn(conn))
|
209
|
194
|
}
|
|
195
|
+
|
|
196
|
+// validate conn.ProxiedIP and conn.Secure against config, HTTP headers, etc.
|
|
197
|
+func confirmProxyData(conn *utils.WrappedConn, remoteAddr, xForwardedFor, xForwardedProto string, config *Config) {
|
|
198
|
+ if conn.ProxiedIP != nil {
|
|
199
|
+ if !utils.IPInNets(utils.AddrToIP(conn.RemoteAddr()), config.Server.proxyAllowedFromNets) {
|
|
200
|
+ conn.ProxiedIP = nil
|
|
201
|
+ }
|
|
202
|
+ } else if xForwardedFor != "" {
|
|
203
|
+ proxiedIP := utils.HandleXForwardedFor(remoteAddr, xForwardedFor, config.Server.proxyAllowedFromNets)
|
|
204
|
+ // don't set proxied IP if it is redundant with the actual IP
|
|
205
|
+ if proxiedIP != nil && !proxiedIP.Equal(utils.AddrToIP(conn.RemoteAddr())) {
|
|
206
|
+ conn.ProxiedIP = proxiedIP
|
|
207
|
+ }
|
|
208
|
+ }
|
|
209
|
+
|
|
210
|
+ if conn.Config.TLSConfig != nil || conn.Config.Tor {
|
|
211
|
+ // we terminated our own encryption:
|
|
212
|
+ conn.Secure = true
|
|
213
|
+ } else if !conn.Config.WebSocket {
|
|
214
|
+ // plaintext normal connection: loopback and secureNets are secure
|
|
215
|
+ realIP := utils.AddrToIP(conn.RemoteAddr())
|
|
216
|
+ conn.Secure = realIP.IsLoopback() || utils.IPInNets(realIP, config.Server.secureNets)
|
|
217
|
+ } else {
|
|
218
|
+ // plaintext websocket: trust X-Forwarded-Proto from a trusted source
|
|
219
|
+ conn.Secure = utils.IPInNets(utils.AddrToIP(conn.RemoteAddr()), config.Server.proxyAllowedFromNets) &&
|
|
220
|
+ xForwardedProto == "https"
|
|
221
|
+ }
|
|
222
|
+}
|