AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 505826
Accepted
codekandis
codekandis
Asked: 2019-03-13 01:54:12 +0800 CST2019-03-13 01:54:12 +0800 CST 2019-03-13 01:54:12 +0800 CST

不使用文件系统临时读写数据

  • 772

我在管理 debian 盒子的流浪环境中使用 ansible。由于具有保险库加密数据(例如数据库根密码)的多个 ansible 供应商,我必须由第一个供应商输入保险库密码一次。目前,此密码存储在/tmp每个 ansible 供应商中,由脚本读取,并被最后一个供应商覆盖,/dev/null然后被最后一个供应商删除。

Ansible 能够调用返回保险库密码的脚本。所以这个脚本将在一个单独的 shell 中运行。

如果攻击者设法闯入虚拟机,他就有机会恢复任何临时文件并获得保管库密码。

虽然这些流浪环境将用于生产,但我正在寻找一种更安全的方法。我首先想到的是以某种方式读取和写入内存。因此,VM 重新启动会擦除内存。我知道上面提到的数据可以以某种方式在磁盘上交换。但我认为获取这些数据比临时文件方法更难。

编辑

如果配置程序失败,我忘了提及安全风险。然后最后一个provisioner 将不会被执行,临时文件会保留在文件系统上。


我提供了一个额外的答案,仅针对对导致此问题的起源问题的解决方案感兴趣的任何人显示集成解决方案。

bash security
  • 2 2 个回答
  • 512 Views

2 个回答

  • Voted
  1. Best Answer
    Christopher
    2019-03-13T06:09:52+08:002019-03-13T06:09:52+08:00

    使用以下命令创建 1 MB RAM 磁盘tmpfs:

    mkdir /tmp/ramdisk
    mount -t tmpfs -o size=1m myramdisk /tmp/ramdisk
    

    ramfsRAM 磁盘不交换,但在使用 RAM 磁盘时可以关闭和打开交换:tmpfs和swapoff -a,swapon -a如果需要确保在使用tmpfsRAM 磁盘期间没有发生交换。卸载:

    umount /tmp/ramdisk
    

    也许我错过了一些东西,但我看不到在 ; 中描述 RAM 磁盘的好处/etc/fstab;但是,如果需要,以下内容应该足以使 RAM 磁盘root仅对用户可用(mode=0700):

    tmpfs /tmp/ramdisk tmpfs rw,mode=0700,size=1m
    
    • 1
  2. codekandis
    2019-03-13T11:27:47+08:002019-03-13T11:27:47+08:00

    除了@Christopher 的回答之外,我还想展示我如何将解决方案集成到我的 Vagrantfile 中,以便让它与我的 ansible povisioning 一起工作。

    可能会偶然发现这一点。

    流浪文件

    Vagrant.configure("2") do |config|
    
        class AnsibleVaultPassword
            def to_s
                begin
                    system 'stty -echo'
                    print "Enter ansible vault password: "
                    pass = STDIN.gets.chomp
                    ensure
                    system 'stty echo'
                end
                pass
            end
        end
    
        config.vm.box = "vendor/box-name"
        config.vm.box_version = ">=1.0"
        config.vm.box_url = "https://vagrant.example.com/vendor/box-name.json"
        config.vm.box_download_insecure = true
    
        config.vm.define "vendor-server-name"
        config.vm.provider "virtualbox" do |provider|
            provider.name = "vendor-server-name"
        end
    
        config.vm.network "private_network", ip: "192.168.0.42"
    
        config.vm.synced_folder ".", "/vagrant", type: "nfs"
    
        config.vm.provision "Provisioning the server `server-name` with the playbook `ansible`", type: "ansible_local" do |provisioner|
            provisioner.compatibility_mode = "2.0"
            provisioner.playbook = "/vagrant/ansible/ansible.yml"
            provisioner.inventory_path = "/vagrant/ansible/inv/integration/hosts"
            provisioner.limit = "localhost"
        end
    
        config.vm.provision "Requesting the ansible vault password", type: "shell" do |provisioner|
            provisioner.env = { "ansibleVaultPassword" => AnsibleVaultPassword.new }
            provisioner.inline = <<-END
                [[ ! -d "/mnt/ansible-tmp" ]] \
                && mkdir "/mnt/ansible-tmp"
                mountpoint -q "/mnt/ansible-tmp" \
                || mount -t tmpfs -o size=512 ansible-tmp "/mnt/ansible-tmp"
                /vagrant/env/ansible/scripts/vault-password.sh --save "${ansibleVaultPassword}"
            END
        end
    
        config.vm.provision "Provisioning the server `server-name` with the playbook `environment`", type: "ansible_local" do |provisioner|
            provisioner.compatibility_mode = "2.0"
            provisioner.playbook = "/vagrant/ansible/environment.yml"
            provisioner.raw_arguments = [ "--vault-id /vagrant/ansible/scripts/vault-password.sh" ]
            provisioner.inventory_path = "/vagrant/ansible/inv/integration/hosts"
            provisioner.limit = "localhost"
        end
    
        config.vm.provision "Provisioning the server `server-name` with the playbook `users`", type: "ansible_local" do |provisioner|
            provisioner.compatibility_mode = "2.0"
            provisioner.playbook = "/vagrant/ansible/users.yml"
            provisioner.raw_arguments = [ "--vault-id /vagrant/ansible/scripts/vault-password.sh" ]
            provisioner.inventory_path = "/vagrant/ansible/inv/integration/hosts"
            provisioner.limit = "localhost"
        end
    
        config.vm.provision "Deleting the ansible vault password", type: "shell" do |provisioner|
            provisioner.inline = <<-END
                /vagrant/env/ansible/scripts/vault-password.sh --delete
                mountpoint -q "/mnt/ansible-tmp" \
                && umount "/mnt/ansible-tmp"
                [[ -d "/mnt/ansible-tmp" ]] \
                && rm -r "/mnt/ansible-tmp"
            END
        end
    
    end
    

    /vagrant/ansible/scripts/vault-password.sh

    #!/usr/bin/env bash
    
    passwordFile="/mnt/ansible-tmp/vault-password"
    case "${1}" in
        "-s" | "--save" )
            echo "${2}" > "${passwordFile}"
            ;;
        "-d" | "--delete" )
            unlink "${passwordFile}"
            ;;
        * )
            cat "${passwordFile}"
            ;;
    esac
    

    虽然它是一个 Debian VM,但我首先运行ansible从 Ubuntu 添加 ansible 存储库的 playbook,然后安装最新的ansible. 这至少对于为Vagrant--vault-id的调用提供参数是必要的。ansible-playbook(在这篇文章的时候Debian Stretch附带了ansible 2.2不支持这个论点。)

    然后使用类请求保管库密码AnsibleVaultPassword。之后将tmpfs创建,密码将传递给脚本vault-password.sh以将其存储在tmpfs挂载上。

    然后,ansible 将通过vault-password.sh每个提供保险库加密数据的剧本中的脚本来请求密码。

    最后将首先删除密码,然后tmpfs卸载挂载。

    我认为这是一个非常安全可靠的解决方案,通过临时可擦除内存存储提供 ansible vault 密码。因此,可以配置正在运行的系统,并且不再需要重新启动。

    • 1

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 是否有实现 RFC 5848“签名系统日志消息”的系统日志守护程序?

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve