Сценарии сломались после обновления LWP "сертификат не удался"
У меня много сценариев, большинство из которых основаны на WWW::Mechanize
которые очищают данные от разного оборудования, доступного через HTTP. После обновления большей части моей установки Perl и ее модулей все сценарии, использующие HTTPS:// сломались из-за "certificate verify failed"
Это является результатом того факта, что более новые версии LWP правильно проверяют сертификат и dies
если что-то не совпадает
В моем случае из-за обстоятельств ожидается сбой проверки подлинности сертификата, поэтому мне нужно было найти способ аккуратно обойти эту проверку.
5 ответов
Сначала я добавил свой код:
system("export PERL_LWP_SSL_VERIFY_HOSTNAME=0");
... но так как это неоптимально (так как это затрагивает в основном весь сеанс входа в систему).
Редактировать: Кроме того, экспорт таким образом ничего не делает, так как я исказил мою логику. Смотрите комментарии ниже.
Затем я изменил его, добавив код:
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
И после этого только сценарии, которые должны обойти проверку, делают это простым и понятным способом.
Скажи, что я хочу сказать тебе кое-что, и я не хочу, чтобы кто-то еще знал это. Мы договорились бы о пароле, и я бы использовал его для шифрования сообщения, а затем отправил бы вам сообщение.
Что если я не позабочусь о том, чтобы человеком, которому я дал пароль и зашифрованное сообщение, был ты? Тогда любое количество людей может просто выдать себя за вас, и шифрование будет напрасным. Это было состояние поддержки HTTPS LWP до недавнего времени.
Теперь LWP на самом деле проверяет, с кем он разговаривает, если вы не попросите LWP вести себя так, как когда-то. Вы можете сделать это используя:
my $ua = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 },
);
Если вы хотите повлиять на все экземпляры LWP::UserAgent в вашем скрипте, не указав опцию повсеместно, вы можете добавить следующее в ваш скрипт
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
Или вы можете запустить свой скрипт следующим образом:
PERL_LWP_SSL_VERIFY_HOSTNAME=0 script.pl
Наконец, если вы хотите, чтобы LWP всегда был небезопасным, вы можете добавить следующее в ваш скрипт входа в систему:
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
Однако я не рекомендую ничего из вышеперечисленного. Гораздо лучшим вариантом будет предоставить сертификат для хоста, с которым вы общаетесь. (Это эквивалентно добавлению исключения в Firefox, если вы знаете, что я имею в виду.) См. Документацию для $ua->ssl_opts
,
Для меня, используя:
my $ua = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 },
);
Поддавшись
Использование по умолчанию SSL_verify_mode SSL_VERIFY_NONE для клиента не рекомендуется! Пожалуйста, установите SSL_verify_mode на SSL_VERIFY_PEER вместе с SSL_ca_file|SSL_ca_path для проверки. Если вы действительно не хотите проверять сертификат и держать соединение открытым для атак типа "человек-посредник", пожалуйста, явно задайте для SSL_verify_mode значение SSL_VERIFY_NONE в вашем приложении.
Использование этого не дало никаких предупреждений:
my $ua = LWP::UserAgent->new(
ssl_opts => { SSL_verify_mode => 'SSL_VERIFY_NONE'},
);
@ikegami дает хороший аргумент, почему вы не хотите отключать проверку имени хоста SSL, но прямо не упоминает, как этого избежать.
Если вы говорите с общедоступной системой с сертификатом, подписанным CA, вам нужно указать LWP на коллекцию корневых сертификатов вашего дистрибутива. В системе на основе Debian (Ubuntu и т. Д.) Это хранится в /etc/ssl/certs/
,
BEGIN {
$ENV{HTTPS_CA_DIR} = '/etc/ssl/certs'
}
Если вы говорите со своим собственным сервером с самозаверяющим сертификатом, вы можете сохранить копию этого сертификата на клиенте и указать свой сценарий на этот конкретный файл.
BEGIN {
$ENV{HTTPS_CA_FILE} = '/path/to/my/server-certificate.crt'
}
Вместо этого вы можете установить их в среде перед запуском скрипта (например, экспортировать их из вашей оболочки) или применить параметры непосредственно к объекту UserAgent. См. Документацию LWP::UserAgent для более подробной информации; ищи ssl_opts
(примерно на полпути вниз по странице).
Добавьте библиотеку вверху и добавьте остальные объявления ENV и информацию о сокетах ввода-вывода перед использованием функций модуля LWP. Тогда попробуйте, это будет тренировка.
use IO::Socket::SSL;
use LWP::UserAgent;
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
$ENV{HTTPS_DEBUG} = 1;
IO::Socket::SSL::set_ctx_defaults(
SSL_verifycn_scheme => 'www',
SSL_verify_mode => 0,
);
$ua = LWP::UserAgent->new();