Advertisement
Guest User

rc.tc

a guest
Jan 17th, 2015
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 39.62 KB | None | 0 0
  1. #!/bin/bash
  2. # vim: sw=4 ts=4 expandtab ai
  3. TC=`which tc`
  4. IPTABLES=`which iptables`
  5. IPROUTE=`which ip`
  6. USAGE="Usage: $0 {start|stop|restart|status} output_interface"
  7. CAT=`which cat`
  8. CUT=`which cut`
  9. WC=`which wc`
  10. # Это сделано для запуска из ip-up/ip-down скрипта ppp.
  11.  
  12. # Каталог со списками пользователей
  13. LDIR="/etc/iplist"
  14.  
  15. # Если скрипт запустили вручную то нужно проверить наличие параметров DEV_OUT.
  16. if [ -z "$2" ] ; then
  17.     # Интерфейс, для подколючения к интернету, указываем обязательно.
  18.     echo "Not present output_interface"
  19.     echo $USAGE
  20.     exit 1
  21. else
  22.     DEV_OUT=$2
  23. fi
  24. ################################################################################
  25. # Настройки шейпинга
  26. #
  27. # xxx_OUT - относится к adsl интерфейсу, исходящему потоку.
  28. # xxx_IN - относится к интерфейсу локальной сети, но входящему
  29. # на adsl модем потоку :).
  30. # Длина очереди fifo на выходном интерфейсе.
  31. QLEN_OUT=10
  32. # Ограничение исходящей скорости,  кбит/с.
  33. # Рассчитывается на основании фактической исходящей скорости минус 15-20% в
  34. # зависимости от того, как плавает скорость при ADSL соединении.
  35. # Если скорость постоянна, можно снижать от фактической на 10%.
  36. RATE_OUT=100000
  37. # Размер MTU на выходном интерфейсе. В настройке указано для ADSL.
  38. MTU_OUT=1492
  39. # Интерфейс внутренней сети.
  40. DEV_IN=eth0                                                                                                                                              
  41. # Ограничение входящей скорости.                                                                                                                          
  42. # Рассчитывается на основании фактической входящей скорости минус 10-15%.                                                                                
  43. RATE_IN=80000                                                                                                                                            
  44. # Длина очереди fifo на входном интерфейсе                                                                                                                
  45. # (сетевой карте сервера, обращенной в локалку).                                                                                                          
  46. QLEN_IN=1000                                                                                                                                              
  47. # Скорость внутреннего интерфейса (сетевой карты сервера, обращенной в локалку).                                                                          
  48. RATE_LOCAL=100mbit                                                                                                                                        
  49. # Адрес самого сервера в локальной сети.                                                                                                                  
  50. IP_LOCAL="192.168.1.33"                                                                                                                                  
  51. IP2_LOCAL="192.168.2.33"                                                                                                                                  
  52. # Переменные, сокращающие длины команд и облегчающие их понимание.                                                                                        
  53. # Может используются не очень часто :) - но вдруг кому пригодится.                                                                                        
  54. TCP="match ip protocol 6 0xff"                                                                                                                            
  55. UDP="match ip protocol 17 0xff"                                                                                                                          
  56. DPORT="match ip dport"                                                                                                                                    
  57. SPORT="match ip sport"                                                                                                                                    
  58. SRC="match ip src"                                                                                                                                        
  59. DST="match ip dst"                                                                                                                                        
  60. MRK="match mark"                                                                                                                                          
  61. U32="protocol ip u32"                                                                                                                                    
  62. ################################################################################                                                                          
  63.  
  64. ################################################################################                                                                          
  65. # Настройки пользователей                                                                                                                                
  66. # Массив содержит информацию о пользователях сервера из локальной сети                                                                                    
  67. # Адреса пользователей принадлежат локальной сети. Формат записи:                                                                                        
  68. # [Порядк_ном]="IP Приоритет Мин_канала Макс_канала", где                                                                                                
  69. # Порядк_ном      - Номер строки по порядку. Повторение не допускается;                                                                                  
  70. # IP              - IP адрес пользователя;                                                                                                                
  71. # Приоритет       - Приоритет пользователя, чем меньше значение тем лучше;                                                                                
  72. # Мин_канала      - Число обозначающее сколько частей пропускной способности                                                                              
  73. #                   канала нужно гарантировано выделить пользователю, например                                                                            
  74. #                   есть Вася с 2, Петя с 1 и Коля с 1, тогда канал распреде-                                                                            
  75. #                   литься так - Васе достанется 2/(2+1+1)=0,5 канала,                                                                                    
  76. #                   Пете - 1/(2+1+1)=0,25 и Коле тоже 0,25;                                                                                              
  77. # Макс_канала     - Число от 1 до 100, показывающее какую часть общего канала                                                                            
  78. #                   можно выделить пользователю, если канал свободен. Значение                                                                            
  79. #                   1 будет равно 0,01 канала, 100 соответствует каналу целиком;                                                                          
  80. # Для временного отключения клиентов допускается комментировать строки.                                                                                  
  81.  
  82. IPS=( $($CAT ${LDIR}/dhcpd.lst) )                                                                                      
  83. for i in $(seq $(echo ${#IPS[@]}) ); do                                                                                                                  
  84.     if [ "a$(echo ${IPS[$((i - 1))]} | $CUT -f2 -d';')" = "agw33-100mbit" ]; then                                                                        
  85.         LOCAL_IPS[${i}]="$(echo ${IPS[$((i - 1 ))]} | $CUT -f1 -d',') 1 4 85"                                                                            
  86.     elif [ "a$(echo ${IPS[$((i - 1))]} | $CUT -f2 -d';')" = "agw33-limited" ]; then                                                                      
  87.         LOCAL_IPS[${i}]="$(echo ${IPS[$((i - 1))]} | $CUT -f1 -d',') 9 1 2"                                                                              
  88.     elif [ "a$(echo ${IPS[$((i - 1))]} | $CUT -f2 -d';')" = "agw33-2-limited" ]; then                                                                    
  89.         LOCAL_IPS[${i}]="$(echo ${IPS[$((i - 1))]} | $CUT -f1 -d',') 9 1 2"                                                                              
  90.     elif [ "a$(echo ${IPS[$((i - 1))]} | $CUT -f2 -d';')" = "ablock" ]; then                                                                              
  91.         : # LOCAL_IPS[${i}]="$(echo ${IPS[$((i - 1))]} | $CUT -f1 -d',') 10 1 0"                                                                          
  92.     else                                                                                                                                                  
  93.         : #LOCAL_IPS[${i}]="$(echo ${IPS[$(( i -1 ))]} | $CUT -f1 -d',') 10 1 0"                                                                          
  94.     fi                                                                                                                                                    
  95. #    echo ${LOCAL_IPS[${i}]}                                                                                                                              
  96. done                                                                                                                                                      
  97. #echo ${LOCAL_IPS[@]}                                                                                                                                    
  98. ################################################################################                                                                          
  99. # Шейпер подразумевает разбиение выделенной полосы пропускания на конечное                                                                                
  100. # число полос. Каждая полоса обеспечивает гарантированный трафик в выделенных                                                                            
  101. # пределах. Чем больше полос, тем меньший гарантированный трафик приходится на                                                                            
  102. # одну. Расчет общего количества полос производится так:                                                                                                  
  103. # Количество полоc = Cпециальные полосы + Общее количество полос пользователей                                                                            
  104.  
  105. # Спец полосы - по ним пойдет общий для всех пользователей трафик по UDP и ASK                                                                            
  106. # пакеты, но с наивысшим приоритетом, а так же прочий неклассифицированный                                                                                
  107. # трафик, с низким приоритетом.                                                                                                                          
  108. # Число меняется только при изменении в программе.                                                                                                        
  109. NNN=$((count+3))                                                                                                                                          
  110.  
  111. # Общее количество полос.                                                                                                                                
  112. # Получается сложением полос для всех пользователей, и спец полос.                                                                                        
  113. #for client in "${LOCAL_IPS[@]}"; do                                                                                                                      
  114. #    if [ -z "$client" ]; then continue; fi                                                                                                              
  115. #    let "NNN += `echo $client | awk '{print $3}'`"                                                                                                      
  116. #done                                                                                                                                                    
  117.  
  118. ShaperStatus(){                                                                                                                                          
  119.     # Показываем настройки шэйпера.                                                                                                                      
  120.     echo "SHAPER SETTINGS"                                                                                                                                
  121.     echo                                                                                                                                                  
  122.     echo "[qdisc out]"                                                                                                                                    
  123.     $TC -s -d qdisc show dev $DEV_OUT                                                                                                                    
  124.     echo                                                                                                                                                  
  125.     echo "[class out]"                                                                                                                                    
  126.     $TC -s -d class show dev $DEV_OUT                                                                                                                    
  127.     echo                                                                                                                                                  
  128.     echo "[filter out]"                                                                                                                                  
  129.     $TC -s filter show dev $DEV_OUT                                                                                                                      
  130.     echo                                                                                                                                                  
  131.     echo "-----------------------------------------------------------------"                                                                              
  132.     echo "[qdisc in]"                                                                                                                                    
  133.     $TC -s -d qdisc show dev $DEV_IN                                                                                                                      
  134.     echo                                                                                                                                                  
  135.     echo "[class in]"                                                                                                                                    
  136.     $TC -s -d class show dev $DEV_IN                                                                                                                      
  137.     echo                                                                                                                                                  
  138.     echo "[filter in]"                                                                                                                                    
  139.     $TC -s filter show dev $DEV_IN                                                                                                                        
  140.     echo                                                                                                                                                  
  141. }                                                                                                                                                        
  142.  
  143. ShaperStopAll(){                                                                                                                                          
  144.     # Удаляем все настройки шэйпинга. Используется для остановки                                                                                          
  145.     # или перезапуска.                                                                                                                                    
  146.     $TC qdisc del dev $DEV_OUT ingress 2> /dev/null > /dev/null                                                                                          
  147.     $TC qdisc del dev $DEV_OUT root 2> /dev/null > /dev/null                                                                                              
  148.     $TC qdisc del dev $DEV_IN ingress 2> /dev/null > /dev/null                                                                                            
  149.     $TC qdisc del dev $DEV_IN root 2> /dev/null > /dev/null                                                                                              
  150.     echo "Shaping removed on $DEV_OUT/$DEV_IN."                                                                                                          
  151. }                                                                                                                                                        
  152.  
  153. ShaperStartOut(){                                                                                                                                        
  154.     ############################################################################                                                                          
  155.     # Ограничение скорости для SYN пакетов. Закомментировать если не требуется                                                                            
  156.     # ограничить скорость создания новых подключений.                                                                                                    
  157.     # На входном интерфейсе используется для защиты от SYN-атаки из интернета.                                                                            
  158.     # Актуально, если разрешены любые входящие подключения из интернета.                                                                                  
  159. #    $TC qdisc add dev $DEV_OUT handle ffff: ingress                                                                                                      
  160. #    $TC filter add dev $DEV_OUT parent ffff: protocol ip prio 0 handle 1 fw police rate 100kbit burst 1500 mtu 9k drop flowid :1                        
  161.     ############################################################################                                                                          
  162.  
  163.     $TC qdisc add dev $DEV_OUT root handle 1: htb default 17                                                                                              
  164.  
  165.     $TC class add dev $DEV_OUT parent 1: classid 1:1 htb rate $[$RATE_OUT]kbit                                                                            
  166.     # Специальным видам трафика выделяем по одной полосе.                                                                                                
  167.     $TC class add dev $DEV_OUT parent 1:1 classid 1:10 htb rate $[$RATE_OUT/$NNN]kbit ceil $[$RATE_OUT/20]kbit prio 1                                    
  168.     $TC class add dev $DEV_OUT parent 1:1 classid 1:12 htb rate $[$RATE_OUT/$NNN]kbit ceil $[$RATE_OUT/4]kbit prio 2                                      
  169.     $TC class add dev $DEV_OUT parent 1:1 classid 1:17 htb rate $[$RATE_OUT/$NNN]kbit ceil $[$RATE_OUT/4]kbit prio 7                                      
  170.  
  171.     # DNS запросы самые приоритетные.                                                                                                                    
  172.     $TC filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $SPORT 53 0xffff classid 1:10                                                                      
  173.     $TC filter add dev $DEV_OUT parent 1:0 prio 2 $U32 $DPORT 53 0xffff classid 1:10                                                                      
  174.  
  175.     ############################################################################                                                                          
  176.     # Короткие SYN пакеты, для установки соединения, отправляем в ту же полосу.                                                                          
  177.     # Это увеличит скорость установления новых соединий, что при сильной загрузке                                                                        
  178.     # канала обеспечит сохранение минимальной паузы при открытии новой Web страницы.                                                                      
  179.     # Закоментировать, если используется очередь ingress на входном интерфейсе                                                                            
  180.     # и Вы не доверяете локальной сети.                                                                                                                  
  181.     $TC filter add dev $DEV_OUT parent 1:0 protocol ip prio 3 handle 1 fw flowid 1:10                                                                    
  182.     ############################################################################                                                                          
  183.  
  184.     # Все прочие udp пакеты. Возможно, некоторые пиринговые сети будут жить в                                                                            
  185.     # этой полосе. Но в основном для игрушек, которые не попали в более                                                                                  
  186.     # приоритетную полосу.                                                                                                                                
  187.     $TC filter add dev $DEV_OUT parent 1:0 prio 4 $U32 $UDP classid 1:12                                                                                  
  188.  
  189.     #Организуем очереди для специальных полос.                                                                                                            
  190.     $TC qdisc add dev $DEV_OUT parent 1:10 handle 10: sfq perturb 5                                                                                      
  191.     $TC qdisc add dev $DEV_OUT parent 1:12 handle 12: sfq perturb 5                                                                                      
  192.  
  193.     # Это прочий (неклассифицированный) трафик.                                                                                                          
  194.     $TC qdisc add dev $DEV_OUT parent 1:17 handle 17: sfq perturb 10                                                                                      
  195.  
  196.     # Классы клиентов.                                                                                                                                    
  197.     j=21                                                                                                                                                  
  198.     for client in "${LOCAL_IPS[@]}"; do                                                                                                                  
  199.         if [ -z "$client" ]; then continue; fi                                                                                                            
  200.         # Это определяются переменные для выражения.                                                                                                      
  201.         prio=`echo $client | awk '{print $2}'`                                                                                                            
  202.         let "rate= $RATE_OUT / $NNN * `echo $client | awk '{print $3}'`"                                                                                  
  203.         let "cell= $RATE_OUT / 100 * `echo $client | awk '{print $4}'`"                                                                                  
  204.         # Создаем полосы для клиентов.                                                                                                                    
  205.         $TC class add dev $DEV_OUT parent 1:1 classid 1:$j htb rate $[$rate]kbit ceil $[cell]kbit prio $prio                                              
  206.         # Создаем фильтры для машин сети.                                                                                                                
  207.         $TC filter add dev $DEV_OUT parent 1:0 protocol ip prio $j handle $j fw flowid 1:$j                                                              
  208.         # Теперь создаем очереди для машин сети.                                                                                                          
  209.         $TC qdisc add dev $DEV_OUT parent 1:$j handle $j: sfq perturb 5                                                                                  
  210.         let "j += 1"                                                                                                                                      
  211.     done                                                                                                                                                  
  212.     echo "Outbound shaping added to $DEV_OUT.  Rate: ${RATE_OUT}Kbit/sec."                                                                                
  213. }                                                                                                                                                        
  214.  
  215. ShaperStartIn(){                                                                                                                                          
  216.     # Это шейпер на внутреннюю сеть, то есть на входящий трафик.                                                                                          
  217.     $IPROUTE link set dev $DEV_IN qlen $QLEN_IN                                                                                                          
  218.  
  219.     ############################################################################                                                                          
  220.     # Добавляем особый тип очереди - ingress, что контролирует вход интерфейса.                                                                          
  221.     # Собственно, ограничиваем количество входящих! коннектов в секунду.                                                                                  
  222.     # Раскомментировать, если Вы не доверяете локальной сети.                                                                                            
  223.     #$TC qdisc add dev $DEV_IN handle ffff: ingress                                                                                                      
  224.     #$TC filter add dev $DEV_IN parent ffff: protocol ip prio 0 handle 1 fw  police rate 200kbit burst 1500 mtu 9k drop flowid :1                        
  225.     ############################################################################                                                                          
  226.  
  227.     $TC qdisc add dev $DEV_IN root handle 1: htb default 17                                                                                              
  228.     $TC class add dev $DEV_IN parent 1: classid 1:1 htb rate ${RATE_IN}kbit                                                                              
  229.     $TC class add dev $DEV_IN parent 1:1 classid 1:10 htb rate $[$RATE_IN/$NNN]kbit ceil $[$RATE_IN/20]kbit prio 0                                        
  230.     $TC class add dev $DEV_IN parent 1:1 classid 1:12 htb rate $[$RATE_IN/$NNN]kbit ceil $[$RATE_IN/4]kbit prio 2                                        
  231.  
  232.     # Полоса для неопределенного трафика.                                                                                                                
  233.     $TC class add dev $DEV_IN parent 1:1 classid 1:17 htb rate $[$RATE_IN/$NNN]kbit ceil $[$RATE_IN/4]kbit prio 7                                        
  234.  
  235.     # Примерно тоже самое, только этот интерфейс работает с локальной сетью.                                                                              
  236.     $TC class add dev $DEV_IN parent 1: classid 1:2 htb rate $RATE_LOCAL prio 7                                                                          
  237.  
  238.     # Через этот класс пропускается не транзитный с adsl модема трафик, а                                                                                
  239.     # исходящий с роутера, поэтому используется другой, более высокий rate,                                                                              
  240.     # а это фильтр для него.                                                                                                                              
  241.     $TC filter add dev $DEV_IN parent 1:0 prio 1 $U32 $SRC $IP_LOCAL classid 1:2                                                                          
  242.     #  это фильтр для DNS.                                                                                                                                
  243.     $TC filter add dev $DEV_IN parent 1:0 prio 2 $U32 $SPORT 53 0xffff classid 1:10                                                                      
  244.     $TC filter add dev $DEV_IN parent 1:0 prio 3 $U32 $DPORT 53 0xffff classid 1:10                                                                      
  245.     ############################################################################                                                                          
  246.     # Короткие SYN  пакеты, для установки соединения, отправляем в ту же полосу.                                                                          
  247.     # Раскоментировать, если не используется (закоментирована) очередь ingress                                                                            
  248.     # на исходящем интерфейсе.                                                                                                                            
  249.     $TC filter add dev $DEV_IN parent 1:0 protocol ip prio 4 handle 1 fw flowid 1:10                                                                      
  250.     ############################################################################                                                                          
  251.     # Это фильтр для прочих UDP соединений.                                                                                                              
  252.     $TC filter add dev $DEV_IN parent 1:0 prio 5 $U32 $UDP classid 1:12                                                                                  
  253.  
  254.     # Использую самую простую и легкую для процессора очередь pfifo для                                                                                  
  255.     # исходящего с роутера трафика (не транзитный!).                                                                                                      
  256.     $TC qdisc add dev $DEV_IN parent 1:2 handle 2: pfifo                                                                                                  
  257.     # Очереди для DNS и UDP.                                                                                                                              
  258.     $TC qdisc add dev $DEV_IN parent 1:10 handle 10: sfq perturb 5                                                                                        
  259.     $TC qdisc add dev $DEV_IN parent 1:12 handle 12: sfq perturb 5                                                                                        
  260.  
  261.     # Это прочий неклассифицированный трафик.                                                                                                            
  262.     $TC qdisc add dev $DEV_IN parent 1:17 handle 17: sfq perturb 15                                                                                      
  263.  
  264.     # Полосы для клиентских машин.                                                                                                                        
  265.     j=21                                                                                                                                                  
  266.     for client in "${LOCAL_IPS[@]}"; do                                                                                                                  
  267.          if [ -z "$client" ]; then continue; fi                                                                                                          
  268.          # Это определяются переменные для выражения.                                                                                                    
  269.          ip=`echo $client | awk '{print $1}'`                                                                                                            
  270.          prio=`echo $client | awk '{print $2}'`                                                                                                          
  271.          let "rate= $RATE_IN / $NNN * `echo $client | awk '{print $3}'`"                                                                                  
  272.          let "cell= $RATE_IN / 100 * `echo $client | awk '{print $4}'`"                                                                                  
  273.          # Создаем полосы для клиентов.                                                                                                                  
  274.          $TC class add dev $DEV_IN  parent 1:1 classid 1:$j htb rate $[$rate]kbit  ceil $[cell]kbit prio $prio                                            
  275.          # Фильтры для них же.                                                                                                                            
  276.          $TC filter add dev $DEV_IN parent 1:0 prio $j $U32 $DST $ip classid 1:$j                                                                        
  277.          # Очереди.                                                                                                                                      
  278.          $TC qdisc add dev $DEV_IN parent 1:$j handle $j: sfq perturb 5                                                                                  
  279.          let "j += 1"                                                                                                                                    
  280.     done                                                                                                                                                  
  281.     echo "Outbound shaping added to $DEV_IN.  Rate: ${RATE_IN}Kbit/sec."                                                                                  
  282. }                                                                                                                                                        
  283.  
  284. Marking(){
  285.     action=$1
  286.     j=21
  287.     for client in "${LOCAL_IPS[@]}"; do
  288.         if [ -z "$client" ]; then continue; fi
  289.         ip=`echo $client | awk '{print $1}'`
  290.         # Маркируем пакеты для клиентов.
  291.         # Это действие требуется для распределения клиентов по полосам.
  292.         $IPTABLES $action PREROUTING -t mangle -s $ip -j MARK --set-mark $j
  293.         let "j += 1"
  294.     done
  295.     # Маркируем syn пакеты.
  296.     $IPTABLES $action PREROUTING -t mangle -p tcp --syn -j MARK --set-mark 1
  297.     # Назначаем одинаковое время жизни для пакетов.
  298. #    $IPTABLES $action PREROUTING -t mangle -i $DEV_IN -j TTL --ttl-set 64
  299. }
  300.  
  301. case "$1" in
  302. start)
  303.     Marking "-A"
  304.     ShaperStartIn
  305.     ShaperStartOut
  306.     ;;
  307. stop)
  308.     ShaperStopAll
  309.     Marking "-D"
  310.     ;;
  311. status)
  312.     ShaperStatus
  313.     ;;
  314. restart)
  315.     ShaperStopAll
  316.     Marking "-D"
  317.     Marking "-A"
  318.     ShaperStartIn
  319.     ShaperStartOut
  320.     ;;
  321. *)
  322.     echo $USAGE
  323. esac
  324.  
  325. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement