У своєму сценарії iptables я експериментував із написанням якомога дрібніших правил. Я обмежую, яким користувачам дозволено використовувати які сервіси, частково для безпеки та частково як навчальні заняття.
Використання iptables v1.4.16.2 на Debian 6.0.6 під керуванням ядра 3.6.2.
Однак я потрапив у проблему, яку я ще не зовсім розумію ...
вихідні порти для всіх користувачів
Це прекрасно працює. У мене немає жодних загальних правил відстеження стану.
## вихідний порт 81 $ IPTABLES -A OUTPUT -p tcp --dport 81 -m conntrack - statestate НОВЕ, ВСТАНОВЛЕНО -j ACCEPT $ IPTABLES -A INPUT -p tcp --спорт 81 -s $ MYIP -m conntrack --ctstate ВСТАНОВЛЕНО -j ACCEPT
вихідні порти з відповідності користувача
## вихідний порт 80 для використаннярахунку $ IPTABLES -A ВИХІД - власник відповідника - користувач -idid usecountcount -p tcp --dport 80 -m conntrack - statestate НОВЕ, ВСТАНОВЛЕНО --спорт 1024: 65535 -j ACCEPT $ IPTABLES -A INPUT -p tcp --спорт 80 --portport 1024: 65535 -d $ MYIP -m conntrack - statestate Встановлено -j ACCEPT
Це дозволяє порту 80 виходити лише для облікового запису "useraccount", але такі правила, як для трафіку TCP, мають проблеми.
## За замовчуванням вихідний журнал + правила блоку $ IPTABLES -A OUTPUT -j LOG --log-префікс "BAD OUTGOING" --log-ip-options --log-tcp-options --log-uid $ IPTABLES -A ВИХІД -j DROP
Питання
Вищеописане працює, користувач "useraccount" може отримати файли ідеально чудовими. Жоден інший користувач у системі не може здійснювати вихідні з'єднання з портом 80.
useraccount @ host: $ wget http://cachefly.cachefly.net/10mb.test
Але виджет вище листя x7 викинув записи в моєму системному журналі:
18 жовтня 02:00:35 xxxx ядро: BAD OUTGOING IN = OUT = eth0 SRC = xx.xx.xx.xx DST = 205.234.175.175 LEN = 40 TOS = 0x00 PREC = 0x00 TTL = 64 ID = 12170 DF PROTO = TCP SPT = 37792 DPT = 80 SEQ = 164520678 ACK = 3997126942 WINDOW = 979 RES = 0x00 ACK URGP = 0
Я не отримую ці краплі для подібних правил із трафіком UDP. У мене вже є правила, які обмежують, які користувачі можуть робити запити DNS.
Викинуті вихідні пакети ACK, схоже, надходять із кореневого акаунта (URGP = 0), який я не розумію. Навіть коли я міняю usecountcount на root.
Я вважаю, що пакети ACK класифікуються як нові, тому що conntrack починає відстежувати з'єднання після 3-го кроку третього рукостискання, але чому вони відкидаються?
Чи можна ці краплі безпечно ігнорувати?
Редагувати
Тому я часто бачу такі правила, які добре працюють для мене:
$ IPTABLES -A OUTPUT -s $ MYIP -p tcp -m tcp - доповідь 80-м стан - держава НОВИЙ, Встановлений -j ПРИХОД $ IPTABLES -A INPUT -p tcp -m tcp --спорт 80 -d $ MYIP -m стан - держава ВСТАНОВЛЕНО -j ACCEPT
Я поміняв "-m state --state" на "-m conntrack --ctstate", оскільки збіг стану явно застарів.
Чи найкраща практика мати загальні правила відстеження стану? Чи не вважаються наведеними вище правила правильними?
Що б таке краще було для жорсткого контролю над з'єднаннями вихідних користувачів?
$ IPTABLES -A INPUT -m conntrack --ctstate Встановлено -j ACCEPT $ IPTABLES -A OUTPUT -m conntrack --ctstate ВСТАНОВЛЕНО -j ACCEPT $ IPTABLES -A OUTPUT -p tcp --dport 80-s $ SERVER_IP_TUNNEL -m conntrack - держава НОВИЙ -власник --uid-власник використання рахунок -j ACCEPT $ IPTABLES -A OUTPUT -p tcp --portport 80-s $ SERVER_IP_TUNNEL -m conntrack - держава NEW -m власник --uid-власник інший рахунок -j ACCEPT