Apartamento En Familia

Apartamento En Familia
Apartamento de playa para vacaciones. http://www.apartamentoenfamilia.es. Número registro HUTT-005768

jueves, 28 de marzo de 2013

Como extender las posibilidades de UGO hacia ACL (Access Control List)



Una lista de control de acceso o ACL (del inglés, access control list) es un concepto de seguridad informática usado para fomentar la separación de privilegios. Es una forma de determinar los permisos de acceso apropiados a un determinado objeto, dependiendo de ciertos aspectos del proceso que hace el pedido.

(Fuente wikipedia)





¿Para que las necesitamos?

En algunas ocasiones nos podemos plantear a la hora de dar permisos a grupos o archivos de como crear un grupo de grupos. Algo parecido como los grupos anidados de samba (nested groups). Por ejemplo, imaginemos esta situación:

Profesores de primer grado: usuario1, usuario2, usuario3
Profesores de segundo grado: usuario4, usuario5
Alumnos: usuario6, usuario7, usuario8, usuario9
Dirección: usuario10

Es posible que queramos crear un grupo (por ejemplo que llamaremos Escuela) en el cual todos los otros grupos estén incluidos. Por ejemplo:


Profesores: @Profesores de primer grado, @Profesores de segundo grado
Escuela: @Profesores, @Alumnos, @Dirección


Esto por defecto no lo podríamos hacer con nuestro sistema de ficheros ext4 tal como viene por defecto.

Así pues, lo que querremos explicar en este artículo como extender los habituales controles de acceso a los ficheros mediante acl.

Instalación

Lo haremos o bien por el gestor de paquetes visual o por linea de comandos:



apt-get install acl

Ahora tendremos que incluir una opción extra en el /etc/fstab para que cuando monte nuestro disco duro tenga en cuenta las acl:

por ejemplo:
UUID=2ed78188-b7b5-411f-887b /punto/montaje      ext4    acl,errors=remount-ro 0        1

Remontamos el disco (por si no queremos reiniciar, que no es necesario)

sudo mount -o remount /punto/montaje


si queremos comprobar que lo hemos hecho correctamente:

mount | grep acl
 

/dev/sdb1 on /punto/montaje type ext4 (rw,acl,errors=remount-ro)

Planteando el problema

Pues bien, ahora ya tenemos nuestro sistema de archivos preparado para aplicar acl's en las carpetas y/o ficheros. Vemos algunos ejemplos de como conseguirlo:

Imaginemos que tenemos la siguiente estructura de carpetas:

/home/Escuela
/home/Escuela/Profesores
/home/Escuela/Profesores/1er_Grado
/home/Escuela/Profesores/2nd_Grado 
/home/Escuela/Alumnos
/home/Escuela/Dirección

Lo que queremos es que cada grupo de usuarios pueda leer/escribir únicamente en su carpeta y las carpetas superiores. Es decir, un profesor de 1er Grado deberia poder leer/escribir en

/home/Escuela/Profesores/1er_Grado
/home/Escuela/Profesores/
y
/home/Escuela

pero no debería poder acceder/escribir al resto de carpetas.
Para ello la estrategia será crear un grupo de usuarios para cada grupo final de nuestro árbol de usuarios. Es decir, crearemos estos grupos:

prof_1er (Profesores de primer grado)
prof_2nd
(Profesores de segundo grado)
alumnos
direccion



¡Empecemos a dar accesos!

Creamos los usuarios (usuario1 ... usuario10):

usuario1:x:1001:1001:,,,:/home/usuario1:/bin/bash
usuario2:x:1002:1002:,,,:/home/usuario2:/bin/bash
usuario3:x:1003:1003:,,,:/home/usuario3:/bin/bash
usuario4:x:1004:1004:,,,:/home/usuario4:/bin/bash
usuario5:x:1005:1005:,,,:/home/usuario5:/bin/bash
usuario6:x:1006:1006:,,,:/home/usuario6:/bin/bash
usuario7:x:1007:1007:,,,:/home/usuario7:/bin/bash
usuario8:x:1008:1008:,,,:/home/usuario8:/bin/bash
usuario9:x:1009:1009:,,,:/home/usuario9:/bin/bash
usuario10:x:1010:1010:,,,:/home/usuario10:/bin/bash


y metemos a cada usuario en su grupo:


prof_1er:x:1011:usuario1,usuario2,usuario3
prof_2nd:x:1012:usuario4,usuario5
alumnos:x:1013:usuario6,usuario7,usuario8,usuario9
direccion:x:1014:usuario10


Antes de nada vamos a ver como esta el directorio Escuela para familiarizarnos con las acl's:


getfacl Escuela/
# file: Escuela/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x


He usado el comando getfacl (get file access control lists) para obtener la información de acceso.

Ahora para dar acceso usaremos el comando setfacl (set file access control lists).


Miremos como esta la carpeta 1er_Grado:
getfacl /con_acl/Escuela/Profesores/1er_Grado

# file: con_acl/Escuela/Profesores/1er_Grado/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

Ahora apliquemos opciones de rwx al grupo prof_1er y saquemos los privegios al resto y veamos como queda: 

setfacl -m g:prof_1er:rwx /con_acl/Escuela/Profesores/1er_Grado/
setfacl -m o::--- /con_acl/Escuela/Profesores/1er_Grado/
getfacl /con_acl/Escuela/Profesores/1er_Gradogetf

# file: con_acl/Escuela/Profesores/1er_Grado/
# owner: root
# group: root
user::rwx
group::r-x
group:prof_1er:rwx
mask::rwx
other::---

Probemos a ver si un profesor de 2nd Grado puede acceder:

su usuario4
ls
1er_Grado  2nd_Grado
cd 1er_Grado/
bash: cd: 1er_Grado/: Permiso denegado


Como vemos, no podemos acceder a la carpeta, como esperábamos.

Ahora es ir asignado los permisos a los grupos en las carpetas según los comandos antes vistos para obtener un control mucho más flexible de accesos:

setfacl -R -m o::--- /con_acl/Escuela
setfacl -m g:prof_1er:rwx /con_acl/Escuela/Profesores/1er_Grado
setfacl -m g:prof_2nd:rwx /con_acl/Escuela/Profesores/2nd_Grado
setfacl -m g:prof_1er:rwx /con_acl/Escuela/Profesores
setfacl -m g:prof_2nd:rwx /con_acl/Escuela/Profesores
setfacl -m g:alumnos:rwx /con_acl/Escuela/Alumnos
setfacl -m g:direccion:rwx /con_acl/Escuela/Dirección

y finalmente:
setfacl -m g:prof_1er:rwx /con_acl/Escuela
setfacl -m g:prof_2nd:rwx /con_acl/Escuela
setfacl -m g:alumnos:rwx /con_acl/Escuela
setfacl -m g:direccion:rwx /con_acl/Escuela


Si ahora comprobamos los accesos de la raiz, veremos que diferentes grupos de usuarios tienen acceso:
getfacl Escuela
 

# file: Escuela
# owner: root
# group: root
user::rwx
group::r-x
group:prof_1er:rwx
group:prof_2nd:rwx
group:alumnos:rwx
group:direccion:rwx
mask::rwx
other::---


Con esto habríamos conseguido nuestro ejercicio inicial, dar a una carpeta acceso a diferentes grupos de usuarios.







jueves, 14 de marzo de 2013

Instalar Squid (proxy) en Ubuntu 12.10 (+OpenLDAP)

Squid es un popular programa de software libre que implementa un servidor proxy y un dominio para caché de páginas web, publicado bajo licencia GPL. Tiene una amplia variedad de utilidades, desde acelerar un servidor web, guardando en caché peticiones repetidas a DNS y otras búsquedas para un grupo de gente que comparte recursos de la red, hasta caché de web, además de añadir seguridad filtrando el tráfico. Está especialmente diseñado para ejecutarse bajo entornos tipo Unix.
Squid ha sido desarrollado durante muchos años y se le considera muy completo y robusto. Aunque orientado principalmente a HTTP y FTP es compatible con otros protocolos como Internet Gopher. Implementa varias modalidades de cifrado como TLS, SSL, y HTTPS.

