logging: improve action
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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())));
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in New Issue
Block a user