Skip to content

Commit

Permalink
feat(http): add remote_addr to logs
Browse files Browse the repository at this point in the history
With this change, the remote address will be logged. This enables other
software, such as fail2ban, to monitor the logs and make actions if
required.

Closes #944
  • Loading branch information
NefixEstrada committed Feb 2, 2024
1 parent 79bfa3c commit 39f94ec
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
9 changes: 5 additions & 4 deletions warpgate-protocol-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,9 @@ impl ProtocolServer for HTTPProtocolServer {
.with(cache_bust()),
)
.around(move |ep, req| async move {
let method = req.method().clone();
let url = req.original_uri().clone();
let response = ep.call(req).await?;
log_request_result(&method, &url, &response.status());

log_request_result(&req.clone(), &response.status()).await?;
Ok(response)
}),
)
Expand Down Expand Up @@ -206,7 +205,9 @@ impl ProtocolServer for HTTPProtocolServer {

async fn test_target(&self, target: Target) -> Result<(), TargetTestError> {
let TargetOptions::Http(options) = target.options else {
return Err(TargetTestError::Misconfigured("Not an HTTP target".to_owned()));
return Err(TargetTestError::Misconfigured(
"Not an HTTP target".to_owned(),
));
};
let request = poem::Request::builder().uri_str("http://host/").finish();
crate::proxy::proxy_normal_request(&request, poem::Body::empty(), &options)
Expand Down
48 changes: 29 additions & 19 deletions warpgate-protocol-http/src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use http::{Method, StatusCode, Uri};

Check warning on line 1 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

unused imports: `Method`, `Uri`

Check warning on line 1 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

unused imports: `Method`, `Uri`

Check warning on line 1 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

unused imports: `Method`, `Uri`

Check warning on line 1 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

unused imports: `Method`, `Uri`
use poem::web::Data;
use poem::web::{Data, RemoteAddr};

Check warning on line 2 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

unused import: `RemoteAddr`

Check warning on line 2 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

unused import: `RemoteAddr`

Check warning on line 2 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

unused import: `RemoteAddr`

Check warning on line 2 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

unused import: `RemoteAddr`
use poem::{FromRequest, Request};
use tracing::*;
use warpgate_core::Services;
Expand All @@ -8,22 +8,8 @@ use crate::session_handle::WarpgateServerHandleFromRequest;

pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
let handle = WarpgateServerHandleFromRequest::from_request_without_body(req).await;
let services: Data<&Services> = <_>::from_request_without_body(req).await?;
let config = services.config.lock().await;

let remote_ip = req
.remote_addr()
.as_socket_addr()
.map(|x| x.ip().to_string())
.unwrap_or("<unknown>".into());

let client_ip = match config.store.http.trust_x_forwarded_headers {
true => req
.header("x-forwarded-for")
.map(|x| x.to_string())
.unwrap_or(remote_ip),
false => remote_ip,
};
let client_ip = get_client_ip(req).await;

Ok(match handle {
Ok(ref handle) => {
Expand All @@ -40,10 +26,34 @@ pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
})
}

pub fn log_request_result(method: &Method, url: &Uri, status: &StatusCode) {
pub async fn log_request_result(req: &Request, status: &StatusCode) -> poem::Result<()> {
let method = req.method();
let url = req.original_uri();

let client_ip = get_client_ip(req).await?;

if status.is_server_error() || status.is_client_error() {

Check failure on line 35 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

mismatched types

Check failure on line 35 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

mismatched types

Check failure on line 35 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

mismatched types

Check failure on line 35 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

mismatched types
warn!(%method, %url, %status, "Request failed");
warn!(%method, %url, %status, %remote_addr, "Request failed");

Check failure on line 36 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

cannot find value `remote_addr` in this scope

Check failure on line 36 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

cannot find value `remote_addr` in this scope

Check failure on line 36 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

cannot find value `remote_addr` in this scope

Check failure on line 36 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

cannot find value `remote_addr` in this scope
} else {

Check failure on line 37 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

mismatched types

Check failure on line 37 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

mismatched types

Check failure on line 37 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

mismatched types

Check failure on line 37 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

mismatched types
info!(%method, %url, %status, "Request");
info!(%method, %url, %status, %remote_addr, "Request");

Check failure on line 38 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

cannot find value `remote_addr` in this scope

Check failure on line 38 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

cannot find value `remote_addr` in this scope

Check failure on line 38 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

cannot find value `remote_addr` in this scope

Check failure on line 38 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

cannot find value `remote_addr` in this scope
}
}

async fn get_client_ip(req: &Request) -> poem::Result<String> {
let services: Data<&Services> = <_>::from_request_without_body(&req).await?;
let config = services.config.lock().await;

let remote_ip = req
.remote_addr()
.as_socket_addr()
.map(|x| x.ip().to_string())
.unwrap_or("<unknown>".into());

match config.store.http.trust_x_forwarded_headers {
true => req

Check failure on line 53 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

mismatched types

Check failure on line 53 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

mismatched types

Check failure on line 53 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

mismatched types

Check failure on line 53 in warpgate-protocol-http/src/logging.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

mismatched types
.header("x-forwarded-for")
.map(|x| x.to_string())
.unwrap_or(remote_ip),
false => remote_ip,
}
}
3 changes: 2 additions & 1 deletion warpgate-protocol-http/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use tokio_tungstenite::{connect_async_with_config, tungstenite};
use tracing::*;
use url::Url;
use warpgate_common::{try_block, TargetHTTPOptions, TlsMode, WarpgateError};
use warpgate_core::Services;

Check warning on line 19 in warpgate-protocol-http/src/proxy.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-macos)

unused import: `warpgate_core::Services`

Check warning on line 19 in warpgate-protocol-http/src/proxy.rs

View workflow job for this annotation

GitHub Actions / Build (x86_64-linux)

unused import: `warpgate_core::Services`

Check warning on line 19 in warpgate-protocol-http/src/proxy.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-linux)

unused import: `warpgate_core::Services`

Check warning on line 19 in warpgate-protocol-http/src/proxy.rs

View workflow job for this annotation

GitHub Actions / Build (arm64-macos)

unused import: `warpgate_core::Services`
use warpgate_web::lookup_built_file;

use crate::logging::log_request_result;
Expand Down Expand Up @@ -291,7 +292,7 @@ pub async fn proxy_normal_request(
copy_client_response(&client_response, &mut response);
copy_client_body(client_response, &mut response).await?;

log_request_result(req.method(), req.original_uri(), &status);
log_request_result(req, &status).await?;

rewrite_response(&mut response, options, &uri)?;
Ok(response)
Expand Down

0 comments on commit 39f94ec

Please sign in to comment.