logging: improve action

This commit is contained in:
Vaxry
2025-04-28 17:43:57 +01:00
parent fd9baeeab8
commit 467d19d8c3
7 changed files with 28 additions and 38 deletions

View File

@@ -39,7 +39,7 @@ class CConfig {
std::vector<SProxyRule> proxy_rules; std::vector<SProxyRule> proxy_rules;
struct { struct {
bool log_traffic = false; bool log_traffic = false;
std::string traffic_log_schema; std::string traffic_log_schema;
std::string traffic_log_file; std::string traffic_log_file;
} logging; } logging;

View File

@@ -49,17 +49,12 @@ CChallenge::CChallenge(const std::string& jsonResponse) {
CChallenge::CChallenge(const Pistache::Http::Request& reqResponse) { CChallenge::CChallenge(const Pistache::Http::Request& reqResponse) {
auto& q = reqResponse.query(); auto& q = reqResponse.query();
if (!q.has("solution") if (!q.has("solution") || !q.has("fingerprint") || !q.has("challenge") || !q.has("timestamp") || !q.has("sig") || !q.has("difficulty"))
|| !q.has("fingerprint")
|| !q.has("challenge")
|| !q.has("timestamp")
|| !q.has("sig")
|| !q.has("difficulty"))
return; return;
m_challenge = q.get("challenge").value(); m_challenge = q.get("challenge").value();
m_fingerprint = q.get("fingerprint").value(); m_fingerprint = q.get("fingerprint").value();
m_sig = q.get("sig").value(); m_sig = q.get("sig").value();
try { try {
m_issued = std::chrono::system_clock::time_point(std::chrono::seconds(std::stoull(q.get("timestamp").value()))); m_issued = std::chrono::system_clock::time_point(std::chrono::seconds(std::stoull(q.get("timestamp").value())));

View File

@@ -167,14 +167,14 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
Debug::log(TRACE, "Request looks like it is coming from git (UA + GP). Accepting."); Debug::log(TRACE, "Request looks like it is coming from git (UA + GP). Accepting.");
proxyPass(req, response); proxyPass(req, response);
g_pTrafficLogger->logTraffic(req, IP_ACTION_ALLOW); g_pTrafficLogger->logTraffic(req, "PASS (git)");
return; return;
} else if (userAgentHeader->agent().starts_with("git/")) { } else if (userAgentHeader->agent().starts_with("git/")) {
Debug::log(LOG, " | Action: PASS (git)"); Debug::log(LOG, " | Action: PASS (git)");
Debug::log(TRACE, "Request looks like it is coming from git (UA git). Accepting."); Debug::log(TRACE, "Request looks like it is coming from git (UA git). Accepting.");
proxyPass(req, response); proxyPass(req, response);
g_pTrafficLogger->logTraffic(req, IP_ACTION_ALLOW); g_pTrafficLogger->logTraffic(req, "PASS (git)");
return; return;
} }
} }
@@ -190,12 +190,12 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
case IP_ACTION_DENY: case IP_ACTION_DENY:
Debug::log(LOG, " | Action: DENY (rule)"); Debug::log(LOG, " | Action: DENY (rule)");
response.send(Pistache::Http::Code::Forbidden, "Blocked by checkpoint"); response.send(Pistache::Http::Code::Forbidden, "Blocked by checkpoint");
g_pTrafficLogger->logTraffic(req, IP_ACTION_DENY); g_pTrafficLogger->logTraffic(req, "DENY (rule)");
return; return;
case IP_ACTION_ALLOW: case IP_ACTION_ALLOW:
Debug::log(LOG, " | Action: PASS (rule)"); Debug::log(LOG, " | Action: PASS (rule)");
proxyPass(req, response); proxyPass(req, response);
g_pTrafficLogger->logTraffic(req, IP_ACTION_ALLOW); g_pTrafficLogger->logTraffic(req, "PASS (rule)");
return; return;
case IP_ACTION_CHALLENGE: case IP_ACTION_CHALLENGE:
Debug::log(LOG, " | Action: CHALLENGE (rule)"); Debug::log(LOG, " | Action: CHALLENGE (rule)");
@@ -218,7 +218,7 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
std::chrono::duration_cast<std::chrono::milliseconds>(TOKEN.issued().time_since_epoch()).count(); std::chrono::duration_cast<std::chrono::milliseconds>(TOKEN.issued().time_since_epoch()).count();
if (AGE <= TOKEN_MAX_AGE_MS && TOKEN.fingerprint() == NRequestUtils::fingerprintForRequest(req)) { if (AGE <= TOKEN_MAX_AGE_MS && TOKEN.fingerprint() == NRequestUtils::fingerprintForRequest(req)) {
Debug::log(LOG, " | Action: PASS (token)"); Debug::log(LOG, " | Action: PASS (token)");
g_pTrafficLogger->logTraffic(req, IP_ACTION_ALLOW); g_pTrafficLogger->logTraffic(req, "PASS (token)");
proxyPass(req, response); proxyPass(req, response);
return; return;
} else { // token has been used from a different IP or is expired. Nuke it. } else { // token has been used from a different IP or is expired. Nuke it.
@@ -239,7 +239,7 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
const auto PATH_RAW = NFsUtils::htmlPath(RESOURCE_PATH); const auto PATH_RAW = NFsUtils::htmlPath(RESOURCE_PATH);
std::error_code ec; std::error_code ec;
auto PATH_ABSOLUTE = std::filesystem::canonical(PATH_RAW, ec); auto PATH_ABSOLUTE = std::filesystem::canonical(PATH_RAW, ec);
if (ec) { if (ec) {
// bad resource, try .html // bad resource, try .html
@@ -249,12 +249,14 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
if (ec) { if (ec) {
// bad resource // bad resource
response.send(Pistache::Http::Code::Bad_Request, "Bad Request"); response.send(Pistache::Http::Code::Bad_Request, "Bad Request");
g_pTrafficLogger->logTraffic(req, "BAD_CHECKPOINT_RESOURCE");
return; return;
} }
if (!PATH_ABSOLUTE.string().starts_with(HTML_ROOT)) { if (!PATH_ABSOLUTE.string().starts_with(HTML_ROOT)) {
// directory traversal // directory traversal
response.send(Pistache::Http::Code::Bad_Request, "Bad Request"); response.send(Pistache::Http::Code::Bad_Request, "Bad Request");
g_pTrafficLogger->logTraffic(req, "BAD_CHECKPOINT_RESOURCE");
return; return;
} }
@@ -270,10 +272,11 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
auto body = NFsUtils::readFileAsString(PATH_ABSOLUTE).value_or(""); auto body = NFsUtils::readFileAsString(PATH_ABSOLUTE).value_or("");
response.send(body.empty() ? Pistache::Http::Code::Internal_Server_Error : Pistache::Http::Code::Ok, body); response.send(body.empty() ? Pistache::Http::Code::Internal_Server_Error : Pistache::Http::Code::Ok, body);
g_pTrafficLogger->logTraffic(req, "PASS (Checkpoint resource)");
return; return;
} }
g_pTrafficLogger->logTraffic(req, IP_ACTION_CHALLENGE); g_pTrafficLogger->logTraffic(req, "CHALLENGE");
serveStop(req, response, challengeDifficulty); serveStop(req, response, challengeDifficulty);
} }
@@ -294,6 +297,7 @@ void CServerHandler::challengeSubmitted(const Pistache::Http::Request& req, Pist
if (!CHALLENGE.valid()) { if (!CHALLENGE.valid()) {
response.send(Pistache::Http::Code::Bad_Request, "Bad request"); response.send(Pistache::Http::Code::Bad_Request, "Bad request");
g_pTrafficLogger->logTraffic(req, "CHALLENGE_FAIL");
return; return;
} }
@@ -322,6 +326,8 @@ void CServerHandler::challengeSubmitted(const Pistache::Http::Request& req, Pist
response.headers().add<Pistache::Http::Header::Location>("/"); response.headers().add<Pistache::Http::Header::Location>("/");
response.send(Pistache::Http::Code::Moved_Permanently, ""); response.send(Pistache::Http::Code::Moved_Permanently, "");
} }
g_pTrafficLogger->logTraffic(req, "CHALLENGE_PASS");
} }
void CServerHandler::serveStop(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, int difficulty) { void CServerHandler::serveStop(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, int difficulty) {

View File

@@ -17,13 +17,13 @@ class CServerHandler : public Pistache::Http::Handler {
void onTimeout(const Pistache::Http::Request& request, Pistache::Http::ResponseWriter response); void onTimeout(const Pistache::Http::Request& request, Pistache::Http::ResponseWriter response);
private: private:
void serveStop(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, int difficulty); void serveStop(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, int difficulty);
void proxyPass(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response); void proxyPass(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response);
void proxyPassInternal(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool async = false); void proxyPassInternal(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool async = false);
void proxyPassAsync(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response); void proxyPassAsync(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response);
void challengeSubmitted(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool js); void challengeSubmitted(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool js);
bool isResourceCheckpoint(const std::string_view& res); bool isResourceCheckpoint(const std::string_view& res);
struct SChallengeResponse { struct SChallengeResponse {
std::string challenge; std::string challenge;

View File

@@ -74,18 +74,7 @@ static std::string sanitize(const std::string& s) {
return cpy; return cpy;
} }
static const char* actionToString(eConfigIPAction a) { void CTrafficLogger::logTraffic(const Pistache::Http::Request& req, const char* actionTaken) {
switch (a) {
case IP_ACTION_CHALLENGE: return "CHALLENGE";
case IP_ACTION_ALLOW: return "ALLOW";
case IP_ACTION_DENY: return "DENY";
case IP_ACTION_NONE: return "NONE";
}
return "ERROR";
}
void CTrafficLogger::logTraffic(const Pistache::Http::Request& req, eConfigIPAction actionTaken) {
if (!g_pConfig->m_config.logging.log_traffic) if (!g_pConfig->m_config.logging.log_traffic)
return; return;
@@ -125,7 +114,7 @@ void CTrafficLogger::logTraffic(const Pistache::Http::Request& req, eConfigIPAct
} }
case TRAFFIC_ACTION: { case TRAFFIC_ACTION: {
ss << fmt::format("{},", actionToString(actionTaken)); ss << fmt::format("{},", actionTaken);
break; break;
} }
} }

View File

@@ -14,7 +14,7 @@ class CTrafficLogger {
CTrafficLogger(); CTrafficLogger();
~CTrafficLogger(); ~CTrafficLogger();
void logTraffic(const Pistache::Http::Request& req, eConfigIPAction actionTaken); void logTraffic(const Pistache::Http::Request& req, const char* actionTaken);
private: private:
enum eTrafficLoggerProps : uint8_t { enum eTrafficLoggerProps : uint8_t {
@@ -27,7 +27,7 @@ class CTrafficLogger {
}; };
std::vector<eTrafficLoggerProps> m_logSchema; std::vector<eTrafficLoggerProps> m_logSchema;
std::ofstream m_file; std::ofstream m_file;
}; };
inline std::unique_ptr<CTrafficLogger> g_pTrafficLogger; inline std::unique_ptr<CTrafficLogger> g_pTrafficLogger;