7

Я хочу сделать это:

  • Объедините несколько подключений к Интернету.
  • Зашифруйте соединение с локального компьютера на удаленный прокси /VPN-сервер.
  • В идеале переключайтесь между режимами "Надежный" и "Скорость" (описано ниже). Если это невозможно, то я бы предпочел, по крайней мере, иметь возможность подключиться к каналу (скорость).
  • Разместите серверное программное обеспечение в моей собственной инфраструктуре (например, выделенный сервер или VPS).
  • В идеале решение должно быть в состоянии работать на клиенте Windows, подключенном к серверу Linux. (например, Windows 10 на клиенте, Ubuntu 14.04 Server на сервере.) Если требуется клиент Linux, пожалуйста , укажите , что в своем ответе; это все еще приемлемый ответ, если для этого требуется клиент Linux, я всегда могу запустить его на виртуальной машине, если потребуется.

Как я могу это сделать?


Более детально

Надежные и скоростные режимы

Надежный режим похож на RAID-1, где одни и те же пакеты отправляются по двум или более восходящим каналам, и первый пакет, поступающий на сервер, принимается, а другая копия отбрасывается. В надежном режиме ваша общая пропускная способность теоретически выше ваших двух восходящих каналов, но на практике она немного меньше, если пакеты от более медленной восходящей линии иногда достигают конечной точки первыми.

Скоростной режим похож на RAID-0, где разные пакеты данных отправляются по обоим каналам связи, так что ваша общая пропускная способность, например, при загрузке, является добавлением пропускной способности обеих восходящих линий.

Speedify использует этот механизм, больше информации здесь. Я мог бы просто использовать это, за исключением того, что собственная служба Speedify не шифрует данные, и одна из моих двух восходящих ссылок - незащищенная точка доступа WiFi; Мне нужно надежное шифрование для защиты протоколов приложений, которые сами по себе не зашифрованы (как обычный HTTP, через который осуществляется доступ к superuser.com).

Моя ситуация

У меня есть два подключения к общедоступному Интернету:

  • Подключение LTE ~ 12 Мбит / с в качестве адаптера Ethernet через USB (на самом деле это iPhone, но он предоставляет себя операционной системе как обычный Ethernet)
  • Соединение LTE ~ 5 Мбит / с от точки доступа WiFi, поставляется с ключом USB 802.11ac

Я хочу объединить их следующим образом:

Connection A --> Internet --> Server --> Internet Activity
Connection B --> Internet --> Server --> Internet Activity

Конец Internet Activity - это то, где он становится рискованным. Я хочу установить два отдельных соединения между моим локальным компьютером и Server , но одно унифицированное соединение между Server и более широким общедоступным Интернетом.

Например, допустим, я отправляю HTTP-запрос, который принимает, скажем, 10 IP-пакетов. Возможно, 6 из этих пакетов будут отправлены через соединение A, а 4 - через соединение B. Эта разбивка будет основываться на уровне насыщения каждой восходящей линии связи. Это то, что делает Speedify, но Speedify ничего не шифрует.

Эти пакеты будут отправляться в правильном порядке с Server на любую конечную точку в общедоступном Интернете, к которой я пытаюсь связаться.

Затем, когда HTTP-ответ возвращается из Интернета, он возвращается как 10 пакетов, которые затем передаются через Server и передаются обратно в Connection A и Connection B таким образом, чтобы избежать перегрузки сети (например, если один из восходящих каналов связи) имеет большую потерю или насыщение пакетов, он будет сосредоточен на использовании другой восходящей линии связи, но если пакеты проходят через обе линии, он будет распределять их по обеим линиям в зависимости от скорости канала).

Это суть того, что произойдет за кулисами. Я подумал, возможно, использовать что-то вроде OpenVPN. Тем не менее, я не знаю, может ли он быть настроен для этого.

Мой вопрос

Я не ищу список предложений программного обеспечения, которые могут быть полезны. Скорее, мой вопрос, каковы детали того, как этого добиться?

1 ответ1

4

Через некоторое время после публикации этого вопроса я переключил некоторые термины в своих поисках в Google и нашел следующую жемчужину сообщения в блоге: http://simonmott.co.uk/vpn-bonding

Статья длинная и предоставляет всю информацию, необходимую для работы. Однако в подходе автора есть существенный недостаток. Туннелируя по SSH, он делает туннель транспортным TCP. Ack. Это означает, что если вы туннелируете TCP через туннель, вы получаете TCP поверх TCP. С какой - либо значительной задержки или потери пакетов на всех, TCP стека будет запутаться и начать метаться , как и TCP стека попытка справиться с алгоритмами управления перегрузкой, повторных передач и т.д. Это существенно ограничивает вашу пропускную способность, если вы не будете использовать только что - то вроде UDP внутри Туннель (что означает, что вы не можете получить доступ к Интернету).

В статье упоминается, что она будет работать аналогично туннелю с чем-то иным, чем ssh, и он прав. Я решил использовать для этого двухточечную функцию OpenVPN. Это не очень безопасно, так как использует статический ключ, но безопасность была достаточно хорошей для моих целей (почти только Advanced Persistent Threats сможет взломать криптографию).

OpenVPN может транспортировать через TCP или ... UDP ! Мы хотим сделать транспортный уровень нашего туннеля UDP, потому что, если пакеты потеряны, "внутренний" уровень TCP будет иметь дело с контролем перегрузки. И если вы запускаете UDP внутри UDP, код приложения отвечает за потерю пакетов или задержку и будет нормально справляться с этим.

Я столкнулся с серьезной проблемой в виде регрессии ядра, которая случилась когда-то во время точечного выпуска серии 3.13, и на данный момент она не решалась даже в git master Торвальдса. Это не упоминается в статье, потому что регрессия не существовала на момент написания статьи. Как на вашем клиенте, так и на сервере вам нужно будет либо перекомпилировать ядро с этим патчем (достаточно просто применить вручную, если patch отказывается работать), либо использовать версию ядра 3.13.0 или более раннюю.

Для своих целей я использовал Debian Wheezy (в настоящее время ветвь oldstable ветки Debian) с ядром 3.2 для сервера, потому что я не хотел перекомпилировать свое ядро на VPS Amazon EC2 t2.nano. На стороне клиента (рабочий стол Linux Mint) я перекомпилировал ядро. Итак, оба метода работают.

Вот инструкции по настройке после перекомпиляции ядра:

У вас будет четыре процесса openvpn : два на клиенте и два на сервере. Используйте openvpn версии 2.1 или новее, иначе это не сработает. Поместите файлы в каталог /etc /openvpn (если у вас нет пользовательского sysconfdir и скомпилированного пользователем openvpn).

В моем случае у меня есть две отдельные NIC, eth0 и eth1 на сервере, которые предоставляют два отдельных общедоступных IP-адреса, сокращенно обозначенных как SERVER_IP1 и SERVER_IP2 . На клиенте у меня есть eth1 и wlan0 подключенные к моим интернет-ссылкам, и их шлюзы (найденные с использованием ifconfig и route -n) сокращенно обозначаются как GW1 и GW2 .

Чтобы создать static.key , прочитайте справочную страницу OpenVPN.

Сервер tun0.conf:

dev tun0
local SERVER_IP1
proto udp
topology p2p
push "topology p2p"
secret static.key
keepalive 30 90

Сервер tun1.conf:

dev tun1
local SERVER_IP2
proto udp
topology p2p
push "topology p2p"
secret static.key
keepalive 30 90

Клиент tun0.conf:

dev tun0
nobind
remote SERVER_IP1
proto udp
topology p2p
secret static.key

Клиент tun1.conf:

dev tun1
nobind
remote SERVER_IP2
proto udp
topology p2p
secret static.key

Теперь вы хотите запустить экземпляры OpenVPN сначала на сервере, а затем на клиенте.

Как только у вас есть tun0 и tun1 подключенные в режиме POINTOPOINT (это должно сказать, что в описании интерфейса при запуске ifconfig) вы готовы установить связующее звено bond0 .

Я предполагаю, что вы используете Debian, Ubuntu или их форк для файлов конфигурации. Вы можете выполнить эквивалентную настройку для систем на базе CentOS/RHEL в /etc/sysconfig/network-scripts/ifcfg-bond0 , если я правильно помню. Вам придется настроить синтаксис конфигурации для этого вида ОС. И все может значительно измениться в ближайшем будущем с внедрением systemd и его сетевого демона.

В любом случае, добавьте это в /etc/network/interfaces на сервере:

iface bond0 inet static
    address 172.26.0.1
    netmask 255.255.255.252
    bond-slaves tun0 tun1
    bond_mode balance-rr

И на клиенте:

iface bond0 inet static
    address 172.26.0.2
    netmask 255.255.255.252
    bond-slaves tun0 tun1
    bond_mode balance-rr

Убедитесь, что ifenslave является допустимой командой в командной строке, прежде чем продолжить. Если нет, установите его из менеджера пакетов с помощью команды sudo apt-get install ifenslave .

Также не забудьте раскомментировать строку с #net.ipv4.ip_forward=1 в /etc/sysctl.conf , и вам может потребоваться echo 1 > /proc/sys/net/ipv4/ip_forward если вы не хотите перезагрузите компьютер после внесения изменений в /etc/sysctl.conf .

Вот мой стартовый скрипт для клиента; вам придется заменить несколько значений заполнителей (SERVER_IP1, SERVER_IP2, GW1, GW2, eth1 и wlan0 и т. д.), чтобы они работали на вас.

Не заменять 172.26.0.1 / 172.26.0.2 с чем - нибудь; это произвольно выбранные частные IP-адреса, которые соответствуют ссылке на связь сервера 0 и ссылку на связь клиента соответственно.

#!/bin/bash
modprobe bonding
modprobe tun
iptables -F

#Force connecting to each of the two server IPs through the separate Internet uplinks you have
ip route add SERVER_IP1 via GW1 dev eth1
ip route add SERVER_IP2 via GW2 dev wlan0
#Connect to OpenVPN - this establishes the tunnel interfaces
sleep 1
screen -mdS tun0 openvpn --config /etc/openvpn/tun0.conf
sleep 1
screen -mdS tun1 openvpn --config /etc/openvpn/tun1.conf
sleep 5

#The next line should be all you need, but I find it doesn't work on Linux Mint, it just hangs after partially configuring the interface. Works fine on Debian Wheezy though.
ifup bond0 >& /dev/null &

sleep 5
killall ifup >& /dev/null
ifconfig bond0 up >& /dev/null

#If the ifup script doesn't do its job (it fails on certain Debian OSes depending on the version of your ifenslave program), we have to manually set it up - the next few lines take care of that 
ifconfig bond0 172.26.0.2 netmask 255.255.255.252
sleep 2
echo '+tun0' > /sys/class/net/bond0/bonding/slaves
echo '+tun1' > /sys/class/net/bond0/bonding/slaves

#Clear the default gateway and set it to the bond interface
#Required regardless of whether you had to manually configure bond0 above or not
ip route del 0.0.0.0/0
ip route add 0.0.0.0/0 via 172.26.0.1 dev bond0

#Use fair queue controlled delay active queue management for managing multiple TCP flows simultaneously - prevents webpages from loading horribly slowly while you have a download going - requires a recent kernel (3.2 or later should suffice)
tc qdisc add dev bond0 root fq_codel

#DEBUGGING
#On client and server:
#ifconfig bond0, make sure IPs are assigned
#iptables -F on client (don't need any rules)
#cat /sys/class/net/bond0/bonding/slaves - make sure tun0 and tun1 are there
#ifdown bond0; modprobe bonding; ifup bond0 then re-set-up the slaves and IPs

А вот и скрипт сервера. В целом он должен выглядеть примерно так же, как и клиентский скрипт, за исключением того, что вам нужно выполнить пересылку пакетов iptables чтобы получить пакеты в и из вашей интернет-линии связи и интерфейса bond0.

К счастью, в скрипте сервера нет заполнителей! Просто скопируйте, вставьте и запустите. (Ошибка, если ваши два интерфейса, к которым подключается клиент, не будут eth0 и eth1 .)

#!/bin/bash

#The next line should be executed before you start doing anything on the client; or you can set openvpn to automatically start on system boot if you prefer.
/etc/init.d/openvpn start

sleep 1
ifup bond0
sleep 1

#Not necessary if your ifenslave script is working properly, but I had to add them manually
echo '+tun0' > /sys/class/net/bond0/bonding/slaves
echo '+tun1' > /sys/class/net/bond0/bonding/slaves

#I honestly have no idea what this line does, but it's in the original blog post and it seems to be required :/
ip route add 10.0.0.0/8 via 172.26.0.2 dev bond0

iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
iptables -A POSTROUTING -t nat -o eth1 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#Optional, but again, the best active queue management around - see client script for details
tc qdisc add dev bond0 root fq_codel

#This gets inserted automatically at some point along the way; 169.254 is defined as unroutable so you definitely don't want that hanging around in there. Could be an artifact of using Amazon EC2, so this may error out for you with a "No such process" error if you don't get this route.
ip route del 169.254.0.0/16

...И это все.

Это быстро? Ну ... вроде. На данный момент я не поражен производительностью, но она определенно дает мне лучшую скорость, чем медленное из двух каналов, и я использовал удобный инструмент iptraf чтобы определить, что и wlan0 и eth1 отправляют и получают пакеты UDP, когда я загрузите шлюз по умолчанию (например, посещая веб-сайты). Я изучаю возможную настройку MTU, MSS, буфера recv и т.д., Чтобы повысить производительность и оптимизировать пропускную способность.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .