Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b1d017f8
Commit
b1d017f8
authored
Aug 06, 2020
by
Brad Davidson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update dynamiclistener
Second round of fixes for #1621 Signed-off-by:
Brad Davidson
<
brad.davidson@rancher.com
>
parent
7fb1797f
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
203 additions
and
76 deletions
+203
-76
go.mod
go.mod
+1
-1
go.sum
go.sum
+2
-2
https.go
pkg/cluster/https.go
+1
-1
types.go
pkg/daemons/config/types.go
+1
-0
server.go
pkg/daemons/control/server.go
+1
-1
cert.go
vendor/github.com/rancher/dynamiclistener/cert/cert.go
+18
-8
io.go
vendor/github.com/rancher/dynamiclistener/cert/io.go
+3
-3
cert_utils.go
.../github.com/rancher/dynamiclistener/factory/cert_utils.go
+33
-1
gen.go
vendor/github.com/rancher/dynamiclistener/factory/gen.go
+52
-25
listener.go
vendor/github.com/rancher/dynamiclistener/listener.go
+29
-17
ca.go
...thub.com/rancher/dynamiclistener/storage/kubernetes/ca.go
+51
-7
controller.go
.../rancher/dynamiclistener/storage/kubernetes/controller.go
+2
-3
memory.go
...thub.com/rancher/dynamiclistener/storage/memory/memory.go
+8
-6
modules.txt
vendor/modules.txt
+1
-1
No files found.
go.mod
View file @
b1d017f8
...
@@ -94,7 +94,7 @@ require (
...
@@ -94,7 +94,7 @@ require (
github.com/opencontainers/runc v1.0.0-rc10
github.com/opencontainers/runc v1.0.0-rc10
github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863
github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863
github.com/pkg/errors v0.9.1
github.com/pkg/errors v0.9.1
github.com/rancher/dynamiclistener v0.2.1
-0.20200418023342-52ede5ec9234
github.com/rancher/dynamiclistener v0.2.1
github.com/rancher/helm-controller v0.6.5
github.com/rancher/helm-controller v0.6.5
github.com/rancher/kine v0.4.0
github.com/rancher/kine v0.4.0
github.com/rancher/remotedialer v0.2.0
github.com/rancher/remotedialer v0.2.0
...
...
go.sum
View file @
b1d017f8
...
@@ -630,8 +630,8 @@ github.com/rancher/cri v1.3.0-k3s.7 h1:5V/AVFLCpYIsJMavJKjKpwrQU92e87dhWSX43N4q8
...
@@ -630,8 +630,8 @@ github.com/rancher/cri v1.3.0-k3s.7 h1:5V/AVFLCpYIsJMavJKjKpwrQU92e87dhWSX43N4q8
github.com/rancher/cri v1.3.0-k3s.7/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
github.com/rancher/cri v1.3.0-k3s.7/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
github.com/rancher/cri-tools v1.18.0-k3s1 h1:pLYthxpSu6k3Up9tNAMA0MK2ERqB6FC1sZQPRSW1qSg=
github.com/rancher/cri-tools v1.18.0-k3s1 h1:pLYthxpSu6k3Up9tNAMA0MK2ERqB6FC1sZQPRSW1qSg=
github.com/rancher/cri-tools v1.18.0-k3s1/go.mod h1:Ij/GWNRcEDP6zVN6eQpvN/s0nhuJVtPQFy7RAdl+Wu8=
github.com/rancher/cri-tools v1.18.0-k3s1/go.mod h1:Ij/GWNRcEDP6zVN6eQpvN/s0nhuJVtPQFy7RAdl+Wu8=
github.com/rancher/dynamiclistener v0.2.1
-0.20200418023342-52ede5ec9234 h1:wZ1Zh7fI7B9hfZw9Ouhz7171CZKu6XffM3ysUhhO6i0
=
github.com/rancher/dynamiclistener v0.2.1
h1:QiY1jxs2TOLrKB04G36vE2ehEvPMPGiWp8zEHLKB1nE
=
github.com/rancher/dynamiclistener v0.2.1
-0.20200418023342-52ede5ec9234
/go.mod h1:9WusTANoiRr8cDWCTtf5txieulezHbpv4vhLADPp0zU=
github.com/rancher/dynamiclistener v0.2.1/go.mod h1:9WusTANoiRr8cDWCTtf5txieulezHbpv4vhLADPp0zU=
github.com/rancher/flannel v0.12.0-k3s1 h1:P23dWSk/9mGT1x2rDWW9JXNrF/0kjftiHwMau/+ZLGM=
github.com/rancher/flannel v0.12.0-k3s1 h1:P23dWSk/9mGT1x2rDWW9JXNrF/0kjftiHwMau/+ZLGM=
github.com/rancher/flannel v0.12.0-k3s1/go.mod h1:zQ/9Uhaw0yV4Wh6ljVwHVT1x5KuhenZA+6L8lRzOJEY=
github.com/rancher/flannel v0.12.0-k3s1/go.mod h1:zQ/9Uhaw0yV4Wh6ljVwHVT1x5KuhenZA+6L8lRzOJEY=
github.com/rancher/go-powershell v0.0.0-20200701182037-6845e6fcfa79 h1:UeC0rjrIel8hHz92cdVN09Cm4Hz+BhsPP/ZvQnPOr58=
github.com/rancher/go-powershell v0.0.0-20200701182037-6845e6fcfa79 h1:UeC0rjrIel8hHz92cdVN09Cm4Hz+BhsPP/ZvQnPOr58=
...
...
pkg/cluster/https.go
View file @
b1d017f8
...
@@ -39,7 +39,7 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler,
...
@@ -39,7 +39,7 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler,
CipherSuites
:
c
.
config
.
TLSCipherSuites
,
CipherSuites
:
c
.
config
.
TLSCipherSuites
,
},
},
SANs
:
append
(
c
.
config
.
SANs
,
"localhost"
,
"kubernetes"
,
"kubernetes.default"
,
"kubernetes.default.svc."
+
c
.
config
.
ClusterDomain
),
SANs
:
append
(
c
.
config
.
SANs
,
"localhost"
,
"kubernetes"
,
"kubernetes.default"
,
"kubernetes.default.svc."
+
c
.
config
.
ClusterDomain
),
ExpirationDaysCheck
:
90
,
ExpirationDaysCheck
:
config
.
CertificateRenewDays
,
})
})
}
}
...
...
pkg/daemons/config/types.go
View file @
b1d017f8
...
@@ -20,6 +20,7 @@ const (
...
@@ -20,6 +20,7 @@ const (
FlannelBackendHostGW
=
"host-gw"
FlannelBackendHostGW
=
"host-gw"
FlannelBackendIPSEC
=
"ipsec"
FlannelBackendIPSEC
=
"ipsec"
FlannelBackendWireguard
=
"wireguard"
FlannelBackendWireguard
=
"wireguard"
CertificateRenewDays
=
90
)
)
type
Node
struct
{
type
Node
struct
{
...
...
pkg/daemons/control/server.go
View file @
b1d017f8
...
@@ -898,7 +898,7 @@ func expired(certFile string, pool *x509.CertPool) bool {
...
@@ -898,7 +898,7 @@ func expired(certFile string, pool *x509.CertPool) bool {
if
err
!=
nil
{
if
err
!=
nil
{
return
true
return
true
}
}
return
certutil
.
IsCertExpired
(
certificates
[
0
])
return
certutil
.
IsCertExpired
(
certificates
[
0
]
,
config
.
CertificateRenewDays
)
}
}
func
cloudControllerManager
(
ctx
context
.
Context
,
cfg
*
config
.
Control
,
runtime
*
config
.
ControlRuntime
)
{
func
cloudControllerManager
(
ctx
context
.
Context
,
cfg
*
config
.
Control
,
runtime
*
config
.
ControlRuntime
)
{
...
...
vendor/github.com/rancher/dynamiclistener/cert/cert.go
View file @
b1d017f8
...
@@ -33,7 +33,7 @@ import (
...
@@ -33,7 +33,7 @@ import (
"math"
"math"
"math/big"
"math/big"
"net"
"net"
"path"
"path
/filepath
"
"strings"
"strings"
"time"
"time"
...
@@ -45,6 +45,10 @@ const (
...
@@ -45,6 +45,10 @@ const (
duration365d
=
time
.
Hour
*
24
*
365
duration365d
=
time
.
Hour
*
24
*
365
)
)
var
(
ErrStaticCert
=
errors
.
New
(
"cannot renew static certificate"
)
)
// Config contains the basic fields required for creating a certificate
// Config contains the basic fields required for creating a certificate
type
Config
struct
{
type
Config
struct
{
CommonName
string
CommonName
string
...
@@ -119,7 +123,13 @@ func NewSignedCert(cfg Config, key crypto.Signer, caCert *x509.Certificate, caKe
...
@@ -119,7 +123,13 @@ func NewSignedCert(cfg Config, key crypto.Signer, caCert *x509.Certificate, caKe
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
x509
.
ParseCertificate
(
certDERBytes
)
parsedCert
,
err
:=
x509
.
ParseCertificate
(
certDERBytes
)
if
err
==
nil
{
logrus
.
Infof
(
"certificate %s signed by %s: notBefore=%s notAfter=%s"
,
parsedCert
.
Subject
,
caCert
.
Subject
,
parsedCert
.
NotBefore
,
parsedCert
.
NotAfter
)
}
return
parsedCert
,
err
}
}
// MakeEllipticPrivateKeyPEM creates an ECDSA private key
// MakeEllipticPrivateKeyPEM creates an ECDSA private key
...
@@ -161,8 +171,8 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a
...
@@ -161,8 +171,8 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a
maxAge
:=
time
.
Hour
*
24
*
365
// one year self-signed certs
maxAge
:=
time
.
Hour
*
24
*
365
// one year self-signed certs
baseName
:=
fmt
.
Sprintf
(
"%s_%s_%s"
,
host
,
strings
.
Join
(
ipsToStrings
(
alternateIPs
),
"-"
),
strings
.
Join
(
alternateDNS
,
"-"
))
baseName
:=
fmt
.
Sprintf
(
"%s_%s_%s"
,
host
,
strings
.
Join
(
ipsToStrings
(
alternateIPs
),
"-"
),
strings
.
Join
(
alternateDNS
,
"-"
))
certFixturePath
:=
path
.
Join
(
fixtureDirectory
,
baseName
+
".crt"
)
certFixturePath
:=
file
path
.
Join
(
fixtureDirectory
,
baseName
+
".crt"
)
keyFixturePath
:=
path
.
Join
(
fixtureDirectory
,
baseName
+
".key"
)
keyFixturePath
:=
file
path
.
Join
(
fixtureDirectory
,
baseName
+
".key"
)
if
len
(
fixtureDirectory
)
>
0
{
if
len
(
fixtureDirectory
)
>
0
{
cert
,
err
:=
ioutil
.
ReadFile
(
certFixturePath
)
cert
,
err
:=
ioutil
.
ReadFile
(
certFixturePath
)
if
err
==
nil
{
if
err
==
nil
{
...
@@ -271,11 +281,11 @@ func ipsToStrings(ips []net.IP) []string {
...
@@ -271,11 +281,11 @@ func ipsToStrings(ips []net.IP) []string {
}
}
// IsCertExpired checks if the certificate about to expire
// IsCertExpired checks if the certificate about to expire
func
IsCertExpired
(
cert
*
x509
.
Certificate
)
bool
{
func
IsCertExpired
(
cert
*
x509
.
Certificate
,
days
int
)
bool
{
expirationDate
:=
cert
.
NotAfter
expirationDate
:=
cert
.
NotAfter
diffDays
:=
expirationDate
.
Sub
(
time
.
Now
()
)
.
Hours
()
/
24.0
diffDays
:=
time
.
Until
(
expirationDate
)
.
Hours
()
/
24.0
if
diffDays
<=
90
{
if
diffDays
<=
float64
(
days
)
{
logrus
.
Infof
(
"certificate
will expire in %f days"
,
diffDays
)
logrus
.
Infof
(
"certificate
%s will expire in %f days at %s"
,
cert
.
Subject
,
diffDays
,
cert
.
NotAfter
)
return
true
return
true
}
}
return
false
return
false
...
...
vendor/github.com/rancher/dynamiclistener/cert/io.go
View file @
b1d017f8
...
@@ -34,15 +34,15 @@ func CanReadCertAndKey(certPath, keyPath string) (bool, error) {
...
@@ -34,15 +34,15 @@ func CanReadCertAndKey(certPath, keyPath string) (bool, error) {
certReadable
:=
canReadFile
(
certPath
)
certReadable
:=
canReadFile
(
certPath
)
keyReadable
:=
canReadFile
(
keyPath
)
keyReadable
:=
canReadFile
(
keyPath
)
if
certReadable
==
false
&&
keyReadable
==
fals
e
{
if
!
certReadable
&&
!
keyReadabl
e
{
return
false
,
nil
return
false
,
nil
}
}
if
certReadable
==
fals
e
{
if
!
certReadabl
e
{
return
false
,
fmt
.
Errorf
(
"error reading %s, certificate and key must be supplied as a pair"
,
certPath
)
return
false
,
fmt
.
Errorf
(
"error reading %s, certificate and key must be supplied as a pair"
,
certPath
)
}
}
if
keyReadable
==
fals
e
{
if
!
keyReadabl
e
{
return
false
,
fmt
.
Errorf
(
"error reading %s, certificate and key must be supplied as a pair"
,
keyPath
)
return
false
,
fmt
.
Errorf
(
"error reading %s, certificate and key must be supplied as a pair"
,
keyPath
)
}
}
...
...
vendor/github.com/rancher/dynamiclistener/factory/cert_utils.go
View file @
b1d017f8
...
@@ -11,6 +11,8 @@ import (
...
@@ -11,6 +11,8 @@ import (
"math/big"
"math/big"
"net"
"net"
"time"
"time"
"github.com/sirupsen/logrus"
)
)
const
(
const
(
...
@@ -40,6 +42,31 @@ func NewSelfSignedCACert(key crypto.Signer, cn string, org ...string) (*x509.Cer
...
@@ -40,6 +42,31 @@ func NewSelfSignedCACert(key crypto.Signer, cn string, org ...string) (*x509.Cer
return
x509
.
ParseCertificate
(
certDERBytes
)
return
x509
.
ParseCertificate
(
certDERBytes
)
}
}
func
NewSignedClientCert
(
signer
crypto
.
Signer
,
caCert
*
x509
.
Certificate
,
caKey
crypto
.
Signer
,
cn
string
)
(
*
x509
.
Certificate
,
error
)
{
serialNumber
,
err
:=
rand
.
Int
(
rand
.
Reader
,
new
(
big
.
Int
)
.
SetInt64
(
math
.
MaxInt64
))
if
err
!=
nil
{
return
nil
,
err
}
parent
:=
x509
.
Certificate
{
ExtKeyUsage
:
[]
x509
.
ExtKeyUsage
{
x509
.
ExtKeyUsageClientAuth
},
KeyUsage
:
x509
.
KeyUsageKeyEncipherment
|
x509
.
KeyUsageDigitalSignature
,
NotAfter
:
time
.
Now
()
.
Add
(
time
.
Hour
*
24
*
365
)
.
UTC
(),
NotBefore
:
caCert
.
NotBefore
,
SerialNumber
:
serialNumber
,
Subject
:
pkix
.
Name
{
CommonName
:
cn
,
},
}
cert
,
err
:=
x509
.
CreateCertificate
(
rand
.
Reader
,
&
parent
,
caCert
,
signer
.
Public
(),
caKey
)
if
err
!=
nil
{
return
nil
,
err
}
return
x509
.
ParseCertificate
(
cert
)
}
func
NewSignedCert
(
signer
crypto
.
Signer
,
caCert
*
x509
.
Certificate
,
caKey
crypto
.
Signer
,
cn
string
,
orgs
[]
string
,
func
NewSignedCert
(
signer
crypto
.
Signer
,
caCert
*
x509
.
Certificate
,
caKey
crypto
.
Signer
,
cn
string
,
orgs
[]
string
,
domains
[]
string
,
ips
[]
net
.
IP
)
(
*
x509
.
Certificate
,
error
)
{
domains
[]
string
,
ips
[]
net
.
IP
)
(
*
x509
.
Certificate
,
error
)
{
...
@@ -67,7 +94,12 @@ func NewSignedCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto.
...
@@ -67,7 +94,12 @@ func NewSignedCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto.
return
nil
,
err
return
nil
,
err
}
}
return
x509
.
ParseCertificate
(
cert
)
parsedCert
,
err
:=
x509
.
ParseCertificate
(
cert
)
if
err
==
nil
{
logrus
.
Infof
(
"certificate %s signed by %s: notBefore=%s notAfter=%s"
,
parsedCert
.
Subject
,
caCert
.
Subject
,
parsedCert
.
NotBefore
,
parsedCert
.
NotAfter
)
}
return
parsedCert
,
err
}
}
func
ParseCertPEM
(
pemCerts
[]
byte
)
(
*
x509
.
Certificate
,
error
)
{
func
ParseCertPEM
(
pemCerts
[]
byte
)
(
*
x509
.
Certificate
,
error
)
{
...
...
vendor/github.com/rancher/dynamiclistener/factory/gen.go
View file @
b1d017f8
...
@@ -5,10 +5,10 @@ import (
...
@@ -5,10 +5,10 @@ import (
"crypto/ecdsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/elliptic"
"crypto/rand"
"crypto/rand"
"crypto/sha
256
"
"crypto/sha
1
"
"crypto/x509"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"encoding/pem"
"fmt"
"net"
"net"
"regexp"
"regexp"
"sort"
"sort"
...
@@ -20,9 +20,9 @@ import (
...
@@ -20,9 +20,9 @@ import (
)
)
const
(
const
(
cnPrefix
=
"listener.cattle.io/cn-"
cnPrefix
=
"listener.cattle.io/cn-"
Static
=
"listener.cattle.io/static"
Static
=
"listener.cattle.io/static"
hashKey
=
"listener.cattle.io/hash
"
fingerprint
=
"listener.cattle.io/fingerprint
"
)
)
var
(
var
(
...
@@ -49,16 +49,14 @@ func cns(secret *v1.Secret) (cns []string) {
...
@@ -49,16 +49,14 @@ func cns(secret *v1.Secret) (cns []string) {
return
return
}
}
func
collectCNs
(
secret
*
v1
.
Secret
)
(
domains
[]
string
,
ips
[]
net
.
IP
,
hash
string
,
err
error
)
{
func
collectCNs
(
secret
*
v1
.
Secret
)
(
domains
[]
string
,
ips
[]
net
.
IP
,
err
error
)
{
var
(
var
(
cns
=
cns
(
secret
)
cns
=
cns
(
secret
)
digest
=
sha256
.
New
()
)
)
sort
.
Strings
(
cns
)
sort
.
Strings
(
cns
)
for
_
,
v
:=
range
cns
{
for
_
,
v
:=
range
cns
{
digest
.
Write
([]
byte
(
v
))
ip
:=
net
.
ParseIP
(
v
)
ip
:=
net
.
ParseIP
(
v
)
if
ip
==
nil
{
if
ip
==
nil
{
domains
=
append
(
domains
,
v
)
domains
=
append
(
domains
,
v
)
...
@@ -67,40 +65,61 @@ func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, hash string,
...
@@ -67,40 +65,61 @@ func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, hash string,
}
}
}
}
hash
=
hex
.
EncodeToString
(
digest
.
Sum
(
nil
))
return
return
}
}
// Merge combines the SAN lists from the target and additional Secrets, and returns a potentially modified Secret,
// along with a bool indicating if the returned Secret has been updated or not. If the two SAN lists alread matched
// and no merging was necessary, but the Secrets' certificate fingerprints differed, the second secret is returned
// and the updated bool is set to true despite neither certificate having actually been modified. This is required
// to support handling certificate renewal within the kubernetes storage provider.
func
(
t
*
TLS
)
Merge
(
target
,
additional
*
v1
.
Secret
)
(
*
v1
.
Secret
,
bool
,
error
)
{
func
(
t
*
TLS
)
Merge
(
target
,
additional
*
v1
.
Secret
)
(
*
v1
.
Secret
,
bool
,
error
)
{
return
t
.
AddCN
(
target
,
cns
(
additional
)
...
)
secret
,
updated
,
err
:=
t
.
AddCN
(
target
,
cns
(
additional
)
...
)
if
!
updated
{
if
target
.
Annotations
[
fingerprint
]
!=
additional
.
Annotations
[
fingerprint
]
{
secret
=
additional
updated
=
true
}
}
return
secret
,
updated
,
err
}
}
func
(
t
*
TLS
)
Refresh
(
secret
*
v1
.
Secret
)
(
*
v1
.
Secret
,
error
)
{
// Renew returns a copy of the given certificate that has been re-signed
// to extend the NotAfter date. It is an error to attempt to renew
// a static (user-provided) certificate.
func
(
t
*
TLS
)
Renew
(
secret
*
v1
.
Secret
)
(
*
v1
.
Secret
,
error
)
{
if
IsStatic
(
secret
)
{
return
secret
,
cert
.
ErrStaticCert
}
cns
:=
cns
(
secret
)
cns
:=
cns
(
secret
)
secret
=
secret
.
DeepCopy
()
secret
=
secret
.
DeepCopy
()
secret
.
Annotations
=
map
[
string
]
string
{}
secret
.
Annotations
=
map
[
string
]
string
{}
secret
,
_
,
err
:=
t
.
AddCN
(
secret
,
cns
...
)
secret
,
_
,
err
:=
t
.
generateCert
(
secret
,
cns
...
)
return
secret
,
err
return
secret
,
err
}
}
// Filter ensures that the CNs are all valid accorting to both internal logic, and any filter callbacks.
// The returned list will contain only approved CN entries.
func
(
t
*
TLS
)
Filter
(
cn
...
string
)
[]
string
{
func
(
t
*
TLS
)
Filter
(
cn
...
string
)
[]
string
{
if
t
.
FilterCN
==
nil
{
if
len
(
cn
)
==
0
||
t
.
FilterCN
==
nil
{
return
cn
return
cn
}
}
return
t
.
FilterCN
(
cn
...
)
return
t
.
FilterCN
(
cn
...
)
}
}
// AddCN attempts to add a list of CN strings to a given Secret, returning the potentially-modified
// Secret along with a bool indicating whether or not it has been updated. The Secret will not be changed
// if it has an attribute indicating that it is static (aka user-provided), or if no new CNs were added.
func
(
t
*
TLS
)
AddCN
(
secret
*
v1
.
Secret
,
cn
...
string
)
(
*
v1
.
Secret
,
bool
,
error
)
{
func
(
t
*
TLS
)
AddCN
(
secret
*
v1
.
Secret
,
cn
...
string
)
(
*
v1
.
Secret
,
bool
,
error
)
{
var
(
err
error
)
cn
=
t
.
Filter
(
cn
...
)
cn
=
t
.
Filter
(
cn
...
)
if
!
NeedsUpdate
(
0
,
secret
,
cn
...
)
{
if
IsStatic
(
secret
)
||
!
NeedsUpdate
(
0
,
secret
,
cn
...
)
{
return
secret
,
false
,
nil
return
secret
,
false
,
nil
}
}
return
t
.
generateCert
(
secret
,
cn
...
)
}
func
(
t
*
TLS
)
generateCert
(
secret
*
v1
.
Secret
,
cn
...
string
)
(
*
v1
.
Secret
,
bool
,
error
)
{
secret
=
secret
.
DeepCopy
()
secret
=
secret
.
DeepCopy
()
if
secret
==
nil
{
if
secret
==
nil
{
secret
=
&
v1
.
Secret
{}
secret
=
&
v1
.
Secret
{}
...
@@ -113,7 +132,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) {
...
@@ -113,7 +132,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) {
return
nil
,
false
,
err
return
nil
,
false
,
err
}
}
domains
,
ips
,
hash
,
err
:=
collectCNs
(
secret
)
domains
,
ips
,
err
:=
collectCNs
(
secret
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
false
,
err
return
nil
,
false
,
err
}
}
...
@@ -133,7 +152,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) {
...
@@ -133,7 +152,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) {
}
}
secret
.
Data
[
v1
.
TLSCertKey
]
=
certBytes
secret
.
Data
[
v1
.
TLSCertKey
]
=
certBytes
secret
.
Data
[
v1
.
TLSPrivateKeyKey
]
=
keyBytes
secret
.
Data
[
v1
.
TLSPrivateKeyKey
]
=
keyBytes
secret
.
Annotations
[
hashKey
]
=
hash
secret
.
Annotations
[
fingerprint
]
=
fmt
.
Sprintf
(
"SHA1=%X"
,
sha1
.
Sum
(
newCert
.
Raw
))
return
secret
,
true
,
nil
return
secret
,
true
,
nil
}
}
...
@@ -157,15 +176,21 @@ func populateCN(secret *v1.Secret, cn ...string) *v1.Secret {
...
@@ -157,15 +176,21 @@ func populateCN(secret *v1.Secret, cn ...string) *v1.Secret {
return
secret
return
secret
}
}
// IsStatic returns true if the Secret has an attribute indicating that it contains
// a static (aka user-provided) certificate, which should not be modified.
func
IsStatic
(
secret
*
v1
.
Secret
)
bool
{
return
secret
.
Annotations
[
Static
]
==
"true"
}
// NeedsUpdate returns true if any of the CNs are not currently present on the
// secret's Certificate, as recorded in the cnPrefix annotations. It will return
// false if all requested CNs are already present, or if maxSANs is non-zero and has
// been exceeded.
func
NeedsUpdate
(
maxSANs
int
,
secret
*
v1
.
Secret
,
cn
...
string
)
bool
{
func
NeedsUpdate
(
maxSANs
int
,
secret
*
v1
.
Secret
,
cn
...
string
)
bool
{
if
secret
==
nil
{
if
secret
==
nil
{
return
true
return
true
}
}
if
secret
.
Annotations
[
Static
]
==
"true"
{
return
false
}
for
_
,
cn
:=
range
cn
{
for
_
,
cn
:=
range
cn
{
if
secret
.
Annotations
[
cnPrefix
+
cn
]
==
""
{
if
secret
.
Annotations
[
cnPrefix
+
cn
]
==
""
{
if
maxSANs
>
0
&&
len
(
cns
(
secret
))
>=
maxSANs
{
if
maxSANs
>
0
&&
len
(
cns
(
secret
))
>=
maxSANs
{
...
@@ -192,6 +217,7 @@ func getPrivateKey(secret *v1.Secret) (crypto.Signer, error) {
...
@@ -192,6 +217,7 @@ func getPrivateKey(secret *v1.Secret) (crypto.Signer, error) {
return
NewPrivateKey
()
return
NewPrivateKey
()
}
}
// Marshal returns the given cert and key as byte slices.
func
Marshal
(
x509Cert
*
x509
.
Certificate
,
privateKey
crypto
.
Signer
)
([]
byte
,
[]
byte
,
error
)
{
func
Marshal
(
x509Cert
*
x509
.
Certificate
,
privateKey
crypto
.
Signer
)
([]
byte
,
[]
byte
,
error
)
{
certBlock
:=
pem
.
Block
{
certBlock
:=
pem
.
Block
{
Type
:
CertificateBlockType
,
Type
:
CertificateBlockType
,
...
@@ -206,6 +232,7 @@ func Marshal(x509Cert *x509.Certificate, privateKey crypto.Signer) ([]byte, []by
...
@@ -206,6 +232,7 @@ func Marshal(x509Cert *x509.Certificate, privateKey crypto.Signer) ([]byte, []by
return
pem
.
EncodeToMemory
(
&
certBlock
),
keyBytes
,
nil
return
pem
.
EncodeToMemory
(
&
certBlock
),
keyBytes
,
nil
}
}
// NewPrivateKey returnes a new ECDSA key
func
NewPrivateKey
()
(
crypto
.
Signer
,
error
)
{
func
NewPrivateKey
()
(
crypto
.
Signer
,
error
)
{
return
ecdsa
.
GenerateKey
(
elliptic
.
P256
(),
rand
.
Reader
)
return
ecdsa
.
GenerateKey
(
elliptic
.
P256
(),
rand
.
Reader
)
}
}
vendor/github.com/rancher/dynamiclistener/listener.go
View file @
b1d017f8
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"sync"
"sync"
"time"
"time"
"github.com/rancher/dynamiclistener/cert"
"github.com/rancher/dynamiclistener/factory"
"github.com/rancher/dynamiclistener/factory"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
v1
"k8s.io/api/core/v1"
v1
"k8s.io/api/core/v1"
...
@@ -22,7 +23,7 @@ type TLSStorage interface {
...
@@ -22,7 +23,7 @@ type TLSStorage interface {
}
}
type
TLSFactory
interface
{
type
TLSFactory
interface
{
Re
fresh
(
secret
*
v1
.
Secret
)
(
*
v1
.
Secret
,
error
)
Re
new
(
secret
*
v1
.
Secret
)
(
*
v1
.
Secret
,
error
)
AddCN
(
secret
*
v1
.
Secret
,
cn
...
string
)
(
*
v1
.
Secret
,
bool
,
error
)
AddCN
(
secret
*
v1
.
Secret
,
cn
...
string
)
(
*
v1
.
Secret
,
bool
,
error
)
Merge
(
target
*
v1
.
Secret
,
additional
*
v1
.
Secret
)
(
*
v1
.
Secret
,
bool
,
error
)
Merge
(
target
*
v1
.
Secret
,
additional
*
v1
.
Secret
)
(
*
v1
.
Secret
,
bool
,
error
)
Filter
(
cn
...
string
)
[]
string
Filter
(
cn
...
string
)
[]
string
...
@@ -152,13 +153,18 @@ type listener struct {
...
@@ -152,13 +153,18 @@ type listener struct {
func
(
l
*
listener
)
WrapExpiration
(
days
int
)
net
.
Listener
{
func
(
l
*
listener
)
WrapExpiration
(
days
int
)
net
.
Listener
{
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
go
func
()
{
go
func
()
{
time
.
Sleep
(
5
*
time
.
Minute
)
time
.
Sleep
(
30
*
time
.
Second
)
for
{
for
{
wait
:=
6
*
time
.
Hour
wait
:=
6
*
time
.
Hour
if
err
:=
l
.
checkExpiration
(
days
);
err
!=
nil
{
if
err
:=
l
.
checkExpiration
(
days
);
err
!=
nil
{
logrus
.
Errorf
(
"failed to check and refresh dynamic cert: %v"
,
err
)
logrus
.
Errorf
(
"failed to check and renew dynamic cert: %v"
,
err
)
wait
=
5
+
time
.
Minute
// Don't go into short retry loop if we're using a static (user-provided) cert.
// We will still check and print an error every six hours until the user updates the secret with
// a cert that is not about to expire. Hopefully this will prompt them to take action.
if
err
!=
cert
.
ErrStaticCert
{
wait
=
5
*
time
.
Minute
}
}
}
select
{
select
{
case
<-
ctx
.
Done
()
:
case
<-
ctx
.
Done
()
:
...
@@ -191,22 +197,26 @@ func (l *listener) checkExpiration(days int) error {
...
@@ -191,22 +197,26 @@ func (l *listener) checkExpiration(days int) error {
return
err
return
err
}
}
cert
,
err
:=
tls
.
X509KeyPair
(
secret
.
Data
[
v1
.
TLSCertKey
],
secret
.
Data
[
v1
.
TLSPrivateKeyKey
])
keyPair
,
err
:=
tls
.
X509KeyPair
(
secret
.
Data
[
v1
.
TLSCertKey
],
secret
.
Data
[
v1
.
TLSPrivateKeyKey
])
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
certParsed
,
err
:=
x509
.
ParseCertificate
(
cert
.
Certificate
[
0
])
certParsed
,
err
:=
x509
.
ParseCertificate
(
keyPair
.
Certificate
[
0
])
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
time
.
Now
()
.
UTC
()
.
Add
(
time
.
Hour
*
24
*
time
.
Duration
(
days
))
.
After
(
certParsed
.
NotAfter
)
{
if
cert
.
IsCertExpired
(
certParsed
,
days
)
{
secret
,
err
:=
l
.
factory
.
Re
fresh
(
secret
)
secret
,
err
:=
l
.
factory
.
Re
new
(
secret
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
return
l
.
storage
.
Update
(
secret
)
if
err
:=
l
.
storage
.
Update
(
secret
);
err
!=
nil
{
return
err
}
// clear version to force cert reload
l
.
version
=
""
}
}
return
nil
return
nil
...
@@ -304,7 +314,7 @@ func (l *listener) updateCert(cn ...string) error {
...
@@ -304,7 +314,7 @@ func (l *listener) updateCert(cn ...string) error {
return
err
return
err
}
}
if
!
factory
.
NeedsUpdate
(
l
.
maxSANs
,
secret
,
cn
...
)
{
if
!
factory
.
IsStatic
(
secret
)
&&
!
factory
.
NeedsUpdate
(
l
.
maxSANs
,
secret
,
cn
...
)
{
return
nil
return
nil
}
}
...
@@ -324,13 +334,6 @@ func (l *listener) updateCert(cn ...string) error {
...
@@ -324,13 +334,6 @@ func (l *listener) updateCert(cn ...string) error {
}
}
// clear version to force cert reload
// clear version to force cert reload
l
.
version
=
""
l
.
version
=
""
if
l
.
conns
!=
nil
{
l
.
connLock
.
Lock
()
for
_
,
conn
:=
range
l
.
conns
{
_
=
conn
.
close
()
}
l
.
connLock
.
Unlock
()
}
}
}
return
nil
return
nil
...
@@ -366,6 +369,15 @@ func (l *listener) loadCert() (*tls.Certificate, error) {
...
@@ -366,6 +369,15 @@ func (l *listener) loadCert() (*tls.Certificate, error) {
return
nil
,
err
return
nil
,
err
}
}
// cert has changed, close closeWrapper wrapped connections
if
l
.
conns
!=
nil
{
l
.
connLock
.
Lock
()
for
_
,
conn
:=
range
l
.
conns
{
_
=
conn
.
close
()
}
l
.
connLock
.
Unlock
()
}
l
.
cert
=
&
cert
l
.
cert
=
&
cert
l
.
version
=
secret
.
ResourceVersion
l
.
version
=
secret
.
ResourceVersion
return
l
.
cert
,
nil
return
l
.
cert
,
nil
...
...
vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go
View file @
b1d017f8
...
@@ -19,27 +19,72 @@ func LoadOrGenCA(secrets v1controller.SecretClient, namespace, name string) (*x5
...
@@ -19,27 +19,72 @@ func LoadOrGenCA(secrets v1controller.SecretClient, namespace, name string) (*x5
return
factory
.
LoadCA
(
secret
.
Data
[
v1
.
TLSCertKey
],
secret
.
Data
[
v1
.
TLSPrivateKeyKey
])
return
factory
.
LoadCA
(
secret
.
Data
[
v1
.
TLSCertKey
],
secret
.
Data
[
v1
.
TLSPrivateKeyKey
])
}
}
func
LoadOrGenClient
(
secrets
v1controller
.
SecretClient
,
namespace
,
name
,
cn
string
,
ca
*
x509
.
Certificate
,
key
crypto
.
Signer
)
(
*
x509
.
Certificate
,
crypto
.
Signer
,
error
)
{
secret
,
err
:=
getClientSecret
(
secrets
,
namespace
,
name
,
cn
,
ca
,
key
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
return
factory
.
LoadCA
(
secret
.
Data
[
v1
.
TLSCertKey
],
secret
.
Data
[
v1
.
TLSPrivateKeyKey
])
}
func
getClientSecret
(
secrets
v1controller
.
SecretClient
,
namespace
,
name
,
cn
string
,
caCert
*
x509
.
Certificate
,
caKey
crypto
.
Signer
)
(
*
v1
.
Secret
,
error
)
{
s
,
err
:=
secrets
.
Get
(
namespace
,
name
,
metav1
.
GetOptions
{})
if
!
errors
.
IsNotFound
(
err
)
{
return
s
,
err
}
return
createAndStoreClientCert
(
secrets
,
namespace
,
name
,
cn
,
caCert
,
caKey
)
}
func
getSecret
(
secrets
v1controller
.
SecretClient
,
namespace
,
name
string
)
(
*
v1
.
Secret
,
error
)
{
func
getSecret
(
secrets
v1controller
.
SecretClient
,
namespace
,
name
string
)
(
*
v1
.
Secret
,
error
)
{
s
,
err
:=
secrets
.
Get
(
namespace
,
name
,
metav1
.
GetOptions
{})
s
,
err
:=
secrets
.
Get
(
namespace
,
name
,
metav1
.
GetOptions
{})
if
!
errors
.
IsNotFound
(
err
)
{
if
!
errors
.
IsNotFound
(
err
)
{
return
s
,
err
return
s
,
err
}
}
if
err
:=
createAndStore
(
secrets
,
namespace
,
name
);
err
!=
nil
{
return
createAndStore
(
secrets
,
namespace
,
name
)
}
func
createAndStoreClientCert
(
secrets
v1controller
.
SecretClient
,
namespace
string
,
name
,
cn
string
,
caCert
*
x509
.
Certificate
,
caKey
crypto
.
Signer
)
(
*
v1
.
Secret
,
error
)
{
key
,
err
:=
factory
.
NewPrivateKey
()
if
err
!=
nil
{
return
nil
,
err
}
cert
,
err
:=
factory
.
NewSignedClientCert
(
key
,
caCert
,
caKey
,
cn
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
secrets
.
Get
(
namespace
,
name
,
metav1
.
GetOptions
{})
certPem
,
keyPem
,
err
:=
factory
.
Marshal
(
cert
,
key
)
if
err
!=
nil
{
return
nil
,
err
}
secret
:=
&
v1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
name
,
Namespace
:
namespace
,
},
Data
:
map
[
string
][]
byte
{
v1
.
TLSCertKey
:
certPem
,
v1
.
TLSPrivateKeyKey
:
keyPem
,
},
Type
:
v1
.
SecretTypeTLS
,
}
return
secrets
.
Create
(
secret
)
}
}
func
createAndStore
(
secrets
v1controller
.
SecretClient
,
namespace
string
,
name
string
)
error
{
func
createAndStore
(
secrets
v1controller
.
SecretClient
,
namespace
string
,
name
string
)
(
*
v1
.
Secret
,
error
)
{
ca
,
cert
,
err
:=
factory
.
GenCA
()
ca
,
cert
,
err
:=
factory
.
GenCA
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
certPem
,
keyPem
,
err
:=
factory
.
Marshal
(
ca
,
cert
)
certPem
,
keyPem
,
err
:=
factory
.
Marshal
(
ca
,
cert
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
secret
:=
&
v1
.
Secret
{
secret
:=
&
v1
.
Secret
{
...
@@ -54,6 +99,5 @@ func createAndStore(secrets v1controller.SecretClient, namespace string, name st
...
@@ -54,6 +99,5 @@ func createAndStore(secrets v1controller.SecretClient, namespace string, name st
Type
:
v1
.
SecretTypeTLS
,
Type
:
v1
.
SecretTypeTLS
,
}
}
secrets
.
Create
(
secret
)
return
secrets
.
Create
(
secret
)
return
nil
}
}
vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go
View file @
b1d017f8
...
@@ -156,10 +156,9 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) {
...
@@ -156,10 +156,9 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) {
if
targetSecret
.
UID
==
""
{
if
targetSecret
.
UID
==
""
{
logrus
.
Infof
(
"Creating new TLS secret for %v (count: %d): %v"
,
targetSecret
.
Name
,
len
(
targetSecret
.
Annotations
)
-
1
,
targetSecret
.
Annotations
)
logrus
.
Infof
(
"Creating new TLS secret for %v (count: %d): %v"
,
targetSecret
.
Name
,
len
(
targetSecret
.
Annotations
)
-
1
,
targetSecret
.
Annotations
)
return
s
.
secrets
.
Create
(
targetSecret
)
return
s
.
secrets
.
Create
(
targetSecret
)
}
else
{
logrus
.
Infof
(
"Updating TLS secret for %v (count: %d): %v"
,
targetSecret
.
Name
,
len
(
targetSecret
.
Annotations
)
-
1
,
targetSecret
.
Annotations
)
return
s
.
secrets
.
Update
(
targetSecret
)
}
}
logrus
.
Infof
(
"Updating TLS secret for %v (count: %d): %v"
,
targetSecret
.
Name
,
len
(
targetSecret
.
Annotations
)
-
1
,
targetSecret
.
Annotations
)
return
s
.
secrets
.
Update
(
targetSecret
)
}
}
func
(
s
*
storage
)
Update
(
secret
*
v1
.
Secret
)
(
err
error
)
{
func
(
s
*
storage
)
Update
(
secret
*
v1
.
Secret
)
(
err
error
)
{
...
...
vendor/github.com/rancher/dynamiclistener/storage/memory/memory.go
View file @
b1d017f8
...
@@ -32,13 +32,15 @@ func (m *memory) Get() (*v1.Secret, error) {
...
@@ -32,13 +32,15 @@ func (m *memory) Get() (*v1.Secret, error) {
}
}
func
(
m
*
memory
)
Update
(
secret
*
v1
.
Secret
)
error
{
func
(
m
*
memory
)
Update
(
secret
*
v1
.
Secret
)
error
{
if
m
.
storage
!=
nil
{
if
m
.
secret
==
nil
||
m
.
secret
.
ResourceVersion
!=
secret
.
ResourceVersion
{
if
err
:=
m
.
storage
.
Update
(
secret
);
err
!=
nil
{
if
m
.
storage
!=
nil
{
return
err
if
err
:=
m
.
storage
.
Update
(
secret
);
err
!=
nil
{
return
err
}
}
}
}
logrus
.
Infof
(
"Active TLS secret %s (ver=%s) (count %d): %v"
,
secret
.
Name
,
secret
.
ResourceVersion
,
len
(
secret
.
Annotations
)
-
1
,
secret
.
Annotations
)
logrus
.
Infof
(
"Active TLS secret %s (ver=%s) (count %d): %v"
,
secret
.
Name
,
secret
.
ResourceVersion
,
len
(
secret
.
Annotations
)
-
1
,
secret
.
Annotations
)
m
.
secret
=
secret
m
.
secret
=
secret
}
return
nil
return
nil
}
}
vendor/modules.txt
View file @
b1d017f8
...
@@ -726,7 +726,7 @@ github.com/prometheus/procfs/xfs
...
@@ -726,7 +726,7 @@ github.com/prometheus/procfs/xfs
# github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0
# github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0
github.com/rakelkar/gonetsh/netroute
github.com/rakelkar/gonetsh/netroute
github.com/rakelkar/gonetsh/netsh
github.com/rakelkar/gonetsh/netsh
# github.com/rancher/dynamiclistener v0.2.1
-0.20200418023342-52ede5ec9234
# github.com/rancher/dynamiclistener v0.2.1
github.com/rancher/dynamiclistener
github.com/rancher/dynamiclistener
github.com/rancher/dynamiclistener/cert
github.com/rancher/dynamiclistener/cert
github.com/rancher/dynamiclistener/factory
github.com/rancher/dynamiclistener/factory
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment