hhyo / Archery

SQL 审核查询平台
https://archerydms.com
Apache License 2.0
6.11k stars 1.69k forks source link

关于在桥接模式中SSH隧道无法链接的问题 #1362

Open chinahuhq opened 2 years ago

chinahuhq commented 2 years ago

目前遇到的问题/使用障碍

使用版本是1.8.1。 因为archery部署在云下,生产服务器在云上不直接开放数据库端口,需要通过前置机连接,发现一直报connection refused,goinception中有日志,archery中没有日志,经查询 #951 ,发现需要修改docker网络模式,后经过排查代码发现,/sql/utils/ssh_tunnel.py 中存在如下代码 image 尝试将127.0.0.1修改为archery,连接成功

希望如何解决/实现它

希望可以修改为,例如动态配置的方式,在项目部署前期就可以识别到,其次可以添加的项目文档中,作为docker部署目录下要注意的一点,减少使用者构建成本。

其他信息

如果有其他类似的产品功能或者图片信息,可在此提交

jyworker commented 2 years ago

谢谢,果然解决了。 使用docker部署,SSH隧道连接,在SQL上线的时候就会出线这个问题。 我是把那个ssh_tunnel.py 文件映射出来修改,因为是在docker,启动之后就会还原回去。

michael-liumh commented 2 years ago

解决+1,感谢大佬

michael-liumh commented 2 years ago

已添加 FAQ 说明: https://github.com/hhyo/Archery/wiki/FAQ

xuzheng0017 commented 1 year ago

helm部署到k8s的话需要改:

  1. 在env中添加,获取POD的IP添加到环境变量中

    - name: ARCHERY_POD_IP
    valueFrom:
      fieldRef:
        fieldPath: status.podIP
  2. 在/opt/archery/sql/utils/ssh_tunnel.py(需要挂载出来)修改

import os

return os.getenv('ARCHERY_POD_IP'), self.server.local_bind_port

bwcxyk commented 2 months ago

helm部署可以参考如下 values.yml 内容,添加 configmap 并绑定 volume

image:
  repository: hhyo/archery # 如果你有二次开发, 改成你自己的 repo
  tag: v1.11.3 # 改到最新版, 或者你想要的版本

volumeMounts:
  # 请慎重更改以下值, 如需更改建议复制粘贴然后按需求增加键值对
  # 更改后可能会造成部分其他配置失效
  - name: archery-settings
    subPath: local_settings.py
    mountPath: /opt/archery/local_settings.py
  - name: archery-settings
    subPath: soar.yaml
    mountPath: /etc/soar.yaml
  - name: archery-settings
    subPath: analysis_slow_query.sh
    mountPath: /opt/archery/src/script/analysis_slow_query.sh
  - name: archery-settings
    subPath: startup.sh
    mountPath: /opt/archery/src/docker/startup.sh
  - name: archery-settings
    subPath: init-archery.sh
    mountPath: /opt/archery/src/docker/init-archery.sh
  - name: archery-settings
    subPath: createsuperuser.py
    mountPath: /opt/archery/src/docker/createsuperuser.py
  - name: archery-settings
    subPath: ssh_tunnel.py
    mountPath: /opt/archery/sql/utils/ssh_tunnel.py

volumes:
  # 请慎重更改以下值, 如需更改建议复制粘贴然后按需求增加键值对
  # 更改后可能会造成部分其他配置失效
  - name: archery-settings
    configMap:
      name: archery-config
      defaultMode: 420
  - name: archery-download
    hostPath:
      path: /data/archery/downloads
  - name: archery-script
    hostPath:
      path: /data/archery/scripts

configMap:
  enabled: true
  # admin password
  superuser:
    username: admin
    password: archery  # 默认密码, 请尽快修改
    email: "archery@example.com" # 超级管理员邮箱, 建议改成内网的邮箱
  data:
    # local_settings , 可以覆盖之前的所有 django settings 配置, python 代码, 灵活性很高
    # 但是也容易出错, 建议慎重
    local_settings.py: |-
        # -*- coding: UTF-8 -*-
        # override your configs here

    ssh_tunnel.py: |-
      # -*- coding:utf-8 -*-
      """
      @author: EliasChiang
      @license: Apache Licence
      @file: ssh_tunnel.py
      @time: 2020/05/09
      """
      import socket
      from sshtunnel import SSHTunnelForwarder
      from paramiko import RSAKey
      import io

      class SSHConnection(object):
          """
          ssh隧道连接类,用于映射ssh隧道端口到本地,连接结束时需要清理
          """

          def __init__(
              self,
              host,
              port,
              tun_host,
              tun_port,
              tun_user,
              tun_password,
              pkey,
              pkey_password,
          ):
              self.host = host
              self.port = int(port)
              self.tun_host = tun_host
              self.tun_port = int(tun_port)
              self.tun_user = tun_user
              self.tun_password = tun_password

              if pkey:
                  private_key_file_obj = io.StringIO()
                  private_key_file_obj.write(pkey)
                  private_key_file_obj.seek(0)
                  self.private_key = RSAKey.from_private_key(
                      private_key_file_obj, password=pkey_password
                  )
                  self.server = SSHTunnelForwarder(
                      ssh_address_or_host=(self.tun_host, self.tun_port),
                      ssh_username=self.tun_user,
                      ssh_pkey=self.private_key,
                      remote_bind_address=(self.host, self.port),
                  )
              else:
                  self.server = SSHTunnelForwarder(
                      ssh_address_or_host=(self.tun_host, self.tun_port),
                      ssh_username=self.tun_user,
                      ssh_password=self.tun_password,
                      remote_bind_address=(self.host, self.port),
                  )
              self.server.start()

              # 动态获取本地IP
              self.local_ip = self.get_local_ip()

          def __del__(self):
              self.server.close()

          def get_local_ip(self):
              """
              动态获取本地IP地址
              """
              return socket.gethostbyname(socket.gethostname())

          def get_ssh(self):
              """
              获取ssh映射的本地IP和端口
              """
              return self.local_ip, self.server.local_bind_port
LeoQuote commented 2 months ago

@bwcxyk 谢谢你的说明,有空可以提一个pr,判断一下环境变量是否存在,如果存在的话就使用这个值,不存在就fallback 到 localhost

LeoQuote commented 2 months ago

好的,理解你的想法,但我觉得能覆盖k8s的场景,只要保证原功能不变就可以提pr,一直欢迎你的pr

bwcxyk commented 2 months ago

我提交了一个PR https://github.com/hhyo/Archery/pull/2808

合并受阻,我修改了上面的回复,有需要还是参考上面的 values.yml