Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions vpn-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# VPN Client

Setup/deploy a IPsec VPN tunnel client on Ubuntu server

## Configure
```
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
```

## Run

- Update inventory

```
python3 -m venv venv
. venv/bin/activate
ansible-playbook --ask-vault-pass -i inventory.ini playbooks/deploy-vpn-client.yml
```

## Verify

```
# on the server
curl -v -k -L --compressed https://10.100.49.2
```
35 changes: 35 additions & 0 deletions vpn-client/group_vars/vpn_clients.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
vpn_server_ip: !vault |
$ANSIBLE_VAULT;1.1;AES256
65313765653365306632333165626635643763663432393138383662363530353035393261353735
3836623138353462346435333139383964336633313735620a333035396433666362613564636230
39313365313935396461303735613766656637363265373537653262396234613638663833363535
3038613435353637350a653938333033646335663566356530613666616266313261313938336434
3866
vpn_user: !vault |
$ANSIBLE_VAULT;1.1;AES256
33396435663663333438376562633538663039323035346533313966366330393634363662323965
3164326435323732636262333834366230663230313234330a366664666164663336353862663630
38336365366339623332646134636361346335313461306365326234633837336530303233363936
3331396131376233620a623036313264366163353035373737666362343337393139303138353836
65376337336562623238346635666361363632363731653661623663386562343561
vpn_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
38396430323363303566653232313463663130666132346664346138316430316564613866363432
3432646130363730316266343566366165343864623135380a636637646430663939386262383736
65356139316530383664623966373439326465303363396637343965356331333137623637353333
3134343934333630340a396133646135363862353565623661623030363237303662363731343261
6439
local_ip_gateway: !vault |
$ANSIBLE_VAULT;1.1;AES256
62363862373934383832376261306162373239383439653061663961306333326263376631323365
3339663032643263656632306137356662363164663662660a326430316265363436373133653136
66613230323361623832613030643933303062373764393062353433373966666166313361626537
6465666431303765610a653766353132383338353430376339396165343732376533363934303264
3439
pre_shared_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
35616232666337663862346665663162376136326362313464633866316537393935303839326339
6133393737633833303866613738363463613236306435330a303638343532316165636432386439
62393832343063646664333137303966653561653431306433393836396666346262323061366163
3762333338373236390a353661316532643534376161383538306431643237313332346234396261
3631
2 changes: 2 additions & 0 deletions vpn-client/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[vpn_clients]
changeme ansible_user=changeme
190 changes: 190 additions & 0 deletions vpn-client/playbooks/deploy-vpn-client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
- name: Install and configure L2TP IPsec vpn client on Ubuntu 22.04
hosts: vpn_clients
become: yes
vars:
wireguard_dir: "/etc/wireguard/"

tasks:
- name: Install strongswan and xl2tpd
apt:
name: ['strongswan', 'xl2tpd']
state: present
update_cache: true

- name: Configure xl2tpd.conf
copy:
dest: "/etc/xl2tpd/xl2tpd.conf"
content: |
[lac testvpn]
lns = {{ vpn_server_ip }}
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

- name: Edit options.l2tpd.client
copy:
dest: "/etc/ppp/options.l2tpd.client"
content: |
ipcp-accept-local
ipcp-accept-remote
refuse-eap
require-chap
noccp
noauth
mtu 1280
mru 1280
noipdefault
defaultroute
usepeerdns
debug
lock
connect-delay 5000
name {{ vpn_user }}
password {{ vpn_pass }}
mode: '0600'

- name: Ensure xl2tpd control directory exists
file:
path: "/var/run/xl2tpd"
state: directory

- name: Ensure l2tp-control exists
file:
path: "/var/run/xl2tpd/l2tp-control"
state: touch

- name: Configure ipsec.conf
copy:
dest: "/etc/ipsec.conf"
content: |
config setup

conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
ike=aes128-sha1-modp2048!
esp=aes128-sha1-modp2048!

conn testvpn
keyexchange=ikev1
left=%defaultroute
auto=add
authby=secret
type=transport
leftprotoport=17/1701
rightprotoport=17/1701
right={{ vpn_server_ip }}

- name: Add the IPSec Secret
copy:
dest: "/etc/ipsec.secrets"
content: "{{ local_ip_gateway }} {{ vpn_server_ip }} : PSK \"{{ pre_shared_key }}\""

- name: Restart strongswan and xl2tpd services
service:
name: "{{ item }}"
state: restarted
loop:
- strongswan-starter
- xl2tpd

- name: Establish the VPN Connection
shell:
cmd: "{{ item }}"
loop:
- ipsec up testvpn
- 'echo "c testvpn" > /var/run/xl2tpd/l2tp-control'
- sleep 10

- name: Route the traffic
command: ip route add 10.100.49.2/32 via 10.100.49.10

- name: Install wireguard
apt:
name: ['wireguard']
state: latest
update_cache: true
tags: [ wireguard ]


- name: Generate laptop-private.key
command: wg genkey
register: laptop_private_key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]


- name: Save laptop-private.key to file
copy:
content: "{{ laptop_private_key.stdout }}"
dest: "{{ wireguard_dir }}laptop-private.key"
mode: '0600'
tags: [ wireguard ]


- name: Generate laptop-public.key
shell: wg pubkey < {{ wireguard_dir }}laptop-private.key > {{ wireguard_dir }}laptop-public.key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]

- name: Register laptop-public.key
command: cat {{ wireguard_dir }}laptop-public.key
register: laptop_public_key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]


- name: Generate router-private.key
command: wg genkey
register: router_private_key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]


- name: Save router-private.key to file
copy:
content: "{{ router_private_key.stdout }}"
dest: "{{ wireguard_dir }}router-private.key"
mode: '0600'
tags: [ wireguard ]


- name: Generate router-public.key
shell: wg pubkey < {{ wireguard_dir }}router-private.key > {{ wireguard_dir }}router-public.key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]

- name: Template wg0.conf to {{ wireguard_dir }}
ansible.builtin.template:
src: wg0.conf.j2
dest: "{{ wireguard_dir }}wg0.conf"
owner: root
group: root
mode: '0600'
tags: [ wireguard ]


- name: Register router-public.key
command: cat {{ wireguard_dir }}router-public.key
register: router_public_key
# command always generates new key but doesn't change system state
changed_when: false
tags: [ wireguard ]

- name: Template client config
become: yes
template:
src: wg-client.conf.j2
dest: "{{ wireguard_dir }}wg-client.conf"
delegate_to: localhost
tags: [ wireguard ]
10 changes: 10 additions & 0 deletions vpn-client/playbooks/templates/wg-client.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Interface]
PrivateKey = {{ laptop_private_key.stdout }}
ListenPort = 51000
Address = 10.10.11.2/24


[Peer]
PublicKey = {{ router_public_key.stdout }}
Endpoint = {{ local_ip_gateway }}:51000
AllowedIPs = 10.10.11.0/24,10.10.10.0/24,10.100.49.2/24
12 changes: 12 additions & 0 deletions vpn-client/playbooks/templates/wg0.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Interface]
PrivateKey = {{ router_private_key.stdout }}
ListenPort = 51000
Address = 10.10.11.1/24
PostUp = iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
PostUp = resolvectl dns eth0 8.8.8.8
PostDown = iptables -t nat -D POSTROUTING -o ppp0 -j MASQUERADE


[Peer]
PublicKey = {{ laptop_public_key.stdout }}
AllowedIPs = 10.10.11.2
1 change: 1 addition & 0 deletions vpn-client/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ansible