{"id":13641717,"url":"https://github.com/ViRb3/nginx-gotchas","last_synced_at":"2025-04-20T11:31:49.414Z","repository":{"id":83273738,"uuid":"213631767","full_name":"ViRb3/nginx-gotchas","owner":"ViRb3","description":"⁉ My personal list of gotchas and other tricky situations with nginx","archived":false,"fork":false,"pushed_at":"2024-02-16T11:29:06.000Z","size":5,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-07T19:54:44.223Z","etag":null,"topics":["bugs","common","gotchas","mistakes","nginx","pitfalls","tricks"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ViRb3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-08T12:07:59.000Z","updated_at":"2024-06-06T12:09:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"75ddeca8-33d6-4c27-83c1-ebabbfad0e7e","html_url":"https://github.com/ViRb3/nginx-gotchas","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViRb3%2Fnginx-gotchas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViRb3%2Fnginx-gotchas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViRb3%2Fnginx-gotchas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViRb3%2Fnginx-gotchas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ViRb3","download_url":"https://codeload.github.com/ViRb3/nginx-gotchas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223827579,"owners_count":17209809,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bugs","common","gotchas","mistakes","nginx","pitfalls","tricks"],"created_at":"2024-08-02T01:01:23.408Z","updated_at":"2024-11-09T12:30:53.782Z","avatar_url":"https://github.com/ViRb3.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Nginx Gotchas\n\n## [Official pitfalls and common mistakes](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/)\n\n## SSL best practices\n- ### [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/)\n- ### [Bettercrypto](https://bettercrypto.org/#_nginx)\n- ### [Cipherli.st](https://cipherli.st/)\n\n## Directive matching order\n- ### [DigitalOcean article](https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms)\n  - #### `server_name`\n    - \u003e ... If none of the above steps are able to satisfy the request, then the request will be passed to the `default_server` for the matching IP address and port.\n    - If no `default_server` is specified, the **first** server block will be chosen\n\n## MIME type detection\n- ### `alias`, `proxy_pass` and jumps won't recognize the destination MIME type. You need an explicit `default_type`:\n    ```nginx\n    location /cv {\n        default_type text/html;\n        alias /etc/nginx/cv.html;\n    }\n    ```\n\n## Snippets\n### Jump location block\n\u003e The order of execution for each approach is different, test which works for your use case.\n```nginx\nlocation /example1 {\n    ...\n    try_files /dev/null @login;\n}\n\nlocation /example2 {\n    ...\n    error_page 404 = @login;\n    return 404;\n}\n\nlocation @login {\n    internal;\n    ...\n}\n```\n\n### Access `http` block from `.config` file\n```nginx\n# will go in parent (http) block\nlimit_req_zone $binary_remote_addr zone=userlimit:10m rate=1r/s;\n\nserver {\n    ...\n}\n```\n\n### Reverse proxy\n```nginx\n# pass proper hostname\nproxy_set_header Host $http_host;\nproxy_set_header X-Forwarded-Host $http_host;\n# pass proper client IP\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\nproxy_set_header X-Real-IP $remote_addr;\n# pass proper protocol\nproxy_set_header X-Forwarded-Proto $scheme;\n\n# don't automatically fix \"location\" and \"redirect\" headers\nproxy_redirect off;\nproxy_buffering off;\n\nproxy_pass ...; \n```\n\n### Rate limit\n```nginx\nlimit_req_status 403;\nlimit_req zone=serverlimit burst=10 nodelay;\nlimit_req zone=userlimit burst=5 nodelay;\n```\n\n### Disable search engine crawling\n```nginx\nlocation = /robots.txt {\n    add_header Content-Type text/plain;\n    return 200 \"User-agent: *\\nDisallow: /\\n\";\n}\n```\n\n### Cookie-based auth proxy\n```nginx\nauth_request /auth;\n\n# pass auth cookie to client\nauth_request_set $saved_set_cookie $upstream_http_set_cookie;\nadd_header Set-Cookie $saved_set_cookie;\n\n# use = to take precedence over other ~ locations\nlocation = /auth {\n    internal;\n    proxy_pass_request_body off;\n    proxy_set_header Content-Length \"\";\n    proxy_set_header X-Original-URI $request_uri;\n    # the \"reverse proxy\" section discussed before\n    include reverse-proxy.conf;\n\n    # don't pass request headers\n    # e.g. If-Modified will result in 412\n    proxy_pass_request_headers off;\n    # only pass the required\n    proxy_set_header Authorization $http_Authorization;\n    proxy_set_header Cookie $http_cookie;\n\n    proxy_pass https://auth.example.com; \n}\n```\n\n### Don't respond if invalid URL\n```nginx\nerror_page 404 403 @putoff;\n\nlocation @putoff {\n    return 444;\n}\n\nlocation / {\n    error_page 418 @putoff;\n    return 418;\n}\n```\n### `proxy_pass` trailing slash ([Source](https://stackoverflow.com/questions/22759345/nginx-trailing-slash-in-proxy-pass-url))\n- No URI (i.e. `http://server:1234`) will forward the URI from the original request exactly as it was with all double slashes, `../` and so on\n-  With URI (i.e. `http://server:1234/a/`) acts like the `alias` directive, meaning nginx will replace the part that matches the location prefix with the URI in the `proxy_pass` directive. For example:\n    ```nginx\n    location /one/ {\n        proxy_pass http://127.0.0.1:8080/two;\n    }\n    ```\n    Accessing `http://yourserver.com/one/path/here?param=1` will become `http://127.0.0.1/twopath/here?param=1`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FViRb3%2Fnginx-gotchas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FViRb3%2Fnginx-gotchas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FViRb3%2Fnginx-gotchas/lists"}