diff --git a/INSTALLATION.rst b/INSTALLATION.rst index a1cb9ae..ceef97a 100644 --- a/INSTALLATION.rst +++ b/INSTALLATION.rst @@ -8,14 +8,16 @@ About Devstack and automation tools *********************************** So far (March 2018) I've been developing Tatu on my devstack instance. The -devstack plugin is mostly working. See the README under tatu/devstack. +devstack plugin for default Neutron (without bastion support) is working. Use +the local.conf file in tatu/devstack to set up devstack and then follow the +steps in tatu/TRY_IT.rst. No work has been done to automate Tatu installation for production. We plan to provide Ansible and Kolla installers, but this is just a vague intent at the moment (March 2018). -Manually installing Tatu’s daemons -================================== +Manually installing Tatu +======================== Note that there are 2 daemons: API daemon and Notifications daemon. diff --git a/README.rst b/README.rst index 3045d7e..93d702a 100644 --- a/README.rst +++ b/README.rst @@ -78,11 +78,11 @@ client certificate. This is simpler, more secure and more manageable than today's common practice: putting each user's public key in the SSH server's authorized_keys file. -Installation ------------- +Installation (including Devstack) +--------------------------------- Please see the INSTALLATION document in this repository. Then see the TRY_IT -document as well for step by step instructions on using it. +document for step by step instructions on using it. APIs, Horizon Panels, and OpenStack CLIs ---------------------------------------- diff --git a/TRY_IT.rst b/TRY_IT.rst index 734dcf9..48d9364 100644 --- a/TRY_IT.rst +++ b/TRY_IT.rst @@ -4,6 +4,9 @@ Notes on using Tatu for the first time **In this example, I'm the "demo" user and I need to connect to VMs in projects named "demo" and "invisible_to_admin".** +Generate SSH keys and certificates +---------------------------------- + Since you'll need separate SSH user certificates for each of your projects, generate separate ssh keys for each of your projects:: @@ -15,7 +18,7 @@ Horizon). First set your environment variables to select your user and project. Note that ssh client expects the certificate's name to be the private key name followed by "-cert.pub":: - source openrc demo demo + source /opt/stack/devstack/openrc demo demo openstack ssh usercert create -f value -c Certificate "`cat ~/.ssh/demo_key.pub`" > ~/.ssh/demo_key-cert.pub openstack ssh usercert create --os-project-name invisible_to_admin -f value -c Certificate "`cat ~/.ssh/inv_key.pub`" > ~/.ssh/inv_key-cert.pub @@ -45,9 +48,13 @@ And the output will look like this:: Note that the Signing CA is different for each certificate. You'll have to use the corresponding key/certificate to ssh to a project's VM. +Configure your client to trust the Certificate Authority for hosts +------------------------------------------------------------------ + Now configure your ssh client to trust SSH host certificats signed by the Host CAs of your projects. Given how Tatu currently generates Host certificates, -you must trust each CA for hostnames in any domain (hence the "*" in the command):: +you must trust each project's Host CA for hostnames in any domain (hence the +"*" in the command):: demo_id=`openstack project show demo -f value -c id` echo '@cert-authority * '`openstack ssh ca show $demo_id -f value -c 'Host Public Key'` >> ~/.ssh/known_hosts @@ -57,17 +64,52 @@ you must trust each CA for hostnames in any domain (hence the "*" in the command Above, note that the --os-project-name option is necessary because we sourced openrc with the "demo" project. +Your known_hosts file should now have one @cert-authority line for each project:: + + cat ~/.ssh/known_hosts + @cert-authority * ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... + @cert-authority * ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKVCfrfD... + +Launch your VM +-------------- + Now launch a VM without a Key Pair. Unless you're using Dragonflow and Tatu's experimental PAT bastion feature, assign a floating IP to the VM. In this example we'll assume the VM's Floating IP is 172.24.4.8 +**Make sure to launch your VM on a private network that has a router attached, +and that the router has a gateway.** In other words, unless you're using a +bastion, the VM's IP must be routable via the Floating IP. + +If you look in Tatu API's log, you should see something like the following. +There may be several calls to /v1/novavendordata because Nova queries Tatu +once for each version of Nova metadata API. It's OK, Tatu returns the same +data each time. The call to /noauth/hostcerts is the VM's request to Tatu to +generate an SSH host certificate. The call does not use Keystone authentication +but is protected by the one-time-token presented in "token_id":: + + journalctl --unit devstack@tatu-api.service + Request POST /v1/novavendordata with body {... u'hostname': u'fluffy', u'boot-roles': u'admin,Member,anotherrole', u'image-id': ... u'project-id': ... u'instance-id': ...} + produced response with status 201 Created location /hosttokens/489b555621f74494adf7089174563bfb + and body {"api_endpoint": "http://172.24.4.1:18322", "auth_pub_key_user": ... "token": "489b555621f74494adf7089174563bfb", "root_principals": "", + "ssh_port": 2222, "sudoers": "admin", "pam_sudo": true, "users": "admin,Member,anotherrole"} + ... + Request POST /noauth/hostcerts with body {u'token_id': '489b555621f74494adf7089174563bfb', u'pub_key': ... u'host_id': ...} + produced response with status 200 OK location /hostcerts/717f9144e20e408380e174bda5855b3b/MD5:da:08:6f:d9:cc:b9:57:66:cb:b7:50:7f:d1:26:71:26 + and body {"created_at": "2018-03-14T18:27:58.000000", "hostname": "fluffy", "expires_at": "2019-03-14T18:27:58.000000", "cert": ... + +SSH to your VM +-------------- + If you launched your VM in the demo project, use the following ssh command. Note that the Linux user account must correspond to one of the principals in your certificate, which in turn corresponds to one of your roles in the project:: ssh -i ~/.ssh/demo_key Member@172.24.4.8 -** You should not get a warning like the following**:: +Thanks to the host's SSH certificate and the @cert-authority line in the client's +known_hosts file, a man-in-the-middle (MITM) attack risk is eliminated, so +**you should no longer see this warning that you always ignore**:: The authenticity of host '172.24.4.8 (172.24.4.8)' can't be established. RSA key fingerprint is SHA256:FS2QGF4Ant/MHoUPxgO6N99uQss57lKkPclXDgFOLAU. @@ -155,9 +197,9 @@ we can see when pam-ussh does its authentication:: debug1: client_input_channel_open: ctype auth-agent@openssh.com rchan 2 win 65536 max 16384 debug1: channel 1: new [authentication agent connection] debug1: confirm auth-agent@openssh.com + hello debug1: channel 1: FORCE input drain debug1: channel 1: free: authentication agent connection, nchannels 2 - hello [admin@dusty ~]$ sudo echo how are you how are you [admin@dusty ~]$ diff --git a/devstack/local.conf b/devstack/local.conf index c085987..f166580 100644 --- a/devstack/local.conf +++ b/devstack/local.conf @@ -19,4 +19,4 @@ PUBLIC_NETWORK_GATEWAY=172.24.4.1 _IMAGE_PREFIX="http://download.fedoraproject.org/pub/fedora/linux/releases" _FEDORA25="/25/CloudImages/x86_64/images/Fedora-Cloud-Base-25-1.3.x86_64.qcow2" _FEDORA27="/27/CloudImages/x86_64/images/Fedora-Cloud-Base-27-1.6.x86_64.qcow2" -IMAGE_URLS+=","$_IMAGE_PREFIX$_FEDORA25","$_IMAGE_PREFIX$_FEDORA27 +IMAGE_URLS+=","$_IMAGE_PREFIX$_FEDORA25"