Add proxy support

This commit is contained in:
Shav Kinderlehrer 2024-04-07 14:44:03 -04:00
parent a29d68aed7
commit 1075ab0ed1
7 changed files with 34 additions and 8 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
/target

2
Cargo.lock generated
View File

@ -194,7 +194,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chela" name = "chela"
version = "0.2.0" version = "0.3.0"
dependencies = [ dependencies = [
"axum", "axum",
"color-eyre", "color-eyre",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "chela" name = "chela"
version = "0.2.0" version = "0.3.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,6 +1,10 @@
FROM rust:1.76.0 FROM rust:1.76.0 AS builder
WORKDIR /usr/src/chela WORKDIR /usr/src/chela
COPY . . COPY . .
RUN cargo build -r RUN cargo build -r
CMD ["./target/release/chela"]
FROM gcr.io/distroless/cc-debian12
WORKDIR /usr/src/chela
COPY --from=builder /usr/src/chela/target/release/chela ./
CMD ["./chela"]
EXPOSE 3000 EXPOSE 3000

View File

@ -11,7 +11,7 @@ You can create a redirect by navigating to the `/create` page and filling out th
### With Docker ### With Docker
#### CLI #### CLI
```bash ```bash
docker run -d \ $ docker run -d \
-p 3000:3000 \ -p 3000:3000 \
-e DATABASE_URL=postgres://chela:password@dbhost/postgres?sslmode=disable \ -e DATABASE_URL=postgres://chela:password@dbhost/postgres?sslmode=disable \
-e CHELA_HOST=a.com \ -e CHELA_HOST=a.com \
@ -37,6 +37,7 @@ services:
- DATABASE_URL=postgres://chela:password@chela-postgres/postgres?sslmode=disable - DATABASE_URL=postgres://chela:password@chela-postgres/postgres?sslmode=disable
- CHELA_HOST=a.com - CHELA_HOST=a.com
- CHELA_MAIN_PAGE_REDIRECT='https://example.com' - CHELA_MAIN_PAGE_REDIRECT='https://example.com'
- CHELA_BEHIND_PROXY=1
depends_on: depends_on:
- chela-postgres - chela-postgres
restart: unless-stopped restart: unless-stopped
@ -59,6 +60,9 @@ The address that Chela should listen on. Defaults to `0.0.0.0`.
##### `CHELA_MAIN_PAGE_REDIRECT` ##### `CHELA_MAIN_PAGE_REDIRECT`
A page that Chela will redirect to when `/` is requested instead of replying with the default homepage. A page that Chela will redirect to when `/` is requested instead of replying with the default homepage.
##### `CHELA_BEHIND_PROXY`
If this variable is set, Chela will use the `X-Real-IP` header as the client IP address rather than the connection address.
### Manually ### Manually
#### Build #### Build
```bash ```bash
@ -86,6 +90,7 @@ server {
location / { location / {
proxy_pass http://localhost:3000/; proxy_pass http://localhost:3000/;
proxy_set_header X-Real-IP $remote_addr;
limit_except GET HEAD { limit_except GET HEAD {
auth_basic 'Restricted'; auth_basic 'Restricted';

View File

@ -93,7 +93,20 @@ pub async fn id(
async fn save_analytics(headers: HeaderMap, item: UrlRow, addr: SocketAddr, state: ServerState) { async fn save_analytics(headers: HeaderMap, item: UrlRow, addr: SocketAddr, state: ServerState) {
let id = item.id; let id = item.id;
let ip = addr.ip().to_string(); let ip: Option<String> = if state.behind_proxy {
match headers.get("x-real-ip") {
Some(it) => {
if let Ok(i) = it.to_str() {
Some(i.to_string())
} else {
None
}
}
None => None,
}
} else {
Some(addr.ip().to_string())
};
let referer = match headers.get("referer") { let referer = match headers.get("referer") {
Some(it) => { Some(it) => {
if let Ok(i) = it.to_str() { if let Ok(i) = it.to_str() {
@ -129,7 +142,7 @@ VALUES ($1,$2,$3,$4)
.await; .await;
if res.is_ok() { if res.is_ok() {
log!("Saved analytics for '{id}' from {ip}"); log!("Saved analytics for '{id}' from {}", ip.unwrap_or_default());
} }
} }

View File

@ -23,6 +23,7 @@ pub struct ServerState {
pub host: String, pub host: String,
pub sqids: Sqids, pub sqids: Sqids,
pub main_page_redirect: Option<Url>, pub main_page_redirect: Option<Url>,
pub behind_proxy: bool,
} }
#[derive(Debug, Clone, sqlx::FromRow, PartialEq, Eq)] #[derive(Debug, Clone, sqlx::FromRow, PartialEq, Eq)]
@ -53,11 +54,13 @@ async fn main() -> eyre::Result<()> {
.blocklist(["create".to_string()].into()) .blocklist(["create".to_string()].into())
.build()?; .build()?;
let main_page_redirect = std::env::var("CHELA_MAIN_PAGE_REDIRECT").unwrap_or_default(); let main_page_redirect = std::env::var("CHELA_MAIN_PAGE_REDIRECT").unwrap_or_default();
let behind_proxy = std::env::var("CHELA_BEHIND_PROXY").is_ok();
let server_state = ServerState { let server_state = ServerState {
db_pool, db_pool,
host, host,
sqids, sqids,
main_page_redirect: Url::parse(&main_page_redirect).ok(), main_page_redirect: Url::parse(&main_page_redirect).ok(),
behind_proxy,
}; };
let address = std::env::var("CHELA_LISTEN_ADDRESS").unwrap_or("0.0.0.0".to_string()); let address = std::env::var("CHELA_LISTEN_ADDRESS").unwrap_or("0.0.0.0".to_string());
@ -108,7 +111,7 @@ CREATE TABLE IF NOT EXISTS chela.urls (
CREATE TABLE IF NOT EXISTS chela.tracking ( CREATE TABLE IF NOT EXISTS chela.tracking (
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
id TEXT NOT NULL, id TEXT NOT NULL,
ip TEXT NOT NULL, ip TEXT,
referrer TEXT, referrer TEXT,
user_agent TEXT user_agent TEXT
) )