Nginx sigue lanzando nginx: [emerg] bind() a 0.0.0.0:80 falló (98: dirección ya en uso)

Nginx sigue lanzando nginx: [emerg] bind() a 0.0.0.0:80 falló (98: dirección ya en uso)

He estado revisando muchos sitios web y tengo muchas preguntas/respuestas aquí en ServerFault sobre este problema. Sin embargo, parece que no logro llegar a la raíz del error de configuración.

Tengo 4 dominios en mi servidor nginx:

  • example.com
  • www.example.com
  • api.example.com
  • blog.example.com

Todos están en funcionamiento, tanto en los puertos 80 como en 443. Esta es la plantilla que utilicé nginx.confpara todos ellos, cambiando solo las directivas server_name, y . Hay algunos otros cambios, pero en principio no deberían afectar. Como diferente .rooterror_logaccess_logfastcgi_param

Esta es la plantilla para example.comy www.example.com:

server {
listen 80;

server_name example.com www.example.com;
root /var/www/example.com/public_html/web;

if ($http_host = example.com) {
    return 301 https://www.example.com$request_uri;
}

location / {
    # try to serve file directly, fallback to front controller
    try_files $uri /index.php$is_args$args;
}

location ~ ^/index\.php(/|$) {
    fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;

    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS off;
    fastcgi_param   DATABASE_NAME           some_database;
    fastcgi_param   DATABASE_USER           some_user;
    fastcgi_param   DATABASE_PASSWORD       some_pwd;
}

#return 404 for all php files as we do have a front controller
location ~ \.php$ {
    return 404;
}

error_log /var/log/nginx/www.example.com_error.log;
access_log /var/log/nginx/www.example.com_access.log;

# Redirect non-https traffic to https
if ($scheme != "https") {
    return 301 https://$host$request_uri;
} # managed by Certbot


listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

Y este es exactamente el error que recibo cuando reinicio el servidor:

root@vps_server:/etc/nginx# journalctl -xe
Mar 09 09:17:16 vps_server systemd[1]: Starting A high performance web server and a reverse proxy server...
-- Subject: Unit nginx.service has begun start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Unit nginx.service has begun starting up.
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] still could not bind()
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Control process exited, code=exited status=1
Mar 09 09:17:18 vps_server systemd[1]: Failed to start A high performance web server and a reverse proxy server.
-- Subject: Unit nginx.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Unit nginx.service has failed.
-- 
-- The result is failed.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Unit entered failed state.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Failed with result 'exit-code'.

Cuando intento renovar los certificados usando sudo certbot renew --dry-runobtengo un error similar, aunque no exactamente el mismo.

Si elimino los subprocesos de nginx, podré reiniciar el servidor. Pero la próxima vez que intento reiniciarlo, arroja el mismo error. Y lo peor es que no consigo renovar mis certificados SSL (aunque eso podría deberse a otro motivo y no me gustaría ponerlo aquí, ya que este podría ser el motivo).

EDITAR

Configuré una máquina local usando Vagrant con exactamente la misma configuración, excepto que comenté los datos de los certificados SSL. Puedo reiniciar el servidor sin problemas. Entonces quizás tenga algo que ver con la configuración de Certbot/SSL.

Para ayudar con la depuración de este problema, aquí está el resultado de netstat -tulpn(solo nginx usa los puertos 80 y 443, que es el resultado esperado, según tengo entendido):

/var/log/nginx# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      16700/mysqld        
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      1578/systemd-resolv 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      30608/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1675/sshd           
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      10001/master        
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      30608/nginx: master 
tcp6       0      0 :::5355                 :::*                    LISTEN      1578/systemd-resolv 
tcp6       0      0 :::22                   :::*                    LISTEN      1675/sshd           
tcp6       0      0 :::25                   :::*                    LISTEN      10001/master        
udp        0      0 127.0.0.53:53           0.0.0.0:*                           1578/systemd-resolv 
udp        0      0 0.0.0.0:68              0.0.0.0:*                           1343/dhclient       
udp        0      0 0.0.0.0:5355            0.0.0.0:*                           1578/systemd-resolv 
udp6       0      0 :::5355                 :::*                                1578/systemd-resolv

Respuesta1

¿Cómo es tu nginx.confapariencia? Supongo que no ha cambiado la configuración, tal vez simplemente agregó el gzip y una nueva carpeta de inclusión para tener una ubicación separada para los sitios web. Para cada uno de sus dominios/subdominios, tenga un archivo de configuración separado. Como:

  • example.com&www.example.com
  • api.example.com
  • blog.example.com

Esto se debe a que supongo que se trata de sitios web separados bajo el mismo dominio. Si están en el mismo sitio web y son solo una de las llamadas subpáginas, entonces sería mejor crear solo subpáginas con las opciones de ubicación.

Para reorganizar su nginxconfiguración, crearía un com.example.confarchivo con 3 secciones de servidor separadas. Lo primero es redirigir a los usuarios que no son www al sitio web www:

server {
    listen       80;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

server {
    listen       443 ssl;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

La tercera sección contendría el sitio principal:

server {
    listen 443 ssl;

    server_name example.com www.example.com;

    root /var/www/example.com/public_html/web;

    index    index.php;

    error_log /var/log/nginx/www.example.com_error.log;
    access_log /var/log/nginx/www.example.com_access.log;

    location / {
        # try to serve file directly, fallback to front controller
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
        fastcgi_param   DATABASE_NAME           some;
        fastcgi_param   DATABASE_USER           some_user;
        fastcgi_param   DATABASE_PASSWORD       some_pwd;
    }

    location ~ \.php$ {
        return 404;
    }
}

(Tengo que decir que tu parte fastcgi en tu ubicación index.php me parece extraña, pero te lo dejo a ti)

Luego cree archivos de configuración separados como com.example.api.confy com.example.blog.conf. Agregue las dos primeras secciones de la configuración anterior de manera similar a como antes, luego puede agregar cada subdominio una configuración diferente para las ubicaciones.

Por ejemplo, tengo esto para mis sitios web de Laravel:

rewrite ^/index\.php?(.*)$ /$1 permanent;

location / {
        try_files $uri @rewrite;
}

location        @rewrite {
        rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index.php(/|$) {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_read_timeout 299;
}

Espero que esto te ayude, si no, comenta tus preguntas.

Respuesta2

Para arreglar el bind() a 0.0.0.0:80 o 443 falló (98: dirección ya en uso)

Ejecute los siguientes comandos:

sudo pkill -f nginx & wait $!

sudo systemctl start nginx

Respuesta3

Finalmente he resuelto el problema. Parecía que IPV6 está habilitado en el servidor y requería que la configuración de nginx fuera ligeramente diferente.

En lugar de usar esto:

listen 80;
listen 443 ssl;

Tuve que usar lo siguiente:

listen [::]:80;
listen [::]:443 ssl;

En este sitio web obtuve una explicación más precisa y detallada:https://chrisjean.com/fix-nginx-emerg-bind-to-80-failed-98-address-already-in-use/

Lo curioso es que mi error fue:

nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)

en lugar de lo descrito (en la URL que proporcioné):

nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)

Sin embargo, esto solucionó el problema y pude reiniciar el servidor nginx sin ningún problema.

El servidor vagabundo que había configurado no tenía IPV6 habilitado, por lo que podría tener algo que ver con el hecho de que no se comportaba de la misma manera.

información relacionada