viernes, 14 de junio de 2013

jueves, 13 de junio de 2013

Crear alertas de email a partir de un pattern en un fichero de log

Descargar los paquetes
 
apt-get install libmailtools-perl libunix-syslog-perl libfile-tail-perl libproc-daemon-perl 

Agregar los módulos a CPAN

for m in Mail::Mailer Proc::Daemon Unix::Syslog File::Tail; 
do 
   perl -MCPAN -e "install $m";
done 

Descargar el script de aquí   http://unixlore.net/downloads/logmon.pl.txt


#!/usr/bin/perl -wT
#
# Parses given logfile, looking for specified pattern, sends alert or
# logs message.
#
# Copyright (c) 2012 Doug Maxwell <doug@unixlore.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
# Sample syslog error we want to alert on and usage:
#
# Jul 17 08:02:49 kaylee mysqld[1532]: 110717  8:02:49 [ERROR] /usr/sbin/mysqld: Table './mysql/user' is marked as crashed and should be repaired
#
# logmon.pl -p 'mysqld.+?table.+?crashed' -m you@example.com -u nobody -g adm -f /var/log/syslog -i 120
#
# Needs Mail::Mailer, Proc::Daemon, Unix::Syslog and File::Tail
# installed - the others are core modules.
#
# On Debian/Ubuntu:
# apt-get install libmailtools-perl libunix-syslog-perl libfile-tail-perl libproc-daemon-perl
#
# On Fedora
# yum install perl-MailTools perl-Unix-Syslog perl-File-Tail perl-Proc-Daemon
#
# CPAN:
#
# for m in Mail::Mailer Proc::Daemon Unix::Syslog File::Tail; do perl -MCPAN -e "install $m"; done
#
use strict;
use File::Tail;
use Mail::Mailer;
use Proc::Daemon;
use Unix::Syslog qw(:subs);
use Unix::Syslog qw(:macros);
use Getopt::Std;
use Sys::Hostname;
use POSIX qw(setuid setgid);
use English;

our ($opt_m,$opt_f,$opt_p,$opt_u,$opt_g,$opt_i,$opt_h,$opt_d,$opt_v);
getopts('hdvm:f:p:u:g:i:');

usage() && exit if ( $opt_h || !$opt_p);

sub usage {
    print "\n$0 synopsis: Daemon that periodically checks logfile for a pattern and send alerts\n";
    print "Pattern is always required. If no other options are given, defaults to syslog alerts and monitors /var/log/messages for given pattern.\n";
    print "Usage: $0  -p pattern [-m alerts\@example.com] [-f logfile] [-u run as user] [-g run as group] [-i max interval] [-v] [-d] [-h]\n";
    print "-m: Email destination for alerts\n-f: logfile to monitor\n-p: Pattern to match against lines in logfile (Perl regexp, match is case-insensitive)\n-u: Run with permissions of user\n-g: Run with permissions of group\n-i: Max time to sleep between checks\n-d: Debug output to STDERR, do not daemonize\n-v: Verbose logging (use with caution or you may have endless alerts)\n-h: This help text\n\n";
}

my $DEBUG = 1 if ( $opt_d );

if ( !$DEBUG ) {
    # Fork and detach
    log_alert("Forking and detaching from controlling terminal...");
    Proc::Daemon::Init;
}

# Drop privileges if needed.
if ( $opt_g && $UID == 0 ) {
    setgid( scalar getgrnam $opt_g ) or log_alert($!);
    log_alert("Now running with permissions of group $opt_g") if ( $GID );
}

if ( $opt_u && $UID == 0 ) {
    setuid( scalar getpwnam $opt_u ) or log_alert($!);
    log_alert("Now running with permissions of user $opt_u") if ( $UID );
}

# Clean up our environment for taint mode
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
$ENV{PATH} = "/bin:/usr/bin";

# Source of email alerts
my $from = 'root@example.com';

# The logfile we are monitoring. Make sure we can read it and that it
# exists.
my $logfile = "/var/log/messages";

if ( $opt_f ) {
    if ( ! -r $opt_f ) {
        log_alert("Logfile $opt_f does not exist or is not readable");
        die;
    } else {
        $logfile = $opt_f;
    }
}

# Pre-compile the regexp we are using
my $pattern = qr/$opt_p/io;

# Mail recipient for alerts
my $recipient = $opt_m if ( $opt_m );

# Max time to wait between checks. File::Tail uses an adaptive
# algorithm to vary the time between file checks, depending on the
# amount of data being written to the file. This is the maximum
# allowed interval.
my $maxinterval = 60;
$maxinterval = $opt_i if ( $opt_i );

my $file = File::Tail->new(name=>$logfile, maxinterval=> $opt_i, adjustafter=>3) or ( log_alert($!) && die );

( $opt_v ) ? log_alert("Running and monitoring $logfile for $pattern") : log_alert("Running and monitoring $logfile");

# Loop as long as we keep getting lines from the file
while (defined(my $line = $file->read)) {
    if ( $line =~ /$pattern/ ) {
        chomp($line);
        if ( $opt_m ) {
            send_mail_alert($from,$recipient,$line);
        } else {
            ( $opt_v ) ? log_alert("Matched $pattern against '$line' in $logfile") : log_alert("$logfile matched!");
        }
    }
}

# Send an email alert using sendmail on the localhost
sub send_mail_alert {
  my ($from,$recipient,$body) = @_;
  my $hostname = hostname();
  my $subject = "Alert from $0 on $hostname while monitoring $logfile for $pattern";
  my $mailer = Mail::Mailer->new("sendmail");
  $mailer->open({ From    => $from,
    To      => $recipient,
    Subject => $subject,
  })
    or log_alert($!);
  print $mailer $body or log_alert($!);
  $mailer->close( );
  log_alert("Sent email alert to $recipient");
  return;
}

# Log a message to this system's syslog. If debugging is enabled, we
# are not a daemon and we just print to STDERR.
sub log_alert {
  my $text = shift;

  if ( $DEBUG ) {
      print STDERR "$0: $text\n";
      return;
  }

  openlog ("$0", LOG_PERROR|LOG_CONS , LOG_LOCAL7);
  syslog (LOG_INFO, "$text\n");
  closelog();
  return;
}
 
 
 Chequear que la sintaxis es correcta con el comando: 
perl -cwT ./logmon.pl

Copiar el fichero en sbin con sus permisos con el siguiente comando



install -m 755 logmon.pl /usr/local/bin/ 

Para ejecutar el comando se puede hacer con:

logmon.pl -p 'pattern buscada' -m pepe@gmail.com -u nobody -g adm -f /var/log/kern.log -i 120

para ejecutarlo en modo debur -dv  (debug + verbose)

para matar el demonio pkill logmon


Fuente: http://www.unixlore.net/articles/monitoring-alerting-patterns-linux-logfiles.html



 

martes, 11 de junio de 2013

Comandos de control de sipwise desde consola

 ngcp-kamctl lb and ngcp-sercmd lb
for querying kamailio functions, for example:
 ngcp-sercmd lb htable.dump ipban.

miércoles, 5 de junio de 2013

proxy transparente con squid en debian

http://parbaedlo.wordpress.com/2013/03/08/configurar-proxy-squid-transparente-en-linux-debian-squeeze/

configurar proxy squid transparente en linux debian squeeze

Ahora configuraremos proxy transparente pero para poder comenzar previamente tenemos que configurar las tarjetas de red y el DHCP.
para configurar las tarjetas de red editar el archivo /etc/network/interfaces para que quede de la siguiente manera

auto lo eth0 eth1
iface lo inet loopback

#Configuracion para interfaz con red eth0 con internet
allow-hotplug eth0
iface eth0 inet static
  address 172.16.2.111
  netmask 255.255.255.0
  gateway 172.16.2.1
  network 172.16.2.0
  broadcast 172.16.2.255
  dns-nameservers 8.8.8.8 #esto también se puede configurar en /etc/resolv.conf

#Configuracion para interfaz eth1 con red lan interna privada
allow-hotplug eth1
  iface eth1 inet static
  address 192.168.2.1
  netmask 255.255.255.0
  network 192.168.2.0
  broadcast 192.168.2.255
Ahora instalamos y configuramos el servidor DHCP que nos servira para proporcionar ips automaticos a las pc’s de la red lan
 # aptitude install isc-dhcp-server 
Configuramos el servicio de DHCP para que este disponible en la red interna y acepte las conexiones en dicha red, en este caso es la interfaz eth1, esto se configura en el archivo /etc/default/isc-dhcp-server
INTERFACES="eth0"
Ahora tenemos que modificar algunas lineas el archivo /etc/dhcpd.conf para especificar rango de ips y tiempo que se le proporcionara el ip a la maquina cliente
option domain-name "example.org";
option domain-name-servers 8.8.8.8, 4.4.4.4;
default-lease-time 600;
max-lease-time 7200;

#SubNet red lan.
subnet 192.168.2.0 netmask 255.255.255.0 {
  range 192.168.2.101 192.168.2.199;
  #option domain-name-servers 8.8.8.8;  #similar a la parte superior
  #option domain-name "example.org";  #similar a la parte superior
  option routers 192.168.2.1;
  option broadcast-address 192.168.2.255;
  #default-lease-time 86400;  #similar a la parte superior
  #max-lease-time 172800;   #similar a la parte superior
} 
Con el servidor DHCP se puede asignar un ip especifica a una determinada mac-address, estas direcciones fijas no deben estar en la gama de las direcciones reservadas para la distribución dinámica.
host desktop {
  hardware ethernet 01:23:45:67:89:10;
  fixed-address 192.168.2.2;
}
host laptop {
  hardware ethernet 01:23:45:67:89:11;
  fixed-address 192.168.2.3;
}
Reiniciar el servicio de dhcp:
# /etc/init.d/isc-dhcp-server restart
Ahora el ultimo paso instalación y configuración de squid, procedemos a la instalacion con el siguiente comando
 # aptitude install squid
Ahora vamos a hacer unos cambios en el fichero de configuración de squid (/etc/squid/squid.conf). Primero localizamos la línea con el puerto de entrada de squid (por defecto http_port 3128) y añadimos el parámetro transparente. Debe de quedarnos algo así:
http_port 3128 transparent 
A continuación de esto, y en el mismo fichero, añadimos las siguientes líneas:
acl redlan src 192.168.2.0/24
http_access allow redlan 
Ahora sólo nos queda configurar la máquina como router y direccionar el tráfico web (puerto 80) que recibe por el interfaz interno (eth1) al puerto 3128 que es el que usa squid. Esto lo hacemos gracias a IPtables (que vienen instaladas en Debian por defecto) el script que se detalla a continuación, se debe configurar para que se ejecute de forma automática.
#!/bin/sh
# squid server IP
SQUID_SERVER="192.168.2.1"
# Interface connected to Internet
INTERNET="eth0"
# Interface connected to LAN
LAN_IN="eth1"
# Squid port
SQUID_PORT="3128"
# DO NOT MODIFY BELOW
# Clean old firewall
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Load IPTABLES modules for NAT and IP conntrack support
modprobe ip_conntrack
modprobe ip_conntrack_ftp
# For win xp ftp client
#modprobe ip_nat_ftp
echo 1 > /proc/sys/net/ipv4/ip_forward
# Setting default filter policy
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# Unlimited access to loop back
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow UDP, DNS and Passive FTP
iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED,RELATED -j ACCEPT
# set this system as a router for Rest of LAN
iptables --table nat --append POSTROUTING --out-interface $INTERNET -j MASQUERADE
iptables --append FORWARD --in-interface $LAN_IN -j ACCEPT
# unlimited access to LAN
iptables -A INPUT -i $LAN_IN -j ACCEPT
iptables -A OUTPUT -o $LAN_IN -j ACCEPT
# DNAT port 80 request comming from LAN systems to squid 3128 ($SQUID_PORT) aka transparent proxy
iptables -t nat -A PREROUTING -i $LAN_IN -p tcp --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT
# if it is same system
iptables -t nat -A PREROUTING -i $INTERNET -p tcp --dport 80 -j REDIRECT --to-port $SQUID_PORT
# DROP everything and Log it
iptables -A INPUT -j LOG
iptables -A INPUT -j DROP 
Para guarde el anterior script nos creamos la carpeta /etc/iptables-script y dentro de ahi colocamos el script con el nombre de proxy.sh, de damos permisos de ejecución:
 # chmod +x /etc/iptables-script/proxy.sh 
Y le indicamos al SO que ejecute dicho script al iniciar el sistema para esto editamos el archivo /etc/rc.local, y antes de exit colocamos la siguiente linea:
sh /etc/iptables-script/proxy.sh
 

Load Balancer - Balancero de Carga con dos Wan usando router EdgeMax de ubiquiti

set protocols static route 0.0.0.0/0 next-hop 192.168.2.1
set protocols static route 0.0.0.0/0 next-hop 192.168.1.1
set protocols static table 1 mark 1
set protocols static table 1 route 0.0.0.0/0 next-hop 192.168.2.1
set protocols static table 2 mark 2
set protocols static table 2 route 0.0.0.0/0 next-hop 192.168.1.1

set firewall modify balance rule 10 action modify
 set firewall modify balance rule 10 description 'restore mark from connection'
 set firewall modify balance rule 10 modify connmark restore-mark

 set firewall modify balance rule 20 action accept
 set firewall modify balance rule 20 description 'accept the packet if the mark isnt zero'
 set firewall modify balance rule 20 mark !0

 set firewall modify balance rule 30 action modify
 set firewall modify balance rule 30 description 'for new connections mark 50% with mark 1'
 set firewall modify balance rule 30 modify mark 1
 set firewall modify balance rule 30 protocol tcp_udp
 set firewall modify balance rule 30 state new enable
 set firewall modify balance rule 30 statistic probability 50%

 set firewall modify balance rule 40 action modify
 set firewall modify balance rule 40 description 'for packets with mark zero, mark with 2'
 set firewall modify balance rule 40 mark 0
 set firewall modify balance rule 40 modify mark 2
 set firewall modify balance rule 40 protocol tcp_udp
 set firewall modify balance rule 40 state new enable

 set firewall modify balance rule 50 action modify
 set firewall modify balance rule 50 description 'save the packet mark to the connection mark'
 set firewall modify balance rule 50 modify connmark save-mark

 set interfaces ethernet eth2 firewall in modify balance

 set firewall modify ISP1_IN rule 1 description 'use mark 1 for new ISP1 connections'
 set firewall modify ISP1_IN rule 1 action modify
 set firewall modify ISP1_IN rule 1 log enable
 set firewall modify ISP1_IN rule 1 modify connmark set-mark 1
 set firewall modify ISP1_IN rule 1 protocol tcp_udp
 set firewall modify ISP1_IN rule 1 state new enable

 set firewall modify ISP2_IN rule 1 description 'use mark 2 for new ISP2 connections'
 set firewall modify ISP2_IN rule 1 action modify
 set firewall modify ISP2_IN rule 1 log enable
 set firewall modify ISP2_IN rule 1 modify connmark set-mark 2
 set firewall modify ISP2_IN rule 1 protocol tcp_udp
 set firewall modify ISP2_IN rule 1 state new enable

 set interfaces ethernet eth0 firewall in modify ISP1_IN
 set interfaces ethernet eth1 firewall in modify ISP2_IN

lunes, 3 de junio de 2013

wifi chillispot roaming with radius

http://www.chillispot.info/chilliforum/viewtopic.php?id=107

http://robin.forumup.it/about2471-0.html

http://lists.freeradius.org/pipermail/freeradius-devel/2011-August/006263.html

Pues según he podido investigar en varios sitios, para hacer roaming en varios APs, una forma (no se si la mejor o la peor pero no deja de ser una solución) es tras autenticarse con el ticket, añadir el usuario en rackcheck con la mac, de la siguiente forma

1º En el radius (en mi caso freeradius con backend de mysql) se crean los usuarios usando como username la MAC del dispositivo que se quiere autenticar sin preguntar en el portal cautivo. Como atributo, Password y como Value, un password arbitrario que será para todos el mismo. Este password se ve en el segundo paso, porque hay que configurarlo en el chilli.conf

 mysql> select  * from radcheck where attribute='Password';
+------+-------------------+-----------+----+---------+
| id   | username          | attribute | op | value   |
+------+-------------------+-----------+----+---------+
| 1829 | 64-A7-69-81-10-ED | Password  | := | pass123 |
| 1831 | 98-0C-82-96-2F-0C | Password  | := | pass123 |
+------+-------------------+-----------+----+---------+

La mac del cliente se puede obtener despues de la primera autenticación existosa de la tabla radacct
en el campo  callingstationid

| radacctid | acctsessionid    | acctuniqueid     | username          | groupname | realm | nasipaddress | nasportid | nasporttype     | acctstarttime       | acctstoptime | acctsessiontime | acctauthentic | connectinfo_start | connectinfo_stop | acctinputoctets | acctoutputoctets | calledstationid   | callingstationid  | acctterminatecause | servicetype | framedprotocol | framedipaddress | acctstartdelay | acctstopdelay | xascendsessionsvrkey |
+-----------+------------------+------------------+-------------------+-----------+-------+--------------+-----------+-----------------+---------------------+--------------+-----------------+---------------+-------------------+------------------+-----------------+------------------+-------------------+-------------------+--------------------+-------------+----------------+-----------------+----------------+---------------+----------------------+
|       139 | 51b0a3c100000005 | 21b6a99e5ed39028 | 64-A7-69-81-10-ED |           |       | 0.0.0.0      | 5         | Wireless-802.11 | 2013-06-06 16:59:47 | NULL         |               0 |               |                   |                  |               0 |                0 | 00-27-22-C4-29-3D | 64-A7-69-81-10-ED |                    |             |                | 192.168.182.7   |              0 |             0 |                      |
+-----------+------------------+------------------+-------------------+-----------+-------+--------------+-----------+-----------------+---------------------+--------------+-----------------+---------------+-------------------+------------------+-----------------+------------------+-------------------+-------------------+--------------------+-------------+----------------+-----------------+----------------+---------------+----------------------+

2ª parte

añadir a las opciones de chillispot los parametros de macauth y macpassword = pass123 (en mi caso)

Mi fichero de chillispot es el siguiente:

coaport 3799
lease 600
dhcpif ath0
radiusserver1 10.0.1.254
radiusserver2 10.0.1.254
radiusauthport 1812
radiusacctport 1813
dns1 8.8.8.8
net 192.168.182.0/24
uamserver http://10.0.1.254/hotspotlogin.php
radiusnasid ubiquiti
radiussecret 1964os
uamallowed 192.168.182.0/24,10.0.1.254,8.8.8.8
uamsecret 1964os
macauth
macpasswd pass123


3º Meter un trigger para que cuando se autentique alguien, meta en radcheck la mac
DELIMITER |
CREATE TRIGGER mac_radcheck AFTER INSERT ON radpostauth
  FOR EACH ROW BEGIN
INSERT INTO radcheck (username,attribute,op,value) VALUES('mac','Password',':=','pass123');
 
  END

|

mac hay que sustituirlo por la consulta que me da la mac del usuario autenticado
select callingstationid from radacct where username='vitoria' order by acctstarttime desc limit 1;



y todo junto sería...

DELIMITER |
CREATE TRIGGER mac_radcheck AFTER INSERT ON radpostauth
  FOR EACH ROW BEGIN
INSERT INTO radcheck (username,attribute,op,value) VALUES((select callingstationid from radacct where username=NEW.username order by acctstarttime desc limit 1),'Password',':=','pass123');
 
  END
|

delimiter ;


------

El trigger no funciona bien, he decidido poner un cron con alguna query como la siguiente

select distinct radpostauth.username,radacct.callingstationid from radpostauth,radacct where radpostauth.username=radacct.username and radpostauth.username not like '%-%';