mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-09 19:22:51 +00:00
feat: add rate limit allow list
This commit is contained in:
@@ -16,10 +16,11 @@
|
|||||||
import {ConfigFile} from '../src/common';
|
import {ConfigFile} from '../src/common';
|
||||||
|
|
||||||
const config: ConfigFile = {
|
const config: ConfigFile = {
|
||||||
activeVersions: ['1\\.0\\.\\d+'],
|
activeVersions: ['1\\.0\\.\\d+','2\\.0\\.\\d+'],
|
||||||
hiddenRoutes: ['/bulk'],
|
hiddenRoutes: ['/bulk'],
|
||||||
outdatedVersions: ['0\\.8\\.\\d+', '0\\.5\\.\\d+', '0\\.6\\.\\d+', '0\\.7\\.\\d+'],
|
outdatedVersions: ['0\\.8\\.\\d+', '0\\.5\\.\\d+', '0\\.6\\.\\d+', '0\\.7\\.\\d+'],
|
||||||
output: '/etc/nginx/conf.d/default.conf',
|
output: '/etc/nginx/conf.d/default.conf',
|
||||||
|
rateLimitAllowList: ['127.0.0.1/32'],
|
||||||
sslFilePaths: {
|
sslFilePaths: {
|
||||||
certificate: '/etc/nginx/certs/ssl.crt',
|
certificate: '/etc/nginx/certs/ssl.crt',
|
||||||
certificateChain: '/etc/nginx/certs/chain.crt',
|
certificateChain: '/etc/nginx/certs/chain.crt',
|
||||||
|
|||||||
@@ -3,7 +3,18 @@
|
|||||||
# create a custom request limit zone which can handle 160,000 IP-Addresses at the same time
|
# create a custom request limit zone which can handle 160,000 IP-Addresses at the same time
|
||||||
# routes using this limit zone will limit each client to not send more than one request in 50ms
|
# routes using this limit zone will limit each client to not send more than one request in 50ms
|
||||||
# be sure to use burst handling when needed, because most clients will fire some requests in parallel
|
# be sure to use burst handling when needed, because most clients will fire some requests in parallel
|
||||||
limit_req_zone $binary_remote_addr zone=customstappslimit:10m rate=20r/s;
|
|
||||||
|
geo $isRateLimited {
|
||||||
|
default 1;
|
||||||
|
{{{ rateLimitAllowList }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
map $isRateLimited $rateLimit {
|
||||||
|
0 "";
|
||||||
|
1 $binary_remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_req_zone $rateLimit zone=customstappslimit:10m rate=20r/s;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
{{{ listener }}}
|
{{{ listener }}}
|
||||||
|
|||||||
731
package-lock.json
generated
731
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
|||||||
"@types/sha1": "1.1.3",
|
"@types/sha1": "1.1.3",
|
||||||
"config": "3.3.6",
|
"config": "3.3.6",
|
||||||
"dockerode": "3.3.0",
|
"dockerode": "3.3.0",
|
||||||
|
"is-cidr": "4.0.2",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"semver": "7.3.5"
|
"semver": "7.3.5"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ export interface ConfigFile {
|
|||||||
* Output?! TODO
|
* Output?! TODO
|
||||||
*/
|
*/
|
||||||
output: string;
|
output: string;
|
||||||
|
/**
|
||||||
|
* Allow list for rate limiting
|
||||||
|
*/
|
||||||
|
rateLimitAllowList: string[];
|
||||||
/**
|
/**
|
||||||
* SSL file paths
|
* SSL file paths
|
||||||
*/
|
*/
|
||||||
@@ -89,6 +93,10 @@ export interface TemplateView {
|
|||||||
* Listener
|
* Listener
|
||||||
*/
|
*/
|
||||||
listener: string;
|
listener: string;
|
||||||
|
/**
|
||||||
|
* Allow list for rate limiting
|
||||||
|
*/
|
||||||
|
rateLimitAllowList: string;
|
||||||
/**
|
/**
|
||||||
* Static route
|
* Static route
|
||||||
*/
|
*/
|
||||||
|
|||||||
13
src/main.ts
13
src/main.ts
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import Dockerode from 'dockerode';
|
import Dockerode from 'dockerode';
|
||||||
|
import isCidr from 'is-cidr';
|
||||||
import {render} from 'mustache';
|
import {render} from 'mustache';
|
||||||
import {join} from 'path';
|
import {join} from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
@@ -187,6 +188,17 @@ async function renderTemplate(path: string, view: unknown): Promise<string> {
|
|||||||
return render(content, view);
|
return render(content, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate allow list entries in CIDR notation that pass thru rate limiting
|
||||||
|
*
|
||||||
|
* @param entries Allow list entries that should be in CIDR notation
|
||||||
|
*/
|
||||||
|
function generateRateLimitAllowList(entries: string[]): string {
|
||||||
|
return entries.filter(entry => isCidr(entry))
|
||||||
|
.map(entry => `${entry} 0;`)
|
||||||
|
.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns view for nginx config file
|
* Returns view for nginx config file
|
||||||
*
|
*
|
||||||
@@ -213,6 +225,7 @@ export async function getTemplateView(containers: Dockerode.ContainerInfo[]): Pr
|
|||||||
dockerVersionMap: await generateUpstreamMap(configFile.activeVersions, configFile.outdatedVersions, containers),
|
dockerVersionMap: await generateUpstreamMap(configFile.activeVersions, configFile.outdatedVersions, containers),
|
||||||
hiddenRoutes: (await Promise.all(hiddenRoutesPromises)).join(''),
|
hiddenRoutes: (await Promise.all(hiddenRoutesPromises)).join(''),
|
||||||
listener: generateListener(configFile.sslFilePaths),
|
listener: generateListener(configFile.sslFilePaths),
|
||||||
|
rateLimitAllowList: generateRateLimitAllowList(configFile.rateLimitAllowList),
|
||||||
staticRoute: await renderTemplate(join('fixtures', 'staticRoute.template'), {cors}),
|
staticRoute: await renderTemplate(join('fixtures', 'staticRoute.template'), {cors}),
|
||||||
visibleRoutes: (await Promise.all(visibleRoutesPromises)).join(''),
|
visibleRoutes: (await Promise.all(visibleRoutesPromises)).join(''),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user