Rutas estáticas fijas en debian

Otra entrada que es un apunte.

Normalmente, para añadir una ruta estática en nuestro GNU/Debian, basta con teclear en la consola:

route add -net red.de.destino.0 netmask mascara.a.poner.0 gw gateway

Por ejemplo, si queremos enrutar la red 192.168.5.0 por la 192.168.2.251, tendremos que añadir:

route add -net 192.168.5.0 netmask 255.255.255.0 gw 192.168.2.251

Ahora, si la queremos hacer permanente, editaremos el fichero /etc/network/intefaces y lo dejaremos tal que:


allow-hotplug eth0
iface eth0 inet static
address 192.168.x.x
netmask 255.255.255.0
gateway 192.168.x.x
network 192.168.2.0
broadcast 192.168.2.255
dns-nameserver 192.168.x.x 192.168.x.x
dns-namesearch craem.net
post-up route add -net 192.168.5.0 netmask 255.255.255.0 gw 192.168.2.251

Siendo la línea con post-up route …. la encargada en cuestión.

Enjoy your routes 😉

Multisite en apache con debian squeeze

Esta entrada es otro apunte para no olvidar los pasos.

Cuando tenemos una sola ip pública disponible y queremos alojar varios sitios, no queda otra que habilitar los diferentes sites en directorios diferentes en nuestro apache. También se aplica si tenemos un servidor web y no queremos ir haciendo máquinas virtuales para cada site, ya que malgastamos recursos.

Nos ponemos en antecedentes…. suponemos que tenemos blog alojado; http://blog.craem.net, pero para un colega que quiere colgar otro blog, tenemos el dominio blog.pepito.com.

Primero de todo, en el home de nuestro server, le creamos el directorio:

diablo:/home# ls -l
total 20
drwxr-xr-x 16 www-data www-data 4096 dic 5 23:51 blog
diablo:/home#mkdir blog.pepito.com
diablo:/home#chown -R www-data:www-data blog.pepito.com
diablo:/home#ls -l
diablo:/home# ls -l
total 20
drwxr-xr-x 16 www-data www-data 4096 dic 5 23:51 blog
drwxr-xr-x 3 www-data www-data 4096 ago 19 09:53 blog.pepito.com
diablo:/home#

Hemos creado el directorio y hemos hecho propietario al usuario www-data.

En este directorio copiaremos los ficheros de la web; léase wordpress, joomla, html ……

Ahora crearemos el sitio en el apache; para ello nos vamos a /etc/apache2 y creamos el fichero del sitio:

diablo:/#cd /etc/apache2/sites-available
diablo:/etc/apache2/sites-available# ls -l
total 36
-rw-r–r– 1 root root 946 jul 7 23:30 default
-rw-r–r– 1 root root 7366 mar 28 2010 default-ssl
-rw-r–r– 1 root root 231 ago 24 19:16 blog.craem.net
diablo:/etc/apache2/sites-available# cp blog.craem.net blog.pepito.com
diablo:/etc/apache2/sites-available# ls -l
total 36
-rw-r–r– 1 root root 946 jul 7 23:30 default
-rw-r–r– 1 root root 7366 mar 28 2010 default-ssl
-rw-r–r– 1 root root 231 ago 24 19:16 blog.craem.net
-rw-r–r– 1 root root 231 ago 24 19:16 blog.pepito.com

Y editamos el fichero creado:

diablo:/etc/apache2/sites-available#nano blog.pepito.com

Y lo dejamos tal que:


ServerName blog.pepito.com
ServerAdmin administrador@sitio.com
DocumentRoot /home/blog.pepito.com
DirectoryIndex index.php

AllowOverride All
Order Deny,Allow
Allow from all

Guardamos cambios, reiniciamos apache

# /etc/init.d/apache2 restart

y habilitamos el site:

diablo:/etc/apache2/sites-available# a2ensite blog.pepito.com

Volvemos a reiniciar el apache y listo.

Enjoy your server 😉

Concatenar rutas estáticas en dhcp3 con Debian

Otra entrada que es un apunte.

Hoy me ha tocado añadir en mi dhcp, 2 rutas estáticas, una de clase A y otra de clase C. Esto, lo había hecho hace tiempo con los dhcp de windows, pero con Linux no estaba tan claro.

Siguiendo los estándares, veo que las rutas estáticas con clase se basan en la rfc 3442, de lectura obligada:

http://tools.ietf.org/html/rfc3442

Y nos dice que añadir varias, tiene que ser de la forma:

Classless Route Option Format

The code for this option is 121, and its minimum length is 5 bytes.
This option can contain one or more static routes, each of which
consists of a destination descriptor and the IP address of the router
that should be used to reach that destination.

Code Len Destination 1 Router 1
+—–+—+—-+—–+—-+—-+—-+—-+—-+
| 121 | n | d1 | … | dN | r1 | r2 | r3 | r4 |
+—–+—+—-+—–+—-+—-+—-+—-+—-+

Destination 2 Router 2
+—-+—–+—-+—-+—-+—-+—-+
| d1 | … | dN | r1 | r2 | r3 | r4 |
+—-+—–+—-+—-+—-+—-+—-+

In the above example, two static routes are specified.

En mi caso, quiero añadir las siguientes rutas:

10.0.0.0 / 8 gateway: 192.168.2.251
192.168.5.0 / 24 gateway: 192.168.2.251

Editamos el fichero /etc/dhcp3/dhcpd.conf y en mi caso, lo dejo tal que:

# option definitions common to all supported networks…
option rfc3442-classless-static-routes 24, 192, 168, 5, 192, 168, 2, 251, 8, 10, 192, 168, 2, 251;

Para la red 192.168.5.0/24: 24, 192, 168, 5, 192, 168, 2, 251
|
|->red / 24
Para la red 10.0.0.0/8 : 8, 10, 192, 168, 2, 251
|
|–> red / 8

Enjoy your dhcp.

FreeRadius + Mysql + PPTPD en Debian.

Siguiendo al post anterior, ahora toca crear el servidor PPTPD, para por ejemplo, lanzar la vpn desde nuestro android.

Primero comprobamos si tenemos en el Kernel de nuestro linux, el soporte para MPPE, para ello:

# modprobe ppp-compress-18 && echo OK

Si sale OK, pues eso, ha ido bien…. ¿ y qué es eso de MPPE ?, pues nada, un protocolo de micro$oft para encriptar datos, léase:

http://en.wikipedia.org/wiki/Microsoft_Point-to-Point_Encryption

Y ojo, que tiene su propia RFC (O_o).

Ahora, instalamos el server pptpd en nuestro querido debian:

# apt-get install pptpd

Antes de empezar a configurar, hemos de tener claro:

1º) Pool de Ip’s que les asignaremos a los usuarios
2º) Dentro del Pool, las opciones de dns y demás que querremos usar para los clientes

Editamos el fichero /etc/pptpd.conf y lo vamos dejando tal que:

localip 192.168.2.13
remoteip 192.168.100.234-240

Donde localip, que con gran ojo avizor, deducimos que es la ip de nuestro servidor y, el que tenga la suerte de poder ponerle la ip pública directamente, pues eso que se lleva.

La remoteip, será el pool de IP’s que asignaremos a los usuarios remotos.

Guardamos los cambios, reinciamos el daemon pptpd y seguimos configurando y instalamos el paquete libradiusclient-ng2, que será el responsable de la relación entre pptpd y freeradius… para ello:

apt-get install libradiusclient-ng2

Y renombramos la carpeta para que quede más elegante:

mv /etc/radiusclient-ng/ /etc/radiusclient/

Creamos un fichero, que ya explicaremos la función:

echo “” > /etc/radiusclient/port-id-map

Ahora editaremos el fichero radiusclient.conf

# nano /etc/radiusclient/radiusclient.conf

Y lo dejamos tal que:

# General settings

# specify which authentication comes first respectively which
# authentication is used. possible values are: “radius” and “local”.
# if you specify “radius,local” then the RADIUS server is asked
# first then the local one. if only one keyword is specified only
# this server is asked.
auth_order radius

# maximum login tries a user has
login_tries 4

# timeout for all login tries
# if this time is exceeded the user is kicked out
login_timeout 60

# name of the nologin file which when it exists disables logins.
# it may be extended by the ttyname which will result in
# a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable
# logins on /dev/ttyS2)
nologin /etc/nologin

# name of the issue file. it’s only display when no username is passed
# on the radlogin command line
issue /etc/radiusclient/issue

# RADIUS settings

# RADIUS server to use for authentication requests. this config
# item can appear more then one time. if multiple servers are
# defined they are tried in a round robin fashion if one
# server is not answering.
# optionally you can specify a the port number on which is remote
# RADIUS listens separated by a colon from the hostname. if
# no port is specified /etc/services is consulted of the radius
# service. if this fails also a compiled in default is used.
authserver localhost:1812

# RADIUS server to use for accouting requests. All that I
# said for authserver applies, too.
#
acctserver localhost:1812

# file holding shared secrets used for the communication
# between the RADIUS client and server
servers /etc/radiusclient/servers

# dictionary of allowed attributes and values
# just like in the normal RADIUS distributions
dictionary /etc/radiusclient/dictionary

# program to call for a RADIUS authenticated login
login_radius /usr/sbin/login.radius

# file which holds sequence number for communication with the
# RADIUS server
seqfile /var/run/radius.seq

# file which specifies mapping between ttyname and NAS-Port attribute
mapfile /etc/radiusclient/port-id-map

# default authentication realm to append to all usernames if no
# realm was explicitly specified by the user
# the radiusd directly form Livingston doesnt use any realms, so leave
# it blank then
default_realm

# time to wait for a reply from the RADIUS server
radius_timeout 10

# resend request this many times before trying the next server
radius_retries 3

# local address from which radius packets have to be sent
# bindaddr 0.0.0.0

# LOCAL settings

# program to execute for local login
# it must support the -f flag for preauthenticated login
login_local /bin/login

Definiremos nuestros servidores radius (modificando lo que está en negrita), con lo que toque.

Ahora definiremos la pre-shared key para los servidores radius:

nano /etc/radiusclient/servers

y colocamos nuestros datos:

#Server Name or Client/Server pair Key
#—————- —————
ip.de.nuestro.radius_server misuperclavemolona

Editamos el fichero pptpd-options

nano /etc/ppp/pptpd-options

Por ahora, nos vamos a centrar en pap / spap… una vez nos funcione, buscaremos otros métodos más seguros:

###############################################################################
# $Id: pptpd-options 4643 2006-11-06 18:42:43Z rene $
#
# Sample Poptop PPP options file /etc/ppp/pptpd-options
# Options used by PPP when a connection arrives from a client.
# This file is pointed to by /etc/pptpd.conf option keyword.
# Changes are effective on the next connection. See “man pppd”.
#
# You are expected to change this file to suit your system. As
# packaged, it requires PPP 2.4.2 and the kernel MPPE module.
###############################################################################

# Authentication

# Name of the local system for authentication purposes
# (must match the second field in /etc/ppp/chap-secrets entries)
name minombrechulo-del-servidor

# Optional: domain name to use for authentication
domain craem.net

# Strip the domain prefix from the username before authentication.
# (applies if you use pppd with chapms-strip-domain patch)
#chapms-strip-domain

# Encryption
# Debian: on systems with a kernel built with the package
# kernel-patch-mppe >= 2.4.2 and using ppp >= 2.4.2, …
# {{{
require-pap
require-chap
refuse-mschap

# Require the peer to authenticate itself using MS-CHAPv2 [Microsoft
# Challenge Handshake Authentication Protocol, Version 2] authentication.
# refuse-mschap-v2
# Require MPPE 128-bit encryption
# (note that MPPE requires the use of MSCHAP-V2 during authentication)
# refuse-mppe-128
# }}}

# Network and Routing

# If pppd is acting as a server for Microsoft Windows clients, this
# option allows pppd to supply one or two DNS (Domain Name Server)
# addresses to the clients. The first instance of this option
# specifies the primary DNS address; the second instance (if given)
# specifies the secondary DNS address.
# Attention! This information may not be taken into account by a Windows
# client. See KB311218 in Microsoft’s knowledge base for more information.
ms-dns 8.8.8.8
ms-dns 8.8.4.4

# If pppd is acting as a server for Microsoft Windows or “Samba”
# clients, this option allows pppd to supply one or two WINS (Windows
# Internet Name Services) server addresses to the clients. The first
# instance of this option specifies the primary WINS address; the
# second instance (if given) specifies the secondary WINS address.
#ms-wins 10.0.0.3
#ms-wins 10.0.0.4

# Add an entry to this system’s ARP [Address Resolution Protocol]
# table with the IP address of the peer and the Ethernet address of this
# system. This will have the effect of making the peer appear to other
# systems to be on the local ethernet.
# (you do not need this if your PPTP server is responsible for routing
# packets to the clients — James Cameron)
proxyarp

# Debian: do not replace the default route
nodefaultroute

# Logging

# Enable connection debugging facilities.
# (see your syslog configuration for where pppd sends to)
#debug

# Print out all the option values which have been set.
# (often requexsted by mailing list to verify options)
#dump

# Miscellaneous

# Create a UUCP-style lock file for the pseudo-tty to ensure exclusive
# access.
lock

# Disable BSD-Compress compression
nobsdcomp

mtu 1200
mru 1200
plugin radius.so
plugin radattr.so
lcp-echo-failure 50

Creamos un NAS en nuestro radius (lo vimos en el post anterior), reiniciamos el servicio pptpd y listo.

Probamos un cliente ( un android, por ejemplo)

Starting PPTP Daemon: pptpd.
root@radius_lan:/etc/ppp# tail -f /var/log/syslog
Oct 8 00:51:12 rlan pppd[2488]: Using interface ppp0
Oct 8 00:51:12 rlan pppd[2488]: Connect: ppp0 <--> /dev/pts/1
Oct 8 00:51:12 rlan pptpd[2486]: GRE: Bad checksum from pppd.
Oct 8 00:51:12 rlan pppd[2488]: Deflate (15) compression enabled
Oct 8 00:51:12 rlan pppd[2488]: Cannot determine ethernet address for proxy ARP
Oct 8 00:51:12 rlan pppd[2488]: local IP address 192.168.2.94
Oct 8 00:51:12 rlan pppd[2488]: remote IP address 192.168.100.234
Oct 8 00:51:26 rlan pptpd[2495]: MGR: Maximum of 200 connections reduced to 7, not enough IP addresses given
Oct 8 00:51:26 rlan pptpd[2496]: MGR: Manager process started
Oct 8 00:51:26 rlan pptpd[2496]: MGR: Maximum of 7 connections available
Oct 8 00:51:40 rlan pptpd[2486]: CTRL: EOF or bad error reading ctrl packet length.
Oct 8 00:51:40 rlan pptpd[2486]: CTRL: couldn’t read packet header (exit)
Oct 8 00:51:40 rlan pptpd[2486]: CTRL: CTRL read failed
Oct 8 00:51:40 rlan pptpd[2486]: CTRL: Reaping child PPP[2488]
Oct 8 00:51:40 rlan pptpd[2498]: CTRL: Client 192.168.2.68 control connection started
Oct 8 00:51:40 rlan pptpd[2498]: CTRL: Starting call (launching pppd, opening GRE)
Oct 8 00:51:40 rlan pppd[2499]: Plugin radius.so loaded.
Oct 8 00:51:40 rlan pppd[2499]: RADIUS plugin initialized.
Oct 8 00:51:40 rlan pppd[2499]: Plugin radattr.so loaded.
Oct 8 00:51:40 rlan pppd[2499]: RADATTR plugin initialized.
Oct 8 00:51:40 rlan pppd[2499]: Plugin /usr/lib/pptpd/pptpd-logwtmp.so loaded.
Oct 8 00:51:40 rlan pppd[2499]: pppd 2.4.5 started by root, uid 0
Oct 8 00:51:40 rlan pppd[2499]: Using interface ppp1
Oct 8 00:51:40 rlan pppd[2499]: Connect: ppp1 <--> /dev/pts/2
Oct 8 00:51:40 rlan pptpd[2498]: GRE: Bad checksum from pppd.
Oct 8 00:51:40 rlan pppd[2499]: Deflate (15) compression enabled
Oct 8 00:51:40 rlan pppd[2499]: Cannot determine ethernet address for proxy ARP
Oct 8 00:51:40 rlan pppd[2499]: local IP address 192.168.2.13
Oct 8 00:51:40 rlan pppd[2499]: remote IP address 192.168.100.234

Y vemos el log del freeradius:

Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.
rad_recv: Access-Request packet from host 127.0.0.1 port 33461, id=45, length=108
Service-Type = Framed-User
Framed-Protocol = PPP
User-Name = “angel”
CHAP-Challenge = 0x33c4ad40b662648176b52f85b7b47c47030561884ce3
CHAP-Password = 0x679fa22be2a3a09c79e7ff5f047edb60ae
Calling-Station-Id = “192.168.2.68”
NAS-IP-Address = 127.0.1.1
NAS-Port = 0

# Executing section authorize from file /etc/freeradius/sites-enabled/default
+- entering group authorize {…}
++[preprocess] returns ok
[chap] Setting ‘Auth-Type := CHAP’
++[chap] returns ok
++[digest] returns noop
[suffix] No ‘@’ in User-Name = “angel”, looking up realm NULL
[suffix] No such realm “NULL”
++[suffix] returns noop
[eap] No EAP-Message, not doing EAP
++[eap] returns noop
[files] users: Matched entry DEFAULT at line 172
++[files] returns ok
[sql] expand: %{User-Name} -> angel
[sql] sql_set_user escaped user –> ‘angel’
rlm_sql (sql): Reserving sql socket id: 3
[sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = ‘%{SQL-User-Name}’ ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = ‘angel’ ORDER BY id
[sql] User found in radcheck table
[sql] expand: SELECT id, username, attribute, value, op FROM radreply WHERE username = ‘%{SQL-User-Name}’ ORDER BY id -> SELECT id, username, attribute, value, op FROM radreply WHERE username = ‘angel’ ORDER BY id
[sql] expand: SELECT groupname FROM radusergroup WHERE username = ‘%{SQL-User-Name}’ ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = ‘angel’ ORDER BY priority
rlm_sql (sql): Released sql socket id: 3
++[sql] returns ok
++[expiration] returns noop
++[logintime] returns noop
[pap] WARNING: Auth-Type already set. Not setting to PAP
++[pap] returns noop
Found Auth-Type = CHAP
# Executing group from file /etc/freeradius/sites-enabled/default
+- entering group CHAP {…}
[chap] login attempt by “angel” with CHAP password
[chap] Using clear text password “password_chulo” for user angel authentication.
[chap] chap user angel authenticated succesfully
++[chap] returns ok
# Executing section post-auth from file /etc/freeradius/sites-enabled/default
+- entering group post-auth {…}
[sql] expand: %{User-Name} -> angel
[sql] sql_set_user escaped user –> ‘angel’
[sql] expand: %{User-Password} ->
[sql] … expanding second conditional

[sql] expand: %{Chap-Password} -> 0x679fa22be2a3a09c79e7ff5f047edb60ae
[sql] expand: INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( ‘%{User-Name}’, ‘%{%{User-Password}:-%{Chap-Password}}’, ‘%{reply:Packet-Type}’, ‘%S’) -> INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( ‘angel’, ‘0x679fa22be2a3a09c79e7ff5f047edb60ae’, ‘Access-Accept’, ‘2012-10-08 00:54:23’)
rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( ‘angel’, ‘0x679fa22be2a3a09c79e7ff5f047edb60ae’, ‘Access-Accept’, ‘2012-10-08 00:54:23’)
rlm_sql (sql): Reserving sql socket id: 2
rlm_sql (sql): Released sql socket id: 2
++[sql] returns ok
[sql_log] Processing sql_log_postauth
[sql_log] expand: %{User-Name} -> angel
[sql_log] expand: %{%{User-Name}:-DEFAULT} -> angel
[sql_log] sql_set_user escaped user –> ‘angel’
[sql_log] WARNING: Deprecated conditional expansion “:-“. See “man unlang” for details
[sql_log] … expanding second conditional
[sql_log] expand: Chap-Password -> Chap-Password
[sql_log] expand: INSERT INTO radpostauth (username, pass, reply, authdate) VALUES (‘%{User-Name}’, ‘%{User-Password:-Chap-Password}’, ‘%{reply:Packet-Type}’, ‘%S’); -> INSERT INTO radpostauth (username, pass, reply, authdate) VALUES (‘angel’, ‘Chap-Password’, ‘Access-Accept’, ‘2012-10-08 00:54:23’);
[sql_log] expand: /var/log/freeradius/radacct/sql-relay -> /var/log/freeradius/radacct/sql-relay
++[sql_log] returns ok
++[exec] returns noop
Sending Access-Accept of id 45 to 127.0.0.1 port 33461
Framed-Protocol = PPP
Framed-Compression = Van-Jacobson-TCP-IP

Finished request 0.
Going to the next request
Waking up in 4.9 seconds.
Invalid packet code 4 sent to authentication port from client port 51954 : IGNORED
Waking up in 4.9 seconds.
Cleaning up request 0 ID 45 with timestamp +8
Ready to process requests.
Invalid packet code 4 sent to authentication port from client port 51954 : IGNORED
Ready to process requests.

Enjoy your server 😉

Freeradius + mysql en debian squeeze

Hoy toca instalar un freeradius en un cliente, para authenticar los accesos de unos hotspots Mikrotik.

Para la parte gráfica, usaremos el DaloRadius… de esta manera, no tendremos que andar con los ficheros de texto.

Suponemos que tenemos instalado ya nuestro Debian Squeeze y, vamos a instalar unos paquetes:


# aptitude install mysql-server php5 php5-mysql php5-gd php-pear php-db freeradius freeradius-mysql subversion

Creamos usuario para mysql y la bbdd para radius:


# mysql -u root -ppassword
mysql> GRANT ALL PRIVILEGES ON *.* TO 'radius'@'%' IDENTIFIED BY 'radius' WITH GRANT OPTION;
FLUSH PRIVILEGES;
mysql> create database radius;

Ahora bajamos el DaloRadius, en la carpeta /usr/src:


# cd /usr/src
# svn co https://daloradius.svn.sourceforge.net/svnroot/daloradius/trunk daloradius

Ahora movemos los directorios:


# cp daloradius/ /var/www -R
# chown www-data:www-data /var/www/daloradius -R
# chmod 644 /var/www/daloradius/library/daloradius.conf.php

Creamos la estructura de la BBDD de radius:


root@radius:/var/www/daloradius/contrib/db# mysql -u radius -pradius radius < fr2-mysql-daloradius-and-freeradius.sql

Editamos el fichero de configuración de daloRadius, para que se conecte a mysql:


# nano /var/www/daloradius/library/daloradius.conf.php

$configValues['CONFIG_DB_ENGINE'] = 'mysql';
$configValues['CONFIG_DB_HOST'] = 'localhost';
$configValues['CONFIG_DB_PORT'] = '3306';
$configValues['CONFIG_DB_USER'] = 'radius';
$configValues['CONFIG_DB_PASS'] = 'radius';
$configValues['CONFIG_DB_NAME'] = 'radius';

Ahora vamos modificando los ficheros de freeradius, para que se conecte a mysql.

En el directorio /etc/freeradius, editamos sql.conf y lo dejamos tal que:


sql {
#
# Set the database to one of:
#
# mysql, mssql, oracle, postgresql
#
database = "mysql"

#
# Which FreeRADIUS driver to use.
#
driver = "rlm_sql_${database}"

# Connection info:
server = "localhost"
#port = 3306
login = "radius"
password = "radius"

El siguiente paso, es que las consultas de usuarios, en vez de mirar en los ficheros locales, haga las consultas en las tablas de mysql. Para ello, modificaremos el fichero:


root@radius:/etc/freeradius/sites-enabled# nano default

Y modificamos:

### authorization Section
#
# Look in an SQL database. The schema of the database
# is meant to mirror the "users" file.
#
# See "Authorization Queries" in sql.conf
sql

### accounting section
#
# Log traffic to an SQL database.
#
# See "Accounting queries" in sql.conf
sql

Y en el fichero /etc/freeradius/radiusd.conf, habilitamos la parte de sql:


# Include another file that has the SQL-related configuration.
# This is another file only because it tends to be big.
#
$INCLUDE sql.conf

Por último, modificamos el fichero clients.conf, con el NAS localhost y una pass para probar .... (nas := network access server 😉 ) y lo dejamos tal que:


# -*- text -*-
##
## clients.conf -- client configuration directives
##
## $Id$

#######################################################################
#
# Define RADIUS clients (usually a NAS, Access Point, etc.).

client localhost {
ipaddr = 127.0.0.1
secret = testing123
nastype = other # localhost isn't usually a NAS...
}

Creamos ahora, desde la interfaz daloRadius, un usuario, para ello, accedemos al daloradius wía web:

http://ip.del.servidor.radius/daloradius

Y nos aparecerá algo tal que:

Usuario: administrator
pass: radius

En el apartado Management / Users , hacemos click en New User

Creamos un usuario, con su password y lo probaremos en la consola.

Paramos el servicio freeradius


# /etc/init.d/freeradius stop

Lanzamos el servicio en modo debug:


# freeradius -X

............
Module: Checking session {...} for more modules to load
Module: Checking post-proxy {...} for more modules to load
Module: Checking post-auth {...} for more modules to load
} # modules
} # server
radiusd: #### Opening IP addresses and Ports ####
listen {
type = "auth"
ipaddr = *
port = 0
}
listen {
type = "acct"
ipaddr = *
port = 0
}
listen {
type = "auth"
ipaddr = 127.0.0.1
port = 18120
}
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.

