В прошлой статье мы познакомились с настройкой окружения для LXC и создали первые контейнеры.
Продолжаем знакомиться с технологией. Из этой статьи вы узнате
- как перенаправлять трафик на определенные порты
- как настроить SSH-доступ к контейнерам
- как можно запретить контейнерам из разных сетей общаться друг с другом
Перенаправляем запросы с порта на порт
Внутри контейнера может быть запущен процесс, работающий с какими-то портами, которые должны быть доступны из интернета. Например, Telegram-бот или сайт на Node.js. В таком случае необходимо направить трафик с внешнего порта основного сервера на определенный порт контейнера.
Для этого воспользуемся iptables.
iptables -t nat -A PREROUTING -i ens3 -p tcp --dport <external_port> -j DNAT --to <host>:<port>
В качестве external_port можно выбрать любой свободный порт на основном сервере. Адрес и порт контейнера, куда отправятся запросы, задаем в параметрах host и port. Выбор портов зависит только от ваших задач.
Рассмотрим пару примеров, где можно воспользоваться этой командой.
Настройка SSH-доступа
Для того, чтобы иметь возможность подключаться к контейнеру напрямую по SSH, необходимо перенаправлять запросы с какого-нибудь порта основного сервера на 22 порт этого контейнера.
Создадим правило, по которому все запросы к 1000 порту основного сервера будут направлены на 22 порт container-alice (10.0.1.2).
iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 1000 -j DNAT --to 10.0.1.2:22
Сохраняем параметры iptables
iptables-save > /etc/iptables/rules.v4
Если вы не знакомы с тем, как подключаться к серверу с использованием rsa-ключей, то рекомендуем ознакомиться со статьей «Беспарольный доступ по SSH».
Подключаемся контейнеру, чтобы поместить в него свой публичный ключ
lxc exec container-alice /bin/bash
Добавляем ключ в файл authorized_keys
nano ~/.ssh/authorized_keys
Сохраняем файл, выходим из nano и отключаемся от контейнера.
exit
Теперь можно подключиться напрямую к container-alice из терминала вашего компьютера. Вместо myserver.com подставьте доменное имя или адрес сервера.
ssh [email protected] -p 1000
Таким образом можно открывать доступ к конкретным контейнерам для администрирования.
Перенаправляем запросы к процессу
К примеру, нам нужно запустить в контейнере с адресом 10.0.1.2 какой-нибудь процесс, который будет слушать порт 1337. При этом мы хотим сделать так, чтобы к этому процессу шли все запросы, которые идут на порт 1400 основного сервера. Тогда нужно выполнить команду с такими параметрами.
iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 1400 -j DNAT --to 10.0.1.2:1337
Порты могут быть и одинаковые, потому что относятся к разным системам. То есть нам ничего не мешает отправлять запросы с порта 1337 основного сервера на порт 1337 контейнера, чтобы схема роутинга была более очевидной.
Сохраним новые параметры iptables с помощью следующей команды
iptables-save > /etc/iptables/rules.v4
Подключимся по ssh к контейнеру, чтобы запустить процесс в фоне с помощью screen.
ssh [email protected] -p 1000
Создаем терминальную сессию, которую можно будет свернуть
screen
При первом запуске screen вы увидите подобное окно. Нажмите пробел или enter.
Откроется терминальная сессия, как если бы вы просто подключились к серверу
Запустим простой python-сервер, который будет показывать содержимое текущей директории.
python3 -m http.server 1337
Теперь можно свернуть эту терминальную сессию, нажав Ctrl+a, d. Процесс будет продолжать работать в фоне.
Открываем в браузере страницу по адресу вашего сервера и указываем порт, например, http://myserver.com:1400
Проксирование запросов также можно сделать с помощью nginx, если вам нужно задать адрес сайта с помощью поддомена без указания специфичного порта. Для этого на основном сервере нужно отредактировать nginx-конфиг этого контейнера.
nano /etc/nginx/sites-available/container-alice
Добавим в ещё одну секцию server в конец конфига
server {
listen 80;
server_name python-alice.myserver.com;
include proxy_params;
location / {
proxy_pass http://10.0.1.2:1337/;
}
}
Перезагружаем nginx
service nginx restart
Теперь та же страница доступна по адресу http://python-alice.myserver.com
Запретим общение между контейнерами
Из соображений безопасности стоит сделать невозможным общение контейнеров из разных сетей между собой. Сейчас первый контейнер может пинговать второй и наоборот.
Прописываем ограничения для сети alice-br
iptables -A FORWARD -s 10.0.1.0/24 -i alice-br -o ens3 -j ACCEPT
iptables -A FORWARD -i alice-br -j DROP
И для сети bob-br
iptables -A FORWARD -s 10.0.2.0/24 -i bob-br -o ens3 -j ACCEPT
iptables -A FORWARD -i bob-br -j DROP
Сохраним параметры iptables
iptables-save > /etc/iptables/rules.v4
Теперь пакеты, которые будут пересылаться за пределы сетей 10.0.1.0/24 и 10.0.2.0/24 никуда не дойдут. Это значит, что если злоумышленник получит доступ к контейнеру в одной сети, то другие сети останутся в безопасности.
Подведем итоги
Мы научились направлять трафик на определенные порты, получили доступ к контейнерам по SSH и запретили передавать пакеты между сетями.
В следующей статье мы расскажем, как работать с резервными копиями контейнеров.