Skip to content

Commit

Permalink
Add Subject Alt Names to self signed apiserver certs
Browse files Browse the repository at this point in the history
A cert from GCE shows:
- IP Address:23.236.49.122
- IP Address:10.0.0.1
- DNS:kubernetes,
- DNS:kubernetes.default
- DNS:kubernetes.default.svc
- DNS:kubernetes.default.svc.cluster.local
- DNS:e2e-test-zml-master

A similarly configured self signed cert shows:
- IP Address:23.236.49.122
- IP Address:10.0.0.1
- DNS:kubernetes
- DNS:kubernetes.default
- DNS:kubernetes.default.svc

So we are missing the fqdn kubernetes.default.svc.cluster.local. The
apiserver does not even know the fqdn! it's defined entirely by the
kubelet! We also do not have the cluster name certificate. This may be
--cluster-name= argument to the apiserver but will take a bit more
research.
  • Loading branch information
eparis committed Jul 1, 2015
1 parent 4f9cfc8 commit 7a29af4
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 11 deletions.
2 changes: 1 addition & 1 deletion cmd/kube-apiserver/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ func (s *APIServer) Run(_ []string) error {
s.TLSCertFile = path.Join(s.CertDirectory, "apiserver.crt")
s.TLSPrivateKeyFile = path.Join(s.CertDirectory, "apiserver.key")
// TODO (cjcullen): Is PublicAddress the right address to sign a cert with?
if err := util.GenerateSelfSignedCert(config.PublicAddress.String(), s.TLSCertFile, s.TLSPrivateKeyFile); err != nil {
if err := util.GenerateSelfSignedCert(config.PublicAddress.String(), s.TLSCertFile, s.TLSPrivateKeyFile, config.ServiceReadWriteIP); err != nil {
glog.Errorf("Unable to generate self signed cert: %v", err)
} else {
glog.Infof("Using self-signed cert (%s, %s)", s.TLSCertFile, s.TLSPrivateKeyFile)
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubelet/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func (s *KubeletServer) InitializeTLS() (*kubelet.TLSOptions, error) {
if s.TLSCertFile == "" && s.TLSPrivateKeyFile == "" {
s.TLSCertFile = path.Join(s.CertDirectory, "kubelet.crt")
s.TLSPrivateKeyFile = path.Join(s.CertDirectory, "kubelet.key")
if err := util.GenerateSelfSignedCert(nodeutil.GetHostname(s.HostnameOverride), s.TLSCertFile, s.TLSPrivateKeyFile); err != nil {
if err := util.GenerateSelfSignedCert(nodeutil.GetHostname(s.HostnameOverride), s.TLSCertFile, s.TLSPrivateKeyFile, nil); err != nil {
return nil, fmt.Errorf("unable to generate self signed cert: %v", err)
}
glog.V(4).Infof("Using self-signed cert (%s, %s)", s.TLSCertFile, s.TLSPrivateKeyFile)
Expand Down
21 changes: 13 additions & 8 deletions pkg/master/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ type Config struct {
// The range of IPs to be assigned to services with type=ClusterIP or greater
ServiceClusterIPRange *net.IPNet

// The IP address for the master service (must be inside ServiceClusterIPRange
ServiceReadWriteIP net.IP

// The range of ports to be assigned to services with type=NodePort or greater
ServiceNodePortRange util.PortRange

Expand Down Expand Up @@ -245,6 +248,15 @@ func setDefaults(c *Config) {
}
c.ServiceClusterIPRange = serviceClusterIPRange
}
if c.ServiceReadWriteIP == nil {
// Select the first valid IP from ServiceClusterIPRange to use as the master service IP.
serviceReadWriteIP, err := ipallocator.GetIndexedIP(c.ServiceClusterIPRange, 1)
if err != nil {
glog.Fatalf("Failed to generate service read-write IP for master service: %v", err)
}
glog.V(4).Infof("Setting master service IP to %q (read-write).", serviceReadWriteIP)
c.ServiceReadWriteIP = serviceReadWriteIP
}
if c.ServiceNodePortRange.Size == 0 {
// TODO: Currently no way to specify an empty range (do we need to allow this?)
// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
Expand Down Expand Up @@ -311,13 +323,6 @@ func New(c *Config) *Master {
glog.Fatalf("master.New() called with config.KubeletClient == nil")
}

// Select the first valid IP from serviceClusterIPRange to use as the master service IP.
serviceReadWriteIP, err := ipallocator.GetIndexedIP(c.ServiceClusterIPRange, 1)
if err != nil {
glog.Fatalf("Failed to generate service read-write IP for master service: %v", err)
}
glog.V(4).Infof("Setting master service IP to %q (read-write).", serviceReadWriteIP)

m := &Master{
serviceClusterIPRange: c.ServiceClusterIPRange,
serviceNodePortRange: c.ServiceNodePortRange,
Expand All @@ -343,7 +348,7 @@ func New(c *Config) *Master {
externalHost: c.ExternalHost,
clusterIP: c.PublicAddress,
publicReadWritePort: c.ReadWritePort,
serviceReadWriteIP: serviceReadWriteIP,
serviceReadWriteIP: c.ServiceReadWriteIP,
// TODO: serviceReadWritePort should be passed in as an argument, it may not always be 443
serviceReadWritePort: 443,

Expand Down
11 changes: 10 additions & 1 deletion pkg/util/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import (
// The certificate will be created with file mode 0644. The key will be created with file mode 0600.
// If the certificate or key files already exist, they will be overwritten.
// Any parent directories of the certPath or keyPath will be created as needed with file mode 0755.
func GenerateSelfSignedCert(host, certPath, keyPath string) error {
func GenerateSelfSignedCert(host, certPath, keyPath string, ServiceReadWriteIP net.IP) error {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
Expand All @@ -63,6 +63,15 @@ func GenerateSelfSignedCert(host, certPath, keyPath string) error {
template.DNSNames = append(template.DNSNames, host)
}

if ServiceReadWriteIP != nil {
template.IPAddresses = append(template.IPAddresses, ServiceReadWriteIP)
}
// It would be nice to have the next line, but only the kubelets know the fqdn, the apiserver is clueless
// template.DNSNames = append(template.DNSNames, "kubernetes.default.svc.CLUSTER.DNS.NAME")
template.DNSNames = append(template.DNSNames, "kubernetes.default.svc")
template.DNSNames = append(template.DNSNames, "kubernetes.default")
template.DNSNames = append(template.DNSNames, "kubernetes")

derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return err
Expand Down

0 comments on commit 7a29af4

Please sign in to comment.