mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 16:00:51 +00:00
Enabling Panel SSL with the self-sign provider rejected IPv6 hosts with
"domain format invalid". Two coupled bugs caused this:
1. The frontend extracted the host from window.location.href with
href.split('//')[1].split(':')[0]. For an IPv6 URL like
https://[::1]:1234 that yields '[' \u2014 not a valid host \u2014 because
the second split splits on the first colon inside the bracketed
address. Use window.location.hostname, which natively returns the
bracket-stripped IPv6 host.
2. The backend ObtainSSL flow used net.ParseIP(domain) directly. Even if
the frontend sent the bracketed form ('[::1]'), net.ParseIP rejects
brackets, so the value flowed into IsValidDomain() and failed the
regex.
Add common.ParseIPLoose() that accepts both bare and bracketed IPv6 in
addition to bare IPv4. Use it at both call sites in ObtainSSL (renew
path and create path). A unit test guards the regression.
Files:
- agent/utils/common/common.go (new ParseIPLoose helper)
- agent/utils/common/parse_ip_test.go (12 cases, all green)
- agent/app/service/website_ca.go (call sites switched)
- frontend/src/views/setting/safe/ssl/index.vue
(host extraction fix)
Fixes #12646
Signed-off-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com>
37 lines
1.1 KiB
Go
37 lines
1.1 KiB
Go
package common
|
|
|
|
import "testing"
|
|
|
|
// Regression test for 1Panel-dev/1Panel#12646: panel SSL self-signed flow
|
|
// rejected IPv6 hosts because net.ParseIP does not accept the bracketed
|
|
// form (e.g. "[::1]") and the upstream caller passes the host portion of
|
|
// a URL rather than a bare IP.
|
|
func TestParseIPLoose(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
in string
|
|
want bool
|
|
}{
|
|
{"bare ipv4", "127.0.0.1", true},
|
|
{"bare ipv6", "::1", true},
|
|
{"bracketed ipv6", "[::1]", true},
|
|
{"bracketed full ipv6", "[2001:db8::1]", true},
|
|
{"trimmed bare ipv6", " ::1 ", true},
|
|
{"trimmed bracketed ipv6", " [::1] ", true},
|
|
{"empty", "", false},
|
|
{"only brackets", "[]", false},
|
|
{"hostname", "example.com", false},
|
|
{"bracketed garbage", "[notanip]", false},
|
|
{"unbalanced bracket left", "[::1", false},
|
|
{"unbalanced bracket right", "::1]", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := ParseIPLoose(tc.in) != nil
|
|
if got != tc.want {
|
|
t.Errorf("ParseIPLoose(%q) ok = %v, want %v", tc.in, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|