summaryrefslogtreecommitdiff
path: root/README.md
blob: 930910dcfee5aea9dab730a7ac70f145ce27e54c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# vmadm README

vmadm is a tool to create and destroy virtual machines running
under a local libvirt. Virtual machines are described in specification
files, using YAML:

~~~yaml
foo:
  cpus: 4
  memory_mib: 4096
  image_size_gib: 100

bar:
  cpus: 1
  memory_mib: 512
  image_size_gib: 1
~~~

All the machines in a specification file are created or destroyed at
once.

## Usage

Given a specification file `machines.yaml`, to create virtual machines
run:

~~~sh
$ vmadm new machines.yaml
~~~

To delete them:

~~~sh
$ vmadm delete machines.yaml
~~~

Creating a VM creates a disk image of qcow2 format, based on a base
image, also of qcow2 format. Deleting the VM deletes the image file as
well. Image files are named after the VM and put into the configured
image directory, unless the specification file names an image file
explicitly.

To get built-in command line help:

~~~sh
$ vmadm help
$ vmadm --help
~~~

A base image is an image with some operating system already installed.
It should use [cloud-init][] on first boot to configure hostname and
SSH keys, or at least not mind that there is an extra ISO disk with
cloud-init configuration attached to the VM. It should open an SSH
port when it has booted. Other than that, vmadm doesn't care what it
is. For Debian, the pre-made OpenStack cloud-image at
<https://cloud.debian.org/> works well. You need to download the base
image yourself, vmadm doesn't do that for you.

## Configuration

The default configuration file is `vmadm/config.yaml` under the XDG
configuration directory; by default, this is
`~/.config/vmadm/config.yaml`. The configuration file may specify the
following fields:

* `default_base_image` &ndash; path to the base image to use by default
* `default_image_gib` &ndash; default size of new image for a VM, in GiB
* `default_memory_mib` &ndash; default amount of memory for a VM, in MiB
* `default_cpus` &ndash; default number of CPUs for a VM
* `default_generate_host_certificate` &ndash; should SSH host
  certificates be generated by default?
* `image_directory` &ndash; directory where VM image files are put
* `authorized_keys` &ndash; list of filenames to SSH public keys, to
  be put into the default user's `authorized_keys` file in the VM
* `ca_key` &ndash; path name to default CA *private* key


## Specification fields

The specification file is YAML and may specify the following fields,
all of which override some default from the configuration.

* `ssh_key_files` &ndash; overrides `authorized_keys`
* `image_size_gib` &ndash; overrides `default_image_giv`
* `memory_mib` &ndash; overrides `default_memory_mib`
* `cpus` &ndash; overrides `default_cpus`
* `base` &ndash; overrides `default_base_image`
* `image` &ndash; overrides default image file name; must include
* `image` &ndash; overrides default image file name; must include
  path name, is not put into the image directory by default
* `generate_host_certificate` &ndash; override host certification
  setting
* `ca_key` &ndash; overrides default CA key
* `rsa_host_key` &ndash; RSA host key to install on host
* `rsa_host_cert` &ndash; RSA host certificate to install on host
* `dsa_host_key` &ndash; DSA host key to install on host
* `dsa_host_cert` &ndash; DSA host certificate to install on host
* `ecdsa_host_key` &ndash; ECDSA host key to install on host
* `ecdsa_host_cert` &ndash; ECDSA host certificate to install on host
* `ed25519_host_key` &ndash; Ed25519 host key to install on host
* `ed25519_host_cert` &ndash; Ed25519 host certificate to install on host

The various `host_key` and `host_cert` fields specify *private* host
keys and certificates to be installed in the new VM. The public key is
computed from the private key, so there's no need to specify it
explicitly. The fields should contain the text of the key or
certificate, not its filename.

If *any* host key is specified, no host certificate is generated: the
`generate_host_certificate` setting is ignored. If no host keys is
specified, an Ed25519 key is generated and signed with the specified
CA certificate. The generated key and certificate are installed in the
new VM.

In other words, if you specify any host keys, you get to do everything
by hand. If you want to keep things easy, don't specify any host keys
and let vmadm generate a host key and host certificate for a VM.

# Using host certificates

Host certificates allow you to access a newly created VM without
having to accept its host key. This is especially useful the VM gets
recreated and the host key changes. You need to configure your SSH
client to trust certificates made with a given SSH CA key, but that is
a one-time operation.

You need to create an SSH key used as a CA key for host certification.
Run this command:

~~~sh
$ mkdir -m 0700 ~/.ssh/ca
$ ssh-keygen -f ~/.ssh/ca/vmadm_ca -t ed25519 -N ''
~~~

This creates a key **without a passphrase**, because vmadm does not
currently support CA keys with passphrases.

Keep the CA key secure. Don't use it for anything else.

Add the following to the `known_hosts` file your SSH client uses, all
on one one:

~~~
@cert-authority * XXXX
~~~

where `XXX` is the public key part of the CA key, as stored in
`~/.ssh/ca/vmadm_ca.pub` in the example above. This tells your client
that the CA key on the line should be accepted for all hosts (`*`).
You can restrict it to only some hosts if you prefer.

# Setup of host

The host where vmadm is run needs to have libvirt running and you must
have access to the `qemu:///system` connection.
The Debian wiki has some useful documentation: 

* <https://wiki.debian.org/libvirt>
* <https://wiki.debian.org/KVM>

I set up my own libvirt hosts using an Ansible role:
<http://git.liw.fi/ansibleness/tree/ansible/roles/vmhost>. It works on
Debian. The short version:

* install
  - `libvirt` (Debian packages `libvirt-daemon-system`,
    `libvirt-daemon`, `libvirt-daemon`)
  - `virt-install` (Debian package `virtinst`)
  - `qemu-img` (Debian package `qemu-uttils`)
  - NSS lookups for VMs (Debian package `libnss-libvirt`)
  - SSH client (Debian package `openssh-client`)
* make sure you are in the `libvirt` group
* edit `/etc/nsswitch.conf` to have `libvirt libvirt_guest` in the
  `hosts` line