Продолжая «цикл» заметок (1, 2, 3, 4) хочу рассказать о новом опыте взаимодействия с «ИТ-Гигантом», который и самостоятельно создаёт большую нагрузку на сервис, чему мы обычно рады, и позволяет это делать своим клиентам, чему мы уже не очень рады.
Если в ситуации с гигантами, описанной здесь всё было довольно просто, или хотя бы допускало упрощение вида «мы не рады всем обращениями из автономок этой конторы», то с Google ситуация иная. Googlebot — посетитель желанный и в общем довольно тактичный, а вот клиенты Google Cloud Platform порой злоупотребляют. Как разделять запросы из автономных систем Google, если из инструментов есть только iptables, а веб-сервер сдаётся на 10K+ коннектах на 443 порт? Оказывается, корпорация добра дала нам инструмент, а именно списки адресов поискового робота и клиентов облачной платформы:
https://www.gstatic.com/ipranges/goog.json
Соответственно, мы можем попытаться сделать что-то такое:
# Пути к утилитам на всякий случай
IPTABLES="/sbin/iptables"
IPSET="/sbin/ipset"
CURL="/usr/bin/curl"
JQ="/usr/bin/jq"
# Скачивание актуальных JSON-файлов
GCP_JSON=$($CURL -s https://www.gstatic.com/ipranges/cloud.json)
GOOG_JSON=$($CURL -s https://www.gstatic.com/ipranges/goog.json)
# Извлечение IPv4-адресов
GCP_IPS=$(echo "$GCP_JSON" | $JQ -r '.prefixes[].ipv4Prefix // empty')
GOOG_IPS=$(echo "$GOOG_JSON" | $JQ -r '.prefixes[].ipv4Prefix // empty')
# Проверка, что данные успешно скачались и распарсились
if [ -z "$GCP_IPS" ] || [ -z "$GOOG_IPS" ]; then
echo "Ошибка: Не удалось получить или распарсить IP-адреса Google." >&2
exit 1
fi
# Создание временного набора ipset для GCP
$IPSET create gcp_block_temp hash:net maxelem 65536 2>/dev/null
$IPSET flush gcp_block_temp
# Шаг 1: Добавляем ВСЕ адреса Google Cloud в блок-лист
for ip in $GCP_IPS; do
$IPSET add gcp_block_temp $ip
done
# Шаг 2: Удаляем из блок-листа адреса, принадлежащие Google Bot
for ip in $GOOG_IPS; do
$IPSET del gcp_block_temp $ip 2>/dev/null
done
# Переименование/активация постоянного набора ipset
$IPSET create gcp_block hash:net maxelem 65536 2>/dev/null
$IPSET swap gcp_block_temp gcp_block
$IPSET destroy gcp_block_temp
# Применение правила в iptables (если его еще нет)
$IPTABLES -C INPUT -m set --match-set gcp_block src -j DROP 2>/dev/null
if [ $? -ne 0 ]; then
$IPTABLES -I INPUT -m set --match-set gcp_block src -j DROP
fi
Если всё хорошо, то код, сохранённый в скрипте с именем, например, /opt/ban_gcp.sh выполнится тихо, создаст ipset список с именем gcp_block и правило iptables.
Один забавный момент про maxelem 65536. Автономка алибабы в 65536 более не влезает. Кто посмеялся, тот молодец 🙂
Про
я и не говорю.
Ну а
0 12 * * * /opt/ban_gcp.sh
или даже
это тоже понятно. Говорят, гугл довольно часто оптимизирует адреса.
Чтопы повесить систему на место можно использовать такой скрипт:
# Пути к утилитам
IPTABLES="/sbin/iptables"
IPSET="/sbin/ipset"
echo "Удаление правил блокировки Google Cloud Platform..."
# 1. Удаляем правило из iptables, если оно существует
$IPTABLES -C INPUT -m set --match-set gcp_block src -j DROP 2>/dev/null
if [ $? -eq 0 ]; then
$IPTABLES -D INPUT -m set --match-set gcp_block src -j DROP
echo "[+] Правило INPUT удалено из iptables."
else
echo "[-] Правило в iptables не найдено."
fi
# 2. Уничтожаем основной список ipset
$IPSET list gcp_block >/dev/null 2>&1
if [ $? -eq 0 ]; then
$IPSET destroy gcp_block
echo "[+] Список gcp_block удален из ipset."
else
echo "[-] Список gcp_block в ipset не найден."
fi
# 3. На всякий случай уничтожаем временный список, если он остался после сбоя
$IPSET list gcp_block_temp >/dev/null 2>&1
if [ $? -eq 0 ]; then
$IPSET destroy gcp_block_temp
echo "[+] Оставшийся временный список gcp_block_temp удален."
fi
echo "Очистка успешно завершена. Доступ для GCP полностью восстановлен."
и сохранить его где-нибудь в /opt/unban_gcp.sh. В этом скрипте уже есть много всякого вывода просто потому что запускаться он скорее всего будет вручную, а не по cron, да и с первого раза у меня чего-то не вышло — пришлось для себя писать сообщения.
