rules: add support for resource excludes

This commit is contained in:
Vaxry
2025-04-15 14:49:29 +01:00
parent 15689ca20a
commit 50fbc7f5ac
7 changed files with 36 additions and 7 deletions

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[submodule "subprojects/glaze"] [submodule "subprojects/glaze"]
path = subprojects/glaze path = subprojects/glaze
url = https://github.com/stephenberry/glaze url = https://github.com/stephenberry/glaze
[submodule "subprojects/re2"]
path = subprojects/re2
url = https://github.com/google/re2

View File

@@ -35,6 +35,7 @@ target_include_directories(checkpoint
PRIVATE PRIVATE
"./subprojects/pistache/include" "./subprojects/pistache/include"
"./subprojects/glaze/include" "./subprojects/glaze/include"
"./subprojects/re2/include"
"./subprojects/tinylates/include" "./subprojects/tinylates/include"
"./subprojects/pistache/subprojects/cpp-httplib" "./subprojects/pistache/subprojects/cpp-httplib"
"./subprojects/pistache/subprojects/hinnant-date/include" "./subprojects/pistache/subprojects/hinnant-date/include"
@@ -43,5 +44,6 @@ target_link_libraries(checkpoint
PkgConfig::deps PkgConfig::deps
pistache pistache
fmt fmt
re2
tinylates tinylates
) )

View File

@@ -33,7 +33,9 @@
"ip_ranges": [ "ip_ranges": [
"127.0.0.1/24", "127.0.0.1/24",
"::1/128" "::1/128"
] ],
// if this regex matches the resource requested, this rule will not be applied
"exclude_regex": ".*/commit/.*"
} }
] ]
} }

View File

@@ -5,6 +5,8 @@
#include "../helpers/FsUtils.hpp" #include "../helpers/FsUtils.hpp"
#include "../GlobalState.hpp" #include "../GlobalState.hpp"
#include "../debug/log.hpp"
static CConfig::eConfigIPAction strToAction(const std::string& s) { static CConfig::eConfigIPAction strToAction(const std::string& s) {
// TODO: allow any case I'm lazy it's 1am // TODO: allow any case I'm lazy it's 1am
if (s == "ALLOW" || s == "allow" || s == "Allow") if (s == "ALLOW" || s == "allow" || s == "Allow")
@@ -32,6 +34,14 @@ CConfig::CConfig() {
parsed.action = strToAction(ic.action); parsed.action = strToAction(ic.action);
parsed.difficulty = ic.difficulty; parsed.difficulty = ic.difficulty;
if (!ic.exclude_regex.empty()) {
parsed.exclude_regex = std::make_unique<re2::RE2>(ic.exclude_regex);
if (parsed.exclude_regex->error_code() != RE2::NoError) {
Debug::log(CRIT, "Regex \"{}\" failed to parse", ic.exclude_regex);
throw std::runtime_error("Failed to parse regex");
}
}
for (const auto& ir : ic.ip_ranges) { for (const auto& ir : ic.ip_ranges) {
parsed.ip_ranges.emplace_back(CIPRange(ir)); parsed.ip_ranges.emplace_back(CIPRange(ir));
} }

View File

@@ -3,6 +3,8 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <re2/re2.h>
#include "IPRange.hpp" #include "IPRange.hpp"
class CConfig { class CConfig {
@@ -18,13 +20,15 @@ class CConfig {
struct SIPRangeConfig { struct SIPRangeConfig {
std::string action = ""; std::string action = "";
std::vector<std::string> ip_ranges; std::vector<std::string> ip_ranges;
int difficulty = -1; int difficulty = -1;
std::string exclude_regex = "";
}; };
struct SIPRangeConfigParsed { struct SIPRangeConfigParsed {
eConfigIPAction action = IP_ACTION_DENY; eConfigIPAction action = IP_ACTION_DENY;
std::vector<CIPRange> ip_ranges; std::vector<CIPRange> ip_ranges;
int difficulty = -1; int difficulty = -1;
std::unique_ptr<re2::RE2> exclude_regex;
}; };
struct SConfig { struct SConfig {

View File

@@ -243,6 +243,15 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
} }
if (matched) { if (matched) {
if (ic.difficulty != -1)
challengeDifficulty = ic.difficulty;
// if we have an exclude regex and it matches the resource, skip this rule
if (ic.exclude_regex && RE2::FullMatch(req.resource(), *ic.exclude_regex)) {
Debug::log(LOG, " | ip rule matched for {}, but resource is excluded.", REQUEST_IP);
continue;
}
if (ic.action == CConfig::IP_ACTION_ALLOW) { if (ic.action == CConfig::IP_ACTION_ALLOW) {
Debug::log(LOG, " | Action: PASS (ip rule matched for {})", REQUEST_IP); Debug::log(LOG, " | Action: PASS (ip rule matched for {})", REQUEST_IP);
proxyPass(req, response); proxyPass(req, response);
@@ -254,8 +263,6 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
} }
// if it's challenge then it's default so just set the difficulty if applicable and proceed // if it's challenge then it's default so just set the difficulty if applicable and proceed
if (ic.difficulty != -1)
challengeDifficulty = ic.difficulty;
break; break;
} }
} }

1
subprojects/re2 Submodule

Submodule subprojects/re2 added at c84a140c93