{{tag>nginx troubleshooting webserver ssl}} ====== Nginx troubleshooting ====== ===== upstream SSL certificate verify error: (21:unable to verify the first certificate) while SSL handshaking to upstream ===== Happened when connecting to upstream server using the [[wiki:proxy_pass_nginx_connection_using_self_signed_certificates|self-signed]] certificate. Workaround can be to set ''proxy_ssl_verify'' nginx directive to **off**; Better option is to add the correct certificates in the file pointed to by //proxy_ssl_trusted_certificate// directive. The file should contain in order, server.crt (and probably any intermediary cert if you have it) then rootCA, e.g. ///etc/ssl/certs/trusted_ca_cert.crt// -----BEGIN CERTIFICATE----- ... server.crt data ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... rootCA cert data ... -----END CERTIFICATE----- ==== Tested on ==== * nginx/1.23.0 ===== nginx seems to serve from wrong vhost? ===== When you visit one site let's say a.example.com and you get b.example.com, pay attention to following aspects: * it could be that the //server_name// is not defined or there's a typo * pay attention to http vs. https and redirects; if you get redirected from http to https and this is not what you want, redirect could be done by some proxied app (for example wordpress might do this via its WP_HOME and WP_SITEURL variables) and then the request will happen to 443 port on which nginx will serve the first vhost that is listening on this port and the //server_name// matches, so if your b.example.com vhost does not listen on 443 as well you might get the configuration from some other vhost which does listen on 443 which will confuse you. * Also listen directive gives precedence to IP:PORT than to only PORT, so nginx might serve for example wrong certificates (i.e. self-signed ones) if there is a config like listen 1.2.3.4:443 ssl; server_name de_verticals_upstream; ssl_certificate /etc/ssl/server.crt; ... and somewhere else you have ... listen 443 ssl; ... ===== Location matching when serving content ===== Remember that nginx will first match blocks defined with regular expressions(''~'' and ''~*'') and then serve prefix locations (''/somelocation''). Example config: server { # port 80 will be matched by default server_name example.org; location ~*/ { rewrite ^/(.*)$ https://www.example.org/$1 permanent; } # Letsencrypt challenge location location /.well-known { return 301 http://letsencrypt.example.org$request_uri; } } The request for https://www.example.org/.well-known will result in nginx serving the first location (one with the rewrite) because even though the second one is also evaluated, first one with regex also matches the ///.well-known// path. If it didn't match the second one would be served. Solution to this would be to use either strict matching ''='' or, in this letsencrypt example, a more valid modifier of ''^~'' which will stop regex processing and return immediately. So example would be: # Letsencrypt challenge location location ^~ /.well-known { return 301 http://letsencrypt.example.org$request_uri; } So modifier priority matching is as follows: 1. `=` Exact match, terminate immediately 2. `^~` Longest-prefix-match (not regex!) 3. `~`, `~*` Regular expression case sensitive/insensitive 4. `/` Longest-prefix-match If you are using the grouping of URIs in parenthesis e.g. location ^~ /(.well-known|pathA|otherslug) This won't work. Use the `~*` modifier for that. ==== Tested on ==== * nginx/1.23.1 ====== See also ====== * [[wiki:proxy_pass_nginx_connection_using_self_signed_certificates|Proxy pass nginx connection using self-signed certificates]] * [[wiki:proxy_non_http_traffic_through_nginx|Proxy non-http traffic through nginx]] * [[wiki:nginx_redirect_rewrites|Example of redirect and rewrites]] * [[wiki:avoid_upstream_not_found_nginx_using_only_one_server|Avoid upstream not found in nginx when using only one upstream server]] ====== References ====== * [[https://serverfault.com/a/1112127/353235|Location block matching - SO]] * https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms