blob: 0a1f440186b223180ccbfcb95d82b5d4be39b470 [file] [log] [blame]
// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package authn
import (
httppb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
"istio.io/pkg/log"
)
import (
"github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/plugin"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/security/authn"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/security/authn/factory"
)
var authnLog = log.RegisterScope("authn", "authn debugging", 0)
type Builder struct {
applier authn.PolicyApplier
trustDomains []string
proxy *model.Proxy
}
func NewBuilder(push *model.PushContext, proxy *model.Proxy) *Builder {
applier := factory.NewPolicyApplier(push, proxy.Metadata.Namespace, proxy.Metadata.Labels)
trustDomains := TrustDomainsForValidation(push.Mesh)
return &Builder{
applier: applier,
proxy: proxy,
trustDomains: trustDomains,
}
}
func (b *Builder) ForPort(port uint32) plugin.MTLSSettings {
if b == nil {
return plugin.MTLSSettings{
Port: port,
Mode: model.MTLSDisable,
}
}
return b.applier.InboundMTLSSettings(port, b.proxy, b.trustDomains)
}
func (b *Builder) ForPassthrough() []plugin.MTLSSettings {
if b == nil {
return []plugin.MTLSSettings{{
Port: 0,
Mode: model.MTLSDisable,
}}
}
// We need to create configuration for the passthrough,
// but also any ports that are not explicitly declared in the Service but are in the mTLS port level settings.
resp := []plugin.MTLSSettings{
// Full passthrough - no port match
b.applier.InboundMTLSSettings(0, b.proxy, b.trustDomains),
}
// Then generate the per-port passthrough filter chains.
for port := range b.applier.PortLevelSetting() {
// Skip the per-port passthrough filterchain if the port is already handled by InboundMTLSConfiguration().
if !needPerPortPassthroughFilterChain(port, b.proxy) {
continue
}
authnLog.Debugf("InboundMTLSConfiguration: build extra pass through filter chain for %v:%d", b.proxy.ID, port)
resp = append(resp, b.applier.InboundMTLSSettings(port, b.proxy, b.trustDomains))
}
return resp
}
func (b *Builder) BuildHTTP(class networking.ListenerClass) []*httppb.HttpFilter {
if b == nil {
return nil
}
if class == networking.ListenerClassSidecarOutbound {
// Only applies to inbound and gateways
return nil
}
res := []*httppb.HttpFilter{}
if filter := b.applier.JwtFilter(); filter != nil {
res = append(res, filter)
}
forSidecar := b.proxy.Type == model.SidecarProxy
if filter := b.applier.AuthNFilter(forSidecar); filter != nil {
res = append(res, filter)
}
return res
}
func needPerPortPassthroughFilterChain(port uint32, node *model.Proxy) bool {
// If there is any Sidecar defined, check if the port is explicitly defined there.
// This means the Sidecar resource takes precedence over the service. A port defined in service but not in Sidecar
// means the port is going to be handled by the pass through filter chain.
if node.SidecarScope.HasIngressListener() {
for _, ingressListener := range node.SidecarScope.Sidecar.Ingress {
if port == ingressListener.Port.Number {
return false
}
}
return true
}
// If there is no Sidecar, check if the port is appearing in any service.
for _, si := range node.ServiceInstances {
if port == si.Endpoint.EndpointPort {
return false
}
}
return true
}