20241214博客临近十年的大礼包——论为什么我的wordpress被黑了

这个博客是2015年创建的,今年是2024年很快就要到10年。当时随便从网上找了个主题就没再管它,这些年一直都是修修补补断断续续的升级,遇到报错就自己修掉。想着只要还能凑合用没大问题就行,到过年的时候放假重新做镜像化或者改成静态页什么的方式弄个新技术栈博客。但计划赶不上变化啊,今天本来要写minikube的记录,但打开博客发现速度巨慢,统计时间总是60s上下

尝试重启了apache2、mysql、甚至整个服务器后依然没用。这时候才怀疑是不是被黑了。

根据curl本地测试结果,和远程效果一致可排除腾讯云网络问题。打开apache2日志没发现明显报错,但下面的日志引起了我的注意

这个域名既不是我网站的,我也没什么印象。实际测了下目前服务器的网络是打不开这个地址的。根据这行日志说的查看comment.php内容

根据相似的base64搜索还能发现

解码后内容是

就是这俩文件超时导致变卡的,删掉这两行代码后速度恢复了。对比上一次备份的文件发现没这个内容,怎么写进去的呢?

看了腾讯云的面板和邮件,没有看到异常

用命令行查询最近修改过的文件如下

可以看到多了一些莫名其妙的插件和cache,打开其中一个php可以看到

它不仅写入了新用户,还给自己加了管理员权限。按这个用户名手动去数据库删掉它

其他php中包含了一个log.zip,但实际内容却是php代码

https://s.threatbook.com/report/file/61c192ad41eb1117320e519941eef22146de5092b1e2bf876ed92cc5336d9bde

可以看到是来自于https://github.com/m7x/cmsmap/的webshell

后面的内容虽然做了层层编码,但最后一行才是执行入口

删了它改成打印文本即可看到原始内容,最后又是套娃

删掉eval可避免实际执行代码

打印结果如下,可以看到是一个webshell,讽刺的是这时候腾讯发来了邮件警告。合着前面的编码都是为了骗过腾讯云的检测啊,简单的套两层编码就能绕过云厂商的检测也是醉了。。。。

安全起见完整文件这里就不放了

再看最开始cache下的文件怎么来的呢?首先怀疑的就是timthumb.php,阅读代码逻辑可发现cache文件夹就是它放缓存文件的地方。

参考https://seclists.org/fulldisclosure/2014/Jun/117可以知道这是个很多年前的rce了

修复方式见https://github.com/GabrielGil/TimThumb/commit/564c00058271147af32da8ac665c00f6a1c4ac29#diff-48eb07ba42e9c840631245fee640f99a5beae7b9e238fe802016332fe21f8593L962

倒霉的是不知道为什么快10年了都没被扫到,最近才被人利用

二进制分析不是我的强项,有没有懂二进制安全的大佬分析下这个文件行为是啥,用在线攻击也扫不出问题

https://s.threatbook.com/report/file/4b51ac4a24dbc5cd015cb3a1055fffb4b45d18935ed8015a0682a4321c8147b8

可私聊我获取原始文件

 

20230407kubekey搭建k8s

视频版

https://www.bilibili.com/video/BV1gL411Y75L

 

背景

20230204尝试搭建k8s青春版

上次尝试了k3s,本来计划是尝试原版k8s,但看了下文档感觉略麻烦,我决定放弃。。。。

按上次eric的建议这次尝试玩下kubekey

安装准备

环境要求

Ubuntu 16.04,18.04,20.04CPU:2 核,内存:4 G,硬盘:40 G

机器节点2c4g * 3

  • 所有节点必须都能通过 SSH 访问。
  • 所有节点时间同步。
  • 所有节点都应使用 sudo/curl/openssl/tar
域名分配
k8s1.k8s.local
k8s2.k8s.local
k8s3.k8s.local
kubesphere.k8s.local

生成config

修改config

每个节点上安装依赖项

任务机上执行这个安装集群

安装过程

这时候可以进到命令行查看安装过程,ks-installer-86ddb55c5b-gwlhh就是安装的pod

可以进入pod容器查看目录

也可以直接用logs查看日志

观察到这两个pod一直起不来

都是源于configmap kubesphere-config不存在

多等了一会发现第二个pod ks-controller-manager-8569fb495c-b9qwv自己成功了,可能有降级?(来自20230701的更新:只是单纯的慢,实际是monitor还没装完,所以不动它也能自己好)

尝试手动修改kubesphere-config 里的jwtToken

kubectl get cm kubesphere-config -n kubesphere-system -o yaml

删除pod ks-apiserver后不再报错

参考

https://kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/multioverview/

https://github.com/kubesphere/kubesphere/issues/4729

http://www.minio.org.cn/docs/minio/kubernetes/upstream/

https://docs.ceph.com/en/quincy/cephfs/index.html

 

20230204尝试搭建k8s青春版

视频版

https://www.bilibili.com/video/BV1qj411T7d5/

背景

之前一直想搭建k8s,但按多年前的印象这玩意很复杂。今天先尝试个青春版k3s

安装准备

按文档说是离线在线都行,离线的需要个私有的镜像中心,但镜像中心最简便的搭建方式是跑个容器。。。死循环了啊,所以先试在线的。

家里的资源不多,尝试做个乞丐版,2~3节点就行了,先弄单机后面再加worker

环境要求

硬件按文档建议是最少1c1g,我就给2c2g吧,机器数量是2

系统要求Ubuntu是22.04

可以使用 --with-node-id 给每个节点后面增加一个随机的后缀。或者使用命令行参数 --node-name 或环境变量 $K3S_NODE_NAME 给集群的每个节点传递唯一的名字

网络每个节点需要6443 可以被访问

Flannel VXLAN 节点间通过 UDP 8472 通信

Flannel Wireguard backend 节点间通过 UDP  51820(ipv4) 51821(ipv6)

安装过程

主节点安装过程如上,疑似成功。。。

查看进程如下,可以看到/run/k3s/containerd/containerd.sock说明containerd已经在运行了

metrics-server不知道是干什么的,后面再翻翻文档。

网络监听情况如下,可以看到大部分都是本地监听,只有10250 6443是有可能对外开放的

按文档描述是个TCP的端口监听,看起来和metrics server进程有关,好像是kubelet在节点之间通讯使用的。官方原文:If you wish to utilize the metrics server, all nodes must be accessible to each other on port 10250.

6443是TCP的监听,流量方向是从Agent向Server的,应该是worker节点向master注册数据用的。官方描述为 supervisor and Kubernetes API Server

按文档所说配置文件内容如下

按文档描述会生成这几个相关命令kubectl, crictl, k3s-killall.sh, and k3s-uninstall.sh。具体位置如下,均在/usr/local/bin下,所以可以从任意目录执行。

说实话k3s-killall.sh和k3s-uninstall.sh感觉并不适合放进这个位置,不知道是不是官方怕你找不到故意也放bin里了,这俩实际生产场景下完全没有全局任意目录运行的必要。万一误执行了就GG

尝试获取当前集群的节点,虽然知道只有一个,但需要看看命令是不是能正常执行,别和之前有的服务一样看着没事但实际没正常运行。。。。

这里有个需要关注的东西就是ROLES都有啥,需要看文档了。目前的control-plane顾名思义是控制面, master是主节点。不知道k8s的角色分配是不是和CDH一样能灵活转移。。。

查看TOKEN,准备安装第一个worker节点,按文档描述在这里/var/lib/rancher/k3s/server/node-token

注意,我在一个隔离环境测试,所以/var/lib/rancher/k3s/server/node-token和/etc/rancher/k3s/k3s.yaml的内容暴露了无所谓,待会会直接删除虚机,生产的千万不要轻易暴露。

按要求拼接worker的安装命令如下,到第二个机器上执行

执行到systemd卡住了(后面已确认只是单纯的慢)

再开一个shell查看进程如下

根据systemd服务注册的命令/usr/local/bin/k3s agent,可以看到大概率是执行systemctl restart k3s-agent卡住的

token本身错的可能性不大,所以大概率是K3S_URL的问题,因为我用了本地的DNS,所以写的是域名。尝试配置下HOSTS试试

保险起见我去 /var/lib/rancher/k3s/agent/containerd/containerd.log看了下,居然还在执行东西。。。难道只是单纯的慢?这时候主节点已经能看到agent了,但ROLES里是none让我比较纠结是不是正常

根据命令行参数打印更加详细的节点信息如下,这样看起来worker工作是正常的

测试

尝试构建一个服务是否能正常运行,从k8s官网看看能不能扒一个现成的yaml测试

尝试创建DEMO

尝试使用 kubectl exec进入容器

总结

