Limite diário de download

5

Estou procurando uma maneira de criar um limite diário de internet para o meu servidor Ubuntu. Todo o tráfego de saída sai da Eth2, um dongle usb, este é pré-pago e as crianças o comem rapidamente. Preciso dividir meu valor pré-pago normalmente de 12 Gb em diárias e interromper o tráfego para o dia após esse valor ser atingido. Talvez com uma página da Web lançada dizendo que o limite diário foi excedido.

De preferência, algo do CLI. É uma fera sem cabeça com apenas acesso SSH.

O VNSTAT parece fazer o que eu preciso, eu simplesmente não tenho as habilidades de script para ter um comando ifdown.

Obrigado.

    
por A.Adverse 10.10.2017 / 07:35

1 resposta

5

Minha sugestão é o seguinte script que obterá os dados do tráfego de entrada e saída de ifconfig interface-name e comparará a soma com um valor limite predefinido. Esta ação será repetida a cada 5 segundos (por exemplo).

Quando a quantidade de tráfego (receita + resultado) se tornar igual ou maior que o limite, o script desativará a interface de destino e sairá. A discrepância máxima entre o valor real no qual a interface será desativada e o valor limite será igual a 5s x MaxSpeed .

O script pode ser executado pelo trabalho Cron. Assim, você poderá definir trabalhos diferentes para cada dia da semana, etc. Além disso, quando o limite for atingido, você poderá executar o script manualmente com uma quantidade adicional de tráfego.

O nome do script deve ser traffic-watch , caso contrário, você deve alterar sua quinta linha. Minha sugestão é colocá-lo em /usr/local/bin , assim ele estará disponível como comando shell. Não esqueça de torná-lo executável: chmod +x /usr/local/bin/traffic-watch .

O script deve ser executado como root ( sudo ). Cria um arquivo de log: /tmp/traffic-watch-interface-name.log , onde você pode verificar a última ação. O script tem duas variáveis de entrada:

  • = $LIMIT - o valor do limite de tráfego em MB - o valor padrão é 400 .
  • = $IFACE - o nome da interface de rede de destino - o valor padrão é eth0 .
  • Se você quiser substituir esses valores durante a execução do script, use estes formatos:

    traffic-watch "250" "enp0s25"
    traffic-watch "250"
    traffic-watch "" "enp0s25"
    

Use 'traffic-watch' com 'crontab'. Se você quiser executar o script todas as manhãs em 6:30 , abra o Crontab ( sudo crontab -e ) do root e adicione esta linha:

30 6 * * * /usr/local/bin/traffic-watch 2>/dev/null

Use 'traffic-watch' manualmente. Para rodar o script como root e colocá-lo no background, usaremos sudo -b :

sudo -b traffic-watch "150" 2>/dev/null

O conteúdo do script 'traffic-watch' é:

#!/bin/bash

# Initialize
[ -z "" ] && LIMIT="400"  || LIMIT="" # Set the total traffic daily limit in MB
[ -z "" ] && IFACE="eth0" || IFACE="" # Set the name of the target interface
LOG="/tmp/traffic-watch-$IFACE.log"         # Set the log file name
LANG=C                                      # Set envvar $LANG to 'C' due to grep, awk, etc.
IPPT='[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'       # Set IP address match pattern #IPPT='[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

NIC="$(/sbin/ethtool -i "$IFACE" | awk 'FS=": " {print ; exit}')" # Get the $IFACE (NIC) driver

# Function: Get the current traffic
get_traffic(){
    RX="$(/sbin/ifconfig "$IFACE" | grep -Po "RX bytes:[0-9]+" | sed 's/RX bytes://')" # Get the incoming traffic
    TX="$(/sbin/ifconfig "$IFACE" | grep -Po "TX bytes:[0-9]+" | sed 's/TX bytes://')" # Get the outgoing traffic
    XB=$(( RX + TX ))                                                            # Calculate the total traffic
    XM=$(( XB / ( 1000 * 1000 ) ))                                               # Convert the total traffic in MB
}

# Functions: Disable the interface
interface_down(){ /sbin/ifconfig "$IFACE" down 2>/dev/null && exit; }

# Function: Reset the traffic and enable the interface
reset_traffic_interface_up(){ /sbin/modprobe -r "$NIC" 2>/dev/null && /sbin/modprobe "$NIC" 2>/dev/null && /sbin/ifconfig "$IFACE" up 2>/dev/null; }

# Function: Get the IP address
get_ip(){ /sbin/ifconfig "$IFACE" 2>/dev/null | grep -Po "${IPPT}" | head -1; }

# --- The main program ---

reset_traffic_interface_up

# Wait until the IP address is obtained
until [[ "$(get_ip)" =~ ${IPPT} ]]; do sleep 1; done

# While the interface has IP address == while it is up; check if it is up on every 5 seconds (the 'time' of the cycle is about 75 ms)
while [[ "$(get_ip)" =~ ${IPPT} ]]; do

    get_traffic

    # Start logging
    printf '\n%s\n\nI-face:\t%s\nDriver:\t%s\nIP:\t%s\n' "$(date)" "$IFACE" "$NIC" "$(get_ip)" > "$LOG"
    printf '\nRX:\t%s\nTX:\t%s\nXB:\t%s\nXM:\t%s\n' "$RX" "$TX" "$XB" "$XM" >> "$LOG"

    if (( XM >= LIMIT )); then
        printf '\nThe daily limit of %s MB was reached.' "$LIMIT" >> "$LOG"
        printf '  The interface %s was disabled!\n\n' "$IFACE" >> "$LOG"
        interface_down
    else
            printf '\n%s MB remains on %s.\n\n' "$(( LIMIT - XM ))" "$IFACE" >> "$LOG"
    fi

    # Debug:    cat "$LOG"

    sleep 5 ## *Adjust this value* ##

done; interface_down

Notas:

  • Desative o script quando atualizar e atualizar o sistema! A falta de internet pode ser a causa de pacotes quebrados.

  • É uma boa idéia tentar matar a instância anterior do script (caso seu limite não seja atingido) antes de executar um novo:

    sudo pkill traffic-watch
    sudo -b traffic-watch "150" 2>/dev/null
    
    29 6 * * * /usr/bin/pkill traffic-watch 2>/dev/null 
    30 6 * * * /usr/local/bin/traffic-watch 2>/dev/null 
    
  • Provavelmente 2>/dev/null não é obrigatório, porque, acho que todos, os erros são redirecionados para /dev/null pelo próprio script.

  • Para verificar o tráfego restante remotamente, você pode usar este comando:

    ssh [email protected] tail -n3 /tmp/traffic-watch-eth0.log
    

    Obrigado a @Dessert por essa ideia! (Substitua eth0 pela interface real em uso).

  • Para recuperar sua interface de rede UP: Primeiro ise ifconfig -a para encontrar seu nome. Então sudo ifconfig INTERFACE up .

  • Esse script pode ser recriado para funcionar com iptables em vez de ifconfig - up/down . Esta será uma solução poderosa.

  • O script está disponível como repositório do GitHub em: link

  • Outro script, baseado no atual, que só receberá o tráfego por um período de tempo é fornecido aqui: Como obter o tráfego atual da rede através da linha de comando em um formato simples .

Referências:

por pa4080 10.10.2017 / 15:20