-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50 from PocketRelay/49-task-reverse-proxy-ip-forw…
…arding-support Fixed reverse proxy IP forwading
- Loading branch information
Showing
13 changed files
with
139 additions
and
32 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"port": 80, | ||
"reverse_proxy": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
version: "3" | ||
services: | ||
server: | ||
restart: unless-stopped | ||
container_name: pocket-relay | ||
image: jacobtread/pocket-relay:latest | ||
volumes: | ||
# Bind the server config to a local config.json file | ||
- ./config.json:/app/config.json | ||
# Binding the server data to a local data folder | ||
- ./data:/app/data | ||
nginx: | ||
restart: unless-stopped | ||
image: nginx | ||
ports: | ||
- "80:80/tcp" | ||
volumes: | ||
- ./nginx.conf:/etc/nginx/nginx.conf:ro | ||
depends_on: | ||
- server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
events {} | ||
|
||
http { | ||
server { | ||
listen 80; | ||
|
||
server_name localhost; | ||
|
||
location / { | ||
proxy_pass http://server:80; | ||
|
||
# Provide server with real IP address of clients | ||
proxy_set_header X-Real-IP $remote_addr; | ||
|
||
# Upgrade websocket connections | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection "upgrade"; | ||
proxy_http_version 1.1; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::net::SocketAddr; | ||
|
||
use axum::{ | ||
async_trait, | ||
body::boxed, | ||
extract::{rejection::ExtensionRejection, ConnectInfo, FromRequestParts}, | ||
http::request::Parts, | ||
response::{IntoResponse, Response}, | ||
Extension, | ||
}; | ||
use hyper::{HeaderMap, StatusCode}; | ||
use log::warn; | ||
use thiserror::Error; | ||
|
||
use crate::state::App; | ||
|
||
/// Middleware for extracting the server public address | ||
pub struct IpAddress(pub SocketAddr); | ||
|
||
const REAL_IP_HEADER: &str = "X-Real-IP"; | ||
|
||
#[async_trait] | ||
impl<S> FromRequestParts<S> for IpAddress | ||
where | ||
S: Send + Sync, | ||
{ | ||
type Rejection = IpAddressError; | ||
|
||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { | ||
let reverse_proxy = App::config().reverse_proxy; | ||
if reverse_proxy { | ||
let ip = match extract_ip_header(&parts.headers) { | ||
Some(ip) => ip, | ||
None => { | ||
warn!("Failed to extract X-Real-IP header from connecting client. If you are NOT using a reverse proxy\n\ | ||
disable the `reverse_proxy` config property, otherwise check that your reverse proxy is configured\n\ | ||
correctly according the guide. (Closing connection with error)"); | ||
return Err(IpAddressError::InvalidOrMissing); | ||
} | ||
}; | ||
return Ok(Self(ip)); | ||
} | ||
let value = Extension::<ConnectInfo<SocketAddr>>::from_request_parts(parts, state).await?; | ||
Ok(Self(value.0 .0)) | ||
} | ||
} | ||
|
||
fn extract_ip_header(headers: &HeaderMap) -> Option<SocketAddr> { | ||
let header = headers.get(REAL_IP_HEADER)?; | ||
let value = header.to_str().ok()?; | ||
value.parse().ok() | ||
} | ||
|
||
/// Error type used by the token checking middleware to handle | ||
/// different errors and create error respones based on them | ||
#[derive(Debug, Error)] | ||
pub enum IpAddressError { | ||
#[error(transparent)] | ||
ConnectInfo(#[from] ExtensionRejection), | ||
#[error("X-Real-IP header is invalid or missing")] | ||
InvalidOrMissing, | ||
} | ||
|
||
/// IntoResponse implementation for TokenError to allow it to be | ||
/// used within the result type as a error response | ||
impl IntoResponse for IpAddressError { | ||
#[inline] | ||
fn into_response(self) -> Response { | ||
let status: StatusCode = match self { | ||
IpAddressError::ConnectInfo(err) => return err.into_response(), | ||
_ => StatusCode::BAD_REQUEST, | ||
}; | ||
(status, boxed(self.to_string())).into_response() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters