首先使用命令查看是否已安装所需要的模块
nginx -V
若没有找到需要的模块,则需要编译安装。但是宝塔面板中安装的 nginx 如果像自行安装的 nginx 一样的方式去编译可能会出问题。宝塔面板有自己的添加模块方式。
在宝塔面板的软件商店找到 nginx,如果已安装则需要先卸载,卸载不会删除已有网站的配置文件(保险起见可以先备份一下),且安装时原有的模块不需要重新填写。
选择编译安装,添加自定义选装模块:
以添加“--with-http_auth_request_module”模块为例,名称按格式填写即可,模块参数填写--with-http_auth_request_module
,如添加其它模块,按需填写前置脚本。添加完成后,启用它:
开始安装,等待完成。
要在 Alibaba Cloud Linux 3 上设置开机启动 ossftp,你可以通过创建一个系统服务来实现。以下是具体步骤:
安装 ossftp:
按照阿里云官方文档安装 ossftp。
创建服务文件:
首先,你需要创建一个服务文件。使用以下命令创建一个新的服务文件:
sudo nano /etc/systemd/system/ossftp.service
编辑服务文件:
在打开的编辑器中,添加以下内容:
[Unit]
Description=OSS FTP Service
After=network.target
[Service]
ExecStart=/bin/bash /root/ossftp-1.2.0-linux-mac/start.sh
Restart=always
User=root
[Install]
WantedBy=multi-user.target
这里的 ExecStart 指向你的 start.sh 脚本的路径。
保存并退出。
重新加载系统服务:
运行以下命令以重新加载系统服务,使新创建的服务生效:
sudo systemctl daemon-reload
启用服务开机启动:
使用以下命令启用服务,使其在系统启动时自动运行:
sudo systemctl enable ossftp.service
启动服务:
你可以立即启动服务以测试其是否正常工作:
sudo systemctl start ossftp.service
检查服务状态:
使用以下命令检查服务的状态,确保它正在运行:
sudo systemctl status ossftp.service
如果一切设置正确,ossftp 应该会在每次系统启动时自动运行。
如果在你的系统上没有安装 nano 编辑器,你可以使用其他文本编辑器,比如 vi 或 vim。
如果你需要安装 nano,可以使用以下命令:
sudo yum install nano
本文记录于 2024 年 11 月。
升级前 | 期望(最新正式版) | 最终选择 | |
操作系统 | Alibaba Cloud Linux 3 | Alibaba Cloud Linux 3 | Alibaba Cloud Linux 3 |
管理面板 | 宝塔面板 Linux 版 9.2.0 | 宝塔面板 Linux 版 9.2.0 | 宝塔面板 Linux 版 9.2.0 |
Web 服务 | nginx 1.24 | nginx 1.24 | nginx 1.24 |
脚本语言 | PHP 7.4 | PHP 8.2 | PHP 8.2 |
数据库 | PolarDB MySQL 5.6 | RDS MySQL 9.1 | PolarDB MySQL 8.0 |
论坛程序 | Discuz! X3.4 GBK | Discuz! X5.0 | Discuz! X3.5 UTF8 |
版本选择原因:
Discuz! X5 刚刚发布,生态尚未成熟,考虑到是老论坛升级,所以选择 X3.5。
Discuz! X3.5 目前最高支持 PHP 8.2、MySQL 8.0。
完整升级步骤:
购买新的 ECS、PolarDB,具体环境配置步骤参此文;
安装宝塔面板并配置;
安装 nginx 及 PHP;
创建网站、配置 SSL、伪静态、防盗链、可写目录禁执行、仅允许部分入口文件执行等(.conf);
配置 hosts;
如果是正式升级阶段,关闭论坛,防止产生新数据。
备份原网站程序、PolarDB 数据库;
PolarDB 创建快照。
测试阶段:从快照还原到新实例(MySQL 5.6 不能直接恢复到 MySQL 8.0),然后从 5.6 迁移到 8.0.x;
正式阶段:全量模式直接从原实例迁移到 8.0.x,若增量模式且存在触发器,建议从快照还原;
上传原网站程序到新的站点目录下;
按 Discuz! X 升级文档升级 X3.4 至 X3.5;详情见下文 ↓;
升级完成后切换到 PHP 8;
配置 OSS、Redis、更新缓存等;
测试论坛基本功能是否正常;检查附件是否能够正常上传;检查附件是否正常显示;全面检查控制台配置;
逐个开启插件并检查兼容性(短信通、马甲引擎等);
按二开备忘录逐个按需进行二开;
逐个修改调用论坛接口的项目及直接调用论坛数据库的项目;
调试 MAGAPP 接口;
尝试强制 https 访问;
将以上所有修改后的程序保留备份;发布升级公告并关闭论坛;重复以上步骤;修改域名解析;开启论坛;
配置 IP 封禁、定时器、日志、自动备份、配置其它 ECS 的 hosts 等;
查看搜索引擎中收录的地址,是否有无法访问的情况;
尝试将历史遗留的本地附件全部转移到 OSS;
建议 在新服上创建 3 个网站:
第 1 个用来尝试迁移、升级、二开,并测试所有功能;
第 2 个用来再次重复这些步骤,最终保留程序代码及 UGC 文件,作为最终的网站程序,以正式域名作为网站根目录路径;
第 3 个用来正式升级,主要功能是升级最新数据库。完成后修改第 2 个网站的数据库连接指向到最新的数据库,差异化同步新增的 UGC 文件到第 2 个网站。
Discuz! X 升级步骤及注意点:
因 PolarDB MySQL 不支持压缩,所以应移除 Discuz! 和 UCenter 代码中所有的 MYSQLI_CLIENT_COMPRESS,将 , MYSQLI_CLIENT_COMPRESS 替换为 /*, MYSQLI_CLIENT_COMPRESS*/。
升级前务必先修改 ./config/ 目录下的数据库/缓存连接信息,以防出现新站连接老库的情况;
按官方文档进行升级,升级前先修改一下:
【UC】先升级 UCenter 1.6 至 1.7。
将 /uc_server/data 权限改为 777 并递归。
打开 update_ucenter_adult.php 修改 $limit 值为 10000 以免执行超时。
因通信失败的“发送通知失败”可以直接改 URL 参数跳过就完成了,原因可能是因数据量大,发送改名通知执行改名时超时。等DZ升级完成后UC会自动重试改名通知,或单独写个 php 文件将 UCenter 的用户名同步到应用的数据库。
【DZ】运行到 /install/update_adult.php?step=innodb&table=pre_common_member_grouppm 时报错:Duplicate key name 'gpmid' ALTER TABLE common_member_grouppm ADD INDEX gpmid(gpmid);
解决方法:先删除索引,因保存时提示失败,应同时取消 gpmid 字段的自增,转换成功后再设置自增。
【DZ】运行到 /install/update_adult.php?step=file 一片空白而停止
正在解决
【问题】common_menber 表用户名字段编码转换失败
原因是部分用户名包含特殊字符(如全角空格),用以下语句查看两个表同一 uid 的不同用户:
SELECT u.uid, u.username AS ucenter_username, c.username AS common_username FROM pre_ucenter_members u JOIN pre_common_member c ON u.uid = c.uid WHERE u.username <> c.username
Discuz! 用户登录都是以 UCenter 中的用户名为主,所以可以写个小程序直接将 pre_ucenter_members 的用户名同步到 pre_common_member 中,另外 pre_ucenter_members 的用户数少于 pre_common_member 是正常的。若 pre_common_member_archive 表遇到错误同理。
如果用户登录慢,或打开 UCenter 慢,是因为 UC 正在通知 DZ 改用户名,每次打开一个页面会更改一个用户名,具体可以查看 pre_ucenter_notelist 中 closed 为 0 的队列,或进入 UC 后台-数据列表-通知列表 查看。
【问题】发布主题遇到错误:(1062) Duplicate entry '*' for key 'pid'
【原因】forum_post 中的 pid 不是自动增长的,而是由表 forum_post_tableid 中自动增长的 pid 生成的。如果生成的 pid 值已在 forum_post 表中存在,则会出现此错误。
【解决】迁移数据库时应关闭论坛,以防止 forum_post 表有新数据插入。
【问题】打开帖子页面 ./thread-***-1-1.html 显示 404 Not Found,而 ./forum.php?mod=viewthread&tid=*** 可以正常打开
【原因】未配置伪静态(可在宝塔面板中选择)
【问题】打开 UCenter 时报错:UCenter info: MySQL Query Error SQL:SELECT value FROM [Table]vars WHERE name='noteexists'
【解决】打开文件 ./uc_server/data/config.inc.php 配置数据库连接
【问题】打开登录 UCenter 后一片空白
【解决】将目录 ./uc_server/data/ 设为可写
需要将原来安装的插件文件移回 ./source/plugin/ 目录,并设置可写;
界面-表情管理,界面-编辑器设置-Discuz!代码
后续 Discuz! X3.5 小版本升级注意事项:
确认插件是否支持新版本(如短信通)
先创建一个新网站测试二开代码
保留 /config/、/data/、/uc_client/data/、/uc_server/data/、/source/plugin/,其它移入 old
上传文件
移回其它需要的文件,如:
-- 勋章/loading/logo/nv 等:/static/image/common/
-- 表情:/static/image/smiley/
-- 水印:/static/image/common/watermark.*
-- 风格:/template/default/style/t2/nv.png 等
-- 默认头像:/uc_server/images/noavatar_***.gif
-- 根目录 favicon.ico 等
-- 及其它非 DZ 文件
再次检查可写目录的写入权限和禁止运行 PHP 效果。
本文基于 manifest v3
插件使用 Web 技术开发
浏览器提供额外的插件 API
插件与网页分离,运行在一个独立的环境中
插件 API 功能
管理 Tabs、窗口、历史记录、书签、Cookies、下载、浏览数据、通知、网站权限
管理浏览器的外观和感觉 - 背景、主题、右键菜单、新标签页、启动页面
定制 DevTools
向网页注入脚本,与网页通信,与系统中的 Native 应用程序通信
修改/监听发送的 HTTP 请求/接收的回复
插件构成
结构 | 功能 | 调用 API | 操作 Dom | 进程 |
manifest | 配置文件 | - | ||
popup | 弹出对话框 | 所有 | Extension process | |
option page | 用户使用的设置页面 | 所有 | ||
background script | 后台脚本 | 所有 | 禁止? | Extension process |
content script | 内容脚本(注入到网页中) | 有限 | 允许 | Renderer process |
* 即便 content script 是注入到网页中的,而且是运行在 Renderer 进程(与主网页相同的进程),但是它们仍运行在不同的世界(world)。主网页运行在 main world,插件的 content script 运行在 isolated world。比如说 main world 中有一个变量,它在 isolated world 中是访问不到的,但是如果修改了 dom,对其它世界是有影响的。
将 Chrome 插件迁移到 Edge
移除 Chrome 独有的 API(如调用 Google 账户)
移动 update_URL 字段(如果是从 Chrome 商店直接下载的包会有这个字段)
改名 Chrome 相关的文字(插件名称、描述文字)
参考文献
SignalR 是一个开源的实时通信库,用于构建实时 Web 应用程序。它提供了一个简单的 API,可以在客户端和服务器之间建立持久连接,以便实时地推送数据。
与传统的 WebSocket 相比,SignalR 提供了更高级的功能和更简单的开发体验。下面是一些主要区别:
支持多种传输方式:SignalR 可以使用多种传输方式,包括 WebSocket、Server-Sent Events(SSE)、长轮询和 Forever Frame。这使得 SignalR 在不同的环境中都能提供实时通信的能力,即使某些浏览器不支持 WebSocket,也可以使用其他传输方式。
自动处理连接管理:SignalR 管理连接的生命周期,包括连接的建立、断开和重新连接。它会自动处理连接的失败和重新连接的逻辑,简化了开发人员的工作。
服务器端推送:SignalR 允许服务器端主动推送消息给客户端,而不需要客户端发起请求。这使得实时通信变得更加高效和实时,适用于聊天应用、实时监控等场景。
跨平台支持:SignalR 可以在多个平台上使用,包括 .NET、Java、JavaScript 等。这使得开发人员可以使用自己熟悉的语言和框架来构建实时应用程序。
微软官方提供了针对 ASP.NET Core Web 应用(Razor 页面)的详细教程,这里给出 MVC 版本入门教程。
最终将创建一个正常运行的聊天应用:
创建 Web 应用项目
添加 SignalR 客户端库
在“解决方案资源管理器”>中,右键单击项目,然后选择“添加”“客户端库”。
在“添加客户端库”对话框中:
“提供程序”选择“unpkg”
“库”,请输入 @microsoft/signalr@latest。
选择“选择特定文件”,展开“dist/browser”文件夹,然后选择 signalr.js 和 signalr.min.js。
点击“安装” 。
创建 SignalR Hubs 类
using Microsoft.AspNetCore.SignalR;
/// <summary>
/// Hub 类管理连接、组和消息
/// </summary>
public class ChatHub : Hub
{
/// <summary>
/// 可通过已连接客户端调用 SendMessage,以向所有客户端发送消息
/// </summary>
public async Task SendMessage(string user, string message)
{
// Clients.All 向所有的客户端发送消息
// ReceiveMessage 是客户端监听的方法
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
其父类 Hub 可管理连接、组和消息。这里演示的是向所有客户端发送消息。
配置 SignalR
打开 Program.cs,添加注入:
builder.Services.AddSignalR();
添加路由:
app.MapHub<ChatHub>("/chatHub");
添加 SignalR 客户端代码
视图页面:
<div class="container">
<div class="row p-1">
<div class="col-1">用户</div>
<div class="col-5"><input type="text" id="userInput" /></div>
</div>
<div class="row p-1">
<div class="col-1">消息</div>
<div class="col-5"><input type="text" class="w-100" id="messageInput" /></div>
</div>
<div class="row p-1">
<div class="col-6 text-end">
<input type="button" id="sendButton" value="发送消息" />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<hr />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
<script src="~/lib/microsoft/signalr/dist/browser/signalr.min.js"></script>
<script src="~/js/chat.js"></script>
chat.js 文件:
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
// 在连接建立之前禁用发送按钮
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
// 修改此处时应注意脚本注入问题
li.textContent = `${user} says ${message}`;
});
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
完成。在线示例:https://xoyozo.net/Demo/SignalRDemo
LigerShark.WebOptimizer.Core | BuildBundlerMinifier | |
特点 | 在运行时捆绑和缩小 CSS 和 JavaScript 文件 具有完整的服务器端和客户端缓存,以确保高性能 可禁用缩小 支持使用通配模式 标记帮助程序与缓存破坏 支持内联 支持 SCSS | 将 CSS、JavaScript 或 HTML 文件捆绑到单个输出文件中 保存源文件会自动触发重新捆绑 支持通配模式 支持 CI 方案的 MSBuild 支持 缩小单个或捆绑的 CSS、JavaScript 和 HTML 文件 每种语言的缩小选项是可定制的 打开生成的文件时显示水印 任务运行程序资源管理器集成 命令行支持 快捷更新解决方案中所有捆绑包 禁止生成输出文件 转换为 Gulp |
注入(Program.cs) | services.AddWebOptimizer(); app.UseWebOptimizer(); | |
指定捆绑的项目 | 在运行时自动缩小 css 和 js,也可以在 AddWebOptimizer 中自定义。默认情况下,生成的文件不会保存到磁盘,而是保存在缓存中。 | 手动编辑 bundleconfig.json 文件来指定需要合并和缩小的文件 |
功能配置 |
| 在 bundleconfig.json 捆绑时设置
|
热重载(在开发模式中保存文件自动更新浏览器效果) | VS 安装扩展,方法:菜单 - 扩展 - 管理扩展 - 联机 搜索“Bundler & Minifier” | |
其它资料 | ASP.NET 官方文档 |
中国蚁剑
https://github.com/AntSwordProject
https://github.com/AntSwordProject/AntSword-Loader
http://t.zoukankan.com/liang-chen-p-14181806.html
使用说明:
下载 AntSword-Loader 和 antSword 并解压;
打开 AntSword.exe,初始化时选择 antSword 目录;
右键“添加数据”,填 URL,选择连接类型,以 PHP 为例,服务器上放置一个 PHP 文件,格式如:
<?php @ev删除这七个汉字al($_POST['value']); ?>
那么,“连接密码”就填 POST 的参数名 value。
添加完成,双击可打开树状菜单,显示服务器上所有有权限的文件。
Burp:篡改请求(譬如上传图片时将文件名改为.php,并添加shell脚本)
https://portswigger.net/burp
使用方法:https://zhuanlan.zhihu.com/p/537053564
一句话木马:https://www.icode9.com/content-4-1081174.html
第一步,创建用户和 AccessKey
登录阿里云控制台后,从头像处进入 AccessKey 管理
“开始使用子用户 AccessKey”
点击“创建用户”,填写用户名(本文以 oss-bbs 为例),并勾选“Open API 调用访问”
点击确定创建成功,可以看到 AccessKey ID 和 AccessKey Secret
第二步,创建权限策略
在阿里云控制台左侧菜单“RAM 访问控制”中展开“权限管理”,选择“权限策略”
点击“创建权限策略”,切换到“脚本编辑”
输入以下策略文档(JSON 格式)
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:ListBuckets",
"oss:GetBucketStat",
"oss:GetBucketInfo",
"oss:GetBucketAcl"
],
"Resource": "acs:oss:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"oss:Get*",
"oss:Put*",
"oss:List*",
"oss:DeleteObject"
],
"Resource": "acs:oss:*:*:bbs"
},
{
"Effect": "Allow",
"Action": [
"oss:Get*",
"oss:Put*",
"oss:List*",
"oss:DeleteObject"
],
"Resource": "acs:oss:*:*:bbs/*"
}
]
}
脚本中第一段表示允许用户登录,第二段表示允许操作 Bucket,第三段表示允许操作 Bucket 内的文件对象。
示例中的 bbs 是 Bucket Name,请修改为自己的 Bucket 名称。
点击下一步,填写名称,确定即可。
第三步,添加用户权限
转到“用户”页面,在刚才创建的用户行“添加权限”
切换到“自定义策略”,将上一步创建的权限策略添加到右侧“已选择”区
确定。
相关信息:
You have no right to access this object because of bucket acl.
判断是否为数字
if isNumeric(id) then
else
response.End
end if
强制转换为数字
ii = clng(ii)
转义单引号
replace(xxx, "'", "\'")
判断一个字符串是否包含另一个字符串
if instr(str, "s")>0 then
response.Write(1)
else
response.Write(0)
end if
Linux 设置服务开机自动启动的方式有好多种,这里介绍一下通过 chkconfig 命令添加脚本为开机自动启动的方法。
编写脚本 ossftp(这里以开机启动 ossftp 服务为例),脚本内容如下:
#!/bin/sh #chkconfig: 2345 80 90 #description: 开机自动启动的脚本程序 # 开启 ossftp 服务 /root/ossftp-1.2.0-linux-mac/start.sh &
脚本第一行 “#!/bin/sh” 告诉系统使用的 shell;
脚本第二行 “#chkconfig: 2345 80 90” 表示在 2/3/4/5 运行级别启动,启动序号(S80),关闭序号(K90);
脚本第三行 表示的是服务的描述信息;
要执行的文件(示例中的 /root/ossftp-1.2.0-linux-mac/start.sh)必须设置“可执行”权限,命令结尾的“&”可使进程持续。
注意: 第二行和第三行必写,否则会出现如“服务 ossftp 不支持 chkconfig”这样的错误。
将写好的 ossftp 脚本移动到 /etc/rc.d/init.d/ 目录下
给脚本赋可执行权限
chmod +x /etc/rc.d/init.d/ossftp
添加脚本到开机自动启动项目中
chkconfig --add ossftp chkconfig ossftp on
执行命令“chkconfig --list”可列出开机启动的服务及当前的状态。
到这里就设置完成了,我们只需要重启一下我们的服务器,就能看到我们配置的 ossftp 服务已经可以开机自动启动了。