mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-09-19 18:49:43 +02:00

- Moved certification related functions into tlscert module - Added specific host TLS behavior logic - Added support for disabling SNI and manually overwrite preferred certificate to serve - Fixed SSO requestHeaders null bug
194 lines
5.5 KiB
Go
194 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"imuslab.com/zoraxy/mod/utils"
|
|
)
|
|
|
|
// Handle front-end toggling TLS mode
|
|
func handleToggleTLSProxy(w http.ResponseWriter, r *http.Request) {
|
|
currentTlsSetting := true //Default to true
|
|
if dynamicProxyRouter.Option != nil {
|
|
currentTlsSetting = dynamicProxyRouter.Option.UseTls
|
|
}
|
|
if sysdb.KeyExists("settings", "usetls") {
|
|
sysdb.Read("settings", "usetls", ¤tTlsSetting)
|
|
}
|
|
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
//Get the current status
|
|
js, _ := json.Marshal(currentTlsSetting)
|
|
utils.SendJSONResponse(w, string(js))
|
|
case http.MethodPost:
|
|
newState, err := utils.PostBool(r, "set")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "new state not set or invalid")
|
|
return
|
|
}
|
|
if newState {
|
|
sysdb.Write("settings", "usetls", true)
|
|
SystemWideLogger.Println("Enabling TLS mode on reverse proxy")
|
|
dynamicProxyRouter.UpdateTLSSetting(true)
|
|
} else {
|
|
sysdb.Write("settings", "usetls", false)
|
|
SystemWideLogger.Println("Disabling TLS mode on reverse proxy")
|
|
dynamicProxyRouter.UpdateTLSSetting(false)
|
|
}
|
|
utils.SendOK(w)
|
|
default:
|
|
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
|
|
}
|
|
}
|
|
|
|
// Handle the GET and SET of reverse proxy TLS versions
|
|
func handleSetTlsRequireLatest(w http.ResponseWriter, r *http.Request) {
|
|
newState, err := utils.PostPara(r, "set")
|
|
if err != nil {
|
|
//GET
|
|
var reqLatestTLS bool = false
|
|
if sysdb.KeyExists("settings", "forceLatestTLS") {
|
|
sysdb.Read("settings", "forceLatestTLS", &reqLatestTLS)
|
|
}
|
|
|
|
js, _ := json.Marshal(reqLatestTLS)
|
|
utils.SendJSONResponse(w, string(js))
|
|
} else {
|
|
switch newState {
|
|
case "true":
|
|
sysdb.Write("settings", "forceLatestTLS", true)
|
|
SystemWideLogger.Println("Updating minimum TLS version to v1.2 or above")
|
|
dynamicProxyRouter.UpdateTLSVersion(true)
|
|
case "false":
|
|
sysdb.Write("settings", "forceLatestTLS", false)
|
|
SystemWideLogger.Println("Updating minimum TLS version to v1.0 or above")
|
|
dynamicProxyRouter.UpdateTLSVersion(false)
|
|
default:
|
|
utils.SendErrorResponse(w, "invalid state given")
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleCertTryResolve(w http.ResponseWriter, r *http.Request) {
|
|
// get the domain
|
|
domain, err := utils.GetPara(r, "domain")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "invalid domain given")
|
|
return
|
|
}
|
|
|
|
// get the proxy rule, the pass in domain value must be root or matching domain
|
|
proxyRule, err := dynamicProxyRouter.GetProxyEndpointById(domain, false)
|
|
if err != nil {
|
|
//Try to resolve the domain via alias
|
|
proxyRule, err = dynamicProxyRouter.GetProxyEndpointByAlias(domain)
|
|
if err != nil {
|
|
//No matching rule found
|
|
utils.SendErrorResponse(w, "proxy rule not found for domain: "+domain)
|
|
return
|
|
}
|
|
}
|
|
|
|
// list all the alias domains for this rule
|
|
allDomains := []string{proxyRule.RootOrMatchingDomain}
|
|
aliasDomains := []string{}
|
|
for _, alias := range proxyRule.MatchingDomainAlias {
|
|
if alias != "" {
|
|
aliasDomains = append(aliasDomains, alias)
|
|
allDomains = append(allDomains, alias)
|
|
}
|
|
}
|
|
|
|
// Try to resolve the domain
|
|
domainKeyPairs := map[string]string{}
|
|
for _, thisDomain := range allDomains {
|
|
pubkey, prikey, err := tlsCertManager.GetCertificateByHostname(thisDomain)
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, err.Error())
|
|
return
|
|
}
|
|
|
|
//Make sure pubkey and private key are not empty
|
|
if pubkey == "" || prikey == "" {
|
|
domainKeyPairs[thisDomain] = ""
|
|
} else {
|
|
//Store the key pair
|
|
keyname := strings.TrimSuffix(filepath.Base(pubkey), filepath.Ext(pubkey))
|
|
if keyname == "localhost" {
|
|
//Internal certs like localhost should not be used
|
|
//report as "fallback" key
|
|
keyname = "fallback certificate"
|
|
}
|
|
domainKeyPairs[thisDomain] = keyname
|
|
}
|
|
|
|
}
|
|
|
|
//A domain must be UseDNSValidation if it is a wildcard domain or its alias is a wildcard domain
|
|
useDNSValidation := strings.HasPrefix(proxyRule.RootOrMatchingDomain, "*")
|
|
for _, alias := range aliasDomains {
|
|
if strings.HasPrefix(alias, "*") || strings.HasPrefix(domain, "*") {
|
|
useDNSValidation = true
|
|
}
|
|
}
|
|
|
|
type CertInfo struct {
|
|
Domain string `json:"domain"`
|
|
AliasDomains []string `json:"alias_domains"`
|
|
DomainKeyPair map[string]string `json:"domain_key_pair"`
|
|
UseDNSValidation bool `json:"use_dns_validation"`
|
|
}
|
|
|
|
result := &CertInfo{
|
|
Domain: proxyRule.RootOrMatchingDomain,
|
|
AliasDomains: aliasDomains,
|
|
DomainKeyPair: domainKeyPairs,
|
|
UseDNSValidation: useDNSValidation,
|
|
}
|
|
|
|
js, _ := json.Marshal(result)
|
|
utils.SendJSONResponse(w, string(js))
|
|
}
|
|
|
|
func handleSetDomainPreferredCertificate(w http.ResponseWriter, r *http.Request) {
|
|
//Get the domain
|
|
domain, err := utils.PostPara(r, "domain")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "invalid domain given")
|
|
return
|
|
}
|
|
|
|
//Get the certificate name
|
|
certName, err := utils.PostPara(r, "certname")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "invalid certificate name given")
|
|
return
|
|
}
|
|
|
|
//Load the target endpoint
|
|
ept, err := dynamicProxyRouter.GetProxyEndpointById(domain, true)
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "proxy rule not found for domain: "+domain)
|
|
return
|
|
}
|
|
|
|
//Set the preferred certificate for the domain
|
|
err = dynamicProxyRouter.SetPreferredCertificateForDomain(ept, domain, certName)
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "failed to set preferred certificate: "+err.Error())
|
|
return
|
|
}
|
|
|
|
err = SaveReverseProxyConfig(ept)
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, "failed to save reverse proxy config: "+err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SendOK(w)
|
|
}
|