diff --git a/gravitoninstance.yml b/gravitoninstance.yml index de393ca..db036d2 100644 --- a/gravitoninstance.yml +++ b/gravitoninstance.yml @@ -1,6 +1,8 @@ --- # Provisioning of a graviton server using aws spot instance -- hosts: local +- name: provisions a graviton server as aws spot instance + hosts: localhost + connection: local vars_prompt: - name: ssh_pub_key_file prompt: Location of your public ssh key @@ -9,8 +11,8 @@ prompt: AWS Region to use for instaance default: "us-east-1" - name: aws_ami - prompt: Disk image to use for instance (default is ubuntu 20.10 arm64) - default: "ami-01069be104eb25898" + prompt: Disk image to use for instance (default is debian buster arm64) + default: "ami-057796a93302d0b14" - name: aws_type prompt: Instance type to request default: "t4g.nano" @@ -20,6 +22,19 @@ - name: dns_host_name prompt: Hostname that is registered in Route53 default: "illevpn" + - name: vpn_clients + prompt: Number of vpn clients to be generated + default: "1" roles: - aws_graviton_nano_spot + +- name: set defaults + vars: + vpn_network: '10.100.100' + vpn_port: '58172' + +- name: Install wireguard server on launched hosts + hosts: launched + remote_user: admin + roles: - wireguard_server diff --git a/roles/aws_graviton_nano_spot/tasks/main.yml b/roles/aws_graviton_nano_spot/tasks/main.yml index 88dbc8b..e1d9b39 100644 --- a/roles/aws_graviton_nano_spot/tasks/main.yml +++ b/roles/aws_graviton_nano_spot/tasks/main.yml @@ -3,24 +3,54 @@ name: vpn_key key_material: "{{ lookup('file', '{{ ssh_pub_key_file }}') }}" +- name: network security policy that allows all traffic incoming and outgoing + amazon.aws.ec2_group: + name: "vpn allow all" + description: allow all traffic/protocol/ports + region: "{{ aws_region }}" + rules: + - proto: all + cidr_ip: 0.0.0.0/0 + - proto: all + group_name: "vpn allow all" + rules_egress: + - proto: all + cidr_ip: 0.0.0.0/0 + register: security_group + - name: create graviton spot instance amazon.aws.ec2: + region: "{{ aws_region }}" spot_type: persistent spot_wait_timeout: 120 key_name: vpn_key + group_id: "{{ security_group.group_id }}" instance_type: "{{ aws_type }}" image: "{{ aws_ami }}" wait: yes - assign_public_ip: yes instance_initiated_shutdown_behavior: terminate - register: graviton_instance + register: graviton + +- name: Wait for SSH to come up + delegate_to: "{{ item.public_dns_name }}" + wait_for_connection: + delay: 60 + timeout: 320 + loop: "{{ graviton.instances }}" + +- name: Add new instance to host group + add_host: + hostname: "{{ item.public_ip }}" + groupname: launched + loop: "{{ graviton.instances }}" - name: generate route53 dns entry for the instance route53: command: create overwrite: yes zone: "{{ dns_zone_name }}" - record: "{{ dns_host_name }}" + record: "{{ dns_host_name }}.{{ dns_zone_name }}" type: CNAME ttl: 60 - value: "{{ graviton_instance.domain_name }}" + value: "{{ item.public_dns_name }}" + loop: "{{ graviton.instances }}" \ No newline at end of file diff --git a/roles/wireguard_server/tasks/main.yml b/roles/wireguard_server/tasks/main.yml index 0d528c0..450bda1 100644 --- a/roles/wireguard_server/tasks/main.yml +++ b/roles/wireguard_server/tasks/main.yml @@ -9,8 +9,94 @@ - "wireguard-dkms" state: absent -- name: (Ubuntu) Install wireguard package +- name: Install wireguard package apt: name: "wireguard" state: present +- name: Install qrencode package + apt: + name: "qrencode" + state: present + +- name: Reboot to use new kernel + reboot: + +- name: ensure all wireguard services are stopped and enabled + service: + name: "wg-quick@wg0" + state: stopped + enabled: yes + +- name: generate directories for client configs + file: + path: "~/wg/client_{{ item }}" + state: directory + owner: root + group: root + mode: 0700 + with_sequence: start=1 end={{ vpn_clients }} + +- name: generate private and public keys for the client and server + shell: umask 077; wg genkey | tee ~/wg/{{ item }}.private | wg pubkey > ~/wg/{{ item }}.public + register: key_files + with_sequence: start=1 end={{ vpn_clients }} + +- name: register private key file contents + shell: cat ~/wg/{{ item }}.private + register: private_key_files + with_sequence: start=1 end={{ vpn_clients }} + +- name: register public key file contents + shell: cat ~/wg/{{ item }}.public + register: public_key_files + with_sequence: start=1 end={{ vpn_clients }} + +- name: generate client configs + template: + src: "wg0-client.conf" + dest: "~/wg/client_{{ item }}/wg0-client.conf" + owner: root + group: root + mode: 0600 + with_sequence: start=1 end={{ vpn_clients }} + +- name: generate qr codes for client configs + shell: umask 077; qrencode --type=PNG --output=/root/wg/client_{{ item }}/wg0-client.png < ~/wg/client_{{ item }}/wg0-client.conf + with_sequence: start=1 end={{ vpn_clients }} + +- name: generate server config + template: + src: "wg0.conf" + dest: "/etc/wireguard/wg0.conf" + owner: root + group: root + mode: 0600 + +- name: enable ipv4 traffic forwarding + sysctl: + name: net.ipv4.ip_forward + value: "1" + sysctl_set: yes + state: present + reload: yes + +- name: ensure all wireguard services are started + service: + name: "wg-quick@wg0" + state: started + +- name: download client conf files to the "wireguard_profiles/" folder on your local host + fetch: + src: "~/wg/client_{{item}}/wg0-client.conf" + dest: "wireguard_profiles/{{ ansible_ssh_host }}/client_{{item}}/" + flat: yes + with_sequence: start=1 end={{ vpn_clients }} + +- name: download client qr codes to the "wireguard_profiles/" folder on your local host + fetch: + src: "~/wg/client_{{item}}/wg0-client.png" + dest: "wireguard_profiles/{{ ansible_ssh_host }}/client_{{item}}/" + flat: yes + with_sequence: start=1 end={{ vpn_clients }} + \ No newline at end of file diff --git a/roles/wireguard_server/templates/wg0-client.conf b/roles/wireguard_server/templates/wg0-client.conf new file mode 100644 index 0000000..a4e7cbc --- /dev/null +++ b/roles/wireguard_server/templates/wg0-client.conf @@ -0,0 +1,10 @@ +[Interface] +Address = {{ vpn_network }}.{{item|int + 1}}/32 +DNS = {{ vpn_network }}.1 +PrivateKey = {{ private_key_files.results[item|int].stdout }} + +[Peer] +PublicKey = {{ public_key_files.results[0].stdout }} +AllowedIPs = 0.0.0.0/0 +Endpoint = {{ ansible_default_ipv4.address }}:{{ vpn_port }} +PersistentKeepalive = {{ vpn_persistent_keepalive }} diff --git a/roles/wireguard_server/templates/wg0.conf b/roles/wireguard_server/templates/wg0.conf new file mode 100644 index 0000000..a011f78 --- /dev/null +++ b/roles/wireguard_server/templates/wg0.conf @@ -0,0 +1,12 @@ +[Interface] +Address = {{ vpn_network }}.1/24 +SaveConfig = true +ListenPort = {{ vpn_port }} +PrivateKey = {{ private_key_files.results[0].stdout }} + +{% for i in range(vpn_clients) %} +[Peer] +PublicKey = {{ public_key_files.results[i + 1].stdout }} +AllowedIPs = {{ vpn_network }}.{{ i + 2 }}/32 + +{% endfor %} \ No newline at end of file diff --git a/wireguard.yml b/wireguard.yml new file mode 100644 index 0000000..ad86213 --- /dev/null +++ b/wireguard.yml @@ -0,0 +1,23 @@ +--- +- name: set defaults + vars: + vpn_network: '10.100.100' + vpn_port: '58172' + vpn_clients: 1 + +# manually prepare inventory +- name: add host + hosts: localhost + tasks: + - name: manually add host + add_host: + hostname: "illevpn.appments.net" + groupname: launched + +# Provisioning of a graviton server using aws spot instance +- name: Install wireguard server on launched hosts + hosts: launched + remote_user: admin + become: yes + roles: + - wireguard_server