containers / podman

Podman: A tool for managing OCI containers and pods.
https://podman.io
Apache License 2.0
23.85k stars 2.42k forks source link

host.containers.internal accessing host port served by Windows app #14933

Open qrli opened 2 years ago

qrli commented 2 years ago

Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)

/kind feature

Description

This is about latest Podman for Windows and host.containers.internal. The capability of host.containers.internal seems to differ from docker's. My tests have excluded the firewall factor.

I'm guessing it may because host.containers.internal refers to the Fedora host than Windows host.

On the other hand, WSL 2 has a special domain name $(hostname).local to access the Windows part. ($hostname refers to Windows host name rather than Linux's.)

This surprise me. I cannot explain why. But at least I got a way to access Windows app ports from podman. The tricky thing is that, unlike host.docker.internal which I can use for all scenarios, I have to split config depending on what it is accessing to.

I wish both of them work out of box. Or, at least one of them works. Thanks for the good work.

Steps to reproduce the issue:

1.

2.

3.

Describe the results you received:

Describe the results you expected:

Additional information you deem important (e.g. issue happens only occasionally):

Output of podman version:

Client:       Podman Engine
Version:      4.1.1
API Version:  4.1.1
Go Version:   go1.16.15
Git Commit:   f73d8f8875c2be7cd2049094c29aff90b1150241
Built:        Wed Jun 15 21:17:12 2022
OS/Arch:      windows/amd64

Server:       Podman Engine
Version:      4.2.0-rc1
API Version:  4.2.0-rc1
Go Version:   go1.16.15
Built:        Tue Jul 12 04:58:55 2022
OS/Arch:      linux/amd64

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.27.0-dev
  cgroupControllers: []
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: conmon-2.1.1-2.fc35.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.1, commit: '
  cpuUtilization:
    idlePercent: 99.9
    systemPercent: 0.05
    userPercent: 0.05
  cpus: 8
  distribution:
    distribution: fedora
    variant: container
    version: "35"
  eventLogger: file
  hostname: BGC-QLi7-S
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 5.10.102.1-microsoft-standard-WSL2
  linkmode: dynamic
  logDriver: journald
  memFree: 16790450176
  memTotal: 26781720576
  networkBackend: netavark
  ociRuntime:
    name: crun
    package: crun-1.4.5-2.fc35.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.4.5
      commit: c381048530aa750495cf502ddb7181f2ded5b400
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  remoteSocket:
    exists: true
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: true
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.12-2.fc35.x86_64
    version: |-
      slirp4netns version 1.1.12
      commit: 7a104a101aa3278a2152351a082a6df71f57c9a3
      libslirp: 4.6.1
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.3
  swapFree: 7516192768
  swapTotal: 7516192768
  uptime: 136h 40m 29.00s (Approximately 5.67 days)
plugins:
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  volume:
  - local
registries:
  search:
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - docker.io
  - quay.io
store:
  configFile: /home/user/.config/containers/storage.conf
  containerStore:
    number: 22
    paused: 0
    running: 22
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/user/.local/share/containers/storage
  graphRootAllocated: 269490393088
  graphRootUsed: 5464207360
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 22
  runRoot: /run/user/1000/containers
  volumePath: /home/user/.local/share/containers/storage/volumes
version:
  APIVersion: 4.2.0-rc1
  Built: 1657573135
  BuiltTime: Tue Jul 12 04:58:55 2022
  GitCommit: ""
  GoVersion: go1.16.15
  Os: linux
  OsArch: linux/amd64
  Version: 4.2.0-rc1

Package info (e.g. output of rpm -q podman or apt list podman):

(paste your output here)

Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide? (https://github.com/containers/podman/blob/main/troubleshooting.md)

Yes

Additional environment details (AWS, VirtualBox, physical, etc.):

mheon commented 2 years ago

Any chance you can find out what IP address Docker's host.containers.internal points to, versus ours? Knowing how their configuration differs would help significantly.

qrli commented 2 years ago

In podman: 172.24.126.173 host.containers.internal nameserver 172.24.112.1 // It is what WSL's $(hostname).local resolves to.

In Docker: host.docker.internal resolves to 192.168.65.2 while nameserver 192.168.65.5

I think docker is playing some magic here. It uses its own nameserver than WSL's, and the host.docker.internal access is forwarded to Windows side without roadblock of Windows Firewall. (As it uses its own nameserver, WSL's $(hostname).local does not work in docker. But it is OK as host.docker.internal works for all scenarios.)

On the other hand, podman's seem to be within the WSL realm, following what's provided by WSL. In this case, I think the WSL's $(hostname).local should work, but it does not work with ports served by podman, strangely.

qrli commented 2 years ago

I think there are 2 possible paths which podman for windows can choose from:

  1. the Docker's approach which creates a secret tunnel back to Windows. This makes it feel rather native on the Windows side. But this may be non-trivial to implement.
  2. the WSL path so that host.containers.internal is equivalent to WSL's $(hostname).local. (Of course need to address the issue of access podman exposed ports.) The benefit is that it will be consistent with WSL and inherit any new feature of WSL, while the drawback is that WSL has not yet solved the Windows Firewall issue, which treats WSL ethernet as public network, thus blocks non-standard port access from WSL by default.
github-actions[bot] commented 2 years ago

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] commented 2 years ago

A friendly reminder that this issue had no activity for 30 days.

qrli commented 1 year ago

Some update about latest status:

jolyons123 commented 1 year ago

Some update about latest status:

* It seems "$(hostname).local" is no longer supported by WSL

* nameserver IP (the 172.* IP of the Windows host for WSL) still works

* There are people saying the access is no longer blocked as part of supporting WSLg - I tried but no success. Access from WSL2 to high ports of Windows side is still blocked by Windows Firewall by default. But it can be unblocked by executing `Set-NetFirewallProfile -Name Public -DisabledInterfaceAliases "vEthernet (WSL)"`

Thanks for the info.

I have a similar problem: From within the podman VM I need to access a Windows port (This is a cntlm proxy listening on :3128 on Windows). Is there any way you found to make a connection from within podman VM to Windows without having to touch firewall settings?

qrli commented 10 months ago

Pops this up a bit. There is still no change on this.

Any progress of WSL does not help either, because host.containers.internal binds to the WSL IP, which cannot access anything on the Windows side. It is basically the same as installing Linux version of Podman inside WSL, although we expect Podman Windows to be replacement of Docker on Windows.

I think host.containers.internal should bind to gateway IP of WSL, which is show in the first line of ip route show. See https://learn.microsoft.com/en-us/windows/wsl/networking#mirrored-mode-networking

It may still be blocked by Windows Firewall by default when accessing ports served from Windows side, but there are already easy ways to allow it.

randomstuff commented 2 months ago

Terrible workaround follows.

Get a shell on the podman VM:

podman machine ssh

From this shell:

sudo yum install socat
ip route
socat TCP-LISTEN:8000,fork TCP:$ip:8000

where $ip is the address found in ip route (default via …)

timohermans commented 2 months ago

Is there any progress on this?

timohermans commented 2 months ago

Terrible workaround follows.

Get a shell on the podman VM:

podman machine ssh

From this shell:

sudo yum install socat
ip route
socat TCP-LISTEN:8000,fork TCP:$ip:8000

where $ip is the address found in ip route (default via …)

@randomstuff I suppose you'll have to do this for every port you want to expose? :)

yunnysunny commented 1 month ago

I modified the .wslconfig , and added such configuration:

[wsl2]
networkingMode=mirrored

Then restarted wsl and podman machine, I found that telnet host.containers.internal 3001 was refused, but when I tried telnet 127.0.0.1 3001 , it worked.