Часть 1. Введение. Топология.
Часть 2. OpenVPN Server на Asus RT-N10U.
Часть 3. Тестирование подключения изнутри и извне.
Часть 4. Подключение извне с роутера Netgear DGN2200.
В своём примере я использую статическую привзяку mac-ip, поэтому если хотите повторить всё с точностью как в примере не забудьте заполнить эти связки для компьютера и планшета в меню Static DHCP в вашем Tomato.
Этап 1. Включение JFFS.
Во первых необходимо включить в Tomato поддержку jffs. Раздел jffs будет нужен для хранения файла, в котором будут прописаны статические IP устройств внутри подсети OpenVPN. В нем также будут храниться файлы кастомных конфигураций клиентов(client-config-dir), о которых я расскажу ниже.
Для включения jffs необходимо перейти в меню Administration -> JFFS отметить галочкой Enable и сохранить изменения.
Этап 2. Генерация ключей.
Для защиты соединения и проверки прав доступа OpenVPN сервер требует генерации ряда ключей. Для удобной их генерации я собрал архив из связки easy-rsa и openssl.
Для создания ключей используется ряд параметров, такие как название организации, сведения о местоположении, длина ключа и прочие. Для примера они уже заполнены в файле vars.bat. Загрузим их:
vars
Сгенерируем ключ центра сертификации. Т.к. все необходимые переменные уже были заполнены в vars, остается только жать enter на все вопросы.
build-ca
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key .........++++++ ...............................++++++ writing new private key to 'keys\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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]: Name [ServerKey]: Email Address [admin@home.ru]:
Сгенерируем ключ Диффи — Хеллмана:
build-dh
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating DH parameters, 1024 bit long safe prime, generator 2 This is going to take a long time ...........+.......................................+..................+...+........+.......+...................................................................................+.... .......+...+......+...........................................................................................................+..........................+.......................... ........................................................................................+..+......................+.+.....+......................................................... .............+.......................................................................+....................................................................+...........+..+..+....... ..........+........................+...........................+...................+.....................................+.......................................................... .+.......................................+................................................................................................................................+......... ...............................................................+...........+.....................+............................................................+.............+....... ...........................+....................................................................++*++*++*
Сгенерируем серверные ключи указав в качестве имени ServerKey. Опять жмем enter(challenge password можно оставить пустым). В конце 2 раза жмем «y» и enter чтобы подписать сертификат и занести его в базу данных.
build-key-server Serverkey
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key ...........++++++ ..........................++++++ writing new private key to 'keys\Serverkey.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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]: Name [ServerKey]: Email Address [admin@home.ru]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from openssl-1.0.0.cnf Loading 'screen' into random state - done Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'RU' stateOrProvinceName :PRINTABLE:'MSK' localityName :PRINTABLE:'Moscow' organizationName :PRINTABLE:'Home' organizationalUnitName:PRINTABLE:'MainUnit' commonName :PRINTABLE:'ServerKey' name :PRINTABLE:'ServerKey' emailAddress :IA5STRING:'admin@home.ru' Certificate is to be certified until Dec 21 07:48:38 2025 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
На тему типов ключей доступа уже написано много в интернете. Расписаны их недостатки и приемущества. Для себя я выбрал ключи pkcs12.
В процессе генерации уже не нужно будет жать только enter как раньше — нужно будет заполнить имена Common Name и Name значениями отличными от ServerKey, иначе произойдет ошибка записи данных о ключе с теми же именами. Для себя я выбрал имена PCKey, TabletKey, SmartKey и NetgearKey. Также необходимо будет заполнить пароли к ключам. Обязательно сделайте это и сделайте их разными.
build-key-pkcs12 PCKey
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key .....................................................................++++++ .++++++ writing new private key to 'keys\PCKey.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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]:PCKey Name [ServerKey]:PCKey Email Address [admin@home.ru]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from openssl-1.0.0.cnf Loading 'screen' into random state - done Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'RU' stateOrProvinceName :PRINTABLE:'MSK' localityName :PRINTABLE:'Moscow' organizationName :PRINTABLE:'Home' organizationalUnitName:PRINTABLE:'MainUnit' commonName :PRINTABLE:'PCKey' name :PRINTABLE:'PCKey' emailAddress :IA5STRING:'admin@home.ru' Certificate is to be certified until Dec 21 07:48:55 2025 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 WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Enter Export Password: Verifying - Enter Export Password:
build-key-pkcs12 TabletKey
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key ..............................++++++ ...............................++++++ writing new private key to 'keys\TabletKey.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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]:TabletKey Name [ServerKey]:TabletKey Email Address [admin@home.ru]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from openssl-1.0.0.cnf Loading 'screen' into random state - done Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'RU' stateOrProvinceName :PRINTABLE:'MSK' localityName :PRINTABLE:'Moscow' organizationName :PRINTABLE:'Home' organizationalUnitName:PRINTABLE:'MainUnit' commonName :PRINTABLE:'TabletKey' name :PRINTABLE:'TabletKey' emailAddress :IA5STRING:'admin@home.ru' Certificate is to be certified until Dec 21 07:51:44 2025 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 WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Enter Export Password: Verifying - Enter Export Password:
build-key-pkcs12 SmartKey
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key .......++++++ ..++++++ writing new private key to 'keys\SmartKey.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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]:SmartKey Name [ServerKey]:SmartKey Email Address [admin@home.ru]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from openssl-1.0.0.cnf Loading 'screen' into random state - done Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'RU' stateOrProvinceName :PRINTABLE:'MSK' localityName :PRINTABLE:'Moscow' organizationName :PRINTABLE:'Home' organizationalUnitName:PRINTABLE:'MainUnit' commonName :PRINTABLE:'SmartKey' name :PRINTABLE:'SmartKey' emailAddress :IA5STRING:'admin@home.ru' Certificate is to be certified until Dec 21 07:52:37 2025 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 WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Enter Export Password: Verifying - Enter Export Password:
build-key-pkcs12 NetgearKey
WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key ..............++++++ ..............++++++ writing new private key to 'keys\NetgearKey.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) [RU]: State or Province Name (full name) [MSK]: Locality Name (eg, city) [Moscow]: Organization Name (eg, company) [Home]: Organizational Unit Name (eg, section) [MainUnit]: Common Name (eg, your name or your server's hostname) [ServerKey]:NetgearKey Name [ServerKey]:NetgearKey Email Address [admin@home.ru]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from openssl-1.0.0.cnf Loading 'screen' into random state - done Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'RU' stateOrProvinceName :PRINTABLE:'MSK' localityName :PRINTABLE:'Moscow' organizationName :PRINTABLE:'Home' organizationalUnitName:PRINTABLE:'MainUnit' commonName :PRINTABLE:'NetgearKey' name :PRINTABLE:'NetgearKey' emailAddress :IA5STRING:'admin@home.ru' Certificate is to be certified until Dec 21 07:53:02 2025 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 WARNING: can't open config file: /usr/local/ssl/openssl.cnf Loading 'screen' into random state - done Enter Export Password: Verifying - Enter Export Password:
Этап 3. Настройка сервера.
Редактируем основные настройки в меню VPN Tunneling -> OpenVPN Server -> Basic:
Отметить галочку Start with WAN нужно для того, чтобы сервер стартовал автоматически когда включается роутер поднимается сеть.
Тип интерфейса лучше оставить TUN. В отличие от TAP, не придется рутовать смартфон на Android чтобы подключиться к сети.
Протокол рекомендуется ставить UDP, потому что сеть так быстрее будет работать. Но есть одно но. Если вы захотите поднять OpenVPN Client на персональном компьютере находясь за HTTP-прокси, сделать этого у вас не получится — UDP можно прокинуть только через SOCKS. TCP же можно прокинуть через HTTP, поэтому я выбрал его.
В качестве подсети указываем желаемую.
Остальные настройки оставляем по умолчанию.
Теперь можно настроить серверные ключи на вкладке Keys.
Содержимое файла ca.crt нужно перенести в Certificate Authority, ключ из конца файла Serverkey.crt в Server Certificate, Serverkey.key в Server Key, dh1024.pem в Diffie Hellman parameters.
После этого можно впервые нажать на кнопку Start Now. Если всё было настроено правильно, надпись на кнопке станет Stop Now, то будет означать что сервер запущен успешно. Если сервер запущен неуспешно ошибки можно посмотреть в файле /var/log/messages непосредственно на роутере.
В качестве подготовки к последней настройке сервера необходимо зайти на роутер по ssh и создать на jffs два файла: /jffs/openvpn/ipp.txt и /jffs/openvpn/ccd/NetgearKey. Оба простые текстовые файлы. Второй без расширения, т.к. должен совпадать с именем Common Name зарегистрированного ключа(в данном случае NetgearKey).
Содержимое файлов:
ipp.txt
NetgearKey,192.168.110.2 PCKey,192.168.110.3 TabletKey,192.168.110.4 SmartKey,192.168.110.5
NetgearKey
iroute 192.168.105.0 255.255.255.0
О назначении файлов я напишу ниже.
Последний шаг — настройка дополнительных параметров во вкладке Advanced.
На этой вкладке я предпочел не включать галки Push LAN to clients и Direct clients to redirect Internet traffic, а объявил команды вручную в блоке Custom Configuration.
В качестве шифрования выбрал AES-128-CBC.
Сжатие трафика отключено, т.к. забегая вперед, вызывало проблемы на роутере Netgear.
В блок Custom Configuration добавлены следующие команды:
client-to-client topology subnet auth sha1 keepalive 10 60 ifconfig-pool-persist /jffs/openvpn/ipp.txt client-config-dir /jffs/openvpn/ccd route 192.168.105.0 255.255.255.0 push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 192.168.110.1" push "ping 10" push "ping-restart 60" push "redirect gateway def1" push "route 192.168.100.0 255.255.255.0" push "route 192.168.105.0 255.255.255.0 vpn_gateway 999" mssfix 1400
client-to-client — Открывает доступ между клиентами внутри vpn.
topology subnet — Рекомендуемая сейчас топология это subnet, но т.к. она не является в текущий момент по-умолчанию включаю её принудительно. Подробнее здесь.
auth sha1 — Метод хеширования кода авторизации при иницииации соединения с клиентом.
keepalive 10 60 — Сервер пингует клиента, если за последние 10 секунд от него не приходило никаких пакетов, и пытается пересоздать соединение, если пакетов не было 60 секунд.
ifconfig-pool-persist /jffs/openvpn/ipp.txt — Указывает на файл, в котором содержатся имена Common Name ключей и соответствующие им статические IP.
client-config-dir /jffs/openvpn/ccd — Указывает на директорию, в которой хранятся файлы совпадающие с именами Common Name ключей. Внутри файлов содержатся команды исполнять которые нужно только при подключении определенного клиента. В моём случае есть только один такой клиент — роутер Netgear. При его подключении выполняется команда iroute, которая создает внутренний маршрут указывающий на Netgear(192.168.105.0/24).
route 192.168.105.0 255.255.255.0 — Добавляет маршрут указывающий на подсеть из Netgear в Asus при старте OpenVPN Server.
mssfix 1400 — Помог мне вылечить нестабильную передачу данных. 1400 это значение в байтах, которое ограничивает максимальный размер пакета передаваемого внутри vpn-сети. В офф. доке написано, что параметр имеет смысл только при использовании UDP, но мне помог и с TCP.
Все опции push отправляют команду в ковычках клиенту и выполняются уже на клиентской машине.
push «dhcp-option DNS 8.8.8.8» — Назначаем клиентам гугловский DNS в качестве основного.
push «dhcp-option DNS 192.168.110.1» — В качестве вторичного DNS назначаем сам OpenVPN Server.
push «ping 10» — То же самое что и 10 секунд в команде keepalive. Просто передать keepalive на сторону клиента нельзя. Поэтому передаются ping и ping-restart.
push «ping-restart 60» — То же самое что и 60 секунд в команде keepalive.
push «redirect gateway def1» — Позволяет клиентам редиректить весь трафик на сервер и уже с сервера в интернет. С момента подключения внешний IP клиента совпадает с внешним IP роутера.
push «route 192.168.100.0 255.255.255.0» — Добавляет клиентам маршрут указывающий на подсеть Asus 192.168.100.0/24.
push «route 192.168.105.0 255.255.255.0 vpn_gateway 999» — Добавляет клиентам маршрут указывающий на подсеть Netgear 192.168.105.0/24. Большая метрика выставлена скорее всего из-за проблем с Netgear, когда маршрут указывающий на подсеть 192.168.105.0/24 со шлюзом 192.168.110.1(OpenVPN Server) имел меньшую метрику, чем тот же маршрут со шлюзом 192.168.105.1(Netgear). Точную причину не помню)
После занесения конфигурации можно нажать на кнопку Save, после чего OpenVPN сервер автоматически перезагрузится.
Поздравляю! OpenVPN сервер настроен. Теперь нужно протестить подключение к нему.