Завалялся тут у меня на cloudatcost пожизненно оплаченный инстанс. Стабильности никакой, так пусть хоть трафик гоняет. Под катом описан личный опыт запуска OpenVPN.

DISCLAIMER

Данный мануал является порождением Франкенштейна: он был собран из множества источников, хоть я и не Виктор!

0. Сразу скопируем ssh-ключи

$ ssh-keygen -t rsa
$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@hostname

1. Установка пакетов

В Debian Stretch нам понадобится только родной sources.list. easy-rsa занимается созданием личного центра сертификации.

# apt-get update
# apt-get install openvpn easy-rsa

2. Генерируем сертификаты

Ничего особо примечательного в этом пункте кроме нескольких нефатальных глюков нет. Идём в /etc/openvpn, и нагенерируем себе центр сертификации имени себя.

# cd /etc/openvpn
# make-cadir rsa

Подгоним переменные центра сертификации под наши нужды:

# nano vars

Нас тут интересует в первую очередь вот это:

export KEY_COUNTRY="RU"
export KEY_PROVINCE="NA"
export KEY_CITY="Moscow"
export KEY_ORG="FORCE"
export KEY_EMAIL="mail@example.com"
export KEY_OU="FORCE"

Здесь меняем всё ненужное на нужное. KEY_PROVINCE заполняем как угодно, но без фанатизма.

Импортируем наши сетапы:

# source vars
ВНИМАНИЕ

Если вы получаете что-то типа:

**************************************************************
  No /root/rsa/openssl.cnf file could be found
  Further invocations will fail
**************************************************************
NOTE: If you run ./clean-all, I will be doing a rm -rf on /root/rsa/keys
То можно попробовать сделать так:

Если не помогло, и вылезает нечто типа -bash: /etc/openvpn/easy-rsa/openssl-1.0.0.cnf: Permission denied, то строку export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` меняем на export KEY_CONFIG=$EASY_RSA/openssl-1.0.0.cnf, как рекомендуют тут.

Удаляем всё ненужное:

# ./clean-all

Генерируем закрытый ключ и сертификат нашего ЦС:

# ./build-ca
ВНИМАНИЕ

Если вдруг ВНЕЗАПНО вылезло что-то типа:

error on line 198 of /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
140224783447712:error:0E065068:configuration file routines:STR_COPY:variable has no value:conf_def.c:618:line 198

То в vars дописываем это: export KEY_ALTNAMES="stopitplease". Тык.

И наконец-то всё должно сгенерироваться:

#: ./build-ca
Generating a 2048 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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:

Отлично. Проверим на месте ли наши сертификаты:

#: ls -lah ./keys
total 20K
drwx------ 2 root root 4.0K Mar 22 02:30 .
drwx------ 3 root root 4.0K Mar 22 02:30 ..
-rw-r--r-- 1 root root 1.8K Mar 22 02:39 ca.crt  # ага
-rw------- 1 root root 1.7K Mar 22 02:39 ca.key  # <--
-rw-r--r-- 1 root root    0 Mar 22 02:30 index.txt
-rw-r--r-- 1 root root    3 Mar 22 02:30 serial

Генерируем ключ и сертификат сервера. challenge password скипаем, с Sign the certificate? соглашаемся.

# ./build-key-server vpn_server
...
A challenge password []:
An optional company name []:
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y

Аналогичным способом создадим ключи для наших клиентов, пусть их зовут client1 && client2.

# ./build-key client1
# ./build-key client2

Создаём ключ Диффи-Хеллмана:

# ./build-dh

Для дополнительной безопасности создадим "HMAC firewall", помогающий блокировать DoS атаки и UDP port flooding (c) manual.

# openvpn --genkey --secret /etc/openvpn/ta.key

Всё, с генерацией покончено. Дабы меньше править sample-конфиг из примеров OpenVPN, перетащим всё нагенерённое добро в /etc/openvpn:

# cp ./keys/ca.crt ./keys/vpn_server.{crt,key} ./keys/dh*.pem /etc/openvpn/ -v
'./keys/ca.crt' -> '/etc/openvpn/ca.crt'
'./keys/vpn_server.crt' -> '/etc/openvpn/vpn_server.crt'
'./keys/vpn_server.key' -> '/etc/openvpn/vpn_server.key'
'./keys/dh2048.pem' -> '/etc/openvpn/dh2048.pem'

3. Пишем server.conf OpenVPN

Приводить тут все настройки подряд я не буду, отмечу только:

  1. Провайдер может фильтровать ваши пакеты.
  2. UDP могут не доходить по разным причинам.
  3. Стандартный порт OpenVPN может гаситься провайдерами по умолчанию.
  4. В начале настройки логи стоит писать с verb 5.

Поскольку провайдер может себя плохо вести, лучше выбрать для тренировок порт 443 и proto=udp поменять на proto=tcp. DNS можно брать, как предлагают в мануале, тут, или тут.

Полный конфиг выглядит так:

user nobody
group nogroup
port 1771
proto udp
dev tun

dh dh2048.pem
ca ca.crt
cert vpn_server.crt
key vpn_server.key
tls-auth ta.key 1
auth SHA512
mode server
tls-server

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 193.183.98.154"
push "dhcp-option DNS 5.135.183.146"

client-to-client
keepalive 10 120

cipher AES-256-CBC
comp-lzo
persist-key
persist-tun

verb 5
status /var/log/openvpn-status.log
log /var/log/openvpn.log

Активируем и перезапускаем openvpn:

systemctl enable openvpn
service openvpn restart

На этом этапе скорее всего не должно быть никаких проблем, кроме кривых путей.

4. Копируем клиентские ключи с сервера

mkdir ~/openvpn/
scp root@vpn_server:/etc/openvpn/rsa/keys/home1.{crt,csr,key} ~/openvpn/
scp root@vpn_server:/etc/openvpn/ta.key ~/openvpn/
scp root@vpn_server:/etc/openvpn/ca.crt ~/openvpn/

5. Настраиваем клиент OpenVPN

Создаём на клиентском хосте ~/openvpn/client.conf следующего вида:

tls-client
remote replace.me 1771
proto udp
dev tun0
resolv-retry infinite
nobind

user nobody
group nogroup

persist-key
persist-tun

ca ca.crt
cert home1.crt
key home1.key
tls-auth ta.key 0
remote-cert-tls server
cipher AES-256-CBC
comp-lzo

verb 5
auth SHA512

pull

Опция pull в конце позволяет OpenVPN серверу передавать нашему клиенту маршруты. Эти маршруты он [сервер] шлёт через push.

Пробуем подключиться:

sudo su
cd /home/user/openvpn/
openvpn --config client.conf
Потенциальные проблемы

Потенциальная проблема: Authenticate/Decrypt packet error: packet HMAC authentication failed, TLS Error: TLS key negotiation failed to occur within 60 seconds. Может быть связана с тем, что:

  1. Некорректно указано время на клиенте/сервере. Устанавливаем apt-get install ntpdate и настраиваем, если провайдер откусывает ntp.
  2. Неправильно сгенерирован сертификат. Он может быть просрочен, или выпущен в будущем.
  3. Неправильно указан в конфигах tls-auth ta.key. Если на сервере стоит tls-auth ta.key 1, то на клиенте должно быть tls-auth ta.key 0.
  4. Неправильно указаны параметры в auth.

Всё, что тут можно посоветовать - это использовать verb 5 и более и через tail -f смотреть логи.

Если всё прошло хорошо, то OpenVPN расскажет в консоль как ему живётся:

# openvpn --config client.conf
......
Wed Mar 22 13:23:23 2017 GID set to nogroup
Wed Mar 22 13:23:23 2017 UID set to nobody
Wed Mar 22 13:23:23 2017 Initialization Sequence Completed

Попутно стоит проверить появился ли tunXX:

# ifconfig -a | grep tun
tun0: flags=4240<POINTOPOINT,NOARP,MULTICAST>  mtu 1500
tun99: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
ВНИМАНИЕ

Если ничего похоже на tunXX ifconfig не выдаёт значит интерфейс не сконфигурирован, нужно проверить:

  • указан ли в client.conf dev tunXX;
  • указан ли в client.conf pull;
  • посмотреть создаётся ли вообще хотя бы какой-то интерфейс: ifconfig -a | grep tun

Если pull пропущен намеренно, то придётся прописывать в client.conf свои ip route rules, ifconfig и т.д. Пару примеров можно найти на debian wiki.

6. Настройка маршрутов на сервере

В /etc/sysctl.conf включим форвардинг:

net.ipv4.ip_forward=1

Запишем выходные маршруты в iptables для серверного tun0 OpenVPN:

iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source <SOURCE>

Запустим клиент еще раз и проверим traceroute:

# openvpn --config client.conf
# traceroute google.com
traceroute to google.com (74.125.232.231), 30 hops max, 60 byte packets
 1  10.8.0.1 (10.8.0.1)  148.285 ms  148.295 ms  148.400 ms
 2  ...

Если пакеты гуляют через 10.8.0.1, значит все нормально и конфиг iptables можно сохранять.

Это..

Для сохранения iptables можно использовать iptables-persistent.

# iptables-save > /etc/iptables.up.rules
# echo -e '#!/bin/sh\n/sbin/iptables-restore < /etc/iptables.up.rules\n' > /etc/network/if-pre-up.d/iptables
# chmod +x /etc/network/if-pre-up.d/iptables

После чего для чистоты эксперимента отправляем сервер в ребут:

# shutdown -r now

7. NetworkManager

Всё настраивается аналогично OpenVPN:

# cat /etc/NetworkManager/system-connections/vpn_connection 
[connection]
id=trash
uuid=1c6cce35-3849-4d2f-ad9e-b98b2f1d7a09
type=vpn
permissions=

[vpn]
auth=SHA512
ca=/home/user/openvpn/ca.crt
cert=/home/user/openvpn/home1.crt
cert-pass-flags=1
cipher=AES-256-CBC
comp-lzo=adaptive
connection-type=tls
dev-type=tun
key=/home/user/openvpn/home1.key
mssfix=no
port=1771
proto-tcp=no
remote=replace.me
remote-cert-tls=server
remote-random=no
ta=/home/user/openvpn/ta.key
ta-dir=0
service-type=org.freedesktop.NetworkManager.openvpn

[ipv4]
dns-search=
method=auto

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto


Экраны настройки Network Manager

Вот только проблема в том, что на следующий день я стал получать Could not find source connection. К счастью, меня устраивает консолькой подключать VPN, когда это нужно.

UPDATE 2017-05-29

Когда NetworkManager жалуется на "Сould not find source connection", нужно в /etc/NetworkManager/NetworkManager.conf изменить в секции [ifupdown] атрибут managed=false на managed=true.

8. Разное

8.1. Хинт 1

Стоит проверить не протекает ли наш DNS, например, на dnsleaktest.

8.2. Хинт 2

Всего вышеперечисленного поможет избежать sshuttle:

sshuttle -r root@example.com 0.0.0.0/0
night-crawler
Просмотров: 289
blog comments powered by Disqus