github.com/coreos/mantle@v0.13.0/kola/tests/ignition/security.go (about) 1 // Copyright 2018 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ignition 16 17 import ( 18 "crypto/tls" 19 "fmt" 20 "io/ioutil" 21 "net" 22 "net/http" 23 "net/http/httptest" 24 "strings" 25 26 "github.com/vincent-petithory/dataurl" 27 28 "github.com/coreos/mantle/kola/cluster" 29 "github.com/coreos/mantle/kola/register" 30 "github.com/coreos/mantle/platform/conf" 31 "github.com/coreos/mantle/platform/machine/packet" 32 ) 33 34 var ( 35 localSecurityClient = conf.Ignition(`{ 36 "ignition": { 37 "version": "2.2.0", 38 "config": { 39 "append": [{ 40 "source": "https://$IP" 41 }] 42 }, 43 "security": { 44 "tls": { 45 "certificateAuthorities": [{ 46 "source": "$KEY" 47 }] 48 } 49 } 50 } 51 }`) 52 localSecurityClientV3 = conf.Ignition(`{ 53 "ignition": { 54 "version": "3.0.0", 55 "config": { 56 "merge": [{ 57 "source": "https://$IP" 58 }] 59 }, 60 "security": { 61 "tls": { 62 "certificateAuthorities": [{ 63 "source": "$KEY" 64 }] 65 } 66 } 67 } 68 }`) 69 ) 70 71 func init() { 72 register.Register(®ister.Test{ 73 Name: "coreos.ignition.security.tls", 74 Run: securityTLS, 75 ClusterSize: 1, 76 NativeFuncs: map[string]func() error{ 77 "TLSServe": TLSServe, 78 "TLSServeV3": TLSServeV3, 79 }, 80 // DO: https://github.com/coreos/bugs/issues/2205 81 // Packet & QEMU: https://github.com/coreos/ignition/issues/645 82 ExcludePlatforms: []string{"do", "packet", "qemu"}, 83 Distros: []string{"cl", "fcos", "rhcos"}, 84 }) 85 } 86 87 func securityTLS(c cluster.TestCluster) { 88 server := c.Machines()[0] 89 90 ip := server.PrivateIP() 91 if c.Platform() == packet.Platform { 92 // private IP not configured in the initramfs 93 ip = server.IP() 94 } 95 96 c.MustSSH(server, "sudo mkdir /var/tls") 97 c.MustSSH(server, "sudo openssl ecparam -genkey -name secp384r1 -out /var/tls/server.key") 98 c.MustSSH(server, strings.Replace(`sudo bash -c 'openssl req -new -x509 -sha256 -key /var/tls/server.key -out /var/tls/server.crt -days 3650 -subj "/CN=$IP" -config <(cat <<-EOF 99 [req] 100 default_bits = 2048 101 default_md = sha256 102 distinguished_name = dn 103 104 [ dn ] 105 CN = $IP 106 107 [ SAN ] 108 subjectAltName = IP:$IP 109 EOF 110 ) -extensions SAN'`, "$IP", ip, -1)) 111 publicKey := c.MustSSH(server, "sudo cat /var/tls/server.crt") 112 113 var serveFunc string 114 var conf *conf.UserData 115 switch c.IgnitionVersion() { 116 case "v2": 117 serveFunc = "TLSServe" 118 conf = localSecurityClient 119 case "v3": 120 serveFunc = "TLSServeV3" 121 conf = localSecurityClientV3 122 default: 123 c.Fatal("unknown ignition version") 124 } 125 126 c.MustSSH(server, fmt.Sprintf("sudo systemd-run --quiet ./kolet run %s %s", c.H.Name(), serveFunc)) 127 128 client, err := c.NewMachine(conf.Subst("$IP", ip).Subst("$KEY", dataurl.EncodeBytes(publicKey))) 129 if err != nil { 130 c.Fatalf("starting client: %v", err) 131 } 132 133 checkResources(c, client, map[string]string{ 134 "data": "kola-data", 135 }) 136 } 137 138 func ServeTLS(customFile []byte) error { 139 publicKey, err := ioutil.ReadFile("/var/tls/server.crt") 140 if err != nil { 141 return fmt.Errorf("reading public key: %v", err) 142 } 143 144 privateKey, err := ioutil.ReadFile("/var/tls/server.key") 145 if err != nil { 146 return fmt.Errorf("reading private key: %v", err) 147 } 148 149 cer, err := tls.X509KeyPair(publicKey, privateKey) 150 if err != nil { 151 return fmt.Errorf("error loading x509 keypair: %v", err) 152 } 153 154 config := &tls.Config{ 155 Certificates: []tls.Certificate{cer}, 156 } 157 158 caserver := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 159 w.Write(customFile) 160 })) 161 l, err := net.Listen("tcp", ":443") 162 if err != nil { 163 return err 164 } 165 caserver.Listener.Close() 166 caserver.Listener = l 167 caserver.TLS = config 168 caserver.StartTLS() 169 170 select {} 171 } 172 173 func TLSServe() error { 174 customFile := []byte(`{ 175 "ignition": { "version": "2.1.0" }, 176 "storage": { 177 "files": [{ 178 "filesystem": "root", 179 "path": "/var/resource/data", 180 "contents": { "source": "data:,kola-data" } 181 }] 182 } 183 }`) 184 return ServeTLS(customFile) 185 } 186 187 func TLSServeV3() error { 188 customFileV3 := []byte(`{ 189 "ignition": { "version": "3.0.0" }, 190 "storage": { 191 "files": [{ 192 "path": "/var/resource/data", 193 "contents": { "source": "data:,kola-data" } 194 }] 195 } 196 }`) 197 return ServeTLS(customFileV3) 198 }