DEV Community

Cover image for Automating WireGuard VPN Setup with Ansible Ec2 Linux: A Step-by-Step Guide
Gias Uddin
Gias Uddin

Posted on

Automating WireGuard VPN Setup with Ansible Ec2 Linux: A Step-by-Step Guide

In the rapidly evolving world of cybersecurity, Virtual Private Networks (VPNs) play a critical role in ensuring data privacy and secure communication. WireGuard is one such modern VPN solution known for its simplicity, speed, and state-of-the-art cryptography. This guide will show you how to automate the installation and configuration of WireGuard on your Linux server using Ansible.

By the end of this article, you'll have a fully operational WireGuard VPN server with key generation, IP forwarding, and client configuration, all managed through Ansible playbooks.

Prerequisites
Before we dive into the Ansible playbook, ensure that:

  • You have an Ec2 Linux machine.
  • you have a .pem file to access to access on that ec2 Machine

Make sure you have a proper security group in the EC2, ensure all port are enable

SSH (TCP 22): Allows SSH access from any IP address (0.0.0.0/0), which could be a security risk since it opens the SSH port to the entire internet. Consider restricting this to known IPs.
HTTPS (TCP 443): Allows secure web traffic (HTTPS) from any IP address (0.0.0.0/0).
Custom UDP (51820): This is the port used for WireGuard VPN. It's open to all IP addresses (0.0.0.0/0).
HTTP (TCP 80): Allows regular web traffic (HTTP) from any IP address (0.0.0.0/0).
Custom UDP (53): Allows DNS traffic over UDP from any IP address (0.0.0.0/0).
Recommendations:
Restrict SSH access: Limit access to specific IPs rather than allowing 0.0.0.0/0 for security.
WireGuard (51820): This rule is needed for WireGuard to function, but like SSH, it's best to restrict it to known IP ranges if possible.
HTTP/HTTPS (80/443): These are common web traffic ports and should remain open unless you're not hosting a web application.
DNS (UDP 53): Ensure this is necessary, as opening it widely can expose your server to potential risks.

Why Automate with Ansible?
Automating WireGuard setup with Ansible saves time, reduces manual errors, and allows for consistency across different environments. Whether you're deploying one server or managing multiple VPN nodes, Ansible streamlines the process.

Step-by-Step Breakdown of the Ansible Playbook
Below is a sample playbook for setting up WireGuard on a Linux server. This playbook covers package installation, key generation, configuration file creation, and service management.

Download full source code from GitHub

  # Step 1: Install WireGuard and Dependencies
  - name: Install WireGuard and related packages
    apt:
      name:
        - wireguard
        - resolvconf
        - vim
      state: present

  # Step 2: Generate WireGuard Private Key
  - name: Generate WireGuard private key
    command: wg genkey
    register: wg_private_key

  # Step 3: Save Private Key to File
  - name: Save private key to file
    copy:
      content: "{{ wg_private_key.stdout }}"
      dest: /etc/wireguard/private.key
      mode: '0600'

  # Step 4: Generate Public Key from Private Key
  - name: Generate WireGuard public key from private key
    shell: echo "{{ wg_private_key.stdout }}" | wg pubkey
    register: wg_public_key

  # Step 5: Save Public Key to File
  - name: Save public key to file
    copy:
      content: "{{ wg_public_key.stdout }}"
      dest: /etc/wireguard/public.key
      mode: '0644'

  # Client Key Creation

  # Step 6: Create Directory for Client Keys
  - name: Create client directory for WireGuard keys
    file:
      path: /etc/wireguard/client
      state: directory
      mode: '0755'

  # Step 7: Generate Private Key for Client
  - name: Generate private key for client
    shell: wg genkey | tee /etc/wireguard/client/client_private_key
    register: client_private_key

  # Step 8: Generate Public Key for Client
  - name: Generate public key for client
    shell: cat /etc/wireguard/client/client_private_key | wg pubkey
    register: client_public_key

  # Step 9: Save Client Public Key to File
  - name: Save client public key to file
    copy:
      content: "{{ client_public_key.stdout }}"
      dest: /etc/wireguard/client/client_public_key
      mode: '0644'

  # Step 10: Create WireGuard Server Configuration File
  - name: Create WireGuard configuration file
    template:
      src: wg0.conf.j2
      dest: /etc/wireguard/wg0.conf
      mode: '0644'

  # Step 11: Create WireGuard Client Configuration File
  - name: Create WireGuard client configuration file
    template:
      src: clientvpn.conf.j2
      dest: /etc/wireguard/client/clientvpn.conf
      mode: '0644'

  # Step 12: Enable WireGuard on Boot
  - name: Enable WireGuard on boot
    systemd:
      name: wg-quick@wg0
      enabled: yes

  # Step 13: Start WireGuard Service
  - name: Start WireGuard service
    systemd:
      name: wg-quick@wg0
      state: started

  # Step 14: Enable IP Forwarding
  - name: Enable IP forwarding by adding to /etc/sysctl.conf
    shell: echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.conf

  # Step 15: Apply the Changes in sysctl.conf
  - name: Reload sysctl to apply the changes
    command: sysctl -p

  # Step 16: Ensure WireGuard Interface is Up
  - name: Check if WireGuard interface is already up
    shell: ip link show wg0
    register: wg0_interface_check
    ignore_errors: yes

  # Step 17: Bring Up WireGuard Interface if Not Already Up
  - name: Bring up WireGuard interface if it's not already up
    command: wg-quick up wg0
    when: wg0_interface_check.rc != 0

  # Step 18: Restart WireGuard Service
  - name: Restart WireGuard service
    systemd:
      name: wg-quick@wg0
      state: restarted

  # Step 19: Download Client Configuration for Local Use
  - name: Download WireGuard client configuration file
    fetch:
      src: /etc/wireguard/client/clientvpn.conf
      dest: ./clientvpn.conf
      flat: yes

Enter fullscreen mode Exit fullscreen mode

Follow the github instructions, you can complete your setup

Conclusion
You have successfully set up WireGuard on an AWS EC2 instance and configured a client. This setup ensures secure access to your private network while keeping your instance accessible only through necessary ports.
If you need technical consulting on your project, check out our website or connect with me directly.

Top comments (0)