V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
eggt
V2EX  ›  程序员

如何通过跳板机无缝连接需要跳转的服务器?

  •  
  •   eggt · 2021-07-23 09:16:34 +08:00 · 8297 次点击
    这是一个创建于 1217 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本机( mac 环境) 与跳板机 A 是通的,A 与 B, C, D ... 是通的,但 本机与 B,C,D 之间是不直通的,请教下,如何通过一些配置或工具,达到 本机全局情况下与 B,C,D 无缝连接(自动通过 A 中转连接)

    A, B, C, D.... 均是 linux 服务器
    51 条回复    2021-07-24 11:12:24 +08:00
    zwy100e72
        1
    zwy100e72  
       2021-07-23 09:22:41 +08:00
    先搭建 本机 - A 的隧道( SSH / VPN 均可)
    再通过隧道连接其他机器
    Ariver
        2
    Ariver  
       2021-07-23 09:28:42 +08:00
    一楼正解。
    有的跳板机是 windows,烦死了。
    lcdtyph
        3
    lcdtyph  
       2021-07-23 09:33:25 +08:00 via iPhone   ❤️ 1
    ssh -J jumpserver targetserver

    可以写进 .ssh/config
    huoshen
        4
    huoshen  
       2021-07-23 09:34:32 +08:00
    gost 直接端口转发中转
    mrxun1998
        5
    mrxun1998  
       2021-07-23 09:34:49 +08:00
    ssh -t -t B_user@B_ip -p 22 -o ProxyCommand='ssh -t -t A_user@A_ip -p 22 -W %h:%p''
    两边都配置成密钥登录的话一条命令就能通过 A 登录 B 了
    liyunyang
        6
    liyunyang  
       2021-07-23 09:35:36 +08:00
    同问,有没有详细教程~
    公司的堡垒机限制太烦了,mac 环境被迫只能先远程 window 桌面,再连接 Linux 服务器
    重点是 mac 的 Windows 远程桌面工具( Microsoft Remote Desktop )实在难用,被迫安装了 pd 虚拟机。。
    神烦
    eggt
        7
    eggt  
    OP
       2021-07-23 09:39:12 +08:00
    @lcdtyph 这只针对会话吧?我想找个全局都真通的方案
    @mrxun1998
    jk1030
        8
    jk1030  
       2021-07-23 09:51:50 +08:00
    我也被搞得很烦 假如 A 是 windows b,c,d 是 lunix 这个时候应该怎么联通
    huoshen
        9
    huoshen  
       2021-07-23 09:52:25 +08:00
    啥叫全局都真通?
    shynome
        10
    shynome  
       2021-07-23 09:59:52 +08:00 via Android
    可以使用 tinc 组网,但前提是你能在 a, b, c, d 机器上安装软件
    组网的话以 a 机器为中心,本机和 b, c, d 都连接到 a,连接成功后,本机和 a, b, c, d 都可以互相访问就像在同一个局域网内(记得选一个不冲突的网段
    whale
        11
    whale  
       2021-07-23 10:04:10 +08:00
    不直通的意思是 A,B,C,D 是同一个 VPC,就 A 开启了外网访问?
    网络环境不清楚,不好给方案。
    eggt
        12
    eggt  
    OP
       2021-07-23 10:05:04 +08:00
    @huoshen 打错了,是直通😂
    eggt
        13
    eggt  
    OP
       2021-07-23 10:05:48 +08:00
    @shynome 如果要在 b,c,d 上都要安装软件,这不被允许
    LLaMA2
        14
    LLaMA2  
       2021-07-23 10:08:49 +08:00   ❤️ 4
    全程不使用额外的工具,完全依赖各个平台已有的工具,如下:
    假定本机的 ip 是 192.168.1.1,跳板机 windows (代号 A )是 192.168.2.1,生产机( BCD )是 192.168.3.1 、192.168.3.2 、192.168.3.3

    先在 A 上使用 Windows 命令行配置端口映射如下
    netsh interface portproxy add v4tov4 listenport=40022 connectport=22 connectaddress=192.168.3.1
    netsh interface portproxy add v4tov4 listenport=50022 connectport=22 connectaddress=192.168.3.2
    netsh interface portproxy add v4tov4 listenport=60022 connectport=22 connectaddress=192.168.3.3

    然后本机想要连接 B 机器就是 ssh [email protected] -p 40022
    然后本机想要连接 C 机器就是 ssh [email protected] -p 50022
    然后本机想要连接 D 机器就是 ssh [email protected] -p 60022
    yuanzi0
        15
    yuanzi0  
       2021-07-23 10:09:11 +08:00
    mmh?
    shynome
        16
    shynome  
       2021-07-23 10:11:09 +08:00 via Android
    @eggt 那只能在本机写路由转发了,将特定 ip 的访问转发到 a 服务器上,Linux 我知道能做到,Mac 不知道好不好做
    PandaRun
        17
    PandaRun  
       2021-07-23 10:14:38 +08:00
    ssh tunnel
    LLaMA2
        18
    LLaMA2  
       2021-07-23 10:16:56 +08:00
    linux 上端口转发
    # 将 A 机 40022 端口的流量转发至 B 机器 192.168.3.1 的 22 端口
    firewall-cmd --permanent --add-forward-port=port=40022:proto=tcp:toaddr=192.168.3.1:toport=22

    注意
    开启防火墙伪装:firewall-cmd --add-masquerade --permanent //开启后才能转发端口
    其他问题请搜索 firewalld 端口转发
    thet
        19
    thet  
       2021-07-23 10:24:02 +08:00
    .ssh/config 里面配置
    host jump
    user xxxx
    hostname xxx.xxx.xxx.xxx
    port xxxx
    identityfile jumpserver.pem

    host server-a
    user xxxx
    hostname xxx.xxx.xxx.xxx
    proxyjump jump
    identityfile jump.pem

    配置好后,用 ssh server-a 就可以直接登录了,可以搜一下 ssh proxyjump 用法
    dynastysea
        20
    dynastysea  
       2021-07-23 10:32:13 +08:00
    了解下 http tunnel,网上有现成的脚本
    libook
        21
    libook  
       2021-07-23 10:42:33 +08:00
    本机 SSH 到 A,然后在 A 的 Shell 环境下直接 SSH 到 B 、C 、D 就可以。。。

    要是希望非 SSH 协议连到 B 、C 、D,可以在 A 上做几个映射到 B 、C 、D 上相应端口的转发规则,本地直接连接 A 上的对应端口就会自动被 A 转发到 B 、C 、D 上的特定端口上。这个可以去搜一搜 iptables 或者 SSH 隧道。

    VPN 能让你的本机和 A 、B 、C 、D 在一个网络里,这样是最方便的,不用配置特定端口。
    cpstar
        22
    cpstar  
       2021-07-23 10:53:38 +08:00
    方法 1,SSH Tunnel,通过 A 的 ssh 建立 tunnel 到 B 、C 、D
    方法 2,端口映射,A 上开(比如 60022 、60122 、60222 之类)端口映射 B 、C 、D 的 22 。

    方法 1 安全一些,毕竟只暴露 A 的 22,B\C\D 的 22 不直接暴露,但是就是每次建立的时候,费点劲;
    方法 2 省事一些,直接连接连接

    方法 1,用 ssh 命令实现;方法 2 在 A 上用 iptables 或者 firewall-cmd 实现。两者都需要打开 port-forwarding,具体找文章。
    xylophone21
        23
    xylophone21  
       2021-07-23 11:09:09 +08:00
    @zwy100e72
    @lcdtyph
    @huoshen
    @mrxun1998
    @ye4tar
    @ye4tar
    @thet
    @libook
    @cpstar

    这些代理,直通的方案,会不会降低系统的安全性?看起来这些方案里,A 机器都是做了数据转发,这样的话 A 就有可能并不知道 B 、C 、D 执行了什么命令,也就无从做审计,这样的话,堡垒机是不是就没有意义了?
    libook
        24
    libook  
       2021-07-23 11:15:48 +08:00
    @xylophone21 #23 本来本地机器和 B 、C 、D 之间是隔离的,所以具备一定的安全性,你用任何方式打通了肯定就失去了对应的安全保障。这是个取舍问题。

    如果你希望记录本地机对 BCD 的网络调用情况,可以开网络日志进行审计,但你只能审计到网络连接的建立和断开以及对应的端口情况。

    如果是想知道具体做了哪些操作,就得做对应的协议的日志记录,比如 Shell 的日志、Web 日志。

    如果 A 是堡垒机,那么用本机直接操作 BCD 就是个伪命题,堡垒机的存在就是为了不让你在本机操作 BCD 的,必须登录到堡垒机 A,然后在堡垒机上再连接 BCD 进行操作,堡垒机 A 负责记录你的所有操作,甚至还会有录屏。

    安全和便利性是矛盾的,两者只能取其一。
    lavanil
        25
    lavanil  
       2021-07-23 13:23:33 +08:00
    sshuttle -NHr user@B
    beginor
        26
    beginor  
       2021-07-23 13:34:16 +08:00 via Android
    如果 堡垒机 a 能 ssh 转发的话可以这样,ssh 本地端口转发 `ssh -TNL 127.0.0.1:2022:server-b:22 user@a` 然后再 `ssh
    -p 2022 [email protected]`, 就是登录 b 了, 不用安装任何第三方软件
    xuboying
        27
    xuboying  
       2021-07-23 13:40:05 +08:00
    真通只有 VPN 拨入啊。其他方案都是端口转发也就是通一个端口。
    其实这就是一个 AB 问题,OP 根本没有讲清楚业务需求,直接要一个最全最广的方案,相应的就是安全性或者部署复杂度的牺牲。
    xylophone21
        28
    xylophone21  
       2021-07-23 15:27:56 +08:00
    @libook 对,所以我感觉这题是不是讨论偏了?无缝连接是个伪需求,因为要方便,要无缝连接,直接开放端口就好了,之所以不开放就是为了安全,才加堡垒机。如果又在堡垒机上开无缝连接,那么堡垒机就没有价值了。
    mringg
        29
    mringg  
       2021-07-23 15:34:23 +08:00
    感觉还是老老实实用跳板机,通过打洞的方式访问服务器,跳板机就失去意义了。并且可能会带来新的安全隐患。
    Volekingsg
        30
    Volekingsg  
       2021-07-23 15:34:26 +08:00
    我是往 A 开了个 SOCKS 代理,外网时自动走这个代理规则连 B, C, D 。
    Xusually
        31
    Xusually  
       2021-07-23 15:38:38 +08:00
    直通的话,跳板机的作用就大打折扣了。
    knightdf
        32
    knightdf  
       2021-07-23 15:50:39 +08:00
    ssh 隧道
    no1xsyzy
        33
    no1xsyzy  
       2021-07-23 16:03:14 +08:00
    那就 ssh A -t ssh [B|C|D] -t 啊(
    eggt
        34
    eggt  
    OP
       2021-07-23 16:07:19 +08:00
    @Volekingsg 我使用 clashx 创建了一个 scoket 代理,好像没用作用
    cpstar
        35
    cpstar  
       2021-07-23 16:31:49 +08:00
    哦,堡垒机啊,那你应当选用具有审计功能的堡垒机。其实你这个 A 根本就不能称之为“堡垒机”,能 SSH 上去,然后再 SSH 到别的地方,审计,审啥啊,靠系统那点日志?得了吧。
    再说了,A 能 SSH,你能确保 ssh 到 A 的不打洞?一旦打动,任何所谓的审计措施全都失效。
    xiang0818
        36
    xiang0818  
       2021-07-23 16:53:01 +08:00
    上面说了这么多,其实直接用 finalShell 建立隧道就可以了,哈哈哈 https://www.hualigs.cn/image/60fa811834c88.jpg
    Rache1
        37
    Rache1  
       2021-07-23 17:08:49 +08:00
    @liyunyang 我觉得 RDP 还行呀,日常操作还是可以的,之前试过用 VNC 连 MAC mini 那才叫难受 😂
    libook
        38
    libook  
       2021-07-23 17:53:15 +08:00
    @xylophone21 #28 堡垒机的价值就是约束管理员只能登录到堡垒机上对受保护资源进行操作,然后堡垒机记录相应的操作供审计。
    所以主题里描述的需求是和堡垒机的价值相悖的,要么去除堡垒机 A 然后让 BCD 可以被自由访问,要么老老实实登录到堡垒机 A 上再登录 BCD 进行操作,没有第三种方案。
    github2020
        39
    github2020  
       2021-07-23 19:19:17 +08:00
    不考虑安全,单纯为了绕过限制、自己方便的话,可以:
    mac -> linux 透明代理(搞个 r2s 之类便携的) -> A 上的 ssh 或 socks5 代理-> B/C/D
    透明代理可以用 gost/glider 之类
    guanyin8cnq12
        40
    guanyin8cnq12  
       2021-07-23 19:31:35 +08:00
    从 a 到 c 用 haproxy,代理 tcp 链接。从 a 到 d,经过 c,2 层代理,没搞过。
    Volekingsg
        41
    Volekingsg  
       2021-07-23 19:42:41 +08:00
    @eggt #34
    Volekingsg
        42
    Volekingsg  
       2021-07-23 19:45:43 +08:00
    @eggt #34
    大概步骤:
    1. ssh -fnNT -D 1080 username@ip -p port
    2. proxies 下面添加 socks 代理:
    proxies:
    - name: "name"
    type: socks5
    server: 127.0.0.1
    port: 1080
    udp: true
    3. 添加策略组和规则
    proxy-groups:
    - name: local
    type: select
    proxies:
    - name
    - DIRECT
    rules:
    - 'IP-CIDR,192.168.14.14/32,local'
    - 'IP-CIDR,192.168.14.16/32,local'
    4. 另外 clashx 没有增强模式,需要给 ssh 配置代理,或者使用 clashx pro
    Host *
    ...
    Proxycommand nc -X 5 -x 127.0.0.1:7890 %h %p
    ...
    Volekingsg
        43
    Volekingsg  
       2021-07-23 20:38:37 +08:00
    @Volekingsg #42 或者连接不上再走代理
    Volekingsg
        44
    Volekingsg  
       2021-07-23 20:39:01 +08:00
    @Volekingsg #42 或者连接不上再走代理
    Match exec "echo %h | grep '192\|124' | grep -q -v '208' && ! timeout 1 nc -z %h %p &> /dev/null"
    ProxyCommand nc -X 5 -x 127.0.0.1:7890 %h %p
    eggt
        45
    eggt  
    OP
       2021-07-23 21:16:36 +08:00 via iPhone
    @Volekingsg 感谢老哥,我下周试试
    apeople
        46
    apeople  
       2021-07-23 21:40:43 +08:00
    @liyunyang 我和你的情况简直一模一样,Microsoft Remote Desktop 经常连不上 mac 上的文件夹。
    akira
        47
    akira  
       2021-07-24 00:55:22 +08:00
    跳板机就是让你 从跳板机去访问目标服务器的呀,还是你对跳板机理解有偏差了
    yuruizhe
        48
    yuruizhe  
       2021-07-24 02:11:43 +08:00 via iPhone
    expect 脚本
    jinwyp
        49
    jinwyp  
       2021-07-24 03:17:06 +08:00
    wireguard linux 内核自带 可以用我的脚本安装 wget --no-check-certificate https://raw.githubusercontent.com/jinwyp/one_click_script/master/install_kernel.sh && chmod +x ./install_kernel.sh && ./install_kernel.sh
    baoshuo
        50
    baoshuo  
       2021-07-24 09:54:37 +08:00
    我用 Termius 解决这个问题,添加一个 Snippet 到主机的设置就行了
    jie123168
        51
    jie123168  
       2021-07-24 11:12:24 +08:00   ❤️ 1
    用 expect 脚本, 我现在一直这么用的, 分享一个示例吧:
    ```
    #!/usr/bin/expect -f
    set user [lindex $argv 0];
    set password [lindex $argv 1];
    set server [lindex $argv 2];
    set ip 跳板机域名或 IP
    set port 22
    set timeout -1

    spawn ssh -p $port $user@$ip
    expect {
    "*yes/no" { send "yes\r"; exp_continue}
    "*跳板机域名或 IP's password: " {
    send "$password\r";
    exp_continue
    }
    "*Last login*" { exp_continue}
    "*Welcome to Alibaba Cloud*" { exp_continue}
    "Enter code*" {
    set code [gets stdin]
    send "$code\r"
    exp_continue
    }
    "*@跳板机主机名*" { send "ssh $server\r"; exp_continue }
    "*'s ssh password*" {send "$password\r"}
    }


    interact
    expect eof
    ```
    这里面先登陆跳板机, 然后手动输入了动态验证码, 再通过 ssh 登陆真实服务器.
    参数是跳板机的用户名, 密码. 及远程服务器的(主机名或 IP)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1073 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 19:03 · PVG 03:03 · LAX 11:03 · JFK 14:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.