con nginx reescribiendo la URL base a https

con nginx reescribiendo la URL base a https

Me gustaría que solo se reescribiera mi dominio base www.dominio.comhttps://www.dominio.com De forma predeterminada, en mi bloque https lo redirecciono a http:// si no es ~uri = "/" (dominio base) o contenido estático.

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

Entonces, en mi bloque http necesito reescribirlo si es necesario https:

server {
  listen              80;
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

Si no tengo la declaración if $uri = '/' en el bloque http, entonces https funciona bien si voy directamente a él, pero no seré redirigido si voy al http normal, como se espera. Si pongo esa declaración en el bloque http, todo dejará de funcionar en cuestión de minutos. Puede que funcione para algunas solicitudes, pero siempre se detendrá en aproximadamente un minuto. En los navegadores aparece una página en blanco para todas las solicitudes. Si reinicio nginx, seguirá sin funcionar hasta que elimine ambos bloques de sentencias if en los bloques https y http y reinicie nginx. Cuando miro los registros de errores, no veo nada registrado. Cuando miro en el registro de acceso veo este mensaje:

"-" 400 0 "-" "-"

lo que supongo significa un error 400. No entiendo por qué esto no funciona para mí. Mi objetivo final es que el dominio base sea solo https mientras que todas las demás páginas tienen por defecto http. ¿Cómo puedo conseguir esto?

Respuesta1

Terminé cambiando $uri a $request_uri para que los argumentos puedan manejarse sin bucles de redireccionamiento.

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($request_uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

Luego cambié el bloque http para hacer una reescritura inmediata si la ubicación era =/

server {
  listen              80;
  location = / {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

Todavía tengo las declaraciones IF para manejar otras reescrituras y luego toda la publicación específica se realiza debajo de ellas. Probablemente sea solo mi configuración específica la que genera bucles de redireccionamiento y errores cuando intento manejar todo como sugirió Christopher o como lo presenté originalmente en mi pregunta.

Respuesta2

No necesitas todas las declaraciones if. Deberías trabajar con declaraciones de ubicación.

server {
    listen              80;
    #rewrite base (/) to ssl
    location = / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }

    #serve anything else
    location / {
        [serve non-ssl page ...]
    }
}

server {
    listen              443;

    #serve base url
    location = / {
        [serve ssl page ...]
    }

    #serve assets
    location ~ ^/(img|js|css|static)/ {
        [serve ssl assets ...]
    }

    #rewrite anything else
    location / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }
}

Esto no está probado y puede contener errores, pero debería funcionar.

información relacionada