Initial commit
This commit is contained in:
95
roles/wireguard/README.md
Normal file
95
roles/wireguard/README.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# `flyoverhead.openwrt.wireguard`
|
||||
|
||||
OpenWRT `wireguard` configuration
|
||||
- create and configure wireguard interfaces
|
||||
- create and configure wireguard peers
|
||||
|
||||
## Role Variables
|
||||
|
||||
| Variable | Descritpion | Status | Type | Default/Example |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| `wireguard_pkgs` | List of wireguard packages to be installed | `required` | `list` | `["wireguard-tools", "luci-proto-wireguard", "luci-app-wireguard", "qrencode"]` |
|
||||
| `wireguard_interfaces` | List of [wireguard network interfaces](https://openwrt.org/docs/guide-user/services/vpn/wireguard/server#network) to be configured | | `list of dictionaries` | |
|
||||
|  `id` | Unique wireguard server interface ID | `mandatory` | `string` | `wg0` |
|
||||
|  `state` | Interface status (`present` or `absent`) | `required` | `string` | `present` |
|
||||
|  `proto` | Interface protocol | `mandatory` | `string` | `wireguard` |
|
||||
|  `private_key` | Wireguard server private key (will be generated automatically when omit) | `optional` | `string` | `null` |
|
||||
|  `addresses` | Wireguard server IP address in CIDR notation | `required` | `string` | `192.168.10.1/32` |
|
||||
|  `listen_port` | Wireguard server listening port | `required` | `string` | `51820` |
|
||||
|  `peers` | List of wireguard peers to be generated automatically | `required` | `list` | `["mobile", "desktop"]` |
|
||||
| `wireguard_peers` | List of [wireguard peers](https://openwrt.org/docs/guide-user/services/vpn/wireguard/client#network) | | `list of dictionaries` | |
|
||||
|  `id` | Unique peer ID | `mandatory` | `string` | `example_peer` |
|
||||
|  `name` | Unique peer name | `mandatory` | `string` | `Wireguard peer` |
|
||||
|  `state` | Peer status (`present` or `absent`) | `required` | `string` | `present` |
|
||||
|  `public_key` | Peer public key | `mandatory` | `string` | `example_public_key` |
|
||||
|  `preshared_key` | Peer preshared key | `required` | `list` | `example_preshared_key` |
|
||||
|  `endpoint_host` | Wireguard server (endpoint) public IP address | `required` | `string` | `192.168.2.1` |
|
||||
|  `endpoint_port` | Wireguard server (endpoint) listening port | `required` | `integer` | `51820` |
|
||||
|  `route_allowed_ips` | Create routes for allowed IPs | `optional` | `boolean` | `0` |
|
||||
|  `persistent_keepalive` | Set keep alive messages interval in seconds | `optional` | `integer` | `25` |
|
||||
|  `allowed_ips` | IP addresses and prefixes that are allowed to use inside the tunnel | `required` | `list` | `["0.0.0.0/0"]` |
|
||||
|  `wireguard_interface_name` | Wireguard associated interface name | `required` | `string` | `wg0` |
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Name | Description |
|
||||
| :--- | :--- |
|
||||
| `Ansible Role: openwrt` | [Ansible role by gekmihesg](https://github.com/gekmihesg/ansible-openwrt) for managing OpenWRT and derivatives |
|
||||
|
||||
## Example Playbook
|
||||
|
||||
```yaml
|
||||
- hosts: openwrt
|
||||
roles:
|
||||
- role: flyoverhead.openwrt.wireguard
|
||||
```
|
||||
|
||||
## Example Vars
|
||||
|
||||
### Server Mode
|
||||
|
||||
```yaml
|
||||
wireguard_interfaces:
|
||||
- name: "wg0"
|
||||
state: "present"
|
||||
proto: "wireguard"
|
||||
addresses: "192.168.2.1/32"
|
||||
port: "51820"
|
||||
peers: ["mobile_peer", "desktop_peer"]
|
||||
```
|
||||
|
||||
### Client Mode
|
||||
|
||||
```yaml
|
||||
wireguard_interfaces:
|
||||
- id: "wg1"
|
||||
state: "present"
|
||||
proto: "wireguard"
|
||||
private_key: "private_key"
|
||||
addresses: "192.168.2.2/32"
|
||||
wireguard_peers:
|
||||
- id: "vps"
|
||||
name: "Example VPS"
|
||||
state: "present"
|
||||
public_key: "public_key"
|
||||
preshared_key: "preshared_key"
|
||||
endpoint_host: "192.168.2.1"
|
||||
endpoint_port: "51820"
|
||||
route_allowed_ips: "0"
|
||||
persistent_keepalive: 25""
|
||||
allowed_ips: ["0.0.0.0/0"]
|
||||
wireguard_interface_name: "wg1"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
## Author Information
|
||||
|
||||
fly0v3rH34D
|
||||
|
||||
## References
|
||||
|
||||
- https://openwrt.org/docs/guide-user/services/vpn/wireguard/server
|
||||
- https://openwrt.org/docs/guide-user/services/vpn/wireguard/client
|
||||
28
roles/wireguard/defaults/main.yml
Normal file
28
roles/wireguard/defaults/main.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# Wireguard packages
|
||||
wireguard_pkgs:
|
||||
["wireguard-tools", "luci-proto-wireguard", "luci-app-wireguard", "qrencode"]
|
||||
|
||||
# Wireguard servers
|
||||
wireguard_interfaces:
|
||||
- id: ""
|
||||
state: ""
|
||||
proto: ""
|
||||
private_key: ""
|
||||
addresses: ""
|
||||
listen_port: ""
|
||||
peers: []
|
||||
|
||||
# Wireguard peers
|
||||
wireguard_peers:
|
||||
- id: ""
|
||||
name: ""
|
||||
state: ""
|
||||
public_key: ""
|
||||
preshared_key: ""
|
||||
endpoint_host: ""
|
||||
endpoint_port: ""
|
||||
route_allowed_ips: ""
|
||||
persistent_keepalive: ""
|
||||
allowed_ips: []
|
||||
wireguard_interface_name: ""
|
||||
6
roles/wireguard/handlers/main.yml
Normal file
6
roles/wireguard/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# Reload network service
|
||||
- name: Reload network
|
||||
ansible.builtin.service:
|
||||
name: network
|
||||
state: reloaded
|
||||
12
roles/wireguard/meta/main.yml
Normal file
12
roles/wireguard/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: flyoverhead
|
||||
description: Configure wireguard
|
||||
license: GPL-3.0
|
||||
min_ansible_version: "2.13"
|
||||
platforms:
|
||||
- name: OpenWrt
|
||||
versions: ["22.03"]
|
||||
galaxy_tags: ["openwrt", "wireguard"]
|
||||
dependencies:
|
||||
- role: gekmihesg.openwrt
|
||||
23
roles/wireguard/tasks/main.yml
Normal file
23
roles/wireguard/tasks/main.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# Install required packages
|
||||
- name: Install required packages
|
||||
ansible.builtin.include_tasks: prepare.yml
|
||||
|
||||
# Configure wireguard interfaces
|
||||
- name: Configure wireguard interfaces
|
||||
ansible.builtin.include_tasks: server.yml
|
||||
loop: "{{ wireguard_interfaces | default([]) }}"
|
||||
|
||||
# Configure wireguard peers
|
||||
- name: Configure wireguard peers
|
||||
ansible.builtin.include_tasks: peer.yml
|
||||
loop: "{{ wireguard_peers | default([]) }}"
|
||||
loop_control:
|
||||
loop_var: wgpeer
|
||||
label: "{{ wgpeer }}"
|
||||
|
||||
# Apply changes and reload network service
|
||||
- name: Apply changes and reload network
|
||||
uci:
|
||||
command: commit
|
||||
notify: Reload network
|
||||
128
roles/wireguard/tasks/peer.yml
Normal file
128
roles/wireguard/tasks/peer.yml
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
# Configure user-defined wireguard peer
|
||||
- name: Configure user-defined wireguard peer
|
||||
when: wgpeer is defined and wgpeer | type_debug == "dict"
|
||||
block:
|
||||
# Set state status for wireguard peer
|
||||
- name: Set state status for wireguard peer {{ wgpeer.id }}
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_peer_state: "{{ wgpeer.state | default('present') }}"
|
||||
|
||||
# Delete wireguard peer
|
||||
- name: Delete wireguard peer {{ wgpeer.id }}
|
||||
when: "'absent' in wireguard_peer_state"
|
||||
uci:
|
||||
command: "absent"
|
||||
config: "network"
|
||||
section: "{{ wgpeer.id }}"
|
||||
type: "wireguard_{{ wgpeer.wireguard_interface_name }}"
|
||||
|
||||
# Create and configure wireguard peer
|
||||
- name: Create and configure wireguard peer
|
||||
when: "'present' in wireguard_peer_state"
|
||||
block:
|
||||
# Create wireguard peer
|
||||
- name: Create wireguard peer {{ wgpeer.id }}
|
||||
uci:
|
||||
command: "add"
|
||||
config: "network"
|
||||
section: "{{ wgpeer.id }}"
|
||||
type: "wireguard_{{ wgpeer.wireguard_interface_name }}"
|
||||
|
||||
# Configure wireguard peer
|
||||
- name: Configure wireguard peer {{ wgpeer.id }}
|
||||
uci:
|
||||
command: "set"
|
||||
config: "network"
|
||||
section: "{{ wgpeer.id }}"
|
||||
type: "wireguard_{{ wgpeer.wireguard_interface_name }}"
|
||||
value:
|
||||
description: "{{ wgpeer.name | default(omit) }}"
|
||||
public_key: "{{ wgpeer.public_key | default(omit) }}"
|
||||
preshared_key: "{{ wgpeer.preshared_key | default(omit) }}"
|
||||
endpoint_host: "{{ wgpeer.endpoint_host | default(omit) }}"
|
||||
endpoint_port: "{{ wgpeer.endpoint_port | default(omit) }}"
|
||||
route_allowed_ips: "{{ wgpeer.route_allowed_ips | default(omit) }}"
|
||||
persistent_keepalive: "{{ wgpeer.persistent_keepalive | default(omit) }}"
|
||||
allowed_ips: "{{ wgpeer.allowed_ips | default([]) | join(' ') }}"
|
||||
|
||||
# Generate wireguard peer
|
||||
- name: Generate wireguard peer
|
||||
when: wgpeer is defined and wgpeer | type_debug == "str"
|
||||
block:
|
||||
# Create wireguard peer
|
||||
- name: Create wireguard peer {{ wgpeer }}
|
||||
uci:
|
||||
command: "add"
|
||||
config: "network"
|
||||
section: "{{ wgpeer }}"
|
||||
type: "{{ wireguard_interface_name }}"
|
||||
|
||||
# Check current wireguard private key
|
||||
- name: Check current wireguard private key
|
||||
uci:
|
||||
command: "get"
|
||||
config: "network"
|
||||
section: "{{ wgpeer }}.private_key"
|
||||
type: "{{ wireguard_interface_name }}"
|
||||
register: current_wireguard_private_key
|
||||
failed_when: >
|
||||
current_wireguard_private_key.result is undefined and
|
||||
'Entry not found' not in current_wireguard_private_key.result
|
||||
|
||||
# Set current generated wireguard private key fact
|
||||
- name: Set current wireguard private key fact
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_private_key: "{{ current_wireguard_private_key.result }}"
|
||||
when: >
|
||||
(current_wireguard_private_key.result is defined and
|
||||
current_wireguard_private_key.result | length > 0) and
|
||||
'Entry not found' not in current_wireguard_private_key.result
|
||||
|
||||
# Generate wireguard key pair
|
||||
- name: Generate wireguard key pair
|
||||
when: >
|
||||
current_wireguard_private_key.result is undefined or
|
||||
'Entry not found' in current_wireguard_private_key.result
|
||||
block:
|
||||
# Generate wireguard private key
|
||||
- name: Generate wireguard private key
|
||||
ansible.builtin.command:
|
||||
cmd: "umask go= && wg genkey"
|
||||
uses_shell: true
|
||||
register: new_wireguard_private_key
|
||||
|
||||
# Set newely generated wireguard private key fact
|
||||
- name: Set newely generated wireguard private key fact
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_private_key: "{{ new_wireguard_private_key.stdout }}"
|
||||
|
||||
# Generate wireguard public key
|
||||
- name: Generate wireguard public key
|
||||
ansible.builtin.command:
|
||||
cmd: 'umask go= && echo "{{ wireguard_private_key }}" | wg pubkey'
|
||||
uses_shell: true
|
||||
register: wireguard_public_key
|
||||
|
||||
# Generate wireguard preshared key
|
||||
- name: Generate wireguard preshared key
|
||||
ansible.builtin.command:
|
||||
cmd: "umask go= && wg genpsk"
|
||||
uses_shell: true
|
||||
register: wireguard_preshared_key
|
||||
|
||||
# Configure wireguard peer
|
||||
- name: Configure wireguard peer {{ wgpeer }}
|
||||
uci:
|
||||
command: "set"
|
||||
config: "network"
|
||||
section: "{{ wgpeer }}"
|
||||
type: "{{ wireguard_interface_name }}"
|
||||
value:
|
||||
description: "{{ wgpeer }}"
|
||||
private_key: "{{ wireguard_private_key | default(omit) }}"
|
||||
public_key: "{{ wireguard_public_key.stdout | default(omit) }}"
|
||||
preshared_key: "{{ wireguard_preshared_key.stdout | default(omit) }}"
|
||||
route_allowed_ips: "1"
|
||||
persistent_keepalive: "25"
|
||||
allowed_ips: "{{ wireguard_interface_addresses | ansible.utils.ipmath(ansible_loop.index) }}"
|
||||
13
roles/wireguard/tasks/prepare.yml
Normal file
13
roles/wireguard/tasks/prepare.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
# Update opkg cache
|
||||
- name: Update opkg cache
|
||||
ansible.builtin.command:
|
||||
cmd: "opkg update"
|
||||
changed_when: false
|
||||
|
||||
# Install wireguard packages
|
||||
- name: Install wireguard packages
|
||||
opkg:
|
||||
name: "{{ item }}"
|
||||
state: "present"
|
||||
loop: "{{ wireguard_pkgs }}"
|
||||
111
roles/wireguard/tasks/server.yml
Normal file
111
roles/wireguard/tasks/server.yml
Normal file
@@ -0,0 +1,111 @@
|
||||
---
|
||||
# Set state status for wireguard interface
|
||||
- name: Set state status for wireguard interface {{ item.id }}
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_interface_state: "{{ item.state | default('present') }}"
|
||||
|
||||
# Delete wireguard interface
|
||||
- name: Delete wireguard interface {{ item.id }}
|
||||
when: "'absent' in wireguard_interface_state"
|
||||
uci:
|
||||
command: "absent"
|
||||
config: "network"
|
||||
section: "{{ item.id }}"
|
||||
type: "interface"
|
||||
|
||||
# Create and configure wireguard interface
|
||||
- name: Create and configure user-defined wireguard interface
|
||||
when: "'present' in wireguard_interface_state"
|
||||
block:
|
||||
# Create wireguard interface
|
||||
- name: Create wireguard interface {{ item.id }}
|
||||
uci:
|
||||
command: "add"
|
||||
config: "network"
|
||||
section: "{{ item.id }}"
|
||||
type: "interface"
|
||||
|
||||
# Configure wireguard interface
|
||||
- name: Configure user-defined wireguard interface {{ item.id }}
|
||||
when: >
|
||||
item.private_key is defined and
|
||||
item.private_key | length > 0
|
||||
uci:
|
||||
command: "set"
|
||||
config: "network"
|
||||
section: "{{ item.id }}"
|
||||
type: "interface"
|
||||
value:
|
||||
proto: "{{ item.proto | default(omit) }}"
|
||||
private_key: "{{ item.private_key | default(omit) }}"
|
||||
addresses: "{{ item.addresses | default(omit) }}"
|
||||
listen_port: "{{ item.listen_port | default(omit) }}"
|
||||
|
||||
# Configure new wireguard interface
|
||||
- name: Configure new wireguard interface
|
||||
when: >
|
||||
item.private_key is undefined or
|
||||
item.private_key | length == 0
|
||||
block:
|
||||
# Check current wireguard private key
|
||||
- name: Check current wireguard private key
|
||||
uci:
|
||||
command: "get"
|
||||
config: "network"
|
||||
section: "{{ item.id }}.private_key"
|
||||
type: "interface"
|
||||
register: current_wireguard_private_key
|
||||
failed_when: >
|
||||
current_wireguard_private_key.result is undefined and
|
||||
'Entry not found' not in current_wireguard_private_key.result
|
||||
|
||||
# Set current generated wireguard private key fact
|
||||
- name: Set current wireguard private key fact
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_private_key: "{{ current_wireguard_private_key.result }}"
|
||||
when: >
|
||||
(current_wireguard_private_key.result is defined and
|
||||
current_wireguard_private_key.result | length > 0) and
|
||||
'Entry not found' not in current_wireguard_private_key.result
|
||||
|
||||
# Generate wireguard private key
|
||||
- name: Generate wireguard private key
|
||||
ansible.builtin.command:
|
||||
cmd: "umask go= && wg genkey"
|
||||
uses_shell: true
|
||||
register: new_wireguard_private_key
|
||||
when: >
|
||||
current_wireguard_private_key.result is undefined or
|
||||
'Entry not found' in current_wireguard_private_key.result
|
||||
|
||||
# Set newely generated wireguard private key fact
|
||||
- name: Set newely generated wireguard private key fact
|
||||
ansible.builtin.set_fact:
|
||||
wireguard_private_key: "{{ new_wireguard_private_key.stdout }}"
|
||||
when: >
|
||||
new_wireguard_private_key.stdout is defined and
|
||||
new_wireguard_private_key.stdout | length > 0
|
||||
|
||||
# Configure wireguard interface
|
||||
- name: Configure wireguard interface {{ item.id }}
|
||||
uci:
|
||||
command: "set"
|
||||
config: "network"
|
||||
section: "{{ item.id }}"
|
||||
type: "interface"
|
||||
value:
|
||||
proto: "{{ item.proto | default(omit) }}"
|
||||
private_key: "{{ wireguard_private_key }}"
|
||||
addresses: "{{ item.addresses | default(omit) }}"
|
||||
listen_port: "{{ item.listen_port | default(omit) }}"
|
||||
|
||||
# Configure wireguard peers
|
||||
- name: Configure wireguard peers
|
||||
ansible.builtin.include_tasks: peer.yml
|
||||
vars:
|
||||
wireguard_interface_name: "wireguard_{{ item.id }}"
|
||||
wireguard_interface_addresses: "{{ item.addresses }}"
|
||||
loop: "{{ item.peers | default([]) }}"
|
||||
loop_control:
|
||||
extended: true
|
||||
loop_var: wgpeer
|
||||
Reference in New Issue
Block a user