【问题标题】:Ansible: how to clone a repository as other userAnsible:如何以其他用户身份克隆存储库
【发布时间】:2015-07-26 18:44:48
【问题描述】:

我正在尝试使用 Ansible 编写部署规则。一些步骤是:

  1. 更新和升级服务器
  2. 创建一个名为 harry 的用户
  3. 为 harry 添加公钥和私钥
  4. 从 bitbucket.org 克隆 Git 存储库

我想在他的主目录中将存储库克隆为harry 用户(这就是我复制它的公钥和私钥的原因)。问题是无法指定 git clone 必须执行为的用户。所以 Ansible 尝试以 root 身份克隆存储库并失败,因为他没有访问存储库的权限。

你是怎么解决这个问题的?

【问题讨论】:

    标签: git ansible ansible-playbook


    【解决方案1】:

    根据 Ansible 在 Privilege Escalation 上的文档,Ansible 在成为非特权用户方面存在限制,因为它向 Harry 暴露了一个安全漏洞。

    使用 Ansible git 模块,您可以使用 key_file 参数指定使用来自特权 Ansible 用户的 Harry 的私钥,并且使用 become_user 允许将克隆文件的所有权授予 Harry。例如:

    - name: Clone bitbucket repo
      git:
        repo: git@bitbucket.org:your-repo.git
        dest: /var/www/
        version: master
        accept_hostkey: yes
        key_file: /home/harry/.ssh/id_rsa
      become: yes
      become_user: harry
    

    【讨论】:

    • 添加become: yes很重要,因为如果你是root,那么克隆的目录也将是root,即使你become_user: harry
    【解决方案2】:

    您可以为 playbook 中的每个任务指定一个用户:

    - name: Clone bitbucket repo
      git: ...
      become: yes
      become_user: harry
    

    更多详情请见Ansible Privilege Escalation

    将私钥放在远程服务器上的更安全的替代方法是在服务器上的 sshd 配置和本地 ssh 配置中启用 ssh 密钥转发。然后,钥匙永远不会离开您的本地盒子。

    【讨论】:

    • 我有 ssh 转发,它适用于 root。但它似乎不适用于 become_user
    • SSH_AUTH_SOCK 与 become_user 一起丢失。除非保留密钥转发,否则无法进行密钥转发。也许你可以用 become_flags 添加它。
    • 正如@BenAtkin 提到的,SSH_AUTH_SOCK 会丢失,但即使您将其保存在 /etc/sudoers 文件中,您也需要授予harry 访问套接字文件的权限。 serverfault.com/questions/107187/…
    【解决方案3】:

    是的,你可以让它与 ssh 转发一起工作

    只要你在 git clone 中成为的用户是 sudoers 的一部分,那么他就不需要使用 sudo 来执行 git

    因此,除了密钥转发所需的所有配置外,还有一个在 Ansible 文档中甚至提到的技巧。 高层流程如下: 在控制机器中启用代理转发 在目标机器中启用接受代理密钥 创建一个用户并将他(或她:)添加到 sudoers 组 使用 ansible 的 git 模块克隆 repo,变成:your-sudoer-user

    另外,为了避免主机上的任何权限被拒绝,只需将其克隆到 ~/something 你可以随时复制或链接到任何你想要的地方

    这里是显示将用户添加到 sudoers 的剧本部分的链接,它基本上是复制粘贴:Ansible: create a user with sudo privileges

    像魅力一样工作

    另外,请确保在 BitBucket 的常规设置中添加 SSH 公钥,而不是在每个项目中。否则,您的 ssh 密钥将仅适用于一个特定的存储库。但是,如果您在 bitbucket 常规设置中添加 ssh 密钥,它将适用于您的所有存储库

    下面是使它工作的代码,suduer用户是“部署者”

    # the tasks to CREATE A SUDOER GROUP
    
    
    - name: Make sure we have a 'wheel' group
        group:
          name: wheel
          state: present
        become: yes
    
      - name: Allow 'wheel' group to have passwordless sudo
        lineinfile:
          dest: /etc/sudoers
          state: present
          regexp: '^%wheel'
          line: '%wheel ALL=(ALL) NOPASSWD: ALL'
          validate: 'visudo -cf %s'
        become: yes
    
      - name: Add sudoers users to wheel group
        user: name=deployer groups=wheel append=yes state=present createhome=yes
        become: yes
    
    
     # tasks to ADD REPO with Ansible's GIT MODULE
      - name: Add  Git Repo - BitBucket 
        git:
          repo: 'git@bitbucket.org:<your_username>/<your_repo>.git'
          dest: ~/code  # note this destination, you will avoid permissions issues
          accept_hostkey: yes # btw, this is for the ssh key forwarding
          recursive: no
        become: deployer # this guy (or gal) is a sudoer by now
    

    # 额外的“hack”可以一次性更改文件和文件夹的权限,它与大写 X 以及它适用于什么和不适用什么有关。也是从另一个stackoverflow中提取的

    - name: Set perms on new Code repo to deployer:deployer dirs-0755 and files-0644
        file:
          path: ~/code
          state: directory
          owner: deployer 
          group: deployer 
          mode: u=rwX,g=rX,o=rX
          recurse: yes
        become: yes
    

    【讨论】:

    【解决方案4】:

    我们可以简单地让用户 harry(在我的示例中为 www-data)通过与 root 相同的 authorized_keys 被 ssh 访问。这不会是安全问题,如果您可以连接到 root,那么如果您以 harry 身份连接,那么无论如何您都可以做更多的事情。

    remote_user: root
    tasks:
      - name: Create /var/www/.ssh
        file:
          state: directory
          owner: www-data
          group: www-data
          path: /var/www/.ssh
          mode: 0700
    
      - name: Copy authorized_keys to www-data
        copy:
          remote_src: yes
          src: ~/.ssh/authorized_keys
          dest: /var/www/.ssh/
          mode: 0400
          owner: www-data
    
      - name: Ensure www-data has shell
        lineinfile:
          path: /etc/passwd
          regexp: '^www-data:'
          line: 'www-data:x:33:33:www-data:/var/www:/bin/bash'
    
      - name: chown -R www-data /var/www
        file:
          owner: www-data
          path: /var/www
          recurse: yes
    
      - name: Git checkout application
        git:
          repo: git@gitlab.com:harry/project.git
          dest: "/var/www/project_root_dir"
          accept_hostkey: yes
        remote_user: www-data
    

    【讨论】:

      【解决方案5】:

      是的,通过 ssh 转发它可以工作。 如果您的剧本已全局启用“成为:是”,请确保为 git 任务将其关闭。 当您“成为:是”时它不起作用的原因是因为root权限提升破坏了ssh转发。 我不认为你需要成为一个 sudoer。因为如果您的 Ansible 控制机器使用 ssh 密钥通过 Bitbucket 进行身份验证(您将 ssh 密钥添加到存储库中),那么此身份验证将通过 ssh 转发传递。 您可以通过 ssh 进入您的目标并发出“ssh -T git@bitbucket.org”对其进行测试,您将在输出中看到目标已被 Bitbucket 接受为 Ansible 控制机器的用户。因此,只需使用明确的“成为:否”来执行任务。 我同意克隆到目标上的 ~/something 。否则会导致权限问题。 [编辑: 让它发挥作用的另一件事 - ⁃ 回购 URL 应该是 ssh 而不是 https 的,没有 ssh://(尽管在 Ansible手动示例)] 就安全性而言,如上所述,ssh 转发是最好的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-17
        • 2023-03-25
        • 1970-01-01
        • 2017-02-21
        • 2016-05-01
        • 2011-06-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多