- Вопрос или проблема
- Добавьте pem файлы в центр сертификации
- Укажите curl на новые pem файлы
- Ответ или решение
- Шаг 1: Установка необходимых пакетов
- Шаг 2: Обновление сертификатов
- Шаг 3: Перенос сертификатов с Windows
- Шаг 4: Перемещение сертификатов в WSL
- Шаг 5: Создание символических ссылок для сертификатов
- Шаг 6: Настройка curl (опционально)
- Заключение
Вопрос или проблема
При выполнении следующей команды в WSL:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh
Я получаю следующую ошибку:
curl: (60) Проблема с SSL-сертификатом: не удалось получить локальный сертификат-источник
Более подробная информация здесь: https://curl.haxx.se/docs/sslcerts.html
curl не смог подтвердить законность сервера и, следовательно, не смог
установить с ним защищенное соединение. Чтобы узнать больше об этой ситуации и
о том, как это исправить, пожалуйста, посетите веб-страницу, указанную выше.
Эта команда раньше выполнялась успешно, но сейчас нет. Это решение не работает, ни одна комбинация sudo apt update
, sudo apt install ca-certificates --reinstall
или sudo update-ca-certificates --fresh
не помогает. Я перепробовал множество решений в интернете, и ни одно из них не сработало. Я пытался переустановить Ubuntu и даже установить другую версию Ubuntu, ни одно из них не сработало. Я не знаю, что пробовать дальше.
curl -k https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh
Опция -k
(также известная как --insecure
) пропустит проверку TLS-сертификата.
Нашел решение! У меня нет полного понимания проблемы, но я думаю, что дело в том, что корпоративная IT-служба установила некоторые сертификаты на мой компьютер с Windows, которые не были автоматически перенесены в WSL. В любом случае, проблему можно легко исправить с помощью этого скрипта PowerShell:
$StoreToDir = "all-certificates"
$CertExtension = "pem" # используйте "crt" для работы в системах Windows
$InsertLineBreaks=1
If (Test-Path $StoreToDir) {
$path = "{0}\*" -f $StoreToDir
Remove-Item $StoreToDir -Recurse -Force
}
New-Item $StoreToDir -ItemType directory
# Если вы хотите фильтровать по назначению сертификата (например, для языков, не зависящих от соответствия, предоставления сертификатов аутентификации сервера: "(1.3.6.1.5.5.7.3.1)"), просто добавьте:
# -and -not $_.Archived -and ( $_.EnhancedKeyUsageList -match '(1.3.6.1.5.5.7.3.1)' -or -not $_.EnhancedKeyUsageList )
Get-ChildItem -Recurse cert: `
| Where-Object { $_ -is [System.Security.Cryptography.X509Certificates.X509Certificate2] -and $_.NotAfter.Date -gt (Get-Date).Date } `
| ForEach-Object {
# Запись информации о сертификате (например, для CSV, содержащего метаданные); Журнал информации с полными именами и дополнительными значениями для справки
Write-Output "$($_.Thumbprint);$($_.GetSerialNumberString());$($_.Archived);$($_.GetExpirationDateString());$($_.EnhancedKeyUsageList);$($_.GetName())"
# Добавление "Thumbprint" сертификата для уникальных имен файлов
$name = "$($_.Thumbprint)--$($_.Subject)" -replace '[\W]', '_'
$max = $name.Length
# Уменьшаем длину, чтобы избежать ошибок файловой системы
if ($max -gt 150) { $max = 150 }
$name = $name.Substring(0, $max)
# Формируем путь
$path = "{0}\{1}.{2}" -f $StoreToDir,$name,$CertExtension
if (Test-Path $path) { continue } # продолжаем, если сертификат уже был записан
$oPem=new-object System.Text.StringBuilder
[void]$oPem.AppendLine("-----BEGIN CERTIFICATE-----")
[void]$oPem.AppendLine([System.Convert]::ToBase64String($_.RawData,$InsertLineBreaks))
[void]$oPem.AppendLine("-----END CERTIFICATE-----")
$oPem.toString() | add-content $path
}
У меня была эта проблема с gcloud
и curl
. Для меня ответ jhud в основном исправил gcloud
, но мне пришлось выполнить несколько дополнительных шагов. Чтобы заставить curl
работать, мне нужно было сделать еще пару шагов после этого.
Добавьте pem файлы в центр сертификации
- Создайте резервную копию существующих сертификатов в
/etc/ssl/certs
. - Переместите pem файлы, сгенерированные скриптом jhud, в
/etc/ssl/certs
(или, скорее, сделайте/etc/ssl/certs
мягкой ссылкой на каталог, где находились pem файлы). - Обновите сертификаты.
- На Redhat:
update-ca-trust
- На других дистрибутивах:
update-ca-certificates
или, возможно, что-то другое.
- На Redhat:
Хотя это исправило gcloud
, это не исправило curl
. Чтобы заставить curl
работать, я выполнил еще несколько шагов.
Укажите curl на новые pem файлы
-
Создайте мягкие ссылки на каждый из pem файлов с именами:
<hash>.0
в соответствии с ответом на stackoverflow.Пример:
for pem in $pem_dir/*.pem do ln -s "$pem" "$pem_dir/$(openssl x509 -hash -noout -in "$pem").0" done
-
Укажите curl на эти мягкие ссылки, используя аргумент
--capath <pem_dir>
.
Примечание: Чтобы вам не пришлось каждый раз вводить --capath <pem_dir>
при запуске curl
, вы можете добавить его в ваш .curlrc:
capath = <pem_dir>
Ответ или решение
Проблема с SSL-сертификатами при использовании curl
в WSL (Windows Subsystem for Linux) может быть связана с отсутствием необходимых сертификатов в хранилище. Давайте разберем шаги, которые помогут решить эту проблему.
Шаг 1: Установка необходимых пакетов
Прежде всего, убедитесь, что у вас установлены пакеты ca-certificates
и curl
. Выполните команды:
sudo apt update
sudo apt install ca-certificates curl
Шаг 2: Обновление сертификатов
После установки или переустановки пакета ca-certificates
выполните обновление сертификатов:
sudo update-ca-certificates
Шаг 3: Перенос сертификатов с Windows
Если ваша проблема сохраняется, возможно, это связано с тем, что корпоративные сертификаты, установленные на Windows, не видны в WSL. В этом случае можно использовать PowerShell скрипт для переноса сертификатов. Вот как это сделать:
- Откройте PowerShell от имени администратора и выполните следующий скрипт:
$StoreToDir = "all-certificates"
$CertExtension = "pem"
$InsertLineBreaks=1
If (Test-Path $StoreToDir) {
$path = "{0}\*" -f $StoreToDir
Remove-Item $StoreToDir -Recurse -Force
}
New-Item $StoreToDir -ItemType directory
Get-ChildItem -Recurse cert: | Where-Object { $_ -is [System.Security.Cryptography.X509Certificates.X509Certificate2] -and $_.NotAfter.Date -gt (Get-Date).Date } | ForEach-Object {
$name = "$($_.Thumbprint)--$($_.Subject)" -replace '[\W]', '_'
$max = $name.Length
if ($max -gt 150) { $max = 150 }
$name = $name.Substring(0, $max)
$path = "{0}\{1}.{2}" -f $StoreToDir,$name,$CertExtension
if (Test-Path $path) { continue }
$oPem=new-object System.Text.StringBuilder
[void]$oPem.AppendLine("-----BEGIN CERTIFICATE-----")
[void]$oPem.AppendLine([System.Convert]::ToBase64String($_.RawData,$InsertLineBreaks))
[void]$oPem.AppendLine("-----END CERTIFICATE-----")
$oPem.toString() | add-content $path
}
Этот скрипт создаст папку all-certificates
и сохранит в ней все сертификаты в формате pem
.
Шаг 4: Перемещение сертификатов в WSL
Теперь необходимо перенести сгенерированные файлы pem
в директорию /etc/ssl/certs
вашей системы WSL:
-
Перенесите файлы
pem
изall-certificates
в/etc/ssl/certs
.sudo cp /path/to/all-certificates/*.pem /etc/ssl/certs/
-
После этого обновите сертификаты снова:
sudo update-ca-certificates
Шаг 5: Создание символических ссылок для сертификатов
Для правильной работы curl
, возможно, потребуется создать символические ссылки на новые сертификаты. Выполните следующие команды:
pem_dir="/etc/ssl/certs"
for pem in $pem_dir/*.pem; do
ln -s "$pem" "$pem_dir/$(openssl x509 -hash -noout -in "$pem").0"
done
Шаг 6: Настройка curl
(опционально)
Чтобы не указывать --capath
при каждом вызове curl
, добавьте следующую строку в файл ~/.curlrc
:
capath = /etc/ssl/certs
Заключение
После выполненных шагов проблема с SSL-сертификатами должна быть решена, и команда curl
должна работать корректно. Если же проблема все еще сохраняется, рассмотрите возможность использования флага -k
(т.е. --insecure
), но это не рекомендуется для продакшн-среды, так как оно отключает проверку сертификатов безопасности.