summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2019-11-28 17:59:35 +0000
committerPeter Powell <petpow@saberuk.com>2019-11-28 17:59:35 +0000
commitbb1f892f68cb70537b224bca85cc40f1ed23017d (patch)
treec4722306888be6c4864b5b39220313affbb886d2
parent6f2d0b505f4715c696cc5d49874d442cf790b98a (diff)
Implement support for websocket connections via a proxy like nginx.
-rw-r--r--docs/conf/modules.conf.example17
-rw-r--r--src/modules/m_websocket.cpp27
2 files changed, 39 insertions, 5 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 639f02335..9cb78daee 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -2307,11 +2307,18 @@
# Requires SHA-1 hash support available in the sha1 module.
#<module name="websocket">
#
-# Whether to re-encode messages as UTF-8 before sending to WebSocket
-# clients. This is recommended as the WebSocket protocol requires all
-# text frames to be sent as UTF-8. If you do not have this enabled
-# messages will be sent as binary frames instead.
-#<websocket sendastext="yes">
+# behindproxy: Whether the server is behind a proxy that sends the
+# X-Real-IP or X-Forwarded-For headers. If enabled the
+# server will use the IP address specified by those HTTP
+# headers. You should NOT enable this unless you are using
+# a HTTP proxy like nginx as it will allow IP spoofing.
+# sendastext: Whether to re-encode messages as UTF-8 before sending to
+# WebSocket clients. This is recommended as the WebSocket
+# protocol requires all text frames to be sent as UTF-8.
+# If you do not have this enabled messages will be sent as
+# binary frames instead.
+#<websocket behindproxy="no"
+# sendastext="yes">
#
# If you use the websocket module you MUST specify one or more origins
# which are allowed to connect to the server. You should set this as
diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp
index 3437fdb1a..79cabf4e5 100644
--- a/src/modules/m_websocket.cpp
+++ b/src/modules/m_websocket.cpp
@@ -36,6 +36,9 @@ struct WebSocketConfig
// The HTTP origins that can connect to the server.
OriginList allowedorigins;
+ // Whether to trust the X-Real-IP or X-Forwarded-For headers.
+ bool behindproxy;
+
// Whether to send as UTF-8 text instead of binary data.
bool sendastext;
};
@@ -340,6 +343,29 @@ class WebSocketHook : public IOHookMiddle
return -1;
}
+ if (config.behindproxy && sock->type == StreamSocket::SS_USER)
+ {
+ LocalUser* luser = static_cast<UserIOHandler*>(sock)->user;
+ irc::sockets::sockaddrs realsa(luser->client_sa);
+
+ HTTPHeaderFinder proxyheader;
+ if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend)
+ && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa))
+ {
+ // Nothing to do here.
+ }
+ else if (proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend)
+ && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa))
+ {
+ // Nothing to do here.
+ }
+
+ // Give the user their real IP address.
+ if (realsa != luser->client_sa)
+ luser->SetClientIP(realsa);
+ }
+
+
HTTPHeaderFinder keyheader;
if (!keyheader.Find(recvq, "Sec-WebSocket-Key:", 18, reqend))
{
@@ -492,6 +518,7 @@ class ModuleWebSocket : public Module
}
ConfigTag* tag = ServerInstance->Config->ConfValue("websocket");
+ config.behindproxy = tag->getBool("behindproxy");
config.sendastext = tag->getBool("sendastext", true);
// Everything is okay; apply the new config.