Комментарии 26
В вашем случае лучше сделать правило:
-A INPUT -p tcp -m set --match-set cloudflare src -m multiports --dports 80,443 -j ACCEPT
А в скрипте поддерживать два сета (cloudflare и temp_cloudflare), свопая их содержимое.
В дополнение могу сказать что надо в конфиге ipset (/etc/sysconfig/ipset-config для CentOS) указать
IPSET_SAVE_ON_STOP="yes"
Ну и скрипт будет выглядеть:
#!/bin/bash
while read ip ; do ipset -A cloudfare "$ip" ; done <<< "$(curl https://www.cloudflare.com/ips-v4)"
Используйте отдельную цепочку, чтобы очищать её всю, когда нужно, и вы избежите проблемы, описанной выше — это два.
Используйте ipset вместо индивидуальных правил — это три, и об этом Cloudflare написал в заметке, на которую вы ссылаетесь.
Вашу заметку можно было свести к пункту 4.
0 */12 * * * root /root/cloudflare-update.sh &> /dev/null, потому что всё остальное Сloudflare описал.
Надо на всякий случай попробовать). Но лучше всё таки не компрометировать адрес. Например если придёт много трафика на порт будет уже сложно что-то сделать, провайдер пошлет его например в блекхол, ресурс потухнет и придется менять срочно адрес(.
IP вашего сайта станет IP вашего сервера.
А к нему доступ запрещён для всех кроме Cloudflare.
То есть, к вашему решению полезно ещё добавить проверку, что сайт пока еще проксируется Cloudflare.
Если в правилах iptables начинают появляться длинные списки IP-адресов, надо начинать использовать ipset. Кроме того, это позволяет добалять/удалять адреса не перегружая все правила iptables целиком.
Для сабжа в CloudFlare есть Authenticated Origin Pulls. Что позволяет отклонять все запросы без клиентского сертификата, подписанного Cloudflare CA. Это решение желательно попробовать в первую очередь, потому что оно проще. По желанию, можно ограничить доступ на уровне сети, как сделал автор — это безопаснее, имхо, но сложнее сделать правильно.
Удалять тоже можно аккуратно.
Да и стоило бы проверить что там вернул curl.
Как-то так (10 минут на коленке)
#!/bin/bash
IPTABLESCHAIN="CLOUDFLARE"
PREVLIST_MD5_FILENAME="lastchangedlist.md5"
[ -e "${PREVLIST_MD5_FILENAME}" ] && PREVMD5SUM=$(cat "${PREVLIST_MD5_FILENAME}")
IPLIST=$(curl -s https://www.cloudflare.com/ips-v4 2>/dev/null)
if [ -z "${IPLIST}" ] ; then
echo -e "Hell! CF didn't give me IP list!"
exit 1
fi
# Who know what CF return to me? I need only IPv4 networks
IPLIST=$(echo "${IPLIST}" | grep -o '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}\(/[0-9]\{1,2\}\)\{0,1\}' | sort -t '.' -nk1,1 -nk2,2 -nk3,3 -nk4,4)
MD5SUM=$(echo "${IPLIST}" | md5sum | awk '{print $1}') #' I need only md5sum
if [ "${MD5SUM}" == "${PREVMD5SUM}" ] ; then
# everything fine. No changes.
exit 0
fi
ACTIVERULESLIST=$(iptables -nL "${IPTABLESCHAIN}" | awk '/^ACCEPT/{print $4}' | sort -t '.' -nk1,1 -nk2,2 -nk3,3 -nk4,4)
NONUNIQ=$(echo "${ACTIVERULESLIST}" | uniq -c | awk '{if($1!=1){print}}') #'
if [ -n "${NONUNIQ}" ] ; then
echo -e "In ${IPTABLESCHAIN} chain found non unique values:\n${NONUNIQ}"
fi
while read IPNET ; do
# check if ipv4 is valid
ipcalc --silent -b "${IPNET}" >/dev/null
if [ "${?}" -ne 0 ] ; then
echo "[ERROR] \"${IPNET}\" is invalid. Skip."
continue
fi
IPNETREGEX=$(echo "${IPNET}" | sed -e 's/\./\\./g')
ALREADY=$(echo "${ACTIVERULESLIST}" | grep "^${IPNETREGEX}$")
if [ "${ALREADY}" == "${IPNET}" ] ; then
# echo "Already active ${IPNET}"
ACTIVERULESLIST=$(echo "${ACTIVERULESLIST}" | grep -v "^${IPNETREGEX}$")
continue
fi
COLLECTEDIPLIST="${COLLECTEDIPLIST}\n${IPNET}"
echo "iptables -I ${IPTABLESCHAIN} 1 \"${IPNET}\" -J ACCEPT -m comment --comment \"CloudFlare CDN\""
done < <(echo "${IPLIST}")
# delete everything what not in current ip network list
while read IPNET ; do
echo "iptables -D CLOUDFLARE -s ${IPNET} -j ACCEPT"
done < <(echo "${ACTIVERULESLIST}")
echo -e "${MD5SUM}" > "${PREVLIST_MD5_FILENAME}"
Можно ещё посчитать количество изменений чтобы вдруг не грохнуть большое количество.
И добавил немного информации в logger -t CFiptablesUpdater чтобы в случае аварии можно было найти причину.
А если на сервере закрыть вообще все порты, отключить ICMP и реализовать доступ только через IPMI/VNC, никто не узнает, что на нашем IP вообще что-то существует.Если у вас на сервере будут закрыты все порты, то толку в нём никакого.
У CloudFlare есть огромное количество адресов, но все они ужимаются в небольшое количество подсетей....Для этого обычно доменное имя переносят на DNS защищающей компании.
Теперь попасть по 80 и 443 портам на ваш сервер можно только через проксиНе совсем так. Точнее совсем не так. На то есть несколько причин.
1 Команда zmap -N 50000 -B 10M -p 80 -i eth0 выдаст 50000 адресов серверов с открытым 80-м портом и не исключено, что там может оказаться ваш.
2 Есть такие атаки, от которых файервол сервера не поможет. Атаки на исчерпание канала — пинг смерти или хороших поток мусорных пакетов udp либо даже gre (лично наблюдал атаку пакетами gre).
3 Iptables относится к Stateful Firewall в случае пакетов tcp зависит от трехстороннего обмена во время установления соединения. Поэтому хорошей низкоуровневой атакой можно хорошенько положить файервол сервера.
Почему написал это опус? Не стоит думать, что став под защиту решили одним махом все проблемы и теперь у Христа за пазухой. Сетевой адрес сервера может быть засвечен тем или иным способом и поэтому стоит быть готовым к неожиданностям.
Держите классическую схему — все веб-сервера — во внутренней ДМЗ на приватных ИП и только хорошо защищенная иптаблесом, naxsi и прочими вещами реверс-прокси — торчит наружу паблик-ИПом. И не надо будет гнуть велосипед — снаружи никто не подключится.
Дык вся статья про то, как настроить иптаблес так, чтоб принимать трафик только от прокси КлаудФар. То есть по сути предлагается переложить на них ответственность за проверку трафика. И на них проблемы с ДДоСом.
Ну узнать кому принадлежит сеть и начать ее ДДоСить вообще не проблема и для этого ип сайта вычислять не нужно, если у компании есть своя AS и ИПы. И Клаудфар тут не спасет, потому что просто проведут атаку на весь пул адресов, по-любому забивая канал. Так что нафига такие ухищрения, чтобы скрыть ИП — лично мне не осень понятно. Только если нет своей AS такие ухищрения помогут.
А все и не надо — делаешь трассировку нескольких ИПов ренджа с начала и до конца чтоб определить, через какого провайдера идет маршрут и если всегда через одного и того же — смело ддосишь один ип, забивая весь канал. Но в случае с арендованными ИПами — да, поможет, согласен. Я просто даже не предполагал, что если у кого-то серьезный проект — у них нет своих AS. и IP.
Даже когда много каналов обычно выбирается кратчайший маршрут на основе Full BGP Views поэтому между одинаковыми ИПами маршрут один и тот же даже если удаленный роутер настроен на мультихоп и кидает в произвольном порядке пакеты в каждый аплинк. Между ним и получателем куча провайдеров которые обычно еще и свои локал преференсы выстраивают и в итоге маршрут оказывается один и тот же, так что бомбить будет один из каналов, да, второй останется доступен но только тем клиентам, кому посчастливилось попасть в него в силу своих таблиц маршрутизации провайдеров.
Разрешаем доступ к веб-серверу только через CloudFlare (iptables)