Check and complete intermediate SSL certificates

This commit is contained in:
Manuel Alejandro de Brito Fontes 2019-07-04 18:06:55 -04:00
parent edf2b03c22
commit 8807db9748
No known key found for this signature in database
GPG key ID: 786136016A8BA02A
13 changed files with 132 additions and 214 deletions

View file

@ -20,16 +20,14 @@ import (
"fmt"
"strings"
"github.com/imdario/mergo"
"k8s.io/klog"
apiv1 "k8s.io/api/core/v1"
networking "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/ingress-nginx/internal/file"
"k8s.io/ingress-nginx/internal/ingress"
"k8s.io/ingress-nginx/internal/k8s"
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
"k8s.io/ingress-nginx/internal/net/ssl"
)
@ -103,7 +101,7 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
return nil, fmt.Errorf("unexpected error creating SSL Cert: %v", err)
}
if !s.isDynamicCertificatesEnabled || len(ca) > 0 {
if !ngx_config.EnableDynamicCertificates || len(ca) > 0 {
err = ssl.StoreSSLCertOnDisk(s.filesystem, nsSecName, sslCert)
if err != nil {
return nil, fmt.Errorf("error while storing certificate and key: %v", err)
@ -152,57 +150,6 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
return sslCert, nil
}
func (s *k8sStore) checkSSLChainIssues() {
for _, item := range s.ListLocalSSLCerts() {
secrKey := k8s.MetaNamespaceKey(item)
secret, err := s.GetLocalSSLCert(secrKey)
if err != nil {
continue
}
if secret.FullChainPemFileName != "" {
// chain already checked
continue
}
data, err := ssl.FullChainCert(secret.PemFileName, s.filesystem)
if err != nil {
klog.Errorf("Error generating CA certificate chain for Secret %q: %v", secrKey, err)
continue
}
fullChainPemFileName := fmt.Sprintf("%v/%v-%v-full-chain.pem", file.DefaultSSLDirectory, secret.Namespace, secret.Name)
file, err := s.filesystem.Create(fullChainPemFileName)
if err != nil {
klog.Errorf("Error creating SSL certificate file for Secret %q: %v", secrKey, err)
continue
}
_, err = file.Write(data)
if err != nil {
klog.Errorf("Error creating SSL certificate for Secret %q: %v", secrKey, err)
continue
}
dst := &ingress.SSLCert{}
err = mergo.MergeWithOverwrite(dst, secret)
if err != nil {
klog.Errorf("Error creating SSL certificate for Secret %q: %v", secrKey, err)
continue
}
dst.FullChainPemFileName = fullChainPemFileName
klog.Infof("Updating local copy of SSL certificate %q with missing intermediate CA certs", secrKey)
s.sslStore.Update(secrKey, dst)
// this update must trigger an update
// (like an update event from a change in Ingress)
s.sendDummyEvent()
}
}
// sendDummyEvent sends a dummy event to trigger an update
// This is used in when a secret change
func (s *k8sStore) sendDummyEvent() {

View file

@ -35,7 +35,6 @@ import (
"k8s.io/apimachinery/pkg/labels"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes"
@ -187,8 +186,6 @@ func (i *Informer) Run(stopCh chan struct{}) {
// k8sStore internal Storer implementation using informers and thread safe stores
type k8sStore struct {
isOCSPCheckEnabled bool
// backendConfig contains the running configuration from the configmap
// this is required because this rarely changes but is a very expensive
// operation to execute in each OnUpdate invocation
@ -224,36 +221,31 @@ type k8sStore struct {
defaultSSLCertificate string
isDynamicCertificatesEnabled bool
pod *k8s.PodInfo
}
// New creates a new object store to be used in the ingress controller
func New(checkOCSP bool,
func New(
namespace, configmap, tcp, udp, defaultSSLCertificate string,
resyncPeriod time.Duration,
client clientset.Interface,
fs file.Filesystem,
updateCh *channels.RingChannel,
isDynamicCertificatesEnabled bool,
pod *k8s.PodInfo,
disableCatchAll bool) Storer {
store := &k8sStore{
isOCSPCheckEnabled: checkOCSP,
informers: &Informer{},
listers: &Lister{},
sslStore: NewSSLCertTracker(),
filesystem: fs,
updateCh: updateCh,
backendConfig: ngx_config.NewDefault(),
syncSecretMu: &sync.Mutex{},
backendConfigMu: &sync.RWMutex{},
secretIngressMap: NewObjectRefMap(),
defaultSSLCertificate: defaultSSLCertificate,
isDynamicCertificatesEnabled: isDynamicCertificatesEnabled,
pod: pod,
informers: &Informer{},
listers: &Lister{},
sslStore: NewSSLCertTracker(),
filesystem: fs,
updateCh: updateCh,
backendConfig: ngx_config.NewDefault(),
syncSecretMu: &sync.Mutex{},
backendConfigMu: &sync.RWMutex{},
secretIngressMap: NewObjectRefMap(),
defaultSSLCertificate: defaultSSLCertificate,
pod: pod,
}
eventBroadcaster := record.NewBroadcaster()
@ -878,10 +870,6 @@ func (s *k8sStore) setConfig(cmap *corev1.ConfigMap) {
func (s *k8sStore) Run(stopCh chan struct{}) {
// start informers
s.informers.Run(stopCh)
if s.isOCSPCheckEnabled {
go wait.Until(s.checkSSLChainIssues, 60*time.Second, stopCh)
}
}
// GetRunningControllerPodsCount returns the number of Running ingress-nginx controller Pods

View file

@ -41,6 +41,7 @@ import (
"k8s.io/ingress-nginx/internal/file"
"k8s.io/ingress-nginx/internal/ingress"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
"k8s.io/ingress-nginx/internal/k8s"
"k8s.io/ingress-nginx/test/e2e/framework"
)
@ -87,7 +88,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -97,7 +98,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -168,7 +168,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -178,7 +178,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -319,7 +318,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -329,7 +328,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -426,7 +424,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -436,7 +434,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -516,7 +513,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -526,7 +523,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -628,7 +624,7 @@ func TestStore(t *testing.T) {
}(updateCh)
fs := newFS(t)
storer := New(true,
storer := New(
ns,
fmt.Sprintf("%v/config", ns),
fmt.Sprintf("%v/tcp", ns),
@ -638,7 +634,6 @@ func TestStore(t *testing.T) {
clientSet,
fs,
updateCh,
false,
pod,
false)
@ -708,6 +703,9 @@ func TestStore(t *testing.T) {
}
t.Run("should exists a secret in the local store and filesystem", func(t *testing.T) {
ngx_config.EnableDynamicCertificates = false
defer func() { ngx_config.EnableDynamicCertificates = true }()
err := framework.WaitForSecretInNamespace(clientSet, ns, name)
if err != nil {
t.Errorf("error waiting for secret: %v", err)