Skip to content

Commit

Permalink
完善CDN支持
Browse files Browse the repository at this point in the history
  • Loading branch information
guguan123 committed Oct 2, 2024
1 parent f3983c7 commit 8273e4f
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 34 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ DCMS 原是俄罗斯的社交网站和 CMS,后由 [eKing](https://github.com/e
- [x] 修复在 "书签" 页面无法翻页
- [ ] 将用户名与昵称区分,在个人主页可显示用户名(或仅限管理员可查看用户名)
- [ ] 纠正翻译和翻译部分残留的文本
- [ ] CDN 支持
- [x] CDN 支持
- [ ] 暗色模式
- [ ] 档案页报错
- [ ] "网站领袖" 新译名
- [ ] "书签分类" -> "日记" 翻页后无法显示标题
- [ ] "书签分类" -> "论坛" 出现数据库查询的 Warning 报错
- [x] 完善“是否允许游客访问《网站资料与帮助》页面”功能,优化 plugins/rules/index.php:13 与 plugins/rules/post.php:13 的代码实现方式
- [ ] 修复RSS订阅功能
- [ ] 修复更新页面
12 changes: 12 additions & 0 deletions adm_panel/settings_sys.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
if ($_POST['replace'] != 1) {}
$temp_set['main'] = esc(stripcslashes(htmlspecialchars(($_POST['main']))));
$temp_set['header'] = esc(stripcslashes(htmlspecialchars(($_POST['header']))));
$temp_set['get_ip_from_header'] = in_array($_POST['get_ip_from_header'], ['auto', 'disabled', 'X-Forwarded-For', 'X-Real-IP', 'CF-Connecting-IP', 'True-Client-IP']) ? $_POST['get_ip_from_header'] : 'auto';
if (save_settings($temp_set)) {
admin_log('设置', '系统', '更改系统设置');
msg('已成功接受设置');
Expand Down Expand Up @@ -103,6 +104,17 @@
</select>
<br />";

echo "从请求标头获取用户IP:<br />
<select name='get_ip_from_header'>
<option ".(setget('get_ip_from_header',"auto")=="auto"? " selected ":null)." value='auto'>自动识别</option>
<option ".(setget('get_ip_from_header',"disabled")=="disabled"? " selected ":null)." value='enable'>禁用</option>
<option ".(setget('get_ip_from_header',"X-Forwarded-For")=="X-Forwarded-For"? " selected ":null)." value='X-Forwarded-For'>X-Forwarded-For</option>
<option ".(setget('get_ip_from_header',"X-Real-IP")=="X-Real-IP"? " selected ":null)." value='X-Real-IP'>X-Real-IP</option>
<option ".(setget('get_ip_from_header',"CF-Connecting-IP")=="CF-Connecting-IP"? " selected ":null)." value='CF-Connecting-IP'>CF-Connecting-IP</option>
<option ".(setget('get_ip_from_header',"True-Client-IP")=="True-Client-IP"? " selected ":null)." value='True-Client-IP'>True-Client-IP</option>
</select>
<br />";

/*
echo " 通过文件夹安装插件 /Replace/:<br />
<select name='replace'>
Expand Down
15 changes: 15 additions & 0 deletions sys/dat/cloudflare-ips-v4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
7 changes: 7 additions & 0 deletions sys/dat/cloudflare-ips-v6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32
160 changes: 127 additions & 33 deletions sys/inc/ipua.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,136 @@
require_once __DIR__ . '/../../vendor/autoload.php';
use UAParser\Parser;

$ipa = false;
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']!='127.0.0.1' && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip2['xff'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$ipa[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
// 下载的 Cloudflare IP 文件路径
define('CLOUDFLARE_IPV4_FILE', __DIR__ . '/../dat/cloudflare-ips-v4.txt');
define('CLOUDFLARE_IPV6_FILE', __DIR__ . '/../dat/cloudflare-ips-v6.txt');
/**
* 从文件加载 Cloudflare IP 地址列表
* @param string $filePath
* @return array
*/
function loadCloudflareIps($filePath) {
if (!file_exists($filePath)) {
return [];
}

$ips = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
return array_filter($ips, function($ip) {
return filter_var($ip, FILTER_VALIDATE_IP) || strpos($ip, '/') !== false; // 处理IP段
});
}
if(isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']!='127.0.0.1' && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['HTTP_CLIENT_IP']))
{
$ip2['cl'] = $_SERVER['HTTP_CLIENT_IP'];
$ipa[] = $_SERVER['HTTP_CLIENT_IP'];

/**
* 检查 IP 是否属于 Cloudflare
* @param string $ip
* @param array $cloudflareIps
* @return bool
*/
function isCloudflareIp($ip, $cloudflareIps) {
foreach ($cloudflareIps as $cidr) {
if (cidr_match($ip, $cidr)) {
return true;
}
}
return false;
}
if(isset($_SERVER['REMOTE_ADDR']) && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['REMOTE_ADDR']))
{
$ip2['add'] = $_SERVER['REMOTE_ADDR'];
$ipa[] = $_SERVER['REMOTE_ADDR'];

/**
* 检查 IP 是否在 CIDR 范围内
* @param string $ip
* @param string $cidr
* @return bool
*/
function cidr_match($ip, $cidr) {
list($subnet, $mask) = explode('/', $cidr);
if ($mask === null) {
$mask = ($ip === $subnet) ? 32 : (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 128 : 32);
}

$ip_bin = inet_pton($ip);
$subnet_bin = inet_pton($subnet);
$mask_bin = str_repeat("f", intval($mask / 4)) . str_repeat("0", (128 - intval($mask)) / 4);
return ($ip_bin & hex2bin($mask_bin)) === ($subnet_bin & hex2bin($mask_bin));
}
$ip = $ipa[0];
$iplong = ip2long($ip);
function cleanUAString($ua) {
return preg_replace('#[^a-z_\. 0-9\-]#iu', "null", strtolower($ua));

$ipa = false;

// 根据不同选项获取IP
switch ($set['get_ip_from_header']) {
case 'X-Forwarded-For':
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]);
}
break;
case 'X-Real-IP':
if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
break;
case 'CF-Connecting-IP':
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
break;
case 'True-Client-IP':
if (!empty($_SERVER['HTTP_TRUE_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_TRUE_CLIENT_IP'];
}
break;
case 'disabled':
$ip = $_SERVER['REMOTE_ADDR'];
case 'auto':
default:
// 自动模式,尝试从多个标头获取
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']!='127.0.0.1' && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip2['xff'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$ipa[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if(isset($_SERVER['HTTP_X_REAL_IP']) && $_SERVER['HTTP_X_REAL_IP']!='127.0.0.1' && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['HTTP_X_REAL_IP'])) {
$ip2['xri'] = $_SERVER['HTTP_X_REAL_IP'];
$ipa[] = $_SERVER['HTTP_X_REAL_IP'];
}
/**
* 获取 Cloudflare 的 IP 列表并检查请求是否来自 Cloudflare。
* 如果是,则返回 Cloudflare 提供的真实用户 IP,否则返回请求者的 IP。
*/
if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && (isCloudflareIp($_SERVER['REMOTE_ADDR'], loadCloudflareIps(CLOUDFLARE_IPV4_FILE)) || isCloudflareIp($_SERVER['REMOTE_ADDR'], loadCloudflareIps(CLOUDFLARE_IPV6_FILE)))) {
$ip2['cf'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
$ipa[] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
if(isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']!='127.0.0.1' && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['HTTP_CLIENT_IP'])) {
$ip2['cl'] = $_SERVER['HTTP_CLIENT_IP'];
$ipa[] = $_SERVER['HTTP_CLIENT_IP'];
}
if(isset($_SERVER['REMOTE_ADDR']) && preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#",$_SERVER['REMOTE_ADDR'])) {
$ip2['add'] = $_SERVER['REMOTE_ADDR'];
$ipa[] = $_SERVER['REMOTE_ADDR'];
}
$ip = $ipa[0];
break;
}

$iplong = ip2long($ip);

if (isset($_SERVER['HTTP_USER_AGENT'])) {
$ua = $_SERVER['HTTP_USER_AGENT'];
// 使用 uap-php 库解析 User-Agent
$parser = Parser::create();
$result = $parser->parse($ua);
$browser_name = $result->ua->family ?? '未知'; // 修正对象访问
$browser_version = $result->ua->major ?? '0';
// 特殊处理 Opera Mini 手机型号
if (isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']) && stripos($ua, 'Opera') !== false) {
$ua_om = cleanUAString($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']);
$browser_name = 'Opera Mini (' . $ua_om . ')';
}
// 构造最终的 User-Agent 字符串
$ua = "{$browser_name} v{$browser_version}";
$ua = $_SERVER['HTTP_USER_AGENT'];
// 使用 uap-php 库解析 User-Agent
$parser = Parser::create();
$result = $parser->parse($ua);
$browser_name = $result->ua->family ?? '未知'; // 修正对象访问
$browser_version = $result->ua->major;
// 特殊处理 Opera Mini 手机型号
if (isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']) && stripos($ua, 'Opera') !== false) {
$ua_om = preg_replace('#[^a-z_\. 0-9\-]#iu', "null", strtolower($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']));
$browser_name = 'Opera Mini (' . $ua_om . ')';
}
// 构造最终的 User-Agent 字符串
if ($browser_version == null) {
// 如果解析不到浏览器版本就不合并版本号
$ua = $browser_name;
} else {
$ua = "{$browser_name} v{$browser_version}";
}
} else {
$ua = '没有可用的数据';
}
?>
$ua = 'N/A';
}

0 comments on commit 8273e4f

Please sign in to comment.