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


OpenVPN одна из самых популярных программ для организации VPN туннеля, а docker-compose отличный инструмент для установки и настройки программ с помощью одного docker-compose.yml файла.


В статье я расскажу как быстро и просто настроить OpenVPN сервер на собственном VPS используя docker-compose. За основу возьмем образ kylemanna/docker-openvpn.


Заинтересовавшихся прошу под кат.


Установка OpenVPN сервера


Итак, для работы нам понадобятся: собственный VPS сервер, установленный docker и docker-compose.


Создаем новый docker-compose.yml


touch docker-compose.yml

Копируем следующие строчки в созданный docker-compose.yml


version: '2'  
services:  
  openvpn:
    cap_add:
     - NET_ADMIN
    image: kylemanna/openvpn
    container_name: openvpn
    ports:
     - "1194:1194/udp"
    restart: always
    volumes:
     - {path_to_save_openvpn_config}:/etc/openvpn

Меняем {path_to_save_openvpn_config} на путь где OpenVPN будет хранить свои настройки, у меня это /home/administrator/openvpn/.


Docker-compose файл готов. Запустим следующие команды для инициализации OpenVPN и создания сертификата сервера. Замените {vpn_server_address} на адрес вашего сервера,
это может быть как IP адрес (10.10.10.8), так и доменное имя (vpn.server.com).


docker-compose run --rm openvpn ovpn_genconfig -u udp://{vpn_server_address}
docker-compose run --rm openvpn ovpn_initpki

Во время генерации сертификата введите контрольную фразу (Enter PEM pass phrase) и имя сертификата (Common Name).


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


Генерирование серверного сертификата


Генерирование сертификата обычно занимает некоторое время, так что откиньтесь на спинку стула и расслабьтесь.


Когда сертификат готов, можно запускать наш OpenVPN сервер.


docker-compose up -d openvpn

Создание клиентских сертификатов


Чтобы соединиться с вашим OpenVPN сервером понадобится клиентский сертификат.


Для создания клиентского сертификата используем следующую команду:


docker-compose run --rm openvpn easyrsa build-client-full {client_name} nopass  

Не забываем заменить {client_name} на имя клиента, например my_phone.


Во время создания сертификата вас попросят ввести контрольную фразу (Enter passpharse) из предыдущего шага.


Если вы хотите максимальной безопасности, рекомендую убрать опцию nopass из предыдущей команды, чтобы назначить клиентскому сертификату контрольную фразу.


Когда клиентский сертификат сгенерирован давайте экспортируем его в .ovpn файл и отправим клиенту


docker-compose run --rm openvpn ovpn_getclient {client_name} > certificate.ovpn  


На этом все, надеюсь кому-то это статья поможет вновь ощутить свободу в интернете.


Дополнительную информацию вы можете найти на официальном сайте образа kylemanna/docker-openvpn.

Комментарии (35)


  1. smer44
    28.04.2018 19:44

    VPN траффик можно выделить среди прочего (отличить от не- VPN)?
    с чего тогда чуствовать себя комфортнее?


    1. jehy
      28.04.2018 19:49
      +1

      Теоретически да. По факту — пока на это нет ни мощностей, ни указа сверху. А даже если они будут — есть всякие неплохие способы обхода этого.


    1. Mako_357
      28.04.2018 21:55

      Если провести обфускацию пакетов, то нет. Но это реально надо заморачиваться и вряд ли стоит того. У нас пока не Китай и не скоро ещё будет, если будет вообще.


    1. Nikobraz
      29.04.2018 04:45

      В Китае, кстати, OpenVPN не работает, с L2TP проблем нет чаще всего.


  1. shadowalone
    28.04.2018 20:21

    Намного проще — andrey.org/openvpn-pritunl-docker


    1. vconst
      28.04.2018 21:00
      +1

      Можно ещё проще, без докера, одной командой
      github.com/Nyr/openvpn-install


      1. codemafia
        28.04.2018 21:26

        Этот скрипт немного устарел.


        1. vconst
          28.04.2018 21:27

          Чём именно?


          1. codemafia
            28.04.2018 23:48

            Не влавался в детали. Что то про устаревшие дерективы. Но все равно работает.


            1. vconst
              29.04.2018 09:31
              +1

              Так скрипт устарел или нет? Как это можно понять «не вдаваясь в детали»? Скрипт простой и понятный, на гитхабе у него 6к+ звёзд и полторы тысячи форков, обновление было три дня назад. Что конкретно в нем не так?


              1. Suvitruf
                29.04.2018 19:48

                Я уже много лет его использую на наших VPS.


                1. vconst
                  29.04.2018 21:12

                  Не хватает одной фичи — одноразового веб-сервера, для скачивания файла для клиента через https. Я на скалевей такой посмотрел, очень удобная штука.


      1. vmspike
        29.04.2018 11:05

        Вот тоже просто, тоже без докера, одной командой: https://github.com/vmspike/openvpn-manage


      1. nikitasius
        29.04.2018 18:29

        Спасибо за скрипт!


        1. vconst
          29.04.2018 21:13

          Когда не нужен докер, он очень удобен, да.


          1. nikitasius
            29.04.2018 23:10

            Я сам докером до недавнего времени не пользовался, но вот как средство для изоляции разного рода софта или шеллов он очень хорош + порог вхождения низкий, не надо тонну документации лопатить.


    1. radist2s
      29.04.2018 10:51
      +1

      Ага, запуск докера в privileged режиме — не лучшая идея. Сами разработчики говорят, что privileged существует только для особо экстраординарных задач, например как запуск докера внутри докера. Для всего прочего --cap-add, как у автора поста. Настаивать на то, что там внутри контейнера и ломать-то нечего можно сколько угодно, но это не докер вей.


      1. nikitasius
        29.04.2018 18:30

        Ну или подмонтировать image в loop, --cap-add SYS_ADMIN не прошел.


  1. Bonio
    28.04.2018 22:17
    +1

    А зачем тут докер?


    1. kilgur
      28.04.2018 22:41

      Например, чтобы потом все убрать и не осталось "хвостов" в системе. Или чтобы ограничить vpn-сервис в ресурсах. Непонятно зачем docker-compose, разве что не вводить параметры каждый раз, но, ИМХО, проще sh-скрипт сваять


      1. vconst
        29.04.2018 00:54

        Какие хвосты на впс, который и так удаляется без следа в один клик?


        1. kilgur
          29.04.2018 09:07
          +1

          Например, я не практикую принцип "1 vps — 1 сервис". Т.е. на vps крутится обычно много мелких сервисов и openvpn (и ipsec+strongswan) находятся именно в докере, п.ч. это удобно — мне не надо вспоминать, что и как настраивается, мне надо просто на новую vps клонировать репу с Dockerfile, положить ключи и запустить скрипт, создающий контейнер. На вкус и цвет фломастеры разные — кому как удобнее. Лично мне глаз режет использование docker-compose для одного контейнера, но опять-таки — кому как удобнее.


      1. danemon
        29.04.2018 01:19

        это если у вас vps. А в вашем конкретном гипотетическом сценарии в проде понадобится создать например какой-то шлюз для входа пользователей в корпоративную сеть через интернет, причём обязательно через OpenVPN и на Docker. Вот тогда вам возможно и станет актуальным вопрос о хвостах. Не цепляйтесь к шаблонам.


        1. vconst
          29.04.2018 08:13

          Автор изначально говорит про впс, для обхода блокировок. И то, что я показал способ проще — ему явно не понравилось))


      1. soshnikov
        29.04.2018 02:08

        docker-compose затем, что делает жизнь легче.


        1. kilgur
          29.04.2018 09:12

          Если нет надобности запустить несколько контейнеров, то в чем конкретно легче? Сохранение параметров запуска в bash-скрипте прозрачнее, плюс отсутствует дополнительная сущность в виде docker-compose. А вот для запуска нескольких связанных контейнеров поддержу — docker-compose удобнее скриптов


          1. VolCh
            29.04.2018 21:43

            Например для автоматической миграции контейнера по нодам. Правда это не docker-compose а чистый docker, но файл docker-compose плюс-минус тот же.


    1. bykvaadm
      30.04.2018 14:47

      Чтобы переиспользовать много раз одну и ту же систему не настраивая ее. В данной статье, если вы обратили внимание, не идет речь о том, как настроить впн, а рассказывается как пользоваться поделкой автора. И когда автор обновит контейнер, вы не пойдете перенастраивать ваш впн, а сделаете docker pull.


  1. koot
    29.04.2018 08:36

    Все ставиться и настраиваться этим скриптом https://github.com/StreisandEffect/streisand/blob/master/README-ru.md


    1. Fedcomp
      29.04.2018 09:11

      Который блокирует все лишние порты а также врубает unattended upgrades. Докер проще.


  1. Busla
    29.04.2018 09:54

    Это извращение идей сертификатов и контейнеров.
    Приватные сертификаты CA и клиентские не должны генерироваться и храниться на сервере. И было бы логичнее собрать образ со своими сертификатами и настройками, а не пробрасывать вовне каталог, который никто сколько-нибудь регулярно менять не обирается.


  1. ArsenAbakarov
    29.04.2018 10:33

    github.com/nanervax/ovpn
    Когда-то делал, сейчас просто актуально стало=)


  1. radist2s
    29.04.2018 10:46
    +3

    Я хоть и только начинаю знакомство с докером, но уже знаю, что имедж собраный как
    FROM alpine:latest не то чтобы очень предусмотрительно. Сам напарывался на эти вилы, когда образ использует по умолчанию тег latest, а в последней версии того же alpine нужных зависимостей уже нет. Все таки лучше указывать конкретный тег.


    Так же хотел отметить, что если используется SELinux(например, в Centos по дефлоту), то если не указать опции монтирования z или Z, то на запись из контейнера в директорию на хосте ничего работать не будет.


    volumes:
         - {path_to_save_openvpn_config}:/etc/openvpn:Z #если несколько контейнеров будут обращаться по одному маунту, то опция должна быть "z"

    И комментарий для всех, кто говорит можно проще. Да, можно проще, но с докером мы получаем нормальную переносимость окружения на любой дистрибутив любой версии(в рамках поддержки докера, конечно) без хитрых манипуляций. Можно ставить самую последнюю версию нужного ПО без страха поломать зависимости на работающем сервере, например. Или парой команд экспортировать хоть контейнер, хоть имедж, хоть вольюм в архив, и на новом сервере так же все это импортировать обратно.


  1. Barafu
    29.04.2018 23:25

    Меня всегда пугал --restart:always в докере на личном сервере, куда заглядываешь нечасто. Предположим, приложение засрало себе конфиг и падает при запуске. Получается, Docker будет его перезапускать до посинения, поедая 100% процессора, пока не заметишь?
    Ну вот почему нельзя ему указать предел количества перезапусков, как это можно сделать в других правилах, ну что за бред…


    1. kilgur
      30.04.2018 11:12

      man docker-run: там есть не только always, есть ещё on-failure[:max-retry]