monitor OpenVZ bandwidth and drop connection to a minimum when the maximum exceeds

  • Filter
  • Time
  • Show
Clear All
new posts

    monitor OpenVZ bandwidth and drop connection to a minimum when the maximum exceeds

    Okay i have been trying to figure this for a while now and finally found a way.
    In this Tutorial i am going to explain how i did it if you know a better way to monitor the traffic of a IP let me know.

    first i log on to the OpenVZ container (the VPS) and run some iptables commands

    iptables -N output
    iptables -A OUTPUT -j output
    iptables -N input
    iptables -A INPUT -j input
    this creates the Rules which are needed for the following bash script

    BANDWIDTHLIMIT=42949672960 #40GB (1 GB = 1073741824 bytes)
    #reset counter if it is first of month & create log if it does not exist
    let DATE=`date +%d`
    if [ $DATE -eq 0 ] || [ ! -e /root/bandwidth.log ]; then
    echo "0" > /root/bandwidth.log
    #calculate usage
    let OLDTOTAL=`cat /root/bandwidth.log`
    let IN=`iptables -L INPUT -v -x | grep input | awk '{print $2}'`
    let OUT=`iptables -L OUTPUT -v -x | grep output | awk '{print $2}'`
    let TOTAL=IN+OUT
    #write updated total out to counter log
    echo $NEWTOTAL > /root/bandwidth.log
    #check if total exceeds our warning threshold and send alert if it does
    if [ $NEWTOTAL -gt $BANDWIDTHLIMIT ]; then
    lynx http://[COLOR=#ff0000][/COLOR]/limit.php
    #clear counters
    iptables -L INPUT -Z -v > /dev/null
    iptables -L OUTPUT -Z -v > /dev/null
    exit 0
    i saved this in /etc/init.d/ as iptraffic and made it executeable with chmod +x iptraffic
    then i created a cron job to run the script every minute you can google on how to do that
    next your main server (not the VPS) needs to support ssh2 and the ssh2 php extension:
    yum install libssh2-devel
    pecl install ssh2-beta
    echo >> /etc/php.ini
    service httpd restart
    php -m | grep ssh2
    after that we need a php script which our bash script calls with lynx
    PHP Code:
    if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist");
    // log in at on port 22
    if(!($con ssh2_connect("localhost"22))){
    "fail: unable to establish connection\n";
    } else {
    // try to authenticate with username root, password secretpassword
    if(!ssh2_auth_password($con"root""yourpass")) {
    "fail: unable to authenticate\n";
        } else {
    // allright, we're in!
    echo "okay: logged in...\n";
    // execute a command
    if (!($stream ssh2_exec($con"/etc/init.d/vps* start" ))) {
    "fail: unable to execute command\n";
            } else {
    "VPS Traffic limited" ;
    // collect returning data from command
    $data "";
                while (
    $buf fread($stream,4096)) {
    $data .= $buf;
    okay and again its time for a bash script :D
    # chkconfig: 2345 96 88
    # description: OpenVZ IP drop script.
    #  tc uses the following units when passed as a parameter.
    #  kbps: Kilobytes per second
    #  mbps: Megabytes per second
    #  kbit: Kilobits per second
    #  mbit: Megabits per second
    #  bps: Bytes per second
    #       Amounts of data can be specified in:
    #       kb or k: Kilobytes
    #       mb or m: Megabytes
    #       mbit: Megabits
    #       kbit: Kilobits
    #  To get the byte figure from bits, divide the number by 8 bit
    # Name of the traffic control command.
    # The network interface we're planning on limiting bandwidth.
    IF=venet0             # Interface
    # Download limit (in mega bits)
    DNLD=10mbit          # DOWNLOAD Limit
    # Upload limit (in mega bits)
    UPLD=10mbit          # UPLOAD Limit
    # IP address of the machine we are controlling
    IP=     # Host IP
    # Filter options for limiting the intended interface.
    U32="$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32"
    start() {
    # We'll use Hierarchical Token Bucket (HTB) to shape bandwidth.
    # For detailed configuration options, please consult Linux man
    # page.
        $TC qdisc add dev $IF root handle 1: htb default 30
        $TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD
        $TC class add dev $IF parent 1: classid 1:2 htb rate $UPLD
        $U32 match ip dst $IP/32 flowid 1:1
        $U32 match ip src $IP/32 flowid 1:2
    # The first line creates the root qdisc, and the next two lines
    # create two child qdisc that are to be used to shape download
    # and upload bandwidth.
    # The 4th and 5th line creates the filter to match the interface.
    # The 'dst' IP address is used to limit download speed, and the
    # 'src' IP address is used to limit upload speed.
    stop() {
    # Stop the bandwidth shaping.
        $TC qdisc del dev $IF root
    restart() {
    # Self-explanatory.
        sleep 1
    show() {
    # Display status of traffic control status.
        $TC -s qdisc ls dev $IF
    case "$1" in
        echo -n "Starting bandwidth shaping: "
        echo "done"
        echo -n "Stopping bandwidth shaping: "
        echo "done"
        echo -n "Restarting bandwidth shaping: "
        echo "done"
        echo "Bandwidth shaping status for $IF:"
        echo ""
        echo "Usage: tc.bash {start|stop|restart|show}"
    exit 0
    here we need to adjust the variables IP DNLD UPLD where IP is comes the public ip of the VPS and save it as in /etc/init.d and again make it executeable with chmod +x

    your all set now :D

    Q: How does it work?
    A: The bash script inside the VPS monitors the bandwith incoming and outgoing if this traffic reaches 40GB it starts the lynx command on your server to call the PHP script, the PHP script is a bridge between the VPS and the main server.
    Q: what does the PHP Script do? i see you login as root aint that dangerous?
    A: The PHP script calls the on the main server to drop the connection to 10mbit, yes it could be dangerous when you re passing variables to it and not secure them anyone could perform root commands. but here i am not passing a single variable its all hardcoded if you prefer to do it like i do you can use .htaccess to secure it with username and password but then you need to adjust the "lynx" line to contain user and pass
    Get connection back to full speed on beginning of new month
    Last edited by djdevil89; 12.02.12, 13:52.

    PHP Code:
    foreach ($_SERVER as $server => $value)
    "$server is $value<br />";