diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 9dba70a..417f3e4 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -28,6 +28,7 @@ services: - MONGO_URL=mongodb://user:user-password@db:27017/odyssey-test - DOCKER_NETWORK=linux-odyssey-players - SECRET_KEY=${SECRET_KEY} + - TRUSTED_PROXIES=${TRUSTED_PROXIES} analytics: image: lancatlin/linux-odyssey:analytics diff --git a/docker-compose.testing.yml b/docker-compose.testing.yml index 6c08595..4e70369 100644 --- a/docker-compose.testing.yml +++ b/docker-compose.testing.yml @@ -46,6 +46,7 @@ services: - MONGO_URL=mongodb://user:user-password@db-test:27017/odyssey-test - DOCKER_NETWORK=linux-odyssey-players - SECRET_KEY=b1d2e917-17b9-4fce-9055-082dee6ec5d6 # Only for testing + - TRUSTED_PROXIES=${TRUSTED_PROXIES} - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID} diff --git a/docker-compose.yml b/docker-compose.yml index 91af29e..5697961 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,7 @@ services: - MONGO_URL=mongodb://db:27017/odyssey-test - DOCKER_NETWORK=linux-odyssey-players - SECRET_KEY=b1d2e917-17b9-4fce-9055-082dee6ec5d6 # Only for testing + - TRUSTED_PROXIES=${TRUSTED_PROXIES} - HOST_PWD=${PWD} - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} diff --git a/server/package.json b/server/package.json index 6cbfd07..f65ca21 100644 --- a/server/package.json +++ b/server/package.json @@ -34,6 +34,7 @@ "passport-local": "^1.0.0", "socket.io": "^4.7.1", "swagger-ui-express": "^5.0.0", + "validator": "^13.11.0", "yaml": "^2.3.1" }, "devDependencies": { diff --git a/server/src/api/routes/index.js b/server/src/api/routes/index.js index 56f3b88..4fc5a87 100644 --- a/server/src/api/routes/index.js +++ b/server/src/api/routes/index.js @@ -5,16 +5,19 @@ import quests from './quests.js' import commands from './commands.js' import authRouter from './auth.js' import authRequired from '../../middleware/authRequired.js' +import config from '../../config.js' const router = Router() -router.get('/', (req, res) => { - res.send('Hello API!') -}) +if (!config.isProduction) { + router.get('/', (req, res) => { + res.send('Hello API!') + }) -router.get('/ip', (req, res) => { - res.json({ ip: req.ip }) -}) + router.get('/ip', (req, res) => { + res.json({ ip: req.ip, forwarded: req.headers['x-forwarded-for'] }) + }) +} router.use('/auth', authRouter) router.use('/quests', quests) diff --git a/server/src/config.js b/server/src/config.js index 889ffa8..78ae76a 100644 --- a/server/src/config.js +++ b/server/src/config.js @@ -1,5 +1,16 @@ +import validator from 'validator' import { get } from './utils/env.js' +function getTrustProxies(key) { + if (!process.env[key]) { + return [] + } + return process.env[key] + .split(',') + .map((p) => validator.trim(p)) + .filter((p) => validator.isIPRange(p) || validator.isIP(p)) +} + const config = { host: get('HOST', 'localhost'), port: get('PORT', 3000), @@ -18,6 +29,7 @@ const config = { clientID: get('GITHUB_CLIENT_ID', ''), clientSecret: get('GITHUB_CLIENT_SECRET', ''), }, + trustedProxies: getTrustProxies('TRUSTED_PROXIES'), } config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`) diff --git a/server/src/index.js b/server/src/index.js index 94d2683..52c2d88 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -42,7 +42,13 @@ async function main() { const app = express() const server = http.createServer(app) socketServer(server) - app.set('trust proxy', true) + app.set('trust proxy', [ + 'loopback', + 'linklocal', + 'uniquelocal', + ...config.trustedProxies, + ]) + console.log('Trusted proxies:', config.trustedProxies) app.use(globalRateLimit) app.use(sessionMiddleware) app.use(passport.session())