Y ahora desde otra consola, hacemos una prueba con la utilidad radtest :


root@radius:~# radtest pruebas pruebas01 localhost:1812 0 testing123
Sending Access-Request of id 49 to 127.0.0.1 port 1812
User-Name = "pruebas"
User-Password = "pruebas01"
NAS-IP-Address = 127.0.1.1
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=49, length=20
root@radius:~#

Nuestros datos:

Username: pruebas
pass:pruebas01
NasKey:testing123 (lo hemos puesto en el apartado nas, anteriormente, en localhost
Puerto Radius: 1812

Y el freeradius, nos responde con:


Ready to process requests.
rad_recv: Access-Request packet from host 127.0.0.1 port 37927, id=49, length=59
User-Name = "process"
User-Password = "control10"
NAS-IP-Address = 127.0.1.1
NAS-Port = 0
# Executing section authorize from file /etc/freeradius/sites-enabled/default
+- entering group authorize {...}
++[preprocess] returns ok
++[chap] returns noop
++[mschap] returns noop
++[digest] returns noop
[suffix] No '@' in User-Name = "pruebas", looking up realm NULL
[suffix] No such realm "NULL"
++[suffix] returns noop
[eap] No EAP-Message, not doing EAP
++[eap] returns noop
++[files] returns noop
[sql] expand: %{User-Name} -> pruebas
[sql] sql_set_user escaped user --> 'pruebas'
rlm_sql (sql): Reserving sql socket id: 4
[sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'pruebas' ORDER BY id
[sql] User found in radcheck table
[sql] expand: SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radreply WHERE username = 'pruebas' ORDER BY id
[sql] expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = 'pruebas' ORDER BY priority
rlm_sql (sql): Released sql socket id: 4
++[sql] returns ok
++[expiration] returns noop
++[logintime] returns noop
++[pap] returns updated
Found Auth-Type = PAP
# Executing group from file /etc/freeradius/sites-enabled/default
+- entering group PAP {...}
[pap] login attempt with password "pruebas01"
[pap] Using clear text password "pruebas01"
[pap] User authenticated successfully
++[pap] returns ok
# Executing section post-auth from file /etc/freeradius/sites-enabled/default
+- entering group post-auth {...}
++[exec] returns noop
Sending Access-Accept of id 49 to 127.0.0.1 port 37927
Finished request 0.
Going to the next request
Waking up in 4.9 seconds.
Cleaning up request 0 ID 49 with timestamp +177
Ready to process requests.

Y vemos como hace la consulta en mysql.

Enjoy your radius 😉

Añadiendo seguridad con IPTABLES

Otra entrada que es un apunte.

Estos días, por cuestiones técnicas y de un proyecto donde estoy colaborando, he tenido que unir mi debian / asterisk a un grupo, mediante el software vpn TINC.

La instalación del tinc es sencilla y funciona muy bien, pero mi máquina es completamente accesible desde el otro extremo de la red. No es que no me fie, pero no suelo dejar mis equipos expuestos al exterior; manias personales.

Bien, tras analizar los puertos que debo dejar abiertos, me hice una lista:

– permitir tráfico SIP/UDP (5060 udp) – abierto
– permitir tráfico RTP VoIP (udp 10000 .. 20000) – abierto
– permitir openLdap (en local) – abierto
– permitir SSH en mi redLocal (TCP 22)
– permitir MySQL en mi redLocal (TCP 3306)
– permitir TINC (655 tcp /udp)
– permitir www (80 tcp)
– permitir dundi (4520 tcp/udp)
– permitir tftp (udp 69)
– permitir syslog (udp 514)
– permitir icmp echo-reply
– permitir icmp unracheable
– permitir icmp echo-request
– permitir icmp unracheable
– permitir SMB en red Local

Una vez tenemos las reglas, vaciamos las reglas ip tables :

# iptables -F
# iptables -X

Y ahora hacemos un copy&paste de las reglas en la consola, quedando tal que:

# permitimos tráfico de loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# permitimos tipos de icmp
iptables -A INPUT -i eth1 -p icmp –icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -i eth1 -p icmp –icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -i eth1 -p icmp –icmp-type echo-reply -j ACCEPT
iptables -A INPUT -i eth1 -p icmp –icmp-type echo-request -j ACCEPT
# permitimos icmp en interface PLN /tinc
iptables -A INPUT -i pln -p icmp –icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -i pln -p icmp –icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -i pln -p icmp –icmp-type echo-reply -j ACCEPT
iptables -A INPUT -i pln -p icmp –icmp-type echo-request -j ACCEPT
# reglas
#### reglas dundi ###
iptables -A INPUT -p udp -m udp –dport 4520 -j ACCEPT
iptables -A INPUT -p tcp –dport 4520 -j ACCEPT
# reglas sip, iax, rtp #
iptables -A INPUT -p udp -m udp –dport 5060 -j ACCEPT
iptables -A INPUT -p udp -m udp –dport 4569 -j ACCEPT
iptables -A INPUT -p udp -m udp –dport 10000:20000 -j ACCEPT
# reglas syslog #
iptables -A INPUT -p udp -m udp –dport 514 -j ACCEPT
# reglas tftp #
iptables -A INPUT -p udp -m udp –dport 69 -j ACCEPT
# reglas tinc #
iptables -A INPUT -p udp -m udp –dport 655 -j ACCEPT
iptables -A INPUT -p tcp –dport 655 -j ACCEPT
# reglas trafico www #
iptables -A INPUT -p tcp –dport 80 -j ACCEPT
# reglas ssh #
iptables -A INPUT -p tcp –dport 22 -s 192.168.2.0/24 -j ACCEPT
iptables -A INPUT -p tcp –dport 22 -s 127.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp –dport 22 -j DROP
# reglas mysql
iptables -A INPUT -p tcp –dport 3306 -s 192.168.2.0/24 -j ACCEPT
# reglas ldap
iptables -A INPUT -p tcp –dport 389 -s 192.168.2.0/24 -j ACCEPT
# reglas SMB
iptables -A INPUT -p udp –dport 137 -s 192.168.2.0/24 -j ACCEPT
iptables -A INPUT -p udp –dport 138 -s 192.168.2.0/24 -j ACCEPT
iptables -A INPUT -p tcp –dport 139 -s 192.168.2.0/24 -j ACCEPT
iptables -A INPUT -p tcp –dport 445 -s 192.168.2.0/24 -j ACCEPT
iptables -A INPUT -p udp –dport 445 -s 192.168.2.0/24 -j ACCEPT
# el resto, rechazamos
iptables -A INPUT -j REJECT

Y con esto, añadimos un granito más de seguridad en nuestra red.

Habilitar / Deshabilitar notificaciones del nagios

Otra entrada que es un apunte.

Ya tengo varios nagios corriendo en clientes y en alguna ocasión (cuando cae todo), es mejor deshabilitar las notificaciones….. ya sabemos que está todo caído y que se queden en cola no es lo óptimo.

Para ello, en un pc con el curl instalado (apt-get install curl), copy&pasteamos los siguientes comandos:

Para deshabilitar:

curl -d “cmd_mod=2&cmd_typ=11” “http://ip.srv.nagios/cgi-bin/nagios/cmd.cgi” -u “user:password”

Para volverlas a habilitar:

curl -d “cmd_mod=2&cmd_typ=12” “http://ip.srv.nagios/cgi-bin/nagios/cmd.cgi” -u “user:password”

Enjoy 🙂

OpenMeetings 2.0 debian Squeeze + asterisk. Parte 1

Hoy toca la integración de OpenMeetings con Asterisk…. un gran paso. Primero instalaremos OpenMeetings 2.0 en nuestro debian y luego, lo integraremos con Asterisk.

Álvaro (aka Greenes), colaborador habitual del proyecto (http://incubator.apache.org/openmeetings/) es el responsable del manual original, del que yo, símplemente he “copiado” aquí, en mi blog.

Partimos de la base de nuestro debian recién instalado, nos vamos al fichero /etc/apt/sources.list y añadimos al principio:

deb http://security.debian.org/ squeeze/updates main contrib non-free
deb-src http://security.debian.org/ squeeze/updates main contrib non-free
deb http://ftp.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.debian.org/debian/ squeeze main contrib non-free
deb http://ftp.debian.org/debian/ squeeze-updates main contrib non-free
deb-src http://ftp.debian.org/debian/ squeeze-updates main contrib non-free
deb http://ftp2.de.debian.org/debian squeeze main non-free
deb http://deb-multimedia.org squeeze main

Hacemos un update:

#apt-get update

Y pasado un rato, estaremos en disposición de empezar a instalar dependencias, siendo :

apt-get install sun-java6-jdk
apt-get install openoffice.org-writer openoffice.org-calc openoffice.org-impress
openoffice.org-draw openoffice.org-math imagemagick gs-gpl -y
apt-get install libgif-dev xpdf libfreetype6 libfreetype6-dev libjpeg8 libjpeg62 libjpeg8-dev
apt-get install g++ libjpeg-dev libdirectfb-dev libart-2.0-2 libt1-5 zip unzip bzip2
apt-get install subversion git-core checkinstall yasm texi2html libfaac-dev libfaad-dev
apt-get install libmp3lame-dev libsdl1.2-dev libx11-dev libxfixes-dev libxvidcore4-dev zlib1g-dev
apt-get install libogg-dev sox libvorbis0a libvorbis-dev libgsm1 libgsm1-dev libfaad2 flvtool2 lame

al hacer el apt-get install sun-java6-jdk, tenemos que aceptar la licencia….. Googleando un poco en la página del proyecto, en versiones anteriores a la 2.0, funcionaba con la openJDK, pero ahora no, en fin.

Instalararemos el mysql-server + mysql-client y crearemos una BBDD para openmeetings, o usaremos otro MySQL que tengamos instalado en otro server. Entramos en el MySql en cuestión y creamos la BBDD y un usuario para tal caso, siendo openmeetings / openmeetings.

CREATE DATABASE openmeetings DEFAULT CHARACTER SET ‘utf8’;
GRANT ALL PRIVILEGES ON openmeetings.* TO ‘openmeetings’@’localhost’ IDENTIFIED BY ‘openmeetings’ WITH GRANT OPTION;

Ahora descargamos y compilamos el SWF:

wget http://www.swftools.org/swftools-2012-04-08-0857.tar.gz
tar -zxvf swftools-2012-04-08-0857.tar.gz
cd swftools-2012-04-08-0857
./configure
make
make install

Ahora toca el paquete ffmpeg:

wget http://ffmpeg.org/releases/ffmpeg-0.11.1.tar.gz
tar -zxvf ffmpeg-0.11.1.tar.gz
cd ffmpeg-0.11.1
./configure –enable-libmp3lame –enable-libxvid –enable-libvorbis –enable-libgsm –enable-libfaac –enable-gpl –enable-nonfree
make
checkinstall

Ahora seguimos con el JOD converter:

wget http://jodconverter.googlecode.com/files/jodconverter-core-3.0-beta-4-dist.zip
unzip jodconverter-core-3.0-beta-4-dist.zip

Y seguimos con ANT, pero usaremos la versión 1.8.4 para compilar openMeetings

wget http://mirror.catn.com/pub/apache//ant/binaries/apache-ant-1.8.4-bin.tar.gz
tar -zxvf apache-ant-1.8.4-bin.tar.gz

Y ahora descargamos openmeetings:

# svn checkout http://svn.apache.org/repos/asf/incubator/openmeetings/branches/2.0/

Y lo compilamos:

# cd /usr/adm/2.0
# /usr/adm/apache-ant-1.8.4/bin/ant clean.all
# /usr/adm/apache-ant-1.8.4/bin/ant -Ddb=mysql

Una vez compilado (tardará un buen rato), lo movemos a su ubicación correcta:

# cd /usr/adm/2.0/dist
# mv red5/ /usr/lib/

Movemos de sitio el JOD converter, a la carpeta de OM

cp -R /usr/adm/jodconverter-core-3.0-beta-4 /usr/lib/red5/webapps/openmeetings

Y cambiamos unos permisos:

# chown -R nobody /usr/lib/red5
# chmod +x /usr/lib/red5/red5.sh
# chmod +x /usr/lib/red5/red5-debug.sh

Y creamos el script para controlar red5:

# nano /etc/init.d/red5

Y hacemos copy & paste de lo siguiente…. (Gracias a Álvaro por modificar el script)

#! /bin/sh
### BEGIN INIT INFO
# Provides: red5
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts red5 server for Openmeetings.
# OpenMeetings 2.X Installation on Debian 64bit Squeeze
# Stephen Cottham 29/07/2012
### END INIT INFO
# For RedHat and cousins:
# chkconfig: 2345 85 85
# description: Red5 flash streaming server for OpenMeetings
# processname: red5
# Created By: Sohail Riaz (sohaileo@gmail.com)
# Modified by Alvaro Bustos
PROG=red5
RED5_HOME=/usr/lib/red5
DAEMON=$RED5_HOME/$PROG.sh
PIDFILE=/var/run/$PROG.pid
[ -r /etc/sysconfig/red5 ] && . /etc/sysconfig/red5
RETVAL=0
case “$1” in
start)
cd $RED5_HOME
start-stop-daemon –start -c nobody –pidfile $PIDFILE
–chdir $RED5_HOME –background –make-pidfile
–exec $DAEMON >/dev/null 2>/dev/null &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo $! > $PIDFILE
fi
echo
;;
stop)
start-stop-daemon –stop –quiet –pidfile $PIDFILE
–name java
rm -f $PIDFILE
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$PROG
;;
restart|force-reload)
$0 stop
$0 start
;;
status)
# Debian and Ubuntu 10 status check
ps aux | grep -f $PIDFILE >/dev/null 2>/dev/null && RETVAL=0 || RETVAL=3
# Ubuntu 12 status check using improved “start-stop-daemon” status query
# (use the above command, or comment out above command and uncomment the two below commands.
# start-stop-daemon –status –pidfile $PIDFILE
# RETVAL=$?
[ $RETVAL -eq 0 ] && echo “$PROG is running”
[ $RETVAL -eq 1 ] && echo “$PROG is not running and the pid file exists”
[ $RETVAL -eq 3 ] && echo “$PROG is not running”
[ $RETVAL -eq 4 ] && echo “$PROG – unable to determine status”
;;
checkports)
netstat -anp | grep soffice
netstat -anp | grep java
;;
*)
echo $”Usage: $0 {start|stop|restart|force-reload|status|checkports}”
RETVAL=1
esac
exit $RETVAL

