Làm cách nào để thêm khóa công khai của riêng tôi vào Vagrant VM?


81

Tôi gặp sự cố khi thêm khóa ssh vào máy ảo Vagrant. Về cơ bản thiết lập mà tôi có ở đây hoạt động tốt. Sau khi các máy ảo được tạo, tôi có thể truy cập chúng thông qua vagrant ssh, người dùng "vagrant" tồn tại và có một khóa ssh cho người dùng này trong authorized_keystệp.

Điều tôi muốn làm bây giờ là: có thể kết nối với các máy ảo đó thông qua sshhoặc sử dụng scp. Vì vậy, tôi chỉ cần thêm khóa công khai của mình từ id_rsa.pubvào authorized_keys- giống như tôi muốn làm với ssh-copy-id.

Có cách nào để nói với Vagrant trong quá trình thiết lập rằng khóa công khai của tôi nên được đưa vào không? Nếu không (có thể là theo kết quả google của tôi), có cách nào để dễ dàng thêm khóa công khai của tôi trong quá trình thiết lập lang thang không?

Câu trả lời:


53

Việc sao chép khóa công khai mong muốn sẽ hoàn toàn rơi vào giai đoạn cung cấp . Câu trả lời chính xác phụ thuộc vào việc cung cấp nào bạn muốn sử dụng (shell, Chef, Puppet, v.v.). Điều nhỏ nhặt nhất sẽ là người filecung cấp chìa khóa, một cái gì đó cùng với điều này:

config.vm.provision "file", source: "~/.ssh/id_rsa.pub", destination: "~/.ssh/me.pub"

Thật ra, bạn cần phải thêm vào các khóa được ủy quyền. Sử dụng trình điều khiển shell, như sau:

config.vm.provision "shell", inline: <<-SHELL
  cat /home/vagrant/.ssh/me.pub >> /home/vagrant/.ssh/authorized_keys
SHELL
end

Bạn cũng có thể sử dụng một công cụ hỗ trợ thực sự, như Puppet . Ví dụ: hãy xem Quản lý khóa được ủy quyền của SSH bằng con rối .


8
Cảm ơn câu trả lời của bạn - đó là động lực mà tôi cần :) Tôi nghĩ có thể Vagrant sẽ cung cấp thứ gì đó, nhưng với việc cung cấp thì điều đó hoàn toàn có thể. Có thể hơi "xấu xí", nhưng nó hoạt động như một cái duyên. Về cơ bản, tôi chỉ sao chép tệp như bạn đề xuất và sau đó sử dụng trình cung cấp trình bao để nối khóa. virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
tehK

6
Có các ký tự unicode ẩn trong @ bình luận tehK của trên (trước khi is) có thể làm hỏng buổi chiều của bạn - đây là một bản sao cố định / phiên bản thể dánvirtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
Aidan Kane

Giải pháp này hoạt động tuyệt vời! Cảm ơn bạn rất nhiều :)
Samir Patel

Xin lỗi, tôi đến muộn trò chơi. Cấu hình.vm.provision là gì?
user2568374 16/02/17

5
Đừng hardcode ~/.ssh/id_rsa.pub. Nhận các chìa khóa từ ssh-add -Lthay thế.
Timur

72

Bạn có thể sử dụng mô-đun Tệp cốt lõi của Ruby, như sau:

  config.vm.provision "shell" do |s|
    ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
    s.inline = <<-SHELL
      echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
      echo #{ssh_pub_key} >> /root/.ssh/authorized_keys
    SHELL
  end

Ví dụ làm việc này gắn ~/.ssh/id_rsa.pubvới ~/.ssh/authorized_keyscả người dùng lang thang và người dùng root, điều này sẽ cho phép bạn sử dụng khóa SSH hiện có của mình.


2
Tốt và nó hoạt động, nhưng nó sẽ thêm một dòng ở mỗi điều khoản có thể được thực thi nhiều lần.
sekrett

2
Tôi bỏ phiếu để từ chối một bổ sung quan trọng cho câu trả lời này - bởi vì bổ sung đó nên được thêm vào vì nó là câu trả lời của chính nó. @ user76329 (nếu bạn quay lại để đọc) thay vào đó, hãy thêm nó dưới dạng một câu trả lời riêng.
HPierce

1
@sekrett Nếu bạn muốn trình cung cấp trình bao chỉ chạy một lần, đây là một giải pháp: blog.ouseful.info/2015/07/27/… Về cơ bản, bạn tạo cờ-tệp để đánh dấu việc cung cấp đã xảy ra.
rszalski

Tôi cần thêm tương đương với: mkdir authorized_keys ~ / .ssh && touch
Douglas Denhartog

@sekrett Đối với Idempotence, bạn được phục vụ tốt hơn với Ansible, shell chỉ có thể làm được nhiều như vậy. docs.ansible.com/ansible/latest/modules/…
MGP

38

Có một cách "thanh lịch" hơn để hoàn thành những gì bạn muốn làm. Bạn có thể tìm thấy khóa cá nhân hiện có và sử dụng nó thay vì gặp rắc rối khi thêm khóa công khai của mình.

Tiếp tục như vậy để xem đường dẫn đến khóa cá nhân hiện có (xem bên dưới để biết IdentityFile ):

chạy

 vagrant ssh-config 

kết quả:

$ vagrant ssh-config
Máy chủ magento2.vagrant150
  HostName 127.0.0.1
  Người dùng lang thang
  Cổng 3150
  UserKnownHostsFile / dev / null
  Không có nghiêm ngặt
  PasswordAuthentication không
  IdentityFile "/Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key"
  Danh tính Chỉ có
  LogLevel FATAL

Sau đó, bạn có thể sử dụng khóa riêng như thế này, cũng lưu ý công tắc tắt xác thực mật khẩu

ssh -i /Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key -o PasswordAuthentication = no vagrant@127.0.0.1 -p 3150

Đã nhận: ssh_exhange_identification: Kết nối bị đóng bởi máy chủ từ xa. Bây giờ tôi thậm chí không thể nhận được lỗi xác thực khi mơ hồ. Nó cho biết các hoạt động dành riêng cho khách đã được thực hiện trên một máy tính chưa sẵn sàng để giao tiếp với khách. Điều này không nên xảy ra và phải được báo cáo.
user2568374 16/02/17

13

Câu trả lời tuyệt vời này đã được thêm bởi người dùng76329 trong một Chỉnh sửa đề xuất bị từ chối

Mở rộng trên ví dụ của Meow , chúng ta có thể sao chép các khóa pub / private ssh cục bộ, đặt quyền và tạo idmpotent cho script nội tuyến (chạy một lần và sẽ chỉ lặp lại nếu điều kiện kiểm tra không thành công, do đó cần cung cấp):

config.vm.provision "shell" do |s|
  ssh_prv_key = ""
  ssh_pub_key = ""
  if File.file?("#{Dir.home}/.ssh/id_rsa")
    ssh_prv_key = File.read("#{Dir.home}/.ssh/id_rsa")
    ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  else
    puts "No SSH key found. You will need to remedy this before pushing to the repository."
  end
  s.inline = <<-SHELL
    if grep -sq "#{ssh_pub_key}" /home/vagrant/.ssh/authorized_keys; then
      echo "SSH keys already provisioned."
      exit 0;
    fi
    echo "SSH key provisioning."
    mkdir -p /home/vagrant/.ssh/
    touch /home/vagrant/.ssh/authorized_keys
    echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
    echo #{ssh_pub_key} > /home/vagrant/.ssh/id_rsa.pub
    chmod 644 /home/vagrant/.ssh/id_rsa.pub
    echo "#{ssh_prv_key}" > /home/vagrant/.ssh/id_rsa
    chmod 600 /home/vagrant/.ssh/id_rsa
    chown -R vagrant:vagrant /home/vagrant
    exit 0
  SHELL
end

11

Mã ngắn hơn và đúng hơn phải là:

ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
config.vm.provision 'shell', inline: 'mkdir -p /root/.ssh'
config.vm.provision 'shell', inline: "echo #{ssh_pub_key} >> /root/.ssh/authorized_keys"
config.vm.provision 'shell', inline: "echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys", privileged: false

Nếu không, người dùng .ssh/authorized_keyssẽ thuộc về người dùng root.

Tuy nhiên, nó sẽ thêm một dòng vào mỗi lần chạy cung cấp, nhưng Vagrant được sử dụng để thử nghiệm và một máy ảo thường có tuổi thọ ngắn, vì vậy không phải là vấn đề lớn.


1
Tôi đã có thêm config.vm.provision 'shell', inline: "mkdir -p /root/.ssh"sau dòng đầu tiên kể từ thư mục không tồn tại
geekQ

@geekQ Tôi sử dụng ssh-copy-id, vì vậy nó luôn được tạo ra cho tôi nhưng sẽ đúng hơn nếu tạo nó cho người khác. Tôi sẽ chỉnh sửa, cảm ơn.
sekrett

9

Tôi kết thúc bằng cách sử dụng mã như:

config.ssh.forward_agent    = true
config.ssh.insert_key       = false
config.ssh.private_key_path =  ["~/.vagrant.d/insecure_private_key","~/.ssh/id_rsa"]
config.vm.provision :shell, privileged: false do |s|
  ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  s.inline = <<-SHELL
     echo #{ssh_pub_key} >> /home/$USER/.ssh/authorized_keys
     sudo bash -c "echo #{ssh_pub_key} >> /root/.ssh/authorized_keys"
  SHELL
end

Lưu ý rằng chúng ta không nên làm cứng đường dẫn mã đến /home/vagrant/.ssh/authorized_keysvì một số hộp mơ hồ không sử dụng vagranttên người dùng.


Câu trả lời thực sự tốt. Đã giúp tôi rất nhiều. Nhưng tôi có các thiết lập điều chỉnh nơi vagrant.dlưu trữ thư mục, vì vậy tôi đã điều chỉnh cấu hình của bạn để xử lý các trường hợp như vậy. Thông tin chi tiết tại đây .
Giacomo1968,

2

Không có bài viết cũ nào phù hợp với tôi mặc dù một số bài viết đã đến gần. Tôi đã phải tạo khóa rsa với keygen trong thiết bị đầu cuối và sử dụng các khóa tùy chỉnh. Nói cách khác, bị đánh bại khi sử dụng chìa khóa của Vagrant.

Tôi đang sử dụng Mac OS Mojave kể từ ngày đăng bài này. Tôi đã thiết lập hai hộp Vagrant trong một tệp Vagrant. Tôi đang hiển thị tất cả hộp đầu tiên để người mới có thể nhìn thấy bối cảnh. Tôi đặt thư mục .ssh trong cùng thư mục với tệp Vagrant, nếu không thì sử dụng thiết lập user9091383.

Tín dụng cho giải pháp này thuộc về người lập trình này.

Vagrant.configure("2") do |config|
  config.vm.define "pfbox", primary: true do |pfbox|
        pfbox.vm.box = "ubuntu/xenial64"
        pfbox.vm.network "forwarded_port", host: 8084, guest: 80
        pfbox.vm.network "forwarded_port", host: 8080, guest: 8080
        pfbox.vm.network "forwarded_port", host: 8079, guest: 8079
        pfbox.vm.network "forwarded_port", host: 3000, guest: 3000
        pfbox.vm.provision :shell, path: ".provision/bootstrap.sh"
        pfbox.vm.synced_folder "ubuntu", "/home/vagrant"
        pfbox.vm.provision "file", source: "~/.gitconfig", destination: "~/.gitconfig"
        pfbox.vm.network "private_network", type: "dhcp"
        pfbox.vm.network "public_network"
        pfbox.ssh.insert_key = false
        ssh_key_path = ".ssh/"  # This may not be necessary.  I may remove.
        pfbox.vm.provision "shell", inline: "mkdir -p /home/vagrant/.ssh"
        pfbox.ssh.private_key_path = ["~/.vagrant.d/insecure_private_key", ".ssh/id_rsa"]
        pfbox.vm.provision "file", source: ".ssh/id_rsa.pub", destination: ".ssh/authorized_keys"
        pfbox.vm.box_check_update = "true"
        pfbox.vm.hostname = "pfbox"
        # VirtualBox
          config.vm.provider "virtualbox" do |vb|
            # vb.gui = true
            vb.name = "pfbox" # friendly name for Oracle VM VirtualBox Manager
            vb.memory = 2048 # memory in megabytes 2.0 GB
            vb.cpus = 1 # cpu cores, can't be more than the host actually has.
          end
  end
  config.vm.define "dbbox" do |dbbox|
        ...

1

Đây là một chủ đề tuyệt vời đã giúp tôi giải quyết một tình huống tương tự như áp phích gốc mô tả.

Mặc dù cuối cùng tôi đã sử dụng các cài đặt / logic được trình bày trong câu trả lời của smartwjw , tôi đã gặp phải trở ngại vì tôi sử dụng VAGRANT_HOMEbiến môi trường để lưu vagrant.dnội dung thư mục cốt lõi trên ổ cứng ngoài trên một trong các hệ thống phát triển của mình.

Vì vậy, đây là mã đã điều chỉnh mà tôi đang sử dụng trong Vagrantfile của mình để phù hợp với một VAGRANT_HOMEbiến môi trường đang được đặt; "điều kỳ diệu" xảy ra trong dòng này vagrant_home_path = ENV["VAGRANT_HOME"] ||= "~/.vagrant.d":

config.ssh.insert_key = false
config.ssh.forward_agent = true
vagrant_home_path = ENV["VAGRANT_HOME"] ||= "~/.vagrant.d"
config.ssh.private_key_path = ["#{vagrant_home_path}/insecure_private_key", "~/.ssh/id_rsa"]
config.vm.provision :shell, privileged: false do |shell_action|
  ssh_public_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  shell_action.inline = <<-SHELL
    echo #{ssh_public_key} >> /home/$USER/.ssh/authorized_keys
  SHELL
end

1

Đối với trình cung cấp trình bao nội tuyến - khóa công khai thường chứa khoảng trắng, nhận xét, v.v. Vì vậy, hãy đảm bảo đặt dấu ngoặc kép (thoát) xung quanh var mở rộng thành khóa công khai:

config.vm.provision 'shell', inline: "echo \"#{ssh_pub_key}\" >> /home/vagrant/.ssh/authorized_keys", privileged: false

0

Một ví dụ khá đầy đủ, hy vọng điều này sẽ giúp ích cho những người ghé thăm tiếp theo. Đã chuyển tất cả các giá trị cụ thể sang các tệp cấu hình bên ngoài. Chỉ định IP chỉ để dùng thử.

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'
vmconfig = YAML.load_file('vmconfig.yml')

=begin
Script to created VMs with public IPs, VM creation governed by the provided
config file.
All Vagrant configuration is done below. The "2" in Vagrant.configure
configures the configuration version (we support older styles for
backwards compatibility). Please don't change it unless you know what
you're doing
Default user `vagrant` is created and ssh key is overridden. make sure to have
the files `vagrant_rsa` (private key) and `vagrant_rsa.pub` (public key) in the
path `./.ssh/`
Same files need to be available for all the users you want to create in each of
these VMs
=end

uid_start = vmconfig['uid_start']
ip_start = vmconfig['ip_start']
vagrant_private_key = Dir.pwd + '/.ssh/vagrant_rsa'
guest_sshkeys = '/' + Dir.pwd.split('/')[-1] + '/.ssh/'
Vagrant.configure('2') do |config|
  vmconfig['machines'].each do |machine|
    config.vm.define "#{machine}" do |node|
      ip_start += 1
      node.vm.box = vmconfig['vm_box_name']
      node.vm.box_version = vmconfig['vm_box_version']
      node.vm.box_check_update = false
      node.vm.boot_timeout = vmconfig['vm_boot_timeout']
      node.vm.hostname = "#{machine}"
      node.vm.network "public_network", bridge: "#{vmconfig['bridge_name']}", auto_config: false
      node.vm.provision "shell", run: "always", inline: "ifconfig #{vmconfig['ethernet_device']} #{vmconfig['public_ip_part']}#{ip_start} netmask #{vmconfig['subnet_mask']} up"
      node.ssh.insert_key = false
      node.ssh.private_key_path = ['~/.vagrant.d/insecure_private_key', "#{vagrant_private_key}"]
      node.vm.provision "file", source: "#{vagrant_private_key}.pub", destination: "~/.ssh/authorized_keys"
      node.vm.provision "shell", inline: <<-EOC
        sudo sed -i -e "\\#PasswordAuthentication yes# s#PasswordAuthentication yes#PasswordAuthentication no#g" /etc/ssh/sshd_config
        sudo systemctl restart sshd.service
      EOC
      vmconfig['users'].each do |user|
        uid_start += 1
        node.vm.provision "shell", run: "once", privileged: true, inline: <<-CREATEUSER
          sudo useradd -m -s /bin/bash -U #{user} -u #{uid_start}
          sudo mkdir /home/#{user}/.ssh
          sudo cp #{guest_sshkeys}#{user}_rsa.pub /home/#{user}/.ssh/authorized_keys
          sudo chown -R #{user}:#{user} /home/#{user}
          sudo su
          echo "%#{user} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/#{user}
          exit
        CREATEUSER
      end
    end
  end

-1

Câu trả lời của Madis Maenni là gần nhất với giải pháp tốt nhất:

cứ làm đi:

vagrant ssh-config >> ~/.ssh/config
chmod 600 ~/.ssh/config

thì bạn có thể ssh thông qua tên máy chủ.

Để nhận danh sách tên máy chủ được định cấu hình trong ~ / .ssh / config

grep -E '^Host ' ~/.ssh/config

Ví dụ của tôi:

$ grep -E '^Host' ~/.ssh/config
Host web
Host db
$ ssh web
[vagrant@web ~]$

-2

Tạo cặp khóa rsa để xác thực lang thang ssh-keygen -f ~/.ssh/vagrant

Bạn cũng có thể muốn thêm các tệp danh tính lang thang vào ~/.ssh/config

IdentityFile ~/.ssh/vagrant
IdentityFile ~/.vagrant.d/insecure_private_key

Vì một số lý do, chúng tôi không thể chỉ định khóa mà chúng tôi muốn chèn, vì vậy chúng tôi thực hiện thêm một số bước để tự tạo khóa. Bằng cách này, chúng tôi có được sự bảo mật và kiến ​​thức về chính xác khóa nào chúng tôi cần (+ tất cả các hộp lang thang sẽ nhận được cùng một khóa)

Không thể truy cập máy ảo ảo sử dụng khóa riêng không an toàn (vagrant 1.7.2) Làm cách nào để thêm khóa công khai của riêng tôi vào máy ảo Vagrant?

config.ssh.insert_key = false
config.ssh.private_key_path = ['~/.ssh/vagrant', '~/.vagrant.d/insecure_private_key']
config.vm.provision "file", source: "~/.ssh/vagrant.pub", destination: "/home/vagrant/.ssh/vagrant.pub"
config.vm.provision "shell", inline: <<-SHELL
cat /home/vagrant/.ssh/vagrant.pub >> /home/vagrant/.ssh/authorized_keys
mkdir -p /root/.ssh
cat /home/vagrant/.ssh/authorized_keys >> /root/.ssh/authorized_keys

VỎ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.