(Fuente Wikipedia)

Instalación

La instalación de squid3 se puede hacer fácilmente desde el repositorio de Ubuntu. Para ello, como es habitual:

apt-get update
apt-get upgrade
apt-get install squid

squid es un paquete de transición (un enlace) a la última versión de squid. En el momento de redactar estas lineas era squid3.

Configuración 

La configuración de squid se encuentra en la carpeta /etc/squid3.

Los archivos que nos encontramos son:
  • errorpage.css: Hoja de estilos para las páginas que queremos mostrar los errores (de acceso a páginas no permitidas, etc)
  • msntauth.conf: Para autenticación MSNT.
  • squid.conf: El archivo de configuración general de squid.

Así pues, vamos a centrarnos en su archivo de configuración general. De todas maneras, posiblemente, sin tocar nada el equipo ya esté funcionando como proxy. Probadlo. En muchos casos la configuración por defecto ya es más que suficiente.

squid.conf

En este archivo, de inicio, encontraremos un 90% de comentarios y el resto de configuración. Esto va genial para poder entender que hace cada opción de squid, si bien, para configurarlo podemos querer tenerlo más 'limpio'. Para ello podemos limpiarlo siguiendo el artículo "Cómo crear un archivo de configuración limpio de comentarios" .

Una vez limpio de comentarios, os pongo un ejemplo y vamos comentando las diferentes opciones. No obstante, podréis encontrar la información más completa en http://www.squid-cache.org/Doc/config/:

auth_param

Este parámetro sirve para especificar la autenticación a nuestro proxy. En nuestro caso la autentificación la haremos contra un servidor OpenLDAP.

auth_param basic program /usr/lib/squid3/squid_ldap_auth -b "dc=dominio,dc=es" -f "uid=%s" servidor_ldap.dominio.es
auth_param basic realm Empresa Proxy Cache
auth_param basic credentialsttl 10 second
auth_param basic children 5

acl

Este parámetro sirve para definir las 'Access List', o listas de acceso. Siempre tiene la forma siguiente:
acl nombre_identificativo tipo_acl argument
Aquí no digo si deniego o accedo. Simplemente doy nombre a las cosas. A una parte de la red le puedo llamar, por ejemplo, Empresa_LAN y a otra parte de la red le llamo proxy_empresarial. Seria como inicializar unas variables que luego haré servir para dar o no acceso al proxy (o requerir contraseña, etc). También puedo definir puertos.

acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
acl Empresa_LAN src 192.168.1.0/24

acl proxy_empresarial src 192.168.22.0/24
acl password proxy_auth REQUIRED
acl SSL_ports port 443
acl Safe_ports port 80        # http
acl Safe_ports port 21        # ftp
acl Safe_ports port 443        # https
acl Safe_ports port 70        # gopher
acl Safe_ports port 210        # wais
acl Safe_ports port 1025-65535    # unregistered ports
acl Safe_ports port 280        # http-mgmt
acl Safe_ports port 488        # gss-http
acl Safe_ports port 591        # filemaker
acl Safe_ports port 777        # multiling http
acl CONNECT method CONNECT

acl local-servers dstdomain .potito.uk
acl local-servers2 dstdomain 141.69.0.0/16

http_access

Con las acl decía que identificaba puertos o segmentos de la red dándoles nombre pero que no permitia o denegaba acceso. Bien, con http_access si. Una vez tenemos una acl, con http_access decimos allow o deny para permitir o denegar respectivamente.

http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access allow Empresa_LAN
http_access allow proxy_empresarial
http_access allow password
http_access deny all


http_reply_access

Como complemento a http_access tenemos este parámetro. Nos sirve para dar acceso o no a las respuestas de servidor hacia los clientes.

http_reply_access allow all

icp_access

Basándonos también en las acl declaradas, aquí denegamos o permitimos acceso al ICP Port (Internet Cache Protocol)

icp_access allow proxy_empresarial
icp_access deny all

http_port

Es el puerto de escucha de nuestro servidor proxy. Por defecto escucha por el puerto 3128. Nosotros podemos mirar de cambiárselo para evitar ataques DoS, etc

http_port 4500

include

Esto no es un parámetro en si. Squid nos da la posibilidad de incluir otros archivos a nuestro archivo de configuración de manera que según que parámetros los tengamos separados del squid.conf general. A mi me resulta útil para separar conceptos y no hacer un squid.conf muy grande que dificulte su comprensión. Como mi lista de acl user src y tcp_outgoing (veremos que es este parámetro) era muy larga, he preferido crear unos archivos fuera del squid.conf e incluirlos mediante include.
 
include /etc/squid3/acl_user_src_IP.txt
include /etc/squid3/tcp_outgoing_address.txt

tcp_outgoing_address

Con este parámetro lo que haremos es mapear, asignar, una ip de salida a un usuario o ip origen. Es decir, imaginemos que tenemos 5 usuarios y queremos que cada usuario salga por nuestro proxy con una IP diferente (para ello hemos de disponer de esas IPs, claro está). Pues lo que haremos es primero definir mediante las acl a los usuarios. Por ejemplo:
acl usuari1 src 192.168.1.10
acl usuari2 src
192.168.1.12
acl usuari3 src 192.168.1.13

Esto como hemos visto antes en el 'include' lo tengo en un archivo llamado acl_user_src_IP.txt , pero perfectamente podria estar en el propio squid.conf. Bien, pues una vez hecha la acl (osea, identificado el usuario con su IP), le decimos mediante tcp_outgoing_address por que IP ha de salir:

tcp_outgoing_address 84.80.60.53 usuari1
tcp_outgoing_address 84.80.60.185 usuari2
tcp_outgoing_address 84.80.60.54 usuari3

Con esto lo que hemos hecho es que el usuario que en la red local tiene la IP 192.168.1.10, al salir por el proxy, éste hace que salga a Internet (o otra red) por la IP 84.80.60.53. Y lo mismo con los otros tres.

Yo lo que también hice es meter toda la configuración tcp_outgoing_address en otro archivo e incluirla con el include. Se podía haber dejado en el propio squid.conf.

always_direct

Este parámetro nos permitirá permitir o denegar conexiones directas a un destino sin usar caché. No significa que hagamos un bypass del proxy, sino que si hacemos una petición podemos hacer que haga una redirección directa, no cacheada. Para ello, usaremos una acl creada.

always_direct allow local-servers
always_direct allow local-servers2

cache_mem y cache_dir

cache_mem nos permite especificar la cantidad de memoria que puede dedicar a la cache (no al squid). cache_dir nos permite especificar donde y que sistema usar para los archivos de la cache. 
cache_mem 100 MB
cache_dir ufs /var/spool/squid3 100 16 256

refresh_pattern

Es para discernir si lo que hay en la cache ha expirado ya o no para según patrones (explicados mediante expresiones regulares regex). Los estados de un objeto en cache son FRESH o STALE (fresco o viciado).
 
refresh_pattern ^ftp:        1440    20%    10080
refresh_pattern ^gopher:    1440    0%    1440
refresh_pattern -i (/cgi-bin/|\?) 0    0%    0
refresh_pattern (Release|Packages(.gz)*)$      0       20%     2880
refresh_pattern .        0    20%    4320

read_timeout

Es el tiempo de espera que queremos para cuando una conexión que ha sido satisfactoria y no nos devuelve ningún tipo de datos.

read_timeout 400 minutes

visible_hostname

Nombre visible con el que queremos que se vea nuestro proxy.

visible_hostname proxy_empresa

forwarded_for

Esto es por si queremos que en las peticiones HTTP se incluya la IP del cliente. Las opciones son on o off. Sería del tipo X-Forwarded-For: IP-Cliente  si lo ponemos a on y X-Forwarded-For: unknown si lo ponemos a off.

forwarded_for off

header_access

Esta opcion viola los estandares de HTTP. Se suele usar para crear un proxy anónimo. Nosotros simplemente denegaremos los X-Forwarded-For ya que los desactivé en una opción anterior.
 
header_access Via deny all
header_access X-Forwarded-For deny all
Con estas opciones (o muchas menos si no tenéis una red muy compleja) podéis hacer funcionar un proxy fácilmente. 

Links de interés 

http://www.squid-cache.org/

miércoles, 6 de marzo de 2013

Instalar y crear volumenes LVM2 en Ubuntu 12.10

LVM es una implementación de un administrador de volúmenes lógicos para el kernel Linux. Se escribió originalmente en 1998 por Heinz Mauelshagen, que se basó en el administrador de volúmenes de Veritas usado en sistemas HP-UX.
LVM incluye muchas de las características que se esperan de un administrador de volúmenes, incluyendo:
  • Redimensionado de grupos lógicos
  • Redimensionado de volúmenes lógicos
  • Instantáneas de sólo lectura (LVM2 ofrece lectura y escritura)
  • RAID0 de volúmenes lógicos.
LVM no implementa RAID1 o RAID5, por lo que se recomienda usar software específico de RAID para estas operaciones, teniendo las LV por encima del RAID

(Fuente wikipedia)


Antes de todo tenemos que instalar el paquete necesario para tener las herramientas que nos permitan hacer lo que queremos.

sudo -s
apt-get install lvm2

Una vez instalado el lvm2, ya podemos empezar:

Inicializamos las particiones para usar LVM

root@server:/temp# pvcreate /dev/sdf1 /dev/sdg1
  Writing physical volume data to disk "/dev/sdf1"
  Physical volume "/dev/sdf1" successfully created
  Writing physical volume data to disk "/dev/sdg1"
  Physical volume "/dev/sdg1" successfully created


Creamos un grupo de volumenes para agrupar los discos:

root@server:/root/Respaldo# vgcreate MiGrupo /dev/sdf1 /dev/sdg1
  Volume group "MiGrupo" successfully created





Ahora tenemos que crear el volumen lógico. Para ello tendremos que especificar el tamaño del que deseamos que dicho volumen. Claro.. uno puede pensar.. vale.. si un disco es de 1 y el otro es de 2, el tamaño es de 3. Fácil. Pero como sabreis, muchas veces los discos no son exactamente lo que ponen.. y aqui tenemos que ser un poco más exactos que esta cuenta de la abuela. 

Así pues, tenemos dos opciones

  • Usamos el comando vgdisplay para ver que tenemos:

 vgdisplay
  --- Volume group ---
  VG Name               MiGrupo
  System ID            
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               2,70 TiB
  PE Size               4,00 MiB
  Total PE              707787
  Alloc PE / Size       0 / 0  
  Free  PE / Size       707787 / 2,70 TiB
  VG UUID               M2DPLa-0ayj-KzHM-EhIJ-EK8B-4f3l-sBAchO


  • Le decimos que use el 100% del espacio libre:
root@server:/temp# lvcreate --name miVol -l 100%FREE MiGrupo
  Logical volume "miVol" created


Bien! pues ya tenemos nuestro volumen creado. Ahora sólo queda crear el sistema de archivos (en el ejemplo usaré el btrfs, pero podemos usar ext4, ext3, etc):

root@server:/tempo# mkfs.btrfs /dev/MiGrupo/miVol

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

fs created label (null) on /dev/MiGrupo/miVol
    nodesize 4096 leafsize 4096 sectorsize 4096 size 2.70TB
Btrfs Btrfs v0.19



Ahora ya lo podemos montar donde queramos:

mount /dev/MiGrupo/miVol /home/miuser/mivol

y cuando hagamos df lo veremos allá:

/dev/mapper/MiGrupo-miVol  2,7T   56K  2,7T   1% /home/miuser/mivol


Si luego queremos borrar dicho volumen, lo desmontamos y luego hacemos:

lvremove /dev/MiGrupo/miVol
Do you really want to remove active logical volume miVol? [y/n]: y
  Logical volume "miVol" successfully removed


 Si además queremos borrar el grupo de volumenes:

vgremove MiGrupo
  Volume group "MiGrupo" successfully removed









martes, 5 de marzo de 2013

Cambiar la fecha ctime atime o mtime de un archivo


El programa DebugFS es un depurador interactivo del sistema de nuestro sistema de archivos. Se puede utilizar para examinar y cambiar el estado de un sistema de archivos en ext2, ext3 o ext4. Cuando digo cambiar, quiero decir que podemos incluso recuperar un archivo borrado.

Hoy voy a explicar como hacer algo más sencillo como es cambiar la fecha de modificación del estado del archivo (ctime). 

Para ello entendamos un poco que son las diferentes marcas de tiempo:

ctime: 'change time' indica el tiempo de la última modificación que se realizó al archivo en términos de su inodo (inode). Es decir, cambios en los permisos, propietario, etc. También, lo utiliza el comando dump para determinar el último respaldo que se realizó al archivo. Es posible ver este tiempo con la opción c del comando ls. Ejemplo ls -lc

atime: 'access time' indica el tiempo en que el archivo fue por última accedido para mostrar su contenido. Por ejemplo cuando se usan los comandos cat, more, less o un script, en que se despliega el contenido del archivo se modificará su atime. Es posible ver este tiempo con la opción u del comando ls. Ejemplo ls -lu

mtime: 'modify time' indica el tiempo en que el contenido del archivo fue por última vez mofificado o editado, por ejemplo cuando usas un editor de texto o se altera por un script, etc. Con la opción l del comando ls se muestra este tiempo, que entonces, es el que estamos acostumbrados a observar con el listado típico: ls -l 
(Fuente LinuxTotal)
 
En alguna ocasión podemos necesitar cambiar la fecha de modificación de los datos del archivo o bien la fecha en la que se actualizó el estado de cambios del archivo.

Imaginemos que creamos un archivo a dia 4 de Marzo:

touch /home/user1/temp/hora_hacktime.txt

ediaz@pcediaz:~/temp$ ls -lath
total 16K
drwxrwxr-x  2 ediaz ediaz 4,0K mar  4 16:55 .
-rw-rw-r--  1 ediaz ediaz    0 mar  4 16:55 hora_hacktime.txt
drwxr-xr-x 92 ediaz ediaz  12K mar  4 16:55 ..


Como vemos, la hora ctime corresponde lógicamente con la mtime. Ahora modifiquemos la hora ctime. Para ello usaremos el comando debugfs. Tiene muchísimas posibilidades este comando, pero nos centraremos en las opciones -w y -R:

-w: El sistema de archivos tiene que ser abierto de lectura-escritura
-R: Lanzamos un comando de debugfs sin ejecutarlo en modo interactivo.

En nuestro caso el comando de debugfs que lanzamos será set_inode_field:
set_inode_field filespec field value

en donde filespec el archivo en cuestión, field en nuestro caso sera ctime y value es el valor datetime que queremos darle. Vamos a probarlo:


sudo debugfs -w -R 'set_inode_field /home/user1/temp/hora_hacktime.txt ctime 200901010101' /dev/sda1

Como veis, al final de todo especifico el sistema de archivos en donde esta el archivo que quiero modificar. En mi caso era /dev/sda1.

¿Y ya esta?. Realmente si. Lo que pasa es que si lo miramos, puede ser que no veamos el cambio aplicado. Como no es algo que haya realizado el sistema, puede ser que necesitemos usar el comando sync para hacer una limpieza (flush) del sistema de buffer:

sudo -s
sync
echo 2 > /proc/sys/vm/drop_caches



Ahora miramos la fecha ctime:

root@maquina:~/temp# ls -lathc
total 16K
drwxrwxr-x  2 ediaz ediaz 4,0K mar  4 16:55 .
drwxr-xr-x 92 ediaz ediaz  12K mar  4 16:55 ..
-rw-rw-r--  1 ediaz ediaz    0 ene  1  2009 hora_hacktime.txt

Y ya lo tenemos modificado.

That u don't know what you've got 'til it's gone