Назад | Перейти на главную страницу

Bash-скрипт для отправки всего трафика точки доступа Wi-Fi через отдельный VPN-туннель в Ubuntu 18

Я работаю над сценарием bash, который должен создать точку доступа на ubuntu 18. Однако у меня есть особые потребности относительно того, какое соединение должна использовать эта точка доступа.

Я хочу, чтобы весь трафик от устройств, подключенных к моей точке доступа, проходил через отдельный VPN-туннель, и (не уверен, что эта часть актуальна) я буду случайным образом выбирать, какой VPN выбирается из набора параметров каждый раз, когда я активирую точку доступа.

По умолчанию при создании точки доступа в Ubuntu 18 он просто будет использовать существующее соединение, каким бы оно ни было в настоящее время.

Когда я открываю nm-connection-editor в графическом интерфейсе есть опция VPN, но я не знаю, как создать и изменить точку доступа, используя только bash.

Я в основном застрял, не зная, как это сделать программно, или если мне не хватает других знаний для этого. Если я что-то не пропустил, справочные страницы для nmcli не помогли мне.

Что, вероятно, усложняет то, что я уже подключен к VPN на tun0, поэтому я предполагаю, что мне нужно создать отдельное VPN-соединение, скажем, через tun1, и заставить точку доступа использовать его.

Вот что у меня есть

#that's the kind of call I use to activate my main VPN connection
#you can assume I have script already that gives me 
#the value for mainconnectionuuid
nmcli con up uuid mainconnectionuuid #activates tun0, all traffic goes through tun0 after this

#now I want to activate a hotspot that uses a different VPN connection 
#the following code activates the hotspot, but there is no option
#to separate the traffic to go over a different VPN
nmcli radio wifi on
nmcli device wifi hotspot ssid somessid password somepassword

Мне нужно что-то вроде этого:

#activate main connection on tun0
nmcli con up uuid mainconnectionuuid

nmcli radio wifi on
#'useconnection' is a phantasy parameter here, but I need something like this
#assuming here that the connection under vpnforhotspotuuid would already define tun1 to be used
nmcli device wifi hotspot ssid somessid password somepassword **useconnection vpnforhotspotuuid**

Или вот так:

#activate main connection on tun0
nmcli con up uuid mainconnectionuuid

#activate connection for hotspot on tun1
nmcli con up uuid vpnforhotspotuuid

nmcli radio wifi on
#'usetunnel' is a phantasy parameter here
nmcli device wifi hotspot ssid somessid password somepassword **usetunnel tun1**

Как я могу этого добиться?

Я не большой специалист, могу писать сценарии на bash и знаю ufw, но я немного боюсь IPtables. Я был бы признателен за решение, которое не так сложно понять, поскольку я также хочу иметь возможность написать сценарий, который отменяет или, по крайней мере, деактивирует изменения.

РЕДАКТИРОВАТЬ 1:

Я попробовал предложенное Петром решение, оно почти работает, но что-то идет не так. Когда я подключаюсь к этой точке доступа с помощью устройства Android 9, кажется, что он работает, пока я не выполню последнюю команду ip route add default via $TUN1IP table hotspot. После этого у меня как раз достаточно времени, чтобы запросить whatismyip.com с помощью браузера на телефоне и убедиться, что у меня действительно есть tun1 ip. Через некоторое время (возможно, примерно через 15-30 с) в настройках Wi-Fi телефона появится сообщение «Нет подключения к Интернету», и телефон начнет повторное подключение в бесконечном цикле, пока я не отменю маршрутизацию с помощью ip route del default table hotspot

Сначала я подумал, была ли это какая-то проблема с брандмауэром, поскольку моя конфигурация очень строгая и начинается с

ufw default deny incoming 
ufw default deny outgoing

а затем у меня есть некоторые правила, разрешающие VPN-соединения и локальные адреса, а затем относительно точки доступа, на которой я остановился:

ufw allow out on tun1 to 0.0.0.0/0
ufw allow out on wlan0 to 10.57.213.1/24

Редактировать 2

Перед выдачей финальной команды ip route add default via $TUN1IP table hotspot Я вижу следующий блок UFW (через dmesg), но соединение все равно работает:

[UFW BLOCK] IN = wlan0 OUT = MAC = xx: xx: xx: xx: xx: xx: xx: xx: xx: xx: xx: xx: xx: xx SRC = 10.57.213.181 DST = 10.57.213.1 LEN = 28 TOS = 0x00 PREC = 0x00 TTL = 1 ID = xxxxx DF PROTO = UDP SPT = 45104 DPT = 4886 LEN = 8

Эти блоки исчезают после выполнения команды маршрутизации, поэтому я предполагаю, что они не важны, хотя не уверен. Однако, если я смотрю на сообщения, отличные от ufw, я вижу следующие сообщения при каждом повторном подключении:

netlink: 'wpa_supplicant': тип атрибута 213 имеет недопустимую длину.

Я немного погуглил, и некоторые люди сказать это ошибка, связанная с WPA2, и что соединение будет работать, если я отключу шифрование, но даже если я отключу шифрование, ничего не изменится. Устройство по-прежнему повторно подключается к точке доступа в бесконечном цикле.

Я, наверное, также должен упомянуть, что пробовал ip route flush cache но это ничего не меняет

Редактировать 3

wpa_cli -i wlan0 log_level DEBUG и последующие journalctl -u wpa_supplicant -e дает (я цензурировал PID и MAC-адреса, используя букву x):

Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-70 fc=0x40 seq_ctrl=0xd740 stype=4
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-72 fc=0x40 seq_ctrl=0xd750 stype=4
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:22 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:33 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:33 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=20:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-75 fc=0x40 seq_ctrl=0x8830 stype=4
Mar 05 20:59:33 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:33 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-72 fc=0x40 seq_ctrl=0xe430 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-70 fc=0x40 seq_ctrl=0xe450 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-71 fc=0x40 seq_ctrl=0xe470 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-71 fc=0x40 seq_ctrl=0xe480 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-71 fc=0x40 seq_ctrl=0xe490 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: BSS Event 59 (NL80211_CMD_FRAME) received for wlan0
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=10:xx:xx:xx:xx:xx bssid=ff:ff:ff:ff:ff:ff freq=2412 ssi_signal=-71 fc=0x40 seq_ctrl=0xe4a0 stype=4
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: wlan0: Event RX_MGMT (19) received
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: P2P: Not a P2P probe - ignore it
Mar 05 20:59:41 machineone wpa_supplicant[xxxx]: Ignore Probe Request due to DS Params mismatch: chan=1 != ds.chan=2

Редактировать 4

После активации tun1 моя таблица маршрутизации выглядит так

Destination       Gateway           Genmask         Flags Metric Ref    Use Iface
0.0.0.0           10.10.2.1         0.0.0.0         UG    50     0        0 tun0
0.0.0.0           10.10.3.1         0.0.0.0         UG    50     0        0 tun1
0.0.0.0           192.168.xxx.xxx   0.0.0.0         UG    100    0        0 eth0
10.10.2.0         0.0.0.0           255.255.255.0   U     50     0        0 tun0
10.10.3.0         0.0.0.0           255.255.255.0   U     50     0        0 tun1
10.57.213.1       0.0.0.0           255.255.255.0   U     600    0        0 wlan0 
the.vpn.ip.tun0   192.168.xxx.xxx   255.255.255.255 UGH   100    0        0 eth0
169.254.0.0       0.0.0.0           255.255.0.0     U     1000   0        0 virbr0 
the.vpn.ip.tun1   192.168.xxx.xxx   255.255.255.255 UGH   100    0        0 eth0
192.168.yyy.0     0.0.0.0           255.255.255.0   U     0      0        0 virbr0
192.168.xxx.0     0.0.0.0           255.255.255.0   U     100    0        0 eth0
192.168.xxx.xxx   0.0.0.0           255.255.255.255 UH    100    0        0 eth0

Я экспериментировал с такими командами, как ip route add default dev wlan0 via default dev tun1 и ip route add default dev wlp8s0 via 10.10.3.1 dev tun1 но ничего не работало. Кроме того, иногда шлюз по умолчанию для tun0 бывает таким же, как и для tun1.

редактировать 5

Я обнаружил, что есть ошибка в ядре linux (а точнее wpa2_supplicant), где ядро ​​очень строгое с переданными ему аргументами и делает wpa2_supplicant потерпеть поражение. Я сделал следующее

# nmcli connection edit hotspot
set 802-11-wireless-security.pmf disable
save
[CTRL+D]

Это отключает защищенные кадры управления (PMF) для созданного мной подключения к точке доступа, в котором происходит вызов ядра, который прерывается. wpa_supplicant. После этого (и route add default dev wlan0 via 10.10.3.1 dev tun1) теперь вся моя система (а не только точка доступа) перегружена tun1 вместо того tun0. Мне все еще нужно понять, почему я не могу сделать так, чтобы tun0 будет использоваться для eth0 в то же время tun1 будет использоваться для wlan0.

После того, как я введу следующие команды

ip route add default dev wlan0 via 10.10.2.1 dev tun1 proto static metric 50
ip route add default dev eth0 via 10.10.3.1 dev tun0 proto static metric 50

Моя таблица маршрутизации выглядит так:

0.0.0.0          10.10.2.1        0.0.0.0         UG    50     0        0 tun1
0.0.0.0          10.10.3.1        0.0.0.0         UG    50     0        0 tun0
0.0.0.0          192.168.xxx.xxx  0.0.0.0         UG    100    0        0 eth0
10.10.2.0        0.0.0.0          255.255.255.0   U     50     0        0 tun0
10.10.3.0        0.0.0.0          255.255.255.0   U     50     0        0 tun1
10.55.213.1      0.0.0.0          255.255.255.0   U     600    0        0 wlan0
the.vpn.ip.tun1  192.168.xxx.xxx  255.255.255.255 UGH   100    0        0 eth0
169.254.0.0      0.0.0.0          255.255.0.0     U     1000   0        0 virbr0
the.vpn.ip.tun1  192.168.xxx.xxx  255.255.255.255 UGH   100    0        0 eth0
192.168.yyy.0    0.0.0.0          255.255.255.0   U     0      0        0 virbr0
192.168.xxx.0    0.0.0.0          255.255.255.0   U     100    0        0 eth0
192.168.xxx.xxx  0.0.0.0          255.255.255.255 UH    100    0        0 eth0

что выглядит так, как будто я их никогда не выпускал

редактировать 6:

когда я пытаюсь установить vpn-соединение с терминала

sudo openvpn --config myconfigfile.ovpn --dev tun1 --verb 3

выдаются следующие команды маршрута, и все пройдет tun1 и tun0 игнорируется:

Wed Mar 11 19:16:12 2020 /sbin/ip link set dev tun1 up mtu 1500
Wed Mar 11 19:16:12 2020 /sbin/ip addr add dev tun1 10.10.2.6/24 broadcast 10.10.2.255
Wed Mar 11 19:16:12 2020 /sbin/ip route add the.vpn.ip.tun1/32 via 10.10.3.1
Wed Mar 11 19:16:12 2020 /sbin/ip route add 0.0.0.0/1 via 10.10.2.1
Wed Mar 11 19:16:12 2020 /sbin/ip route add 128.0.0.0/1 via 10.10.2.1

Я также нахожу 10.10.3.1 ip нечетный, так как он связан с tun0.

Когда я делаю

ip route delete 0.0.0.0/1 via 10.10.2.1

все мои связи возвращаются к tun0 и игнорировать tun1. ip route show table выглядит так:

default via 10.10.3.1 dev tun0 
default via 10.10.3.1 dev tun0 proto static metric 50 
default via 192.168.xxx.xxx dev eth0 proto dhcp metric 100 
10.10.2.0/24 dev tun1 proto kernel scope link src 10.10.2.3 
10.10.3.0/24 dev tun0 proto kernel scope link src 10.10.3.4 metric 50 
10.55.213.0/24 dev wlan0 proto kernel scope link src 10.55.213.1 metric 600 
128.0.0.0/1 via 10.10.2.1 dev tun1 
the.tun0.vpn.ip via 192.168.xxx.xxx dev eth0 proto static metric 100 
169.254.0.0/16 dev virbr0 scope link metric 1000 linkdown 
the.tun1.vpn.ip via 10.10.3.1 dev tun0 
192.168.aaa.bbb/24 dev virbr0 proto kernel scope link src 192.168.aaa.ccc linkdown 
192.168.xxx.0/24 dev eth0 proto kernel scope link src 192.168.xxx.yyy metric 100 
192.168.xxx.xxx dev eth0 proto static scope link metric 100 
broadcast 10.10.2.0 dev tun1 table local proto kernel scope link src 10.10.2.3 
local 10.10.2.3 dev tun1 table local proto kernel scope host src 10.10.2.3 
broadcast 10.10.2.255 dev tun1 table local proto kernel scope link src 10.10.2.3 
broadcast 10.10.3.0 dev tun0 table local proto kernel scope link src 10.10.3.4 
local 10.10.3.4 dev tun0 table local proto kernel scope host src 10.10.3.4 
broadcast 10.10.3.255 dev tun0 table local proto kernel scope link src 10.10.3.4 
broadcast 10.55.213.0 dev wlan0 table local proto kernel scope link src 10.55.213.1 
local 10.55.213.1 dev wlan0 table local proto kernel scope host src 10.55.213.1 
broadcast 10.55.213.255 dev wlan0 table local proto kernel scope link src 10.55.213.1 
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 
broadcast 192.168.aaa.bbb dev virbr0 table local proto kernel scope link src 192.168.aaa.ccc linkdown 
local 192.168.aaa.ccc dev virbr0 table local proto kernel scope host src 192.168.aaa.ccc 
broadcast 192.168.aaa.255 dev virbr0 table local proto kernel scope link src 192.168.aaa.ccc linkdown 
broadcast 192.168.xxx.0 dev eth0 table local proto kernel scope link src 192.168.xxx.yyy 
local 192.168.xxx.yyy dev eth0 table local proto kernel scope host src 192.168.xxx.yyy 
broadcast 192.168.xxx.255 dev eth0 table local proto kernel scope link src 192.168.xxx.yyy

Надеюсь, я правильно отредактировал все эти IP-адреса, поскольку на самом деле каждый раз меняет некоторые IP-адреса, поэтому я сопоставляю их с моими предыдущими изменениями.

Моя плохая интуиция подсказывала мне попробовать следующий

ip route replace 10.57.213.1/24 via 10.10.2.6 dev tun1 table AirSpot

Но все, что я получаю, это Error: Invalid prefix for given prefix length. и я не понимаю, что это значит. Я просто чего-то не понимаю. Для меня маршрутизация не совсем интуитивна. В этой строке я хочу, чтобы все пакеты, адресованные из или в 10.57.213.1/24 (который является диапазоном точек доступа, установленным вручную) должны пройти через 10.10.2.6, что я бы подумал (на основе подробного вывода openvpn) где tun1 является.

Изменить 7:

Я думаю, что это какая-то проблема с маршрутом по умолчанию, но я недостаточно эксперт, чтобы ее решить ...

Решение, которое вы опубликовали в комментарии, почти правильное. Не хватает только правильных IP-адресов.

Шаг 1. Получите информацию

Вам нужно получить две части информации:

  1. IP-адреса подсети вашей точки доступа. По умолчанию это случайная сеть вида 10.42.*.0/24, поэтому вам нужно исправить адреса. Самый простой способ - создать новое соединение Wi-Fi под названием hotspot с помощью nm-connection-editor. Тебе надо:

    • установить режим на Hotspot в "Вай-фай" вкладка
    • установить метод на Shared with other computers в «Настройки IPv4» вкладка
    • выберите подсеть для сети, добавив IP-адрес (например, 10.57.213.1 с сетевой маской 24) на той же вкладке,
    • добавить какой-нибудь метод аутентификации (например, PSK)

    После выполнения этих шагов у вас должен быть хорошо настроенный /etc/NetworkManager/system-connections/hotspot.nmconnection файл с таким содержанием, как:

    [wifi]
    mode=ap
    
    [ipv4]
    address1=10.57.213.1/24
    method=shared
    

    и вы можете начать соединение с nmcli connection up id hotspot.

  2. IP-адрес VPN-шлюза. Будет ли это фиксированным или переменным, зависит от того, какой тип VPN вы используете. Скажем это 10.10.10.1.

Шаг 2. Настройте маршрутизацию политики

  1. Разовая операция. Нам нужна дополнительная таблица маршрутизации. Чтобы иметь возможность обращаться к нему по имени, добавим:

    200 hotspot
    

    к /etc/iproute2/rt_tables.

  2. Один раз при загрузке системы. Нам нужно сообщить ядру, что пакеты, исходящие от 10.57.213.0/24 следует использовать hotspot стол:

    ip rule add from 10.57.213.0/24 table hotspot
    
  3. Каждый раз, когда мы подключаемся к VPN, нам нужно добавить маршрут по умолчанию для адресов HotSpot:

    ip route replace default via 10.10.3.1 dev tun1 table hotspot
    

    где 10.10.3.1 - это адрес другой стороны вашего VPN-туннеля согласно таблице маршрутизации.

    Вы можете запустить эту часть в Скрипт диспетчера NetworkManager, в этом случае адрес шлюза будет в переменной среды $IP4_GATEWAY.

Редактировать: Чтобы автоматически установить маршрут по умолчанию для hotspot таблица добавить сценарий диспетчера /etc/NetworkManager/dispatcher.d/hotspot.sh как это:

#!/bin/bash
# Be verbose until you test this
set -ex

# First parameter passed by NM: interface
DEVICE="$1"
# Second parameter: action
CMD="$2"
IP=/bin/ip

# Delete the part after '/' from $IP4_ADDRESS_0
LOCAL_IP=${IP4_ADDRESS_0%/*}
if [ "$LOCAL_IP" != "" ]; then
  # Add a 'src' option to the route only if the IP is not empty
  SRC="src $LOCAL_IP"
fi

if [ "$CMD" = "vpn-up" ]; then
  $IP route replace default via $IP4_GATEWAY dev $DEVICE $SRC table hotspot
fi

Я не проверял это.