Support IPv4 HTTP public gateway entries

This commit is contained in:
Codex committed 2026-10-26 14:53:52 +08:00
1 parent 6f01d31f97
commit 6d5973bea3
11 files changed
+146 -32

No files matched your search

+24 -8
View File
@@ -21,6 +21,7 @@ import (
)
var domainPattern = regexp.MustCompile(`^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$`)
var numericHostPattern = regexp.MustCompile(`^[0-9.]+$`)
type configuration struct {
domain string
@@ -72,7 +73,22 @@ func DataDir() string {
}
func ValidDomain(domain string) bool {
return len(domain) <= 253 && domainPattern.MatchString(domain) && net.ParseIP(domain) == nil
return len(domain) <= 253 && domainPattern.MatchString(domain) && !numericHostPattern.MatchString(domain)
}
// ValidPublicHost allows a literal IPv4 address only for an HTTP gateway.
// Certificate issuance and HTTPS remain restricted to DNS names.
func ValidPublicHost(scheme, host string) bool {
if !ValidScheme(scheme) {
return false
}
if scheme == "https" {
return ValidDomain(host)
}
if ip := net.ParseIP(host); ip != nil {
return ip.To4() != nil && !ip.IsUnspecified() && !ip.IsMulticast()
}
return ValidDomain(host)
}
func ValidScheme(scheme string) bool {
@@ -94,7 +110,7 @@ func EffectivePort(scheme string, port int) int {
func PublicBaseURL(scheme, host string, port int) string {
scheme = strings.ToLower(strings.TrimSpace(scheme))
host = strings.ToLower(strings.TrimSpace(host))
if !ValidScheme(scheme) || host == "" || !ValidDomain(host) {
if !ValidPublicHost(scheme, host) {
return ""
}
eff := EffectivePort(scheme, port)
@@ -171,9 +187,6 @@ func configFromEnvironment(dataDir string) (configuration, error) {
}
domain = strings.ToLower(raw)
}
if domain != "" && !ValidDomain(domain) {
return configuration{}, fmt.Errorf("VPN_TLS_DOMAIN 不是有效的单个完整域名")
}
schemeEnv := strings.TrimSpace(os.Getenv("VPN_TLS_SCHEME"))
scheme := normalizeScheme(schemeEnv)
if schemeEnv == "" {
@@ -186,6 +199,9 @@ func configFromEnvironment(dataDir string) (configuration, error) {
if !ValidScheme(scheme) {
return configuration{}, fmt.Errorf("VPN_TLS_SCHEME 仅支持 http 或 https")
}
if domain != "" && !ValidPublicHost(scheme, domain) {
return configuration{}, fmt.Errorf("VPN_TLS_DOMAIN 必须是有效域名,HTTP 模式也可使用 IPv4 地址")
}
port := 0
if raw := strings.TrimSpace(os.Getenv("VPN_TLS_PORT")); raw != "" {
var err error
@@ -239,8 +255,8 @@ func ConfigurePublicEntry(dataDir, scheme, domain string, port int) error {
if !ValidScheme(scheme) {
return fmt.Errorf("协议仅支持 http 或 https")
}
if !ValidDomain(domain) {
return fmt.Errorf("请输入单个有效的完整域名")
if !ValidPublicHost(scheme, domain) {
return fmt.Errorf("请输入有效域名;HTTP 也支持 IPv4 地址")
}
if port < 0 || port > 65535 {
return fmt.Errorf("端口必须是 0-65535(0 表示协议默认端口)")
@@ -304,7 +320,7 @@ func AdoptNginxConfiguration(dataDir string) error {
// UseManagedNginxEntry keeps the in-process identity issuer aligned with the
// live Nginx site if an older version left an unapplied draft on disk.
func UseManagedNginxEntry(dataDir, scheme, domain string, port int) error {
if !ValidScheme(scheme) || !ValidDomain(domain) || port < 1 || port > 65535 {
if !ValidPublicHost(scheme, domain) || port < 1 || port > 65535 {
return fmt.Errorf("运行中的 Nginx 公网地址无效")
}
state.Lock()