How to set up Layer 7 Traffic Control
Resources
Some resources that greatly helped to figure this stuff out
L7-Homepage
LARTC-Guide
Freifunk-Wiki
HTB Linux queue manual
HTB How To
Prerequisites
To get l7-filter to work, you will need to install the package ‘iproute’ and patch your kernel and iptables. Some distros already do that and have pre-built packages, but for the sake of completeness I cover these topic here too. First we need to get 2 packages:
Patching the kernel
After downloading and untar’ing, we need to patch the running kernel with patch provided by the l7-filter package. I assume the running kernel source is to be found at ‘/usr/src/linux’. At the time of writing the latest available patch was ‘kernel-2.6.25-2.6.28-layer7-2.22.patch’ which applied fine against 2.6.31.
1 2 3 4 5 |
~# tar xjpf netfilter-layer7-v2.xx.tar.bz2 ~# cd netfilter-layer7-v2.xx ~# cp kernel-2.6.25-2.6.28-layer7-2.22.patch /usr/src/linux && cd /usr/src/linux patch -p1 < kernel-2.6.25-2.6.28-layer7-2.22.patch make menuconfig |
In the kernel configuration menu you have to select the folowing options:
Directly copied from the L7-filter How-to page:
- “Prompt for development and/or incomplete code/drivers” (under “Code maturity level options”)
- “Network packet filtering framework” (Networking → Networking support → Networking Options)
- “Netfilter Xtables support” (on the same screen)
- “Netfilter connection tracking support” (… → Network packet filtering framework → Core Netfilter Configuration), select “Layer 3 Independent Connection tracking”
- “Connection tracking flow accounting” (on the same screen)
- And finally, “Layer 7 match support”
- Optional but highly recommended: Lots of other Netfilter options, notably “FTP support” and other matches. If you don’t know what you’re doing, go ahead and enable all of them.
After you’re done configuring, safe and exit the configuration and install the kernel:
1 |
~# make && make modules && make modules_install && make bzImage && make install |
Now reboot the computer with the new kernel.
Patching iptables
The l7-filter package also comes with extensions for iptables. The files ‘libxt_layer7.c’ and ‘libxt_layer7.man’ have to be copied to the iptables ‘extensions’ folder before compiling the new iptables binary:
1 2 3 4 5 6 |
~# tar xjpf netfilter-layer7-v2.xx.tar.bz2 ~# tar xzvf iptables-1.4.3.2.tar.gz ~# cp netfilter-layer7-v2.xx/iptables-1.4.3forward-<SPAN class=code-keyword>for</SPAN>-kernel-2.6.20forward/libxt_layer7* iptables-1.4.3.2/extensions/ ~# ./configure --prefix=/usr/local/iptables --enable-devel --enable-libipq --enable-shared --enable-<SPAN class=code-keyword>static</SPAN> --enable-ipv6 --with-ksource=/usr/src/linux make make install |
Be careful not to install your distributors and your private version of iptables in parallel to avoid conflicts.
Testing the setup
At the shell prompt type:
1 2 |
~# /usr/local/iptables/sbin/iptables -m layer7 -h ~# tc -help |
The first command will produce lots of information about iptables, the second one will show a brief description of how to operate ‘tc’.
In no case you should recieve an error message like:
1 2 3 4 5 6 7 8 9 |
~# /usr/local/sbin/iptables -m layer7 -h iptables v1.4.3.2: Couldn't load match `layer7':/lib/xtables/libipt_layer7.so: cannot open shared object file: No such file or directory (iptables hasn't been patched properly) or ~# tc -help -bash: tc: command not found (<SPAN class=code-keyword>package</SPAN> iptroute is missing) |
Should any of these errors occur review the previous steps.
Traffic Control Script
After getting the above steps to work you can now happily copy’n’paste the codeblock into a shellscript, make it executable and off you go. Just change the variables at the top that define how much bandwith is available, how it should be distributed and which protocols are to be prioritized. The variable ‘NETDEVICE’ has to be set to the WAN-interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
#!/bin/sh # Copyleft 2010 David Gabriel <b2c> at <dest-unreachable> dot <net> # This program is licensed under the terms of the GPL version 2 or higher. # Use at yee own risk. It works <SPAN class=code-keyword>for</SPAN> me, but then I wrote it. # Thanks to all the people out there who have struggled with l7/tc before # and have left helpful information in their tracks. # This script builds upon Jochen E.'s and Björns tc scripts from freifunk.net, # my own scarce knowledge and various other sources found out there... # <SPAN class=code-keyword>if</SPAN> you compiled iptables yourself add the correct path to 'PATH' here, # otherwise the script won't find it! PATH=<SPAN class=code-quote>"$PATH:/usr/local/sbin:/usr/local/bin"</SPAN> TC=`which tc 2> /dev/<SPAN class=code-keyword>null</SPAN>` IPTABLES=`which iptables 2> /dev/<SPAN class=code-keyword>null</SPAN>` IPT=<SPAN class=code-quote>"$IPTABLES -t mangle"</SPAN> # available protocols (01.02.2010) # 100bao aim aimwebcontent applejuice ares armagetron # battlefield1942 battlefield2 battlefield2142 bgp # biff bittorrent chikka cimd ciscovpn citrix counterstrike-source # cvs dayofdefeat-source dazhihui dhcp directconnect # dns doom3 edonkey fasttrack finger freenet ftp gkrellm # gnucleuslan gnutella goboogy gopher guildwars h323 # halflife2-deathmatch hddtemp hotline http-rtsp http ident # imap imesh ipp irc jabber kugoo live365 liveforspeed # lpd mohaa msn-filetransfer msnmessenger mute napster # nbns ncp netbios nntp ntp openft pcanywhere poco pop3 # pplive qq quake-halflife quake1 radmin rdp replaytv-ivs # rlogin rtp rtsp runesofmagic shoutcast sip skypeout # skypetoskype smb smtp snmp socks soribada soulseek ssdp # ssh ssl stun subspace subversion teamfortress2 teamspeak # telnet tesla tftp thecircle tonghuashun tor tsp # unknown unset uucp validcertssl ventrilo vnc # whois worldofwarcraft x11 xboxlive xunlei yahoo zmaap # filter on which <SPAN class=code-keyword>interface</SPAN> NETDEVICE=<SPAN class=code-quote>"eth0"</SPAN> # max <SPAN class=code-keyword>interface</SPAN> speed in kbp/s MAX_RATE=<SPAN class=code-quote>"2000"</SPAN> # protos, queuing and speeds # SLOW will always be qeued last, NORMAL catches all the random stuff <SPAN class=code-keyword>while</SPAN> FAST will <SPAN class=code-keyword>try</SPAN> to push time-critical services ahead. # PROTOS specifies the affected protocols # RATE specifies the maximum speed that these protocols are granted # CEIL specifies the maximum speed <SPAN class=code-keyword>if</SPAN> more bandwidth is available and lower prioritized queues can borrow bandwith from higher prioritized ones. # This way even filesharing won't be restricted at times of low traffic and only will be slowed down on 'rush hour'. SLOW_PROTOS=<SPAN class=code-quote>"100bao applejuice ares bittorrent directconnect edonkey fasttrack freenet ftp gnucleuslan gnutella gopher imesh ipp live365 liveforspeed msn-filetransfer mute napster openft poco pplive qq smb soulseek subspace tftp tonghuashun tsp unknown xunlei zmaap"</SPAN> SLOW_RATE=<SPAN class=code-quote>"200"</SPAN> SLOW_CEIL=<SPAN class=code-quote>"1700"</SPAN> NORMAL_PROTOS=<SPAN class=code-quote>"aimwebcontent armagetron battlefield1942 battlefield2 battlefield2142 bgp biff chikka cimd counterstrike-source cvs dayofdefeat-source dazhihui dhcp dns doom3 finger gkrellm goboogy gopher guildwars h323 halflife2-deathmatch hddtemp hotline ident jabber kugoo lpd mohaa msnmessenger nbns ncp netbios nntp ntp pcanywhere quake-halflife quake1 replaytv-ivs rtp rtsp runesofmagic snmp socks soribada ssdp stun subversion teamfortress2 telnet tesla thecircle tor tsp unset uucp whois worldofwarcraft x11 xboxlive xunlei"</SPAN> NORMAL_RATE=<SPAN class=code-quote>"1000"</SPAN> NORMAL_CEIL=<SPAN class=code-quote>"1800"</SPAN> FAST_PROTOS=<SPAN class=code-quote>"aim ciscovpn citrix http-rtsp http imap irc pcanywhere radmin rdp rlogin shoutcast sip skypeout skypetoskype ssh ssl teamspeak validcertssl ventrilo vnc"</SPAN> FAST_RATE=<SPAN class=code-quote>"1000"</SPAN> FAST_CEIL=<SPAN class=code-quote>"1900"</SPAN> ######################################################## # # ########### !! NO SERVICEABLE PARTS BELOW !! ########### # # ######################################################## # chains IPT_CHAINS=<SPAN class=code-quote>"track protomatch packetsize typeofservice markit split"</SPAN> # som prios to cling to ;) PRIO_1=<SPAN class=code-quote>"11"</SPAN> PRIO_2=<SPAN class=code-quote>"12"</SPAN> PRIO_3=<SPAN class=code-quote>"13"</SPAN> # some reusables log() { logger -s -t <SPAN class=code-quote>"l7shaper"</SPAN> <SPAN class=code-quote>"$1"</SPAN> } die() { logger -s -t <SPAN class=code-quote>"l7shaper"</SPAN> <SPAN class=code-quote>"$1"</SPAN> stop_prio exit 1 } # create chains and flush them create_chains() { <SPAN class=code-keyword>for</SPAN> chain in ${IPT_CHAINS}; <SPAN class=code-keyword>do</SPAN> $IPT -N ${chain} || die <SPAN class=code-quote>"Could not create chains, aborting"</SPAN> done } flush_chains() { <SPAN class=code-keyword>for</SPAN> chain in ${IPT_CHAINS}; <SPAN class=code-keyword>do</SPAN> $IPT -F ${chain} || die <SPAN class=code-quote>"Could not flush chains, aborting"</SPAN> done } # add them to the postrouting mangle table mangle_chains() { <SPAN class=code-keyword>for</SPAN> chain in ${IPT_CHAINS}; <SPAN class=code-keyword>do</SPAN> $IPT -A POSTROUTING -j ${chain} || die <SPAN class=code-quote>"Could not add chains to mangle table, aborting"</SPAN> done } filter_chains() { # find already established connections an restore them $IPT -A track -p tcp -j CONNMARK --restore-mark || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A track -m mark --mark $PRIO_1 -j ACCEPT || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A track -m mark --mark $PRIO_2 -j ACCEPT || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A track -m mark --mark $PRIO_3 -j ACCEPT || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> # <SPAN class=code-keyword>new</SPAN> connection? classify protos and mark them accordingly <SPAN class=code-keyword>for</SPAN> proto in ${SLOW_PROTOS}; <SPAN class=code-keyword>do</SPAN> $IPT -A protomatch -m layer7 --l7proto ${proto} -j MARK --set-mark $PRIO_3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A protomatch -m mark --mark $PRIO_3 -j markit || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> done <SPAN class=code-keyword>for</SPAN> proto in ${NORMAL_PROTOS}; <SPAN class=code-keyword>do</SPAN> $IPT -A protomatch -m layer7 --l7proto ${proto} -j MARK --set-mark $PRIO_2 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A protomatch -m mark --mark $PRIO_2 -j markit || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> done <SPAN class=code-keyword>for</SPAN> proto in ${FAST_PROTOS}; <SPAN class=code-keyword>do</SPAN> $IPT -A protomatch -m layer7 --l7proto ${proto} -j MARK --set-mark $PRIO_1 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A protomatch -m mark --mark $PRIO_1 -j markit || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> done # we can't find a matching protocol. let's test TOS and jump to markit $IPT -A typeofservice -m tos --tos Minimize-Delay -j MARK --set-mark $PRIO_3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A typeofservice -m tos --tos Maximize-Throughput -j MARK --set-mark $PRIO_3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A typeofservice -m mark --mark $PRIO_3 -j markit || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> # mark the connection and jump to split $IPT -A markit -j CONNMARK --save-mark || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A markit -j split || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> # <SPAN class=code-keyword>this</SPAN> chain catches pakets that haven't met any criteria yet # we mark them according to their size $IPT -A packetsize -m length --length 0:128 -j MARK --set-mark $PRIO_2 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A packetsize -m length --length 129: -j MARK --set-mark $PRIO_3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A packetsize -m mark --mark $PRIO_2 -j split || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> $IPT -A packetsize -m mark --mark $PRIO_3 -j split || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the L7 Filter chains, aborting"</SPAN> # now we initialize the queues <SPAN class=code-keyword>for</SPAN> the incoming traffic which has been marked before # no bandwith management is done here, only protocol proirization # the root class and qdisk... $TC qdisc add dev $NETDEVICE root handle 1:0 htb r2q 1 <SPAN class=code-keyword>default</SPAN> 12 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the tc root qdisc, aborting"</SPAN> $TC class add dev $NETDEVICE parent 1:0 classid 1:1 htb rate ${NORMAL_RATE}kbit || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up the tc root class, aborting"</SPAN> # ... and the children $TC class add dev $NETDEVICE parent 1:1 classid 1:11 htb rate ${FAST_RATE}kbit ceil ${FAST_CEIL}kbit prio 1 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent class, aborting"</SPAN> $TC class add dev $NETDEVICE parent 1:2 classid 1:12 htb rate ${NORMAL_RATE}kbit ceil ${NORMAL_CEIL}kbit prio 2 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent class, aborting"</SPAN> $TC class add dev $NETDEVICE parent 1:3 classid 1:13 htb rate ${SLOW_RATE}kbit ceil ${SLOW_CEIL}kbit prio 3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent class, aborting"</SPAN> $TC qdisc add dev $NETDEVICE parent 1:11 htb || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent qdisc, aborting"</SPAN> $TC qdisc add dev $NETDEVICE parent 1:12 htb || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent qdisc, aborting"</SPAN> $TC qdisc add dev $NETDEVICE parent 1:13 htb || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc parent qdisc, aborting"</SPAN> # these are the filters which distribute the now marked packets to the correct queues $TC filter add dev $NETDEVICE parent 1: protocol ip prio 1 handle $PRIO_1 fw flowid 1:1 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc filter, aborting"</SPAN> $TC filter add dev $NETDEVICE parent 1: protocol ip prio 2 handle $PRIO_2 fw flowid 1:2 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc filter, aborting"</SPAN> $TC filter add dev $NETDEVICE parent 1: protocol ip prio 3 handle $PRIO_3 fw flowid 1:3 || die <SPAN class=code-quote>"An error occured <SPAN class=code-keyword>while</SPAN> setting up a tc filter, aborting"</SPAN> } stop_prio() { # deletion of all traffic control settings, flushing the mangle table $TC qdisc del dev $NETDEVICE root && log <SPAN class=code-quote>"Taffic control disabled."</SPAN> <SPAN class=code-keyword>for</SPAN> chain in ${IPT_CHAINS}; <SPAN class=code-keyword>do</SPAN> $IPT -D ${chain} 2> /dev/<SPAN class=code-keyword>null</SPAN> $IPT -F ${chain} 2> /dev/<SPAN class=code-keyword>null</SPAN> $IPT -X ${chain} 2> /dev/<SPAN class=code-keyword>null</SPAN> done; $IPT -F -t mangle; $IPT -X -t mangle && log <SPAN class=code-quote>"Chains deleted."</SPAN> } # print status aof classes and queues list_table() { htb_status <SPAN class=code-keyword>if</SPAN> [ $HTB == off ]; then log <SPAN class=code-quote>"Traffic shaping is not enabled."</SPAN> exit 1 <SPAN class=code-keyword>else</SPAN> $TC -p -s -d class show dev $NETDEVICE 2>/dev/<SPAN class=code-keyword>null</SPAN> $TC -p -s -d qdisc show dev $NETDEVICE 2>/dev/<SPAN class=code-keyword>null</SPAN> fi } # quick status test <SPAN class=code-keyword>for</SPAN> start/stop/status to use htb_status() { $TC qdisc show dev $NETDEVICE | grep htb >/dev/<SPAN class=code-keyword>null</SPAN> <SPAN class=code-keyword>if</SPAN> [ $? -eq 0 ]; then HTB=<SPAN class=code-quote>"on"</SPAN> <SPAN class=code-keyword>else</SPAN> HTB=<SPAN class=code-quote>"off"</SPAN> fi } <SPAN class=code-keyword>case</SPAN> $1 in start) htb_status <SPAN class=code-keyword>if</SPAN> [ $HTB == off ]; then log <SPAN class=code-quote>"Starting traffic shaping on $NETDEVICE"</SPAN> create_chains && log <SPAN class=code-quote>"Chains created."</SPAN> flush_chains && log <SPAN class=code-quote>"Chains flushed."</SPAN> mangle_chains && log <SPAN class=code-quote>"Chains added to mangle table."</SPAN> filter_chains && log <SPAN class=code-quote>"Filter an traffic control configured."</SPAN> log <SPAN class=code-quote>"L7-Filter successfully initialized on $NETDEVICE. Maximum available bandwidth: $MAX_RATE kbp/s"</SPAN> <SPAN class=code-keyword>else</SPAN> log <SPAN class=code-quote>"Traffic shaping already active, aborting."</SPAN> exit 1 fi ;; stop) htb_status <SPAN class=code-keyword>if</SPAN> [ $HTB == on ]; then log <SPAN class=code-quote>"Stopping traffic shaping on $NETDEVICE"</SPAN> stop_prio log <SPAN class=code-quote>"L7-Filter shut down successfully."</SPAN> exit 0 <SPAN class=code-keyword>else</SPAN> log <SPAN class=code-quote>"Traffic shaping is not enabled."</SPAN> exit 1 fi ;; status) list_table ;; restart) $0 stop $0 start ;; *) echo <SPAN class=code-quote>"Usage: $0 start|stop|status|restart"</SPAN> ;; esac |
IP Accounting
Now that we layed rampaging protocols in chains, we might be interested in the usage of our precious bandwidth and its (hopefully) fair distribution amongst users. This can be accomplished through ip accounting, which keeps track of exactly that. I’ll be using the two programs ‘pmacct’ and ‘pmgraph’ in this tutorial. Both are free as speech, grab them from:
Note to Debian/Ubuntu users: you are in luck as packages for both programs are already available through a PPA. Check the installation details here.
Dependencies
The rest of you follow me over here to walk you through the manual installation process. First we will need to fulfill the dependencies of both pmacct and pmgraph. These can normally be obtained through your distributors package management system. If you’re not familiar with some or any of them I suggest you to search for documentation on the interwebs as there is plenty out there and describing a basic LAMP/Tomcat setup is just out of the scope of this how-to.
In short, you will need:
- MySQL-5
- JDK 1.6
- Tomcat-6
- jdbc-mysql
- pmacct (compiled with MySQL support!)
- pmgraph itself can be obtained through the PPA. Chose the latest .tar.gz and download it to a temporary location, we will just need some parts of it. Install and configure all the packages described above. Done? Good, let’s look into the pmacct/pmgraph setup.
Setting up pmacct and pmgraph
pmacct
Unzip the ‘pmgraph’-package first as it also contains the MySQL database schema. At the time of writing the latest available package was pmgraph_1.3-2.tar.gz so this is the version number i’ll be using throughout the how-to.
1 2 3 |
~# mkdir /tmp/pmgraph ~# tar xzpf pmgraph_1.3-2.tar.gz -C /tmp/pmgraph && cd /tmp/pmgraph ~# cd dist |
Edit the file pmacct-create-db_v6.mysql with you favourite editor. You only have to change the password string which is set to ‘secret’ as default.
1 2 3 4 5 6 |
~# vim pmacct-create-db_v6.mysql create database <SPAN class=code-keyword>if</SPAN> not exists pmacct; GRANT SELECT,INSERT, LOCK TABLES ON pmacct.* TO 'pmacct'@'localhost' identified by 'abetterpasswordthansecret'; use pmacct; ... |
Now import the schema into Mysql:
1 |
~# mysql -uroot -p < pmacct-create-db_v6.mysql |
Edit the file pmacctd.conf. The setting ‘pcap_filter’ has to represent your local subnet, otherwise it won’t work. A 10.1.0.0/16 subnet config would look like this:
1 |
pcap_filter: not (src and dst net 10.1.0.0/16) |
Also change the DB settings (check which ip and port your database binds to, it may not be localhost as in the example!):
1 2 3 |
sql_host: localhost sql_user: pmacct sql_passwd: abetterpasswordthansecret |
Now replace the default pmacct configuration with the new one and start the service:
1 2 3 |
~# mv /etc/pmacctd.conf /etc/pmacctd.conf.orig ~# cp pmacctd.conf /etc/pmacctd.conf ~# /etc/init.d/pmacct start |
pmgraph
Still being in the ‘dist’-folder, unzip the file pmgraph.war to the tomcats ‘webapp’-folder (usually ‘/var/lib/tomcat-6/webapps’ but might also be found at ‘/usr/share/tomcat-6/webapps’ depending on the distribution):
1 |
~# unzip pmgraph.war -d /<SPAN class=code-keyword>var</SPAN>/lib/tomcat-6/webapps/pmgraph |
Now we only have to edit the pmgraph configuration. As before we only need to change the database settings and fill in the correct subnet. the notation is a bit different here, to declare a 10.1.0.0/16 subnet you only need the first two octets: ‘10.1.’. Again, if your database does not bind to localhost, change the setting accordingly:
1 2 3 4 5 6 7 8 9 10 |
~# cd /<SPAN class=code-keyword>var</SPAN>/lib/tomcat-6/webapps/pmgraph/WEB-INF/classes ~# vim database.properties ... <entry key=<SPAN class=code-quote>"JdbcDriver"</SPAN>>com.mysql.jdbc.Driver</entry> <entry key=<SPAN class=code-quote>"DatabaseUser"</SPAN>>pmacct</entry> <entry key=<SPAN class=code-quote>"DatabasePass"</SPAN>>abetterpasswordthansecret</entry> <entry key=<SPAN class=code-quote>"DatabaseURL"</SPAN>>jdbc:mysql:<SPAN class=code-comment>//localhost:3306/pmacct</entry> </SPAN><entry key=<SPAN class=code-quote>"LocalSubnet"</SPAN>>10.1.</entry> ... |
Restart the tomcat server two aplly the new configuration (this can also be done through tomcats management panel if the tomcat also holds other apps which you don’t want to interrupt).
Thank you for bearing with me that long, i hope this how-to was helpful. Questions, Suggestions or the bad stuff? Hit me at:
<b2c> at <dest-unreachable> dot <net>