【问题标题】:How can I automate deployment through multiple ssh firewalls (using PW auth)?如何通过多个 ssh 防火墙自动部署(使用 PW 身份验证)?
【发布时间】:2012-01-19 23:50:24
【问题描述】:

我陷入了一些烦人的境地。

在我的桌面和生产服务器之间有一个机器链。像这样的:

desktop -> firewall 1 -> firewall 2 -> prod_box 1
                                    -> prod_box 2
                                    -> ...

我正在寻找一种通过 ssh 自动部署到产品盒的方法。

我知道通常有多种解决方案,但我的限制是:

  • 不允许对防火墙 2 进行更改
  • 不允许对 prod 框进行配置更改(仅限内容)
  • 防火墙 1 有我的本地用户帐户
  • firewall 2 和 prod 以 root 身份访问
  • 端口 22 是每个链接之间唯一开放的端口

所以,总的来说,我要部署的命令顺序是:

scp archive.tar user@firewall1:archive.tar
ssh user@firewall1
scp archive.tar root@firewall2:/tmp/archive.tar
ssh root@firewall2
scp /tmp/archive.tar root@prod1:/tmp/archive.tar
ssh root@prod1
cd /var/www/
tar xvf /tmp/archive.tar

它比现实中的要复杂一些,但这是对要完成的任务的基本总结。

我已经把我的 ssh 密钥放在了 firewall1:/home/user/.ssh/authorized_keys,所以没问题。

但是,我不能对 firewall2 或 prod 盒执行此操作。

如果我可以在本地从 shell 脚本运行这个(上面的命令),输入我的密码 4 次并完成它,那就太好了。可悲的是,我不知道该怎么做。

我需要一些方法来链接 ssh 命令。我花了整个下午尝试使用 python 来完成这项工作,最终放弃了,因为 ssh 库似乎不支持密码输入式登录。

我可以在这里做什么?

一定有某种库可以用来:

  • 使用密钥文件或动态输入的密码通过 ssh 登录
  • 通过 ssh 隧道链远程远程 shell 命令

我不确定要标记这个问题,所以我暂时将其保留为 ssh,部署。

注意。使用 ssh 隧道和部署工具来推送这些更改会很棒,但是我仍然必须手动登录到每个盒子来设置隧道,而且由于端口阻塞,这无论如何都行不通。

【问题讨论】:

  • 您能否将 bash 脚本永久保留在防火墙 1 和 2 上?
  • 不。这是一个只读文件系统(/tmp 除外;所以我想是的,暂时在 /tmp 我可以...)
  • 哦,这是一个乐趣是吗?一分钟。

标签: deployment ssh


【解决方案1】:

我正在开发 Net::OpenSSH::Gateway,这是我的另一个 Perl 模块 Net::OpenSSH 的扩展,它就是这样做的。

例如:

use Net::OpenSSH;
use Net::OpenSSH::Gateway;

my $gateway = Net::OpenSSH::Gateway->find_gateway(
    proxies => ['ssh://user@firewall1',
                'ssh://password:root@firewall2'],
    backend => 'perl');

for my $host (@prod_hosts) {
    my $ssh = Net::OpenSSH->new($host, gateway => $gateway);
    if ($ssh->error) {
        warn "unable to connect to $host\n";
        next;
    }
    $ssh->scp_put($file_path, $destination)
        or warn "scp for $host failed\n";
}

它需要在两个防火墙中都可以使用 Perl,但没有写入权限或在那里安装任何其他软件。

【讨论】:

  • 根据 OP,如果您还可以展示一个如何使用它的示例,它会更有用。
【解决方案2】:

不幸的是,这不可能作为一个 shell 脚本来实现。我确实尝试过,但ssh 的密码协商需要一个交互式终端,而使用链式ssh 命令是无法获得的。你可以用无密码的密钥来做,但因为那是非常不安全的,而且你无论如何也做不到,没关系。

基本思想是每个服务器发送一个 bash 脚本到下一个,然后激活并发送下一个(依此类推),直到到达最后一个执行分发。
但是,由于这需要在每个阶段都有一个交互式终端,因此您将需要在执行过程中手动执行每个脚本,就像您现在所做的一样,但需要更少的输入。
显然,您需要对它们进行一些自定义,但请尝试以下脚本:

script1.sh

#!/bin/bash

user=doug
firewall1=firewall_1

#Minimise password entries across the board.
tar cf payload1.tar script3.sh archive.tar
tar cf payload2.tar script2.sh payload1.tar
scp payload2.tar ${user}@${firewall1}:payload2.tar
ssh ${user}@${firewall1} "tar xf payload2.tar;chmod +x script2.sh"
echo "Now connect to ${firewall1} and run ./script.sh"

script2.sh

#!/bin/bash

user=root
firewall2=firewall_2

# Minimise password entries
scp payload1.tar ${user}@${firewall2}:/tmp/payload1.tar
ssh ${user}@${firewall2} "cd /tmp;tar xf payload1.tar;chmod +x script3.sh"
echo "Now connect to ${firewall2} and run /tmp/script3.sh"

script3.sh

#!/bin/bash

user=root
hosts="prod1 prod2 prod3 prod4"

for host in $hosts
do
    echo scp archive.tar ${user}@${host}:/tmp/archive.tar
    echo ssh ${user}@${host} "cd /var/www; tar xvf /tmp/archive.tar"
done

每个防火墙确实需要 3 个密码条目,这有点烦人,但这就是生活。
这对你有什么好处?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多