Iproute 2
Traffic Manager
Inleiding
Naar aanleiding van een discussie over het gebruik van iproute2 en tc kwam al snel een conclusie; het is te complex om iemand uit te leggen die er niet dagelijks mee te maken heeft. En om dus iemand anders aan de hand van enkele aanwijzingen de scripts aan te laten passen is niet erg prettig.
Op deze pagina staat erg duidelijk toegelicht hoe htb in zijn werkt gaat, htb is een van de mogelijkheden om met tc "prioriteiten toe te kennen aan bepaalde datastromen. In deze user manual wordt veel gebruik gemaakt van diagrammen om aan te geven welke "nodes" bandbreedte kunnen delen met elkaar. Op dit idee ben ik verder gegaan en hier is de huidige user interface uit ontstaan.
Iproute
Iproute wordt in het systeem gebruikt om eventueel meerdere internet verbindingen tegelijk te gebruiken met als extra de mogelijkheid om bepaalde diensten/hosts/whatever aan bepaalde internet verbindingen te koppelen. Dit koppelen gebeurt aan de hand van de MARK die meegegeven dient te worden aan een stroom gegevens.
Deze MARK kan je met iptables instellen, voorbeeld:
Alle ssh pakketjes in en uit markeren met MARK 1
// De dienst ssh krijgt mark 1 iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 22 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 22 -j RETURN
Nadat deze markering is ingesteld kunnen alle pakketjes met de mark 1 aan een internet verbinding of combinatie van internet verbindingen worden toegewezen.
Ook op gateways met maar 1 internet verbinding kan dit pakket handig zijn, maar dan puur om de verschillende diensten bandbreedte toe te wijzen
tc
Om naast het kiezen van interfaces ook nog prioriteiten toe te kunnen passen is ook tc erbij gehaald. Op basis van dezelfde markering kunnen we een dienst een minimale bandbreedte en een maximale bandbreedte toewijzen.
ssh
Om als php script onder apache toch commando's als root uit te kunnen voeren maken we gebruik van ssh. Een bijkomend voordeel is dat je zo eventueel backend en frontend kuns opsplitsen (nog niet getest!)
Het gebruik van ssh brengt wel wat aandachtpuntjes met zich mee:
known_hosts
Voor ssh een verbinding wil maken naar een host moet deze host + fingerprint bekend zijn op de server. Normaal wordt dit in ~/.ssh/known_hosts bijgehouden maar omdat deze ssh sessies worden gedraait als apache user kunnen deze beter system-wide worden ingesteld
ssh localhost
hierna zal in de /root/.ssh/known_hosts een regel te vinden zijn welke begin met:
localhost rsa ssh-rsa AAAAB3NzaC1yc2E.....
deze moet je kopieren naar de file /etc/ssh/ssh_known_hosts
under construction
Laat duidelijk zijn dat deze web-interface pas bij versie 1.0 alpha is en dus nog gegarandeerd fouten bevat!
Bugs kan je hier melden (zie discussion page) en dan zal ik kijken of ik tijd heb om er naar te kijken.
Als je een goede reden denkt te hebben waarom je toegang nodig hebt tot de subversion repository kan je je ook hier melden!
Voorbeelden en resultaten van onderzoeken
Voor ik beginnen ben aan de TrafficManager heb ik me eerst verdiept in iproute en tc, de resultaten en uitprobeersels die hieruit zijn gekomen staan hieronder:
2 internet verbindingen bundelen tot 1
Hieronder staat een test-script welke in theorie 2 modems tegelijk kan gebruiken, dit voorbeeld is rechtstreeks overgenomen uit de LARTC howto
echo nics config ifconfig eth0 192.168.0.49 ifconfig eth1 10.0.0.5 echo incoming traffic ip route add 192.168.0.0/24 dev eth0 table 100 ip route add default via 192.168.0.1 table 100 ip route add 10.0.0.0/8 dev eth1 table 200 ip route add default via 10.0.0.1 table 200 echo Debug ip route show table 100 ip route show table 200 echo Delete oude Main routes ip route delete 192.168.0.0/24 ip route delete 10.0.0.0/8 ip route delete default echo Route Main ip route add 192.168.0.0/24 dev eth0 src 192.168.0.49 ip route add 10.0.0.0/8 dev eth1 src 10.0.0.5 echo Tabellen koppelen ip rule add from 192.168.0.49 table 100 ip rule add from 10.0.0.5 table 200 echo debug again ip route show echo outgoing ip route add default scope global nexthop via 192.168.0.1 dev eth0 weight 1 \ nexthop via 10.0.0.1 dev eth1 weight 1
QoS in Linux met TC en HTB
Dit script zorgt ervoor dat Client A (met het ip 1.2.3.4) met 30 kb/sec kan downloaden (minimaal) en verder 10 kb/sec over heeft voor overige protocollen. Verder kan http tot 100 kb/sec groeien indien de rest niet wordt gebruikt, ook kan "rest" groeien tot max 100 kb/sec wanneer er geen http verkeer is
Voorbeeld:
Indien een andere client (Client B met ip 1.2.3.5) aan het downloaden is met 60 kb/sec:
- Client A http: 30 kb/sec (of wanneer http 0 kb/sec is kan rest groeien tot 40 kb/sec)
- Client A rest: 10 kb/sec (of wanneer rest 0 kb/sec is kan http tot 40 kb/sec groeien)
De classes kunnen bij elkaar bandbreedte lenen wanneer deze niet gebruikt worden bij een andere class. De maximale snelheid (inclusief het lenen) wordt aangegeven met ceil.
# Enable root tc qdisc add dev eth0 root handle 1: htb default 12 # Root aanmaken, main limit tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps # Per child opgeven wat het limiet is tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps # Als hij source-port 80 heeft en mijn desktop is dan naar :10 tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 1.2.3.4 \ match ip sport 80 0xffff flowid 1:10 # Ander verkeer van mijn desktop naar :11 tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 1.2.3.4 \ flowid 1:11
2 scripts samengevoegd
Dit script deelt de internet verbindingen van eth2 en eth3.
- de dienst ssh gaat altijd over eth2 en krijgt max 30 kb/sec
- HTTP gaat altijd over eth3 en krijgt max 10 kb/sec
- Overige diensten gaan over beide netwerkkaarten (session round-robin) en krijgen max 100 kb/sec
## Config # Internet Subnets INET1="10.6.6.0/24" INET2="10.7.7.0/24" # Gateways GW1="10.6.6.1" GW2="10.7.7.1" # Internet Interfaces IF1="eth2" IF2="eth3" # Internet IP's IP1="10.6.6.2" IP2="10.7.7.2" ## Cleanup previous run ip rule del from $IP1 ip rule del from $IP2 ip rule del fwmark 1 ip rule del fwmark 2 ip rule del fwmark 3 ## Setup load-balancing # Incoming traffic ip route add $INET1 dev $IF1 table 150 ip route add default via $GW1 table 150 ip route add $INET2 dev $IF2 table 151 ip route add default via $GW2 table 151 # Delete old Main routes ip route delete $INET1 ip route delete $INET2 ip route delete default # Route Main ip route add $INET1 dev $IF1 src 10.6.6.2 ip route add $INET2 dev $IF2 src 10.7.7.2 echo Tabellen koppelen ip rule add from 10.6.6.2 table 150 ip rule add from 10.7.7.2 table 151 ip rule add fwmark 1 table 150 ip rule add fwmark 2 table 151 ip rule add fwmark 3 table 152 ip route add $INET1 dev $IF1 table 152 ip route add $INET2 dev $IF2 table 152 ip route add default scope global table 152 nexthop via $GW1 dev $IF1 weight 1 nexthop via $GW2 dev $IF2 weight 1 echo debug again ip route show echo outgoing ip route add default scope global nexthop via $GW1 dev $IF1 weight 1 nexthop via $GW2 dev $IF2 weight 1 ## Dividing traffic # outgoing traffic, mark for gateway selection iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 22 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j MARK --set-mark 2 iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 21 -j MARK --set-mark 3 ## Setup traffic shaping # Enable root tc qdisc add dev eth1 root handle 1: htb default 12 # Root aanmaken, main limit tc class add dev eth1 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps # Per child opgeven wat het limiet is tc class add dev eth1 parent 1:1 classid 1:10 htb rate 30kbps ceil 30kbps tc class add dev eth1 parent 1:1 classid 1:11 htb rate 10kbps ceil 10kbps tc class add dev eth1 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps # verkeer met MARK 1 tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 1 fw flowid 1:10 # verkeer met MARK 2 tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 2 fw flowid 1:11 # incoming traffic, mark for bandwidth throttling iptables -t mangle -A POSTROUTING -o eth1 -p tcp --sport 22 -j MARK --set-mark 1 iptables -t mangle -A POSTROUTING -o eth1 -p tcp --sport 80 -j MARK --set-mark 2 iptables -t mangle -A POSTROUTING -o eth1 -p tcp --sport 21 -j MARK --set-mark 3