diff --git a/apps/rego-tunnel/build/setup-network.sh b/apps/rego-tunnel/build/setup-network.sh deleted file mode 100755 index 8ecd67c..0000000 --- a/apps/rego-tunnel/build/setup-network.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/bash -# Setup TAP/Bridge networking for QEMU VM -# Defaults: -# BRIDGE_NAME=br-rego-vpn -# TAP_NAME=tap0 -# BRIDGE_CIDR=100.100.0.1/24 -# VM_NET_IP=100.100.0.2 -# VM_SUBNET=100.100.0.0/24 - -set -e - -BRIDGE_NAME="${BRIDGE_NAME:-br-rego-vpn}" -TAP_NAME="${TAP_NAME:-tap0}" -BRIDGE_CIDR="${BRIDGE_CIDR:-100.100.0.1}" -VM_NET_IP="${VM_NET_IP:-100.100.0.2}" -VM_SUBNET="${VM_SUBNET:-100.100.0.0}" -TARGET_IP="${TARGET_IP:-10.35.33.230}" - -# Optional second bridge/tap for a second VM NIC (pure L2 with the container). -# This is opt-in: set BRIDGE2_NAME and TAP2_NAME (and optionally BRIDGE2_CIDR). -BRIDGE2_NAME="${BRIDGE2_NAME:-}" -TAP2_NAME="${TAP2_NAME:-}" -BRIDGE2_CIDR="${BRIDGE2_CIDR:-}" -BRIDGE2_UPLINK_IF="${BRIDGE2_UPLINK_IF:-}" - -if [[ "$BRIDGE_CIDR" != */* ]]; then - BRIDGE_CIDR="$BRIDGE_CIDR/24" -fi - -if [[ "$VM_SUBNET" != */* ]]; then - VM_SUBNET="$VM_SUBNET/24" -fi - -# Pick the outbound interface based on the container's default route. -# (In Docker, this is not always eth1 when multiple networks are attached.) -WAN_IF="$(ip route show default 0.0.0.0/0 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')" -if [ -z "${WAN_IF}" ]; then - WAN_IF="eth1" -fi - -# Ensure bridge exists -if ! ip link show "$BRIDGE_NAME" &>/dev/null; then - ip link add "$BRIDGE_NAME" type bridge -fi - -# Ensure bridge has address and is up -ip addr show dev "$BRIDGE_NAME" | grep -qF "$BRIDGE_CIDR" || ip addr add "$BRIDGE_CIDR" dev "$BRIDGE_NAME" 2>/dev/null || true -ip link set "$BRIDGE_NAME" up - -# Ensure TAP exists -if ! ip link show "$TAP_NAME" &>/dev/null; then - ip tuntap add "$TAP_NAME" mode tap -fi - -# Ensure TAP is attached and up -ip link set "$TAP_NAME" master "$BRIDGE_NAME" 2>/dev/null || true -ip link set "$TAP_NAME" up - -# Optional second bridge/tap (no NAT rules are applied here) -if [ -n "$BRIDGE2_NAME" ] || [ -n "$TAP2_NAME" ]; then - if [ -z "$BRIDGE2_NAME" ] || [ -z "$TAP2_NAME" ]; then - echo "[rego-tunnel] WARN: BRIDGE2_NAME and TAP2_NAME must both be set to enable the second bridge" - else - # Optionally bridge an existing container uplink into BRIDGE2 (e.g. eth0/eth1) - # so the VM NIC shares the same L2 network as that uplink. - if [ -n "$BRIDGE2_UPLINK_IF" ]; then - if ! ip link show "$BRIDGE2_UPLINK_IF" &>/dev/null; then - echo "[rego-tunnel] WARN: BRIDGE2_UPLINK_IF=$BRIDGE2_UPLINK_IF not found; skipping uplink bridging" - BRIDGE2_UPLINK_IF="" - fi - fi - - if ! ip link show "$BRIDGE2_NAME" &>/dev/null; then - ip link add "$BRIDGE2_NAME" type bridge - fi - ip link set "$BRIDGE2_NAME" up - - # If an uplink interface is provided, move its IPv4 address to the bridge. - # This keeps the container reachable on that network while allowing the VM - # to participate in the same L2 broadcast domain. - if [ -n "$BRIDGE2_UPLINK_IF" ]; then - UPLINK_CIDR="$(ip -o -4 addr show dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{print $4}' | head -n1)" - UPLINK_DEFAULT_GW="$(ip route show default dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{print $3}' | head -n1)" - UPLINK_DEFAULT_METRIC="$(ip route show default dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="metric"){print $(i+1); exit}}')" - if [ -z "$BRIDGE2_CIDR" ] && [ -n "$UPLINK_CIDR" ]; then - BRIDGE2_CIDR="$UPLINK_CIDR" - fi - if [ -n "$BRIDGE2_CIDR" ]; then - if [[ "$BRIDGE2_CIDR" != */* ]]; then - BRIDGE2_CIDR="$BRIDGE2_CIDR/24" - fi - ip addr show dev "$BRIDGE2_NAME" | grep -qF "$BRIDGE2_CIDR" || ip addr add "$BRIDGE2_CIDR" dev "$BRIDGE2_NAME" 2>/dev/null || true - fi - # Remove IP from uplink and enslave it into the bridge - ip addr flush dev "$BRIDGE2_UPLINK_IF" 2>/dev/null || true - ip link set "$BRIDGE2_UPLINK_IF" master "$BRIDGE2_NAME" 2>/dev/null || true - ip link set "$BRIDGE2_UPLINK_IF" up 2>/dev/null || true - - # If the uplink carried the container default route, it may have been removed - # by the address flush. Restore it on the bridge. - if [ -n "$UPLINK_DEFAULT_GW" ]; then - if ip route show default 2>/dev/null | grep -q '^default '; then - ip route replace default via "$UPLINK_DEFAULT_GW" dev "$BRIDGE2_NAME" ${UPLINK_DEFAULT_METRIC:+metric "$UPLINK_DEFAULT_METRIC"} 2>/dev/null || true - else - ip route add default via "$UPLINK_DEFAULT_GW" dev "$BRIDGE2_NAME" ${UPLINK_DEFAULT_METRIC:+metric "$UPLINK_DEFAULT_METRIC"} 2>/dev/null || true - fi - fi - fi - - if ! ip link show "$TAP2_NAME" &>/dev/null; then - ip tuntap add "$TAP2_NAME" mode tap - fi - ip link set "$TAP2_NAME" master "$BRIDGE2_NAME" 2>/dev/null || true - ip link set "$TAP2_NAME" up - echo "[rego-tunnel] Second bridge enabled: $BRIDGE2_NAME (tap $TAP2_NAME)${BRIDGE2_UPLINK_IF:+ uplink $BRIDGE2_UPLINK_IF}" - fi -fi - -# Enable IP forwarding -echo 1 > /proc/sys/net/ipv4/ip_forward - -# Setup NAT/masquerade for outbound traffic from VM -iptables -t nat -C POSTROUTING -s "$VM_SUBNET" -o "$WAN_IF" -j MASQUERADE 2>/dev/null || \ - iptables -t nat -A POSTROUTING -s "$VM_SUBNET" -o "$WAN_IF" -j MASQUERADE - -# Ensure forwarding between the VM bridge and outbound interface -iptables -C FORWARD -i "$BRIDGE_NAME" -o "$WAN_IF" -j ACCEPT 2>/dev/null || \ - iptables -A FORWARD -i "$BRIDGE_NAME" -o "$WAN_IF" -j ACCEPT -iptables -C FORWARD -i "$WAN_IF" -o "$BRIDGE_NAME" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \ - iptables -A FORWARD -i "$WAN_IF" -o "$BRIDGE_NAME" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - -# Forward traffic destined for VPN networks to VM (TARGET_IP defaults to IBM i) -# The VM will route this through its VPN tunnel -iptables -C FORWARD -d "$TARGET_IP" -j ACCEPT 2>/dev/null || iptables -A FORWARD -d "$TARGET_IP" -j ACCEPT -iptables -C FORWARD -s "$TARGET_IP" -j ACCEPT 2>/dev/null || iptables -A FORWARD -s "$TARGET_IP" -j ACCEPT - -# Route to TARGET_IP through VM -ip route add "$TARGET_IP" via "$VM_NET_IP" 2>/dev/null || true - -echo "Network setup complete" -echo "Bridge: $BRIDGE_NAME = $BRIDGE_CIDR" -echo "TAP: $TAP_NAME attached to $BRIDGE_NAME" -echo "Route: $TARGET_IP via $VM_NET_IP (VM)" -echo "Outbound interface: ${WAN_IF}" - -if [ -n "$BRIDGE2_NAME" ] && [ -n "$TAP2_NAME" ]; then - echo "Bridge2: $BRIDGE2_NAME${BRIDGE2_CIDR:+ = $BRIDGE2_CIDR}" - echo "TAP2: $TAP2_NAME attached to $BRIDGE2_NAME" -fi \ No newline at end of file diff --git a/apps/rego-tunnel/build/start-dnsmasq.sh b/apps/rego-tunnel/build/start-dnsmasq.sh deleted file mode 100755 index 2b2c3b8..0000000 --- a/apps/rego-tunnel/build/start-dnsmasq.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -euo pipefail - -BRIDGE_NAME="${BRIDGE_NAME:-br-rego-vpn}" -BRIDGE_CIDR="${BRIDGE_CIDR:-100.100.0.1}" -VM_NET_IP="${VM_NET_IP:-100.100.0.2}" -VM_MAC="${VM_MAC:-52:54:00:12:34:56}" - -LEASE_TIME="${LEASE_TIME:-12h}" -DNS_SERVERS="${DNS_SERVERS:-1.1.1.1,8.8.8.8}" - -if [[ "$BRIDGE_CIDR" != */* ]]; then - BRIDGE_CIDR="$BRIDGE_CIDR/24" -fi - -GATEWAY_IP="${BRIDGE_CIDR%%/*}" - -mkdir -p /etc/dnsmasq.d - -cat > /etc/dnsmasq.d/rego.conf < ${VM_NET_IP}" -exec dnsmasq --no-daemon --conf-file=/etc/dnsmasq.d/rego.conf diff --git a/apps/rego-tunnel/build/start-vm.sh b/apps/rego-tunnel/build/start-vm.sh deleted file mode 100755 index 6ba3031..0000000 --- a/apps/rego-tunnel/build/start-vm.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# If provided, extract ssh.zip to /root/.ssh (not baked into the image) -SSH_ZIP_PATH="/shared/ssh.zip" -SSH_ZIP_DEST="/root/.ssh" - -if [ -f "$SSH_ZIP_PATH" ]; then - mkdir -p "$SSH_ZIP_DEST" - chmod 700 "$SSH_ZIP_DEST" - - echo "[rego-tunnel] Extracting $SSH_ZIP_PATH -> $SSH_ZIP_DEST" - # Exclude editor swap/backup files; overwrite existing. - 7z x -y -aoa -o"$SSH_ZIP_DEST" "$SSH_ZIP_PATH" \ - -x!*.swp -x!*.swo -x!*.swx -x!*~ -x!.DS_Store >/dev/null - - find "$SSH_ZIP_DEST" -type d -exec chmod 700 {} \; - find "$SSH_ZIP_DEST" -type f -exec chmod 600 {} \; -else - echo "[rego-tunnel] No $SSH_ZIP_PATH found; skipping SSH zip extraction" -fi - -# Wait for network setup -sleep 2 - -TAP_NAME="${TAP_NAME:-tap0}" - -# Optional: provide a dedicated 9p export for host app-data (bind-mounted into the container at /shared/app-data) -TSCLIENT_PATH="/hostshare" -TSCLIENT_TAG="${TSCLIENT_TAG:-TSCLIENT}" -SHARED_TAG="${SHARED_TAG:-shared}" - -# Ensure the VM auto-mounts the 9p shares without manual steps. -# This edits the QCOW2 from the outside (idempotent) before QEMU boots. -AUTO_MOUNT_9P="${AUTO_MOUNT_9P:-1}" -if [ "$AUTO_MOUNT_9P" = "1" ]; then - QCOW2_PATH="/vm/linux-vm.qcow2" - NBD_DEV="${NBD_DEV:-/dev/nbd0}" - VMROOT_MNT="/mnt/vmroot" - - if [ -e "$QCOW2_PATH" ] && [ -e "$NBD_DEV" ]; then - echo "[rego-tunnel] Ensuring guest fstab mounts 9p tags ($SHARED_TAG, $TSCLIENT_TAG)" - modprobe nbd max_part=16 >/dev/null 2>&1 || true - qemu-nbd --disconnect "$NBD_DEV" >/dev/null 2>&1 || true - qemu-nbd --connect "$NBD_DEV" "$QCOW2_PATH" - sleep 1 - - # In containers, the kernel may create sysfs partition entries but not - # auto-create the corresponding /dev/nbd0p* nodes. Create them if missing. - base_dev="$(basename "$NBD_DEV")" - for sysfs_dev in /sys/class/block/${base_dev}p*; do - [ -e "$sysfs_dev" ] || continue - part_name="$(basename "$sysfs_dev")" - devnode="/dev/$part_name" - [ -e "$devnode" ] && continue - if [ -r "$sysfs_dev/dev" ]; then - IFS=: read -r major minor < "$sysfs_dev/dev" || true - if [ -n "${major:-}" ] && [ -n "${minor:-}" ]; then - mknod "$devnode" b "$major" "$minor" 2>/dev/null || true - chmod 660 "$devnode" 2>/dev/null || true - fi - fi - done - - mkdir -p "$VMROOT_MNT" - ROOT_PART="" - for part in "${NBD_DEV}"p*; do - [ -e "$part" ] || continue - # Try mount and detect a Linux root by presence of /etc/fstab and /etc/os-release - if mount "$part" "$VMROOT_MNT" >/dev/null 2>&1; then - if [ -d "$VMROOT_MNT/etc" ] && { [ -f "$VMROOT_MNT/etc/os-release" ] || [ -f "$VMROOT_MNT/usr/lib/os-release" ] || [ -f "$VMROOT_MNT/usr/share/os-release" ]; }; then - ROOT_PART="$part" - break - fi - umount "$VMROOT_MNT" >/dev/null 2>&1 || true - fi - done - - if [ -n "$ROOT_PART" ]; then - # already mounted from loop above - mkdir -p "$VMROOT_MNT/shared" "$VMROOT_MNT/hostshare" - - FSTAB="$VMROOT_MNT/etc/fstab" - # Add entries only if missing - grep -qE "^[[:space:]]*${SHARED_TAG}[[:space:]]+" "$FSTAB" || echo "${SHARED_TAG} /shared 9p trans=virtio,version=9p2000.L,msize=262144,_netdev,nofail,x-systemd.automount 0 0" >> "$FSTAB" - grep -qE "^[[:space:]]*${TSCLIENT_TAG}[[:space:]]+" "$FSTAB" || echo "${TSCLIENT_TAG} /hostshare 9p trans=virtio,version=9p2000.L,msize=262144,_netdev,nofail,x-systemd.automount 0 0" >> "$FSTAB" - - umount "$VMROOT_MNT" >/dev/null 2>&1 || true - else - echo "[rego-tunnel] WARN: could not locate guest root partition; skipping auto-mount setup" - lsblk -fp "$NBD_DEV" 2>/dev/null || true - blkid "$NBD_DEV"* 2>/dev/null || true - fi - - qemu-nbd --disconnect "$NBD_DEV" >/dev/null 2>&1 || true - else - echo "[rego-tunnel] WARN: missing $QCOW2_PATH or $NBD_DEV; skipping auto-mount setup" - fi -fi - -exec qemu-system-x86_64 \ - -enable-kvm \ - -cpu host \ - -m ${VM_RAM:-8G} \ - -smp ${VM_CPUS:-4} \ - -hda /vm/linux-vm.qcow2 \ - -fsdev local,id=fsdev0,path=/shared,security_model=none,multidevs=remap \ - -device virtio-9p-pci,fsdev=fsdev0,mount_tag="$SHARED_TAG" \ - -fsdev local,id=fsdev1,path="$TSCLIENT_PATH",security_model=none,multidevs=remap \ - -device virtio-9p-pci,fsdev=fsdev1,mount_tag="$TSCLIENT_TAG" \ - -netdev tap,id=net0,ifname="$TAP_NAME",script=no,downscript=no \ - -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \ - -vnc :0 \ - -vga virtio \ - -usb \ - -device usb-tablet diff --git a/apps/rego-tunnel/build/supervisord.conf b/apps/rego-tunnel/build/supervisord.conf deleted file mode 100755 index 749a8af..0000000 --- a/apps/rego-tunnel/build/supervisord.conf +++ /dev/null @@ -1,46 +0,0 @@ -[supervisord] -nodaemon=true -logfile=/var/log/supervisord.log - -[program:network-setup] -command=/usr/local/bin/setup-network.sh -autostart=true -autorestart=false -startsecs=0 -priority=1 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:dnsmasq] -command=/usr/local/bin/start-dnsmasq.sh -autostart=true -autorestart=true -priority=5 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:sshd] -command=/usr/sbin/sshd -D -autostart=true -autorestart=true -priority=10 - -[program:qemu] -command=/usr/local/bin/start-vm.sh -autostart=true -autorestart=true -priority=20 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:novnc] -command=/usr/bin/websockify --web /usr/share/novnc 8006 localhost:5900 --auth-plugin BasicHTTPAuth --auth-source alexz:Az@83278327$$@@ -autostart=true -autorestart=true -priority=30 diff --git a/apps/rego-tunnel/config.json b/apps/rego-tunnel/config.json index b8c1f74..f493ad4 100755 --- a/apps/rego-tunnel/config.json +++ b/apps/rego-tunnel/config.json @@ -173,7 +173,7 @@ "placeholder": "${APP_DATA_DIR}", "required": true, "env_variable": "HOSTSHARE_DIR", - "default": "/etc/runtipi/app-data/runtipi/rego-tunnel/hostshare" + "default": "/etc/runtipi/user-config/runtipi/rego-tunnel/shared" } ], "supported_architectures": ["amd64"]