Я пытался решить мою проблему и не нашел Go способа сделать это. У меня есть пара веб-серверов, обслуживающих различные приложения, и мы постарались сделать их доступными для пользователей через одну веб-страницу. Мы думали об использовании обратного прокси. Я пытался nginx и сам кодировать его с помощью Go.
user --> xxx.domain.name ------> /app1 -----> reverse proxy to app1 at its root uri /
/app2 -----> reverse proxy to app2 at its root uri /
/app3 -----> reverse proxy to app3 at its root uri /
Проблема, с которой мы сталкиваемся, заключается в том, что он всегда добавляет / app1 в вызов веб-сервера в серверной части, когда это необходимо. позвонить /.
И переписать все будет много работы, так как мы не владеем кодом для этого внутреннего веб-сервера, и кажется, что многие URI в приложении жестко закодированы.
Кто-нибудь уже пробовал это и нашел способ сделать это без переписывания?
с помощью следующего кода, я могу создать обратный прокси-сервер, который отвечает на root (" / "), используя другой порт. То, что я искал, - это сохранить один порт и использовать / app1, / app2 для перенаправления, но без добавления / app1 или / app2 к запросу вышестоящего сервера.
(я знаю, что код может быть улучшено, чтобы не повторять разбор URL в основном, но я исправлю это, когда найду решение своей проблемы)
package main
import (
"crypto/tls"
"errors"
"log"
"net/http"
"net/url"
"sync"
"time"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
var (
certLock = new(sync.RWMutex)
cert *tls.Certificate
)
func main() {
waf1, err := url.Parse("https://10.0.0.11:443")
if err != nil {
log.Fatal(err)
}
targets1 := []*middleware.ProxyTarget{
{
URL: waf1,
},
}
waf2, err := url.Parse("https://10.0.2.11:443")
if err != nil {
log.Fatal(err)
}
targets2 := []*middleware.ProxyTarget{
{
URL: waf2,
},
}
go server(":6001", targets1)
server(":6002", targets2)
}
func server(port string, targets1 []*middleware.ProxyTarget) {
e := echo.New()
e.HideBanner = true
e.Debug = true
e.Server.ReadTimeout = 10 * time.Second
e.Server.WriteTimeout = 2 * time.Minute
e.Use(middleware.Recover())
//e.Use(middleware.Logger())
e.TLSServer.TLSConfig = new(tls.Config)
e.TLSServer.TLSConfig.MinVersion = tls.VersionTLS12
e.TLSServer.TLSConfig.PreferServerCipherSuites = true
e.TLSServer.TLSConfig.CipherSuites = []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
}
c, err := tls.LoadX509KeyPair("tls_certificate.pem", "tls_private_key.pem")
if err != nil {
log.Fatalln(err.Error())
return
}
certLock.Lock()
cert = &c
certLock.Unlock()
// configure certificate load function and listen on https
e.TLSServer.TLSConfig.GetCertificate = GetCertificate
e.TLSServer.Addr = port
var defaultTransport http.RoundTripper = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
e.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{
Balancer: middleware.NewRoundRobinBalancer(targets1),
Transport: defaultTransport,
}))
e.Logger.Fatal(e.StartServer(e.TLSServer))
}
// GetCertificate extract certificate form PEM
func GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
certLock.RLock()
defer certLock.RUnlock()
if cert == nil {
return nil, errors.New("No certificate configured")
}
return cert, nil
}