Брандмауэр с проверкой IP‑адресов

Сначала задайте приоритет правил и безопасное поведение при ошибках. Ниже действует первое совпадение, по умолчанию доступ запрещён; любой некорректный элемент делает весь набор недействительным.

Короткий ответ

Что ответить на собеседовании

Сначала задайте приоритет правил и безопасное поведение при ошибках. Ниже действует первое совпадение, по умолчанию доступ запрещён; любой некорректный элемент делает весь набор недействительным.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать программу, имитирующую работу брандмауэра. Программа должна принимать набор правил, где каждое правило состоит из CIDR‑блока и действия ("ALLOW" или "DENY"). Основная функция должна проверять, разрешён ли заданный IP‑адрес согласно этим правилам, возвращая true для разрешённых и false для запрещённых. Также требуется корректно обрабатывать некорректные CIDR‑блоки и неизвестные действия.

package main

import (
  "fmt"
)

// Функция проверки разрешения IP-адреса
func IsAllowed(rules [][2]string, ip string) bool {
  // **Вставьте код проверки IP-адреса по правилам**
  return false
}

func main() {
    // **Пример входных данных:**
    // **Пример 1:**
    rules1 := [][2]string{
        {"192.168.1.0/24", "ALLOW"},
        {"10.0.0.0/16", "DENY"},
        {"8.8.8.8", "ALLOW"},
    }
    ip1 := "192.168.1.10" // ответ true

    // **Пример 2:**
    rules2 := [][2]string{
        {"192.168.1.0/24", "ALLOW"},
        {"10.0.0.0/16", "DENY"},
        {"8.8.8.8", "ALLOW"},
    }
    ip2 := "10.0.0.10" // ответ false

    // **Пример 3:**
    rules3 := [][2]string{
        {"192.168.1.0/24", "ALLOW"},
        {"10.0.0.0/16", "DENY"},
        {"8.8.8.8", "ALLOW"},
    }
    ip3 := "192.168.2.10" // ответ false

    processExample(rules1, ip1)
    processExample(rules2, ip2)
    processExample(rules3, ip3)
}

func processExample(rules [][2]string, ip string) {
    if IsAllowed(rules, ip) {
        fmt.Println("true")
    } else {
        fmt.Println("false")
    }
}

Ответ

Сначала задайте приоритет правил и безопасное поведение при ошибках. Ниже действует первое совпадение, по умолчанию доступ запрещён; любой некорректный элемент делает весь набор недействительным.

Пример принимает и CIDR, и одиночные IP из условия. Нужен импорт net/netip:

func IsAllowed(rules [][2]string, ip string) bool {
    addr, err := netip.ParseAddr(ip)
    if err != nil || addr.Zone() != "" { return false }
    addr = addr.Unmap()
    type rule struct { prefix netip.Prefix; allow bool }
    parsed := make([]rule, 0, len(rules))
    for _, r := range rules {
        if r[1] != "ALLOW" && r[1] != "DENY" { return false }
        prefix, err := netip.ParsePrefix(r[0])
        if err != nil {
            host, e := netip.ParseAddr(r[0])
            if e != nil || host.Zone() != "" { return false }
            host = host.Unmap()
            prefix = netip.PrefixFrom(host, host.BitLen())
        } else if prefix.Addr().Is4In6() {
            if prefix.Bits() < 96 { return false }
            prefix = netip.PrefixFrom(prefix.Addr().Unmap(), prefix.Bits()-96)
        }
        parsed = append(parsed, rule{prefix.Masked(), r[1] == "ALLOW"})
    }
    for _, r := range parsed {
        if r.prefix.Contains(addr) { return r.allow }
    }
    return false
}

Проверка всех правил до поиска исключает игнорирование ошибки после раннего ALLOW. IPv4-mapped IPv6 нормализуется; слишком широкий mapped-префикс отвергается. Для трёх примеров результат true, false, false. Bool-интерфейс не сообщает причину ошибки; для реального сервиса конфигурацию лучше валидировать один раз с возвратом error.

Источник: pkg.go.dev.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее