Установка и настройка OpenVPN-сервера

()

Часто возникает необходимость организовать 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.

На этом всё. Приятной работы!

Ключевые слова: openvpn, windows, tun, proxy, tunnel.

Комментарии:

Anonymous 2010-03-09 17:56:43 (#)

Сделал все в точности как описано выше, при выполнении invoke-rc.d openvpn restart


* 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.


вот такая вот ошибка

Anonymous 2010-03-09 19:14:33 (#)

Решил таким образом

mkdir -p /dev/net
mknod /dev/net/tun c 10 200
chmod 600 /dev/net/tun

если не помогло пишите в поддержку Вашего VPS с просььбой включения TUN

Anonymous 2010-03-11 20:10:28 (#)

А как насчет входящих соединений, например, для торрентов?

MooSE 2010-03-12 02:14:08 (#)

Цитата:

А как насчет входящих соединений, например, для торрентов?


Легко. Умеешь порты пробрасывать?

Anonymous 2010-03-13 12:47:47 (#)

Т.е. для каждого пользователя надо выделить диапазон портов, настроить перенаправление с виртуальных интерфейсов на внешний и соответствующим образом настроить пользовательские программы?

MooSE 2010-03-13 22:37:06 (#)

как-то так. да.

Anonymous 2010-03-16 00:03:35 (#)

Поднял VPN по вашему ману. Подскажите пожалуйста какие настроки внести что бы отображались DNS не моего провайдера, а те которые я указал в настройках VPN.

Anonymous 2010-03-16 00:20:44 (#)

При проверке DNS здесь http://private.dnsstuff.com/tools/aboutyou.ch

отображаются DNS моего провайдера

Anonymous 2010-03-16 01:41:09 (#)

Если быть точным то отображается DNS моего провайдера и DNS VPN сервера. Как сделать что бы отображался только DNS сервера?
Сори за несколько сообщений.

MooSE 2010-03-16 23:57:32 (#)

чёзанах ваще? а просто по человечески настройки сети посмотреть религиозные или политические убеждения не позволяют? обязательно левые тульзы пользовать?

Anonymous 2010-03-25 16:51:10 (#)

А по человечески ответить что мешает? Как посмотреть настройки сети, ipconfig /all?

Какие левые тулзы? Если эта тулза увидела мой DNS то и все остальные увидят.

http://private.dnsstuff.com/tools/aboutyou.ch или http://whoer.net/ext все одинаково видят мой DNS, тут же выключаю и включаю другой VPN c DNS все ок, поэтому проблема с настройкой DNS по данному ману есть 100%.

MooSE 2010-03-25 23:13:37 (#)

в винде - да
ipconfig /all
. в *nix смотреть в файле /etc/resolv.conf...

mefodiy 2012-09-28 11:28:41 (#)

Все здрасте! Может быть вопрос немного не в тему, но очень нужно решение) Думаю такие профи как вы смогут разрешить такой пустяк=) Поднял сервер и клиенты. все как описано, все ОК! (За статью отдельное спасибо!!!) Вопрос: как сделать так что бы соединение между компами были только по внутренней сети, то есть по VPN а по локалке нельзя было подключаться?

MooSE 2012-09-28 15:56:33 (#)

Цитата:

Все здрасте! Может быть вопрос немного не в тему, но очень нужно решение) Думаю такие профи как вы смогут разрешить такой пустяк=) Поднял сервер и клиенты. все как описано, все ОК! (За статью отдельное спасибо!!!) Вопрос: как сделать так что бы соединение между компами были только по внутренней сети, то есть по VPN а по локалке нельзя было подключаться?


Т.е. все клиенты у тебя в одной сети? И зачем тогда им VPN?
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE