Skip to content

Commit 77f7177

Browse files
Merge pull request #956 from blegat/fix-podman-pasta-netns
Fix connection for podman with pasta networking
2 parents 7f6b6ab + 594a0d0 commit 77f7177

3 files changed

Lines changed: 73 additions & 20 deletions

File tree

bin/winapps

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ AUTOPAUSE="off"
5454
AUTOPAUSE_TIME="300"
5555
DEBUG="true"
5656
BOOT_TIMEOUT=120
57+
PORT_TIMEOUT=5
5758
HIDEF="on"
5859
RDP_FLATPAK=0
5960
RDP_FLAGS_WINDOWS=""
@@ -764,6 +765,32 @@ function waCheckPortOpen() {
764765
timeout 10 nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null || waThrowExit "$EC_BAD_PORT"
765766
}
766767

768+
# Name: 'waSelectPodmanRoute'
769+
# Role: Determine how FreeRDP can reach the RDP port of the Windows container.
770+
# Note: Depending on the podman version and network backend, the RDP port is
771+
# reachable at the container IP from within the rootless network namespace
772+
# (netavark bridge networking), at localhost from within the rootless
773+
# network namespace (slirp4netns port forwarding), or at localhost from
774+
# the host network namespace (rootlessport/pasta port publishing).
775+
# Probe these routes in order and use the first one that works, modifying
776+
# 'RDP_IP' and 'FREERDP_COMMAND' accordingly.
777+
function waSelectPodmanRoute() {
778+
local CONTAINER_IP=""
779+
CONTAINER_IP=$(podman inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CONTAINER_NAME" 2>/dev/null)
780+
781+
if [ -n "$CONTAINER_IP" ] && timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$CONTAINER_IP" "$RDP_PORT" &>/dev/null; then
782+
dprint "RDP PORT REACHABLE AT CONTAINER IP '${CONTAINER_IP}' WITHIN ROOTLESS NETWORK NAMESPACE."
783+
RDP_IP="$CONTAINER_IP"
784+
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
785+
elif timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null; then
786+
dprint "RDP PORT REACHABLE AT '${RDP_IP}' WITHIN ROOTLESS NETWORK NAMESPACE."
787+
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
788+
else
789+
dprint "RDP PORT UNREACHABLE WITHIN ROOTLESS NETWORK NAMESPACE. CONNECTING FROM HOST NETWORK NAMESPACE."
790+
waCheckPortOpen
791+
fi
792+
}
793+
767794
# Name: 'waRunCommand'
768795
# Role: Run the requested WinApps command.
769796
function waRunCommand() {
@@ -1009,11 +1036,6 @@ if [[ ! -z "$RDP_ASKPASS" ]]; then
10091036
unset RDP_PASSWORD_ARG
10101037
fi
10111038

1012-
# If using podman backend, modify the FreeRDP command to enter a new namespace.
1013-
if [ "$WAFLAVOR" = "podman" ]; then
1014-
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
1015-
fi
1016-
10171039
if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
10181040
RDP_IP="$DOCKER_IP"
10191041
waCheckContainerRunning
@@ -1026,7 +1048,11 @@ else
10261048
waThrowExit "$EC_INVALID_FLAVOR"
10271049
fi
10281050

1029-
waCheckPortOpen
1051+
if [ "$WAFLAVOR" = "podman" ]; then
1052+
waSelectPodmanRoute
1053+
else
1054+
waCheckPortOpen
1055+
fi
10301056
waTimeSync
10311057
waRunCommand "$@"
10321058

compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ services:
3333
# - 3389:3389/udp
3434
cap_add:
3535
- NET_ADMIN # Add network permission
36+
- NET_RAW # Required by dnsmasq for dockur's NAT networking; without it the container falls back to user-mode (passt) networking, which breaks RDP port forwarding from the host
3637
stop_grace_period: 120s # Wait 120 seconds before sending SIGTERM when attempting to shut down the Windows VM.
3738
restart: on-failure # Restart the Windows VM if the exit code indicates an error.
3839
volumes:

setup.sh

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,32 @@ function waCheckPortOpen() {
10991099
echo -e "${DONE_TEXT}Done!${CLEAR_TEXT}"
11001100
}
11011101

1102+
# Name: 'waSelectPodmanRoute'
1103+
# Role: Determine how FreeRDP can reach the RDP port of the Windows container.
1104+
# Note: Depending on the podman version and network backend, the RDP port is
1105+
# reachable at the container IP from within the rootless network namespace
1106+
# (netavark bridge networking), at localhost from within the rootless
1107+
# network namespace (slirp4netns port forwarding), or at localhost from
1108+
# the host network namespace (rootlessport/pasta port publishing).
1109+
# Probe these routes in order and use the first one that works, modifying
1110+
# 'RDP_IP' and 'FREERDP_COMMAND' accordingly.
1111+
function waSelectPodmanRoute() {
1112+
local CONTAINER_IP=""
1113+
CONTAINER_IP=$(podman inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "WinApps" 2>/dev/null)
1114+
1115+
if [ -n "$CONTAINER_IP" ] && timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$CONTAINER_IP" "$RDP_PORT" &>/dev/null; then
1116+
echo -e "RDP port reachable at container IP '${CONTAINER_IP}' within the rootless network namespace."
1117+
RDP_IP="$CONTAINER_IP"
1118+
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
1119+
elif timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null; then
1120+
echo -e "RDP port reachable at '${RDP_IP}' within the rootless network namespace."
1121+
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
1122+
else
1123+
echo -e "RDP port unreachable within the rootless network namespace. Connecting from the host network namespace."
1124+
waCheckPortOpen
1125+
fi
1126+
}
1127+
11021128
# Name: 'waCheckRDPAccess'
11031129
# Role: Tests if Windows is accessible via RDP.
11041130
function waCheckRDPAccess() {
@@ -1710,11 +1736,6 @@ function waInstall() {
17101736
RDP_IP="$DOCKER_IP"
17111737
fi
17121738

1713-
# If using podman backend, modify the FreeRDP command to enter a new namespace.
1714-
if [ "$WAFLAVOR" = "podman" ]; then
1715-
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
1716-
fi
1717-
17181739
if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
17191740
# Check if Windows is powered on.
17201741
waCheckContainerRunning
@@ -1742,8 +1763,13 @@ function waInstall() {
17421763
return "$EC_INVALID_FLAVOR"
17431764
fi
17441765

1745-
# Check if the RDP port on Windows is open.
1746-
waCheckPortOpen
1766+
# Determine how FreeRDP can reach the RDP port of the Windows container.
1767+
if [ "$WAFLAVOR" = "podman" ]; then
1768+
waSelectPodmanRoute
1769+
else
1770+
# Check if the RDP port on Windows is open.
1771+
waCheckPortOpen
1772+
fi
17471773

17481774
# Test RDP access to Windows.
17491775
waCheckRDPAccess
@@ -1907,11 +1933,6 @@ function waAddApps() {
19071933
RDP_IP="$DOCKER_IP"
19081934
fi
19091935

1910-
# If using podman backend, modify the FreeRDP command to enter a new namespace.
1911-
if [ "$WAFLAVOR" = "podman" ]; then
1912-
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
1913-
fi
1914-
19151936
if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
19161937
# Check if Windows is powered on.
19171938
waCheckContainerRunning
@@ -1939,8 +1960,13 @@ function waAddApps() {
19391960
return "$EC_INVALID_FLAVOR"
19401961
fi
19411962

1942-
# Check if the RDP port on Windows is open.
1943-
waCheckPortOpen
1963+
# Determine how FreeRDP can reach the RDP port of the Windows container.
1964+
if [ "$WAFLAVOR" = "podman" ]; then
1965+
waSelectPodmanRoute
1966+
else
1967+
# Check if the RDP port on Windows is open.
1968+
waCheckPortOpen
1969+
fi
19441970

19451971
# Test RDP access to Windows.
19461972
waCheckRDPAccess

0 commit comments

Comments
 (0)