Автоматическая загрузка правил для iptables |
![]() |
Добавил(а) microsin |
С некоторых пор мой сайт перестал справляться с нагрузкой. И как временную меру решил ограничить к нему доступ только для выделенных IP-адресов (публичный адрес домашней сетки, и адрес сети на работе). Для этого понадобилось загрузить в правила iptables публичный список адресов сканирования Google [1], представленный в формате JSON. План такой: 1. Подготовить файл со списком разрешенных IP-адресов. Каждая строка в этом файле должна состоять из адреса сети и маски подсети: a.b.b.d/mask. Пример такого файла enabledIP: # Возможно моя домашняя сеть будет среди этих IP:
95.31.169.0/24
# Публичные адреса сети на работе:
213.87.55.0/27
2. Загрузить список адресов ботов Google по ссылке [1] с помощью команды wget, сохранить его в файл. 3. Обработать загруженный на шаге 2 файл командой grep так, чтобы получился список из IP-адресов IPv4 с масками подсети, аналогичный списку сетей шага 1, и сохранить этот список в отдельный файл googleIP. 4. Сбросить текущие цепочки правил iptables командой iptables -F [2]. iptables -F
5. Загрузить для iptables в качестве разрешающих правил доступа подготовленные списки адресов enabledIP и googleIP, подготовленные на шагах 1 и 3. Загрузка адресов будет производиться командой: iptables -I INPUT -s a.b.c.d/mask -j ACCEPT
Здесь "a.b.c.d/mask" это строка из файлов enabledIP и googleIP. 6. Добавить для iptables правило, отбрасывающее посторонний трафик командой: iptables -A INPUT -p tcp --dport 80 -j DROP
[Реализация] В результате получилась вот такая несложная программа: // Эта программа была сделана для автоматического создания
// правил iptables из файла публичных адресов ботов Google,
// которые сканируют доступность сайтов. Этот файл доступен
// по ссылке:
// https://developers.google.com/search/apis/ipranges/googlebot.json
#include < stdio.h>
#include < stdlib.h>
#include < string.h>
#include < regex.h>
#include < stdbool.h>
#include < unistd.h>
#define GOOGLEBOTFILE "googlebot.json"
#define GOOGLEBOTFILECPY "googlebot.json.cpy"
#define GOOGLEBOTURL "https://developers.google.com/search/apis/ipranges/googlebot.json" #define REGEXP "\"([0-9]{1,3}[\\.]){3}[0-9]{1,3}/[0-9]{1,2}\""
#define ENABLEDIPLIST "enabledIP"
#define GOOGLEIPLIST "googleIP"
bool fileexist (char *fn) { if (0 == access(fn, F_OK)) return true; else return false; } bool downloadGoogleList (char *gfn) { char command[256]; // Закачка файла: strcpy(command, "wget "); strcat(command, GOOGLEBOTURL); system(command); return fileexist(gfn); } void copyfile (char *src, char *dst) { char command[256]; strcpy(command, "cat "); strcat(command, src); strcat(command, " >"); strcat(command, dst); system(command); } void makelist (char *src, char *dst) { char command[256]; strcpy(command, "grep -E -o "); strcat(command, REGEXP); strcat(command, " "); strcat(command, src); strcat(command, " >"); strcat(command, dst); system(command); } void removefile (char *fn) { char command[256]; strcpy(command, "rm "); strcat(command, fn); system(command); } void iptables_flush (void) { char command[256]; strcpy(command, "iptables -F"); system(command); } void trim (char *s) { int i, j; // Удаляем пробелы, табы, CR, LF с начала строки: i = 0; while ((' '==s[i])||('\t'==s[i])||('\r'==s[i])||('\n'==s[i])) i++; if (i>0) { for(j=0; j < strlen(s); j++) { s[j] = s[j+i]; } s[j] = 0; } // Удаляем пробелы, табы, CR, LF с конца строки: i = strlen(s)-1; while ((' '==s[i])||('\t'==s[i])||('\r'==s[i])||('\n'==s[i])) i--; if (i < (strlen(s)-1)) s[i+1] = '\0'; } void iptables_load_list (char *list) { char command[256]; FILE *fin; char temp[80]; char *readresult; fin = fopen(list, "r"); if (NULL == fin) return; // Обработаем список адресов построчно, и сформируем // из его строк команды для iptables. while(1) { readresult = fgets(temp, sizeof(temp)-1, fin); if (NULL == readresult) break; trim(readresult); // Пропуск пустых строк и строк комментариев: if ((0 == strlen(readresult)) || ('#' == readresult[0])) continue; strcpy(command, "iptables "); strcat(command, "-I INPUT -s "); strcat(command, readresult); strcat(command, " -j ACCEPT"); printf("%s\n", command); system(command); } fclose(fin); } void iptables_restore (char *list) { char command[256]; // Добавление списка разрешенных адресов. iptables_load_list(list); // Всезапрещающее правило должно быть последним. strcpy(command, "iptables -A INPUT -p tcp --dport 80 -j DROP"); printf("%s\n", command); system(command); } int main (int argc, char **argv) { // Если файл закачался, то продолжим. if (!downloadGoogleList(GOOGLEBOTFILE)) { printf("%s download error\n", GOOGLEBOTFILE); return 1; } // Сделаем копию файла: copyfile(GOOGLEBOTFILE, GOOGLEBOTFILECPY); // Обработка файла командой grep, чтобы // выделить адреса: makelist(GOOGLEBOTFILE, GOOGLEIPLIST); // Удалим закачанный файл: removefile (GOOGLEBOTFILE); // Сброс правил iptables: iptables_flush(); // Загрузка новых правил: iptables_load_list(GOOGLEIPLIST); // В конец добавятся правил из разрешенного списка, // и правило для запрета посторонних обращений. iptables_restore(ENABLEDIPLIST); return 0; } [Дополнительная информация] Как компилировать программу: gcc mkiprules.c -o mkiprules
Как запускать (нужны права администратора): ./mkiprules
После этого можно сделать загруженные правила постоянными командой: iptables-save > /var/путь_до_автоматически_загружаемых_правил
Проверить корректность загрузки правил можно командой: iptables -S
[Ссылки] 1. https://developers.google.com/search/apis/ipranges/googlebot.json. |