273 lines
11 KiB
Bash
273 lines
11 KiB
Bash
#!/bin/bash
|
||
# ============================================================
|
||
# ЗАДАНИЕ 1. Настройка HQ-RTR (Linux / РЕД ОС 8)
|
||
# Имя, net_admin, интерфейс к ISP, VLAN 100/200/999 на ОДНОМ адаптере,
|
||
# GRE-туннель до BR-RTR, OSPF (MD5) в туннеле, NAT, DHCP для VLAN 200,
|
||
# часовой пояс.
|
||
# ============================================================
|
||
|
||
# --- Проверка прав root ---
|
||
if [[ $EUID -ne 0 ]]; then
|
||
echo "Запустите скрипт с правами root (sudo bash hq-rtr.sh)"
|
||
exit 1
|
||
fi
|
||
|
||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||
HOSTNAME_FQDN="hq-rtr.au-team.irpo" # таблица 3, запись hq-rtr.au-team.irpo
|
||
|
||
# --- Пользователь net_admin (значения из задания) ---
|
||
NET_ADMIN_USER="net_admin"
|
||
NET_ADMIN_PASS="P@ssw0rd"
|
||
|
||
# --- Интерфейс в сторону ISP ---
|
||
ISP_IF="enp0s3" # 1-й NIC — к ISP (если порядок иной — поменять)
|
||
ISP_NET="172.16.1.2/28" # адрес HQ-RTR в сети линка (по заданию 172.16.1.0/28, .2 = HQ-RTR)
|
||
ISP_GW="172.16.1.1" # шлюз — адрес ISP в этой же сети
|
||
DNS_ROUTER="8.8.8.8" # внешний DNS для роутера (можно заменить, оставить пустым чтобы убрать)
|
||
|
||
# --- Единственная адресная переменная: базовая сеть офиса HQ ---
|
||
# Схема (соответствует размерам задания): VLAN100 = +0 /27, VLAN200 = +32 /28,
|
||
# VLAN999 = +48 /29; роутер = первый адрес сети, сервер = второй.
|
||
HQ_BASE="10.10.100.0/24" # поменяйте на свой расчёт при необходимости
|
||
|
||
# --- Локальные VLAN на ОДНОМ физическом адаптере ---
|
||
LAN_IF="enp0s8" # 2-й NIC — физический адаптер в сторону HQ-SW (для VLAN 100/200/999)
|
||
|
||
# --- GRE-туннель до BR-RTR (сеть 10.10.10.0/24, минимальная маска -> /30) ---
|
||
GRE_IF="gre1"
|
||
# GRE_LOCAL берётся из HQ_BASE-схемы (см. Автозаполнение ниже)
|
||
GRE_REMOTE="172.16.2.2" # удалённый конец — адрес BR-RTR в сети линка к ISP
|
||
|
||
# --- OSPF (значения из задания) ---
|
||
OSPF_PASSWORD="P@ssw0rd"
|
||
OSPF_AREA="0.0.0.0"
|
||
# ПРОВЕРИТЬ на РЕД ОС 8: пакет, конфиг и службу OSPF (frr / quagga)
|
||
FRR_PACKAGE="frr"
|
||
FRR_CONF="/etc/frr/frr.conf"
|
||
FRR_DAEMONS="/etc/frr/daemons"
|
||
|
||
# --- NAT в сторону ISP (адресации не содержит) ---
|
||
# Список сетей офиса для NAT — адреса сетей с префиксом (для правил iptables).
|
||
# NAT-сети ВЫЧИСЛЯЮТСЯ автоматически из VLAN-адресов ниже (после проверок)
|
||
|
||
# --- DHCP для VLAN 200 (клиент — HQ-CLI) ---
|
||
DHCP_PACKAGE="dhcp-server" # ПРОВЕРИТЬ: пакет DHCP-сервера в РЕД ОС 8
|
||
DHCPD_SERVICE="dhcpd" # ПРОВЕРИТЬ: имя службы
|
||
DHCPD_CONF="/etc/dhcp/dhcpd.conf"
|
||
# Параметры DHCP ВЫЧИСЛЯЮТСЯ автоматически из VLAN200_ADDR (после проверок):
|
||
# subnet/маска — из адреса, range — со следующего после адреса HQ-RTR (тем самым
|
||
# адрес роутера исключается из выдачи), последний — broadcast-1.
|
||
DHCP_DOMAIN="au-team.irpo"
|
||
# (адрес HQ-SRV для DNS-опции DHCP берётся из HQ_BASE-схемы автоматически)
|
||
|
||
# --- Прочее ---
|
||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||
FORWARD_CONF="/etc/sysctl.d/99-ip-forward.conf" # перезаписывается целиком
|
||
NM_CONF_DIR="/etc/NetworkManager/system-connections"
|
||
IPTABLES_SERVICE="iptables" # ПРОВЕРИТЬ
|
||
|
||
# ============ Проверка заполнения переменных ============
|
||
MISSING=()
|
||
for NAME in HOSTNAME_FQDN ISP_IF ISP_NET ISP_GW LAN_IF HQ_BASE EXAM_TZ; do
|
||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||
done
|
||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||
exit 1
|
||
fi
|
||
|
||
# ==== Автозаполнение адресации (план по схеме — tools/subnets.py) ====
|
||
REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||
eval "$(python3 "$REPO_ROOT/tools/subnets.py" hq "$HQ_BASE")"
|
||
GRE_LOCAL="$GRE_LOCAL_HQ"
|
||
echo "Адресация: VLAN100=$VLAN100_NET VLAN200=$VLAN200_NET VLAN999=$VLAN999_NET"
|
||
echo "GRE: local=$GRE_LOCAL remote=$GRE_REMOTE"
|
||
|
||
# ==== Сети офиса для NAT — из адресов VLAN ====
|
||
NAT_NETS="$VLAN100_NET $VLAN200_NET $VLAN999_NET"
|
||
# Параметры DHCP для VLAN 200: subnet, маска, первый/последний адрес выдачи
|
||
read -r DHCP_SUBNET DHCP_NETMASK DHCP_RANGE_FIRST DHCP_RANGE_LAST <<< "$(python3 -c "
|
||
import ipaddress, sys
|
||
a = ipaddress.ip_interface(sys.argv[1])
|
||
n = a.network
|
||
first = int(a.ip) + 1
|
||
last = int(n.broadcast_address) - 1
|
||
print(n.network_address, n.netmask, ipaddress.ip_address(first), ipaddress.ip_address(last))" "$VLAN200_ADDR")"
|
||
echo "DHCP: subnet=$DHCP_SUBNET mask=$DHCP_NETMASK range=$DHCP_RANGE_FIRST..$DHCP_RANGE_LAST"
|
||
|
||
|
||
echo "=== Настройка HQ-RTR ==="
|
||
|
||
# --- 1. Имя хоста ---
|
||
hostnamectl set-hostname "$HOSTNAME_FQDN"
|
||
echo "Имя хоста: $(hostname)"
|
||
|
||
# --- 2. Пользователь net_admin с sudo без пароля ---
|
||
echo "--- Пользователь $NET_ADMIN_USER ---"
|
||
if id "$NET_ADMIN_USER" &>/dev/null; then
|
||
echo "Пользователь уже существует"
|
||
else
|
||
useradd -m "$NET_ADMIN_USER"
|
||
fi
|
||
echo "$NET_ADMIN_USER:$NET_ADMIN_PASS" | chpasswd
|
||
# Файл в sudoers.d перезаписывается целиком — дублей нет
|
||
echo "$NET_ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/net_admin
|
||
chmod 440 /etc/sudoers.d/net_admin
|
||
echo "Проверка: su - $NET_ADMIN_USER -c 'sudo -n true && echo sudo OK'"
|
||
|
||
# --- 3. Интерфейс в сторону ISP ---
|
||
echo "--- Профиль $ISP_IF (статика, шлюз $ISP_GW) ---"
|
||
cat > "$NM_CONF_DIR/$ISP_IF.nmconnection" <<EOF
|
||
[connection]
|
||
id=$ISP_IF
|
||
type=ethernet
|
||
autoconnect=yes
|
||
interface-name=$ISP_IF
|
||
|
||
[ethernet]
|
||
|
||
[ipv4]
|
||
address1=$ISP_NET
|
||
gateway=$ISP_GW
|
||
method=manual
|
||
|
||
[ipv6]
|
||
method=disabled
|
||
|
||
[proxy]
|
||
EOF
|
||
chmod 600 "$NM_CONF_DIR/$ISP_IF.nmconnection"
|
||
|
||
# --- 4. VLAN-интерфейсы (100/200/999) на одном физическом адаптере ---
|
||
make_vlan_profile () {
|
||
printf '%s\n' \
|
||
"[connection]
|
||
id=$1
|
||
type=vlan
|
||
autoconnect=yes
|
||
interface-name=$1
|
||
|
||
[vlan]
|
||
parent=$LAN_IF
|
||
id=$2
|
||
|
||
[ipv4]
|
||
address1=$3
|
||
method=manual
|
||
|
||
[ipv6]
|
||
method=disabled
|
||
|
||
[proxy]" > "$NM_CONF_DIR/$1.nmconnection"
|
||
chmod 600 "$NM_CONF_DIR/$1.nmconnection"
|
||
}
|
||
echo "--- VLAN 100 ---"; make_vlan_profile vlan100 100 "$VLAN100_ADDR"
|
||
echo "--- VLAN 200 ---"; make_vlan_profile vlan200 200 "$VLAN200_ADDR"
|
||
echo "--- VLAN 999 ---"; make_vlan_profile vlan999 999 "$VLAN999_ADDR"
|
||
|
||
# --- 5. GRE-туннель ---
|
||
echo "--- Туннель $GRE_IF ---"
|
||
cat > "$NM_CONF_DIR/$GRE_IF.nmconnection" <<EOF
|
||
[connection]
|
||
id=$GRE_IF
|
||
type=ip-tunnel
|
||
autoconnect=yes
|
||
interface-name=$GRE_IF
|
||
|
||
[ip-tunnel]
|
||
mode=gre
|
||
remote=$GRE_REMOTE
|
||
|
||
[ipv4]
|
||
address1=$GRE_LOCAL
|
||
method=manual
|
||
|
||
[ipv6]
|
||
method=disabled
|
||
|
||
[proxy]
|
||
EOF
|
||
chmod 600 "$NM_CONF_DIR/$GRE_IF.nmconnection"
|
||
|
||
nmcli connection reload
|
||
for C in "$ISP_IF" vlan100 vlan200 vlan999 "$GRE_IF"; do
|
||
nmcli connection up "$C" || echo "ВНИМАНИЕ: не поднялся профиль $C"
|
||
done
|
||
|
||
# --- 6. IP forwarding ---
|
||
echo "net.ipv4.ip_forward = 1" > "$FORWARD_CONF"
|
||
sysctl -p "$FORWARD_CONF"
|
||
|
||
# --- 7. NAT в сторону ISP ---
|
||
echo "--- NAT (MASQUERADE) ---"
|
||
for SRC_NET in $NAT_NETS; do
|
||
if iptables -t nat -C POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE 2>/dev/null; then
|
||
echo "Правило для $SRC_NET уже есть"
|
||
else
|
||
iptables -t nat -A POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE
|
||
echo "Добавлено MASQUERADE для $SRC_NET"
|
||
fi
|
||
done
|
||
iptables-save > /etc/sysconfig/iptables
|
||
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|
||
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
|
||
|
||
# --- 8. OSPF в туннеле с аутентификацией MD5 ---
|
||
echo "--- OSPF (${FRR_PACKAGE}) ---"
|
||
dnf install -y "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $FRR_PACKAGE не установился"
|
||
# Сеть туннеля вычисляем из адреса туннеля (нужен python3)
|
||
TUN_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$GRE_LOCAL")
|
||
cat > "$FRR_CONF" <<EOF
|
||
frr version 8
|
||
frr defaults traditional
|
||
hostname $(hostname -s)
|
||
service integrated-vtysh-config
|
||
!
|
||
router ospf
|
||
passive-interface default
|
||
no passive-interface $GRE_IF
|
||
network $TUN_NET area $OSPF_AREA
|
||
!
|
||
interface $GRE_IF
|
||
ip ospf authentication message-digest
|
||
ip ospf message-digest-key 1 md5 $OSPF_PASSWORD
|
||
!
|
||
EOF
|
||
# Включаем нужные демоны frr (zebra + ospfd) — файл правим точечно, без дублей
|
||
if [[ -f "$FRR_DAEMONS" ]]; then
|
||
sed -ri 's/^zebra=.*/zebra=yes/; s/^ospfd=.*/ospfd=yes/' "$FRR_DAEMONS"
|
||
fi
|
||
systemctl enable --now "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: служба $FRR_PACKAGE не запустилась"
|
||
|
||
# --- 9. DHCP для VLAN 200 ---
|
||
echo "--- DHCP ($DHCP_PACKAGE) ---"
|
||
dnf install -y "$DHCP_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $DHCP_PACKAGE не установился"
|
||
cat > "$DHCPD_CONF" <<EOF
|
||
# Клиент HQ-CLI получает адрес из указанного range.
|
||
# Адрес HQ-RTR в выдачу не попадает (он вне range) — это и есть исключение.
|
||
subnet $DHCP_SUBNET netmask $DHCP_NETMASK {
|
||
range $DHCP_RANGE_FIRST $DHCP_RANGE_LAST;
|
||
option routers $VLAN200_ADDR; # шлюз — HQ-RTR (его адрес в VLAN 200)
|
||
option domain-name-servers $HQ_SRV_IP;
|
||
option domain-name "$DHCP_DOMAIN";
|
||
}
|
||
EOF
|
||
systemctl enable --now "$DHCPD_SERVICE" || echo "ПРОВЕРИТЬ: служба $DHCPD_SERVICE не запустилась"
|
||
|
||
# --- 10. Часовой пояс ---
|
||
timedatectl set-timezone "$EXAM_TZ"
|
||
|
||
echo ""
|
||
echo "=== Самопроверка для HQ-RTR ==="
|
||
ip -4 -br address show
|
||
echo ""
|
||
echo "Правила NAT:"
|
||
iptables -t nat -L POSTROUTING -n -v
|
||
echo ""
|
||
echo "Дополнительные проверки вручную:"
|
||
echo " nmcli connection show (все профили активны?)"
|
||
echo " ip -4 addr show $GRE_IF (туннель поднят?)"
|
||
echo " vtysh -c 'show ip ospf neighbor' (сосед BR-RTR в состоянии FULL?)"
|
||
echo " ss -clip -n | grep 67 (DHCP слушает?)"
|
||
echo " ping -c2 $ISP_GW (шлюз ISP доступен?)"
|