понедельник, 21 апреля 2008 г.

OpenVPN между FreeBSD и Windows

OpenVPN между FreeBSD и Windows




Для создания vpn между Windows и FreeBSD оптимальным решением является использование OpenVPN, по крайней мере в моём случае. У меня сервер на FreeBSD а клиенты будут на Windows-e. Так как клиенты будут подключатся к серверу "не известно откуда" (т.е. гостиницы, аэропорты) это значит, что постоянного IP адреса у них не будет, и возможно, провайдером будут блокированны некоторые порты. Поэтому решения с помощью IPSEC и прочих сладостей отпадают, поэтому и OpenVPN :) . Оффициальный Howto рекомендует использовать для конекта UDP порт с номером 1194. Но я поставил у себя TCP 443. Объясню почему, потому что на TCP вероятность установить соединение больше, (т.к. если кто-то будет блокировать UDP), а 443 порт всегда открыт, я еще не видел, чтобы его закрывали. Но если хочется иметь 100% гарантию удачного соединения, можно сервер повесить и на TCP 80-ый порт.

Итак что нужно для того, чтобы все заработало? Я решил разбить задачи на несколько пунктов - так нагляднее:

1. Установка OpenVPN из портов
2. Генерация сертификатов для клиента и для сервера
3. После сертификатов необходимо создать и откофигурировать конфигурационный файл OpenVPN server-a
4. Далее запуск сервера и включение автозапуска при старте системы
5. Настройка OpenVPN клиента под Windows
6. Тестинг и проверинг
7. Как оно работает

Итак пункт 1-ый - Установка, тут все просто :)



#make && make install && make clean


Далее пункт 2-ой - Генерация ключей и сертификатов. Здесь тоже все просто, нужно перейти в каталог в котором расположенны скрипты для создания сертификатов. Нужно поочереди запустить каждый скрипт и отвечать на его вопросы. В общем создание сертификатов - дело интерактивное :)

# cd /usr/local/share/doc/openvpn/easy-rsa/
#ls

vars
clean-all
build-ca
build-key-server
build-key
build-dh
ta.key



На самом деле там больше скриптов, но мне только эти нужны. Далее запускаем оболочку shell и очищаем старые сертификаты:

# sh
# . ./vars

NOTE: when you run ./clean-all, I will be doing a rm -rf on /usr/local/share/doc /openvpn/easy-rsa/keys
# ./clean-all

Теперь создаем Certificate Authority для сервера

# ./build-ca
Generating a 1024 bit RSA private key
.....................................++++++
......++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:MD
State or Province Name (full name) [NA]:Chisinau
Locality Name (eg, city) [BISHKEK]:Chisinau
Organization Name (eg, company) [OpenVPN-TEST]:company
Organizational Unit Name (eg, section) []:server
Common Name (eg, your name or your server's hostname) []:server
Email Address [me@myhost.mydomain]:administrator@company.md
#

Пояснения:
то, что выделенно жирным - то я вводил своими руками, хочу обратить внимание, только на 2-е вещи
Country Name (2 letter code) [KG]:MD --> Здесь нужно написать только 2-е буквы.
Common Name (eg, your name or your server's hostname) []:server а это идентификатор, где будет использоваться сертификат. Т.е. для сервера это будет server а для клиентов это будет client, client2,client3.


Далее необходимо создать сертификат X.509 для сервера, тут почти то же самое, что и для первого (CA).

# ./build-key-server server
Generating a 1024 bit RSA private key
.........................................++++++
........................++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:MD
State or Province Name (full name) [NA]:Chisinau
Locality Name (eg, city) [BISHKEK]:Chisinau
Organization Name (eg, company) [OpenVPN-TEST]:company
Organizational Unit Name (eg, section) []:company
Common Name (eg, your name or your server's hostname) []:server
Email Address [me@myhost.mydomain]:administrator@company.md

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:gfccdjhl
An optional company name []:company
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'MD'
stateOrProvinceName :PRINTABLE:'Chisinau'
localityName :PRINTABLE:'Chisinau'
organizationName :PRINTABLE:'company'
organizationalUnitName:PRINTABLE:'company'
commonName :PRINTABLE:'server'
emailAddress :IA5STRING:'administrator@company.md'
Certificate is to be certified until Apr 1 20:31:10 2018 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#


Теперь ключ для клиента, все то же самое, нужно отвечать на простые вопросы :)


# ./build-key client
Generating a 1024 bit RSA private key
..........++++++....++++++
writing new private key to 'client.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:MD
State or Province Name (full name) [NA]:Chisinau
Locality Name (eg, city) [BISHKEK]:Chisinau
Organization Name (eg, company) [OpenVPN-TEST]:company
Organizational Unit Name (eg, section) []:client
Common Name (eg, your name or your server's hostname) []:client
Email Address [me@myhost.mydomain]:director@company.md

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:gfccdjhl
An optional company name []:company
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'MD'
stateOrProvinceName :PRINTABLE:'Chisinau'
localityName :PRINTABLE:'Chisinau'
organizationName :PRINTABLE:'company'
organizationalUnitName:PRINTABLE:'client'
commonName :PRINTABLE:'client'
emailAddress :IA5STRING:'director@company.md'
Certificate is to be certified until Apr 1 20:35:54 2018 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#



Далее нужно создать ключ Diffie Hellman Интерессный вывод получается ;)

# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.................................................................................................................
+................................+.............................................................................
......................+.........................................................................................
...+................+....+....................+.....................................................+......
...............................+................................................................................
....+.........+.......................................+...................+..................................
....+......................................................................................+....................
........................................+........................+...+.........................................
..++*++*++*
#


И еще один ключ:

# openvpn --genkey --secret ta.key


ta.key будет находится здесь /usr/local/share/doc/openvpn/easy-rsa/
А все остальные ключи, которые я до сих пор создавал будут здесь /usr/local/share/doc/openvpn/easy-rsa/keys.
Что для чего можно увидеть в табличке:



Filename Needed By Purpose Secret
ca.crt server + all clients Root CA certificate NO
ca.key key signing machine only Root CA key YES
dh1024.pem server only Diffie Hellman parameters NO
server.crt server only Server Certificate NO
server.key server only Server Key YES
client.crt client1 only Client1 Certificate NO
client.key client1 only Client1 Key YES



С ключами я закончил, перехожу к пункту 3.

Пункт 3-и создание и кофигурирование файла настроек OpenVPN server-a



Для начала необходимо создать директорию, в которой будет находится конфиг файл и сертификаты. Конфиг файл нужно создать вручную, а сертификаты и ключи, которые я создал нужно скопировать из директории keys. Еще нужно самому создать будущие лог файлы, после этого в конфиге нужно указать "что - где" находится.

#mkdir /usr/openvpn (<- Здесь будет конфиг сервера)
#mkdir /usr/openvpn/keys (<- Здесь будут ключи сервера)
#mkdir /usr/openvpn/ccd (<- Здесь будут настройки клиента (мне это не понадобилось))
#mkdir /var/log/openvpn (<- Здесь будут логи)
#touch /usr/openvpn/server.conf (<- Собственно сам конфиг сервера)
#touch /var/log/openvpn/openvpn.log (<- Собственно лог)
#touch /var/log/openvpn/openvpn-status.log (<- А здесь можно будет увидеть в каком состоянии сервер)

Уже хочется начать править конфиг, но надо не забыть скопировать ключи в рабочую директорию.


#cd /usr/local/share/doc/openvpn/easy-rsa/keys
#cp ca.crt /etc/openvpn/keys
#cp dh1024.pem /etc/openvpn/keys
#cp server.crt /etc/openvpn/keys
#cp server.key /etc/openvpn/keys
#cd ../ cp ta.key /etc/openvpn/keys

Вот теперь самое вкуссное :)

#ee /usr/openvpn/server.conf

port 443 ;порт
proto tcp ;протокол
dev tun ;устройство (tun тунель)
keepalive 20 240 ;ping каждые 20 сек, если после 240 сек ответа нет - значит связь потерянна
server 10.20.30.0 255.255.255.0 ;указываю VPN подсеть (все VPN клиенты будут получать адреса из 10.20.30.0 подсети)

;далее я указываю пути к сертификатам
ca /usr/openvpn/keys/ca.crt
cert /usr/openvpn/keys/server.crt
key /usr/openvpn/keys/server.key
dh /usr/openvpn/keys/dh1024.pem

tls-server ;включение дополнительной безопасности, ключ ta.key должен быть и на сервере и на клиенте. 2-ой параметр в конфигах должен быть "0" на сервере и "1" у клиента (см. ниже)
tls-auth /usr/openvpn/keys/ta.key 0 ;путь к ключу
tls-timeout 120 ;время до реконекта
cipher BF-CBC ;шифрование Blowfish (можно поставить AES, DES - у меня стандартное)
persist-key
persist-tun

user nobody ;запуск OVPN от виртуального пользователя
group nobody

ifconfig-pool-persist ipp.txt ;для того, чтобы клиенту всегда выдавался один и тот же ip (здесь хранится соотвествие клиент - виртуальный IP)
push "route 10.0.0.0 255.255.255.0" ;так прописывается маршрут для клиента, чтобы он смог видеть подсеть за VPN сервером
route 10.20.30.0 255.255.255.0 ;а это маршрут сервер-клиент

comp-lzo ;включить сжатие
max-clients 10 ;максимум 10 клиентов
log /var/log/openvpn/openvpn.log ;лог файл (не забываем создавать лог файлы)
status /var/log/openvpn/openvpn-status.log ;здесь можно будет посмотреть текущее состояние сервера
verb 4 ;уровень логирования, от 0 до 9 (9-максимум логов)
mute 10 ;Запрет на повтор сообщений в логах. Не более 10 идущих друг за другом сообщений одного типа будут направлены в лог.



Это был конфигурационный файл OpenVPN сервера, у меня он находится здесь /usr/openvpn/server.conf
еще раз, только уже без комментариев:

#NETWORK
port 443
proto tcp
dev tun
keepalive 20 240
server 10.20.30.0 255.255.255.0

route 10.20.30.0 255.255.255.0
push "route 10.0.0.0 255.255.255.0"
ifconfig-pool-persist ipp.txt

#SECURITY
ca /usr/openvpn/keys/ca.crt
cert /usr/openvpn/keys/server.crt
key /usr/openvpn/keys/server.key
dh /usr/openvpn/keys/dh1024.pem
tls-server
tls-auth /usr/openvpn/keys/ta.key 0
tls-timeout 120
cipher BF-CBC
persist-key
persist-tun

user nobody
group nobody

comp-lzo
max-clients 10
log /var/log/openvpn/openvpn.log
status /var/log/openvpn/openvpn-status.log
verb 4
mute 10


Пункт 4-ый запуск сервера и включение автозапуска


Запуск:

#/usr/local/etc/rc.d/openvpn start


или так (переходим в каталог openvpn и запускаем оттуда конфиг сервера)

#cd /usr/openvpn/
#openvpn --config server.conf


Чтобы при старте системы запускался openvpn нужно добавить пару строк в /etc/rc.conf

openvpn_enable="YES"
openvpn_if="tun"
openvpn_configfile="/usr/openvpn/server.conf"
openvpn_dir="/usr/openvpn"


Пункт 5-ый Настройка OpenVPN клиента под Windows


Скачать. Установить. Сюда C:\Program Files\OpenVPN\config скинуть с сервера ключи/сертификаты:
-ca.crt
-client.crt
-client.key
-ta.key

Подправить этот конфиг C:\Program Files\OpenVPN\config\client.ovpn - у меня он такой:

dev tun
proto tcp
remote 211.211.211.21 ;это реальный IP сервера
port 443
client
resolv-retry infinite
ca ca.crt
cert client.crt
key client.key
tls-client
tls-auth ta.key 1
cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun
verb 4



Запуск клиента:
Прав. кнопкой по конфиг файлу client.ovpn из открывшегося меню выбрать "Start openvpn on this config file" или через *.bat файл с таким содержанием:

"C:\Program Files\OpenVPN\bin\openvpn.exe" "C:\Program Files\OpenVPN\config\client.ovpn"


ВАЖНО:


OPENVPN и WINDOWS VISTA не будут работать с конфигом кот. выше. Для того чтобы связать vpn клиента на vista нужно добавить в конфиг файл клиента пару строк:

route-method exe
route-delay 2


И ОБЯЗАТЕЛЬНО запускать через *.bat файл. Содержимое как и выше, путь к программе и путь к конфигу:

"C:\Program Files\OpenVPN\bin\openvpn.exe" "C:\Program Files\OpenVPN\config\client.ovpn"


Для запуска, нажать правой кнопкой мыши на *.bat файл и выбрать “Запустить как администратор”. Дело в том, что при запуске, идет подключение к серверу и клиент пытается прописать маршруты в таблицу маршрутизации, а vista блокирует попытку и в логах можно увидеть такие строки:

ROUTE: route addition failed using CreateIpForwardEntry:


Пункт 6-ой Тестинг



После запуска сервера можно посмотреть запустился ли он:

# top | grep openvpn
659 nobody 1 96 0 2984K 2444K select 0:01 0.00% openvpn

# sockstat -4 | grep 443
nobody openvpn 659 5 tcp4 *:443 *:*


Если нет смотрим логи. У меня лог файл здесь /var/log/openvpn/openvpn.log если запустился можно пинговать клиента его IP будет 10.20.30.6 (это IP адресс первого клиента)

С клиента можно пинговать vpn сервер (10.20.30.1) пинговать компы за сервером (10.0.0.2, 10.0.0.10), подключать папки, заходить на терминал сервер (если есть).



7 Как оно работает



Почему такая странная адресация у первого клиента? Почему IP адресс 10.20.30.6 , а не к примеру 10.20.30.2 ?

Для каждого подключения OpenVPN разделяет сеть 10.20.30.0 на подсети по 4-ре IP-адреса.

Первому клиенту выделяется подсеть 10.20.30.4 с маской /30 (255.255.255.252)


-10.20.30.4 это адрес самой сети
-10.20.30.5 это виртуальный шлюз сервера (этот адрес не пингуется и используется только сервером)
-10.20.30.6 это адрес клиента
-10.20.30.7 это широковещательный адрес сети (subnet broadcast)


Второму клиенту выделяется следующий блок из 4-х узлов (10.20.30.8/30)

10.20.30.8 это адрес самой сети
10.20.30.9 это виртуальный шлюз сервера
10.20.30.10 это адрес клиента
10.20.30.11 это широковещательный адрес сети


VPN server всегда ждет подключения по адресу 10.20.30.1, он и есть Основной шлюз для VPN клиента.


Удачи в настройке

9 комментариев:

  1. А если во внутренней сети шлюз по умолчанию не равен внутреннему интерфейсу сервера с OpenVPN?
    То кактогда настроить чтобы сожно было видеть внутреннюю сеть?

    ОтветитьУдалить
  2. # . build-key-server server
    .: Can't open build-key-server: No such file or directory


    как быть?

    ОтветитьУдалить
  3. Выполните команду pwd посмотрите в какой директории вы находитесь.

    вам нужно быть здесь:

    # cd /usr/local/share/doc/openvpn/easy-rsa/

    проверте есть ли нужный вам скрипт:

    #ls
    vars
    clean-all
    build-ca
    build-key-server
    build-key
    build-dh
    ta.key

    если есть, то запускайте его правильно:

    #./build-key-server server

    ОтветитьУдалить
  4. Все сделал по статье - статья отличная. Но у меня одна проблеммка - подключиться может только один человек, когда подключается второй одновременно - отключается первый и ему назначается адрес первого (10.1.0.6). Я подозреваю что под каждое соединение нужно прописать маршрут, но как это сделать не соображу. Подскажите пожалуйста?

    ОтветитьУдалить
  5. пользователи должны иметь отдельные ключи и отдельные файлы настроек (в принципе это не обязательно но так 100% работает без шаманства, и конфликтов не будет)

    итак в конфиг сервера должен быть добавлен следующий параметр:
    client-config-dir /etc/openvpn/ccd
    # это путь где будут храниться файлы конфигураций клиентов
    # в этом каталоги создать файлы client1, client2 ... и по именам ключей пользователей (заданым в параметре "commonName " при генерации ключа!!! желательно не содержащее точек!)
    файлы клиента должны содержить что-то вроде этого:
    # ip-address assignment
    ifconfig-push 192.168.10.2 255.255.255.0
    # routing
    push "route 192.168.1.0 255.255.255.0 192.168.10.1"

    ОтветитьУдалить
  6. при попытке подключиться пишет в логах UDPv4: Connection reset by peer (WSAECONNRESET)(code=10054). что может быть?

    ОтветитьУдалить
  7. Здравствуйте. Имеется сервер в Польше, я нахожусь в России. Что бы я выходил на сайты с Польского IP, мне подойдет VPN через сервер в Польше?

    ОтветитьУдалить
  8. Да, можно клиента "заставить" пустить весь трафик через VPN туннель как написано здесь:
    http://forum.searchengines.ru/showthread.php?t=709641

    или сделать так:

    http://senatum.blogspot.com/2008/07/ssh-sleepshell.html

    ОтветитьУдалить
  9. # ./build-key-server server
    usage: build-key-server
    как исправить? подскажите пожалуста!

    ОтветитьУдалить