github.com/bshelton229/agent@v3.5.4+incompatible/scripts/vagrant/windows/create-docker-machine.ps1 (about) 1 param ([String] $machineHome, [String] $machineName, [String] $machineIp) 2 3 if (!(Test-Path $env:USERPROFILE\.docker)) { 4 mkdir $env:USERPROFILE\.docker 5 } 6 7 $ipAddresses = ((Get-NetIPAddress -AddressFamily IPv4).IPAddress) -Join ',' 8 9 if (!$machineIp) { 10 $machineIp=(Get-NetIPAddress -AddressFamily IPv4 ` 11 | Where-Object -FilterScript { ` 12 ( ! ($_.InterfaceAlias).StartsWith("vEthernet (") ) ` 13 -And $_.IPAddress -Ne "127.0.0.1" ` 14 -And $_.IPAddress -Ne "10.0.2.15" ` 15 }).IPAddress 16 } 17 18 $homeDir = $machineHome 19 if ($machineHome.startsWith('/')) { 20 $homeDir = "C:$machineHome" # /Users/stefan from Mac -> C:/Users/stefan 21 } 22 23 function ensureDirs($dirs) { 24 foreach ($dir in $dirs) { 25 if (!(Test-Path $dir)) { 26 mkdir $dir 27 } 28 } 29 } 30 31 # https://docs.docker.com/engine/security/https/ 32 # Thanks to @artisticcheese! https://artisticcheese.wordpress.com/2017/06/10/using-pure-powershell-to-generate-tls-certificates-for-docker-daemon-running-on-windows/ 33 function createCA($serverCertsPath) { 34 Write-Host "`n=== Generating CA" 35 $parms = @{ 36 type = "Custom" ; 37 KeyExportPolicy = "Exportable"; 38 Subject = "CN=Docker TLS Root"; 39 CertStoreLocation = "Cert:\CurrentUser\My"; 40 HashAlgorithm = "sha256"; 41 KeyLength = 4096; 42 KeyUsage = @("CertSign", "CRLSign"); 43 TextExtension = @("2.5.29.19 ={critical} {text}ca=1") 44 } 45 $rootCert = New-SelfSignedCertificate @parms 46 47 Write-Host "`n=== Generating CA public key" 48 $parms = @{ 49 Path = "$serverCertsPath\ca.pem"; 50 Value = "-----BEGIN CERTIFICATE-----`n" ` 51 + [System.Convert]::ToBase64String($rootCert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks) ` 52 + "`n-----END CERTIFICATE-----"; 53 Encoding = "ASCII"; 54 } 55 Set-Content @parms 56 return $rootCert 57 } 58 59 # https://docs.docker.com/engine/security/https/ 60 function createCerts($rootCert, $serverCertsPath, $serverName, $ipAddresses, $clientCertsPath) { 61 Write-Host "`n=== Generating Server certificate" 62 $parms = @{ 63 CertStoreLocation = "Cert:\CurrentUser\My"; 64 Signer = $rootCert; 65 KeyExportPolicy = "Exportable"; 66 Provider = "Microsoft Enhanced Cryptographic Provider v1.0"; 67 Type = "SSLServerAuthentication"; 68 HashAlgorithm = "sha256"; 69 TextExtension = @("2.5.29.37= {text}1.3.6.1.5.5.7.3.1", "2.5.29.17={text}DNS=$serverName&DNS=localhost&IPAddress=$($ipAddresses.Split(',') -Join '&IPAddress=')"); 70 KeyLength = 4096; 71 } 72 $serverCert = New-SelfSignedCertificate @parms 73 74 $parms = @{ 75 Path = "$serverCertsPath\server-cert.pem"; 76 Value = "-----BEGIN CERTIFICATE-----`n" ` 77 + [System.Convert]::ToBase64String($serverCert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks) ` 78 + "`n-----END CERTIFICATE-----"; 79 Encoding = "Ascii" 80 } 81 Set-Content @parms 82 83 Write-Host "`n=== Generating Server private key" 84 $privateKeyFromCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($serverCert) 85 $parms = @{ 86 Path = "$serverCertsPath\server-key.pem"; 87 Value = ("-----BEGIN RSA PRIVATE KEY-----`n" ` 88 + [System.Convert]::ToBase64String($privateKeyFromCert.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob), [System.Base64FormattingOptions]::InsertLineBreaks) ` 89 + "`n-----END RSA PRIVATE KEY-----"); 90 Encoding = "Ascii"; 91 } 92 Set-Content @parms 93 94 Write-Host "`n=== Generating Client certificate" 95 $parms = @{ 96 CertStoreLocation = "Cert:\CurrentUser\My"; 97 Subject = "CN=clientCert"; 98 Signer = $rootCert ; 99 KeyExportPolicy = "Exportable"; 100 Provider = "Microsoft Enhanced Cryptographic Provider v1.0"; 101 TextExtension = @("2.5.29.37= {text}1.3.6.1.5.5.7.3.2") ; 102 HashAlgorithm = "sha256"; 103 KeyLength = 4096; 104 } 105 $clientCert = New-SelfSignedCertificate @parms 106 107 $parms = @{ 108 Path = "$clientCertsPath\cert.pem" ; 109 Value = ("-----BEGIN CERTIFICATE-----`n" + [System.Convert]::ToBase64String($clientCert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks) + "`n-----END CERTIFICATE-----"); 110 Encoding = "Ascii"; 111 } 112 Set-Content @parms 113 114 Write-Host "`n=== Generating Client key" 115 $clientprivateKeyFromCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($clientCert) 116 $parms = @{ 117 Path = "$clientCertsPath\key.pem"; 118 Value = ("-----BEGIN RSA PRIVATE KEY-----`n" ` 119 + [System.Convert]::ToBase64String($clientprivateKeyFromCert.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob), [System.Base64FormattingOptions]::InsertLineBreaks) ` 120 + "`n-----END RSA PRIVATE KEY-----"); 121 Encoding = "Ascii"; 122 } 123 Set-Content @parms 124 125 copy $serverCertsPath\ca.pem $clientCertsPath\ca.pem 126 } 127 128 function updateConfig($daemonJson, $serverCertsPath) { 129 $config = @{} 130 if (Test-Path $daemonJson) { 131 $config = (Get-Content $daemonJson) -join "`n" | ConvertFrom-Json 132 } 133 134 $config = $config | Add-Member(@{ ` 135 hosts = @("tcp://0.0.0.0:2376", "npipe://"); ` 136 tlsverify = $true; ` 137 tlscacert = "$serverCertsPath\ca.pem"; ` 138 tlscert = "$serverCertsPath\server-cert.pem"; ` 139 tlskey = "$serverCertsPath\server-key.pem" ` 140 }) -Force -PassThru 141 142 Write-Host "`n=== Creating / Updating $daemonJson" 143 $config | ConvertTo-Json | Set-Content $daemonJson -Encoding Ascii 144 } 145 146 function createMachineConfig ($machineName, $machineHome, $machinePath, $machineIp, $serverCertsPath, $clientCertsPath) { 147 $machineConfigJson = "$machinePath\config.json" 148 149 $config = @" 150 { 151 "ConfigVersion": 3, 152 "Driver": { 153 "IPAddress": "$machineIp", 154 "MachineName": "$machineName", 155 "SSHUser": "none", 156 "SSHPort": 3389, 157 "SSHKeyPath": "", 158 "StorePath": "$machineHome/.docker/machine", 159 "SwarmMaster": false, 160 "SwarmHost": "", 161 "SwarmDiscovery": "", 162 "EnginePort": 2376, 163 "SSHKey": "" 164 }, 165 "DriverName": "generic", 166 "HostOptions": { 167 "Driver": "", 168 "Memory": 0, 169 "Disk": 0, 170 "EngineOptions": { 171 "ArbitraryFlags": [], 172 "Dns": null, 173 "GraphDir": "", 174 "Env": [], 175 "Ipv6": false, 176 "InsecureRegistry": [], 177 "Labels": [], 178 "LogLevel": "", 179 "StorageDriver": "", 180 "SelinuxEnabled": false, 181 "TlsVerify": true, 182 "RegistryMirror": [], 183 "InstallURL": "https://get.docker.com" 184 }, 185 "SwarmOptions": { 186 "IsSwarm": false, 187 "Address": "", 188 "Discovery": "", 189 "Agent": false, 190 "Master": false, 191 "Host": "tcp://0.0.0.0:3376", 192 "Image": "swarm:latest", 193 "Strategy": "spread", 194 "Heartbeat": 0, 195 "Overcommit": 0, 196 "ArbitraryFlags": [], 197 "ArbitraryJoinFlags": [], 198 "Env": null, 199 "IsExperimental": false 200 }, 201 "AuthOptions": { 202 "CertDir": "$machineHome/.docker/machine/machines/$machineName", 203 "CaCertPath": "$machineHome/.docker/machine/machines/$machineName/ca.pem", 204 "CaPrivateKeyPath": "$machineHome/.docker/machine/machines/$machineName/ca-key.pem", 205 "CaCertRemotePath": "", 206 "ServerCertPath": "$machineHome/.docker/machine/machines/$machineName/server.pem", 207 "ServerKeyPath": "$machineHome/.docker/machine/machines/$machineName/server-key.pem", 208 "ClientKeyPath": "$machineHome/.docker/machine/machines/$machineName/key.pem", 209 "ServerCertRemotePath": "", 210 "ServerKeyRemotePath": "", 211 "ClientCertPath": "$machineHome/.docker/machine/machines/$machineName/cert.pem", 212 "ServerCertSANs": [], 213 "StorePath": "$machineHome/.docker/machine/machines/$machineName" 214 } 215 }, 216 "Name": "$machineName" 217 } 218 "@ 219 220 Write-Host "`n=== Creating / Updating $machineConfigJson" 221 $config | Set-Content $machineConfigJson -Encoding Ascii 222 223 Write-Host "`n=== Copying Client certificates to $machinePath" 224 copy $serverCertsPath\ca.pem $machinePath\ca.pem 225 copy $clientCertsPath\cert.pem $machinePath\cert.pem 226 copy $clientCertsPath\key.pem $machinePath\key.pem 227 } 228 229 $dockerData = "$env:ProgramData\docker" 230 $userPath = "$env:USERPROFILE\.docker" 231 232 ensureDirs @("$dockerData\certs.d", "$dockerData\config", "$userPath") 233 234 $serverCertsPath = "$dockerData\certs.d" 235 $clientCertsPath = "$userPath" 236 $rootCert = createCA "$dockerData\certs.d" 237 238 createCerts $rootCert $serverCertsPath $serverName $ipAddresses $clientCertsPath 239 updateConfig "$dockerData\config\daemon.json" $serverCertsPath 240 241 if ($machineName) { 242 $machinePath = "$env:USERPROFILE\.docker\machine\machines\$machineName" 243 ensureDirs @($machinePath) 244 createMachineConfig $machineName $machineHome $machinePath $machineIp $serverCertsPath $clientCertsPath 245 } 246 247 Write-Host "`n=== Copying Docker Machine configuration to $homeDir\.docker\machine\machines\$machineName" 248 if (Test-Path "$homeDir\.docker\machine\machines\$machineName") { 249 rm -recurse "$homeDir\.docker\machine\machines\$machineName" 250 } 251 Copy-Item -Recurse "$env:USERPROFILE\.docker\machine\machines\$machineName" "$homeDir\.docker\machine\machines\$machineName" 252 253 Write-host Restarting Docker 254 stop-service docker 255 dockerd --unregister-service 256 dockerd --register-service 257 start-service docker 258 259 Write-Host Opening Docker TLS port 260 & netsh advfirewall firewall add rule name="Docker TLS" dir=in action=allow protocol=TCP localport=2376