Configuración de un servidor de instalación en Solaris

sysadmin 0 comentarios »

De vez en cuando me toca instalar alguna máquina Solaris que o bien no tiene unidad de CD/DVD o bien yo no tengo acceso físico a la máquina. En estos casos suele ser útil montar un servidor de instalación, o servidor JumpStart, en otra máquina e instalar la máquina en cuestión por red.

jumpstart

El servidor de instalación como tal es realmente una parte de lo que se denomina servidor JumpStart. JumpStart es un framework, incluido con Solaris, que nos permite la instalación automatizada de máquinas. Aunque hablemos de servidor JumpStart, realmente existen 3 servidores diferentes, que normalmente estarán en la misma máquina:

  • servidor de arraque
  • servidor de instalación
  • servidor de configuración

Si lo único que queremos es instalar una máquina, pero no tiene unidad de CD/DVD o no tenemos acceso físico a la máquina, nos podemos ahorrar configurar el servidor de configuración. La instalación de la máquina será interactiva, es decir, tendremos que ir respondiendo a las típicas preguntas del proceso de instalación de Solaris. Si tuvieramos que instalar muchas máquinas entonces sí que merecería la pena configurar el servidor de configuración.

En las siguientes indicaciones os cuento cómo configurar un servidor de instalación y de arranque en la misma máquina. Supondré además que están en la misma subred que la máquina a instalar, ya que en el arranque por defecto se utiliza RARP, que no es enrutable. En el caso de que el servidor de instalación y la máquina a instalar estuvieran en subredes diferentes hay que acudir a configuraciones más avanzadas.

Configuración del servidor de instalación

Creamos el directorio donde vamos a crear la imagen de Solaris que vamos a utilizar y lo compartimos por NFS. Podríamos tener diferentes imágenes de Solaris para diferentes grupos de máquinas. Supongamos que este directorio es /export/jumpstart y que vamos crear una imagen para la versión 10/08 de Solaris 10.

# mkdir -p /export/jumpstart/Solaris10_10_08
# cat >> /etc/dfs/dfstab
share -o ro,anon=0 /export/jumpstart
[Ctrl+D]
# shareall
# dfshares

Ahora creamos la imagen propiamente dicha. Supongamos hemos introducido el DVD de Solaris 10 y que está montado en /cdrom/cdrom0.

# cd /cdrom/cdrom0/Solaris_10/Tools
# ./setup_install_server /export/jumpstart/Solaris10_10_08

Con esto ya tendríamos configurado el servidor de instalación.

Configuración del servidor de arranque

Ahora nos queda el servidor de arranque. Para ello vamos a suponer que la IP del servidor de instalación es la 10.0.0.1, que la máquina a instalar se va a llamar abedul, su IP va a ser la 10.0.0.2 y que su dirección MAC es la 8:0:20:ff:ff:ff.

Primeramente, en el servidor, tendríamos que añadir una entrada para el cliente, abedul, en el /etc/hosts.

Después ejecutamos:

# cd /export/jumpstart/Solaris10_10_08/Solaris_10/Tools
# ./add_install_client -i 10.0.0.2 -e 8:0:20:ff:ff:ff \
-s 10.0.0.1:/export/jumpstart/Solaris10_10_08 abedul sun4u

Este comando tiene mucha magia por detrás. Nos deja listos los demonios in.rarpd (RARP), rpc.bootparamd (BOOTP) e in.tftpd (TFTP). Ahora ya podremos hacer en la máquina a instalar:

ok boot net - install

De manera que nos acabará apareciendo, después del arranque por red, el proceso de instalación interactiva de Solaris.

Enlaces recomendados


Dan Kaminsky habla sobre la vulnerabilidad de DNS

sysadmin 1 comentario »

Hace varias semanas Dan Kaminsky descubrió una grave vulnerabilidad en el protocolo DNS. En la conferencia de seguridad BlackHat que se acaba de celebrar, Dan ha contado los detalles de dicha vunerabilidad. Su ponencia ha sido muy interesante. Las conclusiones a las que llega se pueden resumir en los siguientes puntos:

  • La infraestructura DNS estaba expuesta a una grave vulnerabilidad.
  • La investigación en seguridad está entrando en una nueva era, ya que las aplicaciones están sumamente interrelacionadas a través de internet.
  • La actualización de aplicaciones online puede verse comprometida debido a la vulnerabilidad de DNS. Por ejemplo, un atacante podría hacerse pasar por el sitio del cual nos descargamos las actualizaciones del sistema operativo.
  • SSL no aporta mucho, ya que en última instancia la cadena de autoridades certificadoras depende de DNS.
  • Las redes internas tampoco están totalmente a salvo, ya que siempre acaba habiendo alguna dependencia con el exterior.

Ha sido publicado también un curioso video elaborado por Clarified Networks en el que puede verse cómo se ha propagado la instalación del parche en los servidores DNS:

Rojo — Sin parchear
Amarillo — Parcheado, pero el NAT embrolla las cosas
Verde — OK


Rails en producción - Parte 6 - Cluster de mongrels

ruby, rails, sysadmin 4 comentarios »

Ya sólo nos queda configurar un cluster de mongrels y apuntar hacia ellos el servidor web nginx. Supongamos que vamos a arrancar 4 mongrels, tal y como representamos en la figura de la primera parte parte de este tutorial. Los mongrels escucharán en los puertos 8000 a 8003.

Para configurar el cluster hacemos:

$ mongrel_rails cluster::configure -e production -p 8000 -N 4 -c /var/miaplicacion/current -a 127.0.0.1
** Ruby version is not up-to-date loading cgi_multipart_eof_fix
Writing configuration file to config/mongrel_cluster.yml.

Este comando habrá creado el fichero config/mongrel_cluster.yml. Lo editamos y añadimos al final sendas líneas indicando el usuario y el grupo que ejecutarán los mongrels. Como ya indicamos, será un usuario no privilegiado el que ejecute tanto el servidor web como los mongrels:

cwd: /var/www/miaplicacion/current
log_file: log/mongrel.log
port: "8000"
environment: production
address: 127.0.0.1
pid_file: tmp/pids/mongrel.pid
servers: 4
user: usuario
group: usuario

Añadiremos el cluster de mongrels al arranque de la máquina:

sudo mkdir /etc/mongrel_cluster
sudo ln -s /var/www/miaplicacion/current/config/mongrel_cluster.yml /etc/mongrel_cluster/miaplicacion.yml
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d
sudo chmod +x /etc/init.d/mongrel_cluster
sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults
sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby

Y ya podremos arrancar y parar el cluster de mongrels:

$ sudo /etc/init.d/mongrel_cluster start
$ sudo /etc/init.d/mongrel_cluster stop

Ahora sólo nos queda apuntar el servidor web nginx a los mongrels. Para ello, editaremos el fichero /usr/local/nginx/conf/nginx.conf. Éste es un ejemplo básico del cual podemos partir.

user              miusuario miusuario;
worker_processes  4;
 
events {
    worker_connections  1024;
}
 
http {
    include           mime.types;
    default_type      application/octet-stream;
    sendfile          on;
    keepalive_timeout 65;
    gzip              on;
 
    upstream miaplicacion {
        server 127.0.0.1:8000;
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;
        server 127.0.0.1:8003;
    }
 
    server {
        listen       80;
        server_name  midominio.com;
 
        root   /var/www/miaplicacion/current/public;
        index  index.html;
 
        location / {
          proxy_set_header  X-Real-IP  $remote_addr;
          proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host;
          proxy_redirect false;
 
          if (-f $request_filename/index.html) {
            rewrite (.*) $1/index.html break;
          }
 
          if (-f $request_filename.html) {
            rewrite (.*) $1.html break;
          }
 
          if (!-f $request_filename) {
            proxy_pass http://miaplicacion;
            break;
          }
        }
 
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

En la sección “upstream” apuntamos hacia los mongrels. En ella, “miaplicacion” es una etiqueta, la misma que usamos más abajo en la línea:

proxy_pass http://miaplicacion;

En la sección “server” cabe destacar que “root” apunta al directorio public de mi aplicación.

Rearrancamos nginx para que la nueva configuración surta efecto:

$ sudo /etc/init.d/nginx stop
$ sudo /etc/init.d/nginx start

Y ahora sí, por fin, tenemos que poder abrir desde nuestro navegador la URL:

http://midominio.com/

y acceder a nuestra aplicación. Si no tenemos configurado todavía la entrada en DNS, tendremos que poner la IP.

Como una última prueba, probaremos una vez más a rearracar la máquina y ver que todo arranca correctamente.

Tutorial completo


Rails en producción - Parte 5 - Mongrel e instalación de nuestra aplicación

ruby, rails, sysadmin 0 comentarios »

Mongrel

Mongrel será el encargado de atender las peticiones HTTP que lleguen del servidor web y ejecutar nuestra aplicación en el intérprete de Ruby.

Para instalar mongrel simplemente haremos:

$ sudo gem install mongrel mongrel_cluster --include-dependencies --no-rdoc --no-ri

Instalación de nuestra aplicación

Supondré que tenemos nuestra aplicación en un repositorio de subversion. En este caso, antes de poder hacer un export de la aplicación desde el repositorio, necesitaré instalar subversion:

$ sudo aptitude install subversion -y

Ahora ya podré transferir una copia de mi aplicación al servidor de producción. Supondré que la aplicación la vamos a instalar, por ejemplo, en /var/www/miaplicacion/current.

$ sudo chown usuario:usuario /var/www
$ mkdir /var/www/miaplicacion
$ cd /var/www/miaplicacion
$ svn export http://svn.midominio.com/miaplicacion/trunk current

Necesitamos crear una base de datos para la aplicación:

$ mysql --user=root -p
mysql> grant all on miaplicacion_production.* to miaplicacion@localhost identified by 'miaplicacion';
mysql> flush privileges;
mysql> create database miaplicacion_production;

Es decir, hemos creado una base de datos llamada “miaplicacion_production” y un usuario “miaplicacion”, con idéntica password, que dispone de todos los permisos en “miaplicacion_production”.

Normalmente, tendremos que configurar el fichero config/database.yml de nuestra aplicación para que apunte a la base de datos que acabamos de crear:

production:
  adapter: mysql
  database: miaplicacion_production
  username: miaplicacion
  password: miaplicacion
  socket: /var/run/mysqld/mysqld.sock
  host: localhost
  encoding: utf8

Antes de poder arrancar nuestra aplicación deberemos instalar todas las gemas que utilicemos y que no hayamos instalado. Si no nos acordamos podemos intentar arrancar la aplicación y ver los errores. Leyendo el log de errores suele ser fácil identificar si nos falta alguna gema. Una que siempre viene bien será:

$ sudo gem install rake

Hay que tener en cuenta que si no especificamos la versión, gem install instalará la última versión disponible en el repositorio. Esto quiere decir que en el entorno de desarrollo y en el de test, si instalamos las gemas hace tiempo, las versiones pueden ser inferiores, y por lo tanto, nos podemos encontrar con problemas de compatibilidad. Para ver las gemas instaladas en una máquina y sus versiones podemos ejecutar:

$ gem list

Ahora ya puedo arrancar mi aplicación. De momento, para probar, arrancaremos un único proceso mongrel. Todavía no hemos configurado el servidor web para que apunte a los mongrels, así que no podremos comprobar con un navegador que funciona. Simplemente, veremos que arranca correctamente leyendo el fichero log/production.log:

$ cd /var/www/miaplicacion/current
$ mongrel_rails start -d -e production -p 8000 -P log/mongrel8000.pid

Si en el fichero de log vemos que la aplicación ha arrancado, podríamos incluso comprobar que sirve peticiones:

$ cd
$ wget http://localhost:8000/

Esto me guardaría en el directorio raíz del usuario un fichero llamado index.html con el HTML de la página raíz de mi aplicación. En el fichero de log debería poder ver la petición. ¿Quién necesita un browser?

En el último capítulo configuraremos un cluster de mongrels y apuntaremos el servidor web hacia ellos. Por eso, ahora, paramos el mongrel que hemos arrancado como prueba:

$ mongrel_rails stop -P log/mongrel8000.pid

Tutorial completo


Rails en producción - Parte 4 - Servidor web nginx

ruby, rails, sysadmin 1 comentario »

El servidor web que vamos a utilizar es nginx. Lo instalaremos compilando el código fuente de la última versión estable. Yo he utilizado la versión 0.6.32.

Primeramente, instalaremos varios paquetes de debian que son necesarios:

$ sudo aptitude install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev

En el directorio sources que creamos anteriormente para compilar Rubygems, nos descargamos nginx y hacemos el configure con la opción with-http_ssl_module:

$ sudo aptitude install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev
$ cd ~/sources
$ wget http://sysoev.ru/nginx/nginx-0.6.32.tar.gz
$ tar xvf nginx-0.6.32.tar.gz 
$ cd nginx-0.6.32
$ ./configure --with-http_ssl_module

La salida del configure es muy extensa. Al final nos aparecerá un resumen con el path de los ejecutables y los ficheros de configuración:

Configuration summary
  + using system PCRE library
  + OpenSSL library is not used
  + md5 library is not used
  + sha1 library is not used
  + using system zlib library
 
  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "/usr/local/nginx/client_body_temp"
  nginx http proxy temporary files: "/usr/local/nginx/proxy_temp"
  nginx http fastcgi temporary files: "/usr/local/nginx/fastcgi_temp"

Después del configure, ejecutamos make para compilar y make install para instalar:

$ make
$ sudo make install

Para probar que funciona arrancamos el demonio:

$ sudo /usr/local/nginx/sbin/nginx

Esto habrá arrancado el servidor web en el puerto 80. En un navegador podemos teclear la URL:

http://IP/

Siendo IP, claro está, la IP de nuestro servidor. Nos deberá aparecer la página de bienvenida a nginx.

Paramos el proceso que hemos arrancado:

$ sudo kill `cat /usr/local/nginx/logs/nginx.pid`

Creamos el fichero de arranque de nginx /etc/init.d/nginx con el siguiente contenido:

#! /bin/sh
 
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO
 
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx
 
test -x $DAEMON || exit 0
 
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi
 
set -e
 
case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
                --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
                --exec $DAEMON
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /usr/local/nginx/logs/nginx.pid --exec $DAEMON
        sleep 1
        start-stop-daemon --start --quiet --pidfile \
                /usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  reload)
      echo -n "Reloading $DESC configuration: "
      start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
          --exec $DAEMON
      echo "$NAME."
      ;;
  *)
        N=/etc/init.d/$NAME
        echo "Usage: $N {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac
 
exit 0

Le damos permisos de ejecución y lo añadimos al arranque de la máquina:

$ sudo chmod +x /etc/init.d/nginx
$ sudo /usr/sbin/update-rc.d -f nginx defaults

Editamos el fichero de configuración /usr/local/nginx/conf/nginx.conf. El usuario encargado de ejecutar nginx será el usuario no privilegiado que hemos creado anteriomente. También podemos ajustar el número de procesos que atenderán peticiones:

user              usuario usuario;
worker_processes  4;

Para arrancarlo y pararlo ya podemos hacer:

$ sudo /etc/init.d/nginx start
$ sudo /etc/init.d/nginx stop

Tutorial completo