博客 (42)

  • location 优先于 access_by_lua_block,即使 access_by_lua_block 放在 http 中。

  • location 的 3 种匹配的优先级,精确匹配(=) > 正则匹配(~) > 前缀匹配(无符号,直接是“/”开头的 uri 前缀)。

  • 相同匹配类型的多个 location(比如有多个正则匹配),按定义顺序来进行匹配。

  • 一旦有一个 location 被匹配到,就不再继续匹配其它 location。

  • 如果使用 access_by_lua_block 鉴权,那么不要放在任何 location 中,这样,匹配完 location 后只要没有命中直接返回语句,就会继续执行 access_by_lua_block。并且,如果 access_by_lua_block 中鉴权拒绝,后续的业务处理(如 php 业务)不会继续进行。


xoyozo 2 天前
34

鉴权方式有许多,譬如可以用 lua 的 access_by_lua 来实现,这里用 nginx 自带的 auth_request,虽然功能简单,但效率更高。

第一步,确保 nginx 已编译安装 auth_request 模块,见此文

第二步,打开需要鉴权的网站的 nginx 配置文件,添加以下代码块:

    #鉴权-START
    location / {
        auth_request /auth;
        error_page 403 = @error403;
        
        #PHP-INFO-START  PHP引用配置,可以注释或修改
        include enable-php-**.conf;
        #PHP-INFO-END
    }
    location = /auth {
        internal;
        proxy_pass https://鉴权地址;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Uri $request_uri;
        proxy_intercept_errors on;
        #proxy_read_timeout 1s; # 超时会报 500
    }
    location @error403 {
        #default_type text/plain;
        #return 403 'forbidden';
        return 302 https://一个显示403友好信息的页面.html;
    }
    #鉴权-END

一般放在所有的 location 之前。

这里自定义请求头 X-Forwarded-HostX-Forwarded-Uri 用来传递 host 与 uri。API 应从 Header 中相应取值。

宝塔面板中是通过 include enable-php-**.conf; 的方式调用 PHP ,那么可以将此行移入上面的 location / 代码块中,因为此代码块能匹配所有的请求路径。

最后,若鉴权接口在私网中,将鉴权接口域名和私网 IP 添加到 hosts 文件中。

xoyozo 10 天前
112
  1. 登录 UCenter,添加应用

    image.png

    选择 DiscuzX,并填写名称和密钥等信息

  2. 正常的话,提交后会自动更新缓存文件 /uc_server/data/cache/apps.php,如果没有更新,检查添加这个文件的写入权限,并在后台更新缓存。

  3. 在编辑应用界面底部可以看到“应用的 UCenter 配置信息”

    image.png

  4. 复制这段内容,粘贴到 /config/config_ucenter.php。

  5. 在 Discuz! 控制面板 - 站长 - UCenter 设置 中可以看到这些配置信息。标签名为灰色的是从配置文件读取的,无法在此修改。

  6. 返回 UCenter 中心的应用列表可以看到“通信成功”

    image.png

xoyozo 1 个月前
212

今天早上同事反映论坛某管理账号无法登录,于是我尝试用创始人账号登录,也不行,第一反应就是中招了。

于是进阿里云控制台,发现云安全中心有许多安全警告,类型是网站后门,幸好 nginx 中设置了仅部分文件可执行 PHP,这些后门文件无法被执行。

尝试在 config_global_default.php 文件中添加创始人,但账号必须是副站长等管理账号才能成为创始人。

于是借用一个小号,从表 pre_ucenter_members 中将这个小号的 password 和 salt 复制到创始人账号中,这样创始人账号就可以用这个小号的密码登录了。

进入论坛后台,在 工具-运行记录-系统记录-后台访问 中查看入侵时间段的记录(操作、时间、IP 等),可搜索。

发现基本上在操作模板管理和专题管理。

对比时间,发现进入后台操作在先,上传后门在后。

查询 web 访问日志,通过访问文件路径或 IP 查询,在进入论坛后台之间,他进入了 UCenter 的后台,但是再往前就没有记录了。

因此基本可以确定:

黑客从 UCenter 修改了某管理员账号的密码(可能是利用漏洞),然后登录论坛后台修改了创始人的密码(可能也是用 UCenter 改的),通过模板管理和专题管理功能的上传功能上传了后门文件。

索性他没有对数据进行破坏性处理,也没有挂马,只是发现后门文件无法执行就放弃了。

xoyozo 2 个月前
225

本文记录于 2024 年 11 月。



升级前期望(最新正式版)最终选择
操作系统Alibaba Cloud Linux 3Alibaba Cloud Linux 3Alibaba Cloud Linux 3
管理面板宝塔面板 Linux 版 9.2.0宝塔面板 Linux 版 9.2.0宝塔面板 Linux 版 9.2.0
Web 服务nginx 1.24nginx 1.24nginx 1.24
脚本语言PHP 7.4PHP 8.2PHP 8.2
数据库
PolarDB MySQL 5.6RDS MySQL 9.1PolarDB MySQL 8.0
论坛程序
Discuz! X3.4 GBKDiscuz! X5.0Discuz! X3.5 UTF8


版本选择原因:

  • Discuz! X5 刚刚发布,生态尚未成熟,考虑到是老论坛升级,所以选择 X3.5。

  • Discuz! X3.5 目前最高支持 PHP 8.2、MySQL 8.0。


完整升级步骤:

  1. 购买新的 ECS、PolarDB,具体环境配置步骤参此文

  2. 安装宝塔面板并配置;

  3. 安装 nginx 及 PHP;

  4. 创建网站、配置 SSL、伪静态、防盗链、可写目录禁执行仅允许部分入口文件执行等(.conf);

  5. 配置 hosts;

  6. 如果是正式升级阶段,关闭论坛,防止产生新数据。

  7. 备份原网站程序、PolarDB 数据库;

  8. PolarDB 创建快照。

    测试阶段:从快照还原到新实例(MySQL 5.6 不能直接恢复到 MySQL 8.0),然后从 5.6 迁移到 8.0.x;

    正式阶段:全量模式直接从原实例迁移到 8.0.x,若增量模式且存在触发器,建议从快照还原;

  9. 上传原网站程序到新的站点目录下;

  10. 按 Discuz! X 升级文档升级 X3.4 至 X3.5;详情见下文 ↓;

  11. 升级完成后切换到 PHP 8;

  12. 配置 OSS、Redis、更新缓存等;

  13. 测试论坛基本功能是否正常;检查附件是否能够正常上传检查附件是否正常显示;全面检查控制台配置;

  14. 逐个开启插件并检查兼容性(短信通、马甲引擎等);

  15. 按二开备忘录逐个按需进行二开;

  16. 逐个修改调用论坛接口的项目及直接调用论坛数据库的项目;

  17. 调试 MAGAPP 接口;

  18. 尝试强制 https 访问;

  19. 将以上所有修改后的程序保留备份;发布升级公告并关闭论坛;重复以上步骤;修改域名解析;开启论坛;

  20. 配置 IP 封禁、定时器、日志、自动备份、配置其它 ECS 的 hosts 等;

  21. 查看搜索引擎中收录的地址,是否有无法访问的情况;

  22. 尝试将历史遗留的本地附件全部转移到 OSS;

  23. 建议 在新服上创建 3 个网站:

    1. 第 1 个用来尝试迁移、升级、二开,并测试所有功能

    2. 第 2 个用来再次重复这些步骤,最终保留程序代码及 UGC 文件,作为最终的网站程序,以正式域名作为网站根目录路径;

    3. 第 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 小版本升级注意事项:

  1. 确认插件是否支持新版本(如短信通)

  2. 先创建一个新网站测试二开代码

  3. 保留 /config/、/data/、/uc_client/data/、/uc_server/data/、/source/plugin/,其它移入 old

  4. 上传文件

  5. 移回其它需要的文件,如:

  6. -- 勋章/loading/logo/nv 等:/static/image/common/

  7. -- 表情:/static/image/smiley/

  8. -- 水印:/static/image/common/watermark.*

  9. -- 风格:/template/default/style/t2/nv.png 等

  10. -- 默认头像:/uc_server/images/noavatar_***.gif

  11. -- 根目录 favicon.ico 等

  12. -- 及其它非 DZ 文件

  13. 再次检查可写目录的写入权限和禁止运行 PHP 效果。


xoyozo 2 个月前
205

截止 2024 年 9 月,CZDB 数据已支持 JAVA、PHP、C、Node.js、Python 语言解析,但官方迟迟未推出 C# / ASP.NET 的版本,于是我参照前面几种语言版本写了 C# 版,支持 IPv4 与 IPv6,实测查询速度,CZDB 版的 MEMORY 模式比原来的 DAT 版数据库快数百倍(具体要看磁盘和内存的读写速度)。能够有效降低 CPU 的使用率,特别是在需要频繁查询 IP 属地的应用场景(譬如每个 HTTP 请求都要判断 IP 属地来决定是否允许访问)。

我要试试→

源代码已提交给纯真官方,相信很快就会有官方版本的 SDK。

xoyozo 3 个月前
585

实例化方法一:DbSearcher(String dbFile, QueryType queryType, String key)

实例化方法二:DbSearcher(InputStream is, QueryType queryType, String key)


  • 方法一通过传入文件路径来实例化,方法二通过传入文件流来实例化;

  • 当 queryType 为 MEMORY 时,方法一和方法二只有在实例化时有性能差别,差别在于将指定路径的文件读到内存中保存;在执行 Search 方法时无性能差别,因为都是在内存中执行查找;

  • queryType 为 MEMORYBTREE 的差别在于前者是在内存中查找,速度快但占内存,后者是在文件中查找,速度慢但省内存


错误:Padding is invalid and cannot be removed.

原因:可能是数据库文件与密钥不一致。

xoyozo 3 个月前
602

unpack("C*", $data)

C 表示一个无符号的字符(unsigned char),它将被解析为一个介于 0 到 255 之间的十进制整数。

* 表示重复该指令直到数据被完全解析。

对应到 C# 中,即在 VS 中断点调试看到的 data 的值。

xoyozo 3 个月前
414

以以下版本为例

PHP 7.3

sqlsrv 5.6.0


步骤:

  1. 安装 PHP 7.3

  2. 加入微软的源

    curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssqlrelease.repo
  3. 安装微软 ODBC 驱动、命令行工具及开发包

    yum install msodbcsql mssql-tools unixODBC-devel
  4. 下载 sqlsrc 扩展

    wget http://pecl.php.net/get/sqlsrv-5.6.0.tgz
  5. 解压(注意最好是 wget 直接下载解压的,如果是 SFTP 上传的,用户是 root 编译会出错)

    tar -zxvf sqlsrv-5.6.0.tgz
  6. 进入

    cd sqlsrv-5.6.0
  7. /www/server/php/73/bin/phpize
  8. ./configure --with-php-config=/www/server/php/73/bin/php-config
  9. make && make install
  10. 添加扩展

    echo "extension = sqlsrv.so" >> /www/server/php/73/etc/php.ini
  11. 重新加载配置

    /etc/init.d/php-fpm-73 reload

image.png

http://pecl.php.net/package/sqlsrv

转自 雕木乱 8 个月前
1,402
  1. 购买 ECS

  2. 解析域名(非网站域名)、修改实例名称、主机名

  3. 设置阿里云(重要)

  4. 远程连接进入 ECS(若解析未生效可以先用 IP)(若新服默认使用 22 端口,可在阿里云控制台登录系统,或先在安全组临时放行 22 端口)

  5. 修复系统漏洞

  6. 将磁盘挂载到目录(fdisk、df 命令参考:https://xoyozo.net/Blog/Details/SSH

  7. 安装宝塔面板(本文以宝塔面板方案为例,选择任何你喜欢的环境部署方案都行)。可以在阿里云控制台ECS实例页安装扩展程序

  8. 临时放行宝塔面板端口,进入宝塔面板(http方式),或用命令更改宝塔面板端口

  9. 配置面板 SSH、添加新的安全端口、面板设置

  10. 更改 SSH 默认端口(参:https://xoyozo.net/Blog/Details/change-default-port

  11. 安装 nginx、PHP 等

  12. 配置 PHP 扩展(Redis、sqlsrv(注意选择兼容的版本)、memcached 及端口)

  13. 创建网站,配置网站(路径、伪静态等)

  14. 迁移网站文件(参:https://xoyozo.net/Blog/Details/SSH

  15. 仔细对比新旧网站的配置文件(特别是 .php 的访问权限,参:https://xoyozo.net/Blog/Details/nginx-location-if

  16. 设置写入目录(使用 rsync 同步的文件会同步用户和权限)

  17. 解析域名(先改 hosts 测试网站功能)

  18. 更改内网其它 ECS 上的 hosts

  19. 关闭原 ECS(能马上发现问题,不然等运行一段时间才发现问题就麻烦点)

  20. 设置 FTP

  21. 迁移“计划任务”

  22. 所有网站和软件的配置文件都要使用 WinMerge 进行对比

  23. 移除“宝塔面板-安全”和“阿里云-ECS-安全组”中不用的端口

  24. 再次检查阿里云设置

  25. 在备份工具中添加该服务器的所有备份项

  26. 私网中若有 ECS 的 hosts 中域名直接绑定到私网 IP 的,做相应更改


更多文章:

从零搭建一台阿里云 ECS(Windows Server)并迁移网站

xoyozo 8 个月前
1,584