Часто возникает необходимость организовать VPN-туннель чтобы скрыть свой реальный IP-адрес, или находясь за NAT своего провайдера и имея "снаружи" сервер с реальным IP-адресом использовать преимущества этого адреса. Далее будет показано как можно решить эту задачу используя OpenVPN.
В качестве сервера мы будем использовать VDS от Gelihost с тарифом SmallVDS-VPN и установленной операционной системой Ubuntu 8.04. На этом тарифном плане нам дают два IP-адреса в разных сетях класса C.
Допустим что нам были выделены адреса 1.1.1.10 и 1.1.2.10. Первый мы используем как "точку входа" (к нему буду подключаться клиенты), а второй как "точку выхода" (в этот адрес мы будем транслировать адреса наших клиентов). Клиентам мы будем выдавать адреса из сети 172.17.255.0/24.
Для начала установим необходимое программное обеспечение:
apt-get install openvpn iptables maradns
Настройка iptables
Сразу настроим правила iptables, для этого создадим скрипт /usr/local/scripts/firewall.sh следующего содержания:
#!/bin/sh # Имена сетевых интерфейсов: # Внешний, на котором "висят" белые адреса нашего сервера: IF_EXT="venet0" # Виртуальный интерфейс, на котором будут все пользователи VPN: IF_VPN="tun0" # IP-Адреса: # Внешний (используется для исходящих соединений: IP_OUT="1.1.2.10" # Второй внешний адрес, к нему будут подключаться клиенты: IP_IN="1.1.1.10" # Сеть, в которой будут находиться клиенты нашего VPN-сервера: NET_VPN="172.17.255.0/255.255.255.0" # Сбрасываем все правила: iptables -F iptables -F -t nat # Устанавливаем политики по умолчанию: # Запрещаем весь входящий трафик: iptables -P INPUT DROP # Разрешаем исходящий трафик: iptables -P OUTPUT ACCEPT # Запрещаем пересылку трафика: iptables -P FORWARD DROP # Разрешаем входящий трафик в рамках установленных соединений: iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # Разрешаем весь трафик внутри сервера: iptables -A INPUT -i lo -j ACCEPT # Разрешаем ICMP-трафик для всех: iptables -A INPUT -p icmp -j ACCEPT # Разрешаем SSH на IP-адресе для входящих подключеий: iptables -A INPUT -m tcp -p tcp --dport 22 -d ${IP_IN} -j ACCEPT # Разрешаем OpenVPN на IP-адресе для входящих подключений:: iptables -A INPUT -m tcp -p tcp --dport 1194 -d ${IP_IN} -j ACCEPT # Разрешаем использование DNS-сервера клиентами VPN-сервера iptables -A INPUT -m udp -p udp --dport 53 -s ${NET_VPN} -i ${IF_VPN} -j ACCEPT # NAT для сети VPN: iptables -t nat -A POSTROUTING -s ${NET_VPN} -j SNAT -o ${IF_EXT} --to-source ${IP_OUT} iptables -A FORWARD -i ${IF_VPN} -o ${IF_EXT} -s ${NET_VPN} -j ACCEPT iptables -A FORWARD -i ${IF_EXT} -o ${IF_VPN} -d ${NET_VPN} -m state --state RELATED,ESTABLISHED -j ACCEPT
Применим эти правила:
/usr/local/scripts/firewall.sh
И добавим строку вызова этого скрипта в файл /etc/rc.local. Затем добавим в файл /etc/sysctl.conf строку:
net.ipv4.ip_forward=1
Эта строка разрешает пересылку пакетов в соответствии с правилами iptables в цепочке FORWARD таблицы filter. Применим эти изменения командой:
sysctl -p
Настройка DNS-сервера
Теперь настроим DNS-сервер для клиентов (в качестве него мы будем использовать пакет maradns, установленный чуть раньше). Для этого открываем в редакторе файл /etc/maradns/mararc и первым делом меняем значение параметра "bind_address":
bind_address = "0.0.0.0"
Затем разрешим использование сервера нашими клиентами добавив в конец файла строки:
ipv4_alias["localhost"] = "127.0.0.0/8" ipv4_alias["localnet"] = "172.17.255.0/24" recursive_acl = "localhost,localnet"
Чтобы настройки вступили в силу перезапустим процесс:
invoke-rc.d maradns restart
Настройка OpenVPN-сервера
На этом приготовления закончены и можем приступить к настройке OpenVPN-сервера. Для начала подготовим структуру каталогов:
cp -av /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa mkdir -p /etc/openvpn/{ccd,easy-rsa/keys} ln -sf /etc/openvpn/easy-rsa/keys /etc/openvpn/keys
Переходим директорию /etc/openvpn/easy-rsa:
cd /etc/openvpn/easy-rsa
Редактируем файл "vars", указывая желаемые данные для генерируемых сертификатов после чего устанавливаем необходимые переменный окружения командой:
. ./vars
Генерируем основные ключи:
./clean-all && ./build-ca && ./build-dh
Генерируем сертификат сервера:
./build-key-server server
Далее для каждого из пользователей генерируем именной клиентский сертификат:
./build-key username
Закончив создание сертификатов приступаем к написанию файлов конфигурации. Создаём файл /etc/openvpn/server.conf следующего содержания:
mode server tls-server daemon server 172.17.255.0 255.255.255.0 port 1194 proto tcp-server dev tun0 ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/server.crt key /etc/openvpn/keys/server.key dh /etc/openvpn/keys/dh1024.pem client-config-dir /etc/openvpn/ccd push "redirect-gateway def1" push "dhcp-option DNS 172.17.255.1" push "dhcp-option WINS 172.17.255.1" keepalive 10 120 client-to-client comp-lzo persist-key persist-tun verb 3 log-append /var/log/openvpn.log
Здесь мы настраиваем OpenVPN-сервер для работы по протоколу TCP, несмотря на то, что обычно в таких конфигурациях используют протокол UDP. У варианта с использованием TCP есть как минимум одно существенное преимущество: клиент может находиться за http-прокси (с поддержкой метода CONNECT) и при этом пользоваться туннелем.
Закончив написание основного файла конфигурации сервера создадим для каждого пользовательского сертификата соответствующий ему файл конфигурации. Между клиентом и сервером будет устанавливаться соединение "точка-точка". Для каждого клиента мы выделим подсеть с маской /30 из нашей виртуальной сети (172.17.255.0/24).
В каждой такой подсети один адрес будет принадлежать серверу, а другой - клиенту. Приведём сводную таблицу возможных адресов для нашего случая:
Сеть | Адрес сервера | Адрес клиента |
---|---|---|
172.17.255.0/30 | 172.17.255.1 | 172.17.255.2 |
172.17.255.4/30 | 172.17.255.5 | 172.17.255.6 |
172.17.255.8/30 | 172.17.255.9 | 172.17.255.10 |
172.17.255.12/30 | 172.17.255.13 | 172.17.255.14 |
172.17.255.16/30 | 172.17.255.17 | 172.17.255.18 |
172.17.255.20/30 | 172.17.255.21 | 172.17.255.22 |
172.17.255.24/30 | 172.17.255.25 | 172.17.255.26 |
172.17.255.28/30 | 172.17.255.29 | 172.17.255.30 |
172.17.255.32/30 | 172.17.255.33 | 172.17.255.34 |
172.17.255.36/30 | 172.17.255.37 | 172.17.255.38 |
172.17.255.40/30 | 172.17.255.41 | 172.17.255.42 |
172.17.255.44/30 | 172.17.255.45 | 172.17.255.46 |
172.17.255.48/30 | 172.17.255.49 | 172.17.255.50 |
172.17.255.52/30 | 172.17.255.53 | 172.17.255.54 |
172.17.255.56/30 | 172.17.255.57 | 172.17.255.58 |
172.17.255.60/30 | 172.17.255.61 | 172.17.255.62 |
172.17.255.64/30 | 172.17.255.65 | 172.17.255.66 |
172.17.255.68/30 | 172.17.255.69 | 172.17.255.70 |
172.17.255.72/30 | 172.17.255.73 | 172.17.255.74 |
172.17.255.76/30 | 172.17.255.77 | 172.17.255.78 |
172.17.255.80/30 | 172.17.255.81 | 172.17.255.82 |
172.17.255.84/30 | 172.17.255.85 | 172.17.255.86 |
172.17.255.88/30 | 172.17.255.89 | 172.17.255.90 |
172.17.255.92/30 | 172.17.255.93 | 172.17.255.94 |
172.17.255.96/30 | 172.17.255.97 | 172.17.255.98 |
172.17.255.100/30 | 172.17.255.101 | 172.17.255.102 |
172.17.255.104/30 | 172.17.255.105 | 172.17.255.106 |
172.17.255.108/30 | 172.17.255.109 | 172.17.255.110 |
172.17.255.112/30 | 172.17.255.113 | 172.17.255.114 |
172.17.255.116/30 | 172.17.255.117 | 172.17.255.118 |
172.17.255.120/30 | 172.17.255.121 | 172.17.255.122 |
172.17.255.124/30 | 172.17.255.125 | 172.17.255.126 |
172.17.255.128/30 | 172.17.255.129 | 172.17.255.130 |
172.17.255.132/30 | 172.17.255.133 | 172.17.255.134 |
172.17.255.136/30 | 172.17.255.137 | 172.17.255.138 |
172.17.255.140/30 | 172.17.255.141 | 172.17.255.142 |
172.17.255.144/30 | 172.17.255.145 | 172.17.255.146 |
172.17.255.148/30 | 172.17.255.149 | 172.17.255.150 |
172.17.255.152/30 | 172.17.255.153 | 172.17.255.154 |
172.17.255.156/30 | 172.17.255.157 | 172.17.255.158 |
172.17.255.160/30 | 172.17.255.161 | 172.17.255.162 |
172.17.255.164/30 | 172.17.255.165 | 172.17.255.166 |
172.17.255.168/30 | 172.17.255.169 | 172.17.255.170 |
172.17.255.172/30 | 172.17.255.173 | 172.17.255.174 |
172.17.255.176/30 | 172.17.255.177 | 172.17.255.178 |
172.17.255.180/30 | 172.17.255.181 | 172.17.255.182 |
172.17.255.184/30 | 172.17.255.185 | 172.17.255.186 |
172.17.255.188/30 | 172.17.255.189 | 172.17.255.190 |
172.17.255.192/30 | 172.17.255.193 | 172.17.255.194 |
172.17.255.196/30 | 172.17.255.197 | 172.17.255.198 |
172.17.255.200/30 | 172.17.255.201 | 172.17.255.202 |
172.17.255.204/30 | 172.17.255.205 | 172.17.255.206 |
172.17.255.208/30 | 172.17.255.209 | 172.17.255.210 |
172.17.255.212/30 | 172.17.255.213 | 172.17.255.214 |
172.17.255.216/30 | 172.17.255.217 | 172.17.255.218 |
172.17.255.220/30 | 172.17.255.221 | 172.17.255.222 |
172.17.255.224/30 | 172.17.255.225 | 172.17.255.226 |
172.17.255.228/30 | 172.17.255.229 | 172.17.255.230 |
172.17.255.232/30 | 172.17.255.233 | 172.17.255.234 |
172.17.255.236/30 | 172.17.255.237 | 172.17.255.238 |
172.17.255.240/30 | 172.17.255.241 | 172.17.255.242 |
172.17.255.244/30 | 172.17.255.245 | 172.17.255.246 |
172.17.255.248/30 | 172.17.255.249 | 172.17.255.250 |
172.17.255.252/30 | 172.17.255.253 | 172.17.255.254 |
Подобный список можно сгенерировать с помощью несложного скрипта на perl:
#!/usr/bin/perl # Первые три октета сети my $net = shift || "172.17.255"; # Счётчик my $i = 0; while ($i < 255) { # Считаем адрес сервера $s = $i + 1; # Считаем адрес клиента $c = $i + 2; # Отображаем результат print "$net.$i/30\t$net.$s\t$net.$c\n"; # Увеличиваем значение счётчика $i += 4; }
Таким образом к нашему серверу может подключиться до шестидесяти четырёх клиентов. Теперь для каждого клиента нужно создать файл с именем вроде "/etc/openvpn/ccd/username" (здесь имя файла совпадает с именем соответствующего сертификата) и примерно такого содержания:
ifconfig-push 172.17.255.105 172.17.255.106
Если вам лень писать отдельную конфигурацию для каждого клиента вы можете посмотреть в сторону опции ifconfig-pool-persist, подробнее о которой можно прочитать в документации OpenVPN или в примерах использования. Закончив написание файлов конфигурации перезапустим сервис командой:
invoke-rc.d openvpn restart
Информацию о состоянии сервера можно получать в реальном времени читая файл "/var/run/openvpn.server.status".
Настройка клиента на машине под управлением Linux
На этом настройка сервера заканчивается и можно переходить к настройке клиентских машин. Для начала рассмотрим настройки клиентов, работающих в операционной системе Linux (на примере Ubuntu 9.10, однако в остальных дистрибутивах всё будет примерно так же).
Первым делом установим openvpn-клиент:
apt-get install openvpn
Скопируем в директорию "/etc/openvpn" с сервера ключевые файл:
- ca.crt
- username.crt
- username.key
А затем создадим файл "/etc/openvpn/client.conf", следующего содержания:
client dev tun0 proto tcp-client remote 1.1.1.10 1194 resolv-retry infinite nobind persist-key persist-tun ca /etc/openvpn/ca.crt cert /etc/openvpn/username.crt key /etc/openvpn/username.key comp-lzo verb 3
Разумеется что имена файлов ключей и адрес сервера нужно адаптировать под свой случай. Закончив конфигурирование клиента перезапустим процесс:
invoke-rc.d openvpn restart
Проверить что соединение установлено можно проверив таблицу роутинга на машине командой:
ip route|grep tun0
Результат должен выглядеть примерно вот так:
172.17.255.102 dev tun0 proto kernel scope link src 172.17.255.101 172.17.255.0/24 via 172.17.255.102 dev tun0 0.0.0.0/1 via 172.17.255.102 dev tun0 128.0.0.0/1 via 172.17.255.102 dev tun0
Если что-то пойдёт не так - внимательно проверьте конфигурацию клиента.
Настройка клиента на машине под управлением Windows
Переходим к настройке клиента на машине под управлением Windows. Для начала нужно скачать последнюю версию клиента OpenVPN и проинсталлировать её.
По умолчанию клиент устанавливается в директорию "C:\Program Files\OpenVPN", в которой есть поддиректория "config". В эту поддиректорию нужно положить файлы ключей, а так же в ней нужно создать файл "client.ovpn", следующего содержания:
client dev tun proto tcp-client remote 1.1.1.10 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert username.crt key username.key comp-lzo verb 3
Точно так же как и на Linux-машине здесь нужно соответствующим образом подправить адрес сервера и имена сертификатов. Важно что в данном случае можно не указывать абсолютные пути к файлам сертификатов.
После этого нужно запустить приложение "OpenVPN GUI", в трее появится иконка с изображением двух красных мониторов. По этой иконке надо кликнуть правой кнопкой мыши и в выпавшем меню выбрать пункт "Connect".
Так же следует отметить что OpenVPN имеет проблемы с Windows 7, поэтому пользователям этой операционной системы нужно в свойствах файла "openvpn.exe" выставить режим совместимости с Windows Vista и поставить галочку "Запускать с правами администратора".
Работа клиентов через прокси
Если клиент находится за прокси, то нужно добавить в файл конфигурации клиента строку:
http-proxy 192.168.2.1 3128
Здесь нужно указать адрес и порт прокси-сервера. Если используется прокси с авторизацией то настройка будет немного сложнее и подробнее об этом рекомендуется читать в документации OpenVPN.
На этом всё. Приятной работы!
Anonymous 2010-03-09 17:56:43 (#)
* Stopping virtual private network daemon(s)... * No VPN is running.
* Starting virtual private network daemon(s)... * Autostarting VPN 'server' [fail]
invoke-rc.d: initscript openvpn, action "restart" failed.
вот такая вот ошибка