Я хотел бы запустить OpenVPN в клиентском режиме на моей облачной виртуальной машине (экземпляр EC2), чтобы трафик, исходящий из виртуальной машины, обычно проходил через VPN. Но я бы все равно хотел, чтобы существующий IP-адрес был доступен для SSH-подключений (чтобы он не нарушал SSH-соединение, к которому я сейчас подключен к машине).
Вот текущие .ovpn
файл настроек, который я использую:
client
dev tun
proto udp
remote xxx.yyy.com 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.rsa.2048.pem
ca ca.rsa.2048.crt
disable-occ
Изменить: этот вопрос может быть дубликатом Предотвращение потери соединения SSH после входа в VPN на сервере ... но и там нет принятого ответа.
Вы можете использовать расширенную маршрутизацию для маршрутизации пакетов, входящих на ваш основной интерфейс, через тот же интерфейс. Таким образом, любой трафик, исходящий с сервера, будет маршрутизироваться через VPN, но основной интерфейс вашего сервера останется доступным для подключений. Идея заключается в том, что если пакет проходит через основной интерфейс, он будет использовать другую таблицу маршрутизации с именем «vpn», поэтому на него не будут влиять настройки маршрутизации VPN-клиента.
Для этого сделайте следующее:
Отредактируйте /etc/iproute2/rt_tables
файл. Он должен содержать что-то вроде этого:
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
Добавьте эту строку в конец файла:
1 vpn
К /etc/network/interfaces
файл в настройках вашего основного интерфейса (или в соответствующий файл в /etc/network/interfaces.d/
) добавьте следующие строки:
up ip route add 0.0.0.0/0 via def.ault.gw table vpn
up ip rule add from the.primary.ip.addr table vpn
down ip route del 0.0.0.0/0 table vpn
down ip rule del from the.primary.ip.addr
Заменить the.primary.ip.addr
с IP-адресом вашего основного интерфейса (то есть IP-адресом, через который вы хотите, чтобы ваш сервер был доступен), и def.ault.gw
с адресом шлюза по умолчанию.
Вы можете сделать это с помощью расширенной маршрутизации, как предлагается, но это не так просто.
Самым простым решением для достижения вашей цели является маршрутизация пакетов, адресующих ваш (домашний) IP-адрес по-другому. Всегда полезно ограничить доступ по ssh несколькими безопасными IP-адресами. Например, вы можете:
ip route add 1.1.1.1 via 9.9.9.9
Здесь 1.1.1.1 - ваш домашний IP-адрес, а 9.9.9.9 - шлюз по умолчанию. уже достижимый в таблице маршрутизации. Теперь все пакеты с вашего компьютера на внешний IP-адрес будут возвращаться одинаково. Вы можете маршрутизировать все остальное через VPN как обычно. Вы даже можете добавить этот маршрут в конфигурационный файл openvpn. Все супер.
Однако это не так уж важно, если ваш домашний IP-адрес меняется (он же динамический адрес) или вам нужно подключаться к своей машине со случайных адресов (несколько пользователей, в пути). В этом случае вы должны пройти нелегкий путь.
Обратите внимание: если вы ничего не сделаете, пакеты ssh придут на ваш внешний интерфейс (и ip), но они не смогут найти обратный путь, если вы направите их через VPN (на самом деле они мог в зависимости от настроек VPN, но исходный IP-адрес будет другим, и пакет будет удален). Ваша цель - перенаправить некоторые исходящие пакеты на внешний интерфейс, а некоторые - на VPN. Это проблема.
Создайте альтернативную таблицу маршрутизации:
echo "100 secure" >> /etc/iproute2/rt_tables
Заполнить и контролировать маршрутизацию:
# route ssh over external iface eth0 to router 9.9.9.9
ip route add default via 9.9.9.9 dev eth0 table secure
# send all packages with fwmark 1 to the secondary routing table
ip rule add fwmark 0x1 table secure
# Mark outgoing ssh packages with the mark 1
iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1
Здесь мы отметим все исходящие пакеты ssh, а затем перенаправим все отмеченные пакеты по альтернативной маршрутизации. Конечно, теперь ты не будет чтобы иметь возможность использовать ssh через vpn, потому что весь ответ будет перенаправлен на другой интерфейс. Дело в том, что вы можете создавать произвольно сложные правила iptables и по-разному маршрутизировать их, используя set-mark.
К счастью, у нас есть вещь под названием CONNMARK, которая (с использованием функции отслеживания соединений ядра) может помечать целые соединения туда и обратно (вам понадобится модуль xt_connmark).
# mark incoming ssh *connection* with 1. Here eth0 is your external interface
iptables -A INPUT -m state --state NEW -i eth0 -p tcp --dport 22 -t mangle -j CONNMARK --set-mark 1
# restore connection mark (e.g. mark the packages)
iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark
# send all packages with fwmark 1 to the secondary routing table as before..
ip rule add fwmark 0x1 table secure
Пожалуйста, используйте вышеуказанное в соответствии с вашей текущей настройкой после понимания концепций, а не просто копируйте и вставляйте.
Если вы используете свой VPN из тем же машина, с которой выполняется ssh-соединение, возникает дополнительная проблема.
По умолчанию одноранговый узел VPN становится шлюзом по умолчанию. Это может легко разорвать ваше существующее соединение, поскольку ваши пакеты ssh будут маршрутизироваться через канал VPN (сервер получит их из интерфейса tun или tap и не из физического интерфейса eth). Простое решение не включает параметр шлюза по умолчанию в клиент боковая конфигурация (или не торопитесь). Проталкивать только маршрут предпочтительных подсетей. Предупреждение: если вы сделали VPN, чтобы скрыть свой (домашний) публичный адрес, возможно, это не то, что вам нужно!
Я думаю, что проблема, с которой вы столкнулись, заключается в том, что маршрут по умолчанию находится в VPN, и есть некоторые маршруты, которые фильтруют пакеты, поступающие с интерфейса, у которого нет маршрута к источнику. Это называется RP фильтр.
У вас есть 2 решения, чтобы иметь другой маршрут по умолчанию для sshd, чем для остальных процессов. Вы можете использовать сетевые пространства имен или контрольные группы. Я мало что знаю об этом, но вы можете прочитать больше в ответах на:
https://superuser.com/questions/271915/route-the-traffic-over-specific-interface-for-a-process-in-linux
Я бы предложил использовать параметры «--up» и «--down» для запуска сценариев оболочки, которые управляют брандмауэром и таблицей маршрутизации на вашей виртуальной машине по мере необходимости. Это позволит вам туннелировать трафик через вашу VPN (если openvpn этого еще не делает) и сделать исключение для трафика ssh. Помните, что правила iptables применяются сверху вниз, поэтому убедитесь, что ваше правило исключения применяется до правила туннелирования. Есть и другие вопросы, которые вы можете использовать в качестве примеров, о том, как управлять таблицами маршрутизации и правилами брандмауэра.
iptables - Цель для маршрутизации пакета к определенному интерфейсу?