Поиск по этому блогу

суббота, 29 сентября 2012 г.

Шейпим трафик, используя ifb и hash фильтры tc

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

Итак, есть следующая схема сети:

На сервере присутствуют две сетевых карты:
  • eth0 - ip 192.168.0.10/24, смотрит в мир и на ней поднят nat
    iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.10
  • eth1 - ip 192.168.200.254/24, смотрит в локальную сеть.
Шейпить можно только исходящий трафик с интерфейса. Для клиентов (pc0 - ip 192.168.200.10 и pc1 - ip 192.168.200.20) скорость закачки (download) шейпим на интерфейсе eth1, т.к. для этого интерфейса трафик будет исходящим в сторону клиента.

Логично для отдачи (upload) использовать eth0, но тут есть один нюанс, на этом интерфейсе прописан nat и шейпить на нем исходящий трафик от клиентов не получиться. Чтобы решить данную проблему, завернём весь входящий трафик от клиентов на интерфейсе eth1 в виртуальный интерфейс ifb0, тем более, на данный момент, поддержка IFB есть в ядре.

Для начала нарежем download:
  • Создаем корневую дисциплину на интерфейсе eth1:
    tc qdisc add dev eth1 root handle 1: htb default 20
  • Далее создаем корневой класс для наших клиентских классов. Скорость у него будет 1 mbit, для тестов достаточно:
    tc class add dev eth1 parent 1: classid 1:1 htb rate 1024kbit
  • Теперь создадим таблицу 10 на 256 ячеек:
    tc filter add dev eth1 parent 1:0 prio 1 handle 10: protocol ip u32 divisor 256
  • Создаем фильтр, направлящий весь трафик в хеш таблицу с ID 10:
    tc filter add dev eth1 parent 1:0 protocol ip u32 ht 800:: match ip dst 192.168.200.0/24 hashkey mask 0x000000ff at 16 link 10:
  • Ну а теперь нарежем скорость для наших двух клиентов, для pc0 - 256 kbit, а для pc1 - 512 kbit:
    • Создаем класс 100 со скоростью 256 kbit для pc0:
      tc class add dev eth1 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
    • Создаем дисциплину шейпирования для конечного класса:
      tc qdisc add dev eth1 parent 1:100 handle 100: sfq perturb 10
    • Заворачиваем весть трафик для ip 192.168.200.10 в класс 100:
      tc filter add dev eth1 protocol ip prio 2 u32 ht 10:a: match ip dst 192.168.200.10/32 flowid 1:100
    • То же самое, но для pc1:
      tc class add dev eth1 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
      tc qdisc add dev eth1 parent 1:200 handle 200: sfq perturb 10
      tc filter add dev eth1 protocol ip prio 2 u32 ht 10:14: match ip dst 192.168.200.20/32 flowid 1:200
  • Весь трафик, который не подпадает под указанные правила будет заворачиваться в класс по умолчанию 20:
    tc class add dev eth1 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
    tc qdisc add dev eth1 parent 1:20 handle 20: sfq perturb 10

Теперь upload. Для этого будем использовать виртуальный интерфейс ifb0, куда будет заворачиваться весь входящий трафик от пользователей на интерфейс eth1.
  • Подключаем модуль ядра для ifb:
    modprobe ifb
  • Поднимаем интерфейс ifb0:
    ip link set dev ifb0 up
  • Создаем корневую дисциплину для входящего трафика на интерфейсе eth1:
    tc qdisc add dev eth1 ingress
  • Теперь непосредственно заворачиваем трафик в ifb0:
    tc filter add dev eth1 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
  • А далее по аналогии с исходящим трафиком с интерфейса eth1:
    • Создаем корневую дисциплину и класс:
      tc qdisc add dev ifb0 root handle 1: htb default 20
      tc class add dev ifb0 parent 1: classid 1:1 htb rate 1024kbit
    • Описываем правила для pc0:
      tc class add dev ifb0 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
      tc qdisc add dev ifb0 parent 1:100 handle 100: sfq perturb 10
      tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.10/32 flowid 1:100
    • Теперь для pc1:
      tc class add dev ifb0 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
      tc qdisc add dev ifb0 parent 1:200 handle 200: sfq perturb 10
      tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.20/32 flowid 1:200
  • Ну и про класс по умолчанию не забываем:
    tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
    tc qdisc add dev ifb0 parent 1:20 handle 20: sfq perturb 10
    
psht 10:14: ; ht 10:a: ; ht 800:: - это значения не в десятичной, а шестнадцатеричной системе исчисления.

пятница, 28 сентября 2012 г.

Дополнительные атрибуты

Для начала небольшой примерчик:
root@terminal:/tmp# touch text.txt
root@terminal:/tmp# ls -l text.txt 
-rw-r--r-- 1 root root 0 2012-09-28 18:41 text.txt
root@terminal:/tmp# lsattr text.txt 
-----------------e- text.txt
Теперь о том, что всё это значит.
Через команду chattr можно добавить и удалить дополнительные атрибуты. Какие же они бывают?

Usage: chattr [-RVf] [-+=AacDdeijsSu] [-v version] files...
  • i: Файл с установленным атрибутом 'i' становится полностью не модифицируемым (недосягаемым): он не может быть удален или переименован, никакие ссылки не могут быть созданы на этот файл и никакие данные не могут быть записаны в него. Только суперпользователь или процесс, обладающий возможностью CAP_LINUX_IMMUTABLE может установить или очистить такой атрибут.
    root@terminal:/tmp# chattr +i text.txt 
    root@terminal:/tmp# lsattr text.txt 
    ----i------------e- text.txt
    root@terminal:/tmp# echo test >> text.txt 
    bash: text.txt: Отказано в доступе
    root@terminal:/tmp# chattr -i text.txt 
    root@terminal:/tmp# echo test >> text.txt 
  • j: Для файла с установленным атрибутом 'j' все его данные прежде, чем быть записанными непосредственно в файл, сохраняются в журнал, правда, это происходит в том случае, если файловая система смонтирована с опциями "data=ordered" или "data=writeback". Когда файловая система смонтирована с опцией "data=journal" все данные файла уже журналируются и этот атрибут не имеет никакого эффекта. Только суперпользователь или процесс, обладающий возможностью CAP_SYS_RESOURCE, может установить или очистить этот атрибут.
  • s: при удалении файла с установленным атрибутом 's' выполняется обнуление его блоков и запись их обратно на диск.
  • S: модифицируя файл с атрибутом `S', внесенные изменения синхронно записываются на диск; использование этого атрибута эквивалентно применению опции монтирования `sync' к подмножеству расположенных файлов.
  • u: при удалении файла с атрибутом 'u', его содержимое сохраняется (остается не тронутым) на диске. Это позволяет пользователю в последующем восстановить такой файл.
  • d: указывает на то, что не нужно делать резервные копии файла. Файл будет проигнорирован командой dump.
  • а: указывает, что в файл можно добавлять информацию, но нельзя удалять.
  • A: не обновлять время доступа к объекту. Теоретически установка этого атрибута должна повысить производительность файловой системы и соответственно системы в целом.
  • c: файл использующий этот атрибут автоматически сжимается ядром при записи на диск. При чтении с диска он автоматически будет распакован.
  • D: при изменении директории с установленным флагом все изменения синхронно записываются на диск.

Дополнительно можно почитать тут https://rstcenter.com/forum/35191-advanced-file-permissions-extended-attributes.rst