use trusted proxy list instead of cloudflare proxy header cause it works better (#23)

* use trusted proxy list

comes with cfaddresses.txt cause i know bob uses cloudflare
added support for # comments to the file cause why not

* Fix indentation 

thanks fucked github mobile editor
This commit is contained in:
Barnaby 2022-02-12 22:48:52 +00:00 committed by GitHub
parent 6dc957ad3b
commit 6d3784e26c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 51 deletions

View File

@ -22,14 +22,7 @@ module.exports = ( fastify, opts, done ) => {
},
},
async ( request, response ) => {
let clientIp = request.ip
// pull the client ip address from a custom header if one is specified
if (process.env.CLIENT_IP_HEADER && request.headers[process.env.CLIENT_IP_HEADER])
clientIp = request.headers[process.env.CLIENT_IP_HEADER]
// check if account exists
// check if account exists
let account = await accounts.AsyncGetPlayerByID( request.query.id )
if ( !account )
return null
@ -37,12 +30,12 @@ module.exports = ( fastify, opts, done ) => {
// if the client is on their own server then don't check this since their own server might not be on masterserver
if ( account.currentServerId == "self" ) {
// if the ip sending the request isn't the same as the one that last authed using client/origin_auth then don't update
if ( clientIp != account.lastAuthIp )
if ( request.ip != account.lastAuthIp )
return null
} else {
let server = GetGameServers()[ request.query.serverId ]
// dont update if the server doesnt exist, or the server isnt the one sending the heartbeat
if ( !server || clientIp != server.ip || account.currentServerId != request.query.serverId )
if ( !server || request.ip != server.ip || account.currentServerId != request.query.serverId )
return null
}

24
cfaddresses.txt Normal file
View File

@ -0,0 +1,24 @@
# ipv4
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
# ipv6
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32

View File

@ -62,13 +62,7 @@ module.exports = ( fastify, opts, done ) => {
let authToken = crypto.randomBytes( 16 ).toString( "hex" )
accounts.AsyncUpdateCurrentPlayerAuthToken( account.id, authToken )
let clientIp = request.ip
// pull the client ip address from a custom header if one is specified
if (process.env.CLIENT_IP_HEADER && request.headers[process.env.CLIENT_IP_HEADER])
clientIp = request.headers[process.env.CLIENT_IP_HEADER]
accounts.AsyncUpdatePlayerAuthIp( account.id, clientIp )
accounts.AsyncUpdatePlayerAuthIp( account.id, request.ip )
return {
success: true,

View File

@ -5,14 +5,11 @@ LISTEN_IP=0.0.0.0
LISTEN_PORT=8080
REQUIRE_SESSION_TOKEN=
# if the proxy provides a custom header to get the client's ip address
# (example: cloudflare uses CF-Connecting-IP)
CLIENT_IP_HEADER=
# not used for dev
SSL_KEY_PATH=
SSL_CERT_PATH=
TRUST_PROXY=
TRUST_PROXY_LIST_PATH=
# ratelimit
USE_RATELIMIT=1
@ -27,4 +24,4 @@ REQ_PER_MINUTE__SERVER_ADDSERVER=5
REQ_PER_MINUTE__SERVER_HEARTBEAT=60
REQ_PER_MINUTE__SERVER_UPDATEVALUES=20
REQ_PER_MINUTE__SERVER_REMOVESERVER=5
REQ_PER_MINUTE__ACCOUNT_WRITEPERSISTENCE=50
REQ_PER_MINUTE__ACCOUNT_WRITEPERSISTENCE=50

View File

@ -7,6 +7,12 @@ else
const fs = require( "fs" )
const path = require( "path" )
let trustProxy = !!(process.env.TRUST_PROXY)
if(trustProxy && process.env.TRUST_PROXY_LIST_PATH) {
let addressList = fs.readFileSync( process.env.TRUST_PROXY_LIST_PATH ).toString();
trustProxy = addressList.split("\r\n").map(a => a.trim()).filter(a => !a.startsWith("#") && a != '')
}
let fastify = require( "fastify" )
if ( process.env.USE_HTTPS )
{
@ -16,14 +22,14 @@ if ( process.env.USE_HTTPS )
key: fs.readFileSync( process.env.SSL_KEY_PATH ),
cert: fs.readFileSync( process.env.SSL_CERT_PATH )
},
trustProxy: !!(process.env.TRUST_PROXY)
trustProxy
})
}
else
{
fastify = fastify({
logger: process.env.USE_FASTIFY_LOGGER || false,
trustProxy: !!(process.env.TRUST_PROXY)
trustProxy
})
}

View File

@ -14,13 +14,6 @@ async function SharedTryAddServer( request )
{
// check server's verify endpoint on their auth server, make sure it's fine
// in the future we could probably check the server's connect port too, with a c2s_connect packet or smth, but atm this is good enough
let clientIp = request.ip
// pull the client ip address from a custom header if one is specified
if (process.env.CLIENT_IP_HEADER && request.headers[process.env.CLIENT_IP_HEADER])
clientIp = request.headers[process.env.CLIENT_IP_HEADER]
let hasValidModInfo = true
let modInfo
@ -36,7 +29,7 @@ async function SharedTryAddServer( request )
let authServerResponse = await asyncHttp.request( {
method: "GET",
host: clientIp,
host: request.ip,
port: request.query.authPort,
path: "/verify"
})
@ -80,7 +73,7 @@ async function SharedTryAddServer( request )
let name = filter.clean( request.query.name )
let description = request.query.description == "" ? "" : filter.clean( request.query.description )
let newServer = new GameServer( name, description, playerCount, request.query.maxPlayers, request.query.map, request.query.playlist, clientIp, request.query.port, request.query.authPort, request.query.password, modInfo )
let newServer = new GameServer( name, description, playerCount, request.query.maxPlayers, request.query.map, request.query.playlist, request.ip, request.query.port, request.query.authPort, request.query.password, modInfo )
AddGameServer( newServer )
return {
@ -130,16 +123,9 @@ module.exports = ( fastify, opts, done ) => {
}
},
async ( request, reply ) => {
let clientIp = request.ip
// pull the client ip address from a custom header if one is specified
if (process.env.CLIENT_IP_HEADER && request.headers[process.env.CLIENT_IP_HEADER])
clientIp = request.headers[process.env.CLIENT_IP_HEADER]
let server = GetGameServers()[ request.query.id ]
// dont update if the server doesnt exist, or the server isnt the one sending the heartbeat
if ( !server || clientIp != server.ip || !request.query.id )// remove !request.playerCount as if playercount==0 it will trigger skip heartbeat update
if ( !server || request.ip != server.ip || !request.query.id )// remove !request.playerCount as if playercount==0 it will trigger skip heartbeat update
{
return null
}
@ -156,16 +142,10 @@ module.exports = ( fastify, opts, done ) => {
// updates values shown on the server list, such as map, playlist, or player count
// no schema for this one, since it's fully dynamic and fastify doesnt do optional params
fastify.post( '/server/update_values',
{
{
config: { rateLimit: getRatelimit("REQ_PER_MINUTE__SERVER_UPDATEVALUES") }, // ratelimit
},
},
async ( request, reply ) => {
let clientIp = request.ip
// pull the client ip address from a custom header if one is specified
if (process.env.CLIENT_IP_HEADER && request.headers[process.env.CLIENT_IP_HEADER])
clientIp = request.headers[process.env.CLIENT_IP_HEADER]
if ( !( "id" in request.query ) )
return null
@ -176,7 +156,7 @@ module.exports = ( fastify, opts, done ) => {
{
return SharedTryAddServer( request )
}
else if ( clientIp != server.ip ) // dont update if the server isnt the one sending the heartbeat
else if ( request.ip != server.ip ) // dont update if the server isnt the one sending the heartbeat
return null
// update heartbeat
@ -214,7 +194,7 @@ module.exports = ( fastify, opts, done ) => {
async ( request, reply ) => {
let server = GetGameServers()[ request.query.id ]
// dont remove if the server doesnt exist, or the server isnt the one sending the heartbeat
if ( !server || clientIp != server.ip )
if ( !server || request.ip != server.ip )
return null
RemoveGameServer( server )