Bash 访问主机&x27;来自docker容器的ssh隧道
使用UbuntuTusty,有一个在远程机器上运行的服务,我可以通过ssh隧道从Bash 访问主机&x27;来自docker容器的ssh隧道,bash,ssh,docker,netcat,ssh-tunnel,Bash,Ssh,Docker,Netcat,Ssh Tunnel,使用UbuntuTusty,有一个在远程机器上运行的服务,我可以通过ssh隧道从localhost:9999通过端口转发访问该服务 我有一个docker容器在运行。我需要从容器中通过主机的隧道访问远程服务 我尝试使用-L 9000:host ip:9999从容器到主机进行隧道传输,然后从容器内通过127.0.0.1:9000访问服务时连接失败。为了检查端口映射是否打开,我尝试 nc-luv-p 9999#在主机上 nc-luv-p 9000#at集装箱 但即使在做的时候,也没有感知到交流
localhost:9999
通过端口转发访问该服务
我有一个docker容器在运行。我需要从容器中通过主机的隧道访问远程服务
我尝试使用-L 9000:host ip:9999
从容器到主机进行隧道传输,然后从容器内通过127.0.0.1:9000
访问服务时连接失败。为了检查端口映射是否打开,我尝试
nc-luv-p 9999#在主机上
nc-luv-p 9000#at集装箱
但即使在做的时候,也没有感知到交流
nc-luv主机ip-p 9000
在容器上
我还尝试通过docker run-p 9999:9000映射端口,但这报告绑定失败,因为主机端口已经在使用(大概是从主机隧道到远程机器)
所以我的问题是
1-我将如何实现连接?我是否需要设置到主机的ssh隧道,或者仅通过docker端口映射就可以实现这一点
2-测试连接是否正常的快速方法是什么?最好是通过bash
谢谢。我想您可以通过在docker跑步中添加
--net=host
来实现。但也请参见此问题:通过--net=host
或通过网络在docker compose中使用主机网络作为容器的网络。\u模式:主机
是一个选项,但这会产生不必要的副作用:(a)您现在在主机系统中公开容器端口,以及(b)您无法再连接到那些未映射到主机网络的容器
在您的情况下,一个快速而干净的解决方案是使您的ssh隧道“可用”到docker容器(例如,通过将ssh绑定到docker0
bridge),而不是在主机环境中公开您的docker容器(如公认的答案中所建议的)
设置隧道:
为此,请通过以下方式检索您的docker0
网桥正在使用的ip:
ifconfig
您将看到如下内容:
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
现在,您需要告诉ssh通过监听定向到端口9000的流量
ssh -L 172.17.0.1:9000:host-ip:9999
如果不设置绑定地址,:9000
将可用于主机的环回接口,而不是docker容器本身
旁注:您还可以将隧道绑定到0.0.0.0
,这将使ssh侦听所有接口
设置应用程序:
在集装箱化应用程序中,使用相同的docker0
ip连接到服务器:172.17.0.1:9000
。现在,通过docker0
网桥路由的流量也将到达您的ssh隧道:)
例如,如果您有一个“DOT.NET Core”应用程序需要连接到位于:9000
的远程数据库,则您的“ConnectionString”将包含“server=172.17.0.19000;”
转发多个连接:
当处理多个传出连接(例如,docker容器需要通过隧道连接到多个远程DB)时,存在几种有效的技术,但简单而直接的方法是创建多个隧道,监听到达不同docker0
桥接端口的流量
在ssh隧道命令中(ssh-L[bind_address:]port:host:hostport][user@]hostname
),绑定地址的port
部分不必与主机的hostport
匹配,因此可以由您自由选择。因此,在docker容器中,只需将流量引导到docker0
网桥的不同端口,然后创建几个ssh隧道命令(您正在侦听的每个端口一个)在这些端口截取数据,然后将其转发到您选择的不同的主机和主机端口。在MacOS上(在v19.03.2
中测试),
1)在主机上创建隧道
ssh -i key.pem username@jump_server -L 3336:mysql_host:3306 -N
2)从容器中,您可以使用host.docker.internal
或docker.for.mac.localhost
或docker.for.mac.host.internal
引用主机
例如
mysql -h host.docker.internal -P 3336 -u admin -p
我想从容器连接到主机上的服务
主机的IP地址正在更改(如果您没有网络访问权限,则没有IP地址)。
从18.03开始,我们建议连接到特殊DNS
namehost.docker.internal
,解析为内部IP地址
由主机使用。这是用于开发目的,在中不起作用
Mac Docker Desktop之外的生产环境
网关也可以通过gateway.docker.internal
访问
我想分享我的解决方案,我的案例如下:我的主机上有一个PostgreSQL SSH隧道,我需要堆栈中的一个容器通过它连接到数据库
我花了几个小时试图找到一个解决方案(Ubuntu+Docker 19.03)我失败了。我没有用iptables
来施巫术,而是修改了Docker引擎本身的设置。我想出了一个解决方案,并震惊于我之前没有想到这一点。最重要的是我不想使用主机
模式:安全第一
我没有尝试允许容器与主机对话,而是简单地在堆栈中添加了另一个服务,这将创建隧道,这样其他容器就可以轻松地与主机对话,而无需任何黑客攻击
在my~/.ssh/config中配置主机后:
Host project-postgres-tunnel
HostName remote.server.host
User sshuser
Port 2200
ForwardAgent yes
TCPKeepAlive yes
ConnectTimeout 5
ServerAliveCountMax 10
ServerAliveInterval 15
以及向堆栈中添加服务:
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
PHP容器开始通过隧道进行通信,没有任何问题:
postgresql://user:password@postgres/db?serverVersion=11&charset=utf8
记住把你的公钥放在
ssh-copy-id project-postgres-tunnel
PING 192.168.0.5 (192.168.0.5) 56(84) bytes of data.
64 bytes from 192.168.0.5 : icmp_seq=1 ttl=37 time=2.17 ms
64 bytes from 192.168.0.5 : icmp_seq=2 ttl=37 time=1.44 ms
64 bytes from 192.168.0.5 : icmp_seq=3 ttl=37 time=1.68 ms
-R [bind_address:]port:host:hostport
mysql -u user -p -h host.docker.internal -P 3300