2016-12-17 17:04:44 +00:00
|
|
|
/*
|
|
|
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
|
|
|
|
|
|
|
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 util
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
2017-02-20 01:53:42 +00:00
|
|
|
"net"
|
2016-12-17 17:04:44 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
2017-02-18 21:35:03 +00:00
|
|
|
|
|
|
|
"k8s.io/minikube/pkg/minikube/constants"
|
2016-12-17 17:04:44 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestGenerateCACert(t *testing.T) {
|
2021-09-28 10:58:01 +00:00
|
|
|
tmpDir, err := os.MkdirTemp("", "")
|
2021-04-19 22:16:31 +00:00
|
|
|
defer func() { // clean up tempdir
|
2020-04-15 02:33:26 +00:00
|
|
|
err := os.RemoveAll(tmpDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("failed to clean up temp folder %q", tmpDir)
|
|
|
|
}
|
|
|
|
}()
|
2016-12-17 17:04:44 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error generating tmpdir: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
certPath := filepath.Join(tmpDir, "cert")
|
|
|
|
keyPath := filepath.Join(tmpDir, "key")
|
2017-02-18 21:35:03 +00:00
|
|
|
if err := GenerateCACert(certPath, keyPath, constants.APIServerName); err != nil {
|
2016-12-17 17:04:44 +00:00
|
|
|
t.Fatalf("GenerateCACert() error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the cert has the right shape.
|
2021-09-28 10:58:01 +00:00
|
|
|
certBytes, err := os.ReadFile(certPath)
|
2016-12-17 17:04:44 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error reading cert data: %v", err)
|
|
|
|
}
|
|
|
|
data, _ := pem.Decode(certBytes)
|
|
|
|
c, err := x509.ParseCertificate(data.Bytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error parsing certificate: %v", err)
|
|
|
|
}
|
|
|
|
if !c.IsCA {
|
|
|
|
t.Fatalf("Cert is not a CA cert.")
|
|
|
|
}
|
|
|
|
}
|
2017-02-20 01:53:42 +00:00
|
|
|
|
|
|
|
func TestGenerateSignedCert(t *testing.T) {
|
2021-09-28 10:58:01 +00:00
|
|
|
tmpDir, err := os.MkdirTemp("", "")
|
2021-04-19 22:16:31 +00:00
|
|
|
defer func() { // clean up tempdir
|
2020-04-15 02:33:26 +00:00
|
|
|
err := os.RemoveAll(tmpDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("failed to clean up temp folder %q", tmpDir)
|
|
|
|
}
|
|
|
|
}()
|
2017-02-20 01:53:42 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error generating tmpdir: %v", err)
|
|
|
|
}
|
|
|
|
|
2021-09-28 10:58:01 +00:00
|
|
|
signerTmpDir, err := os.MkdirTemp("", "")
|
2021-04-19 22:16:31 +00:00
|
|
|
defer func() { // clean up tempdir
|
2020-04-15 02:33:26 +00:00
|
|
|
err := os.RemoveAll(signerTmpDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("failed to clean up temp folder %q", signerTmpDir)
|
|
|
|
}
|
|
|
|
}()
|
2017-02-20 01:53:42 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error generating signer tmpdir: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
validSignerCertPath := filepath.Join(signerTmpDir, "cert")
|
|
|
|
validSignerKeyPath := filepath.Join(signerTmpDir, "key")
|
|
|
|
|
2017-02-28 02:47:30 +00:00
|
|
|
err = GenerateCACert(validSignerCertPath, validSignerKeyPath, constants.APIServerName)
|
2017-02-20 01:53:42 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error generating signer cert")
|
|
|
|
}
|
|
|
|
|
|
|
|
certPath := filepath.Join(tmpDir, "cert")
|
|
|
|
keyPath := filepath.Join(tmpDir, "key")
|
|
|
|
|
virtualbox: change default `host-only-cidr`
We change the default `--host-only-cidr` to `192.168.59.1/24` in order
to be compatible with the new default host-only networking restrictions
implemented in VirtualBox 6.1.28.
This fixes access denied errors on `minikube start` when using
VirtualBox >= 6.1.28:
```
VBoxManage: error: Code E_ACCESSDENIED (0x80070005) - Access denied (extended info not available)
VBoxManage: error: Context: "EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw())" at line 242 of file VBoxManageHostonly.cpp
```
More details:
VirtualBox 6.1.28 introduced new restrictions on host-only networking:
https://www.virtualbox.org/wiki/Changelog-6.1#v28
Manual: https://www.virtualbox.org/manual/ch06.html#network_hostonly
> On Linux, Mac OS X and Solaris Oracle VM VirtualBox will only allow IP
> addresses in 192.68.56.0/21 range to be assigned to host-only
> adapters. For IPv6 only link-local addresses are allowed. If other
> ranges are desired, they can be enabled by creating
> /etc/vbox/networks.conf and specifying allowed ranges there. For
> example, to allow 10.0.0.0/8 and 192.168.0.0/16 IPv4 ranges as well as
> 2001::/64 range put the following lines into /etc/vbox/networks.conf:
>
> * 10.0.0.0/8 192.168.0.0/16
> * 2001::/64
>
> Lines starting with the hash # are ignored. Next example allows any
> addresses, effectively disabling range control:
>
> * 0.0.0.0/0 ::/0
These new restrictions manifest in the form of the following issue on
`minikube start` due to the default `--host-only-cidr` used by the
VirtualBox driver being `192.168.99.1/24`:
```console
😄 minikube v1.23.2 on Ubuntu 18.04
✨ Using the virtualbox driver based on user configuration
👍 Starting control plane node minikube in cluster minikube
🔥 Creating virtualbox VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
🔥 Deleting "minikube" in virtualbox ...
🤦 StartHost failed, but will try again: creating host: create: creating: Error setting up host only network on machine start: /usr/bin/VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.99.1 --netmask 255.255.255.0 failed:
VBoxManage: error: Code E_ACCESSDENIED (0x80070005) - Access denied (extended info not available)
VBoxManage: error: Context: "EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw())" at line 242 of file VBoxManageHostonly.cpp
🔥 Creating virtualbox VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
😿 Failed to start virtualbox VM. Running "minikube delete" may fix it: creating host: create: creating: Error setting up host only network on machine start: /usr/bin/VBoxManage hostonlyif ipconfig vboxnet1 --ip 192.168.99.1 --netmask 255.255.255.0 failed:
VBoxManage: error: Code E_ACCESSDENIED (0x80070005) - Access denied (extended info not available)
VBoxManage: error: Context: "EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw())" at line 242 of file VBoxManageHostonly.cpp
❌ Exiting due to GUEST_PROVISION: Failed to start host: creating host: create: creating: Error setting up host only network on machine start: /usr/bin/VBoxManage hostonlyif ipconfig vboxnet1 --ip 192.168.99.1 --netmask 255.255.255.0 failed:
VBoxManage: error: Code E_ACCESSDENIED (0x80070005) - Access denied (extended info not available)
VBoxManage: error: Context: "EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw())" at line 242 of file VBoxManageHostonly.cpp
╭───────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ 😿 If the above advice does not help, please let us know: │
│ 👉 https://github.com/kubernetes/minikube/issues/new/choose │
│ │
│ Please run `minikube logs --file=logs.txt` and attach logs.txt to the GitHub issue. │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────╯
```
While the above is the primary error, other errors will be reported if
the adapter already exists (this happens when the adapter was created
before updating to VirtualBox 6.1.28, on a version of VirtualBox without
the new restrictions). Some examples:
```
❌ Exiting due to IF_VBOX_NOT_VISIBLE: Failed to start host: creating host: create: creating: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue
```
```
❌ minikube is unable to connect to the VM: dial tcp 192.168.99.112:22: i/o timeout
This is likely due to one of two reasons:
- VPN or firewall interference
- virtualbox network configuration issue
Suggested workarounds:
- Disable your local VPN or firewall software
- Configure your local VPN or firewall to allow access to 192.168.99.112
- Restart or reinstall virtualbox
- Use an alternative --vm-driver
- Use --force to override this connectivity check
❌ Exiting due to GUEST_PROVISION: Failed to validate network: dial tcp 192.168.99.112:22: i/o timeout
```
When switching to a valid CIDR, `minikube start` works as usual:
```console
😄 minikube v1.23.2 on Ubuntu 18.04
✨ Using the virtualbox driver based on user configuration
👍 Starting control plane node minikube in cluster minikube
🔥 Creating virtualbox VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.22.2 on Docker 20.10.8 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🔎 Verifying Kubernetes components...
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```
Signed-off-by: Nicolas Busseneau <nicolas@isovalent.com>
2021-10-28 15:24:24 +00:00
|
|
|
ips := []net.IP{net.ParseIP("192.168.59.100"), net.ParseIP("10.0.0.10")}
|
2017-02-20 01:53:42 +00:00
|
|
|
alternateDNS := []string{"kubernetes.default.svc.cluster.local", "kubernetes.default"}
|
|
|
|
|
|
|
|
var tests = []struct {
|
|
|
|
description string
|
|
|
|
signerCertPath string
|
|
|
|
signerKeyPath string
|
|
|
|
err bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
description: "wrong cert path",
|
|
|
|
signerCertPath: "",
|
|
|
|
signerKeyPath: validSignerKeyPath,
|
|
|
|
err: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "wrong key path",
|
|
|
|
signerCertPath: validSignerCertPath,
|
|
|
|
signerKeyPath: "",
|
|
|
|
err: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "valid cert",
|
|
|
|
signerCertPath: validSignerCertPath,
|
|
|
|
signerKeyPath: validSignerKeyPath,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "wrong key file",
|
|
|
|
signerCertPath: validSignerCertPath,
|
|
|
|
signerKeyPath: validSignerCertPath,
|
|
|
|
err: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "wrong cert file",
|
|
|
|
signerCertPath: validSignerKeyPath,
|
|
|
|
signerKeyPath: validSignerKeyPath,
|
|
|
|
err: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
test := test
|
|
|
|
t.Run(test.description, func(t *testing.T) {
|
2017-09-06 22:11:59 +00:00
|
|
|
err := GenerateSignedCert(
|
|
|
|
certPath, keyPath, "minikube", ips, alternateDNS, test.signerCertPath,
|
2021-09-24 18:47:10 +00:00
|
|
|
test.signerKeyPath, constants.DefaultCertExpiration,
|
2017-09-06 22:11:59 +00:00
|
|
|
)
|
2017-02-20 01:53:42 +00:00
|
|
|
if err != nil && !test.err {
|
|
|
|
t.Errorf("GenerateSignedCert() error = %v", err)
|
|
|
|
}
|
|
|
|
if err == nil && test.err {
|
|
|
|
t.Errorf("GenerateSignedCert() should have returned error, but didn't")
|
|
|
|
}
|
|
|
|
if err == nil {
|
2021-09-28 10:58:01 +00:00
|
|
|
certBytes, err := os.ReadFile(certPath)
|
2017-02-20 01:53:42 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error reading cert data: %v", err)
|
|
|
|
}
|
|
|
|
data, _ := pem.Decode(certBytes)
|
|
|
|
_, err = x509.ParseCertificate(data.Bytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error parsing certificate: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|