Giter Site home page Giter Site logo

wireguard_ansible's Introduction

wireguard_ansible

This is the ansible automation of the Wireguard VPN set up described here https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/

This will create ten VPN client profiles when done.

This project has also been restructured as an ansible role for inclusion in other ansible playbooks.

Requirements

This assumes an ubuntu 16.04 or 18.04 client. It should also work on other platforms with minimal tweaking.

Install git

sudo apt-get install git

Install ansible

sudo apt-add-repository ppa:ansible/ansible -y
sudo apt-get update && sudo apt-get install ansible -y

For optimal use, use ansible version greater than 2.5

Server set up

This assumes you have an Ubuntu 16.04 server with ssh access on port 22. Ensure that you've already added the server key to your known hosts file by sshing into it at least once. If you are using an SSH key, then you can forgo that.

Quick setup

On the client

git clone https://github.com/iamckn/wireguard_ansible
cd wireguard_ansible

Edit the hosts file in that folder and fill in the IP field with the VPN server IP

Begin the remote installation process by running

ansible-playbook wireguard.yml -u root -k -i hosts

If you're using an SSH key for authentication run this instead

ansible-playbook wireguard.yml -u root -i hosts --key-file /path/to/keyfile

Give it a few minutes and the server set up will be complete.

Ten client configs will be created on the VPN server in the folder /root/wg_clients. They will also be downloaded to the wireguard_role/profiles folder on your local host.

Assuming you're using the first client config, copy it to /etc/wireguard/ and you can start using the VPN tunnel on your client.

To bring up the VPN interface

sudo wg-quick up wg0-client

To bring down the VPN interface

sudo wg-quick down wg0-client

To view connection details

sudo wg show

Advanced use

You have the option of determining the vpn network subnet you prefer your clients to use by editing the file wireguard_role/defaults/main.yml, and setting the vpn_network variable as desired. You can also change the vpn server port and the number of client profiles you want generated in the same file:

vpn_network: '10.200.200'

vpn_port: '51820'

clients: 10

Adding a client

If you want to generate an additional client profile in future, edit the following two variables in wireguard_role/tasks/main.yml to your specific needs:

    new_client: newclient
    new_client_ip: 10.200.200.12

Then run the setup process again but now with the tag add_client specified:

ansible-playbook wireguard.yml -u root -k -i hosts -t add_client

The new client config will then be downloaded to the wireguard_role/profiles folder on your local host.

Note: This needs to be run from the directory the initial setup was done from and not from a newly cloned one.

Use as an ansible role

This project has been structured as an ansible role. You can therefore include it in other ansible playbooks

- name: Setup Wireguard VPN
  hosts: all
  gather_facts: true
  roles:
    - {role: 'wireguard_role', tags: 'wireguard'}

DNS

If there is another service listening on port 53, you will have issues with getting DNS resolution working. It is therefore advisable to either disable or change the port of any service already using port 53. This will automatically be handled for you on Ubuntu 18.04 when you run this playbook.

wireguard_ansible's People

Contributors

iamckn avatar testpersonal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wireguard_ansible's Issues

iptables rules don't necessarily persist past reboots in Ubuntu 18.04.1

Fixing Ubuntu 18.04 DNS in #6 required rebooting the server.

While troubleshooting the resulting total connection failure, I re-ran the playbook.

After doing so, the connection started working again (given the POSTROUTING wg0.conf lines discussed in #6).

The reason for the connection failure therefore appears to be that some of the iptables rules were wiped during reboot.

The following items were changed on the playbook re-run:

TASK [wireguard_ansible/wireguard_role : Enable IPv4 forwarding continued] **********************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Track input chain] *************************************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Track forward chain] ***********************************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Allow incoming wireguard connections] ******************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Allow recursive DNS tcp] *******************************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Allow recursive DNS udp] *******************************************************************************************************************************************
changed: [myserver]

TASK [wireguard_ansible/wireguard_role : Allow forwarding of packets that stay in the tunnel] ***************************************************************************************************************
changed: [myserver]

...

TASK [wireguard_ansible/wireguard_role : Set up iptables persistence] ***************************************************************************************************************************************
changed: [myserver]

To check whether this was a function of the reboot, or whether these playbook tasks are simply not idempotent, I re-ran the playbook again immediately. This time only the following tasks came back 'changed':

TASK [wireguard_ansible/wireguard_role : Enable IPv4 forwarding continued] **********************************************************************************************************************************
changed: [myserver]

...

TASK [wireguard_ansible/wireguard_role : Set up iptables persistence] ***************************************************************************************************************************************
changed: [myserver]

It looks like quite a few of the iptables rules are not persisting past reboots in Ubuntu 18.04.

Refactoring: Keys and client files should be iterated over, not handled manually

Rather than doing one_private key, two_private_key or having to individually do Generate client one config, Generate client two config, we should be able to:

  • access keys by either a name or an index, so priv_key[1] or priv_key['one'] instead of one_private_key, and
  • use one task to handle repetitive client config generation, such as
- name: Generate client configs
  template:
    src: "templates/{{item}}.conf"
    dest: "~/{{item}}.conf"
    owner: root
    group: root
    mode: 0600
  with_items:
    - one
    - two
    - three
    - four

instead of doing:

  - name: Generate client one config
    template:
      src: "templates/one.conf"
      dest: "~/one.conf"
      owner: root
      group: root
      mode: 0600

  - name: Generate client two config
    template:
      src: "templates/two.conf"
      dest: "~/two.conf"
      owner: root
      group: root
      mode: 0600

Error

I got this error when I run ansible-playbook wireguard.yml -u root -k -i hosts

fatal: [172.31.43.89]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey).", "unreachable": true}
to retry, use: --limit @/home/ubuntu/wireguard_ansible/wireguard.retry

PLAY RECAP *********************************************************************
172.31.43.89 : ok=0 changed=0 unreachable=1 failed=0

I setup my hosts as

[all]

172.31.43.89 ansible_python_interpreter=/usr/bin/python

I run this on Amazon EC2 , ubuntu 14

10 profiles not in /home but in /root

Hi
(Awesome project this, thank you so much!)

This might be a newbie linux thing but the ten profiles can't actually be found in the "home" as the instructions say, but they are in /root. Maybe clear that up a bit more? I spent ten minutes looking in /home where they obviously weren't.

Thanks again! (I'll be using this a lot lol)

iptables NAT configuration doesn't forward packets

The stock NAT iptables configuration does not seem to be enough for me:

 - name: Set up NAT
   iptables:
     table: nat
     chain: POSTROUTING
     source: 10.200.200.0/24
     out_interface: "{{ ansible_default_ipv4.interface }}"
     jump: MASQUERADE

If I leave it this way, then I can send ICMP echo traffic over the VPN but every other kind of traffic seems to stop at the VPN server.

Instead I am finding it necessary to add to the wg0-server.conf some lines I found in another Wireguard walkthrough:

[Interface]
Address = 10.200.200.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = {{ server_private_key }}
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

I am not very familiar with iptables but I assume the correct Ansible block would therefore be:

 - name: Forward packets from the tunnel to the outside world
   iptables:
     chain: FORWARD
     in_interface: wg0
     match: conntrack
     ctstate: NEW
     jump: ACCEPT

 - name: Set up NAT
   iptables:
     table: nat
     chain: POSTROUTING
     out_interface: "{{ ansible_default_ipv4.interface }}"
     jump: MASQUERADE

Does this make sense?

Note: the "{{ ansible_default_ipv4.interface }}" is a System Fact and requires gather_facts: true in the main playbook

what about ipv6?

Hello,

What about ipv6 and how to provide clients with global ipv6 address if I have /64 ipv6 subnet on server?

Thanks.

Multi-hop with WireGuard

Hello,

I just installed WireGuard with UI on two different virtual private servers (https://github.com/ngoduykhanh/wireguard-ui/).
Everything is working properly and has been independently tested on both servers, and clients will connect to the VPN without issue. The internet was also working properly during their connection.

I want to run the following configuration (Multi-hop with WireGuard or Chaining Servers with WireGuard):
Client → Server1 → Server2 → Public Internet

For example
Client (IP: 123.123.123.1) → VPN1 (VPS1: 90.90.90.1) → VPN2 (VPS2: 80.80.80.1) → Google.com (assumes the user's IP address is 80.80.80.1).

Now here are my questions:

  1. All configurations are detailed step-by-step on VPS1 to route all traffic to VPS2.
  2. All configurations are detailed step-by-step on VPS2.

NOTES:

  • The operating system on VPS1 and VPS2 is Ubuntu 20.04.
  • VPS1 and VPS2 are on different networks, so authentication may be required to connect them together, and I do not know how.
  • I know it's possible with IP routing, but I don't have detailed step-by-step instructions.

I would be grateful if you could guide me in full detail.

Also, if it is possible for you to make the configurations for me on both servers and also send the description of the steps in a document or video, I can pay the fee you declare via crypto-currency, PayPal, etc.

Thank you.

Regards,
Nigel.

Make this a role

This should be formatted as a Role so that it can be incorporated into other playbooks, by

cd my_playbook/roles
git pull [wireguard_ansible repository url]

I have the major changes done (moving things into tasks/ etc, renaming wireguard.yml to main.yml, etc).

However the issue remains how to create a playbook.yml that can live in the wireguard_ansible directory:

#
# Unfinished: As written this file needs to be placed in ../../ and the
# current directory in ../roles/, so e.g
#   - ~/my_playbook/playbook.yml
#   - ~/my_playbook/roles/wireguard_ansible/
#
# There is probably a way to include the files directly without the
# `roles` directory structure, while maintaining the ability to use
# the current directory as a role:
#   https://docs.ansible.com/ansible/2.3/playbooks_roles.html
#
- name: Setup VPN
  hosts: all
  gather_facts: true
  roles:
    - {role: 'wireguard_ansible', tags: 'wireguard'}

I've made quite a lot of other minor fixes as well:

  • automatically turn off systemd-resolved if needed,
  • make the playbook idempotent and only generate keys if the config files don't exist, don't nuke the keys on every run
  • make rebooting the server a handler which only runs if it needs to be run,
  • automatically detect the ipv4 interface name if it is not eth0,
  • automatically fetch client config from the server

However, submitting pull requests for those is not practical unless we get the role-friendly directory structure solved, since my files have already been rearranged to fit the role structure.

(I also have to do some minor debugging and figure out why connections are not working, oops!)

Error: Destination directory /etc/wireguard does not exist

Seems to plug along OK until:

TASK [wireguard_role : Generate server config] *******************************************************************************************************************************************************************************************************************************************************************************
fatal: [linode.example.com]: FAILED! => {"changed": false, "checksum": "e6bdaa293e4cd1bedebe62b54ec805b76884cdba", "msg": "Destination directory /etc/wireguard does not exist"} 
PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************************************************************
linode.example.com   : ok=12   changed=8    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0 

DNS/unbound not working when using on Ubuntu 18.04

As you may have noted from my other issue I have been messing around with this project a bit and found that if the ansible scripts are ran from a Ubuntu 18.04 client to an Ubuntu 16.04 server all is well, but running to configure a 18.04 server messes up. DNS won't work, neither from a connected client or a local lookup via unbound-control. Not sure where it goes wrong, I am just getting into linux (and already in over my head I think) but that's what I found.

I know the readme says the scripts are for 16.04 so if you won't be looking into this just close the issue instantly and that'll be that.

Edit: upon further trial and error it seems unbound is accepting and resolving hostnames via unbound-control and dig, but my dns is still leaking if browsing

DNS and ICMP works, but that's it

$ sudo wg-quick up wg0-client                                                                                                                                                                                                                                             
[#] ip link add wg0-client type wireguard
[#] wg setconf wg0-client /dev/fd/63
[#] ip -4 address add 10.200.200.2/32 dev wg0-client
[#] ip link set mtu 1420 up dev wg0-client
[#] resolvconf -a wg0-client -m 0 -x
Too few arguments.
Too few arguments.
[#] wg set wg0-client fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0-client table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
michael@corwin ~/source/wireguard_ansible$ ping -c1 google.com                                                                                                                                                                                                                                                     
PING google.com (216.58.194.206) 56(84) bytes of data.
64 bytes from sfo03s01-in-f14.1e100.net (216.58.194.206): icmp_seq=1 ttl=57 time=33.2 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 33.165/33.165/33.165/0.000 ms

Awesome, DNS and ICMP are working

`curl www.google.com` just hangs.

$ sudo wg show
interface: wg0-client
public key: {redacted}
private key: (hidden)
listening port: 57514
fwmark: 0xca6c

peer: {redacted}
endpoint: {redacted}:51820
allowed ips: 0.0.0.0/0
latest handshake: 30 seconds ago
transfer: 13.77 KiB received, 41.77 KiB sent
persistent keepalive: every 21 seconds

Lost original ansible install directory and need to add clients

I've lost my original ansible install directory and need to add more clients how can I do this?

I've tried manually creating the public and private keys and adding to /etc/wireguard/wg0.conf but when you restart the service it reverts to the original wg0.conf

Failed to connect to the host via ssh: ssh

TASK [Gathering Facts] *****************************************************************************************
fatal: [<35.236.----->]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname <35.236.----->: Name or service not known", "unreachable": true}
to retry, use: --limit @/home/myaccount/wireguard_ansible/wireguard.retry

PLAY RECAP *****************************************************************************************************
<35.236.------> : ok=0 changed=0 unreachable=1 failed=0

I am using Google cloud platform with SSH Key

fatal: [<my-server-ip>]: UNREACHABLE! =>

Hello,

Two question:

1#fatal:
On ubuntu, I install it on Linode server with SSH shell by following installation tutorial at https://github.com/iamckn/wireguard_ansible#quick-setup


Edit the hosts file in that folder and fill in the IP field with the VPN server IP

Begin the remote installation process by running

ansible-playbook wireguard.yml -u root -k -i hosts

before running command ansible-playbook wireguard.yml -u root -k -i hosts, I did input server ip in hosts file under directory of /wireguard_ansible, bu there is fatal error as below, and I replace real ip with my-server-ip:

`fatal: []: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname : Name or service not known", "unreachable": true}

PLAY RECAP *********************************************************************
: ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 `

or check the screenshot please: https://prnt.sc/10jn88k
what did I missed please?

2# Prevent DNS leak
By the way, after wireguard_ansible installation, do I still need configure to prevent DNS leaking as tutorial at https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/

Thanks

skipping some steps

Hi there!
I'm running the commands, as mentioned in the readme file. But the problem is, it is skipping some steps and then fails at the end (because it skipped creating client files and 14 other actions!)
Is there anything I can do to fix that?

Reasoning for (number of) firewall rules?

Hi,

First of all, thanks for your work, your very detailed article and for taking the time to turn it all into an Ansible playbook.

Keeping in mind that my knowledge of firewall rules is still quite crude, I was trying to understand why your setup uses 7 rules when other guides I've seen only use one:

iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE

(ens3 or eth0 or whatever your uplink interface is called)

or three:

iptables -A FORWARD -i %i -j ACCEPT
iptables -A FORWARD -o %i -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

(Thes other setups I mention also put these rules in the wgX.conf, to ensure they are added and removed by Wireguard when the wg interface is brought up and down, as necessary, and does it for both IPv4 and IPv6. Example:
PostUp = iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE)

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.