trailofbits / algo

Set up a personal VPN in the cloud
https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/
GNU Affero General Public License v3.0
28.98k stars 2.32k forks source link

How to add users when deploying from script? #1596

Closed darrylb-github closed 4 years ago

darrylb-github commented 5 years ago

Is your feature request related to a problem? Please describe. I'm looking for advice on how to add users after the initial deployment when using the deploy-from-script method.

Describe the solution you'd like Extra docs in the deploy from script RE how to manage users when using that method. Ideally this method should also not be interactive and be something I can easily script as part of a terraform run or other provisioning.

Describe alternatives you've considered The main method of running the algo script to add users doesnt seem to apply when installing by script. My /opt/algo directory doesn't contain my user list; the only reference of the users I'm adding is the resulting configs/ output.

Connecting to the server, setting my new USERS environment variable and re-running the script does generate the new users, but it seems to be replacing the existing config for users that already exists. I want a way to add or remove users, ideally from a script.

I see you have some alpha terraform modules and I have experimented with those, but atm they feel more complicated than this script method.

Additional context I'm looking to use algo as a replacement for OpenVPN in a company AWS VPC environment. I'm using terraform to create an ASG with 1 instance and a launch template with userdata that calls this script:

#!/bin/bash
set -eo xtrace

apt-get -y update
apt-get install -y python-pip
pip install awscli

# Associate EIP
instance_id=$(curl http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 associate-address --instance-id "$instance_id" --allocation-id "${aws_eip.algo.id}" --region "${data.aws_region.current.name}"

# Install algo
export METHOD=local
export ENDPOINT=${aws_eip.algo.public_ip}
export USERS="${join(",", local.users)}"
export STORE_PKI=true
curl -s https://raw.githubusercontent.com/trailofbits/algo/master/install.sh | sudo -E bash -x

aws s3 sync --sse aws:kms /opt/algo/configs s3://${aws_s3_bucket.algo_user_configs.bucket}/algo

Updating my user list would update the user data so that if my instance dies a new one would come up with the up to date list of users, but I still need a solution to add/remove users programmatically to an existing server. If I can find a solution to do it manually, then I could look at having terraform remote exec run this command when my list of users changes so that the active server gets the latest users.

Also as a sidenote, is it possible to keep the same user profiles if the server gets recreated? Or do I have to redistribute profiles to each user when my server is replaced?

TC1977 commented 5 years ago

So I could be mistaken, but I believe the cloud-init script was primarily intended to set up a new instance, not for maintenance. Rather than re-run the install.sh, the better way to do this might be to run ./algo update-users from /opt/algo after updating the config.cfg file to the new user list you want. That would leave the existing users untouched.

I haven't tried a non-interactive update users, and don't have the time to figure it out, but I think if you start with something like ansible-playbook users.yml -e "server=localhost CA_password=<yourCApasswordhere>" (CA_password not required if you haven't deployed IPsec) and play around from there, you should be able to get something that works. I'd be happy to update the Ansible and cloud-init docs with whatever you work out.

darrylb-github commented 5 years ago

I'll experiment with updating the config and trying update-users. I'm assuming that if I don't include any other config in that file, it will only update the users and leave my initial config untouched, but I'll find out.

TC1977 commented 5 years ago

@darrylb-github Did this work for you? Trying to update the docs.

darrylb-github commented 5 years ago

@darrylb-github Did this work for you? Trying to update the docs.

Yea using the playbooks directly like below worked:

ansible-playbook main.yml -e "provider=local server=localhost server_name=${var.name} endpoint=${aws_eip.algo.public_ip} ca_password=${var.ca_password} CA_password=${var.ca_password} dns_adblocking=false ondemand_cellular=false ondemand_wifi=false ssh_tunneling=false store_pki=true" --skip-tags "debug"
ansible-playbook users.yml -t update-users -e "provider=local server=localhost server_name=${var.name} endpoint=${aws_eip.algo.public_ip} ca_password=${var.ca_password} CA_password=${var.ca_password} dns_adblocking=false ondemand_cellular=false ondemand_wifi=false ssh_tunneling=false store_pki=true"--skip-tags "debug"

I had to skip debug tags due to errors using tee to /dev/tty when running noninteractively in userdata style script. I also noticed main / server playbook relies on CA_password whilst users playbook expects ca_password.

My userdata script does the initial install via main playbook then sets up a bash script on a cron that checks for differences in my config file stored on s3; if differences are found it downloads the new config file and reruns the user playbook then syncs the profiles to s3.