GitHub
Обновление от 25 ноября 2022 ¶
Перешёл на классический wg-quick с этого Ansible. Решение получилось в целом много проще технически, а по функционалу меня удовлетворяет.
Обновление от 21 марта 2022 ¶
Убрал автоматическую генерацию ключей из-за чрезмерной сложности реализации и невозможности настраивать сервера по отдельности, только все вместе можно было. Теперь иначе. Изменения в конфигурации не совместивы со старой, проверь примеры в репозитории, я там докуменатцию дописал.
Введение ¶
Wireguard – обалденный, простой VPN, который уже включён в состав ядра. Очень мощный и простой инструмент. Ставиться в разы проще чем OpenVPN.
Постановка задачи ¶
- Я живу в Украине и, к сожалению, у нас заблокированы некоторые Интернет ресурсы, а доступ иногда нужен.
- Хочется иметь возможность достучаться по удалённому доступу с телефона или чужого компьютера до домашнего сервера.
- Хочется, чтобы на ПК проксировался трафик только на домены из списка, а не вообще всё.
Вот с такими запросами я стал работать. Для себя, всё для себя. Больше пока никому не нужен, хотя на GitHub выложил. Выложил - это тоже громко сказано. Ни документации, ничего! Да! Лень просто написать… Ну да ладно.
Обзор решения ¶
Использовал Ansible, который может настроить сразу сеть. Что умеет:
- Использование константного preshared ключа для всех соединений
- Возможность прописывать свои AllowedIPs
- Возможность добавлять пиров со статически прописанными ключами (на телефоне-то Ansible не запустить)
- Автоматический подбор свободных rt_table ID и fwmark-ов
- Возможность за один запуск поднимать больше одной сети на тех же машинах!
Чего не умеет.
- Отдельный запуск на одном или подгруппе хостов. Только на всём сразу.
Разбираем переменные Ansible ¶
all.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| # CIDR сетей
wireguard_networks:
home: 192.168.99.0/24
vpn: 10.0.0.0/24
# марки для маршрутизации - для каждой сети своя
wireguard_fwmarks:
home: 1000
vpn: 2000
# по прешаренному ключу на сеть
wireguard_preshared_keys:
home: longalphanum
vpn: longalphanum
# ключи каждого сервера в каждой сети где он есть
wireguard_keys:
home:
public_host:
public: longalphanum
private: longalphanum
home_server:
public: longalphanum
private: longalphanum
laptop:
public: longalphanum
private: longalphanum
vpn:
public_host:
public: longalphanum
private: longalphanum
laptop:
public: longalphanum
private: longalphanum
smartphone:
# у телефона, только публичный, так как приватный тут не нужен
public: longalphanum
wireguard_addresses:
# адреса каждого сервера в каждой сети
home:
public_host: 192.168.99.1
laptop: 192.168.99.2
home_server: 192.168.99.3
vpn:
public_host: 10.0.0.1
laptop: 10.0.0.2
smartphone: 10.0.0.3
|
У нас есть сервер с публичным IP и вот он-то послужит точкой подключения для всех. Топология - звезда.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| # это переменнные для отдельно взятого хоста - сервера
wireguard_enabled: yes
# wireguard-tools поставили уже, по-этому тут это выключаем
wireguard_install_tools: no
# список пиров
wireguard_peers:
# для домашней сети
home:
# первый пир это наш ноутбук, на котором мы Ansible запускаем
- name: laptop
# а второй, имеет inventory_hostname home_server
- name: home_server
# и поддерживай сеть, чтобы всегда можно было достучаться,
# потому что сервер за NAT-ом
keepalive_seconds: 25
# вторую сеть только с телефона и ПК использовать будем
vpn:
- name: laptop
# а вот и телефон
- name: smartphone
# ну и выберем порты, по которым он должен слушать
# для остальных можно не указывать - не важно, а вот
# для сервера лучше всё сразу прописать статикой
# чтобы ничего не было перегенерено если что
# и не нужно было перенастраивать всех клиентов
# на новые креды сервера
wireguard_ports:
home: 2000
vpn: 3000
# включаем маскарад, чтобы сервер через себя в Интернет
# выпускал трафик пиров как gateway
wireguard_masquarade:
vpn: auto
|
А теперь укажем переменные для ноутбука, за которым работаем.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # и опять включем роль явным образом
wireguard_enabled: yes
wireguard_peers:
vpn:
# из пиров в сети VPN только наш публичный сервер
- hostname: public_host
# у нас есть домен, который указывает на сервер чтобы адрес не запоминать
endpoint: vpn.example.com
# направляем через VPN весь трафик, и тут важно понимать,
# что мы не весь трафик системы пускаем через wireguard
# мы говорим wireguard-у на хосте, что в эту сетку пускай
# всё, что к тебе конкретно пришло на выход и не подходит
# в другие сети по более узким правилам
allowed_ips:
- 0.0.0.0/0
- ::0
keepalive_seconds: 25
home:
# точкой связи для домашней сети является он же
- hostname: public_host
endpoint: vpn.example.com
keepalive_seconds: 25
allowed_ips:
# а в путях прописываем только подсеть домашней сети
- "{{ wireguard_networks.home }}"
# и включаем проксирование отдельных доменов через сеть VPN
wireguard_proxy_domains:
vpn:
list:
- site.we.want.access
- another.one
|
Ну и домашний сервер, просто должен быть доступен. В VPN ему ни к чему.
1
2
3
4
5
6
7
8
9
| # тут я надеюсь уже всё понятно
wireguard_enabled: yes
wireguard_peers:
home:
- hostname: public_host
endpoint: vpn.example.com
allowed_ips:
- "{{ wireguard_networks.home }}"
keepalive_seconds: 25
|
Итог ¶
С любого пира на любой есть доступ в пределах сети. Трафик находит свой путь через публичный сервер. Всё работает. Померял iperf-ом, из 80 Мбит, Wireguard отдаёт ~60 - как по мне, так это блестящий результат!