Настройка OpenVPN, VPN через http (https) прокси
В некоторых сетях единственным доступным сервисом является веб через прокси-сервер. Многие сервисы (ssh, почта, некоторые IM) не могут работать через прокси, но существуют способы пробросить vpn на какой-либо удаленных хост.
Итак, после проведения некоторого исследования, выбор пал на openvpn. И вот как я его настраивал:
У меня было две машины: мой ноутбук (note) и домашний сервер vpn.mydomain.ru (который выполняет у меня функции интернет-шлюза, кешрующего прокси, тестового веб-сервера, файлохранилища, и многого чего другого).
Установка и на том и на другом прошла очень легко (строго говоря, он у меня уже был установлен "на всякий случай"):
Первое что нужно сделать, это сгенерировать все необходимые ключи, это можно сделать с помощью скриптов, входящих в комплект openvpn:
После этого в поддиректории keys появятся все необходимые ключи.
Переместите их в какое-нибудь надежное и защищеное место.
Скопируйте файлы ca.crt и note.* на клиент.
Строго говоря, можно было сгенерировать пару ключей на клиенте и передать на сервер публичный ключ для подписи. Но поскольку у меня был защищеный канал (ssh) между клиентом и сервером, я сгенерировал все в одном месте.
Далее нужно написать конфигурационный файл для openvpn. У меня получилось так:
Запуск сервера происходит командой openvpn /etc/openvpn/server.conf.
Перед запуском надо подгрузить модуль tun.
Вот конфигурационный файл:
После подгрузки модуля tun и запуска клиента, можно убедиться что интерфейс поднимается, и сервер пингуется.
Внимание: после поднятия vpn, openvpn перепишет шлюз по умолчнию, так что нужно заранее добавить статические маршруты (если таковых нету) к прокси-серверу и местной локальным ресурсам.
Однако после поднятия vpn, внешние ресурсы все еще не будут работать. А все потому что нужно выполнить шаг
Во-первых, разрешаем серверу маршрутизировать пакеты. Для этого пишем в /etc/sysctl следующее:
Далее нужно средствами iptables настроить правила маскарадинга. Для этого удобно написать sh-скриптик, который в дальнейшем будет удобно пополнять и редактировать. У меня он имеет примерно такой вид (сокращено):
После выполнения скрипта достаточно сделать
Итак, после проведения некоторого исследования, выбор пал на openvpn. И вот как я его настраивал:
1: установка OpenVPN
У меня было две машины: мой ноутбук (note) и домашний сервер vpn.mydomain.ru (который выполняет у меня функции интернет-шлюза, кешрующего прокси, тестового веб-сервера, файлохранилища, и многого чего другого).
Установка и на том и на другом прошла очень легко (строго говоря, он у меня уже был установлен "на всякий случай"):
emerge -av1 openvpnОтмечу полезный USE-флаг: examples. Он включает установку примеров конфигурационных файлов, которыми можно воспользоваться как основой для написания своих.
2: конфигурация сервера
Первое что нужно сделать, это сгенерировать все необходимые ключи, это можно сделать с помощью скриптов, входящих в комплект openvpn:
cd /usr/share/openvpn/easy-rsa/
# инициализация
. ./vars
./clean-all
# эта команда создает Certificate Authority, выполняется интерактивно (т.е. вам нужно будет
#ответить на несколько вопросов). Можно оставить все по умолчанию, изменив лишь данные о
#географическом положении.
# Единственный вопрос, на который следует обратить внимание - Common Name. Не так важно, что вы
#туда введте, но он должен быть установлен.
./build-ca
# генерация пары ключей для сервера
./build-key-server server
# генерация пары ключей для клиента
./build-key note
# генерация Diffie Hellman:
./build-dh
После этого в поддиректории keys появятся все необходимые ключи.
Переместите их в какое-нибудь надежное и защищеное место.
Скопируйте файлы ca.crt и note.* на клиент.
Строго говоря, можно было сгенерировать пару ключей на клиенте и передать на сервер публичный ключ для подписи. Но поскольку у меня был защищеный канал (ssh) между клиентом и сервером, я сгенерировал все в одном месте.
Далее нужно написать конфигурационный файл для openvpn. У меня получилось так:
# биндимся к порту 443, т.к. это единственный порт, на который разрешено делать CONNECT на том прокси-сервере
#port 1194
port 443
# TCP or UDP server?
proto tcp
;proto udp
dev tun
# пути к файлам сертификатов
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key # This file should be kept secret
dh /etc/openvpn/keys/dh1024.pem
# тут важно выбрать такую подсеть, которая не пересекалась бы ни с одной другой используемой вами
server 192.168.120.0 255.255.255.0
ifconfig-pool-persist ipp.txt
# так можно указывать клиенту, какие сети нужно маршритизировать через этот vpn
;push "route 192.168.1.0 255.255.255.0"
# а так можно указать, что этот vpn следует сделать шлюзом по умолчанию (что нам и нужно)
push "redirect-gateway"
# Разрешаем клентам взаимодействовать друг с другом, по умолчанию отключено
client-to-client
# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120
# включаем компрессию
comp-lzo
# так можно указать максимально количество клиентов
;max-clients 100
# так можно заставить openvpn сбросить права
;user nobody
;group nobody
# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun
# лог-фай
status openvpn-status.log
Запуск сервера происходит командой openvpn /etc/openvpn/server.conf.
Перед запуском надо подгрузить модуль tun.
3: Конфигурация клиента
Вот конфигурационный файл:
client
dev tun
# указываем протокол и прокси
proto tcp
http-proxy proxy 3128
;http-proxy-retry # retry on connection failures
# указываем адрес и порт удаленного сервера
remote vpn.mydomain.ru 443
resolv-retry infinite
nobind
# Downgrade privileges after initialization (non-Windows only)
;user nobody
;group nobody
persist-key
persist-tun
# пути к сертификатам и ключам
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/note.crt
key /etc/openvpn/keys/note.key
# разрешаем компрессию
comp-lzo
После подгрузки модуля tun и запуска клиента, можно убедиться что интерфейс поднимается, и сервер пингуется.
Внимание: после поднятия vpn, openvpn перепишет шлюз по умолчнию, так что нужно заранее добавить статические маршруты (если таковых нету) к прокси-серверу и местной локальным ресурсам.
Однако после поднятия vpn, внешние ресурсы все еще не будут работать. А все потому что нужно выполнить шаг
4: настройка NAT
Во-первых, разрешаем серверу маршрутизировать пакеты. Для этого пишем в /etc/sysctl следующее:
net.ipv4.ip_forward = 1После чего выполняем sysctl -a.
net.ipv4.ip_dynaddr = 1
Далее нужно средствами iptables настроить правила маскарадинга. Для этого удобно написать sh-скриптик, который в дальнейшем будет удобно пополнять и редактировать. У меня он имеет примерно такой вид (сокращено):
#!/bin/sh
# маски используемых сетей
IP_LAN="192.168.1.1/24" # моя домашняя сеть
IP_PROVIDER="10.0.0.1/8" # локальная сеть провайдера
# интерфейсы
IF_EXT="eth1" # сюда подключен Ethernet от провайдера
IF_LAN="eth0" # сюда подключена локальная сеть
IF_INET="ppp0" # сюда "подключен" интернет
IF_VPN="tun0" # это интерфейс нашего vpn
IPT="iptables"
# cleaning:
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X
# тут по желанию и степени паранои
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
# allow loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
###
# local host:
# allow outgoing connections:
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# разрешаем подключения к vpn
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT
# разрешаем NAT из локальной сети и VPN:
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $IF_INET -j MASQUERADE
$IPT -A FORWARD -i $IF_LAN -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_EXT -o $IF_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_LAN -o $IF_INET -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_INET -o $IF_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_VPN -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_EXT -o $IF_VPN -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_VPN -o $IF_INET -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_INET -o $IF_VPN -m state --state ESTABLISHED,RELATED -j ACCEPT
После выполнения скрипта достаточно сделать
/etc/init.d/iptables save
и добавить iptables в runlevel: rc-update add iptables default
Комментарии