Домашний сервер (шлюз в интернете)

Я уже писал про домашний сервер не один раз и эта статья должна стать завершающей в данном цикле. В этот раз мне требуется организовать доступ к своему «домашнему железу«, чтобы можно было работать из любой точки города, региона или страны. Есть 2 варианта организации такого доступа: купить внешний IP-адрес у провайдера на постоянку (белый IP) или арендовать внешний VPS, который будет являться шлюзом в интернете. Лично я для себя решил выбрать VPS. Ну что же… Release it!

Домашний сервер (шлюз в интернете)

Выбор VPS

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

Чтобы подобрать для себя VPS нужно определиться с техническими характеристиками. В моем случае у меня будет установлено всего 3 основных приложения: openvpn, nginx и certbot. Для чего они нужны я буду говорить далее. На весь этот ворох приложений на текущий момент у меня уходит 260МБ ОЗУ, загрузка CPU (на одно ядро) не более 30% и HDD занято 5.5ГБ. Так что выбираем под себя (или даже один из самых дешевых на сколько это возможно). На счет скорости сети смотрим и оцениваем сами. Может вы будете гонять терабайты данных на высоких скоростях, а может и 100 мегабайт превышать не будет. Так что прикидываем и определяемся.

Что на счет операционной системы, то выбираем то, что умеем настраивать лучше всего. Просто потому что так проще. Лично я для себя выбрал CentOS из тех дистрибутивов, что были доступны.

Настройка хостера

Для начала нужно немного подготовить настройки хостинга. Первым делом идем в настройки самого хостера и настраиваем сеть. Первое это нужно убедиться, что нам дали внешний IP, по которому мы будем подключаться. После заходим в настройки безопасности сети и проверяем какие порты открыты. Понадобятся следующие порты:

  • 80 (http)
  • 443 (https)
  • 22 (ssh)
  • 1194 (openvpn)

Все остальные можно закрыть (они не понадобятся). Как это сделать я не буду рассказывать, так как у каждого хостера свой интерфейс с настройками. По факту ничего сложного нету. Что касается портов, то 22-й множно перенести на другой, например 2222 с перенаправлением порта на 22 самой виртуальной машины (VM), а 1194 можно просто использовать другой, например, 11194й, ну или какой-то еще по желанию. 80й и 443й должны остаться такими, чтобы web-браузеры могли спокойной работать.

Если же хостинг не предоставляет таких настроек и Вам открыты все порты, то хорошим тоном будет настройка межсетевого экрана на самой VPS, иначе получится проходной двор. В общем «не секурно» как-то…

Подготовка ОС

Чтобы не мешал SELinux — выключим его. Для этого в консоли переходим в root и выполняем:


setenforce 0

И в файле /etc/sysconfig/selinux устанавливаем параметр SELINUX=disabled. Кстати, в CentOS по умолчанию редактор vim, но те кто хочет nano ставим так:


dnf install nano

Теперь подключаем epel (а вдруг пригодится):


yum install epel-release

Далее устанавливаем nginx по мануалу. Я не буду описывать, потому что все предельно просто.

Теперь устанавливаем некоторые пакеты:


dnf install openvpn certbot openvpn easy-rsa

Здесь мы устанавливаем CertBot для Let’s Encrypt, OpenVPN для соединения с нашим домашним сервером и easy-rsa для генерирования сертификатов и настройки тоннеля.

OpenVPN

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

Первым делом действуем по инструкции и генерируем сертификаты. Здесь все выполняется пошагово. Различия начинаются (как у меня сделано) в конфигурационных файлах самого OpenVPN.

На сервере файлы распологаются по пути /etc/openvpn/server и в моем случае конфигурационный файл называется gateway.conf:


port 1194
proto tcp
dev tun

server 10.26.0.0 255.255.255.0

keepalive 10 120

dh dh.pem
ca ca.crt
cert gateway.crt
key gateway.key
tls-auth ta.key 0

verb 3

status /var/log/openvpn/openvpn-status.log 1
status-version 3
log-append /var/log/openvpn/openvpn-client.log

client-config-dir /etc/openvpn/clients

comp-lzo

Вот тут появляются моменты, с которыми я столкнулся.

server 10.26.0.0 255.255.255.0

Здесь я устанавливаю водсеть самого vpn. У меня это будет 10.26.0.0/24. Соответственно выставляйте свою, которая Вам нравится. Просто это класс корпоративной сети. За подробностями стоит обратиться к соответствующей технической литературе.

keepalive 10 120

Вот этот параметр говорит, что каждые 10 секунд и, если в течении 120 секунд не будет ответа, то попытаться перезапустить туннель. Без этого у меня туннель зависал и отваливался. Обидно даже.

comp-lzo

Тут все просто! Включаем сжатие трафика в туннеле алгоритмом lzo. Бинарные сжатые данные конечно же не сожмутся (может даже чуть увеличится объем), а вот на текстовых данные это будет видно. Порой спорный параметр, нужно смотреть, но в общем и целом, думаю, использовать можно.

client-config-dir /etc/openvpn/clients

В этой директории будут лежать некоторые настройки для клиентов. Здесь все просто. У меня лежит один файл apps с таким содержимым:


ifconfig-push 10.26.0.253 10.26.0.1

Тут говорится, что подключенномe клиенту apps (так называется сертификат клиента и так его показывает openvpn) присвоить адрес 10.26.0.253 и сказать ему, что шлюз будет 10.26.0.1.

Перезапускаем сервер:


systemctl start openvpn-server@gateway && systemctl enable openvpn-server@gateway

Туннель на шлюзе

OpenVPN-клиент

Теперь на домашнем сервере необходимо установить как раз соединение со шлюзом. Устанавливаем (напоминаю, у меня armbian):


apt install openvpn

Сразу идем в /etc/openvpn и наполняем файл client.conf настройками:


dev tun
proto tcp
remote <внешний IP-адрес сервера> 1194
client
resolv-retry infinite
ca /etc/openvpn/client/ca.crt
cert /etc/openvpn/client/apps.crt
key /etc/openvpn/client/apps.key

persist-key
persist-tun
comp-lzo
verb 3
status /var/log/openvpn/openvpn-status.log 1
status-version 3
log-append /var/log/openvpn/openvpn-client.log

tls-auth client/ta.key 1

keepalive 10 120

Файл клиента очень похож на файл сервера, просто в нем отличается пара строк. Так же не забываем скопировать с сервера сертификаты для клиента.

Теперь запускаем:


systemctl start openvpn@client && systemctl enable op[envpn@client

Обязательно проверяем, что туннель поднялся как на сервере, так и на клиенте с помощью команды ip a. В выводе должен появиться сетевой интерфейс tun и отобразиться IP-адреса, которые мы установили.

Туннель на внутреннем сервере

DNS

cloudПеред настройкой web-сервера хочется чтобы это было «красиво«. Так что бежим за покупкой доменного имени второго уровня! Проверяем желаемый и, если он свободен, покупаем и радуемся! Сказать тут больше нечего…

После покупки прописываем внешний IP-адрес нашего шлюза и ждем… Ждем… Ждем… Можем и сутки ждать, пока все заработает. Это нормально, так как DNS-запись должна распространиться по всем DNS-серверам.

Если нужен домен 3-го уровня на Вашем же домене 2-го уровня, то добавляем его там же и вешаем на этот же IP-адрес. В этом ничего страшного нет, так как web-сервер сам разрулит какой запрос к какому серверу перенаправить.

Nginx и CertBot

Вот тут, по сути, нужно их настраивать в паре. Чтобы настроить получение сертификатов я использовал вот эту статью. Работает и на CentOS (а чего бы ему не работать?).

Теперь когда все готово прописываем конфигурацию для нашего сайта:


server {
    listen       80;
    server_name  <домен 2го уровня> www.<домен 2го уровня>;

    access_log  /var/log/nginx/site.access.log  main;

    include acme;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen      443 ssl http2;
    server_name <домен 2го уровня> www.<домен 2го уровня>;

    gzip on;

    access_log /var/log/nginx/site.access.log;
    
    ssl_certificate /etc/letsencrypt/live/<директория с сертификатами>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<директория с сертификатами>/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/<директория с сертификатами>/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
    #ssl_ciphers  "RC4:HIGH:!aNULL:!MD5:!kEDH";

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

    ssl_prefer_server_ciphers on;

    ssl_session_cache   shared:SSL:100m;
    ssl_session_timeout 5m;

    add_header Strict-Transport-Security 'max-age=604800';
    add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests";

    resolver 8.8.8.8;

    client_max_body_size 1024m;
    
    set_real_ip_from 10.26.0.1;
    real_ip_header X-Forwarded-For;

    location / {
        proxy_pass http://10.26.0.253:8080;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 120s;
        proxy_read_timeout 180s;
    }

    error_page 404              /404.html;

    error_page  500 502 503 504         /50x.html;

}

Вот тут нужно немного пояснить.

Тот сервер, что слушает 80й порт нужен чтобы ответить на acme для certbot, а остальные запросы перенаправить на 443й порт. Второй сервер, который слушает 443й порт перенаправляет запросы по vpn-каналу на наш домашний сервер. Вот собственно и все.

Теперь проверим правильно ли написана конфигурация (нет ли ошибок):


nginx -t

И, если все хорошо, скажем nginx чтобы применил конфигурацию:


nginx -s reload

Результат

Вот и все. Теперь можно спокойно отключать мобильник от домашнего Wi-Fi и пробовать ломиться по нашему адресу.

Поделиться
Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий

Вы должны быть авторизованы, чтобы разместить комментарий.