相比多年前的印象,现在的k8s可以借助k3s这个青春版快速的启动一个集群,是时候更新下这个错误认知了,现在启动一个k8s测试用是相当简便并且成本很低的。下次尝试原版k8s,成功后尝试kubekey这个类似ansible一样的自动化安装工具

参考

https://docs.k3s.io/architecture

https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-7-1/

资源分配和实际占用统计  https://docs.k3s.io/reference/resource-profiling

自动化安装 https://kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/kubekey/

ROLES https://blog.csdn.net/Lingoesforstudy/article/details/116484624

https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/

https://blog.csdn.net/qq_44246980/article/details/120143353

20221217mongodb集群搭建

视频版

 

https://www.bilibili.com/video/BV1Lv4y1Q7xe/

环境准备

https://www.mongodb.com/docs/manual/administration/production-notes/#std-label-prod-notes-supported-platforms 所说6.0支持20.04和18.04

没说22.04支持,保险起见按文档准备系统版本

至少3个以上的奇数节点,5.0以上必须使用域名配置,节点间端口27017网络要求互通

 

1.安装

常见目录

常用命令

2.集群配置

MongoDB 的复制集是由一组保持相同数据集的 mongod 进程组成的。复制集提供了冗余和 高可用的能力,同时它是所有生产环境部署的基础

在特定情况下可以提高读取性能,因为客户端可以把读取请求发送给不同的服务器。被复制多份数据可以用于灾备或审计

复制集包含几个 data bearing nodes和可选的一个arbiter node。在data bearing nodes上有且仅有一个成员是主节点,主节点 接收所有写请求操作,一个主节点会使用 { w: "majority" } 来标识

 

设置bindIp启用远程访问,生产环境注意提前设置密码和防火墙

https://www.mongodb.com/docs/manual/reference/configuration-options/#mongodb-setting-net.bindIp

配置集群名

https://www.mongodb.com/docs/manual/reference/configuration-options/#mongodb-setting-replication.replSetName

3.灾备测试

挂掉1之后到2 上查看集群状态如下,可以发现2自动变成了主

重启1之后,再次查看,可以发现1重新加入了集群,但身份是从节点

从2写入点新数据,到1查询测试,可以发现是正常的

挂掉现在的从节点3,写入新数据后再重启3

可以发现新写入的数据依然可以正常查询

 

 

附录

 

参考

https://www.mongodb.com/docs/manual/

https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/#install-mongodb-community-edition

https://www.mongodb.com/docs/manual/replication/

https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/

https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set-with-keyfile-access-control/#std-label-deploy-repl-set-with-auth

20221127redis-sentinel集群搭建

视频版

https://www.bilibili.com/video/BV1u84y1y7Mu/

1.安装redis

环境信息,按官方文档准备三个节点

执行安装过程

2.配置集群复制配置

复制的配置,假设第一个是主节点。这里测试没做安全防护,生产记得加密码和网段限制

记得重启,之后测试集群复制情况,正常后继续配置sentinel

3.配置sentinel

新建配置文件sentinel.conf  这里测试的是自己新建的,记得关掉系统的service防止干扰。实际应该修改/etc/redis下的配置

启动成功效果

观察端口监听5000

查看集群状态

redis1

redis2

redis3

3.测试故障迁移

模拟主节点挂掉30s或者直接关掉服务,可以看到自动选主,并且修改slave的指向(redis2日志)

见加粗部分

 

这时候再看master已经变成了redis3

去redis3改点数据,去redis2看变不变

显然redis3改的值可以从redis2读到,说明复制正常,继续尝试恢复redis1看看能不能读到test=2

也可以读到,高可用集群搭建完成

附用到的命令

参考

https://redis.io/docs/

https://redis.io/docs/getting-started/installation/install-redis-on-linux/

https://redis.io/docs/management/replication/

https://redis.io/docs/management/sentinel/

20221114mysql-shell部署mysql集群

视频版

https://www.bilibili.com/video/BV1H24y117uh/

1.安装mysql-apt-config并准备基础环境

channel选mysql8, apt update后就能安装 mysql-shell了

获取debian-sys-maint的密码备用

使用/etc/hosts尝试模拟域名或者自行配置DNS

mysqld下的配置增加report_host=mysql1.db,

2.创建账户

2.1.一个InnoDB Cluster server configuration账户用于配置集群的实例

使用dba.configureInstance()创建

2.2.一个或多个InnoDB Cluster administrator账户可以在集群安装后被用来管理服务器实例

在所有节点加入集群后,使用cluster.setupAdminAccount(),这个命令会创建指定的账号并赋予所需的权限,创建这个账号的事务会写入binlog并发送给集群的其他服务器

2.3一个或多个MySQL Router账户可以被MySQL Router用来连接集群

以上每个账户必须在所有InnoDB Cluster节点同时存在, 并使用相同的用户名和相同的密码

mysqlsh进入终端,在三个机器重复这个过程

 

3.检查机器

使用dba.checkInstanceConfiguration(instance) 可以检查节点是否满足 Section 7.1, “InnoDB Cluster Requirements” 提到的前置条件,详见 Checking Instance State

使用dba.configureInstance() 来自动配置节点

连接服务器所用的账户必须有这里要求的权限 Configuring InnoDB Cluster Administrator Accounts Manually

三个机器分别检查自己本地和对方

成功会输出这样的

 

4.创建集群并添加节点

使用\connect 连接主节点

使用dba.createCluster() 使用当前 MySQL Shell 连接的节点作为集群的种子

使用setupAdminAccount广播管理账号,生产环境的话要注意下安全,这里测试没限定网段

使用cluster.addInstance()向当前集群内增加节点,C选择完全量复制,I选择增量复制,默认是全量

使用cluster.status()查看当前集群状态

重复这个过程,添加mysql3

再次查看集群状态,可以看到mysql1是主,mysql2和3是从

使用 cluster.checkInstanceState() 检查集群内节点状态

5.集群测试

5.1.写入测试

连上mysql1,往mysql1里写下数据测试下,在mysql2和3上查看

5.2 灾备测试

我们尝试直接停掉mysql1的服务来模拟主库挂掉,在两外两个机器上查看集群状态,可以看到mysql2自动成为了PRIMARY

向mysql2写入数据测试

到mysql3查看,可以看到数据正常

重新把mysql1启动,在mysql2也就是当前的主节点查看集群,可以看到mysql1自动成为了SECONDARY

到mysql1检查下c1=2也就是宕机期间的数据还在不在,可以发现mysql1重新加入集群后会自动恢复宕机期间的数据

附录:用到的命令

ubuntu安装速度测试

安系统时候在均使用清华源情况下居然发现有错,顺便测下怎么给资源能装的快点

#https://mirrors.tuna.tsinghua.edu.cn

都是40G预分配硬盘

是否联网|核数内存|单个CPU核数*CPU个数|测试结果 虚拟磁盘名

联网|8c1g| 1c*8 不开启VT-x| 反复安装失败  从未见过,可能是CPU内存给少了

联网|8c2g| 1c*8 不开启VT-x| 将近25min,怀疑是CPU给少了 mysql1.vmdk

联网|8c2g| 4c*2 不开启VT-x| 18min,大概10min装完,但是自动升级花了8min mysql1-0.vmdk

断网|8c2g| 4c*2 不开启VT-x| 6min,果然还是断网大法最好,后面都断网装系统好了。这样首次启动联网即可有DHCP下发的IP不影响测试  mysql1-1.vmdk

继续尝试增加核心数看看能否更快

断网|8c2g| 8c*1 不开启VT-x| 5min45s,基本持平,所以CPU数量并不影响这个速度,尝试削减核数  mysql1-2.vmdk

断网|4c2g| 4c*1 不开启VT-x|5min51s,基本持平,所以CPU核数并不影响这个速度,怀疑是单线程,因此试试1c*1 mysql1-3.vmdk

断网|1c2g| 1c*1 不开启VT-x|7min23s,明显下滑,说明不是单线程,至少是2个线程,不然不会这么长时间   mysql1-4.vmdk

断网|2c2g| 2c*1 不开启VT-x|6min22s,回归6min上下了,说明安装的过程确实是2个线程 mysql1-5.vmdk

断网|2c2g| 2c*1 开启VT-x|TODO 有闲心再测 估计不会再快了

参考文档

https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-install-linux-quick.html

https://dev.mysql.com/doc/mysql-shell/8.0/en/configuring-router-user.html

https://dev.mysql.com/doc/mysql-shell/8.0/en/innodb-cluster-user-accounts.html#admin-api-configuring-users

https://dev.mysql.com/doc/mysql-shell/8.0/en/check-instance-configuration.html

 

https://dev.mysql.com/doc/mysql-shell/8.0/en/creating-user-accounts-for-admin-api.html

20221024mysql集群搭建

背景

有了基础的虚拟化环境,打算从头搭建一个分布式应用环境,学习学习各种集群的搭建过程。在公司这些都是别的部门弄好了直接用的,包括高可用、灾备等特性都有值得我研究学习的地方。

集群方式选择

mysql的集群方法

传统方法是基于源节点二进制日志重放事件,并且要求日志文件和位置在源和副本之间是同步的

更新一点的方法是基于 global transaction identifiers (GTIDs),GTIDs是事务性的,不需要依赖日志文件和位置就能工作,这极大的简化了许多常见的副本任务.使用GTIDs的方法保证了源和副本之间的一致性,所有的事务只要在源上提交了就一定会被应用到副本上。

基于日志的方法

源节点个每个副本都应该被设置唯一的ID (using the server_id system variable),顺带一提,每个副本必须设置源节点的host name, log file文件名,文件内的偏移量

这些细节可以通过mysql的session语句控制。MySQL 8.0.23开始是 CHANGE REPLICATION SOURCE TO ,之前是 CHANGE MASTER TO . 这些细节被存储在副本连接的元数据存储中 (see Section 17.2.4, “Relay Log and Replication Metadata Repositories”).

这里有多种不同的方法可以设置副本, 使用某个具体的方法取决于你如何设置以及你是否在源节点已经有想要复制的数据

想要安装多实例的 MySQL, 你可以使用 InnoDB Cluster ,它可以让你使用 MySQL Shell 轻易的管理mysql服务器集群. InnoDB Cluster 用程序化的方式提供了环境包装了MySQL Group Replication,它可以让你轻易的部署一个高可用的Mysql集群。另外 InnoDB Cluster的接口可以无缝集成 MySQL Router, 它可以让你的程序无需编写降级逻辑的情况下连接集群.  对于不需要高可用的相似场景可以使用 InnoDB ReplicaSet. 这里是安装过程here.

 

这里是一些通用任务来改概括所有步骤:

1.在源节点上开启binlog并配置unique server ID Section 17.1.2.1, “Setting the Replication Source Configuration”.

可以考虑使用 –init-file 执行SET GLOBAL server_id = 2;

查看这个值

2.在每个副本上配置a unique server ID.  Section 17.1.2.2, “Setting the Replica Configuration”.

重复1

3.可选,为每个副本创建不同的用户用于鉴权 Section 17.1.2.3, “Creating a User for Replication”.

4.在创建快照或重启副本进程之前,在记录源节点上的binlog当前位置. 当配置你副本节点时你需要这个信息 Section 17.1.2.4, “Obtaining the Replication Source Binary Log Coordinates

在源节点上执行

记录File | Position

5.如果你在源节点上已经有数据了并且想要同步到副本上,你需要创建数据的快照来复制数据到副本. 你所使用的存储引擎会决定你如何创建快照

当你使用 MyISAM时,你必须在源上停止处理语句来获得read-lock, 在允许源节点继续执行语句之前获取当前binlog的坐标并导出数据。 Section 17.1.2.4, “Obtaining the Replication Source Binary Log Coordinates”.

当你使用 InnoDB, 你不需要获取read-lock,一个够长的事务足够可以传输数据的快照(这么翻译感觉怪怪的,原文: you do not need a read-lock and a transaction that is long enough to transfer the data snapshot is sufficient.) Section 15.19, “InnoDB and MySQL Replication”.

6.在副本上设置连接的源节点,例如host name,、登录凭证、binlog文件名和位置 Section 17.1.2.7, “Setting the Source Configuration on the Replica”.

在副本节点上执行

7.对源和副本实施特定的安全措施 Section 17.3, “Replication Security”.

基础配置完成后,选择你的场景:

在管理MySQL集群之前,阅读完整的章节并尝试这里所有的语句,同时熟悉副本的启动选项

Section 13.4.1, “SQL Statements for Controlling Source Servers,

Section 13.4.2, “SQL Statements for Controlling Replica Servers.

Section 17.1.6, “Replication and Binary Logging Options and Variables.

基于GTIDs的方法

TODO

MRG搭建

注意,任意节点脱离group后需要手动执行start group_replication重新加入,执行前的数据保留在离开group时的状态

例如mysql2重新加入group变化如下

尝试mysql shell自动配置

https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html

 

参考文档

https://dev.mysql.com/doc/refman/8.0/en/replication.html

https://dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-in-single-primary-mode.html

https://ethendev.github.io/2018/12/17/JPA-MySQL-read-write-separation/

https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html