Repository: traefik/traefik (language: go)

Issue:
[Windows] ipWhiteList middleware failed to parse IP on (local) IPv6 with zone id attached
<!-- PLEASE FOLLOW THE ISSUE TEMPLATE TO HELP TRIAGE AND SUPPORT! -->

### Do you want to request a *feature* or report a *bug*?

<!--
DO NOT FILE ISSUES FOR GENERAL SUPPORT QUESTIONS.

The issue tracker is for reporting bugs and feature requests only.
For end-user related support questions, please refer to one of the following:

- the Traefik community forum: https://community.containo.us/

-->

Bug

<!--

The configurations between 1.X and 2.X are NOT compatible.
Please have a look here https://docs.traefik.io/v2.0/getting-started/configuration-overview/.

-->

### What did you do?
I set up an ipWhiteList middleware for our application and tried to access one of the routers with the middleware attached.
<!--

HOW TO WRITE A GOOD BUG REPORT?

- Respect the issue template as much as possible.
- The title should be short and descriptive.
- Explain the conditions which led you to report this issue: the context.
- The context should lead to something, an idea or a problem that you’re facing.
- Remain clear and concise.
- Format your messages to help the reader focus on what matters and understand the structure of your message, use Markdown syntax https://help.github.com/articles/github-flavored-markdown

-->

### What did you expect to see?
A valid service response.


### What did you see instead?
A canceled request.


### Output of `traefik version`: (_What version of Traefik are you using?_)
<!--
`latest` is not considered as a valid version.

For the Traefik Docker image:
    docker run [IMAGE] version
    ex: docker run traefik version

-->

```
Version:      2.2.11
Codename:     chevrotin
Go version:   go1.14.8
Built:        2020-09-07T14:12:48Z
OS/Arch:      windows/amd64
```

### What is your environment & configuration (arguments, toml, provider, platform, ...)?

```toml

[http.services.nginx]
      [http.services.nginx.loadBalancer]
        [[http.services.NGINX.loadBalancer.servers]]
          url = "http://example.com:8080"

[http.routers.nginx]
      entryPoints = ["web", "web-secure"]
      priority = 10
      service = "nginx"
      rule = "PathPrefix(`/test`)"
      middlewares = ["whitelist"]

[http.middlewares.whitelist.ipWhiteList]
      sourceRange = ["0.0.0.0/0", "::/0"]
```

<!--
Add more configuration information here.
-->


### If applicable, please paste the log output in DEBUG level (`--log.level=DEBUG` switch)

```
RemoteAddr:[fe80::xxxx:yyy:zzz:0123%vEthernet (Default Switch)]:58904 RequestURI:/test/ TLS:0xc0003da210 Cancel:<nil> Response:<nil> ctx:0xc0008ef530}: unable to parse address: fe80::xxxx:yyyy:zzzz:0123%vEthernet (Default Switch): can't parse IP from address fe80::xxxx:yyyy:zzzz:0123%vEthernet (Default Switch)"
```



Discussion / hints:
Hey, any ETA on this issue?
Our devs have to disable IPv6 on their systems/browsers to debug our application.
It looks like a simple parsing error because of an unexpected zone id when the middleware is enabled.
Hey, this is still a serious issue for us in 2.5.4. Will this ever be fixed?
Hey, is there any update?
The issue is also on linux/amd64.
Hey @knopfm, sorry to leave you hanging.  I just wanted to let you know that this is still in our list for investigation.  Community members are always welcome to help us verify bugs.  If you are interested, just comment and someone from our triage team would work with you to discuss what we need for verification. 
traefik 3.0.0 beta2  has a similar problem with ipallowlist with TCP connection 

 ERR Connection from [fe80::1f85:b4af:f75f:52cb%enp1s0]:45798 rejected error="unable to parse address: fe80::1f85:b4af:f75f:52cb%enp1s0: can't parse IP from address fe80::1f85:b4af:f75f:52cb%enp1s0" middlewareName=squid@docker middlewareType=IPAllowListerTCP
Hello @DirkTheDaring,

Thank you for the information.
We would love community support to address it.  

If you or another community member would like to fix it, let us know and we will work with you to make sure you have all the information needed so that it can be merged.  
I'm also seeing similar problem with `ipWhiteList` and `"fe80::/10"` in `sourceRange`. `"ClientHost":"fe80::9400:2ff:fe68:7408%eth0"` is not being recognized.
```
Version:      2.10.5
Codename:     saintmarcelin
Go version:   go1.21.3
Built:        2023-10-11T13:54:02Z
OS/Arch:      linux/arm64
```

Fix patch:
diff --git a/pkg/ip/checker.go b/pkg/ip/checker.go
index c51df036c4..eb2728a12b 100644
--- a/pkg/ip/checker.go
+++ b/pkg/ip/checker.go
@@ -4,6 +4,7 @@ import (
 	"errors"
 	"fmt"
 	"net"
+	"net/netip"
 	"strings"
 )
 
@@ -91,10 +92,11 @@ func (ip *Checker) ContainsIP(addr net.IP) bool {
 }
 
 func parseIP(addr string) (net.IP, error) {
-	userIP := net.ParseIP(addr)
-	if userIP == nil {
+	parsedAddr, err := netip.ParseAddr(addr)
+	if err != nil {
 		return nil, fmt.Errorf("can't parse IP from address %s", addr)
 	}
 
-	return userIP, nil
+	ip := parsedAddr.As16()
+	return ip[:], nil
 }


Test patch:
diff --git a/pkg/ip/checker_test.go b/pkg/ip/checker_test.go
index 53bcb13110..5893c9ef54 100644
--- a/pkg/ip/checker_test.go
+++ b/pkg/ip/checker_test.go
@@ -258,6 +258,7 @@ func TestContainsIsAllowed(t *testing.T) {
 				"2a03:4000:6:d080::42",
 				"fe80::1",
 				"fe80:aa00:00bb:4232:ff00:eeee:00ff:1111",
+				"fe80:aa00:00bb:4232:ff00:eeee:00ff:1111%vEthernet",
 				"fe80::fe80",
 				"1.2.3.1",
 				"1.2.3.32",
@@ -271,6 +272,7 @@ func TestContainsIsAllowed(t *testing.T) {
 			rejectIPs: []string{
 				"2a03:4000:7:d080::",
 				"2a03:4000:7:d080::1",
+				"2a03:4000:7:d080::1%vmnet1",
 				"4242::1",
 				"1.2.16.1",
 				"1.2.32.1",