poloniumv's

OpenVPN на Arch Linux

3 февраля 2017 г. 10:38

Когда надо заиметь доступ в локальную сеть извне, скажем, с сети другого провайдера, например, на помощь приходит OpenVPN. Установка нехитрая и много времени не займет.

Ставим, собственно, сам openvpn и тулкит для генерации сертификатов и ключей безопасности:

sudo pacman -S openvpn easyrsa

Приступаем к генерации ключей и сертификатов. Создаем рабочий каталог и тянем в него необходимые для генерации файлы:

mkdir ~/easyrsa
cp -r /etc/easyrsa/x509-types ~/easyrsa/
cp /etc/easyrsa/openssl-1.0.cnf ~/easyrsa/
cd ~/easyrsa

Создаем инфраструктуру публичных ключей PKI:

easyrsa init-pki

И удостоверяющий центр CA:

easyrsa build-ca

Процесс создания удостоверяющего центра запросит пароль. Пароль желательно придумать сложный и запомнить/записать. Он понадобится когда будем подписывать сертификаты. Также надо будет придумать т. н. Common Name. Туда можно писать что угодно.

Еще нужен ключ Диффи-Хелмана для защиты трафика (самый длительный этап из всего процесса установки, лол):

easyrsa gen-dh

На случай если перестаним дружить с кем-то, кому выдали сертификат, обеспечиваем механизм отзыва (запросит ранее придуманный пароль удостоверяющего центра CA):

easyrsa gen-crl

Отзыв же сертификата выполняется этой командой:

easyrsa revoke username

Далее выполняем запрос на приватный ключ и сертификат для нашего сервера (nopass указываем чтоб не пришлось каждый раз при перезагрузке сервера или рестарте OpenVPN вводить пароль):

easyrsa gen-req openvpn-server nopass

Понадобится придумать Common Name для сервера (можно вписать что угодно).

Подписываем сертификат для сервера (запросит придуманный ранее пароль для CA):

easyrsa sign-req server openvpn-server

Набор непосредственно для сервера почти готов, закидываем все необходимое в /etc/openvpn/keys/:

sudo mkdir -p /etc/openvpn/keys
sudo cp pki/ca.crt /etc/openvpn/keys/
sudo cp pki/crl.pem /etc/openvpn/keys/
sudo cp pki/issued/openvpn-server.crt /etc/openvpn/keys/
sudo cp pki/private/openvpn-server.key /etc/openvpn/keys/
sudo cp pki/dh.pem /etc/openvpn/keys/

И там генерим еще TLS-ключ:

cd /etc/openvpn/keys
sudo openvpn --genkey --secret ta.key

Теперь пишем конфиг для OpenVPN-сервера:

sudo nano /etc/openvpn/server/server.conf
port 1194
proto udp
dev tap0

dh /etc/openvpn/keys/dh.pem
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/openvpn-server.crt
key /etc/openvpn/keys/openvpn-server.key
tls-auth /etc/openvpn/keys/ta.key 0
crl-verify /etc/openvpn/keys/crl.pem

script-security 2
cipher BF-CBC
tls-server
comp-lzo
mute 10
persist-key
persist-tun

max-clients 50
keepalive 10 900

client-config-dir /etc/openvpn/ccd
ifconfig-pool-persist /etc/openvpn/ccd/ipp.txt

server-bridge 10.0.1.1 255.255.255.0 10.0.1.200 10.0.1.250
push "route 10.0.1.0 255.255.255.0"

status /var/log/openvpn/openvpn-status.log 1
status-version 3
log-append /var/log/openvpn/openvpn-server.log
verb 5

Строкой server-bridge 10.0.1.1 255.255.255.0 10.0.1.200 10.0.1.250 подразумевается, что сетевка, через которую бегает локальный трафик во внутренней сетке (к которой, собственно, надо подключиться извне) будет объединена в сетевой мост с интерфейсом tap0, с которым будет построен тоннель. Так же подразумевается что локалка имеет адреса из сети 10.0.1.0/24 и что подключаемые извне клиенты получат адреса из области 10.0.1.200-10.0.1.250 (следует убедится что они не заняты и DHCP-сервер из этой области пользователям ничего не выдаст).

Если надо добавить маршрут на какой-либо ресурс, на который пускает только из той сетки к которой будет построено подключение -- добавляем в конфиг строку типа

push "route 172.16.0.123 255.255.255.255"

, где 172.16.0.123 -- адрес того ресура, доступ к которому необходимо предоставить.

Не забываем создать каталог для логов OpenVPN-сервера:

sudo mkdir /var/log/openvpn/

Создаем юнит для systemd:

sudo nano /etc/systemd/system/openvpn.service
[Unit]
Description=OpenVPN server
After=network.target

[Service]
User=root
Group=root
WorkingDirectory=/etc/openvpn
ExecStart=/usr/bin/openvpn /etc/openvpn/server/server.conf

[Install]
WantedBy=multi-user.target

И не забываем за netctl-юниты для tap-интерфейса:

sudo nano /etc/netctl/openvpn-tap
Description="tap0 interface"
Interface=tap0
Connection=tuntap
Mode='tap'
User='nobody'
Group='nobody'

и моста:

sudo nano /etc/netctl/openvpn-bridge
Description="OpenVPN bridge"
Interface=br0
Connection=bridge
BindsToInterfaces=(enp5s0 tap0)
IP=static
Address=('10.0.1.1/24')

, где enp5s0 (у меня) сетевка, через которую работает LAN. И за саму сетевку не забываем:

sudo nano /etc/netctl/enp5s0
Description="LAN interface"
Interface=enp5s0
Connection=ethernet

Активируем и запускаем netctl-юниты:

sudo netctl enable openvpn-tap
sudo netctl enable enp5s0
sudo netctl enable openvpn-bridge
sudo netctl start openvpn-tap
sudo netctl start enp5s0
sudo netctl start openvpn-bridge

Активируем и запускаем systemd-юнит OpenVPN:

sudo systemctl enable openvpn
sudo systemctl start openvpn

Теперь приступаем к генерации клиентских ключей и сертификатов. И конфига для OpenVPN-клиента.

Итак, ключи. Возвращаемся в рабочий каталог, генерим и подписываем:

cd ~/easyrsa
easyrsa gen-req username

Придется придумать пароль для username (клиенту его нужно будет вводить при запуске VPN-соединения с сервером) и Common Name (как всегда, можно вписать что угодно). Если есть желание чтоб клиенту не надо было вводить пароль, то после username можно дописать nopass. Но так неинтересно.

Подписываем (затребует CA пароль):

easyrsa sign-req client username

Теперь создадим, для удобства, какой-нибудь каталог, в котором соберем все что необходимо будет отдать клиенту для подключения:

mkdir username.openvpn
cp pki/issued/username.crt username.openvpn/
cp pki/private/username.key username.openvpn/
cp pki/ca.crt username.openvpn/
sudo chmod +r /etc/openvpn/keys/ta.key
cp /etc/openvpn/keys/ta.key username.openvpn/

И создадим конфиг для OpenVPN-клиента:

nano username.openvpn/username.ovpn
client
dev tap
proto udp
remote 1.2.3.4 1194
tls-client
ca "ca.crt"
tls-auth "ta.key" 1
cert "username.crt"
key "username.key"
remote-cert-tls server
comp-lzo
tun-mtu 1500

, где вместо 1.2.3.4 пишем IP-адрес (или доменное имя) сервера, к которому клиенту надо подключиться извне.

Архивируем все это добро:

tar -cvzf username.openvpn.tar.gz username.openvpn/

И отдаем клиенту любым удобным способом (почта, флешка etc). Не забываем поделиться ссылкой на OpenVPN-клиент.