rego-tunnel: parameterize net + add DHCP static lease
Some checks failed
Test / test (push) Has been cancelled
Some checks failed
Test / test (push) Has been cancelled
This commit is contained in:
@@ -2,7 +2,7 @@ FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y qemu-system-x86 qemu-utils novnc websockify openssh-server supervisor iproute2 bridge-utils iptables nano net-tools p7zip-full && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get install -y qemu-system-x86 qemu-utils novnc websockify openssh-server supervisor iproute2 bridge-utils iptables nano net-tools p7zip-full dnsmasq && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup SSH
|
||||
RUN mkdir /var/run/sshd && echo 'root:vmpassword' | chpasswd && sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
|
||||
@@ -12,6 +12,7 @@ WORKDIR /vm
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
COPY start-vm.sh /usr/local/bin/start-vm.sh
|
||||
COPY setup-network.sh /usr/local/bin/setup-network.sh
|
||||
RUN chmod +x /usr/local/bin/start-vm.sh /usr/local/bin/setup-network.sh
|
||||
COPY start-dnsmasq.sh /usr/local/bin/start-dnsmasq.sh
|
||||
RUN chmod +x /usr/local/bin/start-vm.sh /usr/local/bin/setup-network.sh /usr/local/bin/start-dnsmasq.sh
|
||||
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Setup TAP/Bridge networking for QEMU VM
|
||||
# Bridge: 100.100.0.1/24
|
||||
# VM will be: 100.100.0.2/24
|
||||
# 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/24}"
|
||||
VM_NET_IP="${VM_NET_IP:-100.100.0.2}"
|
||||
VM_SUBNET="${VM_SUBNET:-100.100.0.0/24}"
|
||||
TARGET_IP="${TARGET_IP:-10.35.33.230}"
|
||||
|
||||
# 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}}')"
|
||||
@@ -13,44 +24,44 @@ if [ -z "${WAN_IF}" ]; then
|
||||
fi
|
||||
|
||||
# Create bridge if not exists
|
||||
if ! ip link show br0 &>/dev/null; then
|
||||
ip link add br0 type bridge
|
||||
ip addr add 100.100.0.1/24 dev br0
|
||||
ip link set br0 up
|
||||
echo "Bridge br0 created with IP 100.100.0.1/24"
|
||||
if ! ip link show "$BRIDGE_NAME" &>/dev/null; then
|
||||
ip link add "$BRIDGE_NAME" type bridge
|
||||
ip addr add "$BRIDGE_CIDR" dev "$BRIDGE_NAME"
|
||||
ip link set "$BRIDGE_NAME" up
|
||||
echo "Bridge $BRIDGE_NAME created with IP $BRIDGE_CIDR"
|
||||
fi
|
||||
|
||||
# Create TAP device if not exists
|
||||
if ! ip link show tap0 &>/dev/null; then
|
||||
ip tuntap add tap0 mode tap
|
||||
ip link set tap0 master br0
|
||||
ip link set tap0 up
|
||||
echo "TAP device tap0 created and attached to br0"
|
||||
if ! ip link show "$TAP_NAME" &>/dev/null; then
|
||||
ip tuntap add "$TAP_NAME" mode tap
|
||||
ip link set "$TAP_NAME" master "$BRIDGE_NAME"
|
||||
ip link set "$TAP_NAME" up
|
||||
echo "TAP device $TAP_NAME created and attached to $BRIDGE_NAME"
|
||||
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 100.100.0.0/24 -o "$WAN_IF" -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -s 100.100.0.0/24 -o "$WAN_IF" -j MASQUERADE
|
||||
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 br0 -o "$WAN_IF" -j ACCEPT 2>/dev/null || \
|
||||
iptables -A FORWARD -i br0 -o "$WAN_IF" -j ACCEPT
|
||||
iptables -C FORWARD -i "$WAN_IF" -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
|
||||
iptables -A FORWARD -i "$WAN_IF" -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
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 (10.35.33.230 = IBM i)
|
||||
# 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 10.35.33.230 -j ACCEPT 2>/dev/null || iptables -A FORWARD -d 10.35.33.230 -j ACCEPT
|
||||
iptables -C FORWARD -s 10.35.33.230 -j ACCEPT 2>/dev/null || iptables -A FORWARD -s 10.35.33.230 -j ACCEPT
|
||||
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 IBM i through VM
|
||||
ip route add 10.35.33.230 via 100.100.0.2 2>/dev/null || true
|
||||
# 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: br0 = 100.100.0.1/24"
|
||||
echo "TAP: tap0 attached to br0"
|
||||
echo "Route: 10.35.33.230 via 100.100.0.2 (VM)"
|
||||
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}"
|
||||
|
||||
34
apps/rego-tunnel/build/start-dnsmasq.sh
Normal file
34
apps/rego-tunnel/build/start-dnsmasq.sh
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
BRIDGE_NAME="${BRIDGE_NAME:-br-rego-vpn}"
|
||||
BRIDGE_CIDR="${BRIDGE_CIDR:-100.100.0.1/24}"
|
||||
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}"
|
||||
|
||||
GATEWAY_IP="${BRIDGE_CIDR%%/*}"
|
||||
|
||||
mkdir -p /etc/dnsmasq.d
|
||||
|
||||
cat > /etc/dnsmasq.d/rego.conf <<EOF
|
||||
interface=${BRIDGE_NAME}
|
||||
bind-interfaces
|
||||
except-interface=lo
|
||||
|
||||
dhcp-authoritative
|
||||
log-dhcp
|
||||
|
||||
dhcp-range=${VM_NET_IP},${VM_NET_IP},${LEASE_TIME}
|
||||
dhcp-option=option:router,${GATEWAY_IP}
|
||||
dhcp-option=option:dns-server,${DNS_SERVERS}
|
||||
|
||||
# Static lease for the VM
|
||||
# (VM must use DHCP for this to take effect)
|
||||
dhcp-host=${VM_MAC},${VM_NET_IP}
|
||||
EOF
|
||||
|
||||
echo "[rego-tunnel] dnsmasq on ${BRIDGE_NAME} gateway=${GATEWAY_IP} lease ${VM_MAC} -> ${VM_NET_IP}"
|
||||
exec dnsmasq --no-daemon --conf-file=/etc/dnsmasq.d/rego.conf
|
||||
@@ -23,6 +23,8 @@ fi
|
||||
# Wait for network setup
|
||||
sleep 2
|
||||
|
||||
TAP_NAME="${TAP_NAME:-tap0}"
|
||||
|
||||
exec qemu-system-x86_64 \
|
||||
-enable-kvm \
|
||||
-cpu host \
|
||||
@@ -31,7 +33,7 @@ exec qemu-system-x86_64 \
|
||||
-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 \
|
||||
-netdev tap,id=net0,ifname=tap0,script=no,downscript=no \
|
||||
-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 \
|
||||
|
||||
@@ -13,6 +13,16 @@ 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
|
||||
|
||||
@@ -28,6 +28,78 @@
|
||||
"placeholder": "4",
|
||||
"required": true,
|
||||
"env_variable": "WINDOWS_CPU_CORES"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "VM IP (internal)",
|
||||
"hint": "Internal VM IP on the tap/bridge network",
|
||||
"placeholder": "100.100.0.2",
|
||||
"required": true,
|
||||
"env_variable": "VM_NET_IP"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "VM MAC",
|
||||
"hint": "Used for DHCP reservation (VM must use DHCP)",
|
||||
"placeholder": "52:54:00:12:34:56",
|
||||
"required": true,
|
||||
"env_variable": "VM_MAC"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Bridge name",
|
||||
"hint": "Linux bridge created inside the container for VM networking",
|
||||
"placeholder": "br-rego-vpn",
|
||||
"required": true,
|
||||
"env_variable": "BRIDGE_NAME"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "TAP name",
|
||||
"hint": "Tap interface name used by QEMU",
|
||||
"placeholder": "tap0",
|
||||
"required": true,
|
||||
"env_variable": "TAP_NAME"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Bridge CIDR",
|
||||
"hint": "Bridge address/CIDR assigned inside the container",
|
||||
"placeholder": "100.100.0.1/24",
|
||||
"required": true,
|
||||
"env_variable": "BRIDGE_CIDR"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "VM subnet",
|
||||
"hint": "Subnet that should be NATed out of the container",
|
||||
"placeholder": "100.100.0.0/24",
|
||||
"required": true,
|
||||
"env_variable": "VM_SUBNET"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Target IP (routed via VM)",
|
||||
"hint": "Traffic to this IP is routed via the VM (VPN inside the VM)",
|
||||
"placeholder": "10.35.33.230",
|
||||
"required": true,
|
||||
"env_variable": "TARGET_IP"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "DNS servers",
|
||||
"hint": "DNS servers offered to the VM via DHCP",
|
||||
"placeholder": "1.1.1.1,8.8.8.8",
|
||||
"required": true,
|
||||
"env_variable": "DNS_SERVERS"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "DHCP lease time",
|
||||
"hint": "Lease duration (dnsmasq format, e.g. 12h)",
|
||||
"placeholder": "12h",
|
||||
"required": true,
|
||||
"env_variable": "LEASE_TIME"
|
||||
}
|
||||
],
|
||||
"supported_architectures": ["amd64"]
|
||||
|
||||
@@ -15,9 +15,19 @@ services:
|
||||
environment:
|
||||
- VM_RAM=${WINDOWS_RAM_GB}G
|
||||
- VM_CPUS=${WINDOWS_CPU_CORES}
|
||||
- BRIDGE_NAME=${BRIDGE_NAME:-br-rego-vpn}
|
||||
- TAP_NAME=${TAP_NAME:-tap0}
|
||||
- BRIDGE_CIDR=${BRIDGE_CIDR:-100.100.0.1/24}
|
||||
- VM_NET_IP=${VM_NET_IP:-100.100.0.2}
|
||||
- VM_SUBNET=${VM_SUBNET:-100.100.0.0/24}
|
||||
- TARGET_IP=${TARGET_IP:-10.35.33.230}
|
||||
- VM_MAC=${VM_MAC:-52:54:00:12:34:56}
|
||||
- DNS_SERVERS=${DNS_SERVERS:-1.1.1.1,8.8.8.8}
|
||||
- LEASE_TIME=${LEASE_TIME:-12h}
|
||||
volumes:
|
||||
- /etc/runtipi/user-config/runtipi/rego-tunnel/storage/linux-vm.qcow2:/vm/linux-vm.qcow2
|
||||
- /etc/runtipi/user-config/runtipi/rego-tunnel/shared:/shared
|
||||
- /etc/runtipi/app-data:/shared/app-data
|
||||
networks:
|
||||
- tipi_main_network
|
||||
sysctls:
|
||||
|
||||
Reference in New Issue
Block a user