Add docker security headers via labels

This commit is contained in:
Daniel Tomcej 2017-11-22 12:40:04 -06:00 committed by Traefiker
parent bee8ebb00b
commit 7063da1c7d
5 changed files with 369 additions and 50 deletions

View file

@ -205,6 +205,52 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
basicAuth = [{{range getBasicAuth $container}}
"{{.}}",
{{end}}]
[frontends."frontend-{{$frontend}}".headers]
{{if hasSSLRedirectHeaders $container}}
SSLRedirect = {{getSSLRedirectHeaders $container}}
{{end}}
{{if hasSSLTemporaryRedirectHeaders $container}}
SSLTemporaryRedirect = {{getSSLTemporaryRedirectHeaders $container}}
{{end}}
{{if hasSSLHostHeaders $container}}
SSLHost = {{getSSLHostHeaders $container}}
{{end}}
{{if hasSTSSecondsHeaders $container}}
STSSeconds = {{getSTSSecondsHeaders $container}}
{{end}}
{{if hasSTSIncludeSubdomainsHeaders $container}}
STSIncludeSubdomains = {{getSTSIncludeSubdomainsHeaders $container}}
{{end}}
{{if hasSTSPreloadHeaders $container}}
STSPreload = {{getSTSPreloadHeaders $container}}
{{end}}
{{if hasForceSTSHeaderHeaders $container}}
ForceSTSHeader = {{getForceSTSHeaderHeaders $container}}
{{end}}
{{if hasFrameDenyHeaders $container}}
FrameDeny = {{getFrameDenyHeaders $container}}
{{end}}
{{if hasCustomFrameOptionsValueHeaders $container}}
CustomFrameOptionsValue = {{getCustomFrameOptionsValueHeaders $container}}
{{end}}
{{if hasContentTypeNosniffHeaders $container}}
ContentTypeNosniff = {{getContentTypeNosniffHeaders $container}}
{{end}}
{{if hasBrowserXSSFilterHeaders $container}}
BrowserXSSFilter = {{getBrowserXSSFilterHeaders $container}}
{{end}}
{{if hasContentSecurityPolicyHeaders $container}}
ContentSecurityPolicy = {{getContentSecurityPolicyHeaders $container}}
{{end}}
{{if hasPublicKeyHeaders $container}}
PublicKey = {{getPublicKeyHeaders $container}}
{{end}}
{{if hasReferrerPolicyHeaders $container}}
ReferrerPolicy = {{getReferrerPolicyHeaders $container}}
{{end}}
{{if hasIsDevelopmentHeaders $container}}
IsDevelopment = {{getIsDevelopmentHeaders $container}}
{{end}}
{{if hasRequestHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.customrequestheaders]
{{range $k, $v := getRequestHeaders $container}}
@ -216,6 +262,24 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
{{range $k, $v := getResponseHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if hasAllowedHostsHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.AllowedHosts]
{{range getAllowedHostsHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasHostsProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.HostsProxyHeaders]
{{range getHostsProxyHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasSSLProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.SSLProxyHeaders]
{{range $k, $v := getSSLProxyHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
[frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"]
rule = "{{getFrontendRule $container}}"

View file

@ -169,11 +169,33 @@ Labels can be used on containers to override default behaviour.
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.headers.customrequestheaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.customresponseheaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: `HEADER:value,HEADER2:value2` |
| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. |
| `traefik.frontend.redirect=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) |
#### Security Headers
| Label | Description |
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed. Format: `Host1,Host2` |
|`traefik.frontend.headers.customrequestheaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.customresponseheaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: `HEADER:value,HEADER2:value2` |
|`traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` |
| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. |
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as X-Forwarded-For:https). Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the IncludeSubdomains section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. |
| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. |
| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. |
| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. |
| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. |
| `traefik.frontend.headers.publicKey=VALUE` | Adds pinned HTST public key header. |
| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. |
| `traefik.frontend.headers.isDevelopment=false` | This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false. |
### On Service
Services labels can be used for overriding default behaviour

View file

@ -260,46 +260,82 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
func (p *Provider) loadDockerConfig(containersInspected []dockerData) *types.Configuration {
var DockerFuncMap = template.FuncMap{
"getBackend": p.getBackend,
"getIPAddress": p.getIPAddress,
"getPort": p.getPort,
"getWeight": p.getWeight,
"getDomain": p.getDomain,
"getProtocol": p.getProtocol,
"getPassHostHeader": p.getPassHostHeader,
"getPriority": p.getPriority,
"getEntryPoints": p.getEntryPoints,
"getBasicAuth": p.getBasicAuth,
"getFrontendRule": p.getFrontendRule,
"getRedirect": p.getRedirect,
"hasCircuitBreakerLabel": p.hasCircuitBreakerLabel,
"getCircuitBreakerExpression": p.getCircuitBreakerExpression,
"hasLoadBalancerLabel": p.hasLoadBalancerLabel,
"getLoadBalancerMethod": p.getLoadBalancerMethod,
"hasMaxConnLabels": p.hasMaxConnLabels,
"getMaxConnAmount": p.getMaxConnAmount,
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
"getSticky": p.getSticky,
"getStickinessCookieName": p.getStickinessCookieName,
"hasStickinessLabel": p.hasStickinessLabel,
"getIsBackendLBSwarm": p.getIsBackendLBSwarm,
"hasServices": p.hasServices,
"getServiceNames": p.getServiceNames,
"getServicePort": p.getServicePort,
"getServiceWeight": p.getServiceWeight,
"getServiceProtocol": p.getServiceProtocol,
"getServiceEntryPoints": p.getServiceEntryPoints,
"getServiceBasicAuth": p.getServiceBasicAuth,
"getServiceFrontendRule": p.getServiceFrontendRule,
"getServicePassHostHeader": p.getServicePassHostHeader,
"getServicePriority": p.getServicePriority,
"getServiceBackend": p.getServiceBackend,
"getServiceRedirect": p.getServiceRedirect,
"getWhitelistSourceRange": p.getWhitelistSourceRange,
"getRequestHeaders": p.getRequestHeaders,
"getResponseHeaders": p.getResponseHeaders,
"hasRequestHeaders": p.hasRequestHeaders,
"hasResponseHeaders": p.hasResponseHeaders,
"getBackend": p.getBackend,
"getIPAddress": p.getIPAddress,
"getPort": p.getPort,
"getWeight": p.getWeight,
"getDomain": p.getDomain,
"getProtocol": p.getProtocol,
"getPassHostHeader": p.getPassHostHeader,
"getPriority": p.getPriority,
"getEntryPoints": p.getEntryPoints,
"getBasicAuth": p.getBasicAuth,
"getFrontendRule": p.getFrontendRule,
"getRedirect": p.getRedirect,
"hasCircuitBreakerLabel": p.hasCircuitBreakerLabel,
"getCircuitBreakerExpression": p.getCircuitBreakerExpression,
"hasLoadBalancerLabel": p.hasLoadBalancerLabel,
"getLoadBalancerMethod": p.getLoadBalancerMethod,
"hasMaxConnLabels": p.hasMaxConnLabels,
"getMaxConnAmount": p.getMaxConnAmount,
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
"getSticky": p.getSticky,
"getStickinessCookieName": p.getStickinessCookieName,
"hasStickinessLabel": p.hasStickinessLabel,
"getIsBackendLBSwarm": p.getIsBackendLBSwarm,
"hasServices": p.hasServices,
"getServiceNames": p.getServiceNames,
"getServicePort": p.getServicePort,
"getServiceWeight": p.getServiceWeight,
"getServiceProtocol": p.getServiceProtocol,
"getServiceEntryPoints": p.getServiceEntryPoints,
"getServiceBasicAuth": p.getServiceBasicAuth,
"getServiceFrontendRule": p.getServiceFrontendRule,
"getServicePassHostHeader": p.getServicePassHostHeader,
"getServicePriority": p.getServicePriority,
"getServiceBackend": p.getServiceBackend,
"getServiceRedirect": p.getServiceRedirect,
"getWhitelistSourceRange": p.getWhitelistSourceRange,
"hasRequestHeaders": p.hasLabel(types.LabelFrontendRequestHeader),
"getRequestHeaders": p.getRequestHeaders,
"hasResponseHeaders": p.hasLabel(types.LabelFrontendResponseHeader),
"getResponseHeaders": p.getResponseHeaders,
"hasAllowedHostsHeaders": p.hasLabel(types.LabelFrontendAllowedHosts),
"getAllowedHostsHeaders": p.getAllowedHostsHeaders,
"hasHostsProxyHeaders": p.hasLabel(types.LabelFrontendHostsProxyHeaders),
"getHostsProxyHeaders": p.getHostsProxyHeaders,
"hasSSLRedirectHeaders": p.hasLabel(types.LabelFrontendSSLRedirect),
"getSSLRedirectHeaders": p.getSSLRedirectHeaders,
"hasSSLTemporaryRedirectHeaders": p.hasLabel(types.LabelFrontendSSLTemporaryRedirect),
"getSSLTemporaryRedirectHeaders": p.getSSLTemporaryRedirectHeaders,
"hasSSLHostHeaders": p.hasLabel(types.LabelFrontendSSLHost),
"getSSLHostHeaders": p.getSSLHostHeaders,
"hasSSLProxyHeaders": p.hasLabel(types.LabelFrontendSSLProxyHeaders),
"getSSLProxyHeaders": p.getSSLProxyHeaders,
"hasSTSSecondsHeaders": p.hasLabel(types.LabelFrontendSTSSeconds),
"getSTSSecondsHeaders": p.getSTSSecondsHeaders,
"hasSTSIncludeSubdomainsHeaders": p.hasLabel(types.LabelFrontendSTSIncludeSubdomains),
"getSTSIncludeSubdomainsHeaders": p.getSTSIncludeSubdomainsHeaders,
"hasSTSPreloadHeaders": p.hasLabel(types.LabelFrontendSTSPreload),
"getSTSPreloadHeaders": p.getSTSPreloadHeaders,
"hasForceSTSHeaderHeaders": p.hasLabel(types.LabelFrontendForceSTSHeader),
"getForceSTSHeaderHeaders": p.getForceSTSHeaderHeaders,
"hasFrameDenyHeaders": p.hasLabel(types.LabelFrontendFrameDeny),
"getFrameDenyHeaders": p.getFrameDenyHeaders,
"hasCustomFrameOptionsValueHeaders": p.hasLabel(types.LabelFrontendCustomFrameOptionsValue),
"getCustomFrameOptionsValueHeaders": p.getCustomFrameOptionsValueHeaders,
"hasContentTypeNosniffHeaders": p.hasLabel(types.LabelFrontendContentTypeNosniff),
"getContentTypeNosniffHeaders": p.getContentTypeNosniffHeaders,
"hasBrowserXSSFilterHeaders": p.hasLabel(types.LabelFrontendBrowserXSSFilter),
"getBrowserXSSFilterHeaders": p.getBrowserXSSFilterHeaders,
"hasContentSecurityPolicyHeaders": p.hasLabel(types.LabelFrontendContentSecurityPolicy),
"getContentSecurityPolicyHeaders": p.getContentSecurityPolicyHeaders,
"hasPublicKeyHeaders": p.hasLabel(types.LabelFrontendPublicKey),
"getPublicKeyHeaders": p.getPublicKeyHeaders,
"hasReferrerPolicyHeaders": p.hasLabel(types.LabelFrontendReferrerPolicy),
"getReferrerPolicyHeaders": p.getReferrerPolicyHeaders,
"hasIsDevelopmentHeaders": p.hasLabel(types.LabelFrontendIsDevelopment),
"getIsDevelopmentHeaders": p.getIsDevelopmentHeaders,
}
// filter containers
filteredContainers := fun.Filter(func(container dockerData) bool {
@ -807,14 +843,11 @@ func (p *Provider) getBasicAuth(container dockerData) []string {
return []string{}
}
func (p *Provider) hasRequestHeaders(container dockerData) bool {
label, err := getLabel(container, types.LabelFrontendRequestHeader)
return err == nil && len(label) > 0
}
func (p *Provider) hasResponseHeaders(container dockerData) bool {
label, err := getLabel(container, types.LabelFrontendResponseHeader)
return err == nil && len(label) > 0
func (p *Provider) hasLabel(label string) func(container dockerData) bool {
return func(container dockerData) bool {
label, err := getLabel(container, label)
return err == nil && len(label) > 0
}
}
func (p *Provider) getRequestHeaders(container dockerData) map[string]string {
@ -843,6 +876,124 @@ func parseCustomHeaders(container dockerData, containerType string) map[string]s
return customHeaders
}
func (p *Provider) getAllowedHostsHeaders(container dockerData) []string {
return getSliceStringHeaders(container, types.LabelFrontendAllowedHosts)
}
func (p *Provider) getHostsProxyHeaders(container dockerData) []string {
return getSliceStringHeaders(container, types.LabelFrontendHostsProxyHeaders)
}
func (p *Provider) getSSLRedirectHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendSSLRedirect)
}
func (p *Provider) getSSLTemporaryRedirectHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendSSLTemporaryRedirect)
}
func (p *Provider) getSSLHostHeaders(container dockerData) string {
label, _ := getLabel(container, types.LabelFrontendSSLHost)
return label
}
func (p *Provider) getSSLProxyHeaders(container dockerData) map[string]string {
ProxyHeaders := make(map[string]string)
if label, err := getLabel(container, types.LabelFrontendSSLProxyHeaders); err == nil {
for _, headers := range strings.Split(label, ",") {
pair := strings.Split(headers, ":")
if len(pair) != 2 {
log.Warnf("Could not load header %v, skipping...", pair)
} else {
ProxyHeaders[pair[0]] = pair[1]
}
}
}
if len(ProxyHeaders) == 0 {
log.Errorf("Could not load any SSL Proxy Headers")
}
return ProxyHeaders
}
func (p *Provider) getSTSSecondsHeaders(container dockerData) int64 {
label, _ := getLabel(container, types.LabelFrontendSTSSeconds)
i, err := strconv.ParseInt(label, 10, 64)
if err == nil && i > 0 {
return i
}
return 0
}
func (p *Provider) getSTSIncludeSubdomainsHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendSTSIncludeSubdomains)
}
func (p *Provider) getSTSPreloadHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendSTSPreload)
}
func (p *Provider) getForceSTSHeaderHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendForceSTSHeader)
}
func (p *Provider) getFrameDenyHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendFrameDeny)
}
func (p *Provider) getCustomFrameOptionsValueHeaders(container dockerData) string {
label, _ := getLabel(container, types.LabelFrontendCustomFrameOptionsValue)
return label
}
func (p *Provider) getContentTypeNosniffHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendContentTypeNosniff)
}
func (p *Provider) getBrowserXSSFilterHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendBrowserXSSFilter)
}
func (p *Provider) getContentSecurityPolicyHeaders(container dockerData) string {
label, _ := getLabel(container, types.LabelFrontendContentSecurityPolicy)
return label
}
func (p *Provider) getPublicKeyHeaders(container dockerData) string {
label, _ := getLabel(container, types.LabelFrontendPublicKey)
return label
}
func (p *Provider) getReferrerPolicyHeaders(container dockerData) string {
label, _ := getLabel(container, types.LabelFrontendReferrerPolicy)
return label
}
func (p *Provider) getIsDevelopmentHeaders(container dockerData) bool {
return getBoolHeader(container, types.LabelFrontendIsDevelopment)
}
func getSliceStringHeaders(container dockerData, containerType string) []string {
value := []string{}
if label, err := getLabel(container, containerType); err == nil {
for _, sublabels := range strings.Split(label, ",") {
if len(sublabels) == 0 {
log.Warnf("Could not load header %v, skipping", sublabels)
} else {
value = append(value, sublabels)
}
}
}
if len(value) == 0 {
log.Errorf("Could not load %v headers", containerType)
}
return value
}
func getBoolHeader(container dockerData, containerType string) bool {
label, err := getLabel(container, containerType)
return err == nil && len(label) > 0 && strings.EqualFold(strings.TrimSpace(label), "true")
}
func (p *Provider) getRedirect(container dockerData) string {
if entryPointredirect, err := getLabel(container, types.LabelFrontendRedirect); err == nil {
return entryPointredirect

View file

@ -80,6 +80,52 @@
basicAuth = [{{range getBasicAuth $container}}
"{{.}}",
{{end}}]
[frontends."frontend-{{$frontend}}".headers]
{{if hasSSLRedirectHeaders $container}}
SSLRedirect = {{getSSLRedirectHeaders $container}}
{{end}}
{{if hasSSLTemporaryRedirectHeaders $container}}
SSLTemporaryRedirect = {{getSSLTemporaryRedirectHeaders $container}}
{{end}}
{{if hasSSLHostHeaders $container}}
SSLHost = {{getSSLHostHeaders $container}}
{{end}}
{{if hasSTSSecondsHeaders $container}}
STSSeconds = {{getSTSSecondsHeaders $container}}
{{end}}
{{if hasSTSIncludeSubdomainsHeaders $container}}
STSIncludeSubdomains = {{getSTSIncludeSubdomainsHeaders $container}}
{{end}}
{{if hasSTSPreloadHeaders $container}}
STSPreload = {{getSTSPreloadHeaders $container}}
{{end}}
{{if hasForceSTSHeaderHeaders $container}}
ForceSTSHeader = {{getForceSTSHeaderHeaders $container}}
{{end}}
{{if hasFrameDenyHeaders $container}}
FrameDeny = {{getFrameDenyHeaders $container}}
{{end}}
{{if hasCustomFrameOptionsValueHeaders $container}}
CustomFrameOptionsValue = {{getCustomFrameOptionsValueHeaders $container}}
{{end}}
{{if hasContentTypeNosniffHeaders $container}}
ContentTypeNosniff = {{getContentTypeNosniffHeaders $container}}
{{end}}
{{if hasBrowserXSSFilterHeaders $container}}
BrowserXSSFilter = {{getBrowserXSSFilterHeaders $container}}
{{end}}
{{if hasContentSecurityPolicyHeaders $container}}
ContentSecurityPolicy = {{getContentSecurityPolicyHeaders $container}}
{{end}}
{{if hasPublicKeyHeaders $container}}
PublicKey = {{getPublicKeyHeaders $container}}
{{end}}
{{if hasReferrerPolicyHeaders $container}}
ReferrerPolicy = {{getReferrerPolicyHeaders $container}}
{{end}}
{{if hasIsDevelopmentHeaders $container}}
IsDevelopment = {{getIsDevelopmentHeaders $container}}
{{end}}
{{if hasRequestHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.customrequestheaders]
{{range $k, $v := getRequestHeaders $container}}
@ -91,6 +137,24 @@
{{range $k, $v := getResponseHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if hasAllowedHostsHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.AllowedHosts]
{{range getAllowedHostsHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasHostsProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.HostsProxyHeaders]
{{range getHostsProxyHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasSSLProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.SSLProxyHeaders]
{{range $k, $v := getSSLProxyHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
[frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"]
rule = "{{getFrontendRule $container}}"

View file

@ -16,6 +16,24 @@ const (
LabelFrontendEntryPoints = LabelPrefix + "frontend.entryPoints"
LabelFrontendRequestHeader = LabelPrefix + "frontend.headers.customrequestheaders"
LabelFrontendResponseHeader = LabelPrefix + "frontend.headers.customresponseheaders"
LabelFrontendAllowedHosts = LabelPrefix + "frontend.headers.allowedHosts"
LabelFrontendHostsProxyHeaders = LabelPrefix + "frontend.headers.hostsProxyHeaders"
LabelFrontendSSLRedirect = LabelPrefix + "frontend.headers.SSLRedirect"
LabelFrontendSSLTemporaryRedirect = LabelPrefix + "frontend.headers.SSLTemporaryRedirect"
LabelFrontendSSLHost = LabelPrefix + "frontend.headers.SSLHost"
LabelFrontendSSLProxyHeaders = LabelPrefix + "frontend.headers.SSLProxyHeaders"
LabelFrontendSTSSeconds = LabelPrefix + "frontend.headers.STSSeconds"
LabelFrontendSTSIncludeSubdomains = LabelPrefix + "frontend.headers.STSIncludeSubdomains"
LabelFrontendSTSPreload = LabelPrefix + "frontend.headers.STSPreload"
LabelFrontendForceSTSHeader = LabelPrefix + "frontend.headers.forceSTSHeader"
LabelFrontendFrameDeny = LabelPrefix + "frontend.headers.frameDeny"
LabelFrontendCustomFrameOptionsValue = LabelPrefix + "frontend.headers.customFrameOptionsValue"
LabelFrontendContentTypeNosniff = LabelPrefix + "frontend.headers.contentTypeNosniff"
LabelFrontendBrowserXSSFilter = LabelPrefix + "frontend.headers.browserXSSFilter"
LabelFrontendContentSecurityPolicy = LabelPrefix + "frontend.headers.contentSecurityPolicy"
LabelFrontendPublicKey = LabelPrefix + "frontend.headers.publicKey"
LabelFrontendReferrerPolicy = LabelPrefix + "frontend.headers.referrerPolicy"
LabelFrontendIsDevelopment = LabelPrefix + "frontend.headers.isDevelopment"
LabelFrontendPassHostHeader = LabelPrefix + "frontend.passHostHeader"
LabelFrontendPassTLSCert = LabelPrefix + "frontend.passTLSCert"
LabelFrontendPriority = LabelPrefix + "frontend.priority"