Configuración de un clúster de alta disponibilidad para una página web
1. Proyecto fin de curso
Indice
1.- Introducción
2.- Clúster
Requisitos
Configuración SAN
Instalacion del rol Servicios de archivos y almacenamiento
Configuración del rol Servicios de archivos y almacenamiento
Configuración del DC
Configuración de los equipos del clúster
Instalación del rol de clúster de conmutación por error
Configuración de los destinos iSCSI
Creando el clúster
3.- Base de Datos
Esquema
Usuarios MySQL
Permisos de los usuarios
Disparadores o Triggers
4.- Páginas web
Servidor web
Lenguajes utilizados
PHP
HTML
CSS
Javascript
5.-Ficheros de configuración
5.1 MySQL: my.cnf
5.2 Apache2:
5.2.1. apache2.conf
5.2.2. 000-defaults.conf
5.2.3. defaults-ssl
5.3 PHP: php.ini
6.- Instalación del servidor
7.- Páginas del Proyecto
8.- Secciones de código relevantes
Control de la sesión
Formato de las llamadas a la base de datos
Control de imagenes
Tratamiento de las contraseñas
Enlaces de las fuentes
Botones
Función de la cuenta atrás
10- Auditorias al sistema web
w3af
Nessus
PHPSECINFO
11- Comentarios sobre los clústeres
12.- Comentarios generales
(Indice)
2. 1.- Introducción
A lo largo de este proyecto veremos como hacer un clúster de alta disponibilidad para una
página web que requiere una base de datos, para ello tratare de explicar primero cada componente
del sistema que vamos a utilizar.
"El término clúster (del inglés clúster, "grupo" o "raíz") se aplica a los conjuntos o conglomerados
de computadoras unidos entre sí normalmente por una red de alta velocidad y que se comportan como si
fuesen una única computadora." Clúster Wikipedia
El clúster por lo tanto es lo que nos otorga la alta disponibilidad, lo que significa que si por
algún motivo algún servidor que forma parte del clúster se apaga, esto no nos afectara a la actividad
del servicio ofrecido, debido a que hay varios equipos que están en constante comunicación entre si
para evitar la perdida de información y la caída del servicio.
"Se le llama base de datos a los bancos de información que contienen datos relativos a diversas
temáticas y categorizados de distinta manera, pero que comparten entre sí algún tipo de vínculo o relación
que busca ordenarlos y clasificarlos en conjunto." Base de datos Wikipedia
La base de datos nos ofrecerá un lugar donde guardar toda la información que necesitemos
almacenar y queramos que este disponible para nuestro servicio, como los nombres de los usuarios,
etc.
"Una página web, página electrónica o cyber página,1 2 es un documento o información electrónica
capaz de contener texto, sonido, vídeo, programas, enlaces, imágenes, y muchas otras cosas, adaptada para
la llamada World Wide Web, y que puede ser accedida mediante un navegador. Esta información se
encuentra generalmente en formato HTML o XHTML, y puede proporcionar navegación (acceso) a otras
páginas web mediante enlaces de hipertexto. Las páginas web frecuentemente también incluyen otros
recursos como ser hojas de estilo en cascada, guiones (scripts), imágenes digitales, entre otros." Página web
Wikipedia
La página web sera la interfaz con el usuario, y es necesario que sea accesible en cualquier
momento, por lo que necesitamos que tenga una alta disponibilidad, lo que nos obliga a hacer el
clúster para que eso sea real, además queremos guardar los datos de los usuarios registrados en
algún sitio y ese lugar sera la base de datos.
Este proyecto se divide en 4 apartados que unidos entre si generan un todo, al estar
estrechamente relacionados: como es la configuración y disposición del hardware y de los sistemas
operativos con la generación de un clúster, en un siguiente nivel estaría la base de datos donde
estará toda la información que necesitemos guardar, después vendría la interfaz web que se
relacionaría con el usuario final, y rodeando todo el sistema una capa que se va entrelazando con las
otras que es la seguridad del proyecto, los datos de los usuarios, etc.
A lo largo del documento iremos diseccionando el proyecto de tal manera que podamos ver
como ir creando las distintas partes por separado, y como se van uniendo poco a poco para hacer un
(Indice)
3. todo.
2.- Clúster
Requisitos:
Windows Windows Server 2008 R2 Datacenter o Enterprise
Windows Server 2012 R2 Datacenter
Escenario:
1 Controlador de Dominio
3 w2008r2 para el clúster
1 w2012r2 para SAN
Conexiones:
1 red interna con el DC:
10.10.1.0/24
1 red interna para los clústeres:
10.10.2.0/24
1 red interna para SAN:
10.10.3.0/24
(Indice)
4. Configurando el almacenamiento SAN en Windows Server 2012 R2:
Configuración de la MV del servidor SAN:
Este servidor no estará dentro del Dominio
2 discos duros:
1. Disco del sistema: 100 GB
2. Disco del servidor SAN: 400GB
Mínimo de 1 adaptador de red con
conexión a la red interna "red san"
(Indice)
5. Le asignamos una IP de nuestra red interna "red san", y le cambiamos el nombre al equipo.
(Indice)
6. Nos aseguramos que el disco este utilizable, sino creamos un nuevo volumen simple.
Una vez realizados estos pasos previos, pasaremos a agregar la funcionalidad iSCSI Target:
1. Vamos a "Agregar roles y características"
(Indice)
7. 2. Aquí nos indica que hace este asistente, "Siguiente".
3. Seleccionamos "Instalación basada en características y roles" y "Siguiente"
4. Escogemos el servidor donde queremos hacer la instalación y “Siguiente”
(Indice)
8. 5. Seleccionamos en “Roles del servidor” dentro de “Servicios de archivos y almacenamiento”
los “Servicios de iSCSI y archivo”, dentro de esta pestaña tenemos que elegir 2, el “Servidor
de archivos” y el “Servidor del destino iSCSI”, en el caso que pinchemos primero en el
servidor de destino iSCSI nos dirá que es necesario el servidor de archivos, y “Siguiente”.
6. En características le damos a “Siguiente”
(Indice)
9. 7. Confirmamos que todo esta correcto e instalamos
8. Una vez instalado pinchamos en “Cerrar”
(Indice)
10. Una vez instalado el rol, procedemos a configurarlo:
1. Vamos a “Servicios de archivos y de almacenamiento”
2. Seleccionamos “iSCSI”
3. Pinchamos en el enlace al asistente
(Indice)
11. 4. Seleccionamos el disco donde crearemos nuestro almacenamiento iSCSI y “Siguiente”
5. Le asignamos un nombre, a ser posible significativo de su función
(Indice)
12. 6. Asignamos el tamaño del disco y en mi caso le pongo que se expanda dinámicamente y
“Siguiente”
7. Ahora elegimos la opción de “Nuevo destino iSCSI” y “Siguiente”
(Indice)
13. 8. Le ponemos un nombre a nuestro destino SAN y “Siguiente”.
(Indice)
14. 9. Agregamos los iniciadores del servidor SAN, elegimos la opción de identificación por IP.
(Indice)
16. 12. Una vez finalizada la creación cerramos.
13. Ahora continuamos creando el disco quorum, para el clúster, vamos a “Tareas” > “Nuevo
disco virtual iSCSI”
(Indice)
17. 14. Seleccionamos la ubicación del nuevo disco y “Siguiente”
15. Le asignamos un nombre y “Siguiente”
(Indice)
18. 16. Le damos asignamos 10 GB, este disco no necesita tener gran capacidad y “Siguiente”
17. Seleccionamos nuestro destino que hemos creado previamente y “Siguiente”
(Indice)
19. 18. Confirmamos que esta todo correctamente y creamos el disco
19. Cuando finalice cerramos
20. Y podemos ver los 2 discos creados
(Indice)
20. Configuración del DC:
En el controlador de dominio he agregado los siguientes roles, par una mayor comodidad a lo largo
de las pruebas:
1. Servicios de acceso y directivas de redes, el enrutamiento, para mantener toda la red clúster
dentro de la propia red y simular así la salida a Internet
2. Servidor DHCP, con un ámbito para repartir IPs dinámicamente a los clientes cuando se
hagan las pruebas
3. 1 usuario llamado “clúster” para la administración de los clústeres
Configuración de los equipos de los clústeres, previo a la creación del clúster:
1. Configuramos las IPs y el nombre del equipo de todos los equipos
(Indice)
21. 2. Los agregamos al dominio
Agregaremos la característica de clústeres a todos los equipos:
1. Vamos a Agregar características
(Indice)
26. 5. En la pestaña “Volúmenes y dispositivos” pinchamos en “Autoconfigurar” y nos aparecerán
los discos.
(Indice)
27. 6. En la pestaña de “Destinos favoritos” comprobamos que esta nuestro destino y le damos a
“Aceptar”
(Indice)
28. La primera vez que los usemos tendremos que seguir unos pasos previos para inicializar el disco:
1. Empezamos por ir a la administración de discos y poner el disco “En línea”
2. Después inicializamos el disco
(Indice)
29. 3. Le decimos el tipo de tabla de particiones que queremos:
4. Creamos un “Nuevo volumen simple...” y seguimos el asistente
5. Finalmente debe de tener este aspecto, un disco pequeño para el quorum y el disco de
almacenamiento de datos:
(Indice)
30. Llegados a este momento debemos de repetir todos los pasos menos la inicialización de los discos
que la hicimos en el primero, pero en el resto hay que ponerlos “En línea” a todos.
Haciendo una pequeña recapitulación de lo que llevamos hecho:
1. Instalado y configurado el DC
2. Instalado y configurado el servidor SAN
3. Instalada la característica de clúster por conmutación por error y configurados e iniciados
los destinos iSCSI
Creando el clúster:
1. Vamos a las características y seleccionamos “Administrador de clústeres” y una vez dentro
pinchamos en “Validar una configuración”
(Indice)
31. 2. Nos informa para que vale el asistente y le damos a “Siguiente”
3. Seleccionamos los equipos con los que queremos crear el clúster
(Indice)
32. 4. Seleccionamos la opción de “Ejecutar todas las pruebas”
5. Confirmamos y le damos a “Siguiente” y esperamos a que realice las pruebas
(Indice)
33. 6. Una vez finalizadas las pruebas revisamos el informe y si todo es correcto pinchamos en
“Crear el clúster ahora con los nodos validados”
7. Aquí nos mostrara lo que hace este nuevo asistente, “Siguiente”
(Indice)
34. 8. Le damos un nombre al clúster y una IP publica para su uso y administración y “Siguiente”
9. Confirmamos y le damos “Siguiente” y esperamos a que se cree el clúster.
(Indice)
35. 10. Una vez terminado, le damos a Finalizar
En este punto tendremos un Clúster de conmutación por error listo para instalarle servicios
Informe de la validación:
1. Aquí vemos que nos da una advertencia, pero que el resto esta todo perfecto
(Indice)
36. 2. La advertencia es sobre los controladores firmados que no se han podido validar
3. Cuando los vemos podemos ver que el motivo es debido a que Windows no reconoce a
VirtualBox como un controlador confiable
(Indice)
38. 3.- Base de Datos
Esquema:
Usuarios MySQL:
Hay dos usuarios de MySQL dedicados en exclusividad al manejo de la base de datos del juego,
estos son “juegophp”, usuario pensado para que lo maneje el motor del juego para actualizar la base
de datos y hacer de nexo entre los usuarios finales del juego y la base de datos, este es un usuario
limitado a lo que es necesario para mover el juego.
Y otro usuario llamado “adminjuego” que es el administrador del juego, que tiene control total
sobre la base de datos de juegophp pero no puede hacer absolutamente nada fuera de su base de
datos.
Permisos de los usuarios:
Permisos del usuario “juegophp” sobre las tablas de la base de datos:
(Indice)
39. Permisos del usuario “adminjuego”:
Disparadores o Triggers de la base de datos:
(Indice)
40. 4.- Páginas Web
Servidor web:
He decidido elegir Apache web server por varios motivos:
1. Familiaridad, debido al que es el que más he usado, que no el único.
2. Tipo de Licencia, open source : Licencia Apache 2.0
3. Soporte y documentación
Lenguajes utilizados:
• PHP
• HTML
• CSS
• Javascript
PHP:
“Es un lenguaje de 'scripting' de propósito general y de código abierto que está especialmente
pensado para el desarrollo web y que puede ser embebido en páginas HTML.” de php.net
Lo importante del lenguaje PHP es que es del lado del servidor, por lo que su ejecución se realiza en
el servidor y el resultado se envía al cliente.
El echo de que sea un lenguaje de servidor le hace ideal para realizar todo tipo de proyectos web
que queremos que sean más o menos fáciles de implementar debido a la que la curva de aprendizaje
inicialmente es muy fácil y hasta que se complica de verdad hay mucho espacio para empezar
muchos proyectos distintos, en mi caso un juego online.
Además el PHP serán las entrañas del juego, donde se filtraran y gestionaran los datos obtenidos de
los clientes, en gran medida de que nuestro servidor sea o no seguro depende del tipo de
implementación elegida, como el uso de $_POST en lugar de $_GET, etc.
HTML:
“Es un estándar que sirve de referencia para la elaboración de páginas web en sus diferentes
versiones, define una estructura básica y un código para la definición de contenido de una página
web” de Wikipedia
Con el lenguaje HTML lo que hacemos es definir el esqueleto de la interfaz gráfica que el usuario
final recibirá, es lo que le dará uniformidad a nuestro proyecto.
CSS:
“Es un lenguaje usado para definir y crear la presentación de un documento estructurado escrito en
HTML o XML, es el encargado de formular la especificación de las hojas de estilo que servirán de
estándar para los agentes de usuario o navegadores.” de Wikipedia
Usamos CSS para darle al esqueleto del HTML la definición del diseño, y la armonía que todo
proyecto web necesita.
Además las hojas de estilo nos permitan personalizar y jugar con el diseño de la página de manera
dinámica.
(Indice)
41. Javascript:
“ Es un lenguaje de programación interpretado. Se define como orientado a objetos, basado en
prototipos, imperativo, débilmente tipado y dinámico.” de Wikipedia
Javascript esta orientado en nuestro proyecto a darle vida al contenido del juego en el lado del
cliente. Y generando el dinamismo esperado por el usuario final.
Con él también tendremos a nuestra disposición herramientas de filtrado previo nuestro servidor,
por lo que aunque sigamos filtrando con PHP, esto nos ayudara a evitar llamadas de errores al
servidor por lo que al final es menor carga de trabajo.
5.-Ficheros de configuración
En este apartado veremos como quedan al final los ficheros de configuración, la única diferencia
entre estos ficheros y los reales es que he borrado los comentarios de los mismos.
5.1 MySQL: my.cnf
Ruta del fichero: /etc/mysql/my.cnf
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address = 127.0.0.1
key_buffer = 32M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
myisam-recover = BACKUP
table_cache = 1024
(Indice)
42. query_cache_limit = 1M
query_cache_size = 32M
log_error = /var/log/mysql/error.log
slow_query_log_file = /var/log/mysql/mysql-slow.log
slow_query_log = 1
long_query_time = 2
expire_logs_days = 10
max_binlog_size = 100M
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 16M
!includedir /etc/mysql/conf.d/
5.2 Apache2:
5.2.1. apache2.conf
Ruta del fichero: /etc/apache2/apache2.conf
#ServerRoot "/etc/apache2"
Mutex file:${APACHE_LOCK_DIR} default
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
(Indice)
50. • Instalamos PHP5, PHP5-MySQL, libapache2-mod-php5
• Instalamos phpmyadmin
• Reiniciamos el servidor por primera vez
Creacción de los certificados ssl/ssh:
Los certificados los generamos para poder probar las funcionalidades de HTTPS que usaremos en el
servidor, pero hay que tener en cuenta que para un servidor en producción, debemos obtener un
certificado de un tercero para que nuestra página sea de total confianza
◦ Paso 1, generamos el primer certificado
◦ Paso 2, generamos el certificado no pass, y le cambiamos los permisos para que solo lo use
root
(Indice)
51. ◦ Paso 3, terminamos el certificado, y los resultante los movemos a las carpetas donde
guardaremos nuestros certificados
Configurando Apache2
Habilitamos el modulo de SSL de Apache y reiniciamos el apache
Si hacemos la prueba ahora, veremos que podemos acceder a la version HTTPS de nuesto servidor
web
Pero esto es solo el principio ya que aun debemos de configurar 2 ficheros enteros para que nuestro
servidor Apache este utilizable. Y Habilitar un par de módulos, que son: rewrite, expires y ssl.
(Indice)
52. Así que ahora una vez instalado todo, aun no hemos configurado nada, probamos que funcionan y
procedemos a configurar fichero a fichero, y hacer pruebas a lo largo de la configuración para
confirmarnos que todo va bien.
7.- Páginas del proyecto:
1. acceso.html
Página de inicio de Runic Adventures
2. acceso.php
Página de control de acceso al juego
3. combate.php
Página donde se ejecutan los diversos combates de Runic Adventures
4. creaheroe.php
Formulario donde el usuario crea al héroe
5. cuenta.php
Formulario para cambiar los datos de la cuenta
6. enviarmensajes.php
Página de la interfaz y de la gestión de los mensajes enviados
7. fotoheroe.php
Página de gestión de la subida de la imagen del héroe
8. funciones.php
Pagina estándar incluida en todas las demás que contiene las funciones y la plantilla estándar
de la interfaz de Runic Adventures
9. heroe.php
Formulario de personalización del héroe: imagen, nombre y biografía
10. hogar.php
Formulario de selección del equipo, página del inventario
11. juego01.css
Fichero CSS que armoniza la interfaz de Runic Adventures
12. leermensajes.php
Página para la lectura y borrado de los mensajes
13. mensajes.php
Página del menú principal de los mensajes
14. modcuenta.php
Página que genera y controla la petición de los cambios de la cuenta
15. modheroe.php
Página que genera y controla la petición de los cambios del héroe
16. modhogar.php
Página que genera y controla la petición de los cambios del equipo del héroe
17. nuevoheroe.php
Página que genera y controla la creación de un nuevo héroe
18. principal.php
Página principal del juego
19. registro.html
Formulario de creación de un nuevo usuario
20. registro.php
Página que genera y controla la creación de un nuevo usuario
21. salir.php
Página que borra la sesión y desconecta del juego
22. subirlvl.php
Página que genera y controla la petición de subida de nivel del héroe
(Indice)
53. 23. subirnivel.php
Formulario para la subida de nivel del héroe
24. trabajando.php
Página que gestiona la petición de trabajos
25. trabajos.php
Menú de los trabajos disponibles
8.- Secciones de código relevantes:
Control de la sesión:
Normalmente contiene la primera llamada a la base de datos, incluye la llamada al archivo
funciones.php, el header principal del php
***
<?php
if(session_start() && isset($_SESSION['usuario']))
{
$user=trim($_SESSION['usuario']);
$nombreHeroe=$_SESSION['héroe'];
header('Content-Type: text/html; charset=utf-8');
include 'funciones.php';
// Conexión al Servidor
$con=@mysqli_connect('localhost','juegophp','centauro','juegophp');
}
else
{
header("Location: acceso.html");
exit();
}
***
Formato de las llamadas a la base de datos:
***
// Conexión normalmente esta en el control de sesión al principio de la página
$con=@mysqli_connect('localhost','juegophp','centauro','juegophp');
// consulta que se hará a la base de datos
$query = "SELECT * FROM heroes WHERE usuario like '$user'";
// almacenamiento de la consulta realizada
$result = mysqli_query($con, $query);
// guardando los datos de la cunsulta en un array
$héroe = mysqli_fetch_array($result,MYSQLI_BOTH);
***
Control de imágenes subidas por usuarios, resalto este ya que es el que mantiene una imagen por
usuario dentro de nuestro servidor.
***
$query="update heroes set ruta='$rutaDestino' WHERE usuario like '$user' and nombre like
'$nombreHeroe' ";
// Si la ruta del fichero es la misma o es igual que la imagen de base de los usuarios , la sube
if ($héroe[11] == $rutaDestin || $héroe[11] == $base)
{
move_uploaded_file($rutaTemporal,$rutaDestino);
(Indice)
54. }
else
{
// en cualquier otro caso la renombras y después subes la nueva imagen
rename($héroe[11], $rutaDestino);
move_uploaded_file($rutaTemporal,$rutaDestino);
}
//si todo va bien actualizamos la base de datos y volvemos a la página de heroe.php
if (mysqli_query($con, $query)){
header("Location: heroe.php");
}
else
{
header("Location: heroe.php");
}
***
Tratamiento de las contraseñas dentro del juego:
Encripto la contraseña y la corto antes de guardarla en la base de datos, para mejorar la seguridad de
nuestra base de datos
***
$user=trim( $_POST['usuario'] );
$passw=crypt(trim( $_POST['passw'] ),'$5$rounds=5000$calamaresensutin$');
$passw=substr($passw, 32);
***
Enlaces de las fuentes, esto es una curiosidad, ya que yo al solo servir paginas https, hay que
indicarselo en el link para que las utilice porque sino simplemente no las llama por no ser seguras.
***
<link href='https://fonts.googleapis.com/css?family=Cinzel+Decorative:700' rel='stylesheet'
type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Julius+Sans+One' rel='stylesheet'
type='text/css'>
***
Función que controla los botones de subir o bajar un punto a las características, esta funcionalidad
esta realizada con javascript
***
function addfue(delta) {
var total = eval(subirlvl.fue.value)+eval(subirlvl.des.value)+eval(subirlvl.vit.value)
+eval(subirlvl.def.value);
(Indice)
55. valor = eval(subirlvl.fue.value);
if (delta == +1)
{
if (total < max)
{
subirlvl.fue.value = eval(valor+delta);
}
}
else
{
if (valor > fuer)
{
subirlvl.fue.value = eval(valor+delta);
}
}
}
// este es el botón en html
<LABEL for="fue">Fuerza: </LABEL>
<br />
<input type="button" value="-" onClick="addfue(-1);">
<input type='text' name='fue' value="10" size="1" />
<input type="button" value="+" onClick="addfue(1);">
***
Función de la cuenta atrás, marca de manera visual para el usuario el tiempo que le queda para
realizar el siguiente trabajo, esta función costo hacerla andar ya que aunque la base esta obtenida de
Internet había que adaptarla al código y a mi sistema de control de tiempos.
***
toYear=<?php echo date('Y',$trabajo_actual[2])?>;
toMonth=<?php echo date('m',$trabajo_actual[2])?>;
toDay=<?php echo date('d',$trabajo_actual[2])?>;
toHour=<?php echo date('H',$trabajo_actual[2])?>;
toMinute=<?php echo date('i',$trabajo_actual[2])?>;
toSecond=<?php echo date('s',$trabajo_actual[2])?>;
function countDown()
{
new_year=0;
new_month=0;
new_day=0;
new_hour=0;
new_minute=0;
new_second=0;
actual_date=new Date();
if(actual_date.getFullYear()>toYear)
(Indice)
56. {
//si ya nos hemos pasado del año, mostramos los valores a 0
form.second.value=0;
form.minute.value=0;
form.hour.value=0;
form.day.value=0;
form.month.value=0;
form.year.value=0;
}else{
new_second=new_second+toSecond-actual_date.getSeconds();
if(new_second<0)
{
new_second=60+new_second;
new_minute=-1;
}
form.second.value=new_second;
new_minute=new_minute+toMinute-actual_date.getMinutes();
if(new_minute<0)
{
new_minute=60+new_minute;
new_hour=-1;
}
form.minute.value=new_minute;
new_hour=new_hour+toHour-actual_date.getHours();
if(new_hour<0)
{
new_hour=24+new_hour;
new_day=-1;
}
form.hour.value=new_hour;
new_day=new_day+toDay-actual_date.getDate();
if(new_day<0)
{
x=actual_date.getMonth();
if(x==0||x==2||x==4||x==6||x==7||x==9||x==11){new_day=31+new_day;}
if(x==3||x==5||x==8||x==10){new_day=30+new_day;}
if(x==1)
{
//comprobamos si es un año bisiesto...
if(actual_date.getYear()/4-Math.floor(actual_date.getYear()/4)==0)
{
actual_date=29+actual_date;
}else{
actual_date=28+actual_date;
}
}
}
(Indice)
58. -- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `equipo`
--
DROP TABLE IF EXISTS `equipo`;
CREATE TABLE IF NOT EXISTS `equipo` (
`id_equipo` int(4) NOT NULL,
`nombre` varchar(255) NOT NULL,
`lvl` int(4) NOT NULL,
`fue` int(4) NOT NULL,
`def` int(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `heroes`
--
DROP TABLE IF EXISTS `heroes`;
CREATE TABLE IF NOT EXISTS `heroes` (
`usuario` varchar(255) NOT NULL,
`nombre` varchar(255) NOT NULL,
`nivel` int(4) NOT NULL,
`fue` int(4) NOT NULL,
`des` int(4) NOT NULL,
`vit` int(4) NOT NULL,
`def` int(4) NOT NULL,
`equipo` text,
`obj1` int(4) DEFAULT NULL,
`obj2` int(4) DEFAULT NULL,
`exp` int(10) NOT NULL DEFAULT '0',
`ruta` varchar(255) DEFAULT NULL,
`descripcion` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `mensajes`
--
DROP TABLE IF EXISTS `mensajes`;
CREATE TABLE IF NOT EXISTS `mensajes` (
`id_mensaje` int(11) NOT NULL,
`remitente` varchar(255) NOT NULL,
`usuario` varchar(255) NOT NULL,
`fecha` datetime NOT NULL,
(Indice)
59. `leido` int(1) NOT NULL,
`asunto` varchar(255) NOT NULL,
`mensaje` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=34 ;
--
-- Disparadores `mensajes`
--
DROP TRIGGER IF EXISTS `mensajes_delete`;
DELIMITER //
CREATE TRIGGER `mensajes_delete` BEFORE DELETE ON `mensajes`
FOR EACH ROW BEGIN
-- Insert record into audit table
INSERT INTO mensajes_bk(id_mensaje, remitente, usuario, fecha, leido, asunto, mensaje,
fec_borr) VALUES (old.id_mensaje , old.remitente , old.usuario , old.fecha , old.leido , old.asunto ,
old.mensaje,now());
END
//
DELIMITER ;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `mensajes_bk`
--
DROP TABLE IF EXISTS `mensajes_bk`;
CREATE TABLE IF NOT EXISTS `mensajes_bk` (
`id_mensaje` int(11) NOT NULL,
`remitente` varchar(255) NOT NULL,
`usuario` varchar(255) NOT NULL,
`fecha` datetime NOT NULL,
`leido` int(1) NOT NULL,
`asunto` varchar(255) NOT NULL,
`mensaje` text NOT NULL,
`fec_borr` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `monstruos`
--
DROP TABLE IF EXISTS `monstruos`;
CREATE TABLE IF NOT EXISTS `monstruos` (
`id_monstruo` int(4) NOT NULL,
`nombre` varchar(80) COLLATE utf8_spanish_ci NOT NULL,
`nivel` int(4) NOT NULL,
(Indice)
60. `fue` int(4) NOT NULL,
`des` int(4) NOT NULL,
`vit` int(4) NOT NULL,
`def` int(4) NOT NULL,
`exp` int(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `trabajos`
--
DROP TABLE IF EXISTS `trabajos`;
CREATE TABLE IF NOT EXISTS `trabajos` (
`héroe` varchar(255) NOT NULL,
`id_trabajo` int(2) NOT NULL,
`finalizacion` varchar(80) NOT NULL,
`finalizado` int(2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `trabajos_tipos`
--
DROP TABLE IF EXISTS `trabajos_tipos`;
CREATE TABLE IF NOT EXISTS `trabajos_tipos` (
`id_trabajo` int(2) NOT NULL,
`tiempo` varchar(80) NOT NULL,
`exp` int(5) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `usuarios`
--
DROP TABLE IF EXISTS `usuarios`;
CREATE TABLE IF NOT EXISTS `usuarios` (
`usuario` varchar(255) NOT NULL,
`pass` varchar(255) NOT NULL,
`nombre` varchar(50) NOT NULL,
`apellidos` varchar(100) NOT NULL,
`correo` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Índices para tablas volcadas
(Indice)
61. --
--
-- Indices de la tabla `equipo`
--
ALTER TABLE `equipo`
ADD PRIMARY KEY (`id_equipo`);
--
-- Indices de la tabla `heroes`
--
ALTER TABLE `heroes`
ADD PRIMARY KEY (`nombre`), ADD KEY `usuario` (`usuario`), ADD KEY `obj1` (`obj1`),
ADD KEY `obj2` (`obj2`);
--
-- Indices de la tabla `mensajes`
--
ALTER TABLE `mensajes`
ADD PRIMARY KEY (`id_mensaje`), ADD KEY `usuario` (`usuario`);
--
-- Indices de la tabla `mensajes_bk`
--
ALTER TABLE `mensajes_bk`
ADD PRIMARY KEY (`id_mensaje`), ADD KEY `usuario` (`usuario`);
--
-- Indices de la tabla `monstruos`
--
ALTER TABLE `monstruos`
ADD PRIMARY KEY (`id_monstruo`);
--
-- Indices de la tabla `trabajos`
--
ALTER TABLE `trabajos`
ADD KEY `id_trabajo` (`id_trabajo`), ADD KEY `héroe` (`héroe`);
--
-- Indices de la tabla `trabajos_tipos`
--
ALTER TABLE `trabajos_tipos`
ADD PRIMARY KEY (`id_trabajo`);
--
-- Indices de la tabla `usuarios`
--
ALTER TABLE `usuarios`
ADD PRIMARY KEY (`usuario`);
(Indice)
62. --
-- AUTO_INCREMENT de las tablas volcadas
--
--
-- AUTO_INCREMENT de la tabla `mensajes`
--
ALTER TABLE `mensajes`
MODIFY `id_mensaje` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=34;
--
-- AUTO_INCREMENT de la tabla `mensajes_bk`
--
ALTER TABLE `mensajes_bk`
MODIFY `id_mensaje` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=21;
--
-- Restricciones para tablas volcadas
--
--
-- Filtros para la tabla `heroes`
--
ALTER TABLE `heroes`
ADD CONSTRAINT `heroes_ibfk_1` FOREIGN KEY (`usuario`) REFERENCES `usuarios`
(`usuario`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `heroes_ibfk_2` FOREIGN KEY (`obj1`) REFERENCES `equipo`
(`id_equipo`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `heroes_ibfk_3` FOREIGN KEY (`obj2`) REFERENCES `equipo`
(`id_equipo`) ON DELETE SET NULL ON UPDATE CASCADE;
--
-- Filtros para la tabla `mensajes`
--
ALTER TABLE `mensajes`
ADD CONSTRAINT `mensajes_ibfk_1` FOREIGN KEY (`usuario`) REFERENCES `heroes`
(`nombre`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Filtros para la tabla `trabajos`
--
ALTER TABLE `trabajos`
ADD CONSTRAINT `trabajos_ibfk_1` FOREIGN KEY (`id_trabajo`) REFERENCES
`trabajos_tipos` (`id_trabajo`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `trabajos_ibfk_2` FOREIGN KEY (`héroe`) REFERENCES `heroes`
(`nombre`) ON DELETE CASCADE ON UPDATE CASCADE;
(Indice)
63. 10.- Auditorias al sistema web:
w3af:
Este programa me llamo mucho la atención, por su fácil uso y múltiples opciones. Aparte de venir
con herramientas pensadas para la realización de ataques a través de los exploits detectados
Cuenta con una interfaz muy simple, tenemos la opción de elegir el tipo de ataque y donde poner el
objetivo o target
Bien, el tiempo puede depender de muchas cosas, ya sea si la pagina es muy grande o el tipo de
Scan que usaremos, el "fast_scan" no tarda más allá de unos 10 minutos.
En las pestañas de la izquierda podemos ir revisando los resultados y los exploit.
Como conclusión W3af, queda entre la lista de los favoritos en relación a la auditoria y seguridad
web.
Nessus:
“Nessus es un programa de escaneo de vulnerabilidades en diversos sistemas operativos. Consiste
en un daemon, nessusd, que realiza el escaneo en el sistema objetivo, y nessus, el cliente (basado en
consola o gráfico) que muestra el avance e informa sobre el estado de los escaneos. Desde consola
nessus puede ser programado para hacer escaneos programados con cron.
En operación normal, nessus comienza escaneando los puertos con nmap o con su propio
escaneador de puertos para buscar puertos abiertos y después intentar varios exploits para atacarlo.
Las pruebas de vulnerabilidad, disponibles como una larga lista de plugins, son escritos en NASL
(Nessus Attack Scripting Language, Lenguaje de Scripting de Ataque Nessus por sus siglas en
inglés), un lenguaje scripting optimizado para interacciones personalizadas en redes.
(Indice)
64. Opcionalmente, los resultados del escaneo pueden ser exportados como informes en varios
formatos, como texto plano, XML, HTML, y LaTeX. Los resultados también pueden ser guardados
en una base de conocimiento para referencia en futuros escaneos de vulnerabilidades.
Algunas de las pruebas de vulnerabilidades de Nessus pueden causar que los servicios o sistemas
operativos se corrompan y caigan. El usuario puede evitar esto desactivando "unsafe test" (pruebas
no seguras) antes de escanear.
Actualmente existen dos versiones: "Home" y "Work" Esta última de pago y sin restricciones.”
de Wikipedia
(Indice)
65. Esta herramienta de auditoria es la más valorada dentro de las auditorias de servicios webs, tiene
una infinidad de plugins para auditar e intentar romper la seguridad de la web.
Si nos fijamos en la imagen hay 3 advertencias en amarillo, que lo que vienen a decir es que el
certificado autofirmado no es una vulnerabilidad como tal pero no se merece la confianza necesaria,
y el otro es debido a la permisividad de compatibilidad con los usuarios con navegadores más
antiguos.
PHPSECINFO:
Este programa nos sirve para auditar el php.ini y la configuración general de php de nuestro
servidor. Es aplicación que muestra la información sobre la seguridad de un código PHP y nos
sugiere ideas para mejorarlo. Ahora hay que dejar claro que no audita propiamente nuestro código
sino que nos ayuda a configurar los cimientos donde se apoyara nuestro código.
11.- Comentarios sobre los clústeres
Quería dedicar un apartado a los clústeres aunque finalmente no lo haya implementado, por
las razones que veremos más adelante, ya que me parece de las tecnologías más importantes dentro
de cualquier sistema informático que sea importante, ya que una buena clusterización nos permite
tanto dar alta disponibilidad como mantener los datos a salvo en caso de falla de alguno de los
sistemas.
¿Por qué no los he introducido al final?
Pese a qué me parece una parte muy importante de un servicio que fuese grande, y debido ha
que aunque hacer funcionar un clúster en Windows es fácil para ciertos servicios como puede ser el
DFS de Windows que con apenas unos clics lo tienes funcionando no pasa lo mismo cuando quieres
implementar una aplicación como MySQL, Apache2 o el servicio de PHP, y lo que más me molesto
ya que yo en un principio quería un proyecto que manejase apache y mysql, pero decidí probar a
(Indice)
66. clusterizar IIS y MSSQL y el resultado fue el mismo, que llegado cierto punto de la clusterización
de estos servicios especiales requieren una configuración de los registros de Windows en cada nodo,
y tienen que ser ademas de todos los cambios generados por dichas aplicaciones
¿Por qué no Linux?
Al principio no quería usar Linux por 2 motivos principales, la implementación de un clúster
básico de Windows es muy sencilla, cosa que no se puede decir lo mismo de las distribuciones de
Linux que he manejado y la segunda era que ya sabía hacer un clúster de Windows.
Después de mucha investigación he concluido que cierto es que para ciertas operaciones
como mantener un servidor DFS y otros servicios concretos de Windows puede resultar muy
cómodo un clúster en Windows, pero para proyectos webs, es indiscutiblemente mejor y más fácil
de implementar al final pese a que hay que usar de medía 3 programas distintos, y un mínimo de 3
equipos, al final una vez bien configurado un clúster de Linux realiza una muy buena labor ya que
por un lado mantiene sincronizada toda la información como que además pueden funcionar como
equipos en solitario, una opción que para ciertas situaciones puede ser muy importante.
Pero el motivo por el que pese haberme documentado sobre estos clústeres llegue a la
conclusión que si quería un clúster en Linux, que a su vez fuese seguro, no me daba tiempo material
a realizarlo, ya que como muchas cosas en Linux pese a que se puede hacer todo hay que hacerlo
sin ningún tipo de asistente ni script rápido por lo que para hacer un clúster que no sea funcional al
100% he decidido apartarlo del proyecto.
12.- Comentarios generales.
En mi opinión personal este proyecto me ha ayudado a ver una serie de cosas como la
clusterización en Linux o la importancia de usar $_POST en lugar de $_GET para el tratamiento de
las peticiones sean seguras a la hora del desarrollo web, la infinidad de opciones que nos da php, y
su facilidad de uso e implementación.
También me ha generado inquietudes sobre la seguridad en la web y la facilidad que hay de
generar vulnerabilidades en un servidor que este mal configurado, pese a que se que para terminar
de fortificar este servidor habría que hacer una buena configuración de IPTables.
El proyecto en general me ha gustado mucho al realizarlo debido a que en el fondo se que es
la base de muchos juegos online, obviamente aun le faltaría mucho trabajo para poder llevarlo a un
ambiente de producción pero se que son unos buenos cimientos sobre los que poder empezar a
trabajar algo de un nivel más serio.
(Indice)