В данном разделе приведены рекомендации для повышения безопасности при использовании ECCM.
Смена паролей по умолчанию
Замена стандартных паролей на уникальные сложные пароли предотвращает несанкционированный доступ к веб-интерфейсу ECCM.
Перейдите в рабочую директорию ECCM:
cd eccm/2.13/
С помощью скрипта update_password.sh измените следующие пароли:
Основные пароли:
ROOT_POSTGRES_PASSWORD;
ECCM_POSTGRES_PASSWORD;
PEEPER_MONITOR_POSTGRES_PASSWORD;
ECCM_RABBITMQ_PASSWORD;
Пароли кластера (для отказоустойчивой установки):
SENTINEL_PASSWORD;
RABBITMQ_CLUSTER_PASSWORD;
REPMGR_PASSWORD;
TRUSTSTORE_PASSWORD;
REDIS_PASSWORD;
При первом запуске скрипт compose-tools.sh сам предложит сгенерировать пароли — нажмите Enter для подтверждения или введите пароли вручную. Сгенерированные пароли сохраняются в файл .env.personal с правами доступа 600, путь к файлу выводится в выводе скрипта.
При необходимости пароли можно изменить вручную в файле .env.personal, который сохраняется при обновлении ECCM. При его отсутствии пароли берутся из файла eccm/.env, который может быть перезаписан при установке нового архива:
При обновлении ECCM файл .env.personal сохраняется и не перезаписывается. Файл eccm/.env может быть заменен на новый из архива установки — тогда все измененные пароли вернутся к значениям по умолчанию. Чтобы не потерять пароли, используйте файл .env.personal или скопируйте их в новый файл .env после обновления.
Смена паролей при текущей эксплуатации
С помощью скрипта update_password.sh измените все старые пароли на новые или вручную замените в файле .env.personal следующие переменные:
С помощью скрипта update_password.sh измените все старые пароли на новые или вручную замените в файле .env.personal следующие переменные на каждом сервере:
С помощью скрипта update_password.sh измените все старые пароли на новые или вручную замените в файле .env.personal следующие переменные на каждом сервере:
Определите текущего Master и Standby в БД. Подробнее об определении текущего мастера и смене мастерства при необходимости описано в разделе "Обновление 2.12 -> 2.13".
Произведите остановку Slave узла:
Slave
sudo ./compose-tools.sh --stop
После полной остановки узла, произведите аналогичную операцию для Witness и Master.
На каждом узле в конфигурационном файле .env.cluster установите переменной RECONFIGURE_CLUSTER значение true.
После успешного запуска установите значение переменной RECONFIGURE_CLUSTER из конфигурационного файла .env.cluster на значение false.
После изменения значения переменной произведите повторный запуск отказоустойчивой системы, при выполнении каждой из следующих команд дождитесь полного запуска узла:
С помощью скрипта update_password.sh измените все старые пароли на новые или вручную замените в файле .env.personal следующие переменные на каждом сервере:
Произведите остановку узлов приложений на серверах Master-app и Slave-app:
Master-app и Slave-app
sudo ./compose-tools.sh --stop
Определите текущего Master и Standby в БД. Подробнее об определении текущего мастера и смене мастерства при необходимости описано в разделе "Обновление 2.12 -> 2.13".
Далее произведите команду остановки сначала для Slave-db:
Slave-db
sudo ./compose-tools.sh --stop
После полной остановки узла, выполните аналогичную команду для оставшихся узлов Master-db и Witness.
На каждом узле в конфигурационном файле .env.cluster установите переменной RECONFIGURE_CLUSTER значение true.
После успешного запуска установите значение переменной RECONFIGURE_CLUSTER из конфигурационного файла .env.cluster на значение false.
После изменения значения переменной произведите повторный запуск отказоустойчивой системы согласно вышеописанной инструкции.
Настройка HTTPS
Запуск веб-интерфейса ECCM по протоколу HTTPS позволяет шифровать трафик между клиентом и приложением, защищая данные от перехвата. Инструкция по настройке доступна в разделе "Настройка доступа к ECCM по HTTPS".
Настройка PostgreSQL
Настройка PostgreSQL позволяет ограничить доступ нежелательных пользователей к базе данных при запуске ECCM в отказоустойчивой системе, или когда база данных находится на отдельном сервере.
Когда ECCM и база данных — на одном сервере, настройка подключений не требуется. По умолчанию контейнер с базой данных при выбранной инсталляции изолирован и недоступен из внешней сети.
Настройте доступ к БД только с localhost, подсетей docker и адреса администратора при помощи любого текстового редактора в файле postgres/data/pg_hba.cluster.conf.tpl:
postgres/data/pg_hba.cluster.conf.tpl
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Docker network internal (172.21.0.0/20) и external (172.20.0.0/20)
hostssl ${ECCM_DATABASE} ${POSTGRES_USER} 172.21.0.0/16 md5 # docker network internal
hostssl ${ECCM_DATABASE} ${ECCM_POSTGRES_USER} 172.21.0.0/16 md5 # docker network internal
hostssl all ${PEEPER_MONITOR_POSTGRES_USER} 172.21.0.0/16 md5 # docker network internal
hostssl repmgr ${REPMGR_USER} 172.21.0.0/16 md5 # docker network internal
hostssl ${ECCM_DATABASE} ${POSTGRES_USER} 172.20.0.0/16 md5 # docker network external
hostssl ${ECCM_DATABASE} ${ECCM_POSTGRES_USER} 172.20.0.0/16 md5 # docker network external
hostssl all ${PEEPER_MONITOR_POSTGRES_USER} 172.20.0.0/16 md5 # docker network external
hostssl repmgr ${REPMGR_USER} 172.20.0.0/16 md5 # docker network external
# Опционально: удаленный доступ администратора к БД
hostssl all all <admin_ip>/32 md5 # опционально: IP адрес для удаленного подключения администратора к БД
# Опционально: доступ приложений ECCM инсталляции отказоустойчивой системы с БД на отдельном сервере
hostssl ${ECCM_DATABASE} ${POSTGRES_USER} <master_app_ip>/32 md5 # IP адрес Master-ECCM
hostssl ${ECCM_DATABASE} ${ECCM_POSTGRES_USER} <master_app_ip>/32 md5 # IP адрес Master-ECCM
hostssl all ${PEEPER_MONITOR_POSTGRES_USER} <master_app_ip>/32 md5 # IP адрес Master-ECCM
hostssl repmgr ${REPMGR_USER} <master_app_ip>/32 md5 # IP адрес Master-ECCM
hostssl ${ECCM_DATABASE} ${POSTGRES_USER} <slave_app_ip>/32 md5 # IP адрес Slave-ECCM
hostssl ${ECCM_DATABASE} ${ECCM_POSTGRES_USER} <slave_app_ip>/32 md5 # IP адрес Slave-ECCM
hostssl all ${PEEPER_MONITOR_POSTGRES_USER} <slave_app_ip>/32 md5 # IP адрес Slave-ECCM
hostssl repmgr ${REPMGR_USER} <slave_app_ip>/32 md5 # IP адрес Slave-ECCM
IP-адреса всех узлов отказоустойчивой системы будут добавлены автоматически при запуске ECCM.
Синхронизируйте конфигурационные файлы между узлами:
sudo rsync -av --delete --rsync-path="sudo rsync" eccm/2.13/postgres/data/pg_hba.cluster.conf.tpl <имя пользователя сервера>@<IP-адрес сервера назначения>:<полный путь до директории eccm>/postgres/data/
В файле .env.cluster измените значение параметра RECONFIGURE_CLUSTER на true и перезапустите систему в соответствии с инструкцией в разделе "Запуск ECCM в отказоустойчивой системе".
Во избежание ошибок верните значение параметра RECONFIGURE_CLUSTER на false после перезапуска.
Настройка firewall
Для обеспечения большей безопасности необходимо ограничить внешние подключения к серверу ECCM.
Создайте файл iptables.shс правилами:
iptables.sh
#!/bin/bash
# ---------- адреса ----------
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
WEB_INTERFACE=443 # веб-интерфейс ЕССМ
HTTP_PORT=80 # HTTP-порт для обновления БШПД устройств по HTTP
DHCP_PORT=67 # DHCP-сервер: выдача адресов устройствам
TFTP_PORT=69 # TFTP: загрузка прошивок
SNMP_TRAP_PORT=162 # SNMP-trap: события устройств
SYSLOG_PORT=514 # ECCM_SYSLOG_PORT — прием журналов устройств (UDP и TCP)
SFTP_PORT=2222 # SFTP/SCP загрузчика upgrader (публикация 2222:22 — см. правило ниже)
UPGRADER_SSHD_PORT=22 # порт sshd внутри контейнера upgrader;
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
ECCM_LOOP_PORTS="$WEB_INTERFACE,$SFTP_PORT,$SYSLOG_PORT,$DB_PORT"
ECCM_LOOP_PORTS_DNAT="$WEB_INTERFACE,$UPGRADER_SSHD_PORT,$SYSLOG_PORT,$DB_PORT"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
# Веб-интерфейс ЕССМ: порт $WEB_INTERFACE — по умолчанию 443
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$WEB_INTERFACE" -j ACCEPT
# Опционально: для ограничения только сетью администратора
# sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$WEB_INTERFACE" -j ACCEPT
# Прием трафика от управляемых устройств
# Опционально: при необходимости сузьте до сети устройств: -s <dev_net>/NN
sudo iptables -A ECCM-CLUSTER -p udp --dport "$DHCP_PORT" -j ACCEPT # DHCP: выдача адресов
sudo iptables -A ECCM-CLUSTER -p udp --dport "$TFTP_PORT" -j ACCEPT # TFTP: загрузка прошивок
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SNMP_TRAP_PORT" -j ACCEPT # SNMP-trap: события устройств
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (UDP): журналы
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (TCP)
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$HTTP_PORT" -j ACCEPT # HTTP: загрузка прошивок БШПД
sudo iptables -A ECCM-CLUSTER -p tcp -m conntrack --ctorigdstport "$SFTP_PORT" -j ACCEPT # Загрузка прошивок
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS_DNAT" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS_DNAT" -j ACCEPT
Примените правила:
chmod +x iptables.sh
sudo ./iptables.sh
Для того чтобы правила сохранились после перезагрузки, можно использовать утилиту iptables-persistent (или любые другие доступные методы):
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Создайте файл iptables.sh на сервере с ECCM со следующими правилами:
Сервер ECCM
#!/bin/bash
# ---------- адреса ----------
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
WEB_INTERFACE=443 # веб-интерфейс ЕССМ
HTTP_PORT=80 # HTTP-порт для обновления БШПД устройств по HTTP
DHCP_PORT=67 # DHCP-сервер: выдача адресов устройствам
TFTP_PORT=69 # TFTP: загрузка прошивок
SNMP_TRAP_PORT=162 # SNMP-trap: события устройств
SYSLOG_PORT=514 # ECCM_SYSLOG_PORT — прием журналов устройств (UDP и TCP)
SFTP_PORT=2222 # SFTP/SCP загрузчика upgrader
UPGRADER_SSHD_PORT=22 # порт sshd внутри контейнера upgrader
ECCM_LOOP_PORTS="$WEB_INTERFACE,$SFTP_PORT,$SYSLOG_PORT"
ECCM_LOOP_PORTS_DNAT="$WEB_INTERFACE,$UPGRADER_SSHD_PORT,$SYSLOG_PORT"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
# Веб-интерфейс ЕССМ: порт $WEB_INTERFACE — по умолчанию 443
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$WEB_INTERFACE" -j ACCEPT
# Опционально: для ограничения только сетью администратора
# sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$WEB_INTERFACE" -j ACCEPT
# Прием трафика от управляемых устройств
# Опционально: при необходимости сузьте до сети устройств: -s <dev_net>/NN
sudo iptables -A ECCM-CLUSTER -p udp --dport "$DHCP_PORT" -j ACCEPT # DHCP: выдача адресов
sudo iptables -A ECCM-CLUSTER -p udp --dport "$TFTP_PORT" -j ACCEPT # TFTP: загрузка прошивок
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SNMP_TRAP_PORT" -j ACCEPT # SNMP-trap: события устройств
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (UDP): журналы
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (TCP)
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$HTTP_PORT" -j ACCEPT # HTTP: загрузка прошивок БШПД
sudo iptables -A ECCM-CLUSTER -p tcp -m conntrack --ctorigdstport "$SFTP_PORT" -j ACCEPT # Загрузка прошивок
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS_DNAT" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_LOOP_PORTS_DNAT" -j ACCEPT
На сервере с БД создайте файл iptables.sh со следующими правилами:
Сервер с БД
#!/bin/bash
# ---------- адреса ----------
ECCM_HOST=100.110.2.145 # узел ЕССМ
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов (psql, pgAdmin, бэкап)
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD ACCEPT # фильтрация опубликованного 5432 — в DOCKER-USER
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
# PostgreSQL
for eccm_node in "$ECCM_HOST" ; do
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$DB_PORT" -j ACCEPT
done
# Опционально: доступ администратора к БД (psql, pgAdmin, выгрузка бэкапов).
sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$DB_PORT" -j ACCEPT
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp --dport "$DB_PORT" \
-j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp --dport "$DB_PORT" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
--dport "$DB_PORT" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
--dport "$DB_PORT" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for eccm_node in "$ECCM_HOST" ; do
sudo iptables -C INPUT -s "$eccm_node" -p tcp --dport "$DB_PORT" \
-j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$eccm_node" -p tcp --dport "$DB_PORT" -j REJECT --reject-with tcp-reset
done
Примените правила на каждом сервере:
chmod +x iptables.sh
sudo ./iptables.sh
Для того чтобы правила сохранились после перезагрузки, можно использовать утилиту iptables-persistent (или любые другие доступные методы):
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Создайте файл iptables.sh на узлах Master и Slave со следующими правилами:
Узлы Master и Slave
#!/bin/bash
# ---------- адреса ----------
MASTER_IP=192.0.2.10 # узел ЕССМ в роли master
SLAVE_IP=192.0.2.11 # узел ЕССМ в роли slave
WITNESS_IP=192.0.2.12 # узел ЕССМ в роли witness
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
WEB_INTERFACE=443 # веб-интерфейс ЕССМ
HTTP_PORT=80 # HTTP-порт для обновления БШПД устройств по HTTP
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
REDIS_PORT=6379 # Redis (данные)
REDIS_SENTINEL_PORT=26379 # Redis Sentinel
AMQPS_PORT=5671 # RabbitMQ AMQPS — клиентские TLS-соединения
EPMD_PORT=4369 # RabbitMQ epmd — регистрация имен нод
RABBITMQ_CLUSTER_PORT=25672 # RabbitMQ — межузловой канал кластера
DHCP_PORT=67 # DHCP-сервер: выдача адресов устройствам
TFTP_PORT=69 # TFTP: загрузка прошивок
SNMP_TRAP_PORT=162 # SNMP-trap: события устройств
SYSLOG_PORT=514 # ECCM_SYSLOG_PORT — приём журналов устройств (UDP и TCP)
SFTP_PORT=2222 # SFTP/SCP загрузчика upgrader
ECCM_SERVICE_PORTS="$DB_PORT,$REDIS_PORT,$REDIS_SENTINEL_PORT,$AMQPS_PORT,$EPMD_PORT,$RABBITMQ_CLUSTER_PORT,$WEB_INTERFACE"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
sudo iptables -A INPUT -p vrrp -j ACCEPT # Keepalived
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
for eccm_node in "$MASTER_IP" "$SLAVE_IP" "$WITNESS_IP"; do
# PostgreSQL
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$DB_PORT" -j ACCEPT
# Redis
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_PORT" -j ACCEPT
# Redis Sentinel
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_SENTINEL_PORT" -j ACCEPT
# RabbitMQ
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$AMQPS_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$EPMD_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$RABBITMQ_CLUSTER_PORT" -j ACCEPT
done
# Опционально: доступ администратора к БД
# sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$DB_PORT" -j ACCEPT
# Веб-интерфейс ЕССМ: порт $WEB_INTERFACE — по умолчанию 443
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$WEB_INTERFACE" -j ACCEPT
# Опционально: для ограничения только сетью администратора
# sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$WEB_INTERFACE" -j ACCEPT
# Прием трафика от управляемых устройств
# Опционально: при необходимости сузьте до сети устройств: -s <dev_net>/NN
sudo iptables -A ECCM-CLUSTER -p udp --dport "$DHCP_PORT" -j ACCEPT # DHCP: выдача адресов
sudo iptables -A ECCM-CLUSTER -p udp --dport "$TFTP_PORT" -j ACCEPT # TFTP: загрузка прошивок
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SNMP_TRAP_PORT" -j ACCEPT # SNMP-trap: события устройств
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (UDP): журналы
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (TCP)
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$HTTP_PORT" -j ACCEPT # HTTP: загрузка прошивок БШПД
sudo iptables -A ECCM-CLUSTER -p tcp -m conntrack --ctorigdstport "$SFTP_PORT" -j ACCEPT # Загрузка прошивок
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for eccm_node in "$MASTER_IP" "$SLAVE_IP" "$WITNESS_IP"; do
sudo iptables -C INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset
done
На узле Witness создайте файл iptables.sh со следующими правилами:
Узел Witness
#!/bin/bash
# ---------- адреса ----------
MASTER_IP=192.0.2.10 # узел ЕССМ в роли master
SLAVE_IP=192.0.2.11 # узел ЕССМ в роли slave
WITNESS_IP=192.0.2.12 # этот узел, witness
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
REDIS_SENTINEL_PORT=26379 # Redis Sentinel
AMQPS_PORT=5671 # RabbitMQ AMQPS — клиентские TLS-соединения
EPMD_PORT=4369 # RabbitMQ epmd — регистрация имен нод
RABBITMQ_CLUSTER_PORT=25672 # RabbitMQ — межузловой канал кластера
ECCM_SERVICE_PORTS="$DB_PORT,$REDIS_SENTINEL_PORT,$AMQPS_PORT,$EPMD_PORT,$RABBITMQ_CLUSTER_PORT"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
for eccm_node in "$MASTER_IP" "$SLAVE_IP"; do
# PostgreSQL
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$DB_PORT" -j ACCEPT
# Redis Sentinel
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_SENTINEL_PORT" -j ACCEPT
# RabbitMQ
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$AMQPS_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$EPMD_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$RABBITMQ_CLUSTER_PORT" -j ACCEPT
done
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
done
# Случай 2 вставляется ТРЕТЬИМ в ECCM-CLUSTER: после ACCEPT ESTABLISHED и после
# `! --ctstate DNAT -j RETURN`, но обязательно до LOG и DROP в конце цепи.
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for eccm_node in "$MASTER_IP" "$SLAVE_IP"; do
sudo iptables -C INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset
done
Примените правила на каждом сервере:
chmod +x iptables.sh
sudo ./iptables.sh
Для того чтобы правила сохранились после перезагрузки, можно использовать утилиту iptables-persistent (или любые другие доступные методы):
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Создайте файл iptables.sh на узлах Master-app и Slave-app со следующими правилами:
Узлы Master-app и Slave-app
#!/bin/bash
# ---------- адреса ----------
MASTER_IP=100.110.3.139 # узел ЕССМ в роли master
SLAVE_IP=100.110.2.145 # узел ЕССМ в роли slave
WITNESS_IP=100.110.3.67 # узел ЕССМ в роли witness
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
WEB_INTERFACE=443 # веб-интерфейс ЕССМ
HTTP_PORT=80 # HTTP-порт для обновления БШПД устройств по HTTP
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
REDIS_PORT=6379 # Redis (данные)
REDIS_SENTINEL_PORT=26379 # Redis Sentinel
AMQPS_PORT=5671 # RabbitMQ AMQPS — клиентские TLS-соединения
EPMD_PORT=4369 # RabbitMQ epmd — регистрация имен нод
RABBITMQ_CLUSTER_PORT=25672 # RabbitMQ — межузловой канал кластера
DHCP_PORT=67 # DHCP-сервер: выдача адресов устройствам
TFTP_PORT=69 # TFTP: загрузка прошивок
SNMP_TRAP_PORT=162 # SNMP-trap: события устройств
SYSLOG_PORT=514 # ECCM_SYSLOG_PORT — приём журналов устройств (UDP и TCP)
SFTP_PORT=2222 # SFTP/SCP загрузчика upgrader
ECCM_SERVICE_PORTS="$REDIS_PORT,$REDIS_SENTINEL_PORT,$AMQPS_PORT,$EPMD_PORT,$RABBITMQ_CLUSTER_PORT,$WEB_INTERFACE"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
sudo iptables -A INPUT -p vrrp -j ACCEPT # Keepalived
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
for eccm_node in "$MASTER_IP" "$SLAVE_IP" "$WITNESS_IP"; do
# Redis
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_PORT" -j ACCEPT
# Redis Sentinel
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_SENTINEL_PORT" -j ACCEPT
# RabbitMQ
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$AMQPS_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$EPMD_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$RABBITMQ_CLUSTER_PORT" -j ACCEPT
done
# Веб-интерфейс ЕССМ: порт $WEB_INTERFACE — по умолчанию 443
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$WEB_INTERFACE" -j ACCEPT
# Опционально: для ограничения только сетью администратора
# sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$WEB_INTERFACE" -j ACCEPT
# Прием трафика от управляемых устройств
# Опционально: при необходимости сузьте до сети устройств: -s <dev_net>/NN
sudo iptables -A ECCM-CLUSTER -p udp --dport "$DHCP_PORT" -j ACCEPT # DHCP: выдача адресов
sudo iptables -A ECCM-CLUSTER -p udp --dport "$TFTP_PORT" -j ACCEPT # TFTP: загрузка прошивок
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SNMP_TRAP_PORT" -j ACCEPT # SNMP-trap: события устройств
sudo iptables -A ECCM-CLUSTER -p udp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (UDP): журналы
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$SYSLOG_PORT" -j ACCEPT # Syslog (TCP)
sudo iptables -A ECCM-CLUSTER -p tcp --dport "$HTTP_PORT" -j ACCEPT # HTTP: загрузка прошивок БШПД
sudo iptables -A ECCM-CLUSTER -p tcp -m conntrack --ctorigdstport "$SFTP_PORT" -j ACCEPT # Загрузка прошивок
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for eccm_node in "$MASTER_IP" "$SLAVE_IP" "$WITNESS_IP"; do
sudo iptables -C INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$eccm_node" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset
done
На узлах Master-db и Slave-db создайте файл iptables.sh со следующими правилами:
Узлы Master-db и Slave-db
#!/bin/bash
# ---------- адреса ----------
DB_MASTER_IP=100.110.3.203 # узел СУБД в роли master-db
DB_SLAVE_IP=100.110.3.204 # узел СУБД в роли slave-db
ECCM_MASTER_IP=100.110.3.139 # узел ЕССМ в роли master
ECCM_SLAVE_IP=100.110.2.145 # узел ЕССМ в роли slave
ECCM_WITNESS_IP=100.110.3.67 # узел ЕССМ в роли witness
ADMIN_NET=192.0.2.0/24 # сеть рабочих станций администраторов
# ---------- порты ----------
# Все используемые порты — переменные ниже: при нестандартных значениях меняйте только здесь.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD ACCEPT # фильтрация опубликованного 5432 — в DOCKER-USER
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
# PostgreSQL
for db_client in "$DB_MASTER_IP" "$DB_SLAVE_IP" "$ECCM_MASTER_IP" "$ECCM_SLAVE_IP" "$ECCM_WITNESS_IP"; do
sudo iptables -A ECCM-CLUSTER -p tcp -s "$db_client" --dport "$DB_PORT" -j ACCEPT
done
# Опционально: доступ администратора к БД (psql, pgAdmin, выгрузка бэкапов).
sudo iptables -A ECCM-CLUSTER -p tcp -s "$ADMIN_NET" --dport "$DB_PORT" -j ACCEPT
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp --dport "$DB_PORT" \
-j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp --dport "$DB_PORT" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
--dport "$DB_PORT" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
--dport "$DB_PORT" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for db_client in "$DB_MASTER_IP" "$DB_SLAVE_IP" "$ECCM_MASTER_IP" "$ECCM_SLAVE_IP" "$ECCM_WITNESS_IP"; do
sudo iptables -C INPUT -s "$db_client" -p tcp --dport "$DB_PORT" \
-j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$db_client" -p tcp --dport "$DB_PORT" -j REJECT --reject-with tcp-reset
done
На узле Witness создайте файл iptables.sh со следующими правилами:
Узел Witness
#!/bin/bash
# ---------- адреса ----------
MASTER_IP=100.110.3.139 # узел ЕССМ в роли master
SLAVE_IP=100.110.2.145 # узел ЕССМ в роли slave
DB_MASTER_IP=100.110.3.203 # узел СУБД в роли master-db
DB_SLAVE_IP=100.110.3.204 # узел СУБД в роли slave-db
# ---------- порты ----------
# Все используемые порты — переменные ниже: изменяйте при нестандартных значениях.
SSH_PORT=22 # SSH узла — хостовый sshd, не контейнер
DB_PORT=5432 # PostgreSQL (POSTGRES_PORT)
REDIS_SENTINEL_PORT=26379 # Redis Sentinel (на witness узла данных Redis нет — 6379 не нужен)
AMQPS_PORT=5671 # RabbitMQ AMQPS — клиентские TLS-соединения
EPMD_PORT=4369 # RabbitMQ epmd — регистрация имен нод
RABBITMQ_CLUSTER_PORT=25672 # RabbitMQ — межузловой канал кластера
ECCM_SERVICE_PORTS="$DB_PORT,$REDIS_SENTINEL_PORT,$AMQPS_PORT,$EPMD_PORT,$RABBITMQ_CLUSTER_PORT"
# ---------- политика по умолчанию ----------
sudo iptables -P INPUT DROP # запрет всех входящих соединений
sudo iptables -P FORWARD ACCEPT # взаимодействие с docker
sudo iptables -P OUTPUT ACCEPT
# ---------- хостовые сервисы ----------
sudo iptables -A INPUT -i lo -j ACCEPT # разрешить обращения к localhost
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # ответы на исходящие соединения
sudo iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT # SSH
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # опционально: разрешить пинговать себя
# ---------- цепочка сервисных портов ----------
sudo iptables -N ECCM-CLUSTER 2>/dev/null
sudo iptables -F ECCM-CLUSTER # файл можно запускать повторно
sudo iptables -C DOCKER-USER -j ECCM-CLUSTER 2>/dev/null \
|| sudo iptables -I DOCKER-USER 1 -j ECCM-CLUSTER
# Ответы на уже разрешенные соединения и на соединения, открытые контейнером самостоятельно.
sudo iptables -A ECCM-CLUSTER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Фильтрация только новых соединений к опубликованным портам (состояние DNAT)
sudo iptables -A ECCM-CLUSTER -m conntrack ! --ctstate DNAT -j RETURN
for eccm_node in "$MASTER_IP" "$SLAVE_IP"; do
# Redis Sentinel
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$REDIS_SENTINEL_PORT" -j ACCEPT
# RabbitMQ
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$AMQPS_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$EPMD_PORT" -j ACCEPT
sudo iptables -A ECCM-CLUSTER -p tcp -s "$eccm_node" --dport "$RABBITMQ_CLUSTER_PORT" -j ACCEPT
done
# PostgreSQL
for db_node in "$DB_MASTER_IP" "$DB_SLAVE_IP"; do
sudo iptables -A ECCM-CLUSTER -p tcp -s "$db_node" --dport "$DB_PORT" -j ACCEPT
done
# Опционально: журнал отброшенных соединений
sudo iptables -A ECCM-CLUSTER -m limit --limit 6/min --limit-burst 20 \
-j LOG --log-prefix "ECCM-FW: " --log-level 4
# Все остальное к опубликованным портам — отказать.
sudo iptables -A ECCM-CLUSTER -j DROP
# ---------- «петля»: контейнер обращается к своему же узлу ----------
# Нужно, если контейнер ходит в ЕССМ по адресу узла (ECCM_HOSTNAME), а не по имени сервиса.
# Docker не делает DNAT для «своего» моста, поэтому нужны оба правила ниже
for eccm_ifc in external internal docker0 br-+; do
sudo iptables -C INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -A INPUT -i "$eccm_ifc" -s 172.16.0.0/12 -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
done
sudo iptables -C ECCM-CLUSTER -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT 2>/dev/null \
|| sudo iptables -I ECCM-CLUSTER 3 -s 172.16.0.0/12 -m conntrack --ctstate DNAT -p tcp \
-m multiport --dports "$ECCM_SERVICE_PORTS" -j ACCEPT
# ---------- быстрое обнаружение отказа ----------
for eccm_peer in "$MASTER_IP" "$SLAVE_IP" "$DB_MASTER_IP" "$DB_SLAVE_IP"; do
sudo iptables -C INPUT -s "$eccm_peer" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset 2>/dev/null \
|| sudo iptables -A INPUT -s "$eccm_peer" -p tcp -m multiport \
--dports "$ECCM_SERVICE_PORTS" -j REJECT --reject-with tcp-reset
done
Примените правила на каждом сервере:
chmod +x iptables.sh
sudo ./iptables.sh
Для того чтобы правила сохранились после перезагрузки, можно использовать утилиту iptables-persistent (или любые другие доступные методы):
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Дополнительная защита сервера
Использование SSH-ключей вместо паролей
Замена доступа по паролям на доступ по генерируемым локальной машиной ключам обеспечивает повышенную безопасность данных.
Сгенерируйте SSH-ключи на локальной машине администратора ECCM:
ssh-keygen
Скопируйте публичный ключ администратора ~/.ssh/id_rsa.pub с локального хоста в файл, расположенный на хосте ECCM~/.ssh/authorized_keys:
...
PasswordAuthentication no # Запретить вход по паролю
PermitRootLogin no # Запретить вход root
PubkeyAuthentication yes # Разрешить вход по ключам
...
Перезапустите службу sshd:
sudo systemctl restart sshd
Использование Fail2ban
Fail2ban — программа для защиты серверов от brute-force атак, которая автоматически блокирует IP-адреса при множественных неудачных попытках входа по SSH.
Установка Fail2ban
В зависимости от типа ОС, выполните одну из следующих команд:
Dedian и Ubuntu
apt-get install fail2ban
Astra Linux
yum install fail2ban
Настройка конфигурационного файла
Создайте конфигурационный файл и настройте параметры по общим рекомендациям:
sudo vim /etc/fail2ban/ssh.conf
/etc/fail2ban/ssh.conf
[sshd]
# активируем правило
enabled = true
# Если Вы сменили порт SSH по умолчанию, замените 1234 на ваш новый порт
port = ssh,1234
## если в течение 1 часа:
findtime = 1h
## произведено 6 неудачных попыток логина:
maxretry = 6
## то банить IP на 2 часа:
bantime = 2h
# какие ip адреса игнорируются правилом
ignoreip = 127.0.0.1/8 23.34.45.56
sudo systemctl restart fail2ban
Данный набор условий означает, что IP-адрес, с которого было произведено 6 неудачных попыток SSH-подключения за последний час, будет заблокирован на 2 часа. Не будут блокироваться IP-адреса в диапазоне от 127.0.0.1 до 127.0.0.8 и адрес 23.34.45.56. Стоит обратить внимание, что в данном примере "/8" — не маска, а конечный адрес устройства.
Время для параметров findtime и bantime можно указывать не только в секундах, но и в минутах, часах, днях и даже неделях. Для этого необходимо сразу после численного значения параметра указать соответствующую букву (m, h, d, w).
Просмотр адресов
Команда для вывода на экран сведений о работе jail, отвечающего за службу sshd:
sudo fail2ban-client status sshd
С помощью данной команды можно посмотреть список заблокированных IP-адресов.
Если в данный момент машина не подвергается атаке, сразу после установки и запуска программы на экране будет отображена следующая информация:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
Разблокировка адресов
IP-адреса, которые попали в бан:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list: 192.168.х.х
Чтобы разблокировать IP-адрес, который попал в бан (например, 192.168.х.х), используйте следующую команду:
sudo fail2ban-client unban 192.168.x.x
Чтобы разблокировать все адреса, которые попали в бан, используйте следующую команду:
sudo fail2ban-client unban --all
Чтобы разблокировать IP-адрес из jail sshd, используйте следующую команду: