adds tls certificate to tls config
Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
parent
cf156144bc
commit
89adb74414
@ -17,7 +17,7 @@
|
||||
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
|
||||
|
||||
# Not from vendor.conf.
|
||||
CRITOOL_VERSION=976680c4aa382339ccba214d1f1a88fdc8638b78
|
||||
CRITOOL_VERSION=207e773f72fde8d8aed1447692d8f800a6686d6c
|
||||
CRITOOL_PKG=github.com/kubernetes-incubator/cri-tools
|
||||
CRITOOL_REPO=github.com/kubernetes-incubator/cri-tools
|
||||
|
||||
|
@ -17,20 +17,38 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
k8snet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
k8scert "k8s.io/client-go/util/cert"
|
||||
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// OrganizationName is is the name of this organization, used for certificates etc.
|
||||
OrganizationName = "containerd"
|
||||
// CRIName is the common name of the CRI plugin
|
||||
CRIName = "cri"
|
||||
)
|
||||
|
||||
func newStreamServer(c *criService, addr, port string) (streaming.Server, error) {
|
||||
if addr == "" {
|
||||
a, err := k8snet.ChooseBindAddress(nil)
|
||||
@ -42,6 +60,14 @@ func newStreamServer(c *criService, addr, port string) (streaming.Server, error)
|
||||
config := streaming.DefaultConfig
|
||||
config.Addr = net.JoinHostPort(addr, port)
|
||||
runtime := newStreamRuntime(c)
|
||||
tlsCert, err := newTLSCert()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to generate tls certificate for stream server")
|
||||
}
|
||||
config.TLSConfig = &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
return streaming.NewServer(config, runtime)
|
||||
}
|
||||
|
||||
@ -112,3 +138,87 @@ func handleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(si
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// newTLSCert returns a tls.certificate loaded from a newly generated
|
||||
// x509certificate from a newly generated rsa public/private key pair. The
|
||||
// x509certificate is self signed.
|
||||
// TODO (mikebrow): replace / rewrite this function to support using CA
|
||||
// signing of the cetificate. Requires a security plan for kubernetes regarding
|
||||
// CRI connections / streaming, etc. For example, kubernetes could configure or
|
||||
// require a CA service and pass a configuration down through CRI.
|
||||
func newTLSCert() (tls.Certificate, error) {
|
||||
fail := func(err error) (tls.Certificate, error) { return tls.Certificate{}, err }
|
||||
var years = 1 // duration of certificate
|
||||
|
||||
// Generate new private key
|
||||
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "private key cannot be created"))
|
||||
}
|
||||
|
||||
// Generate pem block using the private key
|
||||
keyPem := pem.EncodeToMemory(&pem.Block{
|
||||
Type: k8scert.RSAPrivateKeyBlockType,
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(privKey),
|
||||
})
|
||||
|
||||
// Generate a new random serial number for certificate
|
||||
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to generate serial number"))
|
||||
}
|
||||
hostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to get hostname"))
|
||||
}
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to get host IP addresses"))
|
||||
}
|
||||
|
||||
// Configure and create new certificate
|
||||
tml := x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(years, 0, 0),
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("%s:%s:%s", OrganizationName, CRIName, hostName),
|
||||
Organization: []string{OrganizationName},
|
||||
},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
tml.IPAddresses = append(tml.IPAddresses, ip)
|
||||
tml.DNSNames = append(tml.DNSNames, ip.String())
|
||||
}
|
||||
|
||||
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &privKey.PublicKey, privKey)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "certificate cannot be created"))
|
||||
}
|
||||
|
||||
// Generate a pem block with the certificate
|
||||
certPem := pem.EncodeToMemory(&pem.Block{
|
||||
Type: k8scert.CertificateBlockType,
|
||||
Bytes: cert,
|
||||
})
|
||||
|
||||
// Load the tls certificate
|
||||
tlsCert, err := tls.X509KeyPair(certPem, keyPem)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "certificate could not be loaded"))
|
||||
}
|
||||
|
||||
return tlsCert, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user