Шукати в цьому блозі

пʼятниця, 20 вересня 2024 р.

Як зробити так щоб Linux віддавав перевагу IPv4 адресації, а не IPv6?

Багато провайдерів в Україні ще не надають користувачам IPv6. В принципі, в повсякденні, користувачі цього не помічають. Але є випадки коли все-ж-таки треба отримувати доступ до тих чи інших IPv6 ресурсів. В таких випадках доводиться користуватися Hurricane Electric’s IPv6 tunnel.

З помічених недоліків такого підходу можу визначити два. По-перше, це не дуже швидко. Але це не скарга, бо врешті-решт це безкоштовне рішення. І за це рішення можна лише подякувати. А по-друге, хоч все й чудово працює, але подекуди виникають певні труднощі, коли ресурси на кшталт Google починають активно перевіряти тебе "Підтвердьте, що ви не робот".

Підозрюю, що це виникає саме тому, що за замовчуванням Linux, як в принципі і більшість операційних систем, віддає перевагу саме IPv6. Але чи можна змінити таку поведінку і, в тому випадку коли ресурс має IPv4 та IPv6 адресацію, віддавати перевагу IPv4?

Поведінка за замовчуванням: getaddrinfo та RFC 3484

Виклик getaddrinfo(3) може повернути декілька відповідей. Відповідно до RFC 3484 ці відповіді мають бути відсортовані таким чином, щоб відповідь із найвищим показником успіху була першою у списку. RFC надає алгоритм для сортування.

Цей алгоритм сортування за замовчуванням і набір правил, що стоять за ним, призводять до того, що IPv6 завжди має перевагу перед IPv4:

…
EXAMPLES
       The default table according to RFC 3484 would be specified with the following configuration file:

           label  ::1/128       0
           label  ::/0          1
           label  2002::/16     2
           label ::/96          3
           label ::ffff:0:0/96  4
           precedence  ::1/128       50
           precedence  ::/0          40
           precedence  2002::/16     30
           precedence ::/96          20
           precedence ::ffff:0:0/96  10
…

Це визначає підмережі IPv6 та їхній пріоритет. IPv4 фактично є вбудованою підмножиною IPv6, і ::ffff:0:0/96 вказує 32-розрядну мережу, яка і є IPv4 (подивіться на шпаргалку RIPE щодо префіксів адрес IPv6, щоб дізнатися більше). Це означає, що, наприклад, адреса IPv6 ::ffff:192.168.0.2 і адреса IPv4 192.168.0.2 ідентичні.

Усвідомлюючи це, тепер ми розуміємо, чому перевага буде надаватися адресам IPv6, і бачимо, як можемо легко підвищити пріоритет для IPv4. Просто перетворимо пріоритет 10 на щось на зразок 100, що є вищим за будь-що інше.

Застосування конфігурації

Щоб застосувати конфігурацію, просто відредагуємо або створимо файл /etc/gai.conf і встановимо стандартну конфігурацію зі зміненим пріоритетом для IPv4:

label  ::1/128       0
label  ::/0          1
label  2002::/16     2
label ::/96          3
label ::ffff:0:0/96  4
precedence  ::1/128       50
precedence  ::/0          40
precedence  2002::/16     30
precedence ::/96          20
precedence ::ffff:0:0/96  100

Варто переконатися, що надано повну й правильну конфігурацію, оскільки якщо щось налаштовано в цьому файлі, усю конфігурацію за замовчуванням буде відкинуто.

Переконаємося, що все працює

Простий спосіб перевірки – просто побачити, який тип IP-адреси використовується під час запиту того чи іншого веб-сайту. В цьому прикладі надсилаємо запит до my.ip.fi через IPv4, потім через IPv6, а потім використовуючи типове значення:

$ SITE=my.ip.fi; curl -4 ${SITE} && curl -6 ${SITE} && curl ${SITE}
176.104.xxx.xxx
2001:470:64xx:xxxx:xxxx:xxxx:98b7:29cc
176.104.xxx.xxx

За замовчуванням тепер IPv4 🎉

четвер, 4 липня 2024 р.

Налаштування WireGuard-сервера на Mikrotik

Раніше я був поверхнево написав про Встановлення з'єднання wireguard між Mikrotik та Linux (Debian), але є нюанс… тоді була задача поєднати швиденько Linux-хост з Mikrotik-ом, але досконало вивчати нюанси було ліньки 😢

Але от нещодавно відбулася подія яка примусила більш докладно підійти до процесу: злетів офісний vpn-сервер на базі Debian і було прийнято рішення перенести конфігурацію на RB3011. Окрім того, що було піднято сервіси L2TP/IPSec та інші, також захотілося більш докладно підійти до WireGuard…

Що сказати, незважаючи на те, що MikroTIK молодці і доволі докладно підходять до написання документації, але не все, що хочеться там є. Доводиться притягати весь попередній досвід щоб розібратися що до чого і як. Звісно, можливо, десь є більш докладне документування (я переконаний, що є), але ж то було б не настільки цікавим процесом.

Що хотілося? Хотілося створити багато клієнтів, які б підключалися по wireguard і отримували через організований тунель доступ до ресурсів та до Інтернет.

Спочатку думалося, що можна створити один wireguard інтерфейс і до нього купу малу peer-ів, але… але щось в мене пішло не так. Нормально в такій схемі захотів працювати тільки перший peer, всі хто підключалися після нього чомусь пасли задніх, хоча трафік від них в wireguard-інтерфейсі через torch я бачив. Пляски з бубном не допомогали… можливо бубен був не тієї конструкції, можливо щось інше, але прийшов врешті-решт до схеми яка не те що запрацювала, а запрацювала майже ідеально.

Далі по кроках.

По-перше, під кожного клієнта створюємо окремий wireguard-інтерфейс. При цьому слухати будемо різні порти.

/interface wireguard
add listen-port=12001 mtu=1420 name=wireguard1
add listen-port=12005 mtu=1420 name=wireguard5
add listen-port=12009 mtu=1420 name=wireguard9
add listen-port=13231 mtu=1420 name=wireguard13

Далі до кожного інтерфейса додамо адресу в мережі /30, в якій молодшу адресу й надаму інтерфейсу:

/ip address
add address=192.168.77.1/30 interface=wireguard1
add address=192.168.77.5/30 interface=wireguard5
add address=192.168.77.9/30 interface=wireguard9
add address=192.168.77.13/30 interface=wireguard13

Далі для кожного інтерфейса створимо peer-а:

/interface wireguard peers
add allowed-address=0.0.0.0/0 client-address=192.168.77.2/30 client-endpoint=NA.NB.NC.ND client-keepalive=20s interface=wireguard1 is-responder=yes name=peer-2 private-key=auto
add allowed-address=0.0.0.0/0 client-address=192.168.77.6/30 client-endpoint=NA.NB.NC.ND client-keepalive=20s interface=wireguard5 is-responder=yes name=peer6  private-key=auto
add allowed-address=0.0.0.0/0 client-address=192.168.77.10/30 client-endpoint=NA.NB.NC.ND client-keepalive=20s interface=wireguard9 is-responder=yes name=peer-10 private-key=auto
add allowed-address=0.0.0.0/0 client-address=192.168.77.14/30 client-endpoint=NA.NB.NC.ND client-keepalive=20s interface=wireguard13 is-responder=yes name=peer-10 private-key=auto

Тут NA.NB.NC.ND це ip-адреса серверної частини WireGuard.

В принципі все, що стосується налаштування саме серверної частини WireGuard ми фактично зробили. Ми створили клієнтів яким дозволили через тунель весь трафік (тобто не тільки приватні мережі, а й вихід до Інтернет).

Подивитися конфігурацію для налаштування клієнта, а також і QR-код, можна, наприклад, так:

/interface/wireguard/peers show-client-config number=[find interface=wireguard1 ]

або ж через winbox.

Тепер пару слів про налаштування файрволу. Звісно, що у кожного може бути своє бачення, але поділюся своїм. Весь файрвол, безумовно, наводити не стану, лише ту частину яка стосується саме WireGuard.

/interface list
add name=WIREGUARD
/interface list member
add interface=wireguard1 list=WIREGUARD
add interface=wireguard5 list=WIREGUARD
add interface=wireguard9 list=WIREGUARD
add interface=wireguard13 list=WIREGUARD
/ip firewall address-list
add address=192.168.77.0/24 list=WIREGUARD
/ip firewall filter
add action=accept chain=input in-interface-list=WIREGUARD
add action=jump chain=input in-interface-list=INTERNET jump-target=wireguard
add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface-list=WIREGUARD out-interface-list=LAN
add action=accept chain=forward in-interface-list=WIREGUARD out-interface-list=INTRANET
add action=accept chain=forward in-interface-list=WIREGUARD out-interface-list=INTERNET
add action=accept chain=wireguard dst-port=12001 protocol=udp
add action=accept chain=wireguard dst-port=12005 protocol=udp
add action=accept chain=wireguard dst-port=12009 protocol=udp
add action=accept chain=wireguard dst-port=12013 protocol=udp
/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=LAN src-address-list=WIREGUARD
add action=masquerade chain=srcnat out-interface-list=INTRANET src-address-list=WIREGUARD
add action=masquerade chain=srcnat out-interface-list=INTERNET src-address-list=WIREGUARD

Ідея, сподіваюся, є прозорою і зрозумілою, тому розжовувати що тут до чого, ну от не хочу.

От і все. В такій конфігурації клієнти (peer-и) чудово працюють паралельно, не заважаючи один одному.

Звісно, що порти та назви інтерфейсів кожен може взяти і обізвати так як йому зручно. Мені було зручно щоб був збіг з останнім октетом приватної адреси… якщо ж не вистачить то буде якось інакше.

Про налаштування кліантів на Android писати не стану там все не просто, а дуже просто: скануєте qr-код і все працює!

З очевидних недоліків такої конфігурації - дуже багато інтерфейсів і адрес, які треба прописати. Тому там де можна було введено list-и.

Очевидний плюс: простота налаштування клієнта - в переважній більшості все зводиться до простого сканування qr-кода.

вівторок, 23 квітня 2024 р.

dpkg-deb: error: archive '…skip….deb' uses unknown compression for member 'control.tar.zst', giving up

 За останні декілька днів вже два рази зіткнувся з помилкою "unknown compression for member" при встановленні deb-пакетів. Один раз це відбулося в Linux-контейнері FydeOS, другий раз в Debian Bullseye (11.9). І так, я цілком усвідомлюю, що є новіша версія Debian і там такої помилки не буде. Але що робити якщо є?

Було знайдено наступний "рецепт" (на прикладі apache-netbeans_21-1_all.deb):

$ mkdir apache-netbeans_21-1
$ cd apache-netbeans_21-1/
$ ln -s ../apache-netbeans_21-1_all.deb .
$ ar x apache-netbeans_21-1_all.deb
$ zstd -d < control.tar.zst | xz > control.tar.xz
$ zstd -d < data.tar.zst | xz > data.tar.xz
$ rm apache-netbeans_21-1_all.deb
$ ar -m -c -a sdsd apache-netbeans_21-1_all.deb debian-binary control.tar.xz data.tar.xz
$ rm debian-binary control.tar.xz data.tar.xz control.tar.zst data.tar.zst
$ sudo dpkg -i apache-netbeans_21-1_all.deb

субота, 6 квітня 2024 р.

Key is stored in legacy trusted.gpg keyring, see the DEPRECATION section in apt-key(8) for details

 Дано:

$ apt update
В кеші:1 http://raspbian.raspberrypi.org/raspbian bookworm InRelease
В кеші:2 http://archive.raspberrypi.org/debian bullseye InRelease                                                    
В кеші:3 https://download.docker.com/linux/raspbian bullseye InRelease                                               
Зчитування переліків пакунків... Виконано           
Побудова дерева залежностей... Виконано
Зчитування інформації про стан... Виконано   
1 package can be upgraded. Run 'apt list --upgradable' to see it.
W: http://raspbian.raspberrypi.org/raspbian/dists/bookworm/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.

"Ліки":

$ apt-key list | grep -A4 "trusted.gpg$"
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg
--------------------
pub   rsa2048 2012-04-01 [SC]
      A0DA 38D0 D76E 8B5D 6388  7281 9165 938D 90FD DD2E
uid           [невідома] Mike Thompson (Raspberry Pi Debian armhf ARMv6+VFP) <mpthompson@gmail.com>

$ sudo apt-key export 90FDDD2E | sudo gpg --dearmor -o /tmp/raspi.gpg
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).

$ file /tmp/raspi.gpg
/tmp/raspi.gpg: OpenPGP Public Key Version 4, Created Sun Apr  1 21:02:33 2012, RSA (Encrypt or Sign, 2048 bits); User ID; Signature; OpenPGP Certificate

$ sudo apt-key del 90FDDD2E
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK

$ sudo mv /tmp/raspi.gpg /etc/apt/trusted.gpg.d/

$ apt update
В кеші:1 http://archive.raspberrypi.org/debian bullseye InRelease
В кеші:2 https://download.docker.com/linux/raspbian bullseye InRelease                                              
В кеші:3 http://raspbian.raspberrypi.org/raspbian bookworm InRelease                                                
Зчитування переліків пакунків... Виконано        
Побудова дерева залежностей... Виконано
Зчитування інформації про стан... Виконано   
1 package can be upgraded. Run 'apt list --upgradable' to see it.

пʼятниця, 29 березня 2024 р.

Enable additional developer mode features: root file system write permission

 

Last Update: 2024-03-12

The following guide or recipe requires shell access to your FydeOS installation, therefore “developer mode” is assumed to be enabled.

In FydeOS, if you need to modify system files or perform custom operations, you must first disable root file system verification. This step is taken for security reasons, aimed at preventing system stability and security issues that could arise from unauthorized modifications. Here are the detailed instructions:

  1. Press Control + Alt + T on your FydeOS desktop to open the terminal.
  2. Type shell and hit Enter to access the shell environment.
  3. Enter sudo -i to get root permissions.
  4. Execute /usr/sbin/crossystem_mode-switch.sh disable-rootfs-verification to turn off root file system verification.
  5. Reboot your device.

середа, 27 березня 2024 р.

Налаштовуємо netfilter в Linux для виявлення потенційно небажаного трафіка

 Хочу поділится одним "рецептом", який алгоритм роботи якого вже доволі давно було опробовано на RouterOS і от лише нещодавно переписано під netfilter.

В чому полягає ідея?

До того як з'єднання буде встановлено у стан established перевірити потік трафіку, скажемо так, на періодичність доступу. Адже, давайте скажемо чесно, доступ до наших ресурсів (до нашого хоста) з тих чи інших адрес в Інтернет, на порти, на яких не задіяно жодних сервісів, завжди виглядає як не небажаним то підозрілим.

Що ми робимо? Ми організовуємо set-и з timeout-ами. Ці timeout-и можуть бути виставлені в доволі різні значення, але ідея полягає саме в тому, щоб обмежити доступ до хоста, якщо хтось доволі сильно знахабніє у встановлений час. Set-ів може бути багато, може бути мало, в прикладі їх наведено 16. За аналогією можна зробити 10, а можна зробити й 20, тут вже лише фантазія обмежує.

Від лірики до практики.

sudo nft add table ip scanDetector

Створимо "списки довіри". Хтось може обізвати whitelist, але я обізвав trusted та ignore, так вже історично склалося.

sudo nft add set ip scanDetector trusted { type ipv4_addr\; flags interval\; auto-merge\; comment \"Truster ip and net\" \; }
sudo nft add element ip scanDetector trusted { 192.168.1.0/24, 195.38.16.2, 195.38.16.8 }

sudo nft add set ip scanDetector ignore { type ipv4_addr\; flags interval\; auto-merge\; comment \"Ignore ip and net\" \; }
sudo nft add element ip scanDetector ignore { 0.0.0.0, 127.0.0.0/8 }

Тепер створимо set-и у створеній нами таблиці scanDetector:
sudo nft add set ip scanDetector level15 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 15\" \; timeout 1m \; }
sudo nft add set ip scanDetector level14 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 14\" \; timeout 2m \;  }
sudo nft add set ip scanDetector level13 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 13\" \; timeout 3m \;  }
sudo nft add set ip scanDetector level12 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 12\" \; timeout 4m \;  }
sudo nft add set ip scanDetector level11 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 11\" \; timeout 5m \;  }
sudo nft add set ip scanDetector level10 { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 10\" \; timeout 10m \;  }
sudo nft add set ip scanDetector level9  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 9\" \;  timeout 15m \;  }
sudo nft add set ip scanDetector level8  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 8\" \;  timeout 20m \; }
sudo nft add set ip scanDetector level7  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 7\" \;  timeout 30m \; }
sudo nft add set ip scanDetector level6  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 6\" \;  timeout 40m \; }
sudo nft add set ip scanDetector level5  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 5\" \;  timeout 50m \; }
sudo nft add set ip scanDetector level4  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 4\" \;  timeout 1h \; }
sudo nft add set ip scanDetector level3  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 3\" \;  timeout 1h10m \; }
sudo nft add set ip scanDetector level2  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 2\" \;  timeout 1h20m \; }
sudo nft add set ip scanDetector level1  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 1\" \;  timeout 1h30m \; }
sudo nft add set ip scanDetector level0  { type ipv4_addr\; flags dynamic\; comment \"SynScan Level 0\" \;  timeout 3h \; }
sudo nft add set ip scanDetector scan    { type ipv4_addr\; flags dynamic\; comment \"Scan Detect\" \;      timeout 31d \; }
"Повісимо" hook і дамо йому priority нижчий за той в якому робимо всі інші перевірки з контролю доступу:
sudo nft add chain ip scanDetector input { type filter hook input priority -50 \; }
Ну й нарешті правила, які контролюють всі пакети, які ще не пройшли перевірки, тобто мають state new, а не established, тощо:
do nft add rule scanDetector input ct state new ip saddr @trusted counter log return
sudo nft add rule scanDetector input ct state new ip saddr @ignore counter log return
sudo nft add rule scanDetector input ct state new ip saddr != @scan    ip saddr @level0  add @scan    { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level0  ip saddr @level1  add @level0  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level1  ip saddr @level2  add @level1  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level2  ip saddr @level3  add @level2  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level3  ip saddr @level4  add @level3  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level4  ip saddr @level5  add @level4  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level5  ip saddr @level6  add @level5  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level6  ip saddr @level7  add @level6  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level7  ip saddr @level8  add @level7  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level8  ip saddr @level9  add @level8  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level9  ip saddr @level10 add @level9  { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level10 ip saddr @level11 add @level10 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level11 ip saddr @level12 add @level11 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level12 ip saddr @level13 add @level12 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level13 ip saddr @level14 add @level13 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level14 ip saddr @level15 add @level14 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr != @level15                   add @level15 { ip saddr } counter
sudo nft add rule scanDetector input ct state new ip saddr @scan update @scan { ip saddr } counter log prefix \"[nft] scandetect-input-drop \" drop
sudo nft add rule scanDetector input              ip saddr @scan update @scan { ip saddr } counter log prefix \"[nft] scandetect-input-another-drop \" drop
Тобто, безумовно пропускаємо трафак з хостів та мереж, які було додано в set-и trusted та ignore.  Хости в списки level15…level0 додаються поступово. І це нормально. Не кожен хто до нас "стукає" може бути зловмисником. Але якщо стукає ну дуже вже нахабно то рано чи пізно він потрапить в список scan. Так, в set scan потрапляють лише і виключно ті хости, які були ну ду-у-у-у-уже нахабними. А вибратися з set-у scan не так вже й просто, бо якщо виявляється new-пакет з хоста, що вже є в set-і scan то час його перебування в списку оновлюється на початковий, той, що задано параметром timeout.
От такий от рецепт з блокування доступу.

Масштабуємо рішення на доступ до docker-контейнерів.

Все це добре, але щоб контролювати транзитний трафік hook на input нам не дуже підходить. То додаємо hook на forward:
sudo nft add chain ip scanDetector forward { type filter hook forward priority -50 \; }
Ну, а далі треба пройтися по інтерфейсах, на яких "живуть" docker-контейнери і на них "підвісити" правила. Для цього можна скористатися переглядом або всіх netfilter-правил:
sudo nft list ruleset
або ж лише тієї частки в яких задано chain DOCKER, в моєму випадку це:
sudo nft list table filter
То ж сформуємо правила:
for IFACE in $( sudo nft list table filter | sed '/chain DOCKER {/,/^$/!d;/^$/,$d' | awk '$4~/^oifname$/ { print $5 }' | tr -d \" | sort -u ); do
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr @trusted counter log return
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr @ignore counter log return
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @scan    ip saddr @level0  add @scan    { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level0  ip saddr @level1  add @level0  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level1  ip saddr @level2  add @level1  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level2  ip saddr @level3  add @level2  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level3  ip saddr @level4  add @level3  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level4  ip saddr @level5  add @level4  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level5  ip saddr @level6  add @level5  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level6  ip saddr @level7  add @level6  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level7  ip saddr @level8  add @level7  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level8  ip saddr @level9  add @level8  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level9  ip saddr @level10 add @level9  { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level10 ip saddr @level11 add @level10 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level11 ip saddr @level12 add @level11 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level12 ip saddr @level13 add @level12 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level13 ip saddr @level14 add @level13 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level14 ip saddr @level15 add @level14 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr != @level15                   add @level15 { ip saddr } counter
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE} ct state new ip saddr @scan update @scan { ip saddr } counter log prefix \"[nft] scandetect-forward-drop \" drop
    sudo nft add rule scanDetector forward iifname != ${IFACE} oifname ${IFACE}              ip saddr @scan update @scan { ip saddr } counter log prefix \"[nft] scandetect-forward-another-drop \" drop
done
Все, всі правила в table scanDetector сформовано. Заданий priority для chain нижчий за той, що задано hook-ами в table filter, відповідно й всі ці перевірки будуть виконуватися раніше. І лише після цих перевірок пакети потралятимуть на перевірку в table filter.

Подивитися на те, що вийшло

Всі set-и та правила:

sudo nft list table scanDetector

Подивитися на вміста set-у scan:

sudo nft list table scanDetector | sed '/set scan {/,/^$/!d;/^$/,$d'

Кількість елементів у set-і scan:

sudo nft list table scanDetector | sed '/set scan {/,/^$/!d;/^$/,$d' | egrep expires | awk -v RS='[[:space:]]+' '/expires/' | wc -l

Які підводні камені?

Ну, наприклад, одних з неприємних моментів, при застосуванні лише цих правил, може бути блокування зовнішніх клієнтів, наприклад, web-сервісів, які можуть бути розташовані на хосту. Вірішеється це доволі просто, теж з set-ами, але це тема для зовсім іншої статті.

неділя, 24 березня 2024 р.

Встановлення VirtualBox на Debian 12 (bookworm)

Без зайвих слів, покроково:

  1. wget -O- -q https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmour -o /usr/share/keyrings/oracle_vbox_2016.gpg
  2. echo "deb [arch=amd64 signed-by=/usr/share/keyrings/oracle_vbox_2016.gpg] http://download.virtualbox.org/virtualbox/debian bookworm contrib" | sudo tee /etc/apt/sources.list.d/virtualbox.list
  3. sudo apt update
  4. sudo apt install virtualbox-7.0
  5. wget https://download.virtualbox.org/virtualbox/$( vboxmanage -v | cut -dr -f1 )/Oracle_VM_VirtualBox_Extension_Pack-$( vboxmanage -v | cut -dr -f1 ).vbox-extpack
  6. sudo vboxmanage extpack install Oracle_VM_VirtualBox_Extension_Pack-7.0.14.vbox-extpack
    vboxmanage list extpacks
  7. groups ${USERNAME}
    sudo usermod -a -G vboxusers ${USERNAME}