Как стать автором
Обновить

Как запустить свой сервер с белым ip из локальной домашней сети

Время на прочтение5 мин
Количество просмотров77K

Disclaimer

Я не являюсь сетевым инженером, я просто студент, который решил записать свои действия, чтобы поделиться со знакомыми и не забыть, что я вообще делал. Буду очень рад если меня поправят в комментариях. Этот конспект написан по другим статьям с различных ресурсов, прошу поддержать авторов тех гайдов, у них некоторые моменты расписаны более подробно и возможно вам подойдет именно их статья.

Буду стараться писать очень подробно, чтобы человек, знающий столько сколько я в начале своего пути, все понял.

Вступление

Мне очень давно хотелось поднять видимый извне сервер в своей домашней локальной сети, чтобы использовать его для pet проектов или же возможно для сайта-визитки.

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

Что мы имеем?

Для справки, на момент написания публикации (2021) стоимость минимальной VPS на доверенном ресурсе - 400 руб. , стоимость белого ip у моего провайдера - 179 руб.

  • Ноутбук (intel core i5 M 560 2,67 GHz, 4/60Gb) с установленной Ubuntu Server 20.04.3 (для создания установочной флешки советую использовать rufus (win) или balenaEtcher (os x)

  • роутер провайдера с подключенным пакетом "статический ip адрес"

  • второй компьютер для тестов (все что делается через браузер можно, конечно, сделать и на телефоне, вопрос удобства)

  • хорошая музыка чтобы процесс не был скучным

Какая цель?

Сделать python3 flask (взял для простоты) сервер доступный из вне.

Установка постоянного локального адреса на сервер

Приступим. Во-первых установим постоянный ip для нашего сервера в локальной сети. По идее изначально используется DHCP (протокол, по которому каждое устройство в сети получает относительно случайный ip адрес, а нам нужен постоянный для сервера, чтобы роутер всегда знал куда отправлять внешние запросы)

  1. Смотрим интерфейс, который мы используем, с помощью ifconfig

  2. В зависимости от того какой тип соединения мы используем (кабель или wi-fi) выбираем файл в катологе /etc/netplan

    И настраиваем его примерно так:

    network:
        ethernets:
            ethx:
                dhcp4: no
                dhcp6: no
                addresses: [192.168.1.200/24, ]
                gateway4: 192.168.1.1
                nameservers:
                    addresses: [192.168.1.1, ]
        version: 2

    ethx - название нашего устройства по которому идет подключение

    Здесь важно понимать что означают строки:

    • addresses (6) - адрес нашего сервера в локальной сети, как раз то что мы делаем постоянным

      /24 означает маску сети (255.255.255.0), в данной ситуации первые 3 числа должны совпадать с локальным адресом роутера, а последнее число произольно. Я выбрал адрес 192.168.1.200

    • gateway4 - шлюз нашей сети, то есть роутер. Его адрес 192.168.1.1, обычно он общий для всех роутеров одного провайдера, так что погуглите (иногда его адрес указывается там же где и пароль от wi-fi)

    • в строке nameservers: addresses (9) указываем тот же адрес что и в gateway4 (простите, но я беспонятия что это)

    • dhcp4: no и dhcp6: no указывают, что мы не будем использовать протокол DHCP

На этом этапе возможно потребуется проверка:

  • На сервере:

    sudo tcpdump -i ethx icmp and icmp[icmptype]=icmp-echo

    Чтобы следить за тем кто нас пингует.

  • И пингуем его с другого пк внутри локальной сети по адресу 192.168.1.200.

Также строит проверить есть ли доступ к интернету у нашего ноутбука-сервера: используем команду ping с доменом google.com.

Все это подробно описано в этой статье для Ubuntu, для других дистрибутивов гуглите "Установка статического ip <название дистрибутива>".

Все работает? Идем дальше!

Рассказываем роутеру про сервер

Теперь наш сервер знает, что мы имеем дело с постоянным ip и не используем протокол DHCP. Самое время рассказать роутеру, что внешние запросы нужно отправлять на сервер. Чтобы получить доступ к настройкам роутера вбиваем в поисковую строку его ip адрес.

Есть два варианта:

  • Установить DMZ зону внутри настроек роутера и указать туда локальный адрес нашего сервера. Этим действием мы делаем наш сервер публичным и теперь любой может попробовать подключиться к нему.

  • Пробросить порты нужных нам ресурсов через роутер на сервер (перенаправление портов). Не забудьте порт SSH (22) и flask (5000)

    Попробуйте пингануть его из внешней сети.

Все норм? Теперь наш сервер виден из вне, самое время подумать о безопасности.

Защита сервера

Я буду настраивать SSH, Firewall и fail2ban по вот этому очень хорошему гайду. (еще раз, моя цель не скопипастить все что я нашел, а собрать все в одно место, чтобы не забыть) Я делаю все для Ubuntu Server, но в том гайде есть для CentOS и Red Hat.

Во-первых сделаем еще одного пользователя помимо root (1), зададим ему пароль (2) и разрешим использовать root привелегии через sudo (3):

useradd [options] <username>
passwd <username>
usermod -aG sudo <username>

SSH

Настраивайте по инструкции в статье упомянутой выше. Там мне совсем нечего добавить, кроме подроностей о public и private ключах:

  • ssh-keygen -t rsa генерирует 2 ключа открытый (тот что имеет .pub) и приватный который (не имеет такого расширения)

  • Открытый ключ отправляется на сервер в файл authorized_keys в папке /.ssh в домашней директории пользователя (/home/username/.shh/authorized_key)

    Для этого можно использовать команду:

    cat ~/.ssh/id_rsa.pub | ssh root@ip-адрес-сервера 'cat >> ~/.ssh/authorized_keys'
  • Закрытый ключ используется для аутентификации, скопируйте его куда-нибудь чтобы не потерять

    Использовать ключ для входа можно командой:

ssh -i <путь к ключу> <имя пользователя>@<адрес сервера>

Важно отключить аутентификацию по паролю иначе мы все это делали зря.

Firewall

Используя проброс портов мы разрешаем доступ к нашему серверу лишь посредством подключений к определенным портам, но DMZ зона допускает почти все типы запросов. Используя DMZ зону нам строит поднять FireWall на сервере, который как раз и ограничит количество портов которые могут принимать внешние запросы.

Разрешим использование SSH (1) и порта 5000 (2) в ufw (Firewall), и запустим Firewall (3):

sudo ufw allow ssh
sudo ufw allow 5000/tcp
sudo ufw enable

Подняв FireWall важно не забыть разрешить доступ к порту SSH (22) и порту Flask (5000) (ну или другого ПО, которое мы собираемся использовать). Я забыл и долго не понимал, почему мой сервер не отвечает.

На сайте хорошо разобраны команды для управления Firewall-ом.

Fail2ban

Fail2ban ограничивает количество попыток подключения, это сильно усложнит подбор аутентификационных данных SSH.

Для начала установим его (1) и запустим (2, 3):

sudo apt install fail2ban
systemctl start fail2ban
systemctl enable fail2ban

Теперь можем настроить его, используя эти конфигурационные файлы:/etc/fail2ban/fail2ban.conf и /etc/fail2ban/jail.conf. Во втором находятся ограничения на количество подключений за определенный промежуток времени и время бана.

Теперь сделаем проверку более сложного уровня

  1. Установим flask и python3:

    sudo apt install python3
    sudo apt install pip
    pip install flask
  2. Скопируем код тестового сервера с сайта в файл server.py:

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello_world():
        return "<p>Hello, World!</p>"

    Находясь в директории с этим файлом, запустим сервер:

    export FLASK_APP=server.py
    flask run -h <локальный адрес нашего сервера> -p 5000

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

    94.123.45.70:5000/

    Если все работает мы должны увидеть строку "Hello, World!". Не заработало? Пройдитесь по моим заметкам в этом гайде еще раз.

Источники

Теги:
Хабы:
Всего голосов 41: ↑28 и ↓13+15
Комментарии64

Публикации