我似乎无法通过 SSH 隧道远程连接到我的数据库。我对这些都比较陌生,所以我希望有人能给我一些指点。
我有一台安装了 Docker 的云服务器,并且正在运行一个数据库容器(用于另一项服务 Wordpress):
撰写.yaml
services:
db:
image: mariadb:latest
container_name: database
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_root_password
- db_password
ports:
- '3306:3306'
expose:
- 3306
数据库容器运行良好,并且我的其余 Docker 服务与数据库交互没有任何问题。
如果我通过 SSH 连接到远程机器,我可以通过主机上的 MariaDB 客户端访问 Docker 环境中的数据库,因为端口 3306 从 Docker 容器转发到主机:
➜ ssh -i mykey user@hostname
➜ docker compose up -d
➜ nc -vz localhost 3306
Connection to localhost (::1) 3306 port [tcp/mysql] succeeded!
➜ mariadb -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 15
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
但是我无法使用本地数据库客户端 (DBeaver)。我已在客户端中设置了 SSH 隧道,使用的凭据与通过 CLI 连接到主机时使用的凭据相同。
在我的数据库客户端中测试 SSH 连接成功。但是,一旦建立 SSH 隧道,与数据库的连接就会失败:
Could not connect to 127.0.0.1:31987 : unexpected end of stream, read 0 bytes from 4 (socket was closed by server)
有人能指点我哪里做错了吗?这是远程访问数据库的正确方法吗?
我是否对 SSH 隧道的工作原理做出了一些错误的假设?我假设一旦建立隧道,它就会连接到我的远程主机上的端口 3306,就好像客户端实际上在远程主机上一样。我也不确定端口“31987”来自哪里,但我猜它是客户端用于连接端口 3306 的临时端口,但也许我也错了?
我不希望数据库端口公开访问,因此对远程主机上端口 3306 的远程访问受到防火墙的保护。
我知道我可以安装一个新的 docker 服务、sshtunnel,然后直接通过隧道进入该服务,但我不明白为什么在通过隧道进入主机时无法连接...
提前感谢任何提示!
答案1
我建议在 docker-compose 中使用 network_mode host。因为默认情况下,docker 会创建一个很难建立隧道的单独网络。
services:
db:
image: mariadb:latest
container_name: database
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_root_password
- db_password
networks:
proxy:
aliases:
- test.mysql.docker
sshtunnel:
restart: always
image: ghcr.io/linuxserver/openssh-server
container_name: sshtunnel
ports:
- 2222:2222
volumes:
- ~/.ssh/id_rsa.pub:/etc/tunnel/id_rsa.pub
- ./openssh/sshd_config:/config/ssh_host_keys/sshd_config
environment:
- PUBLIC_KEY_FILE=/etc/tunnel/id_rsa.pub
- USER_NAME=proxy
- SUDO_ACCESS=true
networks:
- proxy
networks:
proxy:
driver: bridge
name: proxy
看这里: https://madewithlove.com/blog/using-an-ssh-tunnel-to-connect-to-your-dev-mysql-with-docker/