allow custom https and http ports

This commit is contained in:
Umputun
2021-04-03 01:20:24 -05:00
parent 79f0514294
commit d45415080a
4 changed files with 51 additions and 21 deletions

View File

@@ -27,11 +27,12 @@ var opts struct {
ProxyHeaders []string `short:"x" long:"header" env:"HEADER" description:"proxy headers"`
SSL struct {
Type string `long:"type" env:"TYPE" description:"ssl (auto) support" choice:"none" choice:"static" choice:"auto" default:"none"` //nolint
Cert string `long:"cert" env:"CERT" description:"path to cert.pem file"`
Key string `long:"key" env:"KEY" description:"path to key.pem file"`
ACMELocation string `long:"acme-location" env:"ACME_LOCATION" description:"dir where certificates will be stored by autocert manager" default:"./var/acme"`
ACMEEmail string `long:"acme-email" env:"ACME_EMAIL" description:"admin email for certificate notifications"`
Type string `long:"type" env:"TYPE" description:"ssl (auto) support" choice:"none" choice:"static" choice:"auto" default:"none"` //nolint
Cert string `long:"cert" env:"CERT" description:"path to cert.pem file"`
Key string `long:"key" env:"KEY" description:"path to key.pem file"`
ACMELocation string `long:"acme-location" env:"ACME_LOCATION" description:"dir where certificates will be stored by autocert manager" default:"./var/acme"`
ACMEEmail string `long:"acme-email" env:"ACME_EMAIL" description:"admin email for certificate notifications"`
RedirHttpPort int `long:"http-port" env:"HTTP_PORT" description:"http port for redirect to https and acme challenge test"`
} `group:"ssl" namespace:"ssl" env-namespace:"SSL"`
Assets struct {
@@ -161,10 +162,12 @@ func makeSSLConfig() (config proxy.SSLConfig, err error) {
config.SSLMode = proxy.SSLStatic
config.Cert = opts.SSL.Cert
config.Key = opts.SSL.Key
config.RedirHttpPort = opts.SSL.RedirHttpPort
case "auto":
config.SSLMode = proxy.SSLAuto
config.ACMELocation = opts.SSL.ACMELocation
config.ACMEEmail = opts.SSL.ACMEEmail
config.RedirHttpPort = opts.SSL.RedirHttpPort
}
return config, err
}

View File

@@ -5,6 +5,8 @@ import (
"net/http"
"net/http/httputil"
"net/url"
"regexp"
"strconv"
"strings"
"time"
@@ -16,6 +18,7 @@ import (
"github.com/pkg/errors"
)
// Http is a proxy server for both http and https
type Http struct {
Matcher
Address string
@@ -29,6 +32,8 @@ type Http struct {
Version string
}
// Matcher source info (server and route) to the destination url
// If no match found return ok=false
type Matcher interface {
Match(srv, src string) (string, bool)
}
@@ -78,11 +83,11 @@ func (h *Http) Run(ctx context.Context) error {
httpsServer = h.makeHTTPSServer(h.Address, handler)
httpsServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
httpServer = h.makeHTTPServer(h.toHttp(h.Address), h.httpToHTTPSRouter())
httpServer = h.makeHTTPServer(h.toHttp(h.Address, h.SSLConfig.RedirHttpPort), h.httpToHTTPSRouter())
httpServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
go func() {
log.Printf("[INFO] activate http redirect server on %s", h.toHttp(h.Address))
log.Printf("[INFO] activate http redirect server on %s", h.toHttp(h.Address, h.SSLConfig.RedirHttpPort))
err := httpServer.ListenAndServe()
log.Printf("[WARN] http redirect server terminated, %s", err)
}()
@@ -94,11 +99,11 @@ func (h *Http) Run(ctx context.Context) error {
httpsServer = h.makeHTTPSAutocertServer(h.Address, handler, m)
httpsServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
httpServer = h.makeHTTPServer(h.toHttp(h.Address), h.httpChallengeRouter(m))
httpServer = h.makeHTTPServer(h.toHttp(h.Address, h.SSLConfig.RedirHttpPort), h.httpChallengeRouter(m))
httpServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
go func() {
log.Printf("[INFO] activate http challenge server on port %s", h.toHttp(h.Address))
log.Printf("[INFO] activate http challenge server on port %s", h.toHttp(h.Address, h.SSLConfig.RedirHttpPort))
err := httpServer.ListenAndServe()
log.Printf("[WARN] http challenge server terminated, %s", err)
}()
@@ -108,8 +113,9 @@ func (h *Http) Run(ctx context.Context) error {
return errors.Errorf("unknown SSL type %v", h.SSLConfig.SSLMode)
}
func (h *Http) toHttp(address string) string {
return strings.Replace(address, ":443", ":80", 1)
func (h *Http) toHttp(address string, httpPort int) string {
rx := regexp.MustCompile(`(.*):(\d*)`)
return rx.ReplaceAllString(address, "$1:") + strconv.Itoa(httpPort)
}
func (h *Http) gzipHandler() func(next http.Handler) http.Handler {

View File

@@ -37,14 +37,12 @@ func TestHttp_Do(t *testing.T) {
}})
go func() {
err := svc.Run(context.Background())
assert.Equal(t, context.DeadlineExceeded, err)
_ = svc.Run(context.Background())
}()
h.Matcher = svc
go func() {
err := h.Run(ctx)
assert.Equal(t, context.DeadlineExceeded, err)
_ = h.Run(ctx)
}()
time.Sleep(10 * time.Millisecond)
@@ -86,3 +84,25 @@ func TestHttp_Do(t *testing.T) {
}
}
func TestHttp_toHttp(t *testing.T) {
tbl := []struct {
addr string
port int
res string
}{
{"localhost:1234", 80, "localhost:80"},
{"m.example.com:443", 8080, "m.example.com:8080"},
{"192.168.1.1:1443", 8080, "192.168.1.1:8080"},
}
h := Http{}
for i, tt := range tbl {
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
assert.Equal(t, tt.res, h.toHttp(tt.addr, tt.port))
})
}
}

View File

@@ -28,12 +28,13 @@ const (
// SSLConfig holds all ssl params for rest server
type SSLConfig struct {
SSLMode sslMode
Cert string
Key string
ACMELocation string
ACMEEmail string
FQDNs []string
SSLMode sslMode
Cert string
Key string
ACMELocation string
ACMEEmail string
FQDNs []string
RedirHttpPort int
}
// httpToHTTPSRouter creates new router which does redirect from http to https server