socketio: Mimic what Express does to get client IP address
This also makes it easier for plugins to get the client IP address.pull/4406/head
parent
ba6bdf35be
commit
661a89355f
|
@ -35,7 +35,6 @@ var _ = require('underscore');
|
|||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
|
||||
var channels = require("channels");
|
||||
var stats = require('../stats');
|
||||
var remoteAddress = require("../utils/RemoteAddress").remoteAddress;
|
||||
const assert = require('assert').strict;
|
||||
const nodeify = require("nodeify");
|
||||
const { RateLimiterMemory } = require('rate-limiter-flexible');
|
||||
|
@ -127,19 +126,11 @@ exports.handleDisconnect = async function(client)
|
|||
|
||||
// if this connection was already etablished with a handshake, send a disconnect message to the others
|
||||
if (session && session.author) {
|
||||
// Get the IP address from our persistant object
|
||||
let ip = remoteAddress[client.id];
|
||||
|
||||
// Anonymize the IP address if IP logging is disabled
|
||||
if (settings.disableIPlogging) {
|
||||
ip = 'ANONYMOUS';
|
||||
}
|
||||
|
||||
const {session: {user} = {}} = client.client.request;
|
||||
accessLogger.info('[LEAVE]' +
|
||||
` pad:${session.padId}` +
|
||||
` socket:${client.id}` +
|
||||
` IP:${ip}` +
|
||||
` IP:${settings.disableIPlogging ? 'ANONYMOUS' : client.request.ip}` +
|
||||
` authorID:${session.author}` +
|
||||
((user && user.username) ? ` username:${user.username}` : ''));
|
||||
|
||||
|
@ -181,11 +172,11 @@ exports.handleMessage = async function(client, message)
|
|||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
if (env === 'production') {
|
||||
const clientIPAddress = remoteAddress[client.id];
|
||||
try {
|
||||
await rateLimiter.consume(clientIPAddress); // consume 1 point per event from IP
|
||||
await rateLimiter.consume(client.request.ip); // consume 1 point per event from IP
|
||||
} catch (e) {
|
||||
console.warn("Rate limited: ", clientIPAddress, " to reduce the amount of rate limiting that happens edit the rateLimit values in settings.json");
|
||||
console.warn(`Rate limited: ${client.request.ip} to reduce the amount of rate limiting ` +
|
||||
'that happens edit the rateLimit values in settings.json');
|
||||
stats.meter('rateLimited').mark();
|
||||
client.json.send({disconnect:"rateLimited"});
|
||||
return;
|
||||
|
@ -239,7 +230,7 @@ exports.handleMessage = async function(client, message)
|
|||
'Rejecting message from client because the author ID changed mid-session.' +
|
||||
' Bad or missing token or sessionID?' +
|
||||
` socket:${client.id}` +
|
||||
` IP:${settings.disableIPlogging ? ANONYMOUS : remoteAddress[client.id]}` +
|
||||
` IP:${settings.disableIPlogging ? 'ANONYMOUS' : client.request.ip}` +
|
||||
` originalAuthorID:${thisSession.author}` +
|
||||
` newAuthorID:${authorID}` +
|
||||
((user && user.username) ? ` username:${user.username}` : '') +
|
||||
|
@ -967,19 +958,11 @@ async function handleClientReady(client, message, authorID)
|
|||
sessionInfo.readonly =
|
||||
padIds.readonly || !webaccess.userCanModify(message.padId, client.client.request);
|
||||
|
||||
// Log creation/(re-)entering of a pad
|
||||
let ip = remoteAddress[client.id];
|
||||
|
||||
// Anonymize the IP address if IP logging is disabled
|
||||
if (settings.disableIPlogging) {
|
||||
ip = 'ANONYMOUS';
|
||||
}
|
||||
|
||||
const {session: {user} = {}} = client.client.request;
|
||||
accessLogger.info(`[${pad.head > 0 ? 'ENTER' : 'CREATE'}]` +
|
||||
` pad:${padIds.padId}` +
|
||||
` socket:${client.id}` +
|
||||
` IP:${ip}` +
|
||||
` IP:${settings.disableIPlogging ? 'ANONYMOUS' : client.request.ip}` +
|
||||
` authorID:${authorID}` +
|
||||
((user && user.username) ? ` username:${user.username}` : ''));
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ var log4js = require('log4js');
|
|||
var messageLogger = log4js.getLogger("message");
|
||||
var securityManager = require("../db/SecurityManager");
|
||||
var readOnlyManager = require("../db/ReadOnlyManager");
|
||||
var remoteAddress = require("../utils/RemoteAddress").remoteAddress;
|
||||
var settings = require('../utils/Settings');
|
||||
|
||||
/**
|
||||
|
@ -56,15 +55,6 @@ exports.setSocketIO = function(_socket) {
|
|||
|
||||
socket.sockets.on('connection', function(client)
|
||||
{
|
||||
// Broken: See http://stackoverflow.com/questions/4647348/send-message-to-specific-client-with-socket-io-and-node-js
|
||||
// Fixed by having a persistant object, ideally this would actually be in the database layer
|
||||
// TODO move to database layer
|
||||
if (settings.trustProxy && client.handshake.headers['x-forwarded-for'] !== undefined) {
|
||||
remoteAddress[client.id] = client.handshake.headers['x-forwarded-for'];
|
||||
} else {
|
||||
remoteAddress[client.id] = client.handshake.address;
|
||||
}
|
||||
|
||||
// wrap the original send function to log the messages
|
||||
client._send = client.send;
|
||||
client.send = function(message) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const express = require("../express");
|
||||
const proxyaddr = require('proxy-addr');
|
||||
var settings = require('../../utils/Settings');
|
||||
var socketio = require('socket.io');
|
||||
var socketIORouter = require("../../handler/SocketIORouter");
|
||||
|
@ -38,6 +39,14 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
|
||||
io.use((socket, next) => {
|
||||
const req = socket.request;
|
||||
// Express sets req.ip but socket.io does not. Replicate Express's behavior here.
|
||||
if (req.ip == null) {
|
||||
if (settings.trustProxy) {
|
||||
req.ip = proxyaddr(req, args.app.get('trust proxy fn'));
|
||||
} else {
|
||||
req.ip = socket.handshake.address;
|
||||
}
|
||||
}
|
||||
if (!req.headers.cookie) {
|
||||
// socketio.js-client on node.js doesn't support cookies (see https://git.io/JU8u9), so the
|
||||
// token and express_sid cookies have to be passed via a query parameter for unit tests.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
exports.remoteAddress = {};
|
|
@ -55,6 +55,7 @@
|
|||
"nodeify": "1.0.1",
|
||||
"npm": "6.14.8",
|
||||
"openapi-backend": "2.4.1",
|
||||
"proxy-addr": "^2.0.6",
|
||||
"rate-limiter-flexible": "^2.1.4",
|
||||
"rehype": "^10.0.0",
|
||||
"rehype-format": "^3.0.1",
|
||||
|
|
Loading…
Reference in New Issue