Настройка сетевой инфраструктуры на ALT Linux

Справочник по настройке маршрутизации, VLAN, GRE-туннелей, NAT, динамической маршрутизации (OSPF), DHCP и DNS на ALT Linux. Каждый раздел содержит краткое пояснение и пример готовой конфигурации для соответствующего узла сети.

Адреса, маски подсетей, имена интерфейсов и доменные имена в примерах относятся к учебному стенду. При настройке подставляйте значения своей схемы.

1-й этап. Настройка узлов сети: маршрутизаторы и серверы

Ниже — учебный вариант (домен linux-skills.irpo, VLAN 110/120/888, пользователи net_mgr / srv_user). В официальном задании ДЭ значения другие, меняются только переменные в блоках «0. Подготовка переменных»: домен au-team.irpo; VLAN 100 (HQ-SRV, сеть не более 32 адресов → /27), VLAN 200 (HQ-CLI, не более 16 → /28), VLAN 999 (управление, не более 8 → /29); сеть в сторону BR-SRV не более 16 адресов (/28); стык BR-FW—BR-RTR с минимальной маской (/30); GRE из 10.10.10.0/24 с минимальной маской (10.10.10.0/30); ISP: 172.16.1.0/28 к HQ-RTR и 172.16.2.0/28 к BR-RTR; net_admin / P@ssw0rd на маршрутизаторах; sshuser с UID 2027, порт SSH 2027, пароль P@ssw0rd; пароль OSPF P@ssw0rd (MD5); записи DNS: docker.au-team.irpo → интерфейс ISP к HQ-RTR, web.au-team.irpo → интерфейс ISP к BR-RTR; PTR обязательны для hq-srv и br-srv.

Граничный маршрутизатор

Граничный маршрутизатор на стыке с внешней сетью: получает адрес от вышестоящего провайдера и выполняет трансляцию адресов (NAT) для внутренних подсетей.

0. Подготовка переменных

Экспортируйте переменные среды перед выполнением команд настройки узла:

Переменные конфигурации
int_internet="enp7s1"
int_hq_rtr="enp7s2"
int_br_rtr="enp7s3"

ip_hq_rtr="172.20.1.1"
mask_hq_rtr="28"

ip_br_rtr="172.20.2.1"
mask_br_rtr="28"

I. Идентификация хоста и времени

Имя хоста идентифицирует узел в сети. Вызов exec bash в конце раздела нужен, чтобы новое имя сразу отобразилось в приглашении (после него переменные придётся объявить заново).

Пример конфигурации
hostnamectl hostname isp
timedatectl set-timezone Europe/Moscow

II. Включение маршрутизации (IP Forwarding)

Параметр ядра net.ipv4.ip_forward включает пересылку IPv4-пакетов.

Пример конфигурации
cd /etc/net/
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' sysctl.conf

III. Подготовка шаблонов интерфейсов

Копирование каталогов etcnet для создания конфигураций новых интерфейсов на основе шаблона.

Пример конфигурации
cd ifaces/
\cp -R $int_internet $int_hq_rtr
\cp -R $int_hq_rtr $int_br_rtr

IV. Настройка режимов BOOTPROTO и IPv4-адресов

Конфигурирование статических адресов и DHCP-клиента на интерфейсах.

Пример конфигурации
cat << EOF > /etc/net/ifaces/$int_internet/options
BOOTPROTO=dhcp
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=dhcp4
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_hq_rtr/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_br_rtr/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

echo "$ip_hq_rtr/$mask_hq_rtr" > $int_hq_rtr/ipv4address
echo "$ip_br_rtr/$mask_br_rtr" > $int_br_rtr/ipv4address

systemctl restart network

enp7s1 > DHCP (uplink к провайдеру)

enp7s2, enp7s3 > static (downlink к роутерам площадок)

V. Скачивание nano, iptables

Пример конфигурации
apt-get update && apt-get install -y nano
apt-get install -y iptables

VI. Применение сетевых настроек и NAT

Пример конфигурации
systemctl restart network
iptables -t nat -A POSTROUTING -o $int_internet -j MASQUERADE
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

exec bash

Маршрутизатор площадки A

Маршрутизатор площадки A: терминирует VLAN пользователей и серверов, поднимает GRE-туннель до второй площадки, распространяет маршруты по OSPF и выдаёт адреса по DHCP.

0. Подготовка переменных

Переменные конфигурации
domain="linux-skills.irpo"

username="net_mgr"
userpassword="Mgr@P@ss88"

int_name_default_gateway="enp7s1"
int_name_vlan_slave="enp7s2"

int_name_vlan_hq_srv="enp7s2.110"
int_name_vlan_hq_cli="enp7s2.120"
int_name_vlan_remote="enp7s2.888"

ip_isp="172.20.1.2"
mask_isp="28"

ip_gateway="172.20.1.1"

# Адреса самого HQ-RTR в VLAN (шлюзы для HQ-SRV и HQ-CLI)
ip_vlan_hq_srv="192.168.110.1"
mask_hq_srv="26"
vlan_id_hq_srv="110"

ip_vlan_hq_cli="192.168.120.1"
mask_hq_cli="24"
vlan_hq_cli="120"

ip_remote="192.168.88.1"
mask_remote="28"
vlan_remote="888"

# Сервер HQ-SRV (DNS для площадки)
ip_hq_srv="192.168.110.2"

ip_br_rtr="172.20.2.2"

dhcp_subnet="192.168.120.0"
dhcp_netmask="255.255.255.0"
dhcp_ip_range_start="192.168.120.2"
dhcp_ip_range_end="192.168.120.12"

I. Идентификация хоста и времени

Пример конфигурации
hostnamectl hostname hq-rtr.$domain
timedatectl set-timezone Europe/Moscow

II. Включение маршрутизации (IP Forwarding)

Пример конфигурации
cd /etc/net/
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' sysctl.conf

III. Подготовка шаблонов интерфейсов

Пример конфигурации
cd ifaces/
\cp -R $int_name_default_gateway $int_name_vlan_slave
\cp -R $int_name_default_gateway $int_name_vlan_hq_srv
\cp -R $int_name_default_gateway $int_name_vlan_hq_cli
\cp -R $int_name_default_gateway $int_name_vlan_remote
\cp -R $int_name_default_gateway gre10

IV. Настройка IPv4-адресов и маршрутов

Пример конфигурации
cat << EOF > /etc/net/ifaces/$int_name_default_gateway/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_name_vlan_hq_srv/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_name_vlan_hq_cli/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_name_vlan_remote/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/gre10/options
BOOTPROTO=static
SYSTEMD_BOOTPROTO=static
TYPE=iptun
TUNTYPE=gre
CONFIG_WIRELESS=no
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
TUNLOCAL=$ip_isp
TUNREMOTE=$ip_br_rtr
TUNTTL=32
TUNOPTIONS='ttl 32'
EOF

echo "$ip_isp/$mask_isp" > $int_name_default_gateway/ipv4address
echo "default via $ip_gateway" > $int_name_default_gateway/ipv4route

echo "$ip_vlan_hq_srv/$mask_hq_srv" > $int_name_vlan_hq_srv/ipv4address
echo "$ip_vlan_hq_cli/$mask_hq_cli" > $int_name_vlan_hq_cli/ipv4address
echo "$ip_remote/$mask_remote" > $int_name_vlan_remote/ipv4address

echo "10.0.0.1/30" > gre10/ipv4address

V. Настройка VLAN-интерфейсов

Пример конфигурации
echo "HOST=$int_name_vlan_slave" >> $int_name_vlan_hq_srv/options
echo "HOST=$int_name_vlan_slave" >> $int_name_vlan_hq_cli/options
echo "HOST=$int_name_vlan_slave" >> $int_name_vlan_remote/options

echo "VID=$vlan_id_hq_srv" >> $int_name_vlan_hq_srv/options
echo "VID=$vlan_hq_cli" >> $int_name_vlan_hq_cli/options
echo "VID=$vlan_remote" >> $int_name_vlan_remote/options

sed -i 's/TYPE=eth/TYPE=vlan/g' $int_name_vlan_hq_srv/options
sed -i 's/TYPE=eth/TYPE=vlan/g' $int_name_vlan_hq_cli/options
sed -i 's/TYPE=eth/TYPE=vlan/g' $int_name_vlan_remote/options

echo "nameserver 77.88.8.8" > /etc/resolv.conf
echo "nameserver 77.88.8.8" > /etc/net/ifaces/$int_name_default_gateway/resolv.conf

VI. Применяем сетевые настройки

Пример конфигурации
systemctl restart network

VII. Установка и настройка динамической маршрутизации (FRR / OSPF), nano и iptables

Пример конфигурации
apt-get update
apt-get install -y frr
apt-get install -y dhcp-server
apt-get install -y sudo
apt-get install -y nano
apt-get install -y iptables
sed -i 's/ospfd=no/ospfd=yes/g' /etc/frr/daemons
systemctl enable --now frr

VIII. Создание пользователей

Пример конфигурации
useradd -m $username
echo "$username:$userpassword" | chpasswd
usermod -aG wheel $username
echo "$username ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers

IX. Настройка NAT

Пример конфигурации
iptables -t nat -A POSTROUTING -o $int_name_default_gateway -j MASQUERADE
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

X. Настройка DNS-резолвера

Пример конфигурации
cat << EOF > /etc/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

cat << EOF > /etc/net/ifaces/$int_name_default_gateway/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

XI. Конфигурация OSPF через vtysh

vtysh — отдельная оболочка, переменные bash в ней не работают: все значения вписываются буквально. Если команда no ip ospf passive не принимается (старый FRR), используйте вместо неё no passive-interface gre10 внутри router ospf.

Пример конфигурации
vtysh
conf t
interface gre10
ip ospf network point-to-point
ip ospf message-digest-key 1 md5 Mgr@P@ss88
ip ospf authentication message-digest
no ip ospf passive
exit
!
router ospf
passive-interface default
network 10.0.0.0/30 area 0
network 192.168.88.0/28 area 0
network 192.168.110.0/26 area 0
network 192.168.120.0/24 area 0
exit
exit
wr
exit

XII. Настройка DHCP-сервера

Шлюз — адрес HQ-RTR в VLAN клиентов; сам он в диапазон выдачи не входит (диапазон начинается со следующего адреса).

Пример конфигурации
cat << EOF >  /etc/dhcp/dhcpd.conf
ddns-update-style none;

subnet $dhcp_subnet netmask $dhcp_netmask {
       option routers                   $ip_vlan_hq_cli;
       option subnet-mask              $dhcp_netmask;

       option domain-name               "$domain";
       option domain-name-servers       $ip_hq_srv;

       range dynamic-bootp $dhcp_ip_range_start $dhcp_ip_range_end;
       default-lease-time 21600;
       max-lease-time 43200;
}
EOF

echo "DHCPDARGS=$int_name_vlan_hq_cli" > /etc/sysconfig/dhcpd
systemctl enable --now dhcpd

systemctl status dhcpd

exec bash

Межсетевой экран площадки B (BR-FW)

Отдельный узел на ALT Linux между BR-RTR и локальной сетью площадки: разделяет FW-NET и BR-NET, маршрутизирует транзит и участвует в OSPF со стороны маршрутизатора.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен и часовой пояс (те же, что на остальных узлах 1-го этапа)
domain="linux-skills.irpo"
tz="Europe/Moscow"

# Интерфейсы — уточните имена командой: ip -br a
int_to_rtr="enp7s1"
int_to_srv="enp7s2"

# FW-NET — стык с BR-RTR, минимальная маска: /30 = ровно два адреса узлов
ip_fw_to_rtr="192.168.3.2"
ip_rtr_to_fw="192.168.3.1"
mask_p2p="30"
net_p2p="192.168.3.0/30"

# BR-NET — локальная сеть площадки B (не более 16 адресов)
ip_fw_to_srv="192.168.4.1"
mask_br="28"
net_br="192.168.4.0/28"
ip_br_srv="192.168.4.2"

# DNS — в этой роли выступает сервер площадки A
ip_hq_srv="192.168.110.2"

# OSPF
ospf_router_id="77.7.7.7"

I. Очистка клонированной машины (если разворачиваете из копии)

Выполняйте только на копии, не на доноре. Стираются сетевые настройки, конфигурация маршрутизации, правила фильтрации и идентификаторы, которые не должны совпадать у двух машин.

Пример конфигурации
# Службы, доставшиеся от донора
systemctl disable --now frr dhcpd nftables 2>/dev/null || true
systemctl disable --now iptables.service 2>/dev/null || true

# Правила фильтрации и трансляции
iptables -F; iptables -X
iptables -t nat -F; iptables -t nat -X
iptables -t mangle -F; iptables -t mangle -X
iptables -P INPUT ACCEPT; iptables -P FORWARD ACCEPT; iptables -P OUTPUT \
  ACCEPT
\rm -f /etc/sysconfig/iptables /etc/nftables.conf

# Конфигурация маршрутизации
\rm -f /etc/frr/frr.conf /etc/frr/zebra.conf /etc/frr/ospfd.conf \
  /etc/frr/ripd.conf
sed -i 's/^\([a-z0-9]*\)=yes/\1=no/' /etc/frr/daemons 2>/dev/null || true

# Описания интерфейсов etcnet, кроме служебных
cd /etc/net/ifaces
for d in *; do
  case "$d" in lo|default|unknown) continue ;; esac
  \rm -rf "$d"
done
cd /

# Резолвер и арендованные адреса
\rm -f /etc/resolv.conf
\rm -rf /var/lib/dhcp/dhcpd/state/* 2>/dev/null || true

# Идентификаторы, которые обязаны различаться
\rm -f /etc/machine-id && systemd-machine-id-setup
\rm -f /etc/openssh/ssh_host_* /etc/ssh/ssh_host_* 2>/dev/null || true
ssh-keygen -A
\rm -f /root/.ssh/known_hosts
\rm -f /etc/udev/rules.d/70-persistent-net.rules

# Журналы и история
: > /root/.bash_history
journalctl --rotate && journalctl --vacuum-time=1s

reboot

II. Имя хоста и часовой пояс

Пример конфигурации
hostnamectl set-hostname br-fw.$domain
timedatectl set-timezone $tz

ip -br a

III. Настройка интерфейсов

Стык с маршрутизатором — /30: в такой подсети ровно два адреса узлов и оба назначаются (/28 дал бы 14 адресов и не был бы «минимально возможной маской»). Маршрут по умолчанию ведёт на маршрутизатор. Файл резолвера пишется и в каталог интерфейса: etcnet при перезапуске сети подставляет оттуда свою копию.

Пример конфигурации
mkdir -p /etc/net/ifaces/$int_to_rtr /etc/net/ifaces/$int_to_srv

cat <<EOF > /etc/net/ifaces/$int_to_rtr/options
TYPE=eth
DISABLED=no
BOOTPROTO=static
SYSTEMD_BOOTPROTO=static
CONFIG_IPV4=yes
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

echo "$ip_fw_to_rtr/$mask_p2p" > /etc/net/ifaces/$int_to_rtr/ipv4address
echo "default via $ip_rtr_to_fw" > /etc/net/ifaces/$int_to_rtr/ipv4route

cat <<EOF > /etc/net/ifaces/$int_to_srv/options
TYPE=eth
DISABLED=no
BOOTPROTO=static
SYSTEMD_BOOTPROTO=static
CONFIG_IPV4=yes
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

echo "$ip_fw_to_srv/$mask_br" > /etc/net/ifaces/$int_to_srv/ipv4address

# Временный резолвер — нужен для apt-get на следующем шаге
echo "nameserver 77.88.8.8" > /etc/resolv.conf
echo "nameserver 77.88.8.8" > /etc/net/ifaces/$int_to_rtr/resolv.conf

systemctl restart network
ip -4 -br a

IV. Настройка DNS-резолвера

Файл пишется дважды намеренно: etcnet при перезапуске сети подставляет свою копию из каталога интерфейса и затирает корневой /etc/resolv.conf.

Пример конфигурации
apt-get update
apt-get install -y iptables
apt-get install -y frr

cat <<EOF > /etc/resolv.conf
search $domain
nameserver $ip_hq_srv
EOF

cat <<EOF > /etc/net/ifaces/$int_to_rtr/resolv.conf
search $domain
nameserver $ip_hq_srv
EOF

systemctl restart network
cat /etc/resolv.conf

V. Включение маршрутизации (IP Forwarding)

Параметр задаётся в двух местах намеренно: etcnet применяет собственный sysctl.conf при каждом перезапуске сети и может вернуть значение обратно.

Пример конфигурации
cat <<EOF > /etc/sysctl.d/99-router.conf
net.ipv4.ip_forward = 1
EOF

sed -i -E 's/^#?net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/' \
  /etc/net/sysctl.conf

sysctl --system
sysctl net.ipv4.ip_forward

VI. Политика фильтрации (без NAT)

NAT на BR-FW не нужен и вреден: сеть BR-NET анонсируется по OSPF, а маскарад скрыл бы реальные адреса BR-SRV от площадки A (Ansible, домен). По заданию динамическая трансляция настраивается только на HQ-RTR и BR-RTR. Здесь достаточно разрешающей политики транзита и сохранения правил.

Пример конфигурации
iptables -P FORWARD ACCEPT
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

VII. Установка и запуск FRR

Демон ospfd по умолчанию выключен; без zebra маршруты не попадают в ядро.

Пример конфигурации
sed -i 's/^zebra=no/zebra=yes/' /etc/frr/daemons
sed -i 's/^ospfd=no/ospfd=yes/' /etc/frr/daemons

systemctl enable --now frr
systemctl is-active frr

VIII. Конфигурация OSPF

Соседство поднимается только на интерфейсе к маршрутизатору: остальные объявлены пассивными. Сеть в сторону сервера анонсируется, но соседей там не ищет. Внутри vtysh переменные bash не работают, но здесь команды передаются через heredoc без кавычек у EOF — подстановку делает bash ещё до запуска vtysh, поэтому переменные можно использовать. Со стороны BR-RTR интерфейс к BR-FW тоже должен быть не пассивным и его сеть объявлена в OSPF (см. раздел BR-RTR), иначе соседство не поднимется.

Пример конфигурации
vtysh <<EOF
configure terminal
interface $int_to_rtr
 no ip ospf passive
exit
router ospf
 ospf router-id $ospf_router_id
 passive-interface default
 network $net_p2p area 0
 network $net_br area 0
exit
end
write memory
EOF

vtysh -c 'show running-config' | head -20

IX. Проверка

Соседство поднимется только после настройки BR-RTR — до этого список соседей пуст, и это не ошибка. Состояние Full означает, что смежность установлена. Если пусто — смотрите, поднят ли интерфейс, совпадают ли area и маска на обоих концах.

Пример конфигурации
ip -4 -br a
ip route
sysctl net.ipv4.ip_forward

vtysh -c 'show ip ospf neighbor'
vtysh -c 'show ip route ospf'

ping -c2 $ip_rtr_to_fw
ping -c2 $ip_br_srv

getent ahostsv4 hq-srv.$domain

Маршрутизатор площадки B

Маршрутизатор площадки B: подключается к площадке A через GRE-туннель и обменивается маршрутами по OSPF. Внутренний интерфейс смотрит на BR-FW (стык /30, см. раздел межсетевого экрана); сеть BR-SRV приходит по OSPF от BR-FW, поэтому на стыке с BR-FW OSPF не пассивный и без MD5 (на BR-FW аутентификация по заданию не требуется).

0. Подготовка переменных

Переменные конфигурации
domain="linux-skills.irpo"

username="net_mgr"
userpassword="Mgr@P@ss88"

int_name_default_gateway="enp7s1"
int_name_br_fw="enp7s2"

ip_isp="172.20.2.2"
mask_isp="28"

ip_gateway="172.20.2.1"

# Стык с BR-FW — те же значения, что ip_rtr_to_fw / net_p2p в разделе BR-FW
ip_to_br_fw="192.168.3.1"
mask_to_br_fw="30"

ip_hq_srv="192.168.110.2"

ip_hq_rtr="172.20.1.2"

I. Идентификация хоста и времени

Пример конфигурации
hostnamectl hostname br-rtr.$domain
timedatectl set-timezone Europe/Moscow

II. Включение маршрутизации (IP Forwarding)

Пример конфигурации
cd /etc/net/
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' sysctl.conf
cd ifaces/

III. Подготовка шаблонов интерфейсов

Пример конфигурации
\cp -R $int_name_default_gateway $int_name_br_fw
\cp -R $int_name_default_gateway gre10

IV. Настройка IPv4-адресов и маршрутов

Пример конфигурации
cat << EOF > /etc/net/ifaces/$int_name_default_gateway/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/$int_name_br_fw/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

cat << EOF > /etc/net/ifaces/gre10/options
BOOTPROTO=static
SYSTEMD_BOOTPROTO=static
TYPE=iptun
TUNTYPE=gre
CONFIG_WIRELESS=no
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
TUNLOCAL=$ip_isp
TUNREMOTE=$ip_hq_rtr
TUNTTL=32
TUNOPTIONS='ttl 32'
EOF

echo "$ip_isp/$mask_isp" > $int_name_default_gateway/ipv4address
echo "default via $ip_gateway" > $int_name_default_gateway/ipv4route

echo "$ip_to_br_fw/$mask_to_br_fw" > $int_name_br_fw/ipv4address

echo "10.0.0.2/30" > gre10/ipv4address

V. Настраиваем временный DNS-резолвер

Пример конфигурации
echo "nameserver 77.88.8.8" > /etc/resolv.conf
echo "nameserver 77.88.8.8" > /etc/net/ifaces/$int_name_default_gateway/resolv.conf

VI. Установка и настройка динамической маршрутизации (FRR / OSPF), nano и iptables

Пример конфигурации
systemctl restart network
apt-get update
apt-get install -y frr
apt-get install -y sudo
apt-get install -y nano
apt-get install -y iptables
sed -i 's/ospfd=no/ospfd=yes/g' /etc/frr/daemons
systemctl enable --now frr

VII. Создание пользователей

Пример конфигурации
useradd -m $username
echo "$username:$userpassword" | chpasswd
usermod -aG wheel $username
echo "$username ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers

VIII. Настройка DNS-резолвера

Пример конфигурации
cat << EOF > /etc/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

cat << EOF > /etc/net/ifaces/$int_name_default_gateway/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

IX. Настройка NAT

Пример конфигурации
iptables -t nat -A POSTROUTING -o $int_name_default_gateway -j MASQUERADE
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

X. Применяем сетевые настройки

Пример конфигурации
systemctl restart network

XI. Конфигурация OSPF через vtysh

Внутри vtysh переменные bash не работают — все значения вписаны буквально. Имя интерфейса к BR-FW — из переменной int_name_br_fw.

Пример конфигурации
vtysh
conf t
interface gre10
ip ospf network point-to-point
ip ospf message-digest-key 1 md5 Mgr@P@ss88
ip ospf authentication message-digest
no ip ospf passive
exit
interface enp7s2
no ip ospf passive
exit
!
router ospf
passive-interface default
network 10.0.0.0/30 area 0
network 192.168.3.0/30 area 0
exit
exit
wr
exit

exec bash

Сервер площадки A

Сервер площадки A: выполняет роль внутреннего DNS-сервера (dnsmasq) для домена сети и настроен на защищённый SSH-доступ.

0. Подготовка переменных

Переменные конфигурации
ssh_username="srv_user"
ssh_uid="2200"
ssh_userpassword="Srv@P@ss456"
ssh_port="2030"

int_to_hq_rtr="enp7s1"
ip_to_hq_rtr="192.168.110.2"
mask_hq_srv="26"

ip_default_gateway="192.168.110.1"

domain="linux-skills.irpo"

# Публикуемые имена на ISP по таблице задания: docker → интерфейс ISP к HQ-RTR,
# web → интерфейс ISP к BR-RTR (легко перепутать — сверяйтесь с таблицей DNS)
name_isp_hq="docker"
ip_isp_hq="172.20.1.1"
name_isp_br="web"
ip_isp_br="172.20.2.1"

# HQ-RTR (адрес в VLAN серверов = ip_default_gateway)
ip_hq_rtr_to_isp="172.20.1.2"
ip_hq_rtr_to_hq_cli="192.168.120.1"
ip_hq_rtr_to_remote="192.168.88.1"
ip_hq_cli="192.168.120.2"

# BR-RTR, BR-FW, BR-SRV — значения из разделов маршрутизатора и межсетевого экрана площадки B
ip_br_rtr_isp="172.20.2.2"
ip_br_rtr_fw="192.168.3.1"
ip_br_fw_rtr="192.168.3.2"
ip_br_fw_srv="192.168.4.1"
ip_br_srv="192.168.4.2"

I. Идентификация хоста и времени

Пример конфигурации
hostnamectl hostname hq-srv.$domain
timedatectl set-timezone Europe/Moscow

II. Настройка сетевого интерфейса и DNS-резолвера

Пример конфигурации
cd /etc/net/ifaces/

cat << EOF > /etc/net/ifaces/$int_to_hq_rtr/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

echo "$ip_to_hq_rtr/$mask_hq_srv" > $int_to_hq_rtr/ipv4address
echo "default via $ip_default_gateway" > $int_to_hq_rtr/ipv4route
echo "nameserver 77.88.8.8" > /etc/resolv.conf
echo "nameserver 77.88.8.8" > /etc/net/ifaces/$int_to_hq_rtr/resolv.conf

systemctl restart network

III. Установка + создание всего конфига dnsmasq

Пример конфигурации
apt-get update
apt-get install -y sudo
apt-get install -y nano
apt-get install -y openssh-server
apt-get install -y dnsmasq
apt-get install -y iptables

cat << EOF > /etc/dnsmasq.conf
no-hosts
no-resolv
server=77.88.8.8
cache-size=1000
no-negcache
interface=*
domain=$domain
local=/$domain/
host-record=$name_isp_hq.$domain,$ip_isp_hq
host-record=$name_isp_br.$domain,$ip_isp_br
host-record=hq-rtr.$domain,$ip_hq_rtr_to_isp
host-record=hq-rtr.$domain,$ip_default_gateway
host-record=hq-rtr.$domain,$ip_hq_rtr_to_hq_cli
host-record=hq-rtr.$domain,$ip_hq_rtr_to_remote
host-record=hq-srv.$domain,$ip_to_hq_rtr
host-record=hq-cli.$domain,$ip_hq_cli
host-record=br-rtr.$domain,$ip_br_rtr_isp
host-record=br-rtr.$domain,$ip_br_rtr_fw
host-record=br-fw.$domain,$ip_br_fw_rtr
host-record=br-fw.$domain,$ip_br_fw_srv
host-record=br-srv.$domain,$ip_br_srv
EOF

dnsmasq --test

IV. Настройка безопасного SSH-доступа

Пример конфигурации
useradd $ssh_username -m -u $ssh_uid
echo "$ssh_username:$ssh_userpassword" | chpasswd
gpasswd -a $ssh_username wheel
echo "$ssh_username ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers

cat << EOF >> /etc/openssh/sshd_config
port $ssh_port
MaxAuthTries 2 
AllowUsers $ssh_username
Banner /etc/openssh/banner
EOF

cat << EOF > /etc/openssh/banner
................................
... Authorized access only ...
................................
EOF

sshd -t
systemctl enable --now sshd
systemctl restart sshd

V (опционально). Поиск конфликтных процессов, использующих 53 порт

Пример конфигурации
ss -tlpn | grep :53

VI. Добавляем службу в автозапуск

Пример конфигурации
systemctl enable --now dnsmasq.service

VII (опционально). Убиваем процесс, который использует 53 порт

Пример конфигурации
kill <PID из вывода ss>

VIII. Смотрим статус службы dnsmasq

Пример конфигурации
systemctl status dnsmasq

IX. Синхронизация часового пояса (доп. проверка)

Пример конфигурации
timedatectl set-timezone Europe/Moscow
timedatectl

exec bash

Сервер площадки B

Сервер площадки B: базовая сетевая настройка и защищённый SSH-доступ.

0. Подготовка переменных

Переменные конфигурации
domain="linux-skills.irpo"

ssh_username="srv_user"
ssh_uid="2200"
ssh_userpassword="Srv@P@ss456"
ssh_port="2030"

# Сеть BR-NET и шлюз — те же, что net_br / ip_fw_to_srv в разделе BR-FW
int_br_srv="enp7s1"
ip_br_srv="192.168.4.2"
mask_br_srv="28"

ip_default_gateway="192.168.4.1"

ip_hq_srv="192.168.110.2"

I. Идентификация хоста и времени

Пример конфигурации
hostnamectl hostname br-srv.$domain
timedatectl set-timezone Europe/Moscow

II. Настройка сетевого интерфейса и DNS-резолвера

Пример конфигурации
cd /etc/net/ifaces/

cat << EOF > /etc/net/ifaces/$int_br_srv/options
BOOTPROTO=static
TYPE=eth
CONFIG_WIRELESS=no
SYSTEMD_BOOTPROTO=static
CONFIG_IPv4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
EOF

echo "$ip_br_srv/$mask_br_srv" > $int_br_srv/ipv4address
echo "default via $ip_default_gateway" > $int_br_srv/ipv4route

cat << EOF > /etc/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

cat << EOF > /etc/net/ifaces/$int_br_srv/resolv.conf
nameserver $ip_hq_srv
search $domain
domain $domain
EOF

systemctl restart network

III. Настройка безопасного SSH-доступа

Пример конфигурации
useradd $ssh_username -m -u $ssh_uid
echo "$ssh_username:$ssh_userpassword" | chpasswd
gpasswd -a $ssh_username wheel
echo "$ssh_username ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers

cat << EOF >> /etc/openssh/sshd_config
port $ssh_port
MaxAuthTries 2 
AllowUsers $ssh_username
Banner /etc/openssh/banner
EOF

cat << EOF > /etc/openssh/banner
................................
... Authorized access only ...
................................
EOF

sshd -t
systemctl enable --now sshd
systemctl restart sshd

exec bash

1-й этап. Диагностика и проверка конфигурации

Блок 0. Сквозной smoke-тест и MTU

Базовая проверка доступности узлов от самой дальней точки (br-srv) до целевых серверов строго по IP. Тест MTU ловит «чёрные дыры» фрагментации в GRE-туннеле.

Команды проверки
# Последовательный пинг от br-srv (самая дальняя точка):
ping -c2 192.168.4.1        # свой шлюз (br-fw)
ping -c2 192.168.3.1        # br-rtr со стороны br-fw
ping -c2 10.0.0.1           # дальний конец туннеля (hq-rtr)
ping -c2 192.168.110.1      # шлюз серверной VLAN на HQ
ping -c2 192.168.110.2      # hq-srv — цель

# Проверка MTU через туннель (GRE съедает 24 байта: MTU gre10 = 1476):
ping -M do -s 1448 -c2 192.168.110.2   # 1448+28=1476 — ДОЛЖНО пройти
ping -M do -s 1472 -c2 192.168.110.2   # 1472+28=1500 — ДОЛЖНО НЕ пройти (Frag needed)

Блок 1. Граничный маршрутизатор (ISP) — NAT и форвардинг

Команды проверки
ip -br a            # enp7s1 — адрес от DHCP; enp7s2 172.20.1.1/28; enp7s3 172.20.2.1/28; все UP
iptables -t nat -nvL POSTROUTING           # MASQUERADE на out enp7s1, счётчики растут
cat /proc/sys/net/ipv4/ip_forward          # 1 (в рантайме)
grep ip_forward /etc/net/sysctl.conf       # = 1, без # (постоянность!)

Блок 2. Маршрутизатор площадки A (hq-rtr) — VLAN

Команды проверки
cat /etc/net/ifaces/enp7s2.110/options
cat /etc/net/ifaces/enp7s2.110/ipv4address

cat /etc/net/ifaces/enp7s2.120/options
cat /etc/net/ifaces/enp7s2.120/ipv4address

cat /etc/net/ifaces/enp7s2.888/options
cat /etc/net/ifaces/enp7s2.888/ipv4address

Блок 3. Маршрутизатор площадки B (br-rtr) — GRE и OSPF

Команды проверки
cat /etc/net/ifaces/gre10/options
cat /etc/net/ifaces/gre10/ipv4address
vtysh -c "show ip route ospf"

Блок 4. DHCP-сервер (hq-rtr, VLAN 120)

Команды проверки
dhcpd -t                                 # Проверка синтаксиса dhcpd.conf
systemctl status dhcpd                   # active (running)
grep DHCPDARGS /etc/sysconfig/dhcpd      # DHCPDARGS=enp7s2.120 (привязка к VLAN!)
journalctl -u dhcpd --no-pager -n 30     # DHCPDISCOVER/OFFER/ACK при запросах

Блок 5. DNS-сервер (hq-srv) — dnsmasq

Команды проверки
dnsmasq --test                           # Проверка синтаксиса dnsmasq.conf
systemctl status dnsmasq                 # active (running)
ss -tulpn | grep :53                     # dnsmasq слушает 53 (udp и tcp)

# Прямые записи домена:
nslookup hq-rtr.linux-skills.irpo 127.0.0.1   # 192.168.110.1 (и остальные адреса hq-rtr)
nslookup br-srv.linux-skills.irpo 127.0.0.1   # 192.168.4.2
nslookup hq-cli.linux-skills.irpo 127.0.0.1   # 192.168.120.2

# Обратные записи (PTR обязательны для hq-srv и br-srv):
nslookup 192.168.110.2 127.0.0.1         # hq-srv.linux-skills.irpo
nslookup 192.168.4.2 127.0.0.1           # br-srv.linux-skills.irpo

# Форвардинг наружу:
nslookup ya.ru 127.0.0.1                 # пересылка на 77.88.8.8 работает

Блок 6. SSH и безопасность (Hardening)

Команды проверки
sshd -t                                  # Проверка синтаксиса sshd_config
grep -E "^port|MaxAuthTries|AllowUsers|Banner" /etc/openssh/sshd_config
# Ожидаемо: port 2030 / MaxAuthTries 2 / AllowUsers srv_user / Banner /etc/openssh/banner

systemctl status sshd                    # active
ss -tlpn | grep 2030                     # слушает 2030

# Тест входа с клиента:
ssh -p 2030 srv_user@192.168.110.2       # должен показать баннер и запросить пароль

Блок 7. Сквозные «грабли» и постоянность настроек

Команды проверки
# MSS-клампинг (ловит "зависание" TCP при работающем пинге)
iptables -t mangle -nvL FORWARD | grep TCPMSS

# Проверка синтаксиса сохранённых правил iptables (перед загрузкой/рестартом)
iptables-restore --test < /etc/sysconfig/iptables

# Постоянность форвардинга на всех роутерах
grep ip_forward /etc/net/sysctl.conf     # = 1, без #

# Постоянность resolv.conf на роутерах (защита от затирания etcnet)
ls /etc/net/ifaces/enp7s1/resolv.conf     # должен существовать

# Reverse Path Filtering
sysctl net.ipv4.conf.all.rp_filter       # 0 или 2 — ок; 1 (strict) может резать асимметрию

НАСТРОЙКА RIP (запасной вариант вместо OSPF, без скачивания пакетов)

В FRR нет отдельных юнитов zebra/ripd — демон включается в /etc/frr/daemons, после чего перезапускается служба frr. Сети впишите свои (пример для hq-rtr).

Команды проверки
sed -i 's/ripd=no/ripd=yes/' /etc/frr/daemons
systemctl enable --now frr
systemctl restart frr

vtysh

configure terminal

router rip
version 2

network 10.0.0.0/30
network 192.168.110.0/26
network 192.168.120.0/24
network 192.168.88.0/28

passive-interface default
no passive-interface gre10

exit
exit

write memory

exit

ОСНОВНЫЕ ПАРАМЕТРЫ

Справочник значений
доменное имя - linux-skills.irpo

доменное имя isp (hq-rtr) - web
доменное имя isp (br-rtr) - docker

сеть hq-rtr - 172.20.1.0/28
сеть br-rtr - 172.20.2.0/28

в сторону hq-srv (vlan 110) 192.168.110.0/26
в сторону hq-cli (vlan 120) 192.168.120.0/24
в сторону просто vlan (vlan 888) 192.168.88.0/28

GRE hq-rtr — br-rtr 10.0.0.0/30
стык br-rtr — br-fw 192.168.3.0/30
в сторону br-srv (за br-fw) 192.168.4.0/28

пользователь rtr - net_mgr
пароль rtr - Mgr@P@ss88

пользователь ssh - srv_user
uid пользователя ssh - 2200
пароль ssh - Srv@P@ss456
порт ssh - 2030

2-й этап. Организация сетевого администрирования

Контроллер домена Samba, файловое хранилище RAID0 и NFS, служба точного времени, Ansible, контейнеризованное приложение, веб-сервер с базой данных и статическая трансляция портов.

ISP — служба точного времени

ISP выступает сервером времени для обеих площадок и объявляет себя как stratum 5.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Служба точного времени
ntp_upstream="pool.ntp.org"
ntp_stratum="5"

I. Установка и настройка chrony

Директива local stratum позволяет раздавать время даже при недоступности вышестоящего источника.

Пример конфигурации
apt-get update && apt-get install -y chrony
apt-get install -y iptables

cat <<EOF > /etc/chrony.conf
server $ntp_upstream iburst prefer minstratum 4
local stratum $ntp_stratum
allow 0.0.0.0/0
EOF

systemctl enable --now chronyd
systemctl restart chronyd

II. Проверка источников

Пример конфигурации
chronyc sources -v
chronyc tracking

HQ-RTR — статическая трансляция портов

Публикация веб-приложения и SSH сервера HQ-SRV на внешнем адресе маршрутизатора.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Внешний адрес самого маршрутизатора
ip_hq_rtr="172.16.1.10"

# Публикуемый узел
ip_hq_srv="192.168.1.10"

# Порты
app_port="8080"
web_port="80"
ssh_port="2027"

# Маршрут до локальной сети площадки B через GRE
net_br="192.168.4.0/28"
ip_gre_br="192.168.5.2"
int_gre="gre1"

I. Установка пакетов

Пример конфигурации
apt-get update && apt-get install -y iptables
apt-get install -y openssh-server

# SSH для Ansible с BR-SRV (порт 22, пользователь net_admin)
systemctl enable --now sshd
ss -tlpn | grep sshd

II. Маршрут до локальной сети площадки B

Сеть за межсетевым экраном достижима через GRE-туннель. ip route replace не падает, если маршрут уже есть; запись в ipv4route сохраняет его после перезагрузки.

Пример конфигурации
ip route replace $net_br via $ip_gre_br
rt=/etc/net/ifaces/$int_gre/ipv4route
grep -qs "^$net_br via $ip_gre_br" $rt \
  || echo "$net_br via $ip_gre_br" >> $rt

ip route | grep "$net_br"

III. Проброс портов на HQ-SRV

Цепочка PREROUTING подменяет адрес назначения до маршрутизации: обращение на внешний адрес маршрутизатора уходит внутрь сети.

Пример конфигурации
# -C проверяет, есть ли правило — повторный запуск блока не создаст дубликатов
for p in "$app_port $ip_hq_srv:$web_port" "$ssh_port $ip_hq_srv:$ssh_port"; do
  set -- $p
  iptables -t nat -C PREROUTING -d $ip_hq_rtr -p tcp --dport $1 -j DNAT --to-destination $2 2>/dev/null || \
  iptables -t nat -A PREROUTING -d $ip_hq_rtr -p tcp --dport $1 -j DNAT --to-destination $2
done

IV. Разрешение транзита

Нужно, если политика цепочки FORWARD не ACCEPT. Правило пропускает уже отслеженные соединения и новые обращения к опубликованным портам.

Пример конфигурации
iptables -C FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 2>/dev/null || \
  iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -C FORWARD -d $ip_hq_srv -p tcp -m multiport --dports $web_port,$ssh_port -j ACCEPT 2>/dev/null || \
  iptables -A FORWARD -d $ip_hq_srv -p tcp -m multiport --dports $web_port,$ssh_port -j ACCEPT

V. Сохранение правил

Без записи в /etc/sysconfig/iptables правила исчезнут после перезагрузки.

Пример конфигурации
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

VI. Проверка

Пример конфигурации
iptables -t nat -nvL PREROUTING

BR-RTR — клиент NTP и статическая трансляция портов

Синхронизация времени с ISP и публикация контейнеризованного приложения BR-SRV.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Внешний адрес самого маршрутизатора
ip_br_rtr="172.16.2.10"

# Публикуемый узел
ip_br_srv="192.168.4.2"

# Служба точного времени
ip_ntp_br="172.16.2.1"

# Порты
app_port="8080"
ssh_port="2027"

# Маршрут до локальной сети площадки B через межсетевой экран (стык /30)
net_br="192.168.4.0/28"
ip_fw_to_rtr="192.168.3.2"
ip_to_fw="192.168.3.1"
mask_br_rtr_to_fw="30"
int_to_fw="enp7s2"

I. Клиент службы точного времени

Пример конфигурации
echo "$ip_to_fw/$mask_br_rtr_to_fw" > /etc/net/ifaces/$int_to_fw/ipv4address
systemctl restart network

apt-get update && apt-get install -y chrony
apt-get install -y iptables
apt-get install -y openssh-server

# SSH для Ansible с BR-SRV (порт 22, пользователь net_admin)
systemctl enable --now sshd
ss -tlpn | grep sshd

grep -q "^server $ip_ntp_br " /etc/chrony.conf || echo \
  "server $ip_ntp_br iburst" >> /etc/chrony.conf
systemctl enable --now chronyd
systemctl restart chronyd

chronyc sources -v

II. Маршрут до локальной сети площадки B

Сеть сервера лежит за межсетевым экраном. Статический маршрут передаётся в OSPF через redistribute static — так о нём узнает и площадка A.

Пример конфигурации
ip route replace $net_br via $ip_fw_to_rtr
rt=/etc/net/ifaces/$int_to_fw/ipv4route
grep -qs "^$net_br via $ip_fw_to_rtr" $rt \
  || echo "$net_br via $ip_fw_to_rtr" >> $rt

ping -c 2 $ip_br_srv

vtysh <<EOF
configure terminal
router ospf
 redistribute static
exit
end
write memory
EOF

III. Проброс портов на BR-SRV

Контейнеризованное приложение и SSH публикуются на внешнем адресе маршрутизатора без смены номеров портов.

Пример конфигурации
# -C проверяет, есть ли правило — повторный запуск блока не создаст дубликатов
for p in "$app_port $ip_br_srv:$app_port" "$ssh_port $ip_br_srv:$ssh_port"; do
  set -- $p
  iptables -t nat -C PREROUTING -d $ip_br_rtr -p tcp --dport $1 -j DNAT --to-destination $2 2>/dev/null || \
  iptables -t nat -A PREROUTING -d $ip_br_rtr -p tcp --dport $1 -j DNAT --to-destination $2
done

IV. Разрешение транзита

Пример конфигурации
iptables -C FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 2>/dev/null || \
  iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -C FORWARD -d $ip_br_srv -p tcp -m multiport --dports $app_port,$ssh_port -j ACCEPT 2>/dev/null || \
  iptables -A FORWARD -d $ip_br_srv -p tcp -m multiport --dports $app_port,$ssh_port -j ACCEPT

V. Сохранение правил

Пример конфигурации
iptables-save -f /etc/sysconfig/iptables
systemctl enable --now iptables.service

VI. Проверка

Пример конфигурации
iptables -t nat -nvL PREROUTING

HQ-SRV — RAID0, NFS, Apache и MariaDB

Файловое хранилище из двух дисков, сетевой ресурс для рабочей станции и веб-приложение с базой данных.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Служба точного времени
ip_ntp_hq="172.16.1.1"

# Файловое хранилище
raid_dev="/dev/md0"
raid_disk1="/dev/sdb"
raid_disk2="/dev/sdc"
raid_mount="/raid"
nfs_share="/raid/nfs"
net_hq_cli="192.168.2.0/28"

# База данных веб-приложения
db_name="webdb"
db_user="web"
db_password="P@ssw0rd"

I. Установка пакетов и синхронизация времени

Пример конфигурации
# Версию PHP уточните: apt-cache search apache2-mod_php
apt-get update && apt-get install -y mdadm
apt-get install -y nfs-server
apt-get install -y nfs-utils
apt-get install -y apache2
apt-get install -y apache2-mod_php8.2
apt-get install -y php8.2-mysqli
apt-get install -y mariadb-server
apt-get install -y chrony
apt-get install -y iptables
apt-get install -y openssh-server

# SSH для Ansible с BR-SRV: порт 2027, как в задании (в готовом 1-м модуле может стоять другой)
grep -q "^Port $ssh_port\$" /etc/openssh/sshd_config || \
  sed -i "s/^#\?Port .*/Port $ssh_port/" /etc/openssh/sshd_config
sshd -t && systemctl enable --now sshd && systemctl restart sshd
ss -tlpn | grep sshd

grep -q "^server $ip_ntp_hq " /etc/chrony.conf || echo \
  "server $ip_ntp_hq iburst" >> /etc/chrony.conf
systemctl enable --now chronyd
systemctl restart chronyd

II. Сборка массива RAID0

Уровень 0 объединяет ёмкость обоих дисков без избыточности; запись в mdadm.conf нужна, чтобы массив собирался после перезагрузки.

Пример конфигурации
mdadm --create $raid_dev --level=0 --raid-devices=2 $raid_disk1 $raid_disk2
mdadm --detail --scan --verbose >> /etc/mdadm.conf

mkfs.ext4 -F $raid_dev
mkdir -p $raid_mount
grep -q "^$raid_dev " /etc/fstab || echo \
  "$raid_dev $raid_mount ext4 defaults 0 0" >> /etc/fstab
mount -av

cat /proc/mdstat

III. Настройка сетевого ресурса NFS

Экспорт ограничен подсетью рабочей станции.

Пример конфигурации
mkdir -p $nfs_share
chmod 0777 $nfs_share

cat <<EOF > /etc/exports
$nfs_share $net_hq_cli(rw,no_root_squash)
EOF

systemctl enable --now nfs-server
exportfs -rav

IV. Развёртывание веб-приложения

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

Пример конфигурации
mount /dev/sr0 /mnt 2>/dev/null || true
\cp -f /mnt/web/index.php /var/www/html/
\cp -f /mnt/web/logo.png /var/www/html/
\rm -f /var/www/html/index.html

# Учётные данные БД в index.php должны совпадать с db_name / db_user / db_password
grep -n -i -E "host|user|pass|dbname|database" /var/www/html/index.php | head
nano /var/www/html/index.php

V. Запуск MariaDB и создание базы

Первый запуск инициализирует каталог данных: команда systemctl возвращает управление раньше, чем сервер поднимет сокет, поэтому следующий блок должен дождаться готовности. ALTER USER стоит отдельной строкой потому, что CREATE USER IF NOT EXISTS у существующего пользователя молча оставляет старый пароль.

Пример конфигурации
systemctl enable --now mariadb

for i in $(seq 30); do
  mariadb -e "SELECT 1" >/dev/null 2>&1 && break
  sleep 1
done
mariadb -e "SELECT VERSION();"

mariadb <<EOF
CREATE DATABASE IF NOT EXISTS $db_name;
CREATE USER IF NOT EXISTS '$db_user'@'localhost';
ALTER USER '$db_user'@'localhost' IDENTIFIED BY '$db_password';
GRANT ALL PRIVILEGES ON $db_name.* TO '$db_user'@'localhost';
FLUSH PRIVILEGES;
EOF

mariadb -e "SHOW GRANTS FOR '$db_user'@'localhost';"

VI. Импорт дампа

Кодировку дампа определяем, а не угадываем: безусловный iconv превращает обычный ASCII-файл в нечитаемые символы, причём без ошибки — и импорт падает на первой строке.

Пример конфигурации
\cp -f /mnt/web/dump.sql /root/dump.sql
file -b --mime-encoding /root/dump.sql

if file -b --mime-encoding /root/dump.sql | grep -q utf-16; then
  iconv -f UTF-16 -t UTF-8 /root/dump.sql -o /root/dump_ready.sql
else
  \cp -f /root/dump.sql /root/dump_ready.sql
fi

head -1 /root/dump_ready.sql
mariadb $db_name < /root/dump_ready.sql

mariadb -e "USE $db_name; SHOW TABLES;"

VII. Запуск веб-сервера

Проверка под учётной записью приложения важнее проверки под root: именно этим путём пойдёт index.php.

Пример конфигурации
systemctl enable --now httpd2
systemctl is-active httpd2

mariadb -u $db_user -p"$db_password" $db_name -e "SHOW TABLES;"
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/

BR-SRV — Samba DC, Ansible и Docker

Контроллер домена, узел управления конфигурацией и хост контейнеризованного приложения.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен
realm="AU-TEAM.IRPO"
netbios="AU-TEAM"
admin_password="P@ssw0rd"

# Доменная группа и пользователи
domain_group="hq"
domain_user_prefix="hquser"
domain_user_count="5"
domain_user_password="P@ssw0rd"

# Узлы для инвентаря Ansible
ip_hq_srv="192.168.1.10"
ip_hq_cli="192.168.2.10"
ip_hq_rtr="172.16.1.10"
ip_br_rtr="172.16.2.10"

# Доступ к узлам (на серверах SSH на порту 2027 по заданию 1-го этапа)
ssh_user="sshuser"
ssh_password="P@ssw0rd"
ssh_port="2027"
cli_user="user"
cli_password="resu"

# Служба точного времени
ip_ntp_br="172.16.2.1"

# Контейнеризованное приложение
app_dir="/opt/testapp"

I. Установка пакетов

Пример конфигурации
apt-get update && apt-get install -y task-samba-dc
apt-get install -y ansible
apt-get install -y sshpass
apt-get install -y python3-module-pip
apt-get install -y docker-engine
apt-get install -y docker-compose-v2
apt-get install -y chrony
apt-get install -y iptables

II. Развёртывание контроллера домена

Проверка перед provision защищает от повторного развёртывания уже поднятого домена.

Пример конфигурации
if ! samba-tool domain info 127.0.0.1 >/dev/null 2>&1; then
  \rm -f /etc/samba/smb.conf
  \rm -rf /var/lib/samba /var/cache/samba
  mkdir -p /var/lib/samba/sysvol
  samba-tool domain provision --realm=$realm --domain=$netbios \
    --server-role=dc --dns-backend=SAMBA_INTERNAL \
    --option="dns forwarder=$ip_hq_srv" \
    --adminpass="$admin_password"
fi

\cp -f /var/lib/samba/private/krb5.conf /etc/krb5.conf
systemctl enable --now samba

III. Политика паролей и блокировки

Опция сброса счётчика называется --reset-account-lockout-after: варианта со словом counter в samba-tool нет. Вывод show показывает применённые значения.

Пример конфигурации
samba-tool domain passwordsettings set --min-pwd-length=8
samba-tool domain passwordsettings set --account-lockout-threshold=5
samba-tool domain passwordsettings set --account-lockout-duration=30
samba-tool domain passwordsettings set --reset-account-lockout-after=30

samba-tool domain passwordsettings show

IV. Создание группы и пользователей

Пример конфигурации
samba-tool group add $domain_group 2>/dev/null || true

for i in $(seq 1 $domain_user_count); do
  samba-tool user add $domain_user_prefix$i "$domain_user_password" \
    2>/dev/null || true
  samba-tool user setexpiry $domain_user_prefix$i --noexpiry
  samba-tool group addmembers $domain_group $domain_user_prefix$i
done

samba-tool group listmembers $domain_group

V. Настройка Ansible

host_key_checking отключается, иначе первый запуск падает на запросе подтверждения ключа. Вход по паролю обеспечивает sshpass из репозитория — дополнительных транспортов ставить не нужно. На HQ-RTR, BR-RTR и HQ-CLI должен быть запущен sshd на порту 22 (systemctl enable --now sshd), на HQ-SRV — на порту 2027 из 1-го этапа.

Пример конфигурации
mkdir -p /etc/ansible

cat <<EOF > /etc/ansible/hosts
[servers]
HQ-SRV ansible_host=$ip_hq_srv

[clients]
HQ-CLI ansible_host=$ip_hq_cli

[routers]
HQ-RTR ansible_host=$ip_hq_rtr
BR-RTR ansible_host=$ip_br_rtr

[servers:vars]
ansible_user=$ssh_user
ansible_password=$ssh_password
ansible_port=$ssh_port

[clients:vars]
ansible_user=$cli_user
ansible_password=$cli_password

[routers:vars]
ansible_user=net_admin
ansible_password=$admin_password

[all:vars]
ansible_python_interpreter=/usr/bin/python3
EOF

cat <<EOF > /etc/ansible/ansible.cfg
[defaults]
inventory = /etc/ansible/hosts
host_key_checking = False
EOF

# На hq-cli, hq-rtr и br-rtr предварительно: systemctl enable --now sshd

cd /etc/ansible && ansible all -m ping

VI. Синхронизация времени

Пример конфигурации
grep -q "^server $ip_ntp_br " /etc/chrony.conf || echo \
  "server $ip_ntp_br iburst" >> /etc/chrony.conf
systemctl enable --now chronyd
systemctl restart chronyd

VII. Развёртывание testapp в Docker

Образы загружаются из архивов на установочном образе. По заданию используется готовый compose.yaml с образа: перед запуском проверьте в нём имена образов (должны совпадать с выводом docker images), что учётные данные БД у сервиса db и у приложения одинаковые и что приложение публикуется на 8080. Свой файл ниже — запасной вариант, если на образе compose.yaml нет.

Пример конфигурации
systemctl enable --now docker.service
mount /dev/sr0 /mnt 2>/dev/null || true

docker load < /mnt/docker/site_latest.tar
docker load < /mnt/docker/mariadb_latest.tar
docker images   # тег mariadb может быть 10.11, а не latest — в compose должен быть именно он, иначе docker полезет в интернет

# Где на образе compose-файл (имя и каталог могут отличаться)
compose_src=$(find /mnt -iname '*compose*.y*ml' | head -1)
echo "compose=$compose_src"

mkdir -p $app_dir
\cp -f "$compose_src" $app_dir/compose.yaml
cat $app_dir/compose.yaml

cd $app_dir && docker compose -f compose.yaml up -d
docker ps
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/

VII-б (запасной). Собственный compose.yaml

Только если файла на образе нет. Интернета до docker hub нет, поэтому имена образов в compose должны точно совпадать с docker images — для этого загруженной mariadb добавляется тег latest. Кавычки у EOF обязательны — символы $ в пароле bash трогать не должен (путь поэтому задаём cd). Переменные окружения приложения должны совпадать с настройками db.

Пример конфигурации
mdb_tag=$(docker images mariadb --format '{{.Tag}}' | head -1)
docker tag mariadb:$mdb_tag mariadb:latest
docker images

mkdir -p $app_dir && cd $app_dir
cat <<'EOF' > compose.yaml
services:
  db:
    image: mariadb:latest
    container_name: testapp_db
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: db
      MARIADB_USER: web
      MARIADB_PASSWORD: P@ssw0rd
      MARIADB_RANDOM_ROOT_PASSWORD: "yes"
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - testapp_net

  site:
    image: site:latest
    container_name: testapp_site
    restart: unless-stopped
    depends_on:
      - db
    environment:
      DB_TYPE: maria
      DB_HOST: db
      DB_NAME: db
      DB_PORT: "3306"
      DB_USER: web
      DB_PASS: P@ssw0rd
    ports:
      - "8080:8000"   # снаружи 8080, внутри контейнера uvicorn слушает 8000 (см. docker logs)
    networks:
      - testapp_net

volumes:
  db_data:

networks:
  testapp_net:
EOF

cd $app_dir && docker compose -f compose.yaml up -d
docker ps

HQ-CLI — ввод в домен, NFS и браузер

Рабочая станция вводится в домен, монтирует сетевой ресурс и получает ограниченные права sudo для доменной группы.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен
domain="au-team.irpo"
netbios="AU-TEAM"
admin_password="P@ssw0rd"

# Адреса узлов
ip_br_srv="192.168.4.2"
ip_hq_srv="192.168.1.10"
ip_ntp_hq="172.16.1.1"

# Доменная группа и пользователи
domain_group="hq"
domain_user_prefix="hquser"

# Сетевой ресурс
nfs_share="/raid/nfs"
nfs_mount="/mnt/nfs"

I. Переключение резолвера на контроллер домена

Ввод в домен требует, чтобы DNS отвечал контроллер — BR-SRV (он пересылает остальные запросы на HQ-SRV). Адрес HQ-CLI получает по DHCP, поэтому файл пишется и в каталог интерфейса — иначе etcnet перезапишет его значениями от DHCP.

Пример конфигурации
int_cli=$(ip -br link | awk '$1!="lo"{print $1; exit}')

cat <<EOF > /etc/resolv.conf
search $domain
nameserver $ip_br_srv
EOF

cat <<EOF > /etc/net/ifaces/$int_cli/resolv.conf
search $domain
nameserver $ip_br_srv
EOF

host -t SRV _ldap._tcp.$domain

II. Установка пакетов и синхронизация времени

Расхождение часов с контроллером домена ломает Kerberos, поэтому chrony ставится до ввода в домен.

Пример конфигурации
apt-get update && apt-get install -y task-auth-ad-sssd
apt-get install -y libnss-role
apt-get install -y nfs-utils
apt-get install -y nfs-clients
apt-get install -y yandex-browser-stable
apt-get install -y chrony
apt-get install -y iptables
apt-get install -y openssh-server

# SSH для Ansible с BR-SRV (порт 22, локальный пользователь user)
systemctl enable --now sshd
ss -tlpn | grep sshd

grep -q "^server $ip_ntp_hq " /etc/chrony.conf || echo \
  "server $ip_ntp_hq iburst" >> /etc/chrony.conf
systemctl enable --now chronyd
systemctl restart chronyd

III. Ввод в домен

После ввода проверьте, что доменные учётные записи разрешаются командой id.

Пример конфигурации
system-auth write ad $domain $(hostname -s) $netbios 'administrator' \
  "$admin_password"

id ${domain_user_prefix}1@$domain

IV. Ограниченные права sudo для доменной группы

Членам группы разрешены только перечисленные в Cmnd_Alias команды. Группу нельзя добавлять в wheel (roleadd hq wheel) — это дало бы полный sudo. Пути к командам берём с самой машины. Проверка visudo обязательна: ошибка в sudoers лишает доступа всех.

Пример конфигурации
control sudo public

cat <<EOF > /etc/sudoers.d/$domain_group
Cmnd_Alias HQ_LIMITED = $(command -v cat), $(command -v grep), $(command -v id)
%$domain_group ALL=(ALL:ALL) HQ_LIMITED
EOF

chmod 440 /etc/sudoers.d/$domain_group
visudo -c

# Проверка под доменным пользователем: sudo id — работает, sudo ls — отказ
su - ${domain_user_prefix}1@$domain -c 'sudo -l'

V. Автомонтирование сетевого ресурса

Пример конфигурации
mkdir -p $nfs_mount
grep -q "$ip_hq_srv:$nfs_share" /etc/fstab || echo \
  "$ip_hq_srv:$nfs_share $nfs_mount nfs defaults,_netdev 0 0" >> /etc/fstab
mount -av

df -h $nfs_mount

2-й этап. Диагностика и проверка конфигурации

Значения указаны буквально — блоки можно запускать в новой сессии без объявления переменных. В комментарии — ожидаемый результат.

Блок 1. ISP — chrony-сервер

Команды проверки на ISP
systemctl is-active chronyd                 # active
chronyc tracking | grep -E 'Stratum|Leap'   # Stratum : 5, Leap status : Normal
chronyc clients                             # в списке HQ-SRV, HQ-CLI, BR-RTR, BR-SRV после их настройки
grep -E '^(local|allow)' /etc/chrony.conf   # local stratum 5; allow на 172.16.x и внутренние сети

Блок 2. Клиенты chrony — HQ-SRV, HQ-CLI, BR-RTR, BR-SRV

Команды проверки на каждом клиенте
chronyc sources -v | tail -3                # строка с ^* — источник ISP выбран, stratum 5
chronyc tracking | grep -E 'Reference|Stratum'   # Reference ID = адрес ISP, Stratum : 6
timedatectl | grep -E 'synchronized|Time zone'   # System clock synchronized: yes

Блок 3. HQ-RTR и BR-RTR — трансляция портов

Команды проверки
# HQ-RTR
iptables -t nat -nvL PREROUTING            # DNAT tcp dpt:2027 → 192.168.1.10:2027, dpt:80 → 192.168.1.10:80
iptables -nvL FORWARD | grep 192.168.1.10  # ACCEPT на 2027 и 80

# BR-RTR
iptables -t nat -nvL PREROUTING            # DNAT dpt:2027 → 192.168.4.2:2027, dpt:8080 → 192.168.4.2:8080
iptables -nvL FORWARD | grep 192.168.4.2

# С ISP — сквозная проверка проброса
ssh -p 2027 sshuser@172.16.1.10 hostname   # hq-srv
ssh -p 2027 sshuser@172.16.2.10 hostname   # br-srv
curl -s -o /dev/null -w "%{http_code}\n" http://172.16.1.10/          # 200 (Apache HQ-SRV)
curl -s -o /dev/null -w "%{http_code}\n" http://172.16.2.10:8080/     # 200 (testapp BR-SRV)

Блок 4. HQ-SRV — RAID0, NFS, Apache, MariaDB

Команды проверки на HQ-SRV
cat /proc/mdstat                            # md0 : active raid0 — 2 диска, [UU]
mdadm --detail /dev/md0 | grep -E 'Level|State|Devices'
lsblk -f | grep -A1 md0                     # ext4
findmnt /raid                               # смонтирован /dev/md0
grep md0 /etc/fstab /etc/mdadm.conf         # запись в fstab и ARRAY в mdadm.conf (постоянность)

exportfs -v                                 # /raid/nfs 192.168.2.0/28(rw,...,no_root_squash)
systemctl is-active nfs-server              # active
showmount -e localhost

systemctl is-active httpd2 mariadb          # active active
curl -s http://localhost/ | head -5         # страница отвечает
mysql -e 'SELECT VERSION();'                # версия MariaDB

Блок 5. BR-SRV — Samba DC, Ansible, Docker

Команды проверки на BR-SRV
systemctl is-active samba                   # active
samba-tool domain level show                # Domain and forest function level
samba-tool user list                        # hquser1..hquser5 (+ administrator)
samba-tool group listmembers hq             # hquser1..hquser5
samba-tool domain passwordsettings show | grep -E 'Minimum password length|lockout threshold'   # 8 и 5
host -t SRV _ldap._tcp.au-team.irpo         # br-srv.au-team.irpo

cd /etc/ansible && ansible all -m ping      # 4 узла: HQ-SRV, HQ-CLI, HQ-RTR, BR-RTR — "ping": "pong"
ansible-inventory --graph

docker ps                                   # testapp_site 0.0.0.0:8080->8000/tcp, testapp_db — Up
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/   # 200 (HEAD/-I приложение не умеет)

Блок 6. HQ-CLI — домен, sudo, NFS

Команды проверки на HQ-CLI
system-auth status                          # ad / домен au-team.irpo
id hquser1@au-team.irpo                     # uid/gid из домена, группа hq
su - hquser1@au-team.irpo -c 'sudo -l'      # разрешены только /bin/cat, /bin/grep, /usr/bin/id
su - hquser1@au-team.irpo -c 'sudo id'      # работает
su - hquser1@au-team.irpo -c 'sudo ls /'    # отказ — не в списке

findmnt /mnt/nfs                            # 192.168.1.10:/raid/nfs, rw
grep nfs /etc/fstab                         # запись есть (автомонтирование)
touch /mnt/nfs/test && rm -f /mnt/nfs/test  # запись работает
ip -br a | grep enp7s1                      # адрес из 192.168.2.0/28 от DHCP HQ-RTR

3-й этап. Эксплуатация объектов сетевой инфраструктуры

Импорт пользователей в домен, обратный прокси с веб-аутентификацией, собственный центр сертификации и HTTPS, мониторинг atop, печать через CUPS, инвентаризация средствами Ansible, защита SSH через fail2ban и резервное копирование.

BR-SRV — импорт пользователей и инвентаризация

Массовое создание доменных учётных записей из CSV и сбор сведений об узлах площадки HQ средствами Ansible.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен — из него собирается базовый DN
domain="au-team.irpo"

# Кодировка выгрузки, если она не UTF-8
csv_encoding="CP1251"

# Рабочий каталог Ansible
ansible_dir="/etc/ansible"

I. Подготовка файла пользователей

Кодировку определяем, а не угадываем. Русский текст из Windows утилита file часто называет ISO-8859, хотя на деле это CP1251 — поэтому для не-UTF-8 файла берётся csv_encoding. Счётчик кириллических строк в конце показывает, получилась ли читаемая кириллица.

Пример конфигурации
mount /dev/sr0 /mnt 2>/dev/null || true
ls -la /mnt/

# По заданию скрипт import.sh и users.csv лежат в корне образа — сначала пробуем их
csv_src=$(find /mnt -maxdepth 1 -iname 'users.csv' | head -1)
imp_src=$(find /mnt -maxdepth 1 -iname 'import.sh' | head -1)
echo "csv=$csv_src import=$imp_src"

\cp -f "$csv_src" /root/Users.csv
file -b --mime-encoding /root/Users.csv

case "$(file -b --mime-encoding /root/Users.csv)" in
  utf-8|us-ascii)
    iconv -f UTF-8 -t UTF-8//IGNORE /root/Users.csv > /root/Users_fixed.csv ;;
  *)
    iconv -f $csv_encoding -t UTF-8 /root/Users.csv > /root/Users_fixed.csv ;;
esac

head -3 /root/Users_fixed.csv
grep -cP '[а-яА-Я]' /root/Users_fixed.csv

II. Скрипт импорта

Сначала — штатный import.sh с образа (прочитайте его: обычно он ждёт путь к CSV аргументом или рядом с собой). Собственный скрипт ниже — запасной вариант, если штатный падает; порядок колонок в read сверьте с заголовком CSV (head -1). Одинарные кавычки в heredoc обязательны: внутри скрипта используются собственные переменные. Первая строка файла — заголовок, tail -n +2 её пропускает; иначе из заголовка получится лишнее подразделение с именем OU.

Пример конфигурации
systemctl enable --now samba
systemctl is-active samba

# Вариант 1 (по заданию): штатный скрипт с образа
\cp -f "$imp_src" /root/import_iso.sh
\cp -f /root/Users_fixed.csv /root/users.csv
cat /root/import_iso.sh
bash /root/import_iso.sh /root/users.csv
samba-tool user list

# Вариант 2 (запасной): собственный скрипт
head -1 /root/Users_fixed.csv

cat <<'EOF' > /root/import.sh
#!/bin/bash
while IFS=';' \
  read -r first last role phone ou street zip city country pass; do
  [ -z "$first" ] && continue
  username="${first:0:1}${last}"
  username=$(printf '%s' "$username" | tr '[:upper:]' '[:lower:]')
  samba-tool user create "$username" "$pass" \
    --given-name="$first" --surname="$last" \
    --job-title="$role" --telephone-number="$phone" || true
  if [ -n "$ou" ]; then
    samba-tool ou create "OU=$ou" 2>/dev/null || true
    samba-tool user move "$username" "OU=$ou" 2>/dev/null || true
  fi
done < <(tail -n +2 /root/Users_fixed.csv)
EOF

chmod +x /root/import.sh
bash /root/import.sh

samba-tool user list

III. Удаление лишнего подразделения (если импорт уже запускался без пропуска заголовка)

Базовый DN собирается из имени домена: au-team.irpo превращается в DC=au-team,DC=irpo.

Пример конфигурации
base_dn="DC=${domain//./,DC=}"
echo "$base_dn"

samba-tool ou delete "OU=OU,$base_dn" 2>/dev/null || true
samba-tool ou list

IV. Плейбук инвентаризации

delegate_to: localhost сохраняет результат на управляющем узле, а не на опрашиваемой машине.

Пример конфигурации
mkdir -p $ansible_dir/PC-INFO

# По заданию плейбук лежит на образе в каталоге playbook — сначала берём его
mount /dev/sr0 /mnt 2>/dev/null || true
ls -l /mnt/playbook/ && \cp -f /mnt/playbook/*.yml $ansible_dir/

# Запасной вариант, если на образе плейбука нет
cat <<'EOF' > /etc/ansible/get_hostname_address.yml
- name: Inventory HQ workstations
  hosts: HQ-SRV,HQ-CLI
  gather_facts: true
  tasks:
    - name: Save hostname and IP
      copy:
        dest: /etc/ansible/PC-INFO/{{ ansible_hostname }}.yml
        content: |
          Hostname: {{ ansible_hostname }}
          IP_Address: {{ ansible_default_ipv4.address }}
      delegate_to: localhost
EOF

cd $ansible_dir && ansible-playbook get_hostname_address.yml
ls -l $ansible_dir/PC-INFO/

HQ-SRV — центр сертификации, atop, CUPS, fail2ban

Собственный удостоверяющий центр на отечественных алгоритмах, непрерывный мониторинг, виртуальный PDF-принтер и блокировка перебора SSH.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен и публикуемые имена
domain="au-team.irpo"
web_fqdn="web.$domain"
docker_fqdn="docker.$domain"

# Центр сертификации
ca_dir="/root/ca"
ca_cn="Internal-CA"
ca_days="3650"
cert_days="30"

# Куда класть копии для забора по scp под sshuser (root по ssh не пускает AllowUsers)
ssh_user="sshuser"
ca_pub_dir="/home/sshuser/ca"

# Мониторинг (7 минут = 420 с)
atop_interval="420"

# Печать
printer_name="Cups-PDF"
cups_port="631"

# Защита SSH
ssh_port="2027"
f2b_maxretry="3"
f2b_bantime="1m"
# Кибер Бэкап (дистрибутив — CD-ROM с меткой CyberBackup_Linux_Installer: на HQ-SRV sr1, на HQ-CLI sr0;
# монтируем не в /mnt — там может быть Additional.iso)
cb_mnt="/media/cb"
cb_port="9877"
cb_dev=$(lsblk -rno NAME,LABEL | awk '/CyberBackup/{print "/dev/"$1}' | head -1)
echo "cb_dev=$cb_dev"
mkdir -p $cb_mnt; mountpoint -q $cb_mnt || mount $cb_dev $cb_mnt
cb_installer=$(find $cb_mnt -maxdepth 2 -type f | head -1)
echo "installer=$cb_installer"

I. Установка пакетов

Пример конфигурации
apt-get update && apt-get install -y openssl
apt-get install -y openssl-gost-engine
apt-get install -y atop
apt-get install -y cups
apt-get install -y cups-pdf
apt-get install -y fail2ban
apt-get install -y iptables
control openssl-gost enabled

II. Подключение движка ГОСТ в OpenSSL

Без движка openssl не знает алгоритмов gost2012 и не сможет ни выпустить ключ, ни поднять TLS. В ALT движок ставится пакетом и включается командой control; ручная правка openssl.cnf ломает конфигурацию.

Пример конфигурации
# В ALT движок подключается штатным openssl.cnf, но по умолчанию выключен —
# включает его control; вручную openssl.cnf не править
control openssl-gost enabled
control openssl-gost                                   # enabled

openssl engine gost                                    # (gost) Reference implementation of GOST engine
openssl list -public-key-algorithms | grep -i gost     # gost2012_256 и др. — без этого TLS с ГОСТ не поднимется
openssl ciphers | tr ':' '\n' | grep -i gost          # GOST2012-GOST8912-GOST8912

III. Создание корневого сертификата

Пример конфигурации
mkdir -p $ca_dir && cd $ca_dir

openssl genpkey -algorithm gost2012_256 -pkeyopt paramset:TCB -out ca.key
openssl req -new -x509 -md_gost12_256 -days $ca_days -key ca.key -out ca.crt \
  -subj "/CN=$ca_cn"

openssl x509 -in ca.crt -noout -subject -dates

IV. Выпуск сертификатов веб-серверов

Срок действия — 30 дней согласно заданию. Без subjectAltName современный браузер не примет сертификат даже при доверенном CA (ERR_CERT_COMMON_NAME_INVALID). Подпись ГОСТ-ключом требует явного дайджеста. Копии кладутся в домашний каталог sshuser — оттуда их забирают ISP и HQ-CLI по scp.

Пример конфигурации
cd $ca_dir

for NAME in $web_fqdn $docker_fqdn; do
  openssl genpkey -algorithm gost2012_256 -pkeyopt paramset:A -out $NAME.key
  openssl req -new -md_gost12_256 -key $NAME.key -out $NAME.csr -subj \
    "/CN=$NAME"
  printf 'subjectAltName=DNS:%s\nextendedKeyUsage=serverAuth\n' $NAME > $NAME.ext
  openssl x509 -req -md_gost12_256 -in $NAME.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -extfile $NAME.ext -out $NAME.crt -days $cert_days
  openssl x509 -in $NAME.crt -noout -subject -dates -ext subjectAltName
done

mkdir -p $ca_pub_dir
\cp -f $ca_dir/ca.crt $ca_dir/*.crt $ca_dir/*.key $ca_pub_dir/
chown -R $ssh_user: $ca_pub_dir
chmod 700 $ca_pub_dir
ls -l $ca_dir $ca_pub_dir

V. Настройка мониторинга atop

Интервал читается из файла окружения юнита (на ALT — /etc/sysconfig/atop, в других сборках /etc/default/atop); drop-in дублирует значение на случай, если юнит берёт переменную напрямую. Проверка — в командной строке процесса должно быть 420.

Пример конфигурации
for f in /etc/sysconfig/atop /etc/default/atop; do
  [ -f $f ] && sed -i "s/^LOGINTERVAL=.*/LOGINTERVAL=$atop_interval/" $f
  grep -qs "^LOGINTERVAL=" $f || echo "LOGINTERVAL=$atop_interval" >> $f
done

mkdir -p /etc/systemd/system/atop.service.d
cat <<EOF > /etc/systemd/system/atop.service.d/interval.conf
[Service]
Environment=LOGINTERVAL=$atop_interval
EOF

systemctl daemon-reload
systemctl enable --now atop
systemctl restart atop
systemctl status atop --no-pager
ps -o args= -C atop

VI. Публикация PDF-принтера через CUPS

Служба переводится с прослушивания localhost на сетевой порт, разрешает доступ к разделам управления, затем создаётся и публикуется (расшаривается) сам принтер: пакет cups-pdf даёт только бэкенд cups-pdf:/ и PPD, очередь нужно добавить самому.

Пример конфигурации
sed -i "s/^Listen localhost:$cups_port/Port $cups_port/" /etc/cups/cupsd.conf
grep -q "^Port $cups_port\$" /etc/cups/cupsd.conf || echo "Port $cups_port" \
  >> /etc/cups/cupsd.conf

grep -q "^  Allow all" /etc/cups/cupsd.conf || {
  sed -i '/<Location \/>/a\  Allow all' /etc/cups/cupsd.conf
  sed -i '/<Location \/admin>/a\  Allow all' /etc/cups/cupsd.conf
  sed -i '/<Location \/admin\/conf>/a\  Allow all' /etc/cups/cupsd.conf
}

systemctl enable --now cups
systemctl restart cups

ppd=$(find /usr/share/ppd /usr/share/cups/model -iname 'CUPS-PDF*.ppd' | head -1)
lpadmin -p $printer_name -E -v cups-pdf:/ -P "$ppd" -o printer-is-shared=true
cupsctl --share-printers --remote-admin --remote-any
lpstat -p $printer_name -l

# Пробная печать: PDF появится в /var/spool/cups-pdf/root/ (или ~/PDF)
echo test | lp -d $printer_name

VII. Журналирование попыток входа

В базовой установке rsyslog нет, и /var/log/auth.log не создаётся. fail2ban теперь читает журнал systemd, так что этот файл нужен уже не ему, а для ручного разбора входов.

Пример конфигурации
apt-get install -y rsyslog
systemctl enable --now rsyslog

grep -q '^SyslogFacility AUTHPRIV' /etc/openssh/sshd_config || echo \
  'SyslogFacility AUTHPRIV' >> /etc/openssh/sshd_config
grep -q '^LogLevel INFO' /etc/openssh/sshd_config || echo 'LogLevel INFO' >> \
  /etc/openssh/sshd_config
grep -q '^authpriv.*' /etc/rsyslog.conf || echo \
  'authpriv.* /var/log/auth.log' >> /etc/rsyslog.conf

systemctl restart rsyslog sshd

VIII. Настройка fail2ban

Бэкенд systemd читает попытки входа прямо из журнала — файл лога не нужен. Для этого fail2ban требует модуль Python для systemd; на ALT пакет называется python3-module-systemd, запасной вариант — для других сборок.

Пример конфигурации
apt-get install -y python3-module-systemd || apt-get install -y python3-systemd
python3 -c "import systemd.journal; print('ok')"

cat <<EOF > /etc/fail2ban/jail.d/sshd-hardening.conf
[sshd]
enabled = true
port = $ssh_port
backend = systemd
maxretry = $f2b_maxretry
bantime = $f2b_bantime
EOF

systemctl enable --now fail2ban
systemctl restart fail2ban
systemctl status fail2ban --no-pager
fail2ban-client status sshd

IX. Кибер Бэкап 18 — сервер управления и агент

Дистрибутив — один исполняемый файл (на стенде — cyberbackup_17.4.36200.x86_64; 17.4 допускается заданием как аналог); на стенде он подключён к ВМ отдельным CD-ROM. Установщик графический (ncurses): на HQ-SRV отмечаем «Сервер управления» и «Агент для Linux», регистрацию агента делаем на этот же сервер. Агенту нужен модуль SnapAPI, для сборки — заголовки текущего ядра. Веб-консоль поднимается на порту 9877.

Пример конфигурации
# Установщик найден в пункте 0 (переменная cb_installer); если пусто — lsblk | grep rom
echo "installer=$cb_installer"; ls -la $cb_mnt

# Заголовки ядра для сборки модуля snapapi (имя пакета должно совпадать с uname -r)
uname -r
apt-get install -y kernel-headers-modules-$(uname -r | sed 's/^[0-9.]*-//; s/-alt.*$//')   # напр. std-def
apt-get install -y gcc
apt-get install -y make
apt-get install -y perl

# Файл на диске уже исполняемый (~1,8 ГБ) — запускаем прямо с него, копировать не нужно
$cb_installer
# В мастере (Component Selection): оставить [*] Management Server и [*] Agent for Linux,
# снять Bootable Media Builder, остальное пусто → Next. Путь по умолчанию;
# регистрация агента — локальный сервер (HQ-SRV), порт 9877, учётная запись root;
# на вопрос о сборке модуля SnapAPI — согласиться.

ss -tlpn | grep -E ":$cb_port|:7780"
systemctl list-units --no-pager | grep -i -E 'acronis|cyber|cb_'

X. Веб-консоль Кибер Бэкапа: подразделение и администратор

Дальше — только в браузере (с HQ-CLI): консоль https://192.168.1.10:9877. Первый вход — root системы. По заданию нужны подразделение irpo и пользователь irpoadmin с правами администратора этого подразделения.

Последовательность в консоли
1. https://192.168.1.10:9877 → вход root / пароль root HQ-SRV.
2. Настройки → Подразделения (Организация) → Добавить подразделение → имя: irpo.
3. Настройки → Учётные записи → Добавить учётную запись:
   имя irpoadmin, пароль P@ssw0rd, роль «Администратор», подразделение irpo.
4. Выйти, войти как irpoadmin / P@ssw0rd — убедиться, что вход работает.

ISP — обратный прокси, web-аутентификация и HTTPS

Публикация обоих приложений по доменным именам с базовой аутентификацией на веб-сайте и шифрованием по отечественным алгоритмам.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен и публикуемые имена
domain="au-team.irpo"
web_fqdn="web.$domain"
docker_fqdn="docker.$domain"

# Узлы, на которые проксируем
ip_hq_rtr="172.16.1.10"
ip_br_rtr="172.16.2.10"
app_port="8080"

# Откуда забрать сертификаты: HQ-SRV через проброс 2027 на HQ-RTR (2-й этап),
# под sshuser — root по ssh на сервер не пускает AllowUsers
ssh_user="sshuser"
ssh_port="2027"
ca_pub_dir="/home/sshuser/ca"

# Веб-аутентификация
web_auth_user="WEB"
web_auth_password="P@ssw0rd"

I. Установка пакетов и файла паролей

Пример конфигурации
apt-get update && apt-get install -y nginx
apt-get install -y openssl
apt-get install -y openssl-gost-engine
apt-get install -y iptables
apt-get install -y apache2-htpasswd || apt-get install -y apache2

htpasswd -bc /etc/nginx/.htpasswd $web_auth_user "$web_auth_password"
cat /etc/nginx/.htpasswd

II. Копирование сертификатов с центра сертификации

Сертификаты и ключи выпускаются на HQ-SRV (см. предыдущий раздел, шаг IV кладёт копии в домашний каталог sshuser). Внутренняя сеть с ISP не маршрутируется, поэтому идём на внешний адрес HQ-RTR: проброс порта 2027 из 2-го этапа приводит на HQ-SRV.

Пример конфигурации
for NAME in $web_fqdn $docker_fqdn; do
  scp -P $ssh_port $ssh_user@$ip_hq_rtr:$ca_pub_dir/$NAME.crt /etc/nginx/
  scp -P $ssh_port $ssh_user@$ip_hq_rtr:$ca_pub_dir/$NAME.key /etc/nginx/
done

chmod 600 /etc/nginx/*.key
ls -l /etc/nginx/*.crt /etc/nginx/*.key

III. Конфигурация обратного прокси

Переменные nginx экранированы обратным слэшем — иначе оболочка подставит вместо них пустые значения ещё на этапе записи файла, и прокси потеряет заголовки.

Пример конфигурации
cat <<EOF > /etc/nginx/sites-available.d/default.conf
server {
  listen 80;
  server_name $web_fqdn;
  return 301 https://\$host\$request_uri;
}

server {
  listen 80;
  server_name $docker_fqdn;
  return 301 https://\$host\$request_uri;
}

server {
  listen 443 ssl;
  server_name $web_fqdn;
  ssl_certificate /etc/nginx/$web_fqdn.crt;
  ssl_certificate_key /etc/nginx/$web_fqdn.key;
  ssl_ciphers GOST2012-GOST8912-GOST8912;
  ssl_protocols TLSv1.2;
  ssl_prefer_server_ciphers on;
  location / {
    proxy_pass http://$ip_hq_rtr:$app_port;
    proxy_set_header Host \$host;
    proxy_set_header X-Real-IP \$remote_addr;
    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto \$scheme;
    auth_basic "Authorized access";
    auth_basic_user_file /etc/nginx/.htpasswd;
  }
}

server {
  listen 443 ssl;
  server_name $docker_fqdn;
  ssl_certificate /etc/nginx/$docker_fqdn.crt;
  ssl_certificate_key /etc/nginx/$docker_fqdn.key;
  ssl_ciphers GOST2012-GOST8912-GOST8912;
  ssl_protocols TLSv1.2;
  ssl_prefer_server_ciphers on;
  location / {
    proxy_pass http://$ip_br_rtr:$app_port;
    proxy_set_header Host \$host;
    proxy_set_header X-Real-IP \$remote_addr;
    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto \$scheme;
  }
}
EOF

ln -sf /etc/nginx/sites-available.d/default.conf \
  /etc/nginx/sites-enabled.d/default.conf

IV. Подключение движка ГОСТ в OpenSSL

Без движка openssl не знает алгоритмов gost2012 и не сможет ни выпустить ключ, ни поднять TLS. В ALT движок ставится пакетом и включается командой control; ручная правка openssl.cnf ломает конфигурацию.

Пример конфигурации
# В ALT движок подключается штатным openssl.cnf, но по умолчанию выключен —
# включает его control; вручную openssl.cnf не править
control openssl-gost enabled
control openssl-gost                                   # enabled

openssl engine gost                                    # (gost) Reference implementation of GOST engine
openssl list -public-key-algorithms | grep -i gost     # gost2012_256 и др. — без этого TLS с ГОСТ не поднимется
openssl ciphers | tr ':' '\n' | grep -i gost          # GOST2012-GOST8912-GOST8912

V. Включение движка ГОСТ и запуск

Если nginx -t не принимает ssl_engine или браузер на HQ-CLI не умеет ГОСТ-TLS (ERR_SSL_VERSION_OR_CIPHER_MISMATCH), отечественные алгоритмы по заданию лишь «рекомендуются»: выпустите на HQ-SRV ключи RSA (openssl genrsa 2048 вместо genpkey, -sha256 вместо -md_gost12_256), уберите строки ssl_ciphers и ssl_engine — остальное без изменений.

Пример конфигурации
grep -q '^ssl_engine gost;' /etc/nginx/nginx.conf || sed -i \
  '/^events {/i ssl_engine gost;' /etc/nginx/nginx.conf

nginx -t
systemctl enable --now nginx
systemctl reload nginx

curl -k -u $web_auth_user:$web_auth_password -s -o /dev/null -w "%{http_code}\n" \
  --resolve $web_fqdn:443:127.0.0.1 https://$web_fqdn/

HQ-CLI — доверие к CA, принтер и узел хранения

Рабочая станция входит в домен, принимает корневой сертификат, подключает сетевой принтер и готовит каталог для резервных копий.

0. Подготовка переменных

Объявите переменные в сессии этого узла перед выполнением остальных команд. Они живут только в текущей оболочке: после bash, su, exit или переподключения по SSH объявите их заново — проверить можно командой echo с именем любой переменной.

Переменные конфигурации
# Домен и контроллер домена
domain="au-team.irpo"
netbios="AU-TEAM"
admin_password="P@ssw0rd"
ip_br_srv="192.168.4.2"
cli_name="hq-cli"
int_cli="enp7s1"

# Доступ к серверу площадки A (root по ssh не пускает AllowUsers — идём под sshuser)
ssh_port="2027"
ssh_user="sshuser"

# Центр сертификации
ip_hq_srv="192.168.1.10"
ca_pub_dir="/home/sshuser/ca"
ca_cn="Internal-CA"

# Печать
printer_name="Cups-PDF"
cups_port="631"

# Узел хранения резервных копий
backup_dir="/backup"
# Кибер Бэкап (дистрибутив — CD-ROM с меткой CyberBackup_Linux_Installer: на HQ-SRV sr1, на HQ-CLI sr0;
# монтируем не в /mnt — там может быть Additional.iso)
cb_mnt="/media/cb"
cb_port="9877"
cb_dev=$(lsblk -rno NAME,LABEL | awk '/CyberBackup/{print "/dev/"$1}' | head -1)
echo "cb_dev=$cb_dev"
mkdir -p $cb_mnt; mountpoint -q $cb_mnt || mount $cb_dev $cb_mnt
cb_installer=$(find $cb_mnt -maxdepth 2 -type f | head -1)
echo "installer=$cb_installer"

I. Резолвер на контроллер домена и ввод в домен

Для ввода в домен DNS должен отвечать контроллер. Файл пишется и в каталог интерфейса: etcnet при перезапуске сети подставляет оттуда свою копию. Проверка SRV-записи идёт после перезапуска — так видно итоговое состояние.

Пример конфигурации
cat <<EOF > /etc/resolv.conf
search $domain
nameserver $ip_br_srv
EOF

cat <<EOF > /etc/net/ifaces/$int_cli/resolv.conf
search $domain
nameserver $ip_br_srv
EOF

systemctl restart network
cat /etc/resolv.conf
host -t SRV _ldap._tcp.$domain

# Если машина уже в домене со 2-го этапа — шаг пропустить (проверка: system-auth status)
system-auth write ad $domain $cli_name $netbios 'administrator' "$admin_password"

# Импортированные пользователи должны разрешаться (имя — из samba-tool user list на BR-SRV)
id administrator@$domain

II. Установка корневого сертификата в доверенные

Без этого шага браузер будет ругаться на сертификаты web и docker. SSH на сервере слушает нестандартный порт, поэтому -P.

Пример конфигурации
apt-get update && apt-get install -y openssl-gost-engine
apt-get install -y cups
apt-get install -y iptables
apt-get install -y admc
apt-get install -y krb5-kinit
control openssl-gost enabled

mkdir -p /etc/pki/ca-trust/source/anchors
scp -P $ssh_port $ssh_user@$ip_hq_srv:$ca_pub_dir/ca.crt \
  /etc/pki/ca-trust/source/anchors/
update-ca-trust

trust list | grep -A2 "$ca_cn"

# Браузеру системного хранилища мало: добавляем CA в NSS-базу пользователя, под которым открывается браузер
apt-get install -y nss-utils || apt-get install -y libnss-tools
for home in /home/*; do
  u=$(basename $home)
  su - $u -c "mkdir -p ~/.pki/nssdb && certutil -d sql:~/.pki/nssdb -N --empty-password 2>/dev/null; \
    certutil -d sql:~/.pki/nssdb -A -t 'C,,' -n '$ca_cn' \
    -i /etc/pki/ca-trust/source/anchors/ca.crt"
done

curl -s -o /dev/null -w "%{http_code}\n" https://docker.$domain/

III. Подключение сетевого принтера

Пример конфигурации
lpadmin -p $printer_name -E -v \
  ipp://$ip_hq_srv:$cups_port/printers/$printer_name -m everywhere
lpoptions -d $printer_name
lpstat -p $printer_name

IV. Кибер Бэкап: агент и узел хранения на HQ-CLI

По заданию на HQ-CLI ставится агент с функциями узла хранилища и регистрируется на сервере управления HQ-SRV (раздел HQ-SRV, шаг IX должен быть уже выполнен). В мастере установки отмечаем «Агент для Linux» и «Узел хранения»; при регистрации указываем адрес сервера управления 192.168.1.10 и учётную запись irpoadmin (или root HQ-SRV).

Пример конфигурации
mkdir -p $backup_dir
chmod 0770 $backup_dir

# Установщик найден в пункте 0 (переменная cb_installer); если пусто — lsblk | grep rom
echo "installer=$cb_installer"; ls -la $cb_mnt

uname -r
apt-get install -y kernel-headers-modules-$(uname -r | sed 's/^[0-9.]*-//; s/-alt.*$//')   # напр. std-def
apt-get install -y gcc
apt-get install -y make
apt-get install -y perl

# Файл на диске уже исполняемый (~1,8 ГБ) — запускаем прямо с него, копировать не нужно
$cb_installer
# В мастере (Component Selection): [*] Agent for Linux + [*] Storage Node, остальное снять;
# сервер управления: $ip_hq_srv, порт $cb_port, учётная запись irpoadmin / P@ssw0rd.

systemctl list-units --no-pager | grep -i -E 'acronis|cyber|cb_'

V. Веб-консоль: хранилище, план и запуск копирования

Остальное — в консоли https://192.168.1.10:9877 под irpoadmin. Проверка результата — файлы архива в /backup на HQ-CLI и статус «Успешно» в разделе Действия.

Последовательность в консоли
1. Настройки → Узлы хранения: убедиться, что HQ-CLI появился как узел хранения.
2. Резервные копии (Хранилища) → Добавить хранилище → Узел хранения HQ-CLI →
   путь /backup → сохранить (имя, например, backup-hq-cli).
3. Устройства → Все устройства → HQ-SRV → Резервное копирование → Создать план:
   Что копировать: Файлы/папки → /etc (со всеми поддиректориями);
   Куда: хранилище backup-hq-cli на узле HQ-CLI;
   Расписание — любое (или отключить), имя плана, например, etc-hq-srv → Создать.
4. В плане нажать «Запустить сейчас», дождаться статуса «Успешно» в разделе Действия.

# Проверка на HQ-CLI:
ls -la /backup
du -sh /backup

3-й этап. Диагностика и проверка конфигурации

Блок 1. BR-SRV — импорт пользователей и инвентаризация

Команды проверки на BR-SRV
samba-tool user list | wc -l                # число пользователей выросло на количество строк Users.csv
samba-tool user show $(samba-tool user list | grep -v -i admin | head -1) | grep -E 'sAMAccountName|givenName'

ls -l /etc/ansible/                         # плейбук *.yml из Additional.iso
ls -l /etc/ansible/PC-INFO/                 # по файлу .yml на узел
cat /etc/ansible/PC-INFO/*.yml              # имя и адрес узла в каждом

Блок 2. HQ-SRV — CA, сертификаты, atop, CUPS, fail2ban

Команды проверки на HQ-SRV
control openssl-gost                        # enabled
openssl engine gost                         # (gost) Reference implementation of GOST engine
openssl x509 -in /root/ca/ca.crt -noout -subject -dates          # CN=Internal-CA (или свой), 30 дней
for n in web docker; do openssl x509 -in /root/ca/$n.au-team.irpo.crt -noout -subject -dates -ext subjectAltName; done
openssl verify -CAfile /root/ca/ca.crt /root/ca/web.au-team.irpo.crt   # OK
ls -l /home/sshuser/ca/                     # копии для ISP и HQ-CLI

systemctl is-active atop                    # active
grep -s '^LOGINTERVAL' /etc/sysconfig/atop /etc/default/atop   # 420
ps -o args= -C atop                          # в строке запуска интервал 420
ls -l /var/log/atop/                        # журнал atop_YYYYMMDD

systemctl is-active cups                    # active
lpstat -p -d                                # Cups-PDF idle, принтер по умолчанию
ss -tlpn | grep 631                         # слушает на 0.0.0.0/адресе сервера, не только 127.0.0.1

systemctl is-active fail2ban                # active
fail2ban-client status sshd                 # Port 2027, maxretry 3, bantime 60
fail2ban-client get sshd bantime            # 60
fail2ban-client get sshd maxretry           # 3

Блок 3. ISP — обратный прокси, web-аутентификация, HTTPS/ГОСТ

Команды проверки на ISP
control openssl-gost                        # enabled
openssl ciphers | tr ':' '\n' | grep -i gost   # GOST2012-GOST8912-GOST8912
nginx -t                                    # syntax is ok / test is successful
systemctl is-active nginx                   # active
ls -l /etc/nginx/*.au-team.irpo.*           # web/docker .crt и .key
cat /etc/nginx/.htpasswd                    # WEB:$apr1$...

# без пароля — 401, с паролем — 200
curl -k -s -o /dev/null -w "%{http_code}\n" --resolve web.au-team.irpo:443:127.0.0.1 https://web.au-team.irpo/
curl -k -u WEB:P@ssw0rd -s -o /dev/null -w "%{http_code}\n" --resolve web.au-team.irpo:443:127.0.0.1 https://web.au-team.irpo/
curl -k -s -o /dev/null -w "%{http_code}\n" --resolve docker.au-team.irpo:443:127.0.0.1 https://docker.au-team.irpo/   # 200
openssl s_client -connect 127.0.0.1:443 -servername web.au-team.irpo </dev/null 2>/dev/null | grep -E 'Cipher|subject'   # шифр GOST, CN web

Блок 4. HQ-CLI — доверие к CA, принтер, Кибер Бэкап

Команды проверки на HQ-CLI
ls -l /etc/pki/ca-trust/source/anchors/ca.crt
trust list | grep -i -A2 'Internal-CA'      # CA в системном хранилище
curl -s -o /dev/null -w "%{http_code}\n" --resolve web.au-team.irpo:443:172.16.2.1 -u WEB:P@ssw0rd https://web.au-team.irpo/   # 200 без -k (адрес ISP со стороны BR)

lpstat -p Cups-PDF -d                       # принтер подключён, по умолчанию
echo test | lp -d Cups-PDF                  # задание ушло, PDF появится на HQ-SRV в /var/spool/cups-pdf/…

systemctl list-units --no-pager | grep -i -E 'acronis|cyber'   # службы агента и узла хранения active
ls -la /backup                              # каталоги архивов после первого запуска плана
du -sh /backup

# В веб-консоли https://192.168.1.10:9877 (irpoadmin): Settings → Storage nodes — hq-cli;
# Backup storage — хранилище /backup; Plans — план /etc для HQ-SRV; Activities — статус «Успешно».