Instalar nginx en centos 7

2018/05/04

Instalar nginx en centos 7

Los otros días tuve que crear un servidor para servir un mirror de los paquetes de ubuntu 18.04.

Se utilizará Centos 7 para el servidor, instalandolo a partir del DVD ISO. La mayoría de las opciones se dejarán por defecto, eligiendose la opción Minimal Install para el entorno base y sin addons.

Ya con el sistema instalado empieza la diversión:

Se actualiza el sistema y se instala nginx. Ya que nginx no se encuentra en los repositorios de centos, se utilizará el repositorio EPEL - Extra Packages for Enterprise Linux:

(Nota: los comandos serán ejecutados con usuario root):

yum -y update
yum -y install epel-release
yum -y update
yum -y install nginx

Se habilita e inicia nginx a nivel de sistema (servicio de systemd), ya que inicialmente está deshabilitado:

systemctl enable nginx.service
systemctl start nginx.service

Se utiliza curl 127.0.0.1 en el sistema para corroborar que se está sirviendo contenido (la página por defecto configurada por el paquete).

En mi configuración particular los archivos se van a servir de /srv/www, por lo que se crea la siguiente configuración de nginx:

cat <<'END' > /etc/nginx/conf.d/my-mirror.example.com.conf
server {
    listen 80;
    server_name my-mirror.example.com;
    root /srv/www;
    autoindex on;
}
END

Se utiliza el directorio /srv/www ya que los archivos servidos por nginx se encontrarán en otro disco y tiene sentido según las Filesystem Hierarchy Standard de linux.

Ya que es un mirror y solo se servirán archivos, se encuentra útil habilitar la opción autoindex, para listar el contenido de los directorios.

Se reinicia nginx mediante systemctl restart nginx.service y cuando se intenta acceder mediante curl my-mirror.example.com no se devuelve nada. Se busca en los logs /var/log/nginx/access.log y /var/log/nginx/error.log y nada. Una búsqueda rápida en internet y me doy cuenta que había olvidado que Centos 7 tiene habilitado el firewall por defecto.

Se desactiva el firewall:

firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https
firewall-cmd --reload

Ahora curl nuevamente y se obtiene: 404 Not Found.

Se busca en el log de error y se encuentra:

... [error] 11414#0: *3 open() "/srv/www/mirror" failed (13: Permission denied), ...

Despues de buscar un rato más (nuevamente internet), si, Centos 7 también tiene por defecto selinux en estado Enforcing:

# getenforce
Enforcing

Buscando las reglas de selinux

# grep -r '/srv.*www' /etc/selinux
/etc/selinux/targeted/contexts/files/file_contexts:/srv/([^/]*/)?www(/.*)?	system_u:object_r:httpd_sys_content_t:s0
/etc/selinux/targeted/contexts/files/file_contexts:/srv/([^/]*/)?www/logs(/.*)?	system_u:object_r:httpd_log_t:s0
Binary file /etc/selinux/targeted/contexts/files/file_contexts.bin matches
/etc/selinux/targeted/active/file_contexts:/srv/([^/]*/)?www(/.*)?	system_u:object_r:httpd_sys_content_t:s0
/etc/selinux/targeted/active/file_contexts:/srv/([^/]*/)?www/logs(/.*)?	system_u:object_r:httpd_log_t:s0

se encuentra que el directorio /srv/www ya está incluido, pero los archivos que se encuentran allí fueron copiados de otro sistema mediante rsync, por lo cual hay que reestablecer los contextos de selinux:

restorecon -R /srv/www

NOTA: si se utiliza un directorio distinto de /srv/www que no tenga un contexto de selinux asociado (ejemplo /srv/my-files), el comando restorecon no hará nada. La alternativa es agregar primero los archivos a selinux y recién despues utilizar restorecon.

También se agrega un acl para que el usuario nginx puede acceder los archivos, ya que es posible que los archivos tengan otro usuario (el utilizado para copiarlos al sistema):

setfacl -R -m u:nginx:rx /srv/www

Ahora si, haciendo curl my-mirror.example.com se obtiene un listado del directorio.

En resumen; en un Centos 7 con los archivos que se quieren servir en /srv/www hacer:

  1. Descargar los archivos:

  2. Ejecutar en el servidor como root:

    # export SERVER_DOMAIN=my-mirror.example.com
    # export ROOT_DIRECTORY=/srv/www
    # ./provision-nginx.sh
    # ./fix-permissions-srv-www.sh
    

Referencias: