나는 데비안 상자를 관리하는 방랑 환경에서 ansible을 사용하고 있습니다. 여러 Ansible 프로비저너가 볼트 암호화된 데이터(예: 데이터베이스 루트 비밀번호)를 가지고 있으므로 첫 번째 프로비저너가 볼트 암호를 한 번 입력해야 합니다. 현재 이 비밀번호는 에 저장되고 /tmp
, 각 Ansible 프로비저너의 스크립트로 읽혀지며, /dev/null
마지막 프로비저너가 덮어쓰고 삭제합니다.
Ansible에는 볼트 비밀번호를 반환하는 스크립트를 호출하는 기능이 있습니다. 따라서 이 스크립트는 별도의 셸에서 실행됩니다.
공격자가 가상 머신을 성공적으로 손상시키는 경우 임시 파일을 복구하고 볼트 비밀번호를 얻을 수 있습니다.
이러한 변덕스러운 환경은 프로덕션 환경에서 사용되지만 보다 안전한 접근 방식을 찾고 있습니다. 나의 첫 번째 생각은 어떻게든 메모리를 읽고 쓰는 것이었습니다. 따라서 가상 컴퓨터를 다시 시작하면 메모리가 지워집니다. 위의 데이터가 어떻게든 디스크에서 교환될 수 있다는 것을 알고 있습니다. 그런데 이 데이터를 얻는 것이 임시 파일 방식보다 더 어려운 것 같아요.
편집하다
구성자가 실패할 경우 보안 위험에 대해 언급하는 것을 잊었습니다. 그러면 마지막 구성 프로그램이 실행되지 않고 임시 파일이 파일 시스템에 남게 됩니다.
이 문제의 원인에 대한 솔루션에 관심이 있는 모든 사람을 위해 통합 솔루션을 보여주는 추가 답변을 제공했습니다.
답변1
1MB RAM 디스크를 생성하려면 다음 명령을 사용하십시오 tmpfs
.
mkdir /tmp/ramdisk
mount -t tmpfs -o size=1m myramdisk /tmp/ramdisk
RAM 디스크는 스왑되지 않지만 RAM 디스크를 사용하는 동안 스왑이 발생하지 않도록 해야 하는 경우 RAM 디스크 사용 ramfs
시 스왑을 끄거나 켤 수 있습니다 tmpfs
. swapoff -a
및 . 제거:swapon -a
tmpfs
umount /tmp/ramdisk
뭔가 빠졌을 수도 있지만 에 설명된 RAM 디스크의 이점은 보이지 않습니다 /etc/fstab
. 그러나 다음과 같은 내용은 필요한 경우 사용자만 RAM 디스크를 사용할 수 있도록 하는 데 충분합니다 root
( mode=0700
).
tmpfs /tmp/ramdisk tmpfs rw,mode=0700,size=1m
답변2
@Christopher의 답변 외에도 Vagrantfile에 솔루션을 통합하여 Ansible 구성과 작동하는 방법을 보여주고 싶었습니다.
어쩌면 누군가가 이것을 우연히 발견하게 될 것입니다.
길 잃은 파일
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이지만 먼저 플레이북을 실행하고 Ubuntu 에서 Ansible 저장소를 추가 한 ansible
다음 최신 ansible
. (이 기사가 출판된 당시에 는 이 주장을 뒷받침하지 않았습니다.)--vault-id
ansible-playbook
Debian Stretch
ansible 2.2
그런 다음 class 를 통해 볼트 비밀번호를 요청하십시오 AnsibleVaultPassword
. 그런 다음 비밀번호가 생성되어 tmpfs
스크립트에 전달되어 설치 시 vault-password.sh
저장됩니다 .tmpfs
vault-password.sh
그런 다음 Ansible은 볼트의 암호화된 데이터를 제공하는 각 플레이북의 스크립트를 통해 비밀번호를 요청합니다.
마지막으로 비밀번호가 먼저 삭제된 후 tmpfs
마운트가 제거됩니다.
임시 삭제 가능한 메모리 저장소를 통해 Ansible Vault 비밀번호를 제공하는 매우 안전하고 안전한 솔루션이라고 생각합니다. 따라서 실행 중인 시스템을 구성할 수 있으며 더 이상 재부팅이 필요하지 않습니다.