[Из песочницы] Linux tips & tricks: сервер, откройся

?v=1

Тем, кому надо обеспечить себе, любимому, доступ к своим серверам из любой точки мира по SSH/RDP/иное — небольшое RTFM/шпора.

Нам нужно обойтись без VPN и других наворотов, с любого устройства под руками.

И так, чтобы с сервером не слишком упражняться.

Всё, что для этого нужно — knockd, прямые руки и 5 минут работы.

«В интернете всё есть», конечно (даже на Хабре), но когда дело доходит до конкретной реализации — тут и начинается…

Будем упражняться на примере Fedora/CentOS, но это неважно.

Шпора подойдет как новичкам, так и зубрам этого дела, поэтому будут комментарии, но покороче.


  • ставим knock-server:
    yum/dnf install knock-server


  • настраиваем его (например на ssh) — /etc/knockd.conf:

    [options]
        UseSyslog
        interface = enp1s0f0
    [SSHopen]
        sequence        = 33333,22222,11111
        seq_timeout     = 5
        tcpflags        = syn
        start_command   = iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        cmd_timeout     = 3600
        stop_command    = iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    [SSHclose]
        sequence        = 11111,22222,33333
        seq_timeout     = 5
        tcpflags        = syn
        command         = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

    «Открывающая» часть настроена на автозакрытие через 1 час. Мало ли…


  • /etc/sysconfig/iptables:

    ...
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 11111 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22222 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 33333 -j ACCEPT
    ...

  • вперед:

    service iptables restart
    service knockd start

  • можно добавить RDP на крутящийся внутри виртуальный Windows Server (/etc/knockd.conf; название интерфейса подставить по вкусу):

    [RDPopen]
        sequence        = 44444,33333,22222
        seq_timeout     = 5
        tcpflags        = syn
        start_command   = iptables -t nat -A PREROUTING -s %IP% -i enp1s0f0 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.2
        cmd_timeout     = 3600
        stop_command    = iptables -t nat -D PREROUTING -s %IP% -i enp1s0f0 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.2
    [RDPclose]
        sequence        = 22222,33333,44444
        seq_timeout     = 5
        tcpflags        = syn
        command         = iptables -t nat -D PREROUTING -s %IP% -i enp1s0f0 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.2

    Все наши пинки от клиента отслеживаем на сервере командой iptables -S.



knockd.conf:

В манах тоже всё есть (но это неточно), однако knockd — товарищ довольно скупой на сообщения, поэтому надо быть очень внимательным.


  • версия
    В репозитариях Fedora/CentOS крайний knockd на сегодня — 0.63. Кто хочет UDP — ищите пакеты 0.70.
  • interface
    В дефолтной конфигурации Fedora/CentOS эта строка отсутствует. Добавить руками, иначе не будет работать.
  • timeout
    Здесь подобрать по вкусу. Надо чтобы и клиенту времени хватило на все пинки — и бот-сканер портов обломался (а сканировать будут 146%).
  • start/stop/command.
    Если команда одна — то command, если две — то start_command+stop_command.
    Если ошибетесь — knockd промолчит, но работать не будет.
  • proto
    Теоретически можно использовать UDP. На практике я было смешал tcp и udp, а клиент с пляжа в Бали смог открыть себе калитку только с пятого раза. Ибо TCP долетели когда надо, а UDP — не факт. Но это дело вкуса, опять же.
  • sequence
    Неявные грабли в том, что последовательности не должны пересекаться… как бы это сказать…

Например, такое:

open: 11111,22222,33333
close: 22222,11111,33333

По пинку 11111 open будет ждать следующего пинка на 22222. Однако по этому (22222) пинку начнет работать close и всё поломается. Такие дела ©.


iptables

Если в /etc/sysconfig/iptables вот это вот:

*nat
:PREROUTING ACCEPT [0:0]

нам особо не мешает, то вот это вот:

*filter
:INPUT ACCEPT [0:0]
...
-A INPUT -j REJECT --reject-with icmp-host-prohibited

Таки мешает.

Так как knockd добавляет правила в конец цепочки INPUT, то мы получим reject.

А отключить этот reject — это открыть машину всем ветрам.

Дабы не изгаляться в iptables что куда перед чем вставлять (как вот люди предлагают) сделаем проще:


  • дефолтное в CentOS/Fedora первое правило («что не запрещено — разрешено») заменим на обратное,
  • а последнее правило убираем.

В итоге должно получиться:

*filter
:INPUT DROP [0:0]
...
#-A INPUT -j REJECT --reject-with icmp-host-prohibited

Можно, конечно, вместо DROP сделать REJECT, но с DROP ботам будет жить веселее.

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

В принципе ряд клиентов перечислены на сайте проекта, но это из той же серии «в интернете всё есть». Поэтому перечислю то, что здесь и сейчас работает у меня под руками.

При выборе клиента необходимо проследить, чтобы он поддерживал опцию delay между пакетами. Да, пляж пляжу рознь и 100 мегабит ни разу не гарантируют долетание пакетов в нужном порядке в нужное время из данного места.

И да — при настройке клиента delay надо подбирать самостоятельно. Много timeout — боты нападут, мало — клиент не успеет. Много delay — клиент не успеет, мало — пакеты перезаблудятся в интернетах.

При timeout=5s вполне рабочий вариант delay=300…500ms


Windows

Как это ни смешно звучит, но нагуглить внятный knock-клиент под эту платформу довольно нетривиально. Такой, чтобы CLI, поддерживал delay, TCP — и без бантиков.

Как вариант можно попробовать это вот. Видимо у меня гугль не торт.


Linux

Здесь всё просто:

dnf install knock -y
knock -d  11111 22222 33333


MacOS

Проще всего поставить порт из homebrew:
brew install knock
и нарисовать себе нужные батники командники вида:

#!bin/sh
knock -d 300  11111 22222 33333


iOS

Рабочий вариант — KnockOnD (бесплатный, из магазина).


Android

«Knock on Ports». Не реклама, а просто он работает. И разработчики достаточно отзывчивые.

P.S. markdown на Хабре, конечно, дай бог ему здоровья когда-нибудь…

© Habrahabr.ru