Skip to content

Commit

Permalink
Add proxy to the acme challenge server
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmoraisjr committed Sep 23, 2019
1 parent ddfab1a commit 1f1aa9b
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 4 deletions.
5 changes: 5 additions & 0 deletions pkg/acme/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Signer interface {
AddHosts(hosts []string, secret string)
ClearHosts()
HasAccount() bool
Socket() string
Verify(interval time.Duration)
}

Expand Down Expand Up @@ -116,6 +117,10 @@ func (s *signer) HasAccount() bool {
return s.account.Endpoint != "" && s.account.Emails != ""
}

func (s *signer) Socket() string {
return s.socket
}

func (s *signer) Verify(interval time.Duration) {
if s.running {
// a verification is still running on another goroutine
Expand Down
5 changes: 5 additions & 0 deletions pkg/converters/helper_test/acmemock.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func (m *AcmeMock) HasAccount() bool {
return false
}

// Socket ...
func (m *AcmeMock) Socket() string {
return ""
}

// Verify ...
func (m *AcmeMock) Verify(interval time.Duration) {
}
7 changes: 7 additions & 0 deletions pkg/converters/ingress/annotations/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ func (c *updater) buildGlobalCertSigner(d *globalData) {
if endpoint := d.mapper.Get(ingtypes.GlobalAcmeEndpoint).Value; endpoint != "" {
emails := d.mapper.Get(ingtypes.GlobalAcmeEmails).Value
c.acme.AcmeAccount(endpoint, emails)
if c.acme.HasAccount() {
acme := &d.global.Acme
acme.Enabled = true
acme.Prefix = "/.well-known/acme-challenge/"
acme.Shared = d.mapper.Get(ingtypes.GlobalAcmeShared).Bool()
acme.Socket = c.acme.Socket()
}
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/converters/ingress/types/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package types
const (
GlobalAcmeEmails = "acme-emails"
GlobalAcmeEndpoint = "acme-endpoint"
GlobalAcmeShared = "acme-shared"
GlobalBindIPAddrHealthz = "bind-ip-addr-healthz"
GlobalBindIPAddrHTTP = "bind-ip-addr-http"
GlobalBindIPAddrStats = "bind-ip-addr-stats"
Expand Down
73 changes: 73 additions & 0 deletions pkg/haproxy/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,79 @@ backend d1_app_8080
}
}

func TestAcme(t *testing.T) {
testCases := []struct {
shared bool
expected string
}{
{
shared: false,
expected: `
frontend _front_http
mode http
bind :80
acl acme-challenge path_beg /.acme
http-request set-var(req.base) base,regsub(:[0-9]+/,/)
http-request redirect scheme https if !acme-challenge { var(req.base),map_beg(/etc/haproxy/maps/_global_https_redir.map,_nomatch) yes }
<<http-headers>>
http-request set-var(req.backend) var(req.base),map_beg(/etc/haproxy/maps/_global_http_front.map,_nomatch)
use_backend _acme_challenge if acme-challenge
use_backend %[var(req.backend)] unless { var(req.backend) _nomatch }
default_backend _error404`,
},
{
shared: true,
expected: `
frontend _front_http
mode http
bind :80
acl acme-challenge path_beg /.acme
http-request set-var(req.base) base,regsub(:[0-9]+/,/)
http-request redirect scheme https if { var(req.base),map_beg(/etc/haproxy/maps/_global_https_redir.map,_nomatch) yes }
<<http-headers>>
http-request set-var(req.backend) var(req.base),map_beg(/etc/haproxy/maps/_global_http_front.map,_nomatch)
use_backend %[var(req.backend)] unless { var(req.backend) _nomatch }
use_backend _acme_challenge if acme-challenge
default_backend _error404`,
},
}
for _, test := range testCases {
c := setup(t)

var h *hatypes.Host
var b *hatypes.Backend

b = c.config.AcquireBackend("d1", "app", "8080")
b.Endpoints = []*hatypes.Endpoint{endpointS1}
h = c.config.AcquireHost("d1.local")
h.AddPath(b, "/")

acme := &c.config.Global().Acme
acme.Enabled = true
acme.Prefix = "/.acme"
acme.Socket = "/run/acme.sock"
acme.Shared = test.shared

c.Update()
c.checkConfig(`
<<global>>
<<defaults>>
backend d1_app_8080
mode http
server s1 172.17.0.11:8080 weight 100
backend _acme_challenge
mode http
server _acme_server unix@/run/acme.sock
<<backends-default>>` + test.expected + `
<<frontend-https>>
default_backend _error404
<<support>>
`)
c.logger.CompareLogging(defaultLogging)
c.teardown()
}
}

func TestStatsHealthz(t *testing.T) {
testCases := []struct {
stats hatypes.StatsConfig
Expand Down
9 changes: 9 additions & 0 deletions pkg/haproxy/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Global struct {
ModSecurity ModSecurityConfig
Cookie CookieConfig
DrainSupport DrainConfig
Acme AcmeConfig
ForwardFor string
LoadServerState bool
AdminSocket string
Expand Down Expand Up @@ -137,6 +138,14 @@ type DrainConfig struct {
Redispatch bool
}

// AcmeConfig ...
type AcmeConfig struct {
Enabled bool
Prefix string
Shared bool
Socket string
}

// HealthzConfig ...
type HealthzConfig struct {
BindIP string
Expand Down
39 changes: 35 additions & 4 deletions rootfs/etc/haproxy/template/haproxy.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,17 @@ backend {{ $backend.ID }}
{{- end }}
{{- end }}

{{- if $global.Acme.Enabled }}

# # # # # # # # # # # # # # # # # # #
# #
# acme challenge server
#
backend _acme_challenge
mode http
server _acme_server unix@{{ $global.Acme.Socket }}
{{- end }}

{{- if $cfg.Backends }}

# # # # # # # # # # # # # # # # # # #
Expand Down Expand Up @@ -651,18 +662,30 @@ frontend _front_http
{{- end }}
{{- end }}

{{- /*------------------------------------*/}}
{{- if $global.Acme.Enabled }}
acl acme-challenge path_beg {{ $global.Acme.Prefix }}
{{- end }}

{{- /*------------------------------------*/}}
http-request set-var(req.base) base,regsub(:[0-9]+/,/)

{{- /*------------------------------------*/}}
{{- $acmeexclusive := and $global.Acme.Enabled (not $global.Acme.Shared) }}
{{- if $fgroup.HTTPSRedirMap.HasRegex }}
http-request set-var(req.redir)
{{- "" }} var(req.base),map_beg({{ $fgroup.HTTPSRedirMap.MatchFile }},_nomatch)
http-request redirect scheme https if { var(req.redir) yes }
http-request redirect scheme https if { var(req.redir) _nomatch }
http-request redirect scheme https
{{- "" }} if{{- if $acmeexclusive }} !acme-challenge{{ end }}
{{- "" }} { var(req.redir) yes }
http-request redirect scheme https
{{- "" }} if{{- if $acmeexclusive }} !acme-challenge{{ end }}
{{- "" }} { var(req.redir) _nomatch }
{{- "" }} { var(req.base),map_reg({{ $fgroup.HTTPSRedirMap.RegexFile }},_nomatch) yes }
{{- else }}
http-request redirect scheme https if { var(req.base),map_beg({{ $fgroup.HTTPSRedirMap.MatchFile }},_nomatch) yes }
http-request redirect scheme https
{{- "" }} if{{- if $acmeexclusive }} !acme-challenge{{ end }}
{{- "" }} { var(req.base),map_beg({{ $fgroup.HTTPSRedirMap.MatchFile }},_nomatch) yes }
{{- end }}

{{- /*------------------------------------*/}}
Expand All @@ -674,7 +697,9 @@ frontend _front_http
http-request set-var(req.rootredir)
{{- "" }} var(req.host),map_reg({{ $fgroup.HTTPRootRedirMap.RegexFile }},_nomatch) if { var(req.rootredir) _nomatch }
{{- end }}
http-request redirect location %[var(req.rootredir)] if { path / } !{ var(req.rootredir) _nomatch }
http-request redirect location %[var(req.rootredir)]
{{- "" }} if{{- if $acmeexclusive }} !acme-challenge{{ end }}
{{- "" }} { path / } !{ var(req.rootredir) _nomatch }
{{- end }}

{{- /*------------------------------------*/}}
Expand All @@ -690,8 +715,14 @@ frontend _front_http
http-request set-var(req.backend)
{{- "" }} var(req.base),map_reg({{ $fgroup.HTTPFrontsMap.RegexFile }},_nomatch)
{{- "" }} if { var(req.backend) _nomatch }
{{- end }}
{{- if $acmeexclusive }}
use_backend _acme_challenge if acme-challenge
{{- end }}
use_backend %[var(req.backend)] unless { var(req.backend) _nomatch }
{{- if and $global.Acme.Enabled $global.Acme.Shared }}
use_backend _acme_challenge if acme-challenge
{{- end }}

{{- template "defaultbackend" map $cfg }}

Expand Down

0 comments on commit 1f1aa9b

Please sign in to comment.