martes, 27 de noviembre de 2012

Establecer tiempo de sesión en django

Para controlar el tiempo de sesión en django, podemos hacer uso de las siguentes directivas dentro de nuestro settings.py:

#Tiempo de vida de la sesión en segundos
SESSION_COOKIE_AGE = 600


#Para que expire la sesión al cerrar el navegador. Por defecto está a False

SESSION_EXPIRE_AT_BROWSER_CLOSE = True

También es importante si tenemos varios proyectos publicados en el mismo apache, añadir la siguiente directiva:

SESSION_COOKIE_NAME = 'cadena_distintiva'

donde 'cadena_distintiva' deberá ser diferente, para que cada proyecto tenga una cookie diferente y no entre en conflicto con las de otros.

Limpiar django_sessions

Ocurre que la tabla de django "django_session" suele crecer de forma desmesurada, debido a que django por sí sólo no limpia las sesiones expiradas (en gran parte porque al salir no lo hacemos con logout).

Para evitar que crezca esta tabla, django nos ofrece el siguiente comando:

cleanup


el cual limpia de la bbdd aquellas entradas de sesiones ya expiradas.


Lo ideal por tanto, es añadir en el cron una entrada como esta:

0 8 * * * /usr/bin/python /ruta/proyecto/manage.py cleanup

Para que periódicamente (a las 8 de la mañana por ejemplo) limpie las sesiones caducadas de nuestro proyecto django.

miércoles, 21 de noviembre de 2012

Montar un repositorio con Git

Ayer me entró la curiosidad sobre cómo utilizar el gestor de control de versiones git. Ya tengo montado mi repositorio en una máquina remota y configurado para realizar los cambios desde mi equipo para luego subirlos a producción. Os comento cómo hacer esto.

Escenario:

- Servidor de producción [SERVIDOR]. En este servidor tenemos corriendo una aplicación en django (en la ruta /opt/proyecto/aplicacionA). Aquí también motaremos nuestro repositorio remoto. Tendremos que tener git instalado (desde paquetería o compilando).

- Equipo local [LOCAL]. Aquí es desde donde haremos los desarrollos, para posteriormente, subirlos a producción. Tendremos que tener git instalado (desde paquetería o compilando).


Lo que sigue a continuación serán los pasos al estilo receta, para más info de git, acudir al sitio http://git-scm.com/book/es/

1) Crear repositorio remoto

- Accedemos por ssh a SERVIDOR
- Creamos la ubicación del repositorio y lo iniciamos:

    [SERVIDOR] mkdir /opt/repo/aplicacionA.git
    [SERVIDOR] cd /opt/repo/aplicacionA.git
    [SERVIDOR] git init --bare


¡IMPORTANTE! El usuario que utilicemos para conectarnos por ssh al SERVIDOR debe tener permisos sobre /opt/repo/aplicacionA.git

- Configuramos nuestro proyecto de producción para indicar la ubicación del repositorio y hacer la carga de código:

    [SERVIDOR] cd /opt/proyecto/aplcacionA
    [SERIVDOR] git init
    [SERVIDOR] git remote add origin /opt/repo/aplicacionA.git
    [SERVIDOR] git add .
    [SERVIDOR] git commit -m 'Primera entrada de commit'
    [SERVIDOR] git push origin master


Hasta aquí ya tenemos en nuestro repositorio remoto el código del proyecto de producción.

2) Descargar el repositorio
 
- Ahora nos descargaremos el proyecto en LOCAL para poder trabajar con él:

    [LOCAL] mkdir /opt/desarrollo
    [LOCAL] cd /opt/desarrollo
    [LOCAL] git clone ssh://usuario@SERVIDOR//opt/repo/aplicacionA.git


Ya tenemos en local una copia del código de producción.

3) Realizar cambios

- Si queremos realizar un cambio en local y luego aplicarlo a producción (ejemplo, añadir un nuevo fichero):

    [LOCAL] cd /opt/desarrollo/aplicacionA   
    [LOCAL] touch README
    [LOCAL] git add README    #Indicamos que tenga en cuenta este fichero
    [LOCAL] git commit -m "Añadimos fichero README"    #Hacemos commit con un comentario
    [LOCAL] git push origin master    #Subimos el fichero al repositorio


- Ahora aplicaremos este cambio en producción:

    [SERVIDOR] cd /opt/proyecto/aplcacionA
    [SERVIDOR] git pull origin master    #Obtenemos la última versión del respositorio


- Si nos equivocamos mientras hacemos un cambio:

    [LOCAL] cd /opt/desarrollo/aplicacionA
    [LOCAL] git add README
    [LOCAL] echo "Prueba" > README    #Hacemos un cambio en README, pero nos arrepentimos y queremos volver al estado anterior
    [LOCAL] git reset README    #Le decimos que no tenga en cuenta este fichero para los cambios en el respositorio
    [LOCAL] git checkout -- README    #Volvemos a la versión del repositorio del último commit.


- Para recuperar archivos antiguos, remito a esta entrada:

http://www.alvaroremesal.net/blog-alvaroremesal/recuperar-archivos-antigos-con-git

4) Crear ramas

    git branch nueva_rama
    git branch -> nos muestra las distintas ramas existentes
    git checkout nueva_rama -> nos cambiamos a esta nueva rama



Espero que sea útil.

Sacar configuración importante de settings.py en Django

Es posible que necesitemos sacar cierta información de carácter sensible del fichero settings.py de un proyecto, bien por facilitar el trabajo con control de versiones, o por querer tener diferentes configuraciones entre entornos.

Una manera sencilla de hacer esto es como se explica en https://code.djangoproject.com/wiki/SplitSettings.


Por ejemplo, imaginemos que queremos sacar la información de bbdd. Para ello nos vamos a crear un fichero settings.ini en /etc, cuyo contenido será este:

[database]
DATABASE_NAME: nombre_bbdd
DATABASE_USER: usuario
DATABASE_PASSWORD: pass
DATABASE_HOST: localhost
DATABASE_PORT: 3306


Luego tan sólo tendremos que modificar nuestro settings.py añadiendo esto:

from ConfigParser import RawConfigParser

config = RawConfigParser()
config.read('/etc/settings.ini')




Y en la sección DATABASES configuraremos lo siguiente:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'config.get('database', 'DATABASE_NAME')',                     
        'USER': config.get('database', 'DATABASE_USER'),                     
        'PASSWORD': config.get('database', 'DATABASE_PASSWORD'),                 
        'HOST': config.get('database', 'DATABASE_HOST'),                     
        'PORT': config.get('database', 'DATABASE_PORT'),                    
    }
}


Y listo, ya tendremos nuestro settings.py configurado para poder ser distribuido sin tener que estar pendiente de modificar ningún dato sensible.

jueves, 18 de octubre de 2012

Corregir problemas de codificación en Django

Para evitar errores de codificación en Django del tipo: 

django 'ascii' codec can't encode character u'\xf3'

debido a la codificación que tenga por defecto python (que suele ser ascii), simplemente tenemos que añadir a nuestro settings.py las siguientes líneas:


import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )

Y conseguiremos establecer la codificación adecuada.

miércoles, 17 de octubre de 2012

Ejecutar comandos personalizados de Django desde el cron

Para poder ejecutar comandos personalizados de django desde el cron, necesitaremos aplicar el siguiente parche (si es que aún no lo trae):




Una vez aplicado el parche, ya podremos invocar nuestro comando de la siguiente manera:

minutos hora * * * /usr/bin/python /sitio/proyecto/django/manage.py comando



miércoles, 10 de octubre de 2012

Definir rango de puertos del ftp en alfresco 3.2

Debido a que el servicio de ftp de alfresco funciona en modo pasivo, este abrirá puertos por encima del 1024 para llevar a cabo la comunicación de datos.

Si tenemos un firewall muy restrictivo, nos interesará definir un rango determinado de puertos y abrir sólo ese rango.

Para definir el rango de puertos debemos añadir a /tomcat/shared/classes/alfresco-global.properties los siguientes parámetros:

ftp.dataPortFrom=50000
ftp.dataPortTo=60000

En este caso estamos definiendo el rango del 50000 al 60000.


Veamos si esto funciona de verdad. Hacemos un ftp en modo debug a nuestro servidor:

ftp -d 192.168.60.13 2122

Connected to 192.168.60.13.
220 FTP server ready
ftp: setsockopt: Bad file descriptor
Name (servidor:rafa): usuario
---> USER usuario
331 User name okay, need password for usuario
Password:
---> PASS XXXX
230 User logged in, proceed
---> SYST
215 UNIX Type: Java FTP Server
Remote system type is UNIX.

Indicamos el modo pasivo:

ftp> passive
Passive mode on.

Y lanzamos un comando:

ftp> ls
ftp: setsockopt (ignored): Permission denied
---> PASV
227 Entering Passive Mode (192,168,60,13,211,39)
---> LIST
150 File status okay, about to open data connection
drw-rw-rw-   1 user group 0 Jan  1  1970 Alfresco
drw-rw-rw-   1 user group 0 Jan  1  1970 AVM
226 Closing data connection
ftp>




Vemos como efectivamente el puerto que ha utilizado está por encima del 50000 y por debajo del 60000 (el puerto se obtiene de los valores que van después de la ip, 211*256+39=54055).

Si hacemos un tcpdump en el servidor, filtrando por ip origen, veremos que efectivamente ese es el puerto que ha utilizado:


Para puerto de datos:

10:40:20.810783 Out MAC ethertype IPv4 (0x0800), length 68: 192.168.60.13.54055 > ip_local.50958: . ack 2 win 46 <nop,nop,timestamp 552972262 76243556>

Para puerto de conexión:

10:40:20.810795  In MAC ethertype IPv4 (0x0800), length 68: ip_local.50583 > 192.168.60.13.2122: . ack 271 win 115 <nop,nop,timestamp 76243556 552972260>

Obtener informacion de repositorios a través de los metadatos .git publicados por error

 A raiz de CTF realizado recientemente, me ha parecido interesante publicar este post sobre los errores de seguridad que se encuentran en mu...