Compare commits

...

3 Commits

Author SHA1 Message Date
818bd586bd
Added README
Some checks failed
Build and deploy / Build container and manifests (push) Failing after 5m47s
2025-04-17 13:41:43 +02:00
943af8a03c
Removed test file 2025-04-17 13:41:43 +02:00
76080994ea
Changed name to siranga 2025-04-17 13:41:38 +02:00
14 changed files with 113 additions and 75 deletions

BIN
.assets/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

56
Cargo.lock generated
View File

@ -2853,6 +2853,34 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "siranga"
version = "0.0.0"
dependencies = [
"bytes",
"clap",
"clio",
"color-eyre",
"crossterm 0.29.0",
"dotenvy",
"futures",
"git-version",
"http-body-util",
"hyper",
"hyper-util",
"ldap3",
"pin-project-lite",
"rand 0.8.5",
"ratatui",
"reqwest",
"russh",
"thiserror 2.0.12",
"tokio",
"tracing",
"tracing-subscriber",
"unicode-width 0.2.0",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -3299,34 +3327,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tunnel_rs"
version = "0.0.0"
dependencies = [
"bytes",
"clap",
"clio",
"color-eyre",
"crossterm 0.29.0",
"dotenvy",
"futures",
"git-version",
"http-body-util",
"hyper",
"hyper-util",
"ldap3",
"pin-project-lite",
"rand 0.8.5",
"ratatui",
"reqwest",
"russh",
"thiserror 2.0.12",
"tokio",
"tracing",
"tracing-subscriber",
"unicode-width 0.2.0",
]
[[package]]
name = "typenum"
version = "1.18.0"

View File

@ -1,7 +1,7 @@
[package]
name = "tunnel_rs"
name = "siranga"
edition = "2024"
default-run = "tunnel_rs"
default-run = "siranga"
[dependencies]
bytes = "1.10.1"

View File

@ -18,5 +18,5 @@ ENV RUSTC_BOOTSTRAP=1
RUN cargo auditable build --release
FROM gcr.io/distroless/cc-debian12:nonroot AS runtime
COPY --from=builder /app/target/release/tunnel_rs /tunnel_rs
CMD ["/tunnel_rs"]
COPY --from=builder /app/target/release/siranga /siranga
CMD ["/siranga"]

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# Siranga
Siranga allows users to quickly create new subdomains that tunnel to local ports on their machine over SSH.
![Screenshot of the Siranga user interface](./.assets/screenshot.png)
## Features
- Works over SSH, no need to install any other tools to forwards ports
- Using ForwardAuth tunnels can be
- Private, only accessible by you
- Protected, accessible by all logged in users
- Public, accessible for everyone
- SSH keys are pulled from LDAP, so no separate upload is required.
- Provides a user interface for
- Managing access
- Renaming of tunnels
- Network statistics
Siranga does NOT provide HTTPS support, it expects to run behind a reverse proxy.
## Installation
Siranga is intended to be deployed using Kubernetes, example manifest files are provided in [manifests](./manifests).
This deployment runs in a cluster with [Authelia](https://github.com/authelia/authelia), [LLDAP](https://github.com/lldap/lldap), and [Traefik](https://github.com/traefik/traefik).
## User guide
A tunnel can be opened using the following command:
```
ssh <username>@<host> [-p <ssh port>] -t -R <local port>:localhost:<local port>
```
This will open a new tunnel with a randomly generated name, you can specify a name for the tunnel by instead using `-R <name>:<local port>:localhost:<local port>`.
Multiple tunnels can be opened by repeating the `-R` option.
Once connected the tunnels can be managed using the interface.
By appending `-- --help` you can view the available command line options.
### Tip
To make connecting slightly easier I recommend adding the following to `~/.ssh/config`:
```
Host tunnel
HostName <host>
Port <ssh port>
User <username>
RequestTTY yes
```
You can now connect with `ssh tunnel -R <local port>:localhost:<local port>`.

View File

@ -1,25 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: tunnel
name: siranga
labels:
app: tunnel
app.kubernetes.io/name: tunnel
app: siranga
app.kubernetes.io/name: siranga
spec:
replicas: 1
selector:
matchLabels:
app: tunnel
app: siranga
template:
metadata:
labels:
app: tunnel
app: siranga
annotations:
kubectl.kubernetes.io/default-container: tunnel
kubectl.kubernetes.io/default-container: siranga
spec:
containers:
- name: tunnel
image: git.huizinga.dev/dreaded_x/tunnel_rs@${DIGEST}
- name: siranga
image: git.huizinga.dev/dreaded_x/siranga@${DIGEST}
imagePullPolicy: IfNotPresent
resources:
limits:
@ -40,7 +40,7 @@ spec:
mountPath: "/secrets/key"
env:
- name: RUST_LOG
value: info,tunnel_rs=debug
value: info,siranga=debug
- name: TUNNEL_DOMAIN
value: tunnel.${domain}
- name: AUTHZ_ENDPOINT
@ -50,7 +50,7 @@ spec:
- name: LDAP_BASE
value: ou=people,dc=huizinga,dc=dev
- name: LDAP_BIND_DN
value: uid=tunnel.tunnel,ou=people,dc=huizinga,dc=dev
value: uid=siranga.siranga,ou=people,dc=huizinga,dc=dev
- name: LDAP_PASSWORD_FILE
value: /secrets/credentials/password
- name: PRIVATE_KEY_FILE
@ -58,8 +58,8 @@ spec:
volumes:
- name: credentials
secret:
secretName: tunnel-lldap-credentials
secretName: siranga-lldap-credentials
- name: key
secret:
secretName: tunnel-key
secretName: siranga-key

View File

@ -9,7 +9,7 @@ spec:
- match: HostRegexp(`^.+\.tunnel\.${domain//./\\.}$`)
kind: Rule
services:
- name: tunnel
- name: http
port: 3000
tls:
secretName: tunnel-tls

View File

@ -1,6 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tunnel
namespace: siranga
resources:
- ./namespace.yaml
- ./service-user.yaml

View File

@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: tunnel
name: siranga

View File

@ -1,18 +1,13 @@
apiVersion: v1
kind: Secret
metadata:
name: tunnel-key
name: siranga-key
type: Opaque
stringData:
private.pem: ENC[AES256_GCM,data:9chbnKvGVtGEHTytURAK03ewcy+2LO3JLN6uCD6EtovQqAHZvBJFmUWDwSKXXLAoH8ErQ7VjldzaGPNhCqJaF/+69N9ruoOELR/NdqBbeXxQLdzNO95qlFGNbvBQaJheuQmT0BIqMxu8GHEjoswdHiE0wQebbJubPu3x85tLu24T86sUpeBuRcFsdouBPCO3q3h5Prdxscl/McTcdB+DE21Mpk0dw9GvxmyeTWg1LAbmtYv5vhdJRCSQW1EtQQNn/o/K3/7ALoGsekomjAoFmVG7OKIwaUbfJkVxyYN8UQ7Q4YQ3C16NCysoNx4aB9AlcvIeME/eNJ+nAQMWFA5q2ewhza+idw1H9GmBJaoIFCGsXXdPTyEglFFf5xGZR/lHGxxD1UP0Zd/b25dIKkAYBnYVPojN1HLom+3dG+Ci1oGQmDkT91w1Zj72b9uIdT+xNTBG7b8bkBlLprUJ8VYm2sGZiFmzYkJd6slwVJ+j0Y26iEEpvPb63stkhkeSIeg1fKSL,iv:lz3hiOS/+xYJ4/ooITqxXNlpZsiA+UXQH+4UTofj2p0=,tag:Pwz3pCqJkSUFx5JflKJJEw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2025-04-14T22:32:45Z"
mac: ENC[AES256_GCM,data:KGxVfxRVzyzkJTfGzVsWzLMDPBhElcpbgeHalctly14MhzsubEVPwr6Qlj4dh2714Vs0NUo3xERbIeLYRZqbqIQkVkXM31bzA0Tsud+Wapv92B9Z2yr249YX1EhxwnFzSR+180vkIB+Vc8n2hfgSXftUg5L5QEouUuilUiXWQKo=,iv:pal8Fypc6HnTnHulaFvo8A5FH6wjdDQQJGUb0G+w6Do=,tag:D4swtLKJctkyDTfMQpdGtg==,type:str]
lastmodified: "2025-04-17T11:29:42Z"
mac: ENC[AES256_GCM,data:2qRJCmcQTVtI+UMkcNcMlbXiTDNj83RqCOZDsNQ9UxqFmOQy35o6ig5YPfj2bKWYJSR2l4F5JWOKk3rYeAagCZ74tWjOM/LA5u8AiCUf9tDVRA82fQAXIVg7s6Udzif0U0yzPfOb2Ia8xDrm2Hfl7GTeO1WJN+qtI9qQDJHedlA=,iv:dTWKJMCqtnDMqLZS5SwVg5Uu5Kv1p9GtAQ55wZ1j/mI=,tag:KVKKDNAtKLZ7xxVzgh/Nng==,type:str]
pgp:
- created_at: "2025-04-14T16:11:54Z"
enc: |-
@ -56,4 +51,4 @@ sops:
-----END PGP MESSAGE-----
fp: 49F10679C425233EFB4B1B6F9D641BEFA42DEC28
encrypted_regex: ^(data|stringData)$
version: 3.9.4
version: 3.10.1

View File

@ -1,5 +1,5 @@
apiVersion: lldap.huizinga.dev/v1
kind: ServiceUser
metadata:
name: tunnel
name: siranga
spec: {}

View File

@ -1,19 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: tunnel
name: http
spec:
ports:
- name: "3000"
port: 3000
targetPort: 3000
selector:
app: tunnel
app: siranga
---
apiVersion: v1
kind: Service
metadata:
name: tunnel-ssh
name: ssh
annotations:
external-dns.alpha.kubernetes.io/hostname: tunnel.svc.${domain}
spec:
@ -23,4 +23,4 @@ spec:
port: 22
targetPort: 2222
selector:
app: tunnel
app: siranga

View File

@ -7,15 +7,15 @@ use git_version::git_version;
use hyper::server::conn::http1::{self};
use hyper_util::rt::TokioIo;
use rand::rngs::OsRng;
use siranga::ldap::Ldap;
use siranga::ssh::Server;
use siranga::tunnel::Registry;
use siranga::web::{ForwardAuth, Service};
use tokio::net::TcpListener;
use tracing::{error, info, warn};
use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tunnel_rs::ldap::Ldap;
use tunnel_rs::ssh::Server;
use tunnel_rs::tunnel::Registry;
use tunnel_rs::web::{ForwardAuth, Service};
#[tokio::main]
async fn main() -> color_eyre::Result<()> {

View File

@ -1,10 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: tunnel-demo-acl
annotations:
config.huizinga.dev/fragment: authelia-acl
data:
rules: |
- domain: "*.tunnel.huizinga.dev"
policy: one_factor