Роздача internet'y через pppoe або Я дятел, але цього ніхто не помітив

Черговий раз використовував цей блог як записник для того, щоб налаштувати ще один Linux'овий роутер. На цей раз мені стала в нагоді нотатка понад дворічної давності про нарізку internet-каналу з допомогою скрипта htb.init. Проте з голови зовсім вилетіло, що котролювати швидкість можна лише на вихідному інтерфейсі, що логічно: не можете ж ви контролювати швидкість приходу вхідних пакетів — як їх друга сторона відправила так і прийдуть.

В результаті я написав правила обмеження швидкості на інтерфейсі, який «дивиться» в internet, i в мене получилося, що користувач може скачувати інформацію з максимальною швидкістю, а віддавати — з тою, яку я «нарізав». Здоровий глузд же підказує, що треба хоча б навпаки, а в ідеалі — контролювати швидкість в обидві сторони.

Здавалося б — нема нічого простішого — продублювати конфігурацію для інтерфейсу, до якого підключений користувач і «дєло в шляпє», але мої граблі, як завжди виявляється, такими простими не бувають: користувач з’єднується по протоколу pppoe і як називається інтерфейс з’єднання котрого користувача наперед вгадати неможливо, більше того — поки користувач не з’єднався потрібного інтерфейсу просто-напросто в системі немає.

Довелося трохи погуглити.

Як на зло, першими на очі потрапили рішення «викидати htb.init, читати документацію по ip та tc і писати скрипти самому». Були навіть приклади скриптів. Але світ не без добрих людей і хвилин за 15 я таки знайшов відносно просте рішення з використанням того ж htb.init.

Рішення, що називається, «в лоб»: зробити шаблонну конфігурацію, розмножити її для всіх можливих варіантів назви інтерфейсу (від ppp0 до ppp254) і перезапускати htb.init при кожному з’єднанні/відключенні pppoe-клієнта.

Само собою 255 однотипних операцій зручніше робити скриптом, тільки чувак, котрий то написав, в своєму прикладі скрипта намертво забив імена шаблонних файлів (благо в нього їх тільки три) і розмножував їх копіюванням. Мені це не сподобалося, бо
а) по мірі додавання/прибирання користувачів міняється набір шаблонних файлів, тому я просто вирішив читати список і підміняти шаблонну частину назви на потрібну;
б) при зміні параметрів в існуючому файлі потрібно наново запускати процес копіювання, а якщо робити не копії, а лінки на шаблонні файли (як я і зробив), то при редагуванні шаблонів зміни у всіх 255-ти екземплярах відбудуться автоматично.

В результаті скрипт набув такого вигляду:

# cat make_clones 
#!/bin/bash 
#прибрати існуючі версії 
rm -f /etc/sysconfig/htb/ppp* 
#цикл для 255 можливих інтерфейсів 
for pppno in `seq 0 254`; do 
 #прочитати назви шаблонних файлів (починаються зppp)
 for ppptpl in `find /etc/sysconfig/htb/ppp.d/ -name ppp\*`; do 
  #сформувати назву файла конфігурації. Відкидаємоppp,
  #замість нього додаємо повний шлях і назву інтерфейсу; 
  #відкидання символів після крапки — необов’язкове — 
  #htb.init їх дозволяє (як примітку), але так красивіше
  #виглядає: в шаблонах все підписано, а в «живій» 
  #конфігурації тільки необхідний мінімум 
  pppXfile=/etc/sysconfig/htb/ppp${pppno}`basename ${ppptpl}|colrm 1 3|cut -d "." -f 1`
  ln -f ${ppptpl} ${pppXfile}
 done
done

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

Залишилося закинути скрипт перезапуску htb.init в папки /etc/ppp/ip-up.d та /etc/ppp/ip-down.d, який складається з однієї стрічки:
/sbin/htb.init restart

Знаю, що зазвичай він знаходиться зовсім не там, але в мене використовується systemd, та й скрипт потрібно запускати зовсім не на завантаженні системи, тому мені зручніше тримати його в /sbin/

Свої проколи я встиг зрозуміти і виправити до підключення реальних користувачів, тому ніхто нічого не помітив, але на майбутнє нотатку треба собі залишити — хто зна: може через два з половиню роки знов щось таке налаштовувати буду :-)




 

Працює на AutoGenCMS 0.2.6

А чому це всі вирішили, що в сайта має бути шапка?