php内核 内核网络请求底层限制与安全管控
PHP 内核层网络请求安全最佳方式是“默认全拒绝按白名单放行”并且在4层一起做内核/扩展拦截 PHP 配置 业务 SDK forshortcuts 系统防火墙。───────────────────────────────────────────────────────────────────────────────────────────────────────── 下面我给你一套“能落地”的完整方案大白话 代码模板。 --- 先看风险入口你要管住这些 -curl发 HTTP/HTTPS - file_get_contents(http://...)这类 stream wrapper - socket 直连fsockopen, stream_socket_client - 扩展偷偷出网redis、amqp、grpc、第三方 SDK --- 最佳架构生产推荐1. 第1层最硬自定义 PHP 扩展在网络函数入口做白名单校验2. 第2层最省事php.ini 关掉高风险默认能力3. 第3层最好维护业务统一走“安全 HTTP 客户端”4. 第4层兜底iptables/nftables 只允许指定 IP:Port 出网 --- 一、php.ini 基线先收口;关掉 URL 文件包装器防 file_get_contents 远程拉取 allow_url_fopenOff allow_url_includeOff;隐藏版本信息 expose_phpOff;可选禁用直接 socket按业务决定 disable_functionsfsockopen,pfsockopen,stream_socket_client,stream_socket_server;错误日志 display_errorsOff log_errorsOn --- 二、业务统一安全客户端完整 PHP 代码 文件SafeHttpClient.php?php declare(strict_types1);final class SafeHttpClient{private array$allowHosts;private array$allowPorts;private int$connectTimeout;private int$totalTimeout;publicfunction__construct(array$allowHosts, array$allowPorts[80,443], int$connectTimeout3, int$totalTimeout10){$this-allowHostsarray_map(strtolower,$allowHosts);$this-allowPorts$allowPorts;$this-connectTimeout$connectTimeout;$this-totalTimeout$totalTimeout;}publicfunctionget(string$url, array$headers[]): array{$parsed$this-validateUrl($url);$chcurl_init();curl_setopt_array($ch,[CURLOPT_URL$url, CURLOPT_RETURNTRANSFERtrue, CURLOPT_FOLLOWLOCATIONfalse, // 禁止自动跳转防跳白名单外 CURLOPT_MAXREDIRS0, CURLOPT_CONNECTTIMEOUT$this-connectTimeout, CURLOPT_TIMEOUT$this-totalTimeout, CURLOPT_PROTOCOLSCURLPROTO_HTTP|CURLPROTO_HTTPS, CURLOPT_REDIR_PROTOCOLSCURLPROTO_HTTP|CURLPROTO_HTTPS, CURLOPT_SSL_VERIFYPEERtrue, CURLOPT_SSL_VERIFYHOST2, CURLOPT_HTTPHEADER$headers,]);$bodycurl_exec($ch);$errnocurl_errno($ch);$errorcurl_error($ch);$code(int)curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);if($errno!0){throw new RuntimeException(HTTP request failed: {$error});}return[host$parsed[host],status$code,body(string)$body,];}privatefunctionvalidateUrl(string$url): array{$pparse_url($url);if(!is_array($p)||empty($p[scheme])||empty($p[host])){throw new InvalidArgumentException(Invalid URL);}$schemestrtolower($p[scheme]);$hoststrtolower($p[host]);$portisset($p[port])?(int)$p[port]:($schemehttps?443:80);if(!in_array($scheme,[http,https],true)){throw new RuntimeException(Blocked scheme: {$scheme});}if(!in_array($host,$this-allowHosts,true)){throw new RuntimeException(Blocked host: {$host});}if(!in_array($port,$this-allowPorts,true)){throw new RuntimeException(Blocked port: {$port});}// 防 SSRF阻止内网/回环 IP域名解析后校验$ipsgethostbynamel($host)?:[];foreach($ipsas$ip){if($this-isPrivateOrLoopbackIp($ip)){throw new RuntimeException(Blocked private/loopback target: {$ip});}}return[scheme$scheme,host$host,port$port];}privatefunctionisPrivateOrLoopbackIp(string$ip): bool{if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){returntrue;}$longip2long($ip);if($longfalse)returntrue;$ranges[[0.0.0.0,0.255.255.255],[10.0.0.0,10.255.255.255],[127.0.0.0,127.255.255.255],[169.254.0.0,169.254.255.255],[172.16.0.0,172.31.255.255],[192.168.0.0,192.168.255.255],];foreach($rangesas[$start,$end]){if($longip2long($start)$longip2long($end)){returntrue;}}returnfalse;}}使用示例?php requireSafeHttpClient.php;$clientnew SafeHttpClient(allowHosts:[api.example.com,auth.example.com], allowPorts:[443]);$result$client-get(https://api.example.com/v1/ping);echo$result[status].PHP_EOL;--- 三、内核/扩展层拦截C 扩展模板 你要“底层管控”这个才是关键。思路是 hook 执行过程拦截高风险网络函数调用curl_exec, fsockopen, stream_socket_client 等。 文件php_netguard.c简化模板#ifdef HAVE_CONFIG_H#include config.h#endif#include php.h#include zend_extensions.h#include ext/standard/info.hstatic zend_execute_ex_hook_t old_execute_exNULL;static int netguard_enabled1;static int is_blocked_function(const zend_string *fname){if(!fname)return0;const char *deny[]{fsockopen,pfsockopen,stream_socket_client,stream_socket_server,curl_exec, NULL};for(int i0;deny[i]!NULL;i){if(zend_string_equals_literal_ci(fname, deny[i])){return1;}}return0;}static void netguard_execute_ex(zend_execute_data *execute_data){if(netguard_enabledexecute_dataexecute_data-func){zend_function *funcexecute_data-func;if(func-common.function_nameis_blocked_function(func-common.function_name)){zend_throw_error(NULL,netguard blocked function: %s, ZSTR_VAL(func-common.function_name));return;}}old_execute_ex(execute_data);}PHP_INI_BEGIN()STD_PHP_INI_BOOLEAN(netguard.enabled,1, PHP_INI_SYSTEM, OnUpdateBool, netguard_enabled, zend_netguard_globals, netguard_globals)PHP_INI_END()PHP_MINIT_FUNCTION(netguard){REGISTER_INI_ENTRIES();old_execute_exzend_execute_ex;zend_execute_exnetguard_execute_ex;returnSUCCESS;}PHP_MSHUTDOWN_FUNCTION(netguard){zend_execute_exold_execute_ex;UNREGISTER_INI_ENTRIES();returnSUCCESS;}PHP_MINFO_FUNCTION(netguard){php_info_print_table_start();php_info_print_table_header(2,netguard support,enabled);php_info_print_table_end();}zend_module_entry netguard_module_entry{STANDARD_MODULE_HEADER,netguard, NULL, PHP_MINIT(netguard), PHP_MSHUTDOWN(netguard), NULL, NULL, PHP_MINFO(netguard),0.1.0, STANDARD_MODULE_PROPERTIES};#ifdef COMPILE_DL_NETGUARDZEND_GET_MODULE(netguard)#endifconfig.m4 PHP_ARG_ENABLE(netguard, whether toenablenetguard extension,[--enable-netguard Enable netguard extension], no)iftest$PHP_NETGUARD!no;thenPHP_NEW_EXTENSION(netguard, php_netguard.c,$ext_shared)fi编译安装 phpize ./configure --enable-netguardmake-j$(nproc)makeinstallphp.iniextensionnetguard.sonetguard.enabled1--- 四、系统层兜底必须做 示例只允许访问固定出口 IP# 默认拒绝出站iptables-POUTPUT DROP# 放行 DNS 到内网DNSiptables-AOUTPUT-pudp--dport53-d10.0.0.53-jACCEPT# 放行到指定 APIiptables-AOUTPUT-ptcp-d203.0.113.10--dport443-jACCEPT# 放行本机必要通信iptables-AOUTPUT-olo-jACCEPT --- 五、最佳上线方式避免误伤1. 先审计模式只记录不拦3-7 天2. 统计真实目标域名/IP/端口3. 生成白名单4. 切阻断模式5. 告警监控拦截日志来源文件、函数、目标地址 --- 最终落地一句话 “内核拦截负责硬限制业务 SDK 负责可维护系统防火墙负责兜底”三层同开PHP 网络请求安全才真正稳。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2563980.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!