在用whmcs + Proxmox VE VPS For WHMCS插件,一直没找到什么向用户展示NAT端口信息的好的方法,目前大部分人在用的都是源自论坛Twilight佬的单独页面端口计算的方法,不是很方便,需要用户自行计算;同时到看有分享经验的小伙伴提到利用添加hook文件的方式在whmcs前端页面显示当前账户余额功能的代码,于是让ai简单的尝试写了一下,发现可行,于是分享出来。
具体效果:
如何实现:
将下面的代码保存在/includes/hooks/portmap.php即可。
这里查找页面私网IP网段为172.16.x.x的格式,ssh的端口范围从19000开始计算,NAT分配端口从20000开始每隔20为一组,可以根具自己的需求更改,iptable的端口转发大家应该都很熟练,这里不涉及配置方法。
<?phpuse WHMCS\Database\Capsule;if (!defined("WHMCS")) { die("This file cannot be accessed directly");}add_hook('ClientAreaProductDetailsOutput', 1, function($vars) { // 限定仅主产品详情页 if ( (isset($_GET['modop']) && $_GET['modop'] !== '') || (isset($_GET['a']) && $_GET['a'] !== '') || (isset($_GET['mg-page']) && $_GET['mg-page'] !== '') || (isset($_GET['action']) && $_GET['action'] !== 'productdetails') ) { return ''; } $service = $vars['service'] ?? []; // 找所有可能的 IP $candidates = []; if (!empty($service['dedicatedip'])) $candidates[] = $service['dedicatedip']; if (!empty($service['assignedips'])) { foreach (preg_split('/[\r\n,;]+/', $service['assignedips']) as $ip) { if (trim($ip)) $candidates[] = trim($ip); } } if (!empty($service['customfields'])) { foreach ($service['customfields'] as $cf) { if (!empty($cf['value'])) $candidates[] = $cf['value']; } } // 找私网 172.16.N.X $privateIp = null; $N = $X = 0; foreach ($candidates as $c) { if (preg_match('/^172\.16\.(\d{1,3})\.(\d{1,3})$/', $c, $m)) { $N = intval($m[1]); $X = intval($m[2]); if ($N >= 1 && $N <= 255 && $X >= 10 && $X <= 255) { $privateIp = $c; break; } } } if (!$privateIp) return ''; // NAT 端口 $ssh_port = 19000 + ($X - 10); $start_port = 20000 + ($X - 10) * 20; $end_port = $start_port + 19; // HTML $html = <<<HTML<style>.nat-item { cursor:pointer; font-weight:bold; padding:2px 4px; border-radius:4px;}.nat-ip { color:#1a73e8; }.nat-port { color:#d93025; }.copy-tip { display:none; margin-left:6px; color:green; font-size:12px;}</style><script>function natCopy(val, tipId){ navigator.clipboard.writeText(val).then(()=>{ var tip = document.getElementById(tipId); tip.style.display = "inline"; setTimeout(()=>{ tip.style.display="none"; }, 1200); });}</script><div class="panel panel-default" style="margin-top:20px;"> <div class="panel-heading"><strong>NAT 端口信息</strong></div> <div class="panel-body"> <!-- 公网 IP --> <p id="nat-public-ip-row" style="display:none;"> <strong>公网 IP:</strong> <span class="nat-item nat-ip" id="nat-public-ip" onclick="natCopy(this.textContent,'tip-public-ip')" ></span> <span class="copy-tip" id="tip-public-ip">已复制</span> </p> <!-- SSH --> <p> <strong>SSH 端口:</strong> <span class="nat-item nat-port" id="nat-ssh" onclick="natCopy(this.textContent,'tip-ssh')" >{$ssh_port}</span> <span class="copy-tip" id="tip-ssh">已复制</span> </p> <!-- NAT 范围 --> <p> <strong>NAT 端口:</strong> <span class="nat-item nat-ip" onclick="natCopy('{$start_port}','tip-range')" >{$start_port}</span> - <span class="nat-item nat-ip" onclick="natCopy('{$end_port}','tip-range')" >{$end_port}</span> <span class="copy-tip" id="tip-range">已复制</span> </p> </div></div><!-- 解析 NAT 公网 IP --><script>(function(){ function fill() { try { document.querySelectorAll(".list-info-title").forEach(function(el){ var txt = el.textContent.trim(); var m = txt.match(/NAT公网IP[::]\\s*(\\d{1,3}(?:\\.\\d{1,3}){3})/); if (m && m[1]) { document.getElementById("nat-public-ip").textContent = m[1]; document.getElementById("nat-public-ip-row").style.display = "block"; } }); } catch(e){} } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", fill); } else { fill(); }})();</script>HTML; return $html;});在产品的配置页增加一个自定义字段如下图,x.x.x.x改为NAT的IP即可,勾选项都不选即可。
这里只测试了Proxmox VE VPS For WHMCS的插件,其他的没测试,实现方法就是从产品详情页面抓取IP计算端口,可自行修改代码尝试。
参考:
https://virt.spiritlhl.net/guide/pve/pve_install.html
https://www.nodeseek.com/post-12946-1
https://openssw.com/view/我要当oneman.md
评论 (0)