Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wildcard domain matches before specific domain. #3410

Closed
pnomolos opened this issue May 13, 2020 · 18 comments
Closed

Wildcard domain matches before specific domain. #3410

pnomolos opened this issue May 13, 2020 · 18 comments
Labels
bug 🐞 Something isn't working
Milestone

Comments

@pnomolos
Copy link

Caddyfile like so:

specific.example.com {
  # ...
}

www.example.com, *.example.com {
  # ...
}

A request to specific.example.com will get routed to the second definition. My hope was to use it as a catch-all for mis-spellings, etc.

@mholt
Copy link
Member

mholt commented May 13, 2020

Thanks for opening an issue! We'll look into this.

It's not immediately clear to me what is going on, so I'll need your help to understand it better.

Ideally, we need to be able to reproduce the bug in the most minimal way possible. This allows us to write regression tests to verify the fix is working. If we can't reproduce it, then you'll have to test our changes for us until it's fixed -- and then we can't add test cases, either.

I've attached a template below that will help make this easier and faster! It will ask for some information you've already provided; that's OK, just fill it out the best you can. 👍

I've also included some helpful tips below the template. Feel free to let me know if you have any questions!

Thank you again for your report, we look forward to resolving it!

Template

## 1. Environment

### 1a. Operating system and version

```
paste here
```


### 1b. Caddy version (run `caddy version` or paste commit SHA)

```
paste here
```


### 1c. Go version (if building Caddy from source; run `go version`)

```
paste here
```


## 2. Description

### 2a. What happens (briefly explain what is wrong)




### 2b. Why it's a bug (if it's not obvious)




### 2c. Log output

```
paste terminal output or logs here
```



### 2d. Workaround(s)




### 2e. Relevant links




## 3. Tutorial (minimal steps to reproduce the bug)




Helpful tips

  1. Environment: Please fill out your OS and Caddy versions, even if you don't think they are relevant. (They are always relevant.) If you built Caddy from source, provide the commit SHA and specify your exact Go version.

  2. Description: Describe at a high level what the bug is. What happens? Why is it a bug? Not all bugs are obvious, so convince readers that it's actually a bug.

    • 2c) Log output: Paste terminal output and/or complete logs in a code block. DO NOT REDACT INFORMATION except for credentials.
    • 2d) Workaround: What are you doing to work around the problem in the meantime? This can help others who encounter the same problem, until we implement a fix.
    • 2e) Relevant links: Please link to any related issues, pull requests, docs, and/or discussion. This can add crucial context to your report.
  3. Tutorial: What are the minimum required specific steps someone needs to take in order to experience the same bug? Your goal here is to make sure that anyone else can have the same experience with the bug as you do. You are writing a tutorial, so make sure to carry it out yourself before posting it. Please:

    • Start with an empty config. Add only the lines/parameters that are absolutely required to reproduce the bug.
    • Do not run Caddy inside containers.
    • Run Caddy manually in your terminal; do not use systemd or other init systems.
    • If making HTTP requests, avoid web browsers. Use a simpler HTTP client instead, like curl.
    • Do not redact any information from your config (except credentials). Domain names are public knowledge and often necessary for quick resolution of an issue!
    • Note that ignoring this advice may result in delays, or even in your issue being closed. 😞 Only actionable issues are kept open, and if there is not enough information or clarity to reproduce the bug, then the report is not actionable.

Example of a tutorial:

Create a config file:
{ ... }

Open terminal and run Caddy:

$ caddy ...

Make an HTTP request:

$ curl ...

Notice that the result is ___ but it should be ___.

@mholt
Copy link
Member

mholt commented May 13, 2020

To be clear, I'm asking for more information because your config adapts as expected for me:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "specific.example.com"
                  ]
                }
              ],
              "terminal": true
            },
            {
              "match": [
                {
                  "host": [
                    "www.example.com",
                    "*.example.com"
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
  }
}

@mholt mholt added the needs info 📭 Requires more information label May 13, 2020
@pnomolos
Copy link
Author

@mholt The problem isn't that it doesn't adapt - it's that when caddy receives a request on specific.example.com the wildcard domain is taking precedence.

In terms of information:

I'm running the latest available (at time of writing) official docker image of caddy.
Version: v2.0.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=
Host OS is Ubuntu.

@francislavoie
Copy link
Member

francislavoie commented May 13, 2020

We still need more info. Can you give a minimally reproduceable example, with curl -v to show that it hits the wrong site? It would help a lot if you would fill out the template.

@mholt
Copy link
Member

mholt commented May 13, 2020

Right now this is a "works for me" until we can reproduce it...

@pnomolos
Copy link
Author

1. Environment

1a. Operating system and version

latest available (at time of writing) official docker image of caddy.  Host OS is Ubuntu.

1b. Caddy version (run caddy version or paste commit SHA)

v2.0.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=

2. Description

2a. What happens (briefly explain what is wrong)

When given both a specific domain and a wildcard domain in separate site configurations, the wildcard domain is favoured over the specific domain.

@pnomolos
Copy link
Author

I'll see if I can prepare a reproducible example. The site in question is live in production, so I can't go back to the "broken" configuration.

@pnomolos
Copy link
Author

Here's what caddy adapt gives me for the broken configuration:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "schools.teachersfile.ca",
                    "teachersfile.ca",
                    "www.teachersfile.ca",
                    "*.teachersfile.ca"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/vhosts/teachersfile.ca/public"
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "teachersfile:4000"
                            }
                          ]
                        }
                      ],
                      "match": [
                        {
                          "not": [
                            {
                              "file": {
                                "try_files": [
                                  "{http.request.uri.path}"
                                ]
                              }
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "file_server",
                          "hide": [
                            "Caddyfile"
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            },
            {
              "match": [
                {
                  "host": [
                    "packs.teachersfile.ca"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/vhosts/packs.teachersfile.ca/current/public"
                        },
                        {
                          "handler": "headers",
                          "response": {
                            "add": {
                              "Access-Control-Allow-Origin": [
                                "*"
                              ]
                            }
                          }
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "teachersfilepacks:4000"
                            }
                          ]
                        }
                      ],
                      "match": [
                        {
                          "not": [
                            {
                              "file": {
                                "try_files": [
                                  "{http.request.uri.path}"
                                ]
                              }
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "file_server",
                          "hide": [
                            "Caddyfile"
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ],
          "tls_connection_policies": [
            {
              "match": {
                "sni": [
                  "*.teachersfile.ca",
                  "schools.teachersfile.ca",
                  "teachersfile.ca",
                  "www.teachersfile.ca"
                ]
              }
            },
            {}
          ]
        }
      }
    },
    "tls": {
      "automation": {
        "policies": [
          {
            "subjects": [
              "www.teachersfile.ca",
              "*.teachersfile.ca",
              "schools.teachersfile.ca",
              "teachersfile.ca"
            ],
            "on_demand": true
          }
        ]
      }
    }
  }
}

Note that the wildcard is part of the group of routes that comes first in the matching array. I'm going to hazard a guess that perhaps this has something to do with the on_demand tls?

@mholt
Copy link
Member

mholt commented May 13, 2020

@pnomolos

The problem isn't that it doesn't adapt - it's that when caddy receives a request on specific.example.com the wildcard domain is taking precedence.

Works for me:

foo.sub.localhost {
  respond "foo"
}

bar.sub.localhost, *.sub.localhost {
  respond "wildcard: {host}"
}
% curl "https://foo.sub.localhost" 
foo

% curl "https://bar.sub.localhost" 
wildcard: bar.sub.localhost

% curl "https://asdf.sub.localhost" 
wildcard: asdf.sub.localhost

@mholt
Copy link
Member

mholt commented May 13, 2020

Closing, since this is working as expected, and there's not currently enough information to reproduce the issue.

@mholt mholt closed this as completed May 13, 2020
@pnomolos
Copy link
Author

@mholt I posted the broken configuration just before you closed this, so you may have missed it. I may be able to switch to the broken configuration briefly tonight to have a reproducible test case.

@mholt
Copy link
Member

mholt commented May 13, 2020

@pnomolos Indeed, thanks. But, there's still not enough information here. The adapted config appears to be working as shown. Please, why won't you fill out the template?

@pnomolos
Copy link
Author

@mholt Sorry, but what's missing from the template that I haven't provided? I've given the caddy version and OS information, the configuration, and what's not working. I don't have any further information to post, as far as I can tell.

@mholt
Copy link
Member

mholt commented May 13, 2020

@pnomolos I don't know if this was intentional, but you literally only filled out half of it:

Screen Shot 2020-05-13 at 1 47 41 PM

Using the Caddyfile you gave me above (the only other piece of information), I was not able to reproduce the problem you're describing.

Just please please please please please please please please please please please please please please please please fill out the issue template? ☹️ This is beginning to waste my time.

@pnomolos
Copy link
Author

pnomolos commented May 13, 2020

1. Environment

1a. Operating system and version

latest available (at time of writing) official docker image of caddy.  Host OS is Ubuntu.

1b. Caddy version (run caddy version or paste commit SHA)

v2.0.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=

1c. Go version (if building Caddy from source; run go version)

None

2. Description

2a. What happens (briefly explain what is wrong)

When given both a specific domain and a wildcard domain in separate site configurations, the wildcard domain is favoured over the specific domain.

2b. Why it's a bug (if it's not obvious)

Should be going to the subdomain first, not the wildcard domain.

2c. Log output

None

2d. Workaround(s)

Remove wildcard domain from configuration.

2e. Relevant links

None

3. Tutorial (minimal steps to reproduce the bug)

With the below caddyfile, going to packs.teachersfile.ca routes to the site served by the wildcard domain.

packs.teachersfile.ca {
  @notStatic1 {
    not {
      file {
        try_files {path}
      }
    }
  }

  header {
    +Access-Control-Allow-Origin *
  }
  reverse_proxy @notStatic1 teachersfilepacks:4000

  root * /var/www/vhosts/packs.teachersfile.ca/current/public
  file_server
}

schools.teachersfile.ca, teachersfile.ca, www.teachersfile.ca, *.teachersfile.ca {
  @notStatic2 {
    not {
      file {
        try_files {path}
      }
    }
  }
  tls {
    on_demand
  }
  reverse_proxy @notStatic2 teachersfile:4000

  root * /var/www/vhosts/teachersfile.ca/public
  file_server
}

@francislavoie
Copy link
Member

Alright, I was able to confirm the bug:

packs.teachersfile.ca {
  respond "Packs"
}

schools.teachersfile.ca, teachersfile.ca, www.teachersfile.ca, *.teachersfile.ca {
  respond "Everything else"
}

Will order the sites in the wrong order:

[www.teachersfile.ca *.teachersfile.ca schools.teachersfile.ca teachersfile.ca]
[packs.teachersfile.ca]

If I remove schools.teachersfile.ca, then it sorts in the right order:

[packs.teachersfile.ca]
[www.teachersfile.ca *.teachersfile.ca teachersfile.ca]

The reason for this is the logic here:

sort.SliceStable(p.serverBlocks, func(i, j int) bool {

It's comparing the string lengths of the sites, and schools is longer than packs so it considers it less specific.

It probably needs to be adjusted to force a slice that contains a * to be sorted afterwards regardless of string length.

@francislavoie francislavoie reopened this May 13, 2020
@francislavoie francislavoie added bug 🐞 Something isn't working and removed needs info 📭 Requires more information labels May 13, 2020
@francislavoie
Copy link
Member

FYI as a hotfix, I recommend moving the * label to its own site block (and copy the contents of the site block) for now. Some duplication, but it should get around the issue for the time being.

For example:

packs.teachersfile.ca {
  respond "Packs"
}

schools.teachersfile.ca, teachersfile.ca, www.teachersfile.ca {
  respond "Everything else"
}

*.teachersfile.ca {
  respond "Wildcard"
}

Will sort like this:

[schools.teachersfile.ca teachersfile.ca www.teachersfile.ca]
[packs.teachersfile.ca]
[*.teachersfile.ca]

@pnomolos
Copy link
Author

@francislavoie Thanks! Glad to know I'm not completely crazy and there was something going on :)

@francislavoie francislavoie added this to the 2.1 milestone May 23, 2020
@mholt mholt closed this as completed in 97e61c1 Jun 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants