microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.34k stars 814 forks source link

How to import all Root CAs from Windows store into WSL automatically? #3161

Closed rfgamaral closed 6 years ago

rfgamaral commented 6 years ago

I have this self-signed corporate root CA installed on my Windows machine for all internal company services which is not being automatically propagated to WSL.

As a workaround I had to place the crt file under /usr/local/share/ca-certificates/*.crt and invoke sudo update-ca-certificates (this for a Debian WSL installation). The certificate will then be installed to /etc/ssl/certs/* and will also be available in the /etc/ssl/certs/ca-certificates.crt bundle.

Is it possible to configure WSL to do this automatically?

therealkenc commented 6 years ago

Is it possible to configure WSL to do this automatically?

It isn't.

alanaasmaa commented 5 years ago

To get it to work with WSL I approced this way.

  1. I installed mkcert to windows with mkcert -install
  2. Then i installed it to WSL mkcert -install
  3. I went to directory where mkcert created CA filed for windows and copyed them to WSL location. So WSL now uses windows CA files.
  4. I runned mkcert -install again on WSL
  5. Created a certs from WSL and configurated them to apache/nginx. Works!
adamdecaf commented 5 years ago

FYI, mkcert is this tool: https://github.com/FiloSottile/mkcert

alanaasmaa commented 5 years ago

@adamdecaf Oh i posted the this into wrong repo 🙃

ismailcherri commented 4 years ago

@alanaasmaa IT WORKS! Many thanks 😄

gernacke commented 3 years ago

To get it to work with WSL I approced this way.

1. I installed mkcert to windows with `mkcert -install`

2. Then i installed it to WSL `mkcert -install`

3. I went to directory where mkcert created CA filed for windows and copyed them to WSL location.
   So WSL now uses windows CA files.

4. I runned `mkcert -install` again on WSL

5. Created a certs from WSL and configurated them to apache/nginx.
   Works!

this just resolved my SSL errors that I have experienced on my company Windows machines for months!!! Thanks!

abdennour commented 3 years ago

Thank you @gernacke for the confirmation but could you give more details . For example , which directory location regarding point 3 I went to directory where mkcert created CA filed for windows

gernacke commented 3 years ago

Thank you @gernacke for the confirmation but could you give more details . For example , which directory location regarding point 3 I went to directory where mkcert created CA filed for windows

@abdennour Below is a note I wrote to myself for future reference:

Install mkcert on both Windows and Linux machine. Use Chocolatey to install mkcert in Powershell. > choco install mkcert

Check mkcert github for installation process for Linux systems.

Run below on Windows powershell. > mkcert -install Run below on WSL > mkcert -install Copy the files/or make symbolic links in the Windows mkcert folder to WSL mkcert folder, below command will return the mkcert folder location. > mkcert -CAROOT Run below again in WSL, this should make WSL to respect Windows ca root certificates. > mkcert -install

Nguimjeu commented 3 years ago

I know the issue is closed, but this command helped me solved the issue of sharing Root CA between windows and WSL2

Commaand was executed in PowerShell

setx CAROOT "$(mkcert -CAROOT)"; If ($Env:WSLENV -notlike "*CAROOT*") { setx WSLENV "CAROOT/up:$Env:WSLENV" }

antman94 commented 3 years ago

Thank you @gernacke for the confirmation but could you give more details . For example , which directory location regarding point 3 I went to directory where mkcert created CA filed for windows

@abdennour Below is a note I wrote to myself for future reference:

Install mkcert on both Windows and Linux machine. Use Chocolatey to install mkcert in Powershell. > choco install mkcert

Check mkcert github for installation process for Linux systems.

Run below on Windows powershell. > mkcert -install Run below on WSL > mkcert -install Copy the files/or make symbolic links in the Windows mkcert folder to WSL mkcert folder, below command will return the mkcert folder location. > mkcert -CAROOT Run below again in WSL, this should make WSL to respect Windows ca root certificates. > mkcert -install

This was super helpful! Thanks man

chanakasan commented 3 years ago

My solution:

  1. Install mkcert in Windows and WSL.
  2. Run mkcert -install in WSL.
  3. Copy mkcert root CA file (try mkcert -CAROOT to find location) from WSL to C:\Users\User\AppData\Local\mkcert desktop.
  4. Open a command prompt as administrator and cd to C:\Users\User\AppData\Local\mkcert.
  5. Then run certutil -addstore root rootCA.pem

Now the browsers should see this CA as valid.

mrslezak commented 3 years ago

Okay I have FINALLY found a solution for using Chromium in WSL2... I know this issue is closed, but it shouldn't be. If your company has multiple certificates, the mkcert solution won't work. This worked for me:

In Windows 10, type cert in the search bar, Now click on the Manage User Certificates that pops up.

Click on the Trusted Root Certification Authorities entry, then Certificates that pops up on the right side.

Now scroll down until you find certificates issued by [YOUR COMPANY NAME].

For my company, I only used these ones:

[COMPANY NAME] Private Type 1 Primary Issuing CA [COMPANY NAME] Private Type 1 Root CA [COMPANY NAME] Private Type 2 Root CA

Double click on the 1st certificate. Now go to the Details tab. Click the Copy to File... button. Now the Certificate Export Wizard will come up, click Next.

Since we are using this in the Linux certificate store, we need to select Base-64 encoded X.509 (.CER). Then click Next. Now it will pop up with a Browse button on where to export the certificate, so click it.

Let's use WSL2's built in Windows path to avoid extra copying, type \wsl$\ and your WSL2 distribution(s) will show up. Double click the name of the one you're trying to use (for me, it's debian), then browse to: /usr/local/share/ca-certificates/

Now type a logical filename (i.e. COMPANY-Primary.cer). Repeat for the other 2 certificates listed above (I called them COMPANY-Root1.cer and COMPANY-Root2.cer)

Now load up your wsl instance. Powershell / type wsl to launch the default distro.

Now type: cd /usr/local/share/ca-certificates/ Next, we need to convert these into .crt files. So type each line below separately:

sudo openssl x509 -inform PEM -in COMPANY-Primary.cer -out COMPANY-Primary.crt sudo openssl x509 -inform PEM -in COMPANY-Root1.cer -out COMPANY-Root1.crt sudo openssl x509 -inform PEM -in COMPANY-Root2.cer -out COMPANY-Root2.crt

Now we have importable Root Certificates for Chromium! But first, we should load them into the certificate store by typing:

sudo update-ca-certificates

Next, login to the GUI you are using (for me, it's XFCE4). Open Chromium. Click the 3 dots in the upper right, scroll down to Security, then scroll to Manage Certificates, click Authorities, and click Import. Now browse to /usr/local/share/ca-certificates/ and import each .crt file you generated in the prior step, ensure you click on each item that can be trusted (websites, emails). Once you're done, feel free to browse the internet! The only thing I noticed is I was "logged out" of my company internal website, possibly because I missed a certificate, but I don't care because I only use WSL2 for development work. If I need to access the company websites I just use Windows Edge browser.

I really hope this helps someone else out! mkcert NEVER worked for me. This did right away.

mannharleen commented 2 years ago

This is a shorter version of what @mrslezak posted -

Go to Manage User Certificates >  Trusted Root Certification Authorities > Certificates > Open the root CA you are interesed in
> Details > Copy To File > Base64 X.509

Copy that .cer file to /usr/local/share/ca-certificates in WSL2
Run 
sudo openssl x509 -inform PEM -in xxx.cer -out xxx.crt
sudo update-ca-certificates

Verify:
ls /etc/ssl/certs | grep xxx
TiloGit commented 2 years ago

here cmd to run it from WSL env. Could be optimized and via loop automated to get more

here the PS

## Check path/stores/details
Get-ChildItem "cert:\LocalMachine" -recurse | Where-Object { $_.Subject -match "CN=my-cert-subject" }
###export via PS
Export-Certificate -Cert @(Get-ChildItem "cert:\LocalMachine" -recurse | Where-Object { $_.Subject -match "CN=my-cert-subject" })[0] -FilePath root-cert.cer -Type CERT

bash to run on WSL

###export via PS
powershell.exe -c 'Export-Certificate -Cert @(Get-ChildItem "cert:\LocalMachine" -recurse | Where-Object { $_.Subject -match "CN=my-cert-subject" })[0] -FilePath root-cert.cer -Type CERT'
### convert 
openssl x509 -inform der -in root-cert.cer -out root-cert.pem
bayaro commented 2 years ago

or just copy all ca certificates from windows to wsl https://github.com/bayaro/windows-certs-2-wsl

jtele2 commented 2 years ago

This is a shorter version of what @mrslezak posted -

Go to Manage User Certificates >  Trusted Root Certification Authorities > Certificates > Open the root CA you are interesed in
> Details > Copy To File > Base64 X.509

Copy that .cer file to /usr/local/share/ca-certificates in WSL2
Run 
sudo openssl x509 -inform PEM -in xxx.cer -out xxx.crt
sudo update-ca-certificates

Verify:
ls /etc/ssl/certs | grep xxx

What is the difference between running openssl x509 -inform PEM -in xxx.cer -out xxx.crt and just changing the filename from xxx.cer to xxx.crt ?

trallnag commented 2 years ago

For completeness here is my approach based on @bayaro. I simply wanted to get all certificates into a single file:

$certificateType = [System.Security.Cryptography.X509Certificates.X509Certificate2]

$includedStores = @("TrustedPublisher", "Root", "CA", "AuthRoot")

$certificates = $includedStores.ForEach({
    Get-ChildItem Cert:\CurrentUser\$_ | Where-Object { $_ -is $certificateType}
})

$pemCertificates = $certificates.ForEach({
    $pemCertificateContent = [System.Convert]::ToBase64String($_.RawData,1)
    "-----BEGIN CERTIFICATE-----`n${pemCertificateContent}`n-----END CERTIFICATE-----"
})

$uniquePemCertificates = $pemCertificates | select -Unique

return $uniquePemCertificates | Out-String

Note that if you want to write the file to a ca-certificates.pem you must replace the last line with something like this:

($uniquePemCertificates | Out-String).Replace("`r", "") | Out-File -Encoding UTF8 $HOME\ca-certificates.crt

I just encountered that Python can't deal with whatever way > PowerShell encodes output.

timotk commented 2 years ago

When you need to convert a bunch of exported CA certificates at once from .cer (Base-64 encoded X.509) to .crt, you can use:

for f in *.cer;
do sudo openssl x509 -inform PEM -in "${f}" -out "${f%.*}.crt";
done

This will:

  1. Loop over each file with the .cer file extension
  2. Convert the file to crt
  3. Replace the extension using "${f%.*}.crt"

I quoted the variables so spaces in filenames don't cause issues.

bsaranga commented 2 years ago

To get it to work with WSL I approced this way.

  1. I installed mkcert to windows with mkcert -install
  2. Then i installed it to WSL mkcert -install
  3. I went to directory where mkcert created CA filed for windows and copyed them to WSL location. So WSL now uses windows CA files.
  4. I runned mkcert -install again on WSL
  5. Created a certs from WSL and configurated them to apache/nginx. Works!

@alanaasmaa Thank You So much for this! 😊❤

ksmithRenweb commented 1 year ago

or just copy all ca certificates from windows to wsl https://github.com/bayaro/windows-certs-2-wsl

This is what solved it for me. All that stuff with mkcert didn't work in my case.

Lucasjuv commented 1 year ago

Only this worked for me:

For completeness here is my approach based on @bayaro. I simply wanted to get all certificates into a single file:

$certificateType = [System.Security.Cryptography.X509Certificates.X509Certificate2]

$includedStores = @("TrustedPublisher", "Root", "CA", "AuthRoot")

$certificates = $includedStores.ForEach({
    Get-ChildItem Cert:\CurrentUser\$_ | Where-Object { $_ -is $certificateType}
})

$pemCertificates = $certificates.ForEach({
    $pemCertificateContent = [System.Convert]::ToBase64String($_.RawData,1)
    "-----BEGIN CERTIFICATE-----`n${pemCertificateContent}`n-----END CERTIFICATE-----"
})

$uniquePemCertificates = $pemCertificates | select -Unique

return $uniquePemCertificates | Out-String

Note that if you want to write the file to a ca-certificates.pem you must replace the last line with something like this:

($uniquePemCertificates | Out-String).Replace("`r", "") | Out-File -Encoding UTF8 $HOME\ca-certificates.crt

I just encountered that Python can't deal with whatever way > PowerShell encodes output.

then use this on this tutorial https://pmichaels.net/2020/12/29/add-certificate-into-wsl/

carschandler commented 5 months ago

For those who arrived here because of an issue with a Git repository (i.e. company self-signed certificate on a Bitbucket repo), note that you can tell WSL Git to use the credential helper from Git on Windows using credential.helper=/mnt/c/path/to/git/mingw64/bin/git-credential-manager.exe in your (local or global) git config. See https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-git#git-credential-manager-setup for more details.

MatthewYaegerTR commented 1 week ago

or just copy all ca certificates from windows to wsl https://github.com/bayaro/windows-certs-2-wsl

this is what ended up fixing my issues. if, like me, you're not able to identify which root certificate is the source of your problem, just throw EVERYTHING into Ubuntu,

@bayaro, thanks for the PowerShell script!