从docker容器访问主机的ssh隧道

npi*_*pit 32 ssh bash netcat ssh-tunnel docker

使用ubuntu tusty,有一个服务在远程机器上运行,我可以通过ssh隧道从端口转发访问localhost:9999.

我有一个docker容器正在运行.我需要通过主机的隧道从容器内访问该远程服务.

我尝试从容器隧道到主机-L 9000:host-ip:9999,然后127.0.0.1:9000从容器内访问服务无法连接.为了检查端口映射是否打开,我试过了 nc -luv -p 9999 # at host nc -luv -p 9000 # at container

此之后,parag.2但即使 nc -luv host-ip -p 9000 在集装箱内进行操作也没有感知到的沟通

我也试过通过映射端口docker run -p 9999:9000,但是这报告绑定失败,因为主机端口已经在使用中(可能是从主机隧道到远程机器).

所以我的问题是

1 - 如何实现连接?我是否需要设置到主机的ssh隧道,或者这可以通过单独的docker端口映射来实现?

2 - 测试连接是什么的快速方法是什么?通过bash,最好是.

谢谢.

pra*_*upd 22

在 MacOS 上(在 中测试v19.03.2),

1)在主机上创建隧道

ssh -i key.pem username@jump_server -L 3336:mysql_host:3306 -N
Run Code Online (Sandbox Code Playgroud)

2)从容器中,您可以使用host.docker.internaldocker.for.mac.localhostdocker.for.mac.host.internal来引用主机。

例子,

mysql -h host.docker.internal -P 3336 -u admin -p
Run Code Online (Sandbox Code Playgroud)

来自 docker-for-mac 官方文档的说明

我想从容器连接到主机上的服务

主机有一个不断变化的 IP 地址(如果您没有网络访问权限,则没有)。从 18.03 开始​​,我们的建议是连接到特殊的 DNS 名称host.docker.internal,该名称解析为主机使用的内部 IP 地址。这是出于开发目的,不适用于 Docker Desktop for Mac 之外的生产环境。

网关也可以作为gateway.docker.internal.

  • 哇,这太酷了!也已确认在 Docker `18.09.2` 上工作。不知道你能做到这一点。我认为这将允许您访问笔记本电脑本地主机的任何端口,这确实为许多资源打开了大门。 (2认同)
  • 对于 Mac 用户来说,这确实是一个救星,因为“docker0”和“--net=host”都不被支持。谢谢! (2认同)

B12*_*ter 20

通过--net=host或在docker-compose中使用主机网络作为容器的网络network_mode: host是一种选择,但这会产生不必要的副作用:(a)您现在公开主机系统中的容器端口,以及(b)您无法连接到那些容器端口容器不再映射到主机网络.

在您的情况下,一个快速而简洁的解决方案是让您的ssh隧道可用于您的主机系统(即您的docker0网桥),而不是在您的主机环境中公开您的docker容器(如接受的答案中所示).

设置隧道:

要使其正常工作,请检索您的docker0网桥正在使用的IP :

ifconfig
Run Code Online (Sandbox Code Playgroud)

你会看到这样的东西:

docker0   Link encap:Ethernet  HWaddr 03:41:4a:26:b7:31  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
Run Code Online (Sandbox Code Playgroud)

现在你需要告诉ssh 绑定到这个ip来监听通往端口9000的流量

ssh -L 172.17.0.1:9000:host-ip:9999
Run Code Online (Sandbox Code Playgroud)

如果没有设置bind_address,:9000提供给您的主机的loopback接口,而不是本身你的泊坞窗容器.

旁注:您还可以将隧道绑定到0.0.0.0,这将使ssh监听所有接口.

设置您的应用程序:

在您的容器化应用程序中使用相同的docker0ip连接到服务器:172.17.0.1:9000.现在通过你的docker0网桥路由的流量也将到达你的ssh隧道:)

例如,如果您的"DOT.NET Core"应用程序需要连接到位于的远程数据库:9000,则"ConnectionString"将包含"server=172.17.0.1,9000;.

  • 遗憾的是,MacOS 上没有 docker0 https://docs.docker.com/docker-for-mac/networking/#there-is-no-docker0-bridge-on-macos (5认同)
  • 您引用的页面还有一个部分“我想从容器连接到主机上的服务”,其中提到了特殊的 DNS 名称“host.docker.internal”来解析主机 IP(还提到它无法在生产)。有些人还通过环境变量传递本地IP。也许您会在 SO 上找到更详细地涵盖该主题的其他答案。 (3认同)
  • 这太棒了!我已经追了三天了!谢谢你!将 ssh 隧道绑定到 0.0.0.0 修复了它。它最初被省略,可能默认为 127.0.0.1。 (3认同)
  • 这个应该是公认的答案。--net = host确实具有有害的副作用... (2认同)
  • 和@Brandon一样,我感觉到互联网上有一个强烈的随机陌生人对你的爱。非常感谢您的回答!! (2认同)

Mat*_*hew 15

我想你可以通过添加--net=host到docker run来实现.但另请参阅此问题:将主机端口转发到docker容器


emi*_*mix 5

我想分享我的解决方案。我的情况如下:我的主机上有一个 PostgreSQL SSH 隧道,我需要堆栈中的一个容器通过它连接到数据库。

我花了几个小时试图找到解决方案(Ubuntu + Docker 19.03),但失败了。我没有使用巫毒魔法iptables,而是对 Docker 引擎本身的设置进行修改,我想出了一个解决方案,但我很惊讶我没有早点想到这一点。最重要的是我不想使用该host模式:安全第一。

我没有尝试让容器与主机通信,而是简单地向堆栈添加了另一个服务,该服务将创建隧道,以便其他容器可以轻松地进行通信,而无需任何黑客攻击。

在我的内部配置主机后~/.ssh/config

Host project-postgres-tunnel
    HostName remote.server.host
    User sshuser
    Port 2200
    ForwardAgent yes
    TCPKeepAlive yes
    ConnectTimeout 5
    ServerAliveCountMax 10
    ServerAliveInterval 15
Run Code Online (Sandbox Code Playgroud)

并将服务添加到堆栈中:

  postgres:
    image: cagataygurturk/docker-ssh-tunnel:0.0.1
    volumes:
      - $HOME/.ssh:/root/ssh:ro
    environment:
      TUNNEL_HOST: project-postgres-tunnel
      REMOTE_HOST: localhost
      LOCAL_PORT: 5432
      REMOTE_PORT: 5432
    # uncomment if you wish to access the tunnel on the host
    #ports:
    #  - 5432:5432
Run Code Online (Sandbox Code Playgroud)

PHP 容器开始通过隧道进行通信,没有任何问题:

postgresql://user:password@postgres/db?serverVersion=11&charset=utf8
Run Code Online (Sandbox Code Playgroud)

如果您还没有将公钥放入该主机中,请记住:

ssh-copy-id project-postgres-tunnel
Run Code Online (Sandbox Code Playgroud)

我很确定无论使用什么操作系统(MacOS / Linux),这都会起作用。