Размещаем сайт на домашнем роутере

    Мне давно хотелось «потрогать руками» интернет-сервисы, настроив веб-сервер с нуля и выпустив его в Интернет. В этой статье хочу поделиться полученным опытом превращения домашнего роутера из узкофункционального устройства в практически полноценный сервер.

    Началось всё с того, что служивший верой и правдой роутер TP-Link TL-WR1043ND перестал удовлетворять потребности домашней сети, захотелось 5ГГц диапазона и быстрого доступа к файлам на накопителе, подключенном к роутеру. Просмотрев профильные форумы (4pda, ixbt), сайты с отзывами и посмотрев на ассортимент местных магазинов — решил приобрести Keenetic Ultra.

    В пользу именно этого устройства сработали хорошие отзывы владельцев:

    • отсутствие проблем с перегревом (тут пришлось отказаться от продукции Asus);
    • надежность в работе (тут вычеркнул TP-Link);
    • простота в настройке (побоялся не справиться и вычеркнул MikroTik).

    Пришлось примириться с минусами:

    • нет WiFi6, хотелось взять оборудование с запасом на будущее;
    • 4 LAN порта, хотелось больше, но это уже не домашняя категория.

    В итоге получилась вот такая «серверная»:



    • слева оптический терминал Ростелекома;
    • справа наш подопытный роутер;
    • проводом к роутеру подсоединен завалявшийся m.2 SSD на 128 ГБ, помещенный в коробку USB3 с алиэкспресса, сейчас он аккуратно закреплен на стенке;
    • на переднем плане удлинитель с независимым отключением розеток, провод от него идет к недорогому UPS;
    • на заднем плане пучок витой пары — на этапе ремонта квартиры сразу запланировал RJ45 розетки в местах предполагаемого размещения техники, чтобы не зависеть от замусоренности WiFi.

    Итак, у нас есть оборудование, необходимо его настроить:



    • первичная настройка роутера занимает около 2 минут, указываем параметры подключения к провайдеру (у меня оптический терминал переключен в режим бриджа, PPPoE соединение поднимает роутер), название WiFi сети и пароль — в принципе всё, роутер запускается и работает.



    Ставим переадресацию внешних портов на порты самого роутера в разделе «Сетевые правила — Переадресация»:





    Теперь можно перейти к «продвинутой» части, чего я хотел от роутера:

    1. функционал небольшого NAS для домашней сети;
    2. выполнение функций веб-сервера для нескольких частных страничек;
    3. функционал персонального облака для доступа к личным данным из любой точки мира.

    Первое реализуется встроенными средствами, не требуя особых усилий:

    • берем предназначенный для этой роли накопитель (флешку, карту памяти в картридере, жесткий диск или SSD во внешнем боксе и форматируем в Ext4 с помощью MiniTool Partition Wizard Free Edition (у меня нет компьютера с linux под рукой, там можно встроенными средствами). Как я понимаю, при работе система пишет на флешку только логи, поэтому, если их ограничить после настройки системы — можно использовать и карты памяти, если планируете много и часто писать на накопитель — лучше SSD или HDD.



    После этого подключаем накопитель к роутеру и наблюдаем его на экране системного монитора



    Переходим щелчком по «USB-диски и принтеры» в раздел «Приложения» и настраиваем общий ресурс в разделе «Сеть Windows»:



    И у нас имеется сетевой ресурс, который можно использовать с компьютеров под Windows, подключив при необходимости как диск: net use y: \\192.168.1.1\SSD /persistent:yes

    Скорость такого импровизированного NAS вполне достаточна для домашнего применения, по проводу он использует весь гигабит, по WiFi скорость составляет около 400-500 мегабит.



    Настройка хранилища — один из необходимых шагов для настройки сервера, далее нам нужно:
    приобрести домен и статический IP адрес (можно обойтись и без этого, используя Dynamic DNS, но статический IP у меня уже был, поэтому проще оказалось воспользоваться бесплатными сервисами Яндексаделегировав туда домен, мы получаем DNS-хостинг и почту на своем домене);



    настроить DNS сервера и добавить A-записи, указывающие на ваш IP:



    Вступление в силу настроек делегирования домена и DNS занимает несколько часов, поэтому параллельно занимаемся настройкой роутера.

    Для начала необходимо установить репозиторий Entware, из которого мы сможем ставить на роутер необходимые пакеты. Я воспользовался этой инструкцией, только не заливал установочный пакет по FTP, а создал папку прямо на подключенном ранее сетевом диске и скопировал туда файл обычным способом.

    Получив доступ по SSH, меняем пароль командой passwd и ставим командой opkg install [имена пакетов] все нужные пакеты:



    В ходе настройки на роутере оказались установлены следующие пакеты (результат вывода команды opkg list-installed):

    Список пакетов
    bash — 5.0-3
    busybox — 1.31.1-1
    ca-bundle — 20190110-2
    ca-certificates — 20190110-2
    coreutils — 8.31-1
    coreutils-mktemp — 8.31-1
    cron — 4.1-3
    curl — 7.69.0-1
    diffutils — 3.7-2
    dropbear — 2019.78-3
    entware-release — 1.0-2
    findutils — 4.7.0-1
    glib2 — 2.58.3-5
    grep — 3.4-1
    ldconfig — 2.27-9
    libattr — 2.4.48-2
    libblkid — 2.35.1-1
    libc — 2.27-9
    libcurl — 7.69.0-1
    libffi — 3.2.1-4
    libgcc — 8.3.0-9
    libiconv-full — 1.11.1-4
    libintl-full — 0.19.8.1-2
    liblua — 5.1.5-7
    libmbedtls — 2.16.5-1
    libmount — 2.35.1-1
    libncurses — 6.2-1
    libncursesw — 6.2-1
    libndm — 1.1.10-1a
    libopenssl — 1.1.1d-2
    libopenssl-conf — 1.1.1d-2
    libpcap — 1.9.1-2
    libpcre — 8.43-2
    libpcre2 — 10.34-1
    libpthread — 2.27-9
    libreadline — 8.0-1a
    librt — 2.27-9
    libslang2 — 2.3.2-4
    libssh2 — 1.9.0-2
    libssp — 8.3.0-9
    libstdcpp — 8.3.0-9
    libuuid — 2.35.1-1
    libxml2 — 2.9.10-1
    locales — 2.27-9
    mc — 4.8.23-2
    ndmq — 1.0.2-5a
    nginx — 1.17.8-1
    openssl-util — 1.1.1d-2
    opkg — 2019-06-14-dcbc142e-2
    opt-ndmsv2 — 1.0-12
    php7 — 7.4.3-1
    php7-mod-openssl — 7.4.3-1
    poorbox — 1.31.1-2
    terminfo — 6.2-1
    zlib — 1.2.11-3
    zoneinfo-asia — 2019c-1
    zoneinfo-europe — 2019c-1

    Возможно, тут что-то лишнее затесалось, но места на накопителе много, поэтому разбираться не стал.

    После установки пакетов настраиваем nginx, я пробовал с двумя доменами — на втором настроен https, и пока висит заглушка. 81 и 433 внутренние порты вместо 80 и 443 используются, поскольку на нормальных портах висят админки роутера.

    etc/nginx/nginx.conf
    user  nobody;
    worker_processes  1;
    #error_log  /opt/var/log/nginx/error.log;
    #error_log  /opt/var/log/nginx/error.log  notice;
    #error_log  /opt/var/log/nginx/error.log  info;
    #pid        /opt/var/run/nginx.pid;
    
    events {
        worker_connections  64;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
        #access_log  /opt/var/log/nginx/access.log main;
        sendfile        on;
        #tcp_nopush     on;
        #keepalive_timeout  0;
        keepalive_timeout  65;
        #gzip  on;
    
    server {
        listen 81;
        server_name milkov.su www.milkov.su;
        return 301 https://milkov.su$request_uri;
    }
    
    server {
            listen 433 ssl;
            server_name milkov.su;
            #SSL support
            include ssl.conf;
            location / {
                root   /opt/share/nginx/html;
                index  index.html index.htm;
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
                }
            }
    }
    


    etc/nginx/ssl.conf
    ssl_certificate /opt/etc/nginx/certs/milkov.su/fullchain.pem;
    ssl_certificate_key /opt/etc/nginx/certs/milkov.su/privkey.pem;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
    ssl_dhparam /opt/etc/nginx/dhparams.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_stapling on;



    Для того, чтобы сайт работал по https, воспользовался известным скриптом dehydrated, установив его по этой инструкции. Затруднений этот процесс не вызвал, запнулся только на том, что в тексте скрипта для работы на моем роутере надо закомментировать строчку в файле /opt/etc/ssl/openssl.cnf:

    [openssl_conf]
    #engines=engines

    И отмечу, что генерация dhparams.pem командой «openssl dhparam -out dhparams.pem 2048» на моем роутере занимает больше 2 часов, если бы не индикатор прогресса — потерял бы терпение и перезагрузил.

    После получения сертификатов перезапускаем nginx командой "/opt/etc/init.d/S80nginx restart". В принципе на этом настройка закончена, но сайта еще нет — если положим в каталог /share/nginx/html файл index.html, увидим заглушку.

    <!DOCTYPE html>
    <html>
    <head>
    <title>Тестовая страничка!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Тестовая страничка!</h1>
    <p>Это простая статическая тестовая страничка, абсолютно ничего интересного.</p>
    </body>
    </html>


    Чтобы разместить информацию красиво, непрофессионалу типа меня проще воспользоваться готовыми шаблонами, после долгого перебора различных каталогов нашел templatemo.com — там неплохой выбор бесплатных шаблонов, не требующих обязательного указания авторства (что редкость в интернете, большая часть шаблонов в лицензии требуют сохранить ссылку на ресурс, откуда они получены).

    Выбираем подходящий шаблон — там есть на самые разные случаи, скачиваем архив, и раcпаковываем его в каталог /share/nginx/html, делать это можно уже со своего компьютера, затем редактируем шаблон (тут потребуются минимальные знания HTML, чтобы не нарушить структуру) и заменяем графику, как показано на рисунке ниже.



    Резюме: роутер вполне пригоден для размещения на нем легкого сайта, в принципе — если не предполагается большой нагрузки, можно поставить и php, и экспериментировать с более сложными проектами (смотрю на nextcloud/owncloud, вроде есть успешные установки на такое железо). Возможность установки пакетов поднимает его полезность — например, когда надо было защитить RDP порт ПК в локальной сети, поставил knockd на роутер — и проброс порта к ПК открывался только после port knocking.

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

    Подробнее
    Реклама

    Комментарии 21

      0
      Я на роутерах обычно lighttpd для этих целей поднимаю. Как минимум потому, что памяти у меня выше 32 Мб не бывает. =)
        0
        Да, я на TP-Link предыдущем пробовал — у него тоже 32/8, в принципе работало, но уж очень он медленно с диском по USB общается — максимум 3-4 мегабайта в секунду выходило.
          0
          У меня ещё и весь server-side на shell-script написан, т.к. почти все прочие интерпретаторы запускать там очень больно, медленно и печально.

          Вообще, кроме веба у меня на роутере ещё крутится интернет-радио (icecast2 + ices, ogg без перекодирования на роутере) и sshd, в т.ч. туннель через него.

          И всё это сделано на старой штатной прошивке D-Link'а, которая для этого не предназначена совсем.
        +2
        Я так и не понял, зачем роутить 80 и 443 порты на самого себя? Можно же было настроиь nginx слушать на внешнем wan инрефейсе.
          +1
          Подскажите, как? С удовольствием уберу лишнее звено.
          Просто во всех описаниях, которые читал — указывается на необходимость проброса портов с внешнего интерфейса на внутренний.
            +2
            Везде про проброс портов пишут потому, что обслуживающая программа находится на одной из машин локальной сети а не на роутере. А если програма находится на роутере проброс не нужен. У всех програм в конфигураци есть параметр, указывающий на каком адресе или иногда интерфейсе нужно открыть порт и слушать. Если там указать внешний адрес, то все заработает из коробки без пробросов. Например, у nginx этот параметр называется listen. То есть, написав в конфигурации listen внешний_адрес:80 все сразу заработает.
              0
              Покурил обсуждения по этому способу, как я понял — openwrt.org/docs/guide-user/services/webserver/nginx — тут такой вариант описывается, при этом для доступа из локальной сети делается еще одна конфигурация. Сейчас попробовал, без дополнительных настроек, просто отменив проброс портов и поставив в конфиге listen внешнийIP:80 получаю 403 ошибку при попытке открыть сайт из локальной сети.

              Надо подумать — с пробросом портов какой-то костыль, но проще конфиги ;) И при смене внешнего IP ничего перенастраивать не надо.
                0
                Проброс портов действительно не нужен, listen 80 в конфигурации nginx на самом деле означает listen 0.0.0.0:80, то есть он по умолчанию слушает порт на всех имеющихся сетевых интерфейсах, никакой внешний IP прописывать не нужно.

                Дело в другом, у всех роутеров включен файрволл, в цепочке INPUT которого в конце списка правил обычно стоит DROP ALL anywhere, то есть все порты закрыты, кроме некоторых. Вы сами можете в этом убедиться, если зайдете на роутер по SSH и дадите команду iptables -L.

                Стало быть, вам просто нужно открыть этот порт:
                iptables -I INPUT -p tcp --dport 80 -j ACCEPT


                Обратите внимание на ключ I (insert). Обычно в советах в интернете пишут эту команду с ключом -А (append), но с ним правило добавится в самый конец цепочки, а перед ним будет DROP all, и порт не откроется. Insert вставит правило в самое начало, до DROP all.

                Если в роутере есть возможность прописать свои скрипты, эту команду можно прописать в скрипт Firewall, чтобы не заходить по SSH и открывать порт вручную после каждой перезагрузки роутера. Или в скрипт Init.
                  0
                  Подумалось — а что в этом случае будет, учитывая то, что 80/443 порты на внутреннем интерфейсе уже слушает веб-сервер админки роутера?

                  Попробовал открыть порт через iptables (пришлось установить этот пакет) — с указанием в конфиге listen 80 nginx ругается в логах, что не может bind этот порт. И в случае открытия порта мы не даем ли тем самым доступ к админке снаружи?
                    +2
                    Ну если админка роутера уже висит на 80/443, то nginx не сможет забиндить порт, надо переносить админку на другие порты, слушать порт может только одна программа.
                    Вообще обычно не рекомендуется светить админку напрямую в внешнюю сеть, лучше ее оставить только на LAN, при необходимости используя VPN для подключения снаружи. Боты сканируют весь интернет и пытаются подобрать пароли на всем, что подключено напрямую в сеть: роутеры, IP-камеры и т.д.

                    iptables (пришлось установить этот пакет)


                    Firewall в Linux находится в ядре и называется Netfilter. iptables, nftables и другие программы из userspace им управляют. Я не знаю, как там в Keenetic, возможно там nftables по умолчанию, у него другой синтаксис. То есть можно посмотреть, что уже есть в системе, чтобы не ставить лишние пакеты.
                      0
                      Ещё поразбирался — админку перенести на другой порт не получается простыми средствами. Вот, похоже, и причина, почему авторы инструкций предлагают проброс портов — это проще и работает на всех устройствах… Спасибо за замечания — узнал еще немного по сетевым технологиям ;)
          +3
          С проблемой частой записи на флэшку (логи) я справился относительно просто: пишу все логи в /tmp (который расположен в ramdrive) и по cron'у проверяю свободную память. Как только превысило определённый предел — сливаю на флэшку. В итоге вся мелочь пишется редко и «одним куском». Флэшки живут годами в таком режиме.
            +1

            Я бы рекомендовал воспользоваться одноплатным компьютером, на подобии raspberry pi. Подать питание можно от роутера, потребление небольшое, и бесшумный. Но при этом — любой вменяемый дистрибутив, выше производительность, больше возможностей.

              +1
              Тоже думал про малинку, помимо названных плюсов (а на нее еще и элементы умного дома повесить можно, и медиаплеер соорудить), есть и минусы:
              — это еще одна коробочка, которая стоит ощутимых денег;
              — от роутера я бы включать не рискнул — боюсь, не потянет его USB такое потребление, это еще один блок питания, а в удлинителе свободных розеток нет;
              — к малинке надо подтянуть ethernet, но на роутере все порты уже заняты;
              — более-менее мощные raspberry pi требуют радиатор, а при большой нагрузке и вентилятор — иначе перегреваются;
              — и главное — скорость работы в качестве NAS нормальная только у rpi4 (получается гигабит выжать), а она точно хочет вентилятор…

              В общем — история обычная :) «а зачем тебе Х, возьми Y, оно чуть дороже, но зато....», следом «а зачем Y, возьми Z — оно в большом корпусе, с системой охлаждения, но зато....» — в итоге обсуждаем стоечные сервера и системы кондиционирования датацентров.
              А хочется просто маленькую площадку для боевых экспериментов.
                0

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

                  0
                  Сайт на домашнем роутере можно спрятать за Cloudflare, например.
                0
                Еще плюс в сторону отдельного устройства, подключенного проводом — USB3 сильно шумит на 2,4ГГц. Бывает, что на wifi/bluetooth поблизости скорость падает почти до нуля. Зависит конечно от реализации конкретных устройств, кабелей, тп, но тем не менее учитывать приходится. Переход на 5ГГц решает конечно, но к сожалению еще много всего, что может только 2,4
                  0

                  От роутера не взлетит, для raspberry 3b рекомендуемый БП 5В- 3А, на китайских недорогих двухамперных они вообще не включаются

                    0

                    У меня RPi 3 b+, работает даже от USB компьютера, от роутера не пробовал.

                      0

                      А что малина при этом делает? У меня на двухамперном БП она работала до тех пор, пока работала вообще без нагрузки, как только в home assistant появилось с десяток автоматизацией и некоторое количество датчиков она похоже начала троттлить а потом и в ребуты уходить.

                        0
                        Работает desktop raspbian. Редактирую текстовые файлы, docker иногда для сборки запускаю.
                        При питании от 2 А зарядки, запускал анализ шахматных партий (stockfish 8 потоков 100% загрузка) ничего плохого не происходило, но при этом, рядом кулер крутился, сейчас без кулера обхожусь, но и корпуса у меня нет.
                        Некоторое время роутером (openwrt) была на зарядке 2А.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое