ingress-nginx icon indicating copy to clipboard operation
ingress-nginx copied to clipboard

Rewrite rules do not redirect if missing trailing slash

Open evoicefire opened this issue 3 years ago • 18 comments

Right now it seems that when you have a redirect rule. See below for Ingress config. When I access example.com/something/ everything works as expected - however, when I access example.com/something there is no redirect to example.com/something/ therefore the page doesn't work properly.

I can use a workaround in this past issue (now closed) here: https://github.com/kubernetes/ingress-nginx/issues/646

I think there should be an easier way to enable this behaviour (without a config snippet) or it should be enabled by default (probably an annotation of some kind)

https://github.com/kubernetes/ingress-nginx/issues/646

I am using 1.18.20 but it doesn't require a particular version

evoicefire avatar Dec 16 '21 01:12 evoicefire

@evoicefire: This issue is currently awaiting triage.

If Ingress contributors determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

k8s-ci-robot avatar Dec 16 '21 01:12 k8s-ci-robot

Description of problem is not good enough. Can you add kubectl describe ouput of ingress and your curl command.

Thanks, ; Long

On Thu, 16 Dec, 2021, 7:21 AM Kubernetes Prow Robot, < @.***> wrote:

@evoicefire https://github.com/evoicefire: This issue is currently awaiting triage.

If Ingress contributors determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available here https://git.k8s.io/community/contributors/guide/pull-requests.md. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue: repository.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kubernetes/ingress-nginx/issues/8047#issuecomment-995366571, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGZVWU3DITQMMTQ7OGDIF3URFAY3ANCNFSM5KFDHMJQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

longwuyuan avatar Dec 16 '21 03:12 longwuyuan

Sorry I meant to include that originally but forgot:

    Name:             something-landing-static-nginx
    Namespace:        landing
    Address:          0.0.0.0
    Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
    TLS:
      SNI routes www-dev.example.com
      SNI routes landing-dev.example.com
      SNI routes landing-dev.example.com
    Rules:
      Host                        Path  Backends
      ----                        ----  --------
      www-dev.example.com
                                  /something(/|$)(.*)   something-landing-static:http (10.8.6.142:80,10.8.7.32:80)
      landing-dev.example.com
                                  /something(/|$)(.*)   something-landing-static:http (10.8.6.142:80,10.8.7.32:80)
      landing-dev.example.com
                                  /(|$)(.*)   something-landing-static:http (10.8.6.142:80,10.8.7.32:80)
    Annotations:                  cert-manager.io/cluster-issuer: letsencrypt-prod
                                  kubernetes.io/ingress.class: nginx
                                  nginx.ingress.kubernetes.io/rewrite-target: /$2
    Events:
      Type     Reason     Age                   From                      Message
      ----     ------     ----                  ----                      -------
      Normal   Sync       51m (x5 over 58m)     nginx-ingress-controller  Scheduled for sync
      Normal   Sync       51m (x5 over 58m)     nginx-ingress-controller  Scheduled for sync
      Normal   Sync       51m (x5 over 58m)     nginx-ingress-controller  Scheduled for sync
      Normal   Sync       28m (x34 over 17h)    nginx-ingress-controller  Scheduled for sync
      Normal   Sync       28m (x32 over 3h16m)  nginx-ingress-controller  Scheduled for sync
      Normal   Sync       28m (x34 over 17h)    nginx-ingress-controller  Scheduled for sync
      Normal   Sync       27m                   nginx-ingress-controller  Scheduled for sync
      Normal   Sync       27m                   nginx-ingress-controller  Scheduled for sync
      Normal   Sync       27m                   nginx-ingress-controller  Scheduled for sync

    ❯ curl -IvvvkL www-dev.example.com/something
    *   Trying x.x.x.x:80...
    * TCP_NODELAY set
    * Connected to www-dev.example.com (x.x.x.x) port 80 (#0)
    > HEAD /something HTTP/1.1
    > Host: www-dev.example.com
    > User-Agent: curl/7.68.0
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 308 Permanent Redirect
    HTTP/1.1 308 Permanent Redirect
    < Date: Thu, 16 Dec 2021 03:17:51 GMT
    Date: Thu, 16 Dec 2021 03:17:51 GMT
    < Content-Type: text/html
    Content-Type: text/html
    < Content-Length: 164
    Content-Length: 164
    < Connection: keep-alive
    Connection: keep-alive
    < Location: https://www-dev.example.com/something
    Location: https://www-dev.example.com/something
    
    <
    * Connection #0 to host www-dev.example.com left intact
    * Issue another request to this URL: 'https://www-dev.example.com/something'
    *   Trying x.x.x.x:443...
    * TCP_NODELAY set
    * Connected to www-dev.example.com (x.x.x.x) port 443 (#1)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: /etc/ssl/certs/ca-certificates.crt
      CApath: /etc/ssl/certs
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    * TLSv1.3 (IN), TLS handshake, CERT verify (15):
    * TLSv1.3 (IN), TLS handshake, Finished (20):
    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.3 (OUT), TLS handshake, Finished (20):
    * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=CloudFlare, Inc.; OU=CloudFlare Origin CA; CN=CloudFlare Origin Certificate
    *  start date: Nov 20 07:49:00 2021 GMT
    *  expire date: Feb 18 07:49:00 2022 GMT
    *  issuer: C=US; O=CloudFlare, Inc.; OU=CloudFlare Origin SSL Certificate Authority; L=San Francisco; ST=California
    *  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x5609611d7860)
    > HEAD /something HTTP/2
    > Host: www-dev.example.com
    > user-agent: curl/7.68.0
    > accept: */*
    >
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * old SSL session ID is stale, removing
    * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
    < HTTP/2 200
    HTTP/2 200
    < date: Thu, 16 Dec 2021 03:17:51 GMT
    date: Thu, 16 Dec 2021 03:17:51 GMT
    < content-type: text/html
    content-type: text/html
    < vary: Accept-Encoding
    vary: Accept-Encoding
    < referrer-policy: strict-origin-when-cross-origin
    referrer-policy: strict-origin-when-cross-origin
    < permissions-policy: geolocation=(),sync-xhr=(),microphone=(),camera=(),fullscreen=(),payment=()
    permissions-policy: geolocation=(),sync-xhr=(),microphone=(),camera=(),fullscreen=(),payment=()
    < x-content-type-options: nosniff
    x-content-type-options: nosniff
    < x-xss-protection: 1; mode=block
    x-xss-protection: 1; mode=block
    < strict-transport-security: max-age=15724800; includeSubDomains
    strict-transport-security: max-age=15724800; includeSubDomains
    
    <
    * Connection #1 to host www-dev.example.com left intact

Thanks a lot for your quick reply. It definitely could be a config issue but my symptoms seem the same as the previous issue.

evoicefire avatar Dec 16 '21 03:12 evoicefire

What happens if you add a "/" to the end of the value for the redirect annotation like ..../$2/

longwuyuan avatar Dec 16 '21 06:12 longwuyuan

/remove-kind feature /kind support /triage needs-information

longwuyuan avatar Dec 16 '21 06:12 longwuyuan

I believe we discussed something similar in the last community call @kd7lxl could this be related to https://github.com/kubernetes/ingress-nginx/issues/7196

strongjz avatar Dec 16 '21 21:12 strongjz

I believe we discussed something similar in the last community call @kd7lxl could this be related to #7196

Maybe related, but I think this issue is distinct.

kd7lxl avatar Dec 16 '21 22:12 kd7lxl

When are you planning to fix this, this issue is legitimate, I am facing the same problem, if any more details are required, let me know.

Vyom-Yadav avatar Mar 16 '22 05:03 Vyom-Yadav

Sorry for late response. I hope to test this in more detail this week. Thanks :)

On Wed, 16 Mar 2022 at 4:37 pm, Vyom Yadav @.***> wrote:

When are you planning to fix this, this issue is legitimate, I am facing the same problem, if any more details are required, let me know.

— Reply to this email directly, view it on GitHub https://github.com/kubernetes/ingress-nginx/issues/8047#issuecomment-1068751694, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACR5JZWIPZUGU5Z2LCPE5VLVAFXQ7ANCNFSM5KFDHMJQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

evoicefire avatar Mar 16 '22 05:03 evoicefire

You are using TLS and you are talking about trailing slashes so check if this annotation nginx.ingress.kubernetes.io/preserve-trailing-slash is related to this issue https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#server-side-https-enforcement-through-redirect

longwuyuan avatar Mar 16 '22 06:03 longwuyuan

I don't know this issue is same for all ingress controllers ? coz I found this issue: https://github.com/kubernetes/ingress-gce/issues/109

sahilrajput03 avatar Mar 18 '22 20:03 sahilrajput03

What you have posted does not make sense in the context of pointing at a specific problem of any kind. The curl command is doing exactly what is expected as per configuration.

longwuyuan avatar Mar 19 '22 05:03 longwuyuan

@longwuyuan I don't think the OP is going to respond, this issue is genuine, ingress-nginx does not rewrite when you have a trailing slash. See https://stackoverflow.com/questions/71424259/why-url-re-writing-is-not-working-when-i-do-not-use-slash-at-the-end for more information,

Vyom-Yadav avatar Mar 19 '22 06:03 Vyom-Yadav

With limited resources, we can discuss data and avoid discussions that are not based on any data. I see that requested URL is www-dev.example.com/something and rewrite rule will not kick in because there is no $2 regexpgroup in that request.

Please respond with some data pointing at the http request and the config of the ingress object because that is the basic functionality of the ingress-controller (to route traffic after matching rule to request)

longwuyuan avatar Mar 19 '22 06:03 longwuyuan

www-dev.example.com/something and rewrite rule will not kick in because there is no $2 regexpgroup in that request.

Sorry for the late reply, but when I use the above mentioned URL, rewrite rule kicks in and doesn't when I use trailing slash i.e www-dev.example.com/something/

In my case I was using it with minikube, minikube addons enable ingress, ingress configuration-

NAME                                           READY   STATUS      RESTARTS         AGE
pod/ingress-nginx-admission-create-t5qft       0/1     Completed   0                15d
pod/ingress-nginx-admission-patch-z9rzk        0/1     Completed   0                15d
pod/ingress-nginx-controller-cc8496874-szrnp   1/1     Running     14 (5m48s ago)   15d

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.109.126.23   <none>        80:30977/TCP,443:30237/TCP   15d
service/ingress-nginx-controller-admission   ClusterIP   10.104.162.93   <none>        443/TCP                      15d

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           15d

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-cc8496874   1         1         1       15d

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           6s         15d
job.batch/ingress-nginx-admission-patch    1/1           6s         15d

As far as the HTTP request is concerned, it is a simple get request, curl --location --request GET 'http://tutorial.com/link1'

Feel free to ask for more details :)

Vyom-Yadav avatar Mar 23 '22 15:03 Vyom-Yadav

@longwuyuan Thoughts?

Vyom-Yadav avatar Mar 29 '22 03:03 Vyom-Yadav

https://github.com/kubernetes/ingress-gce/issues/109 That was a 4year old issue similar to this...

@Vyom-Yadav , can you check if you have some code handy that the new api works?. I will check this asap too.

sahilrajput03 avatar Jun 14 '22 23:06 sahilrajput03

The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue or PR as fresh with /remove-lifecycle stale
  • Mark this issue or PR as rotten with /lifecycle rotten
  • Close this issue or PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot avatar Sep 13 '22 00:09 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue or PR as fresh with /remove-lifecycle rotten
  • Close this issue or PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

k8s-triage-robot avatar Oct 13 '22 00:10 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

k8s-triage-robot avatar Nov 12 '22 01:11 k8s-triage-robot

@k8s-triage-robot: Closing this issue, marking it as "Not Planned".

In response to this:

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

k8s-ci-robot avatar Nov 12 '22 01:11 k8s-ci-robot