OpenVPN Access Server предоставляет полностью настроенный и готовый к использованию OpenVPN сервер, который требует минимальной настройки для запуска.
Бесплатная версия разрешает использовать 2 одновременных подключения, если требуется больше пользователей – за денежку.
Сейчас для доступа к нашим ресурсам, таким как Jenkins, Nexus и т.д. используются правила в Security Group-ах, в которых для каждого пользователя приходится добавлять домашний IP.
Такой подход был более-менее адекватным решением, пока команда была небольшая, но с ростом количества девелоперов/QA правил становится всё больше, управлять ими становится всё геморройнее, а потому – пришло время поднять VPN, которым могли бы пользоваться все.
Схема, которую будем строить в этом посте будет выглядет примерно так:
Ниже описывается установка и запуск OpenVPN Access Server (по документации тут>>>), создание VPC-peering-ов и маршрутов.
Содержание
AWS: запуск OpenVPN AS
Запуск EC2
Находим AMI:
Лицензии можно добавить позже, сейчас используем Free-версию.
Выбираем t2.micro
– пока этого достаточно:
VPC
Создаём новую VPC для VPN:
Т.к. будет создаваться VPC-пиринг – убедитесь, что блоки адресов не перекрываются.
В данном случае Jenkins VPC будет 10.0.4.0/24, а сеть для VPC VPN-а – 10.0.9.0/24:
Создаём подсеть в этой VPC:
Настраиваем сеть нового EC2:
Internet Gateway
Добавляем Internet Gateway (IGW):
Подключаем его к созданной ранее VPC:
Route table
Далее – обновляем таблицу маршрутизации (RTB), и добавляем маршрут для трафика в сеть 0.0.0.0/0 (интернет) через созданный IGW.
Переходим к подсети, открываем вкладку Route Table, кликаем на имя таблицы маршрутизации:
Добавляем новый маршрут:
Security Group
AWS предложит уже готовую группу безопасности.
Т.к. это такой себе Proof of Concept – оставим тут всё по умолчанию:
- TCP 22 — SSH
- TCP 943 — порт для доступа к админ-панели OpenVPN AS сервиса
- TCP 443 — порт для доступа к пользовательскому интерфейсу OpenVPN AS сервиса
- UDP 1194 — OpenVPN UDP порт, к которому будут подключаться VPN-клиенты
В нормальном варианте – доступ к админ части и SSH следует ограничить доверенными IP.
Запускаем машину, создаём ключ доступа:
Elastic IP
Добавим EIP для доступа к хосту:
Подключаем его к инстансу:
Отключение Source/Destination check
Для корректной работы NAT-а – отключаем проверку адресов (см. посты AWS: миграция RTFM 2.5 — настройка NAT на Bastion EC2 как замена NAT Gateway и AWS: миграция RTFM 2.7 — CloudFormation и Ansible — наcтройка NAT):
На этом с EC2 закончили – переходим к настройке самого OpenVPN AS.
Настройка OpenVPN AS
Подключаемся к хосту, используя логин openvpnas:
[simterm]
$ ssh -i dev-vpn-eu-west-1.pem [email protected]
[/simterm]
Читаем 🙂 лицензионное соглашение, принимаем его:
Инициализация и первичная настройка
При первом логине – OpenVPN AS сам запустит мастер настройки.
При необходимости – его можно вызвать потом с помощью ovpn-init
:
[simterm]
$ sudo ovpn-init --ec2
[/simterm]
По сути – сейчас везде можно принимать значения по умолчанию:
- Will this be the primary Access Server node? // yes
- Please specify the network interface and IP address to be
used by the Admin Web UI:
(1) all interfaces: 0.0.0.0
(2) eth0: 10.0.9.8
// 2 - Please specify the port number for the Admin Web UI.
// yes – 943 - Please specify the TCP port number for the OpenVPN Daemon
// yes – 443 - Should client traffic be routed by default through the VPN?
// no – нет – мы будем роутить толкьо трафик к нашим собственным ресурсам, на ВК пользоватли пусть ходят через свой VPN 🙂 - Should client DNS traffic be routed by default through the VPN?
// no - Use local authentication via internal DB?
// yes - Private subnets detected: [‘10.0.9.0/24’]
Should private subnets be accessible to clients by default?
// yes - Do you wish to login to the Admin UI as “openvpn”?
// yes - > Please specify your OpenVPN-AS license key (or leave blank to specify later):
// оставляем пустым, при необходимости добавим ключ потом
Задаём пароль пользоватея openvpn
:
[simterm]
openvpnas@openvpnas2:~$ sudo passwd openvpn Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
[/simterm]
Теперь можно открыть панель управления – https://52.18.110.226:943/admin.
Т.к. мы не настраивали имена хоста и прочее – соглашаемся:
Your connection is not private
Attackers might be trying to steal your information from 52.18.110.226 (for example, passwords, messages, or credit cards). Learn more
NET::ERR_CERT_AUTHORITY_INVALID
Логинимся в панель управления, используя логин openvpn и пароль, который задали чуть ранее через passwd
:
Подключение VPN-клиента
Открываем страницу доступа пользователя (без /admin
в конце) – https://52.18.110.226:943/?src=connect:
Кликаем на Yourself (user-locked profile) – загружаем файл настроек OpenVPN-клиента client.ovpn
:
Его содержимое:
[simterm]
$ cat ~/.openvpn/client.ovpn # Automatically generated OpenVPN client config file # Generated on Wed Feb 20 15:19:38 2019 by openvpnas2 # Default Cipher cipher AES-256-CBC # Note: this config file contains inline private keys # and therefore should be kept confidential! # Note: this configuration is user-locked to the username below # OVPN_ACCESS_SERVER_USERNAME=openvpn ....
[/simterm]
Устанавливаем openvpn
на локальной машине, тут установка на Arch Linux:
[simterm]
$ sudo pacman -S openvpn
[/simterm]
Запускаем его сопцией --auth-user-pass
:
[simterm]
$ sudo openvpn --config ~/.openvpn/client.ovpn --auth-user-pass Wed Feb 20 17:22:42 2019 OpenVPN 2.4.6 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Apr 24 2018 Wed Feb 20 17:22:42 2019 library versions: OpenSSL 1.1.1a 20 Nov 2018, LZO 2.10 Enter Auth Username: openvpn Enter Auth Password: ******* ... Wed Feb 20 17:22:51 2019 ROUTE_GATEWAY 172.16.64.1/255.255.252.0 IFACE=wlp2s0 HWADDR=10:f0:05:64:0a:73 Wed Feb 20 17:22:51 2019 TUN/TAP device tun0 opened Wed Feb 20 17:22:51 2019 TUN/TAP TX queue length set to 100 Wed Feb 20 17:22:51 2019 do_ifconfig, tt->did_ifconfig_ipv6_setup=0 Wed Feb 20 17:22:51 2019 /usr/bin/ip link set dev tun0 up mtu 1500 Wed Feb 20 17:22:51 2019 /usr/bin/ip addr add dev tun0 172.27.232.3/21 broadcast 172.27.239.255 Wed Feb 20 17:22:56 2019 ROUTE remote_host is NOT LOCAL Wed Feb 20 17:22:56 2019 /usr/bin/ip route add 52.18.110.226/32 via 172.16.64.1 Wed Feb 20 17:22:56 2019 /usr/bin/ip route add 10.0.9.0/24 metric 101 via 172.27.232.1 Wed Feb 20 17:22:56 2019 /usr/bin/ip route add 172.27.224.0/20 metric 101 via 172.27.232.1 Wed Feb 20 17:22:56 2019 Initialization Sequence Completed
[/simterm]
Проверяем маршрутизацию трафика.
Сначала на CloudFlare – должен пойти через офисный шлюз:
[simterm]
$ traceroute 1.1.1.1 traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets 1 _gateway (172.16.64.1) 3.109 ms 3.213 ms 3.428 ms 2 ru-german.relc.com (194.183.169.25) 4.771 ms 5.148 ms 6.039 ms 3 * * * 4 ex4.thinx.pl (212.91.2.13) 16.468 ms 16.778 ms 17.277 ms 5 cloudflare.thinx.pl (212.91.0.28) 23.842 ms 24.154 ms 24.386 ms 6 one.one.one.one (1.1.1.1) 17.787 ms 15.023 ms 15.199 ms
[/simterm]
И к хосту VPN – должен идти напрямую:
[simterm]
$ traceroute 10.0.9.8 traceroute to 10.0.9.8 (10.0.9.8), 30 hops max, 60 byte packets 1 10.0.9.8 (10.0.9.8) 52.095 ms 52.149 ms 53.512 ms
[/simterm]
Отлично.
Маршрутизация трафика через VPN-туннель
Для теста – добавим ещё один EC2-инстанс в той же сети, где находится наш VPN:
Проверим маршруты к нему.
В логах запуска локального VPN-клиента мы видим создание нового маршрута в нашей системе:
Wed Feb 20 17:22:56 2019 /usr/bin/ip route add 172.27.224.0/20 metric 101 via 172.27.232.1
Проверяем – пробуем SSH, используя приватный IP нового инстанса:
[simterm]
$ ssh -i dev-vpn-eu-west-1.pem [email protected] The authenticity of host '10.0.9.6 (10.0.9.6)' can't be established. ECDSA key fingerprint is SHA256:6ldjTtHvQJviBb/9aXwFvwh7nwKjOdpePCxO6TddAJA. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.0.9.6' (ECDSA) to the list of known hosts. Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-1021-aws x86_64) ... ubuntu@ip-10-0-9-6:~$
[/simterm]
Всё работает.
VPC peering
Следующим шагом – требуется настроить VPC-пиринг и маршрутизацию трафика между рабочей машиной, VPN-сервером и VPC, в которой находится наш Jenkins.
VPC-пиринг описан тут>>>,
Создаём новый VPC peering connection:
Принимаем запрос на пиринг:
VPC-peering маршрутизация
Если попробовать подключиться к Jenkins сейчас, используя его приватный IP – ничего не получится:
[simterm]
ubuntu@ip-10-0-9-6:~$ ssh [email protected] ssh: connect to host 10.0.4.13 port 22: Connection timed out
[/simterm]
Так как не созданы маршруты между сетями 10.0.9.0/24 (OpenVPN VPC) и 10.0.4.0/24 (Jenkins VPC).
Требуется обновить таблицы маршрутизации для двух сетей:
- таблица маршрутизации подсети Jenkins – 10.0.4.0/28 => 10.0.9.0/24 через созданный VPN пиринг
- таблица маршрутизации подсети OpenVPN – 10.0.4.0/28 => 10.0.9.0/24 через созданный VPN пиринг
Редактируем таблицу jenkins rtb-9597e6ec | jenkins-dev-route-table:
Добавляем маршрут:
Повторяем для VPN RTB:
Проверяем из сети VPN:
[simterm]
ubuntu@ip-10-0-9-6:~$ ping 10.0.4.13 PING 10.0.4.13 (10.0.4.13) 56(84) bytes of data. 64 bytes from 10.0.4.13: icmp_seq=1 ttl=64 time=0.470 ms 64 bytes from 10.0.4.13: icmp_seq=2 ttl=64 time=0.483 ms
[/simterm]
И обратно – с Jenkins:
[simterm]
admin@jenkins-dev:~$ ping 10.0.9.6 PING 10.0.9.6 (10.0.9.6) 56(84) bytes of data. 64 bytes from 10.0.9.6: icmp_seq=1 ttl=64 time=0.437 ms 64 bytes from 10.0.9.6: icmp_seq=2 ttl=64 time=0.914 ms
[/simterm]
Помним, что у Jenkins есть своя группа безопасности – обновляем в ней правила, и разрешаем доступ из VPN-сети.
Пробуем SSH с хоста в сети VPN:
[simterm]
ubuntu@ip-10-0-9-6:~$ ssh [email protected] The authenticity of host '10.0.4.13 (10.0.4.13)' can't be established. ECDSA key fingerprint is SHA256:+0LP1+neT4udq96jFLdLpjuvTrWCzlAt5GZZpfw2rKI. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.0.4.13' (ECDSA) to the list of known hosts. [email protected]: Permission denied (publickey).
[/simterm]
И обратно:
[simterm]
admin@jenkins-dev:~$ ssh 10.0.9.6 The authenticity of host '10.0.9.6 (10.0.9.6)' can't be established. ECDSA key fingerprint is SHA256:6ldjTtHvQJviBb/9aXwFvwh7nwKjOdpePCxO6TddAJA. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.0.9.6' (ECDSA) to the list of known hosts. Permission denied (publickey).
[/simterm]
Всё работает.
VPN маршруты
Возвращаемся к нашей рабочей машинке, проверяем – как пойдёт трафик к хосту Jenkins, используя приватный IP:
[simterm]
$ traceroute 10.0.4.13 traceroute to 10.0.4.13 (10.0.4.13), 30 hops max, 60 byte packets 1 _gateway (172.16.64.1) 3.243 ms 3.453 ms 3.656 ms 2 ru-german.relc.com (194.183.169.25) 3.962 ms 4.221 ms 4.642 ms ...
[/simterm]
Идёт через шлюз офиса, что нам не подходит.
Переходим в VPN admin => VPN Settings – https://52.18.110.226:943/admin/vpn_settings:
Добавляем NAT-правило для 10.0.4.0/24:
Сохраняем, жмём Update Running Server:
Перезапускаем локальный клиент:
[simterm]
$ sudo openvpn --config ~/.openvpn/client.ovpn --auth-user-pass ... Wed Feb 20 18:25:37 2019 ROUTE remote_host is NOT LOCAL Wed Feb 20 18:25:37 2019 /usr/bin/ip route add 52.18.110.226/32 via 172.16.64.1 Wed Feb 20 18:25:37 2019 /usr/bin/ip route add 10.0.4.0/24 metric 101 via 172.27.232.1 Wed Feb 20 18:25:37 2019 /usr/bin/ip route add 10.0.9.0/24 metric 101 via 172.27.232.1 Wed Feb 20 18:25:37 2019 /usr/bin/ip route add 172.27.224.0/20 metric 101 via 172.27.232.1 Wed Feb 20 18:25:37 2019 Initialization Sequence Completed
[/simterm]
Вот новый маршрут – 10.0.4.0/24 metric 101 via 172.27.232.1.
Проверяем локальную таблицу маршрутизации:
[simterm]
18:26:28 [setevoy@setevoy-arch-work ~] $ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.16.64.1 0.0.0.0 UG 303 0 0 wlp2s0 10.0.4.0 172.27.232.1 255.255.255.0 UG 101 0 0 tun0 10.0.9.0 172.27.232.1 255.255.255.0 UG 101 0 0 tun0 52.18.110.226 172.16.64.1 255.255.255.255 UGH 0 0 0 wlp2s0
[/simterm]
Проверяем трассу:
[simterm]
$ traceroute 10.0.4.13 traceroute to 10.0.4.13 (10.0.4.13), 30 hops max, 60 byte packets 1 172.27.232.1 (172.27.232.1) 55.090 ms 55.207 ms 55.399 ms ...
[/simterm]
Трафик пошёл через шлюз самого OpenVPN.
Проверяем SSH, используя приватный IP:
[simterm]
18:27:41 [setevoy@setevoy-arch-work ~] $ ssh -i jenkins-dev-eu-west-1.pem [email protected] ... admin@jenkins-dev:~$
[/simterm]
Всё работает.
DNS
Последний момент – это настройки DNS.
Т.к. наш Jenkins доступен и из мира по публичному IP, и через VPN – по приватному, то возникает вопрос с резолвом имени.
См. пост OpenVPN: настройки DNS и dnsmasq.