This commit is contained in:
11
apps/cistech-tunnel/.env.example
Executable file
11
apps/cistech-tunnel/.env.example
Executable file
@@ -0,0 +1,11 @@
|
||||
# Required
|
||||
OC_URL=https://vpn.cistech.net/Employees
|
||||
OC_SERVERCERT=pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0=
|
||||
|
||||
# Optional
|
||||
OC_AUTHGROUP=
|
||||
OC_SSO_ARGS=--browser-display-mode shown
|
||||
VNC_PASSWORD=vpnSSO12
|
||||
NOVNC_PORT=6901
|
||||
PUBLISH_ADDR=0.0.0.0
|
||||
SSH_KEY_PATH=/home/alexz/.ssh/id_ed25519-lenovo
|
||||
11
apps/cistech-tunnel/README.md
Executable file
11
apps/cistech-tunnel/README.md
Executable file
@@ -0,0 +1,11 @@
|
||||
# Cistech Tunnel (VPN + SSH)
|
||||
|
||||
- VPN: OpenConnect-SSO with noVNC for first-time SSO (port 6901)
|
||||
- SSH tunnels: forwards to 10.3.1.201 inside the VPN namespace
|
||||
|
||||
Usage
|
||||
- Copy `.env.example` to `.env` and adjust values.
|
||||
- Build and start:
|
||||
docker compose build
|
||||
docker compose up -d vpn ssh_tunnel
|
||||
- First-time SSO: open http://<host>:6901 and complete login; then set `OC_SSO_ARGS=--browser-display-mode hidden` and restart `vpn`.
|
||||
25
apps/cistech-tunnel/config.json
Executable file
25
apps/cistech-tunnel/config.json
Executable file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Cistech Tunnel",
|
||||
"id": "cistech-tunnel",
|
||||
"available": true,
|
||||
"short_desc": "OpenConnect-SSO VPN + SSH forwards (noVNC)",
|
||||
"author": "alexz",
|
||||
"port": 6901,
|
||||
"categories": ["utilities","network"],
|
||||
"description": "OpenConnect-SSO VPN running in an isolated namespace with noVNC for first-time SSO and an SSH tunnel service for local forwards.",
|
||||
"tipi_version": 1,
|
||||
"version": "1.0.0",
|
||||
"source": "https://git.alexzaw.dev/alexz/cistech-tunnel",
|
||||
"exposable": true,
|
||||
"dynamic_config": false,
|
||||
"no_gui": false,
|
||||
"form_fields": [
|
||||
{"label":"VPN URL","type":"text","env_variable":"OC_URL","required":true,"default":"https://vpn.cistech.net/Employees"},
|
||||
{"label":"Server Cert Pin","type":"text","env_variable":"OC_SERVERCERT","required":true,"default":"pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0="},
|
||||
{"label":"Auth Group","type":"text","env_variable":"OC_AUTHGROUP","required":false,"default":""},
|
||||
{"label":"SSO Mode","type":"text","env_variable":"OC_SSO_ARGS","required":true,"default":"--browser-display-mode shown"},
|
||||
{"label":"VNC Password","type":"password","env_variable":"VNC_PASSWORD","required":true,"default":"Az@83278327$$@@"},
|
||||
{"label":"SSH Key Path","type":"text","env_variable":"SSH_KEY_PATH","required":true,"default":"/home/alexz/.ssh/id_ed25519-lenovo"}
|
||||
],
|
||||
"supported_architectures": ["arm64","amd64"]
|
||||
}
|
||||
25
apps/cistech-tunnel/config.json.bak.1765310779
Executable file
25
apps/cistech-tunnel/config.json.bak.1765310779
Executable file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Cistech Tunnel",
|
||||
"id": "cistech-tunnel",
|
||||
"available": true,
|
||||
"short_desc": "OpenConnect-SSO VPN + SSH forwards (noVNC)",
|
||||
"author": "alexz",
|
||||
"port": 6901,
|
||||
"categories": ["networking", "utilities"],
|
||||
"description": "OpenConnect-SSO VPN running in an isolated namespace with noVNC for first-time SSO and an SSH tunnel service for local forwards.",
|
||||
"tipi_version": 1,
|
||||
"version": "1.0.0",
|
||||
"source": "https://git.alexzaw.dev/alexz/cistech-tunnel",
|
||||
"exposable": true,
|
||||
"dynamic_config": true,
|
||||
"no_gui": false,
|
||||
"form_fields": [
|
||||
{ "label": "VPN URL", "type": "text", "env_variable": "OC_URL_A", "required": true, "default": "https://vpn.cistech.net/Employees" },
|
||||
{ "label": "Server Cert Pin", "type": "text", "env_variable": "OC_SERVERCERT_A", "required": true, "default": "pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0=" },
|
||||
{ "label": "Auth Group", "type": "text", "env_variable": "OC_AUTHGROUP_A", "required": false, "default": "" },
|
||||
{ "label": "SSO Mode", "type": "text", "env_variable": "OC_SSO_ARGS_A", "required": true, "default": "--browser-display-mode shown" },
|
||||
{ "label": "VNC Password", "type": "password", "env_variable": "VNC_PASS_A", "required": true, "default": "vpnSSO12" },
|
||||
{ "label": "SSH Key Path", "type": "text", "env_variable": "SSH_KEY_PATH", "required": true, "default": "/home/alexz/.ssh/id_ed25519-lenovo" }
|
||||
],
|
||||
"supported_architectures": ["arm64", "amd64"]
|
||||
}
|
||||
67
apps/cistech-tunnel/config.json.bak.1765311179
Executable file
67
apps/cistech-tunnel/config.json.bak.1765311179
Executable file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "Cistech Tunnel",
|
||||
"id": "cistech-tunnel",
|
||||
"available": true,
|
||||
"short_desc": "OpenConnect-SSO VPN + SSH forwards (noVNC)",
|
||||
"author": "alexz",
|
||||
"port": 6901,
|
||||
"categories": [
|
||||
"utilities",
|
||||
"network"
|
||||
],
|
||||
"description": "OpenConnect-SSO VPN running in an isolated namespace with noVNC for first-time SSO and an SSH tunnel service for local forwards.",
|
||||
"tipi_version": 1,
|
||||
"version": "1.0.0",
|
||||
"source": "https://git.alexzaw.dev/alexz/cistech-tunnel",
|
||||
"exposable": true,
|
||||
"dynamic_config": true,
|
||||
"no_gui": false,
|
||||
"form_fields": [
|
||||
{
|
||||
"label": "VPN URL",
|
||||
"type": "text",
|
||||
"env_variable": "OC_URL",
|
||||
"required": true,
|
||||
"default": "https://vpn.cistech.net/Employees"
|
||||
},
|
||||
{
|
||||
"label": "Server Cert Pin",
|
||||
"type": "text",
|
||||
"env_variable": "OC_SERVERCERT",
|
||||
"required": true,
|
||||
"default": "pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0="
|
||||
},
|
||||
{
|
||||
"label": "Auth Group",
|
||||
"type": "text",
|
||||
"env_variable": "OC_AUTHGROUP",
|
||||
"required": false,
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"label": "SSO Mode",
|
||||
"type": "text",
|
||||
"env_variable": "OC_SSO_ARGS",
|
||||
"required": true,
|
||||
"default": "--browser-display-mode shown"
|
||||
},
|
||||
{
|
||||
"label": "VNC Password",
|
||||
"type": "password",
|
||||
"env_variable": "VNC_PASSWORD",
|
||||
"required": true,
|
||||
"default": "vpnSSO12"
|
||||
},
|
||||
{
|
||||
"label": "SSH Key Path",
|
||||
"type": "text",
|
||||
"env_variable": "SSH_KEY_PATH",
|
||||
"required": true,
|
||||
"default": "/home/alexz/.ssh/id_ed25519-lenovo"
|
||||
}
|
||||
],
|
||||
"supported_architectures": [
|
||||
"arm64",
|
||||
"amd64"
|
||||
]
|
||||
}
|
||||
39
apps/cistech-tunnel/docker-compose.json.bak.1765312176
Executable file
39
apps/cistech-tunnel/docker-compose.json.bak.1765312176
Executable file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://schemas.runtipi.io/v2/dynamic-compose.json",
|
||||
"schemaVersion": 2,
|
||||
"services": [
|
||||
{
|
||||
"name": "vpn_a",
|
||||
"image": "vpn-openconnect-sso:latest",
|
||||
"isMain": true,
|
||||
"internalPort": 6901,
|
||||
"capAdd": ["NET_ADMIN"],
|
||||
"devices": [
|
||||
{ "hostPath": "/dev/net/tun", "containerPath": "/dev/net/tun" }
|
||||
],
|
||||
"environment": [
|
||||
{ "key": "OC_URL", "value": "${OC_URL_A}" },
|
||||
{ "key": "OC_SERVERCERT", "value": "${OC_SERVERCERT_A}" },
|
||||
{ "key": "OC_AUTHGROUP", "value": "${OC_AUTHGROUP_A}" },
|
||||
{ "key": "OC_INTERFACE", "value": "tun0" },
|
||||
{ "key": "OC_SSO_ARGS", "value": "${OC_SSO_ARGS_A}" },
|
||||
{ "key": "VNC_PASSWORD", "value": "${VNC_PASS_A}" },
|
||||
{ "key": "NOVNC_PORT", "value": "6901" }
|
||||
],
|
||||
"volumes": [
|
||||
{ "hostPath": "${APP_DATA_DIR}/data/vpn_a_state", "containerPath": "/root" }
|
||||
],
|
||||
"restartPolicy": "unless-stopped"
|
||||
},
|
||||
{
|
||||
"name": "ssh_tunnel",
|
||||
"image": "alpine:3.20",
|
||||
"networkMode": "service:vpn_a",
|
||||
"volumes": [
|
||||
{ "hostPath": "${SSH_KEY_PATH}", "containerPath": "/root/.ssh/id_ed25519-lenovo", "readOnly": true }
|
||||
],
|
||||
"command": "sh -lc \"apk add --no-cache openssh-client && exec ssh -N -i /root/.ssh/id_ed25519-lenovo -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 127.0.0.1:8090:localhost:8090 -L 127.0.0.1:2001:localhost:2001 -L 127.0.0.1:36001:localhost:36001 zawa@10.3.1.201\"",
|
||||
"restartPolicy": "unless-stopped"
|
||||
}
|
||||
]
|
||||
}
|
||||
43
apps/cistech-tunnel/docker-compose.yml
Executable file
43
apps/cistech-tunnel/docker-compose.yml
Executable file
@@ -0,0 +1,43 @@
|
||||
services:
|
||||
vpn:
|
||||
build: ./vpn-openconnect-sso
|
||||
container_name: cistech-vpn
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
environment:
|
||||
OC_URL: ${OC_URL}
|
||||
OC_SERVERCERT: ${OC_SERVERCERT}
|
||||
OC_AUTHGROUP: ${OC_AUTHGROUP}
|
||||
OC_INTERFACE: tun0
|
||||
OC_SSO_ARGS: ${OC_SSO_ARGS:- --browser-display-mode shown}
|
||||
VNC_PASSWORD: ${VNC_PASSWORD:-changeme}
|
||||
NOVNC_PORT: ${NOVNC_PORT:-6901}
|
||||
ports:
|
||||
- "${PUBLISH_ADDR:-0.0.0.0}:${NOVNC_PORT:-6901}:${NOVNC_PORT:-6901}"
|
||||
volumes:
|
||||
- vpn_state:/root
|
||||
restart: unless-stopped
|
||||
|
||||
ssh_tunnel:
|
||||
image: alpine:3.20
|
||||
container_name: cistech-ssh-tunnel
|
||||
network_mode: "service:vpn"
|
||||
depends_on:
|
||||
- vpn
|
||||
volumes:
|
||||
- ${SSH_KEY_PATH:-/home/alexz/.ssh/id_ed25519-lenovo}:/root/.ssh/id_ed25519-lenovo:ro
|
||||
command: >
|
||||
sh -lc "apk add --no-cache openssh-client &&
|
||||
exec ssh -N -i /root/.ssh/id_ed25519-lenovo \
|
||||
-o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes \
|
||||
-L 0.0.0.0:8090:localhost:8090 \
|
||||
-L 0.0.0.0:2001:localhost:2001 \
|
||||
-L 0.0.0.0:36001:localhost:36001 \
|
||||
-L 0.0.0.0:36000:localhost:36000 \
|
||||
zawa@10.3.1.201"
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
vpn_state: {}
|
||||
20
apps/cistech-tunnel/metadata/description.md
Executable file
20
apps/cistech-tunnel/metadata/description.md
Executable file
@@ -0,0 +1,20 @@
|
||||
# Dockerized OpenConnect-SSO with noVNC and Cloudflared
|
||||
|
||||
## Setup
|
||||
1) Copy `.env.example` to `.env` and fill values (URLs, servercert pins, VNC passwords, cloudflared tokens).
|
||||
|
||||
2) First-time SSO: leave `OC_SSO_ARGS_*=--browser-display-mode visible`.
|
||||
|
||||
3) Build and start:
|
||||
docker compose build
|
||||
docker compose up -d vpn_a
|
||||
# Open http://localhost:6901, complete SSO.
|
||||
# After success, attach app containers or start cloudflared_a.
|
||||
|
||||
4) Optional: switch to headless after first login:
|
||||
Set `OC_SSO_ARGS_*=--browser-display-mode hidden` (or `headless`) and restart the vpn service.
|
||||
|
||||
## Notes
|
||||
- Each VPN runs in its own net namespace; routes from one cannot affect the other or the host.
|
||||
- DNS from the VPN applies within its container namespace and attached services only.
|
||||
- Persisted state lives in the named volumes mounted at `/root` (Playwright cache, configs).
|
||||
BIN
apps/cistech-tunnel/metadata/logo.jpg
Executable file
BIN
apps/cistech-tunnel/metadata/logo.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 609 KiB |
33
apps/cistech-tunnel/vpn-openconnect-sso/Dockerfile
Executable file
33
apps/cistech-tunnel/vpn-openconnect-sso/Dockerfile
Executable file
@@ -0,0 +1,33 @@
|
||||
FROM ubuntu:24.04
|
||||
ENV QTWEBENGINE_DISABLE_SANDBOX=1
|
||||
ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox --disable-gpu"
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
|
||||
VIRTUAL_ENV=/opt/venv \
|
||||
PATH=/opt/venv/bin:$PATH
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openconnect iproute2 iptables ca-certificates \
|
||||
python3 python3-pip python3-venv \
|
||||
vpnc-scripts curl \
|
||||
x11vnc xvfb fluxbox novnc websockify \
|
||||
xauth libnss3 libatk1.0-0 libatk-bridge2.0-0 \
|
||||
libx11-6 libx11-xcb1 libxcomposite1 libxrandr2 libgbm1 libxdamage1 \
|
||||
libpango-1.0-0 fonts-liberation \
|
||||
libegl1 libgl1 libopengl0 libdbus-1-3 libglib2.0-0 \
|
||||
libxkbcommon0 libxkbcommon-x11-0 \
|
||||
libxcb1 libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render0 libxcb-render-util0 libxcb-shm0 libxcb-xfixes0 libxcb-xinerama0 libxcb-randr0 libxcb-glx0 \
|
||||
sudo \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN apt-get update && (apt-get install -y libasound2t64 || apt-get install -y libasound2) && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN python3 -m venv "$VIRTUAL_ENV"
|
||||
RUN pip install --no-cache-dir openconnect-sso playwright \
|
||||
&& python -m playwright install --with-deps chromium
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 6901
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
36
apps/cistech-tunnel/vpn-openconnect-sso/entrypoint.sh
Executable file
36
apps/cistech-tunnel/vpn-openconnect-sso/entrypoint.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${OC_URL:?OC_URL is required}"
|
||||
: "${OC_SERVERCERT:?OC_SERVERCERT is required}"
|
||||
|
||||
NOVNC_PORT="${NOVNC_PORT:-6901}"
|
||||
VNC_PASSWORD="${VNC_PASSWORD:-changeme}"
|
||||
DISPLAY_ADDR="${DISPLAY:-:1}"
|
||||
OC_INTERFACE="${OC_INTERFACE:-tun0}"
|
||||
OC_SSO_ARGS_DEFAULT="--browser-display-mode shown"
|
||||
|
||||
if [[ "${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT}" == *"shown"* ]]; then
|
||||
mkdir -p /root/.vnc
|
||||
x11vnc -storepasswd "$VNC_PASSWORD" /root/.vnc/pass >/dev/null 2>&1 || true
|
||||
rm -f /tmp/.X1-lock /tmp/.X11-unix/X1 2>/dev/null || true
|
||||
Xvfb "$DISPLAY_ADDR" -screen 0 ${XVFB_WxHxD:-1280x800x24} +extension RANDR &
|
||||
sleep 0.5
|
||||
export DISPLAY="$DISPLAY_ADDR"
|
||||
fluxbox >/tmp/fluxbox.log 2>&1 &
|
||||
x11vnc -display "$DISPLAY_ADDR" -rfbauth /root/.vnc/pass -forever -shared -rfbport 5900 -quiet &
|
||||
websockify --web=/usr/share/novnc/ 0.0.0.0:"$NOVNC_PORT" localhost:5900 >/tmp/websockify.log 2>&1 &
|
||||
fi
|
||||
|
||||
OPENCONNECT_CMD=(
|
||||
/usr/sbin/openconnect
|
||||
--protocol=anyconnect
|
||||
--servercert "$OC_SERVERCERT"
|
||||
--interface "$OC_INTERFACE"
|
||||
--script /usr/share/vpnc-scripts/vpnc-script
|
||||
)
|
||||
[[ -n "${OC_AUTHGROUP:-}" ]] && OPENCONNECT_CMD+=(--authgroup "$OC_AUTHGROUP")
|
||||
[[ -n "${OC_USERAGENT:-}" ]] && OPENCONNECT_CMD+=(--useragent "$OC_USERAGENT")
|
||||
[[ -n "${OC_EXTRA_ARGS:-}" ]] && OPENCONNECT_CMD+=(${OC_EXTRA_ARGS})
|
||||
|
||||
exec openconnect-sso -s "$OC_URL" ${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT} -- "${OPENCONNECT_CMD[@]}"
|
||||
Reference in New Issue
Block a user