Seteamos permisos para que pueda ejecutarse:

chmod +x /etc/init.d/red5
update-rc.d red5 defaults

Hacemos backup del fichero persistence.xml, por si las moscas:

mv /usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/persistence.xml
/usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/persistence.xml-ori

Y ahora renombramos para habilitar el template de mysql:

# mv /usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/mysql_persistence.xml
/usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/persistence.xml

#mv /usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/mysql_persistence.xml
/usr/lib/red5/webapps/openmeetings/WEB-INF/classes/META-INF/persistence.xml

Ahora editamos el fichero y cambiamos los datos de acceso mysql

, TestOnBorrow=true
, poolPreparedStatements=true
, Username=openmeetings
, Password=openmeetings”/>

Y iniciamos red5

# /etc/init.d/red5 start

Y si todo ha ido bien, empezaremos a configurarlo, accediendo a la web:

http://ip.del.web.server:5080/openmeetings/install

Rellenamos el user / pass:

Username: admin
Userpass: password
EMail: admin@dominio.com
User Time Zone: spain
Organisation(Domains) craem.net

Y al final de la hoja, le damos al botón de install. Esperamos un poco y ya tenemos la primera parte lista.

Instalando nagios 3 en Debian 6

Otro apunte, para instalar nagios3 en una Debian.

Primero, instalamos unas dependencias básicas:


#aptitude install build-essential gcc libgd2-xpm-dev libglib2.0-dev apache2

Creeamos usuario y grupo:


# /usr/sbin/useradd nagios
# passwd nagios
# /usr/sbin/groupadd nagcmd
#/usr/sbin/usermod -G nagcmd nagios
# /usr/sbin/usermod -G nagcmd www-data

Ahora instalamos unas dependencias básicas:


root@nagios:~# apt-get install apache2 mc libapache2-mod-php5 php5-cli php5-common php5-cgi php5-gd
root@nagios:~# aptitude install build-essential gcc libgd2-xpm-dev libglib2.0-dev apache2
root@nagios:~# apt-get install php5-cli php5-common php5-gd
root@nagios:~# apt-get install libjpeg62 libjpeg62-dev libpng12-0 libpng12-dev
root@nagios:~# apt-get install php5-cli php5-common php5-gd php-pear
root@nagios:~# apt-get install ssh apache2 libapache2-mod-php5 php5-cli php5-common php5-cgi php5-gd -qy bison flex libncurses5-dev zlib1g-dev libssl-dev libnewt-dev libiksemel-dev -qy make linux-headers-`uname -r` gcc g++ libstdc++6 mysql-client mysql-server phpmyadmin linux-headers-`uname -r` bison openssl libssl-dev libeditline0 libeditline-dev libedit-dev gcc make g++ php5-cli mysql-common libmysqlclient15-dev libnewt-dev libmysqlclient15-dev libnewt-dev

Y reiniciamos apache2:


root@nagios:~# /etc/init.d/apache2 restart

Y seguimos añadiendo usuarios y grupos :


root@nagios:~# /usr/sbin/useradd nagios
root@nagios:~# passwd nagios
root@nagios:~# /usr/sbin/groupadd nagcmd
root@nagios:~# /usr/sbin/usermod -G nagcmd nagios
root@nagios:~# /usr/sbin/usermod -G nagcmd www-data

Ahora descargamos el nagios en /usr/src y creamos un directorio para ello y lo descomprimimos:


root@nagios:~# cd /usr/src/
root@nagios:~# mkdir nagios
root@nagios:~# cd nagios/
root@nagios:~# wget -c http://sourceforge.net/projects/nagios/files/nagios-3.x/nagios-3.4.1/nagios-3.4.1.tar.gz/download
root@nagios:~# tar -zxvf nagios-3.4.1.tar.gz
root@nagios:~# wget -c http://sourceforge.net/projects/nagiosplug/files/nagiosplug/1.4.15/nagios-plugins-1.4.15.tar.gz/download
root@nagios:~# tar -zxvf nagios-plugins-1.4.15.tar.gz

Y ahora a compilar:


root@nagios:/usr/src/nagios# ./configure --with-command-group=nagcmd
root@nagios:/usr/src/nagios# make all
root@nagios:/usr/src/nagios# make install
root@nagios:/usr/src/nagios# make install-init
root@nagios:/usr/src/nagios# make install-config
root@nagios:/usr/src/nagios# make install-commandmode
root@nagios:/usr/src/nagios# make install-webconf

Creamos el usuario para el acceso web:


root@nagios:/usr/src/nagios# htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin

Y ahora toca el nagios-plugins


root@nagios:/usr/src/nagios# cd nagios-plugins-1.4.15/
root@nagios:/usr/src/nagios/nagios-plugins-1.4.15# ./configure --with-nagios-user=nagios --with-nagios-group=nagcmd
root@nagios:/usr/src/nagios# make
root@nagios:/usr/src/nagios# make install

Ahora instalamos la parte para que envíe las notificaciones:


root@nagios:/usr/local/nagios/share# apt-get remove exim4 exim4-config
root@nagios:/usr/local/nagios/share# apt-get install postfix postfix-doc

Y configuramos el main.cf de postfix, tal que:


myhostname = nagios.dominio.local
mydomain = dominio.local
myorgin = $mydomain
masquerade_domain = $mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
mynetwork_style = host
##########################################################
mynetworks = 192.168.0.0/16
relay_domains = dominio.local
transport_maps = hash:/etc/postfix/transport

bounce_notice_recipient = email@dominio.com
delay_notice_recipient = email@dominio.com
2bounce_notice_recipient = email@dominio.com
error_notice_recipient = email@dominio.com
default_destination_concurrency_limit = 10
smtpd_recipient_limit = 100
maximal_queue_lifetime = 1d
fallback_relay =
smtp_destination_recipient_limit = 200
smtp_destination_concurrency_limit = 10
message_size_limit = 5240000
append_at_myorigin = yes
append_dot_mydomain = no
swap_bangpath = no

Y reiniciamos postfix:


root@nagios:/etc/postfix# /etc/init.d/postfix restart
Stopping Postfix Mail Transport Agent: postfix.
Starting Postfix Mail Transport Agent: postfix.
root@nagios:/etc/postfix#

Y ahora toca configurar plugins y resto de cosillas.

Enjoy your nagios 🙂

Forzar spa50x cambios por tftp

Otro apunte…. estos días ando liado cambiando configuraciones en los teléfonos de un cliente y, necesito forzar que el teléfono (en mi caso, un spa502g), se descargue de nuevo el fichero del TFTP para aplicar los cambios y verlo de nuevo registrado en mi asterisk, con las modificaciones.

Tengo los ficheros en el tftp de mi servidor debian, siendo la ruta tftp://spa$fichero_config.xml.

Abrimos el navegador y tecleamos como url:

http://10.0.1.71/admin/resync?tftp://10.0.1.5/spa$MA.xml

10.0.1.71 : Ip del teléfono
10.0.1.5 : Ip del tftp / asterisk
spa$MA.xml: el fichero de configuración que hayamos creado, que está basado en la cadena spa + la mac address del dispositivo y con la extensión XML

Y a seguir configurando 😉