<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Jack Zhang</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://www.caiguu.cn/</id>
  <link href="https://www.caiguu.cn/" rel="alternate"/>
  <link href="https://www.caiguu.cn/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Jack Zhang</rights>
  <subtitle>一位入门网络工程师的升级之路</subtitle>
  <title>在代码与网络间</title>
  <updated>2026-05-06T14:17:41.816Z</updated>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="网站维护" scheme="https://www.caiguu.cn/categories/website/"/>
    <category term="建站历程" scheme="https://www.caiguu.cn/categories/website/building/"/>
    <category term="SSL" scheme="https://www.caiguu.cn/tags/ssl/"/>
    <content>
      <![CDATA[<p>博客顺利搭建之后，一个很重要的事情就是配置一个SSL证书，以支持HTTPS访问。这篇博文将首先讲解如何通过腾讯云申请免费SSL证书、并在Nginx服务器上完成SSL证书的安装。</p><h1 id="申请免费SSL证书"><a href="#申请免费SSL证书" class="headerlink" title="申请免费SSL证书"></a>申请免费SSL证书</h1><p>进入腾讯云控制台，选择<code>SSL证书</code>，然后选择<code>我的证书</code>。可以找到<code>免费证书</code>，并点击<code>申请免费证书</code>。</p><h2 id="SSL证书90天倡议"><a href="#SSL证书90天倡议" class="headerlink" title="SSL证书90天倡议"></a>SSL证书90天倡议</h2><p>需要注意的是，免费SSL证书的有效期只有<strong>3个月</strong>，且不能直接对证书进行续期。如果证书到期，需要重新申请新的证书。这是有一些背景故事的：“<strong>SSL证书90天倡议</strong>”主要是指由全球网络安全与浏览器厂商共同推动的一项行业标准变更，核心目标是将所有公开信任的SSL&#x2F;TLS证书的有效期从传统的1年或更长，逐步缩短至90天，并最终在2029年前降至约47天。</p><p>缩短证书有效期主要基于以下安全考量：</p><ul><li><strong>减小密钥泄露的影响范围</strong>：如果私钥被盗或证书被错误签发，较短的有效期能限制攻击者滥用该证书的时间，从而降低潜在的损失。</li><li><strong>推动自动化与敏捷性</strong>：促使网站管理员放弃低效的手动证书管理，转向使用自动化工具（如ACME协议）来定期更新证书，从而减少因遗忘续期导致的网站中断事故。</li></ul><p>所以，在后期我们也将考虑使用自动化工具来处理证书续期问题。不过，路要一步一步走，我们先来体验一下如何用最传统的方式实现免费SSL证书的配置。</p><h2 id="申请免费证书"><a href="#申请免费证书" class="headerlink" title="申请免费证书"></a>申请免费证书</h2><p>我们可以在这里申请免费的SSL证书：</p><img src="/images/apply_free_ssl_certificate.png" style="zoom: 50%;" /><h2 id="手动DNS验证域名"><a href="#手动DNS验证域名" class="headerlink" title="手动DNS验证域名"></a>手动DNS验证域名</h2><p>SSL证书提供商需要确保这个域名是你的，是可用的，所以需要进行一些验证。如果选择了手动DNS验证，那么就需要我们登录到DNS控制台中并增加一条TXT类型的记录，并回来进行验证。验证通过后才能签发证书。</p><p><img src="/images/dns_certificate.png"></p><p>我们进入域名控制台，并按照指引添加对应记录：</p><p><img src="/images/add_dns_record_for_ssl_certificate.png"></p><p>然后点击验证，查看验证通过：</p><img src="/images/dns_certificate_ok.png" alt="" style="zoom:50%;" /><p>这样，证书就可以完成签发了。稍后就会收到SSL证书认证通过的通知。</p><h1 id="部署SSL证书"><a href="#部署SSL证书" class="headerlink" title="部署SSL证书"></a>部署SSL证书</h1><h2 id="下载SSL证书"><a href="#下载SSL证书" class="headerlink" title="下载SSL证书"></a>下载SSL证书</h2><p>证书完成了签发，但是目前还没生效，因为没有部署到网络当中去呢。我们需要先下载下来证书：</p><p><img src="/images/download_ssl_certificate.png"></p><p>证书文件的结构如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">caiguu@JACKERZHANG-MB0 Downloads % tree caiguu.cn_nginx </span><br><span class="line">caiguu.cn_nginx</span><br><span class="line">├── caiguu.cn_bundle.crt</span><br><span class="line">├── caiguu.cn_bundle.pem</span><br><span class="line">├── caiguu.cn.csr</span><br><span class="line">└── caiguu.cn.key</span><br><span class="line"></span><br><span class="line">1 directory, 4 files</span><br></pre></td></tr></table></figure><p>这四个文件的作用分别如下：</p><table><thead><tr><th align="left">文件名</th><th align="left">后缀</th><th align="left">作用</th><th align="left">在Nginx配置中的使用</th></tr></thead><tbody><tr><td align="left"><code>caiguu.cn_bundle.crt</code></td><td align="left"><code>.crt</code></td><td align="left"><strong>完整的证书链</strong>。包含了你的域名证书和中间证书，是浏览器用来验证你网站身份并建立加密连接的关键文件。</td><td align="left"><strong><code>ssl_certificate</code></strong> 指令使用此文件。</td></tr><tr><td align="left"><code>caiguu.cn.key</code></td><td align="left"><code>.key</code></td><td align="left"><strong>私钥文件</strong>。与你的公钥证书配对，用于解密客户端发送的数据，必须严格保密，绝对不能泄露。</td><td align="left"><strong><code>ssl_certificate_key</code></strong> 指令使用此文件。</td></tr><tr><td align="left"><code>caiguu.cn_bundle.pem</code></td><td align="left"><code>.pem</code></td><td align="left">与<code>caiguu.cn_bundle.crt</code>内容相同，只是格式是<code>.pem</code>（一种更通用的文本格式）。为其他软件兼容性而提供。</td><td align="left">Nginx不需要，可忽略。</td></tr><tr><td align="left"><code>caiguu.cn.csr</code></td><td align="left"><code>.csr</code></td><td align="left"><strong>证书签名请求文件</strong>。申请证书时向CA机构提交的临时文件，证书签发后<strong>不再需要</strong>。</td><td align="left"><strong>完全不需要</strong>，可以安全删除。</td></tr></tbody></table><p>所以，接下来我们就可以登录服务器进行对应配置了。</p><h2 id="上传证书文件到服务器"><a href="#上传证书文件到服务器" class="headerlink" title="上传证书文件到服务器"></a>上传证书文件到服务器</h2><p>我把证书文件存储在了<code>/etc/cert/</code>下。于是我现在要做的就是把<code>caiguu.cn_bundle.crt</code>和<code>caiguu.cn.key</code>这两个文件上传到这个位置。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">[root@VM-0-10-opencloudos etc]# tree ./cert</span><br><span class="line">./cert</span><br><span class="line">├── caiguu.cn_bundle.crt</span><br><span class="line">└── caiguu.cn.key</span><br><span class="line"></span><br><span class="line">0 directories, 2 files</span><br></pre></td></tr></table></figure><p>然后我们修改<code>hexo.conf</code>文件如下：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span>       <span class="number">80</span>;  <span class="comment"># 监听80端口（HTTP）</span></span><br><span class="line">    <span class="attribute">listen</span>       [::]:<span class="number">80</span>;</span><br><span class="line">    <span class="attribute">server_name</span>  caiguu.cn;  <span class="comment"># 将此处改为你的域名或服务器IP</span></span><br><span class="line">    <span class="attribute">charset</span> utf-<span class="number">8</span>;  </span><br><span class="line"></span><br><span class="line">    <span class="attribute">return</span> <span class="number">301</span> https://<span class="variable">$server_name</span><span class="variable">$request_uri</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="comment"># 监听 443 端口，并启用 SSL（同时支持IPv4和IPv6）</span></span><br><span class="line">    <span class="attribute">listen</span>       <span class="number">443</span> ssl;</span><br><span class="line">    <span class="attribute">listen</span>       [::]:<span class="number">443</span> ssl;      <span class="comment"># 建议加上 ssl 参数，与上一行保持一致</span></span><br><span class="line">    <span class="attribute">server_name</span>  caiguu.cn;</span><br><span class="line">    <span class="attribute">charset</span>      utf-<span class="number">8</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># SSL 证书文件路径</span></span><br><span class="line">    <span class="attribute">ssl_certificate</span>     /etc/cert/caiguu.cn_bundle.crt;  <span class="comment"># 已添加分号</span></span><br><span class="line">    <span class="comment"># SSL 证书私钥文件路径</span></span><br><span class="line">    <span class="attribute">ssl_certificate_key</span> /etc/cert/caiguu.cn.key;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_session_timeout</span> <span class="number">5m</span>;</span><br><span class="line">    <span class="attribute">ssl_protocols</span>       TLSv1.<span class="number">2</span> TLSv1.<span class="number">3</span>;</span><br><span class="line">    <span class="attribute">ssl_ciphers</span>         ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;</span><br><span class="line">    <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 静态文件目录</span></span><br><span class="line">    <span class="attribute">root</span>   /var/www/hexo;</span><br><span class="line">    <span class="attribute">index</span>  index.html;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 访问和错误日志（目录需要存在且Nginx有写入权限）</span></span><br><span class="line">    <span class="attribute">access_log</span>  /var/log/nginx/hexo.access.log;</span><br><span class="line">    <span class="attribute">error_log</span>   /var/log/nginx/hexo.<span class="literal">error</span>.log;</span><br><span class="line"></span><br><span class="line">    <span class="section">location</span> / &#123;</span><br><span class="line">        <span class="attribute">try_files</span> <span class="variable">$uri</span> <span class="variable">$uri</span>/ =<span class="number">404</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>主要做了两件事：第一是把80访问重定向到443上，强制使用HTTPS。第二是配置了读取SSL证书的路径，并配置了SSL的相关属性。</p><p>接下来需要重新加载一下Nginx服务，以使得它生效。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> nginx -s reload</span><br></pre></td></tr></table></figure><p>我们在浏览器中打开，就能看到这个证书的信息了：</p><img src="/images/my_ssl_certificate.png" style="zoom:50%;" /><p>至此，我们的博客就支持HTTPS访问了！</p><h1 id="凭什么信任我？"><a href="#凭什么信任我？" class="headerlink" title="凭什么信任我？"></a>凭什么信任我？</h1><p>我申请了一个SSL证书，并把这个文件放到服务器上，然后又做了点配置，为什么就能得到信任了呢？凭什么呢？</p><h2 id="一条完整的信任链"><a href="#一条完整的信任链" class="headerlink" title="一条完整的信任链"></a>一条完整的信任链</h2><p>想象一下这个场景：你去派出所办了一张身份证。然后去银行办业务，柜员看了一眼你的身份证，就信你了。为什么？因为他信的不是你这个人，而是你背后的那个体系：身份证上有防伪标识，银行柜员无需见到签发这个证件的过程，凭借对这个体系的信任，他就会信任你。</p><p>类比到我们的证书中，也是这个道理，这里存在一条完整的信任链：</p><ul><li><strong>我的证书</strong>：就像我的身份证，上面有我的名字（<a href="https://caiguu.cn/">caiguu.cn</a>）和我的公钥（相当于我的银行账号）</li><li><strong>中间证书</strong>：证明我这个身份证是TrustAsia这个”派出所”签发的</li><li><strong>根证书</strong>：这个最厉害，它被预装在你电脑的操作系统里，就像全世界所有银行都默认信任的”终极权威”</li></ul><h2 id="根证书"><a href="#根证书" class="headerlink" title="根证书"></a>根证书</h2><p>我们可以在自己的电脑上看到跟证书有哪些：</p><p><img src="/images/root_certificate.png"></p><p>我们可以在其中看到DigCert Global Root G2：</p><img src="/images/digicert_global_root_g2.png" alt="DigiCert Global Root G2" style="zoom:50%;" /><h2 id="TrustAsia中间证书"><a href="#TrustAsia中间证书" class="headerlink" title="TrustAsia中间证书"></a>TrustAsia中间证书</h2><p>我们可以在自己的<code>caiguu.cn_bundle.crt</code>中看到这些信任链：</p><img src="/images/caiguu_cn_bundle.png" alt="" style="zoom:50%;" /><p>这里就能看到我们的证书由TrustAsia签发，同时能够看到公钥和签名。</p><h2 id="证书层次结构"><a href="#证书层次结构" class="headerlink" title="证书层次结构"></a>证书层次结构</h2><p>我们可以在证书层次结构里看到我们的证书层次结构如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">DigiCert Global Root G2 (根证书)</span><br><span class="line">  ↓ 签名</span><br><span class="line">TrustAsia DV TLS RSA Root CA 2025(中间证书)</span><br><span class="line">  ↓ 签名</span><br><span class="line">caiguu.cn (你的服务器证书)</span><br></pre></td></tr></table></figure><h2 id="签名与验证真伪"><a href="#签名与验证真伪" class="headerlink" title="签名与验证真伪"></a>签名与验证真伪</h2><p>接着我们看一下签名。签名不是为了加密什么，而是为了<strong>证明这份内容确实是某个持有私钥的人发出的，并且没有被篡改</strong>。</p><p>假设我们是浏览器，有人想访问<code>caiguu.cn</code>，看看会发生什么：</p><ol><li>浏览器通过Nginx获取到<code>.crt</code>文件，得到证书链</li><li>从证书链找到<strong>TrustAsia 的中间证书</strong></li><li>从我的证书取出<strong>TrustAsia</strong>计算出来的签名</li><li>用TrustAsia的公钥解密这个签名，得到一个哈希值，叫<code>H1</code></li><li>自己用指定的哈希算法（例如SHA-256）计算证书的哈希值，叫<code>H2</code></li><li>对比<code>H1</code>与<code>H2</code>是否相等。如果相等，说明证书真实。否则证书被篡改过！也就是说，<code>H1</code>是解密出来的证书哈希值。是证书最初的样子。 <code>H2</code>是利用当前证书文件计算出来的哈希值。 如果未被篡改，那么<code>H1==H2</code>。如果被改了，那么<code>H1!=H2</code>。至于为什么私钥加密、公钥可以解密，这就是密码学领域的知识了。</li></ol><p>接着，类似地，会继续计算TrustAsia的证书是否可信；直到检查根证书是否在操作系统中内置。如果都通过了，那么说明整个信任链上都是安全可信的。</p><h2 id="通信内容安全怎么保证？"><a href="#通信内容安全怎么保证？" class="headerlink" title="通信内容安全怎么保证？"></a>通信内容安全怎么保证？</h2><p>最后，我还有一个私钥没有出现呢？它干什么用？</p><p>答案是保证通信内容的安全。</p><p>我的私钥在HTTPS中主要做两件事：</p><ol><li><strong>证明身份</strong>：握手阶段，服务器用私钥（也就是我的私钥），生成握手信息的签名。然后浏览器会用我的公钥来解密，查看握手信息是否正确。 </li><li><strong>帮助协商密钥</strong>（可选方式）：浏览器生成一个随机数，用我的公钥加密后发过来，我用私钥解密。这样，我们就能在不安全的网络中安全地商量出一个只有我俩知道的“暗号”，用这个暗号加密后续的所有通信。</li></ol><p>至此，我们就对SSL有了直观、生动的认识，相信现在对于HTTPS的理解已经更上层楼了！</p>]]>
    </content>
    <id>https://www.caiguu.cn/website/building/ssl_configuration/</id>
    <link href="https://www.caiguu.cn/website/building/ssl_configuration/"/>
    <published>2026-05-05T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>博客顺利搭建之后，一个很重要的事情就是配置一个SSL证书，以支持HTTPS访问。这篇博文将首先讲解如何通过腾讯云申请免费SSL证书、并在Nginx服务器上完成SSL证书的安装。</p>
<h1 id="申请免费SSL证书"><a href="#申请免费SSL证书" clas]]>
    </summary>
    <title>为博客配置SSL证书以支持HTTPS访问吧！</title>
    <updated>2026-05-06T14:17:41.816Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="网络探秘" scheme="https://www.caiguu.cn/categories/network/"/>
    <category term="视频讲解" scheme="https://www.caiguu.cn/categories/network/video/"/>
    <category term="视频讲解" scheme="https://www.caiguu.cn/tags/video/"/>
    <content>
      <![CDATA[<p>以下是我录制的计算机网络讲解视频！正在持续更新，敬请期待！</p><h1 id="网络层：数据平面"><a href="#网络层：数据平面" class="headerlink" title="网络层：数据平面"></a>网络层：数据平面</h1><h2 id="Vol-01-网络层概述"><a href="#Vol-01-网络层概述" class="headerlink" title="Vol.01 网络层概述"></a>Vol.01 网络层概述</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aaid=114931026433556&bvid=BV1hw8EzfEie&cid=25832201184&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-02-路由器工作原理（上）"><a href="#Vol-02-路由器工作原理（上）" class="headerlink" title="Vol.02 路由器工作原理（上）"></a>Vol.02 路由器工作原理（上）</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=114942317434131&bvid=BV1dM8BzxEYr&cid=25833379292&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-03-路由器工作原理（下）"><a href="#Vol-03-路由器工作原理（下）" class="headerlink" title="Vol.03 路由器工作原理（下）"></a>Vol.03 路由器工作原理（下）</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=114976140498216&bvid=BV1aUtJz8EKi&cid=25836787879&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-04-IP地址层次结构-1-：IP地址表示"><a href="#Vol-04-IP地址层次结构-1-：IP地址表示" class="headerlink" title="Vol.04 IP地址层次结构(1)：IP地址表示"></a>Vol.04 IP地址层次结构(1)：IP地址表示</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115015566824930&bvid=BV1MEtdzdEaA&cid=25840849197&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-05-IP地址层次结构-2-：IP地址分类"><a href="#Vol-05-IP地址层次结构-2-：IP地址分类" class="headerlink" title="Vol.05 IP地址层次结构(2)：IP地址分类"></a>Vol.05 IP地址层次结构(2)：IP地址分类</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115060898927723&bvid=BV17MegztEa5&cid=25845764316&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-06-IP地址层次结构-3-：子网和子网编址"><a href="#Vol-06-IP地址层次结构-3-：子网和子网编址" class="headerlink" title="Vol.06 IP地址层次结构(3)：子网和子网编址"></a>Vol.06 IP地址层次结构(3)：子网和子网编址</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115129685384946&bvid=BV13yaHzyEg7&cid=25853303014&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-07-IP地址层次结构-4-：子网掩码Subnet-Mask"><a href="#Vol-07-IP地址层次结构-4-：子网掩码Subnet-Mask" class="headerlink" title="Vol.07 IP地址层次结构(4)：子网掩码Subnet Mask"></a>Vol.07 IP地址层次结构(4)：子网掩码Subnet Mask</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115135087648397&bvid=BV1XmaAzfEHF&cid=25853891406&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-08-IP地址层次结构-5-：可变长度子网掩码VLSM和广播地址"><a href="#Vol-08-IP地址层次结构-5-：可变长度子网掩码VLSM和广播地址" class="headerlink" title="Vol.08 IP地址层次结构(5)：可变长度子网掩码VLSM和广播地址"></a>Vol.08 IP地址层次结构(5)：可变长度子网掩码VLSM和广播地址</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115145623738824&bvid=BV1TBamzyEXc&cid=25855006749&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-09-IP地址层次结构-6-：无类域间路由CIDR"><a href="#Vol-09-IP地址层次结构-6-：无类域间路由CIDR" class="headerlink" title="Vol.09 IP地址层次结构(6)：无类域间路由CIDR"></a>Vol.09 IP地址层次结构(6)：无类域间路由CIDR</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115213823119572&bvid=BV1nop2zgECt&cid=25862871420&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-10-IP地址层次结构-7-：子网聚合"><a href="#Vol-10-IP地址层次结构-7-：子网聚合" class="headerlink" title="Vol.10 IP地址层次结构(7)：子网聚合"></a>Vol.10 IP地址层次结构(7)：子网聚合</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115350507101524&bvid=BV1TU4nzsEvU&cid=25879515265&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-11-IP地址层次结构-8-：特殊用途IP地址"><a href="#Vol-11-IP地址层次结构-8-：特殊用途IP地址" class="headerlink" title="Vol.11 IP地址层次结构(8)：特殊用途IP地址"></a>Vol.11 IP地址层次结构(8)：特殊用途IP地址</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=115491318340619&bvid=BV1Ua1CBJEQZ&cid=25900618287&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-12-IP地址层次结构-9-：IP地址分配（上）"><a href="#Vol-12-IP地址层次结构-9-：IP地址分配（上）" class="headerlink" title="Vol.12 IP地址层次结构(9)：IP地址分配（上）"></a>Vol.12 IP地址层次结构(9)：IP地址分配（上）</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=116363247032848&bvid=BV1YSDeByEq3&cid=37314498142&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div><h2 id="Vol-13-IP地址层次结构-10-：IP地址分配（下）：多宿主问题"><a href="#Vol-13-IP地址层次结构-10-：IP地址分配（下）：多宿主问题" class="headerlink" title="Vol.13 IP地址层次结构(10)：IP地址分配（下）：多宿主问题"></a>Vol.13 IP地址层次结构(10)：IP地址分配（下）：多宿主问题</h2><div style="position: relative; padding: 0 0 56.25%; height: 0; overflow: hidden;">  <iframe     src="//player.bilibili.com/player.html?aid=116369102282193&bvid=BV1wHDEBUErg&cid=37340319059&page=1&autoplay=0&muted=1"     style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"     frameborder="0"     allowfullscreen="true">  </iframe></div>]]>
    </content>
    <id>https://www.caiguu.cn/network/video/network_video/</id>
    <link href="https://www.caiguu.cn/network/video/network_video/"/>
    <published>2026-04-06T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>以下是我录制的计算机网络讲解视频！正在持续更新，敬请期待！</p>
<h1 id="网络层：数据平面"><a href="#网络层：数据平面" class="headerlink" title="网络层：数据平面"></a>网络层：数据平面</h1><h2 id="Vol-]]>
    </summary>
    <title>计算机网络讲解视频集合（持续更新）</title>
    <updated>2026-04-08T13:12:48.815Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="网络探秘" scheme="https://www.caiguu.cn/categories/network/"/>
    <category term="BGP" scheme="https://www.caiguu.cn/categories/network/bgp/"/>
    <category term="BGP" scheme="https://www.caiguu.cn/tags/bgp/"/>
    <content>
      <![CDATA[<p>对IP与网络的基础有了初步的认知之后，我们要探索更加深入、更加复杂的内容了。首先要学习的就是BGP——边界网关协议。正是这个协议把世界从一个个局域网串联起来，形成我们众所周知的因特网，打破各个自治系统之间的隔阂，让世界互联成为可能。本实验基于华为HCIP教材以及eNSP进行模拟，通过实战对BGP形成初步认知，了解如何启动BGP、iBGP和eBGP的区别、BGP报文以及对外发送BGP路由条目。</p><h1 id="实验拓扑"><a href="#实验拓扑" class="headerlink" title="实验拓扑"></a>实验拓扑</h1><p><img src="/images/BGP_basic_topology.png"></p><p>实验拓扑如图所示，其中AR1、AR2和AR3都属于AS 65001，而AR4属于AS 65002。值得注意的是，<strong>64512-65534</strong>是私有AS号。各个端口配置的IP地址将会在后面的配置命令中给出。</p><p>其中，AR2不属于BGP路由器，不设置BGP的相关功能。在AS65001内部，仅AR1和AR3构建iBGP对等体，通过Loopback接口地址建立连接；而AR1和AR４建立eBGP对等体关系，通过直连接口地址建立连接。</p><h1 id="基础配置"><a href="#基础配置" class="headerlink" title="基础配置"></a>基础配置</h1><p>我们先在各个设备上配置IP地址，如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis ip int brief </span><br><span class="line">Interface                         IP Address/Mask      Physical   Protocol  </span><br><span class="line">GigabitEthernet0/0/0              192.168.12.1/24      up         up        </span><br><span class="line">GigabitEthernet0/0/1              172.16.14.1/24       up         up        </span><br><span class="line">GigabitEthernet0/0/2              unassigned           down       down      </span><br><span class="line">LoopBack0                         10.0.0.1/32          up         up(s)     </span><br><span class="line">NULL0                             unassigned           up         up(s)  </span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR2&gt;dis ip int br</span><br><span class="line">Interface                         IP Address/Mask      Physical   Protocol  </span><br><span class="line">GigabitEthernet0/0/0              192.168.12.2/24      up         up        </span><br><span class="line">GigabitEthernet0/0/1              192.168.23.2/24      up         up        </span><br><span class="line">GigabitEthernet0/0/2              unassigned           down       down      </span><br><span class="line">LoopBack0                         10.0.0.2/32          up         up(s)     </span><br><span class="line">NULL0                             unassigned           up         up(s)</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR3&gt;dis ip int br</span><br><span class="line">GigabitEthernet0/0/0              unassigned           down       down      </span><br><span class="line">GigabitEthernet0/0/1              192.168.23.3/24      up         up        </span><br><span class="line">GigabitEthernet0/0/2              unassigned           down       down      </span><br><span class="line">LoopBack0                         10.0.0.3/32          up         up(s)     </span><br><span class="line">NULL0                             unassigned           up         up(s)  </span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR4&gt;dis ip int br</span><br><span class="line">GigabitEthernet0/0/0              unassigned           down       down      </span><br><span class="line">GigabitEthernet0/0/1              172.16.14.4/24       up         up        </span><br><span class="line">GigabitEthernet0/0/2              unassigned           down       down      </span><br><span class="line">LoopBack0                         10.0.0.4/32          up         up(s)     </span><br><span class="line">NULL0                             unassigned           up         up(s)   </span><br></pre></td></tr></table></figure><h1 id="AS65001内配置OSPF（IGP）"><a href="#AS65001内配置OSPF（IGP）" class="headerlink" title="AS65001内配置OSPF（IGP）"></a>AS65001内配置OSPF（IGP）</h1><p>然后我们把OSPF配置一下。如果不配OSPF，那么AR1和AR3就无法路由到彼此，那么更无从谈起BGP邻居的建立了。所以，我们要先配置OSPF。本试验在AS65001内配置IGP即可。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis cur con ospf</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">ospf 1 </span><br><span class="line"> area 0.0.0.0 </span><br><span class="line">  network 10.0.0.1 0.0.0.0 </span><br><span class="line">  network 172.16.14.0 0.0.0.255 </span><br><span class="line">  network 192.168.12.0 0.0.0.255 </span><br><span class="line">#</span><br><span class="line">Return</span><br><span class="line"></span><br><span class="line">&lt;AR2&gt;dis cur con ospf</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">ospf 1 </span><br><span class="line"> area 0.0.0.0 </span><br><span class="line">  network 10.0.0.2 0.0.0.0 </span><br><span class="line">  network 192.168.12.0 0.0.0.255 </span><br><span class="line">  network 192.168.23.0 0.0.0.255 </span><br><span class="line">#</span><br><span class="line">Return</span><br><span class="line"></span><br><span class="line">&lt;AR3&gt;  dis cur con ospf</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">ospf 1 </span><br><span class="line"> area 0.0.0.0 </span><br><span class="line">  network 10.0.0.3 0.0.0.0 </span><br><span class="line">  network 192.168.23.0 0.0.0.255 </span><br><span class="line">#</span><br><span class="line">Return</span><br></pre></td></tr></table></figure><p>这样，内部的OSPF就建立好了。可以通过这些命令复习一下OSPF是怎么配置的。通过OSPF进程和area区域，并通过network宣告参与OSPF计算的IP地址即可。</p><h1 id="BGP配置"><a href="#BGP配置" class="headerlink" title="BGP配置"></a>BGP配置</h1><p>我们在AR1上做了这样的配置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">[AR1]bgp 65001</span><br><span class="line">[AR1-bgp]router-id 10.0.0.1 </span><br><span class="line">[AR1-bgp]peer 10.0.0.3 as</span><br><span class="line">[AR1-bgp]peer 10.0.0.3 as-number 65001</span><br><span class="line">[AR1-bgp]peer 10.0.0.3 connect-interface lo0 #iBGP最好用Loopback地址去建立</span><br><span class="line">[AR1-bgp]dis th</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">bgp 65001</span><br><span class="line"> router-id 10.0.0.1</span><br><span class="line"> peer 10.0.0.3 as-number 65001 </span><br><span class="line"> peer 10.0.0.3 connect-interface LoopBack0</span><br><span class="line"> #</span><br><span class="line"> ipv4-family unicast</span><br><span class="line">  undo synchronization</span><br><span class="line">  peer 10.0.0.3 enable</span><br><span class="line">#</span><br><span class="line">return</span><br><span class="line">[AR1-bgp]q</span><br></pre></td></tr></table></figure><p>在AR3上做了这样的配置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">[AR3]bgp 65001</span><br><span class="line">[AR3-bgp]router-id 10.0.0.3</span><br><span class="line">[AR3-bgp]peer 10.0.0.1 as-number 65001</span><br><span class="line">[AR3-bgp]peer 10.0.0.1 connect-interface lo0 </span><br><span class="line">[AR3-bgp]dis th</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">bgp 65001</span><br><span class="line"> router-id 10.0.0.3</span><br><span class="line"> peer 10.0.0.1 as-number 65001 </span><br><span class="line"> peer 10.0.0.1 connect-interface LoopBack0</span><br><span class="line"> #</span><br><span class="line"> ipv4-family unicast</span><br><span class="line">  undo synchronization</span><br><span class="line">  peer 10.0.0.1 enable</span><br><span class="line">#</span><br><span class="line">Return</span><br></pre></td></tr></table></figure><p>BGP的配置要点在于：</p><p>主要步骤在于：</p><ol><li>启动BGP进程。其方法为<code>bgp &lt;as-number&gt;</code></li><li>配置router-id。其方法为<code>router-id &lt;ipv4 address&gt;</code></li><li>配置BGP对等体。其方法为<code>peer &lt;ipv4/ipv6 address&gt; as-number &lt;AS号（数字或者x.y形式均可）&gt;</code></li><li>指定发送BGP报文的源接口。默认使用报文的出接口作为源接口。</li><li>配置BGP引入路由。例如<code>network</code>或者<code>import-route</code>。</li></ol><h1 id="iBGP建立及过程"><a href="#iBGP建立及过程" class="headerlink" title="iBGP建立及过程"></a>iBGP建立及过程</h1><h2 id="BGP邻居查看"><a href="#BGP邻居查看" class="headerlink" title="BGP邻居查看"></a>BGP邻居查看</h2><p>我们看看AR1上的BGP邻居吧：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis bgp peer</span><br><span class="line"></span><br><span class="line"> BGP local router ID : 10.0.0.1</span><br><span class="line"> Local AS number : 65001</span><br><span class="line"> Total number of peers : 1  Peers in established state : 1</span><br><span class="line"></span><br><span class="line">  Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State PrefRcv</span><br><span class="line"></span><br><span class="line">  10.0.0.3        4       65001       15       15     0 00:13:40 Established    0</span><br></pre></td></tr></table></figure><p>以及AR3：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR3&gt;dis bgp peer</span><br><span class="line"></span><br><span class="line"> BGP local router ID : 10.0.0.3</span><br><span class="line"> Local AS number : 65001</span><br><span class="line"> Total number of peers : 1  Peers in established state : 1</span><br><span class="line"></span><br><span class="line">  Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State PrefRcv</span><br><span class="line"></span><br><span class="line">  10.0.0.1        4       65001       16       17     0 00:14:02 Established    0</span><br></pre></td></tr></table></figure><p>可以看到，AR1和AR3已经顺利建立起了iBGP邻居了。</p><h2 id="BGP的建立过程"><a href="#BGP的建立过程" class="headerlink" title="BGP的建立过程"></a>BGP的建立过程</h2><p>我们如果抓包，是可以看到建立过程的，以AR1为例：</p><p><img src="/images/bgp_basic_establish.png"></p><p>我们筛选出来端口号是179的所有TCP包，就能看到整个交互逻辑了。我们可以看到的确两个方向都发送了TCP连接，但是AR3发起的TCP连接最终被关闭了，保留的是由AR1发起的TCP连接。而且可以看到很多互相发送keepalive报文的过程：</p><p><img src="/images/bgp_basic_port_179.png"></p><p>我们可以大概看一下Open报文长什么样：</p><p><img src="/images/bgp_basic_open_packet.png"></p><p>其核心内容包括我的AS号、Hold Time和Router ID。其中保持时间是需要进行协商的，建立BGP peer需要保持这个参数一致。</p><p>我们再看一下Keepalive包，这个没有内容，只有BGP报头。</p><p><img src="/images/bgp_basic_keepalive_packet.png"></p><p>值得注意的是，双方都发送了Keepalive报文，才意味着BGP连接完成，进入Established状态！</p><h1 id="eBGP建立"><a href="#eBGP建立" class="headerlink" title="eBGP建立"></a>eBGP建立</h1><p>到现在，我们AS65001的iBGP连接就已经建立完毕了。接下来我们将建立AR1和AR4之间的BGP连接，即eBGP。 </p><p>对于AR1，由于已经配置了router-id，无需重复配置。而且对于eBGP，最好用接口本身作为建立连接的地址，因此也无需配置connect-interface。所以我们配置如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;sys</span><br><span class="line">Enter system view, return user view with Ctrl+Z.</span><br><span class="line">[AR1]bgp 65001</span><br><span class="line">[AR1-bgp]peer 172.16.14.4 as-number 65002</span><br><span class="line">[AR1-bgp]dis th</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">bgp 65001</span><br><span class="line"> router-id 10.0.0.1</span><br><span class="line"> peer 10.0.0.3 as-number 65001 </span><br><span class="line"> peer 10.0.0.3 connect-interface LoopBack0</span><br><span class="line"> peer 172.16.14.4 as-number 65002 </span><br><span class="line"> #</span><br><span class="line"> ipv4-family unicast</span><br><span class="line">  undo synchronization</span><br><span class="line">  peer 10.0.0.3 enable</span><br><span class="line">  peer 172.16.14.4 enable</span><br><span class="line">#</span><br><span class="line">return</span><br><span class="line">[AR1-bgp]q</span><br><span class="line">[AR1]q</span><br></pre></td></tr></table></figure><p>对于AR4，我们还需要配置一下router-id。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR4&gt;sys</span><br><span class="line">Enter system view, return user view with Ctrl+Z.</span><br><span class="line">[AR4]bgp 65002</span><br><span class="line">[AR4-bgp]peer 172.16.14.1 as-number 65001</span><br><span class="line">[AR4-bgp]router-id 10.0.0.4</span><br><span class="line">[AR4-bgp]dis th</span><br><span class="line">[V200R003C00]</span><br><span class="line">#</span><br><span class="line">bgp 65002</span><br><span class="line"> router-id 10.0.0.4</span><br><span class="line"> peer 172.16.14.1 as-number 65001 </span><br><span class="line"> #</span><br><span class="line"> ipv4-family unicast</span><br><span class="line">  undo synchronization</span><br><span class="line">  peer 172.16.14.1 enable</span><br><span class="line">#</span><br><span class="line">return</span><br><span class="line">[AR4-bgp]q</span><br><span class="line">[AR4]q</span><br></pre></td></tr></table></figure><p>过了一会儿，我们就能看到这样的提示了：</p><blockquote><p>Mar 24 2026 09:35:40-08:00 AR1 %%01BGP&#x2F;3&#x2F;STATE_CHG_UPDOWN(l)[0]:The status of the peer 172.16.14.4 changed from OPENCONFIRM to ESTABLISHED. (InstanceName&#x3D;Public, StateChangeReason&#x3D;Up) </p><p>Mar 24 2026 09:35:41-08:00 AR4 %%01BGP&#x2F;3&#x2F;STATE_CHG_UPDOWN(l)[0]:The status of the peer 172.16.14.1 changed from OPENCONFIRM to ESTABLISHED. (InstanceName&#x3D;Public, StateChangeReason&#x3D;Up)</p></blockquote><p>这就说明这个eBGP peer邻居也建立好了。</p><p>我们可以分别在AR1和AR4上执行dis bgp peer看一眼：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis bgp peer</span><br><span class="line"></span><br><span class="line"> BGP local router ID : 10.0.0.1</span><br><span class="line"> Local AS number : 65001</span><br><span class="line"> Total number of peers : 2  Peers in established state : 2</span><br><span class="line"></span><br><span class="line">  Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State PrefRcv</span><br><span class="line"></span><br><span class="line">  10.0.0.3        4       65001      972      974     0 16:10:40 Established    0</span><br><span class="line">  172.16.14.4     4       65002        3        5     0 00:01:21 Established    0</span><br><span class="line"></span><br><span class="line">&lt;AR4&gt;dis bgp peer</span><br><span class="line"></span><br><span class="line"> BGP local router ID : 10.0.0.4</span><br><span class="line"> Local AS number : 65002</span><br><span class="line"> Total number of peers : 1  Peers in established state : 1</span><br><span class="line"></span><br><span class="line">  Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State PrefRcv</span><br><span class="line"></span><br><span class="line">  172.16.14.1     4       65001        3        3     0 00:01:45 Established    0</span><br></pre></td></tr></table></figure><p>接着，我们让AR4向AS65001宣告路由。我们可以先看看AR4的路由表：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR4&gt;dis  ip ro</span><br><span class="line">Route Flags: R - relay, D - download to fib</span><br><span class="line">------------------------------------------------------------------------------</span><br><span class="line">Routing Tables: Public</span><br><span class="line">         Destinations : 8        Routes : 8        </span><br><span class="line"></span><br><span class="line">Destination/Mask    Proto   Pre  Cost      Flags NextHop         Interface</span><br><span class="line"></span><br><span class="line">       10.0.0.4/32  Direct  0    0           D   127.0.0.1       LoopBack0</span><br><span class="line">      127.0.0.0/8   Direct  0    0           D   127.0.0.1       InLoopBack0</span><br><span class="line">      127.0.0.1/32  Direct  0    0           D   127.0.0.1       InLoopBack0</span><br><span class="line">127.255.255.255/32  Direct  0    0           D   127.0.0.1       InLoopBack0</span><br><span class="line">    172.16.14.0/24  Direct  0    0           D   172.16.14.4     GigabitEthernet0/0/1</span><br><span class="line">    172.16.14.4/32  Direct  0    0           D   127.0.0.1       GigabitEthernet0/0/1</span><br><span class="line">  172.16.14.255/32  Direct  0    0           D   127.0.0.1       GigabitEthernet0/0/1</span><br><span class="line">255.255.255.255/32  Direct  0    0           D   127.0.0.1       InLoopBack0</span><br></pre></td></tr></table></figure><p>BGP这个协议是不会主动对外广播路由条目的，除非你主动要求了。也就是说，需要用<code>network</code>或者<code>import-route</code>进行对外宣告，而且需要遵守BGP条目的产生原则。</p><p>然后我们在AR4上执行如下配置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[AR4]bgp 65002</span><br><span class="line">[AR4-bgp]network 10.0.0.4 32</span><br><span class="line">[AR4-bgp]import-route static</span><br></pre></td></tr></table></figure><p>这是在把路由注入到BGP中。我们可以在AR4上加入好几条静态路由，看看能不能发送过去。我们添加的静态路由如下，并进行了抓包：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[AR4]ip route-static 172.16.0.0 24 172.16.14.5</span><br><span class="line">[AR4]ip route-static 172.16.1.0 24 172.16.14.5</span><br><span class="line">[AR4]ip route-static 172.16.2.0 24 172.16.14.5</span><br><span class="line">[AR4]ip route-static 172.16.3.0 24 172.16.14.5</span><br></pre></td></tr></table></figure><p>我们上AR1再看一下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis bgp peer</span><br><span class="line"></span><br><span class="line"> BGP local router ID : 10.0.0.1</span><br><span class="line"> Local AS number : 65001</span><br><span class="line"> Total number of peers : 2  Peers in established state : 2</span><br><span class="line"></span><br><span class="line">  Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State PrefRcv</span><br><span class="line"></span><br><span class="line">  10.0.0.3        4       65001     1013     1020     0 16:51:22 Established    0</span><br><span class="line">  172.16.14.4     4       65002       49       46     0 00:42:03 Established    5</span><br></pre></td></tr></table></figure><p>请注意，通过<code>172.16.14.4</code>这个peer学习到的路由条目是5了！说明eBGP广播生效了！</p><p>接着，我们分别上AR1和AR3看看是不是这么回事：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR1&gt;dis bgp ro</span><br><span class="line"></span><br><span class="line"> BGP Local router ID is 10.0.0.1 </span><br><span class="line"> Status codes: * - valid, &gt; - best, d - damped,</span><br><span class="line">               h - history,  i - internal, s - suppressed, S - Stale</span><br><span class="line">               Origin : i - IGP, e - EGP, ? - incomplete</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> Total Number of Routes: 5</span><br><span class="line">      Network            NextHop        MED        LocPrf    PrefVal Path/Ogn</span><br><span class="line"></span><br><span class="line"> *&gt;   10.0.0.4/32        172.16.14.4     0                     0      65002i</span><br><span class="line"> *&gt;   172.16.0.0/24      172.16.14.5     0                     0      65002?</span><br><span class="line"> *&gt;   172.16.1.0/24      172.16.14.5     0                     0      65002?</span><br><span class="line"> *&gt;   172.16.2.0/24      172.16.14.5     0                     0      65002?</span><br><span class="line"> *&gt;   172.16.3.0/24      172.16.14.5     0                     0      65002?</span><br><span class="line"></span><br><span class="line">&lt;AR3&gt;dis bgp ro</span><br><span class="line"></span><br><span class="line"> BGP Local router ID is 10.0.0.3 </span><br><span class="line"> Status codes: * - valid, &gt; - best, d - damped,</span><br><span class="line">               h - history,  i - internal, s - suppressed, S - Stale</span><br><span class="line">               Origin : i - IGP, e - EGP, ? - incomplete</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> Total Number of Routes: 5</span><br><span class="line">      Network            NextHop        MED        LocPrf    PrefVal Path/Ogn</span><br><span class="line"></span><br><span class="line"> *&gt;i  10.0.0.4/32        172.16.14.4     0          100        0      65002i</span><br><span class="line"> *&gt;i  172.16.0.0/24      172.16.14.5     0          100        0      65002?</span><br><span class="line"> *&gt;i  172.16.1.0/24      172.16.14.5     0          100        0      65002?</span><br><span class="line"> *&gt;i  172.16.2.0/24      172.16.14.5     0          100        0      65002?</span><br><span class="line"> *&gt;i  172.16.3.0/24      172.16.14.5     0          100        0      65002?</span><br></pre></td></tr></table></figure><p>没错，都学到路由信息了！一条lo0通过network宣告，4条静态通过import-route宣告。我们还捕捉到了至关重要的Update包：</p><p><img src="/images/bgp_basic_update_packet.png"></p><p>可以看到，相关的更新信息都在这里实现的。至此，我们的BGP基础配置就顺利完成了！</p><p>最后，我们看一下聚合路由的配置。因为AR4发布了好多&#x2F;24的路由，条目不少，如果能聚合在一起，可以大幅降低路由条目数量。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[AR4-bgp]aggregate 172.16.0.0 22 detail-suppressed</span><br></pre></td></tr></table></figure><p>我们执行了路由聚合。这将导致对外发布的路由不再是明细路由，而是聚合后的结果。然后我们去AR3上看一下，发现的确如此：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;AR3&gt;dis bgp ro</span><br><span class="line"></span><br><span class="line"> BGP Local router ID is 10.0.0.3 </span><br><span class="line"> Status codes: * - valid, &gt; - best, d - damped,</span><br><span class="line">               h - history,  i - internal, s - suppressed, S - Stale</span><br><span class="line">               Origin : i - IGP, e - EGP, ? - incomplete</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> Total Number of Routes: 2</span><br><span class="line">      Network            NextHop        MED        LocPrf    PrefVal Path/Ogn</span><br><span class="line"></span><br><span class="line"> *&gt;i  10.0.0.4/32        172.16.14.4     0          100        0      65002i</span><br><span class="line"> *&gt;i  172.16.0.0/22      172.16.14.4                100        0      65002?</span><br></pre></td></tr></table></figure><p>所以，路由聚合的作用就是让BGP对外只宣告聚合后的条目，而不宣告明细路由。我们可以看到UPDATE条目：</p><p><img src="/images/bgp_basic_update_packet_delete.png"></p><p>以及新增路由：</p><p><img src="/images/bgp_basic_update_packet_add.png"></p><p>这就是BGP路由条目的“一拆一装”！</p><h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>至此，我们已经顺利完成了基础BGP的搭建，也看到了BGP路由是如何宣告出去的。目前应该对BGP的概念有所了解，知道iBGP、eBGP和IGP的区别和联系，之后应当在现网中加深理解，为后续路由反射、路径属性和路由优选打下坚实的基础。</p>]]>
    </content>
    <id>https://www.caiguu.cn/network/bgp/bgp_basic/</id>
    <link href="https://www.caiguu.cn/network/bgp/bgp_basic/"/>
    <published>2026-03-24T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>对IP与网络的基础有了初步的认知之后，我们要探索更加深入、更加复杂的内容了。首先要学习的就是BGP——边界网关协议。正是这个协议把世界从一个个局域网串联起来，形成我们众所周知的因特网，打破各个自治系统之间的隔阂，让世界互联成为可能。本实验基于华为HCIP教材以及eNSP进行]]>
    </summary>
    <title>BGP基础配置——一个简单的iBGP、eBGP和IGP联动拓扑搭建</title>
    <updated>2026-03-25T11:18:11.894Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="CTF入门" scheme="https://www.caiguu.cn/categories/CTF/"/>
    <category term="Web攻防" scheme="https://www.caiguu.cn/categories/CTF/web-attack-defense/"/>
    <category term="CTF" scheme="https://www.caiguu.cn/tags/CTF/"/>
    <category term="Web" scheme="https://www.caiguu.cn/tags/Web/"/>
    <category term="信息泄露" scheme="https://www.caiguu.cn/tags/%E4%BF%A1%E6%81%AF%E6%B3%84%E9%9C%B2/"/>
    <category term="php" scheme="https://www.caiguu.cn/tags/php/"/>
    <category term="vim" scheme="https://www.caiguu.cn/tags/vim/"/>
    <category term=".DS_Store" scheme="https://www.caiguu.cn/tags/DS-Store/"/>
    <category term="git" scheme="https://www.caiguu.cn/tags/git/"/>
    <category term="svn" scheme="https://www.caiguu.cn/tags/svn/"/>
    <category term="hg" scheme="https://www.caiguu.cn/tags/hg/"/>
    <content>
      <![CDATA[<p>我们正式进入Web攻防的学习！首先学习的第一个专题是信息泄露。目前的学习原则是，按照技能树进行推进，并通过这些题目掌握常见工具的使用方法。</p><h1 id="题单"><a href="#题单" class="headerlink" title="题单"></a>题单</h1><p>本次题目来自CTF Hub的技能树的<code>Web</code>-&gt;<code>信息泄露</code>部分，包括目录遍历、PHPINFO、备份文件下载、Git泄露、SVN泄露和HG泄露。</p><p><img src="/images/info_leakage.png" alt="信息泄露技能树总览"></p><h1 id="目录遍历"><a href="#目录遍历" class="headerlink" title="目录遍历"></a>目录遍历</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p>打开之后有一个按钮，写着“点击开始寻找flag”。点击一下，给了我们一个&#x2F;flag_in_here的文件夹。显然这是需要进行目录遍历了。当然去手动一个一个试肯定没问题，但如果文件很庞大呢？所以使用工具：dirserach，先扫一遍。由于我们重点关注特定的状态码，因此可以用下面的命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dirserach -u http://&lt;靶场URL&gt;/flag_in_here -i 200,301,302,403</span><br></pre></td></tr></table></figure><p>这样就可以让结果显示得比较简单，方便观察。</p><p><img src="/images/dir_search_dirsearch.png"></p><p>这样其实就锁定到了两个文件里，分别在2和4中。我们手动进去找，总能找到。果然在这里：</p><p><img src="/images/dir_search_flag.png"></p><p>flag就是<code>ctfhub{4a3c1a58ac30322ea60e1af0}</code>。官方题解其实给得特别简单，直接手动去搜就行了！当然，我看也有人写了个python脚本，挨个去找。</p><h1 id="PHPINFO"><a href="#PHPINFO" class="headerlink" title="PHPINFO"></a>PHPINFO</h1><h2 id="题目-1"><a href="#题目-1" class="headerlink" title="题目"></a>题目</h2><p>这道题目进去以后，可以查看phpinfo，flag就藏在这里。</p><p><img src="/images/phpinfo_flag.png"></p><p>这道题应该是想说明phpinfo的重要性，所以我们也扫一下，看这个文件会不会被提示出来。</p><p><img src="/images/phpinfo_dirsearch.png"></p><p>果然这个文件能够被提示出来！也就是说，我们需要关注这种搜索出来的、作用比较大的文件。</p><h1 id="备份文件下载"><a href="#备份文件下载" class="headerlink" title="备份文件下载"></a>备份文件下载</h1><h2 id="网站源码"><a href="#网站源码" class="headerlink" title="网站源码"></a>网站源码</h2><p>题目描述：当开发人员在线上环境中对源代码进行了备份操作，并且将备份文件放在了 web 目录下，就会引起网站源码泄露。</p><p>打开这个页面，给了一些提示。不过不管咋样，先扫一遍。当然，这个页面给的这些提示还是值得记录下来的：</p><p><strong>常见的网站源码备份文件后缀</strong></p><ul><li>tar</li><li>tar.gz</li><li>zip</li><li>rar</li></ul><p><strong>常见的网站源码备份文件名</strong></p><ul><li>web</li><li>website</li><li>backup</li><li>back</li><li>www</li><li>wwwroot</li><li>temp</li></ul><p>还真扫到了：</p><p><img src="/images/web_source_dissearch.png"></p><p>那么，看来这个备份文件不简单！我们给它下载下来！</p><p>可是，当我们下载下来，发现这三个文件都并不直接包含flag。有一个文件<code>flag_1768531291.txt</code>直接在文件里写道，<code>Where is flag?</code>，还开了嘲讽？我们要不按着这个路径回现网看看呢？果然！就是这样！找到flag了！</p><p><img src="/images/web_souece_flag.png"></p><h2 id="bak文件"><a href="#bak文件" class="headerlink" title="bak文件"></a>bak文件</h2><p>题目描述：当开发人员在线上环境中对源代码进行了备份操作，并且将备份文件放在了 web 目录下，就会引起网站源码泄露。</p><p>打开题目，醒目的一句话：<code>Flag in index.php source code.</code>。那我们就先找找这个文件呗？没有！这就是index.php。不管了，先扫一遍吧。</p><p><img src="/images/bak_dirsearch.png" alt="image-20260304下午40859117"></p><p>扫到了，那么我们看看这个备份文件会不会有提示？</p><p>下载下来这个文件，其内容如下：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>CTFHub 备份文件下载 - bak<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">// FLAG: ctfhub&#123;75383dc2840905aced557092&#125;</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">echo &quot;Flag in index.php source code.&quot;;</span></span><br><span class="line"><span class="meta">?&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><p>找到flag！本题搞定！</p><h2 id="vim缓存"><a href="#vim缓存" class="headerlink" title="vim缓存"></a>vim缓存</h2><p>题目描述：当开发人员在线上环境中使用 vim 编辑器，在使用过程中会留下 vim 编辑器缓存，当vim异常退出时，缓存会一直留在服务器上，引起网站源码泄露。</p><p>打开页面，依旧提示flag的位置。当然，肯定没那么简单。直接开扫。</p><p><img src="/images/vim_cache_dirsearch.png"></p><p>看起来并没有扫到什么有价值的信息。那么接下来，试试vim缓存吧。其文件名经常是：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">正常文件：index.php</span><br><span class="line">vim 缓存：.index.php.swp</span><br><span class="line">         .index.php.swo</span><br><span class="line">         .index.php.swn</span><br><span class="line">         index.php~（备份）</span><br></pre></td></tr></table></figure><p>恰好在<code>.index.php.swp</code>中找到了，然后我们可以运行以下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">file index.php.swp</span><br><span class="line">strings index.php.swp  | grep -i <span class="string">&quot;ctfhub&quot;</span></span><br></pre></td></tr></table></figure><p>找到flag了！</p><p><img src="/images/vim_cache_flag.png"></p><h3 id="vim缓存解析"><a href="#vim缓存解析" class="headerlink" title="vim缓存解析"></a>vim缓存解析</h3><p><strong>当你用 vim 编辑文件时，会产生三种类型的文件：</strong></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">原始文件：index.php</span><br><span class="line">├── 交换文件 (.swp)  —— 编辑时产生的临时文件</span><br><span class="line">├── 备份文件 (.bak)   —— 保存时的备份</span><br><span class="line">└── 撤销文件 (.un~)   —— 用于撤销操作</span><br></pre></td></tr></table></figure><p><strong>交换文件 (Swap Files)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">文件名格式：.filename.swp, .filename.swo, .filename.swn</span><br><span class="line">产生时机：打开文件时立即创建</span><br><span class="line">作用：保存编辑中的内容，防止数据丢失</span><br><span class="line">特点：文件存在就说明正在编辑或异常退出</span><br></pre></td></tr></table></figure><p><strong>备份文件 (Backup Files)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">文件名格式：filename~, filename.bak</span><br><span class="line">产生时机：保存文件时（如果设置了备份）</span><br><span class="line">作用：保留修改前的版本</span><br><span class="line">特点：取决于 vim 配置</span><br></pre></td></tr></table></figure><p><strong>撤销文件 (Undo Files)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">文件名格式：.filename.un~, .filename.un.swp</span><br><span class="line">产生时机：启用持久撤销功能时</span><br><span class="line">作用：保存编辑历史，支持跨会话撤销</span><br></pre></td></tr></table></figure><p><strong>viminfo 文件</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">文件名：.viminfo</span><br><span class="line">位置：用户主目录</span><br><span class="line">作用：记录命令行历史、搜索历史等</span><br></pre></td></tr></table></figure><p>为什么会存在.swp文件？一般是因为没有正常退出vim。如果正常退出了，那么这个.swp文件是会被删除掉的。而且这个不一定能被扫出来，所以如果感觉像是文件泄露的话，可以思考一下是不是和vim有关。</p><h2 id="DS-Store"><a href="#DS-Store" class="headerlink" title=".DS_Store"></a>.DS_Store</h2><p>题目描述：.DS_Store 是 Mac OS 保存文件夹的自定义属性的隐藏文件。通过.DS_Store可以知道这个目录里面所有文件的清单。</p><p>相同的流程，先扫一遍。</p><p><img src="/images/DS_Stroe_dirsearch.png"></p><p>扫出来了，直接下载这个文件，并调用工具去分析。</p><p><img src="/images/DS_Store_analyze.png"></p><p>找到了一个txt文件，看看是什么，打开就是flag！本题搞定！</p><h1 id="Git泄露"><a href="#Git泄露" class="headerlink" title="Git泄露"></a>Git泄露</h1><h2 id="Git泄露-1"><a href="#Git泄露-1" class="headerlink" title="Git泄露"></a>Git泄露</h2><h3 id="漏洞是怎么产生的？"><a href="#漏洞是怎么产生的？" class="headerlink" title="漏洞是怎么产生的？"></a>漏洞是怎么产生的？</h3><p>当开发者使用 Git 进行版本控制时，会在项目根目录生成一个 <strong><code>.git</code> 隐藏文件夹</strong>，里面记录了：</p><ul><li>所有的代码历史版本</li><li>每次提交的改动（diff）</li><li>提交者的信息</li><li>甚至可能包含被删除的敏感文件</li></ul><p>如果网站上线时，<strong>直接把 <code>.git</code> 文件夹也上传到了服务器</strong>，且没有做访问限制，那么任何人都可以通过 <code>http://target.com/.git/</code> 直接访问到这个目录 。</p><h3 id="攻击者能干什么？"><a href="#攻击者能干什么？" class="headerlink" title="攻击者能干什么？"></a>攻击者能干什么？</h3><p>攻击者可以利用这个漏洞：</p><ol><li><strong>下载整个 <code>.git</code> 目录</strong></li><li><strong>重建完整的项目源代码</strong></li><li><strong>查看提交历史（commit log）</strong></li><li><strong>恢复被删除的敏感文件</strong>（比如 flag）</li><li><strong>对比版本差异，找到隐藏的信息</strong></li></ol><h2 id="GitHack工具"><a href="#GitHack工具" class="headerlink" title="GitHack工具"></a>GitHack工具</h2><p>GitHack 的工作原理是 ：</p><ol><li>解析远程 <code>.git/index</code> 文件，找到所有文件名和对应的 SHA1 值</li><li>根据 SHA1 去 <code>.git/objects/</code> 下载对应的文件</li><li>用 zlib 解压，按原始目录结构重建源代码</li></ol><p><strong>优点</strong>：不需要在本地安装 Git，只要有 Python 就能跑。</p><h2 id="Log"><a href="#Log" class="headerlink" title="Log"></a>Log</h2><p>题目描述：当前大量开发人员使用git进行版本控制，对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。请尝试使用BugScanTeam的GitHack完成本题。</p><p>打开这道题，什么都没有，可以先扫一遍。直接就扫出来了一大堆和Git相关的文件。</p><p><img src="/images/git_log_dirsearch.png"></p><p>然后根据题目提示使用GitHack工具，其下载地址为<a href="https://github.com/BugScanTeam/GitHack%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E6%98%AF%E7%9B%B4%E6%8E%A5%E8%BF%90%E8%A1%8C%60GitHack.py%60%EF%BC%8C%E6%97%A0%E9%9C%80%E5%AE%89%E8%A3%85%E5%85%B6%E4%BB%96%E4%BE%9D%E8%B5%96%E9%A1%B9%E3%80%82">https://github.com/BugScanTeam/GitHack，使用方法是直接运行`GitHack.py`，无需安装其他依赖项。</a></p><p>既然扫到了这么多git相关的内容，那么我们运行如下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python GitHack.py http://&lt;target&gt;/.git</span><br></pre></td></tr></table></figure><p>但是我们会发现，BugScan的GitHack只支持Python2，在我们的Python3环境下已经是不可用状态了。所以我们找了一个替换工具：GitHacker，地址为<a href="https://github.com/WangYihang/GitHacker%E3%80%82">https://github.com/WangYihang/GitHacker。</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip install GitHacker</span><br><span class="line">githacker --url http://&lt;target&gt;/.git --output-folder &lt;OUTPUT_FOLDER&gt;</span><br></pre></td></tr></table></figure><p>运行完此工具后，会在指定文件夹下看到.git文件，我们就可以在这个文件夹里寻找一些有用的东西了。</p><p>最常见的题型就是查看git log。</p><p><img src="/images/git_log_githacker.png"></p><p>所以我们可以看到8dcf那次提交是存在flag的！我们现在需要变更到8dcf这次提交！</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset --hard &lt;commit_id&gt;</span><br></pre></td></tr></table></figure><p><img src="/images/git_log_flag.png"></p><p>变更之后，就发现了flag文件！本题搞定！</p><h2 id="Stack"><a href="#Stack" class="headerlink" title="Stack"></a>Stack</h2><p>题目描述：当前大量开发人员使用git进行版本控制，对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。请尝试使用BugScanTeam的GitHack完成本题。</p><p><code>git stash</code> 是 Git 的一个非常有用的命令，用于<strong>临时保存当前工作目录的修改</strong>，让你可以切换到其他分支（或者做其他操作），稍后再回来恢复这些修改。</p><p><strong>通俗理解</strong>：</p><blockquote><p>你正在写代码，写到一半突然要去修一个紧急 bug，但又不想提交现在的半成品。于是你 <code>git stash</code> 把当前修改存到“抽屉”里，等修完 bug 再 <code>git stash pop</code> 从抽屉里拿出来继续写。</p></blockquote><p>这题我们也可以先扫一下。也是扫出来了好多和Git相关的文件。所以我们还是用GitHacker下载一下。下载后，查看git log，和上一道题目一样，所以我们也需要先恢复到那个分支。但是！就在那个类似的文件下，居然内容变了，开了嘲讽：</p><p><img src="/images/git_stack_fail.png"></p><p>问得好，where is flag？既然最常见的git log不行，就要考虑git stash了。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git stash list</span><br><span class="line">git stash show stash@&#123;0&#125;</span><br><span class="line">git stash show -p stash@&#123;0&#125;</span><br></pre></td></tr></table></figure><p>返回</p><blockquote><p>stash@{0}: WIP on master: 42e8390 add flag</p></blockquote><p>这就是很关键的信息，我们接下来查看一下这个stash：</p><p><img src="/images/git_stash_flag.png"></p><p>找到flag了！</p><p>这个题目可以说是还用了假flag来增加挑战性。值得注意的是git stash是全局的，因此无需切换分支，可以直接执行这个命令。也就是说，出题者加了那个txt后，把内容是where is flag的版本正式提交到了master，后来把这个文件内容改成了正确的flag，但并没实际提交，而是使用stash做了个暂存。这就是我们能在stash中看到它的原因。</p><h2 id="Index"><a href="#Index" class="headerlink" title="Index"></a>Index</h2><p>题目描述：当前大量开发人员使用git进行版本控制，对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。请尝试使用BugScanTeam的GitHack完成本题。</p><h3 id="什么是-Git-Index？"><a href="#什么是-Git-Index？" class="headerlink" title="什么是 Git Index？"></a>什么是 Git Index？</h3><p>Index（也叫暂存区）是 Git 的三个组成部分之一：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">工作区 (Working Directory) → 暂存区 (Index) → 版本库 (Repository)</span><br><span class="line">    你修改的文件            git add 后的位置     git commit 后的位置</span><br></pre></td></tr></table></figure><p><strong>Index 里存的是</strong>：下一次要提交的内容快照。</p><p>依旧先扫一下。还是输出了很多git相关的，因此用GitHacker工具去下载一下。然后git log发现当前版本已经是增加了flag的。直接ls发现文本文件，这个就是flag了。</p><p><img src="/images/git_index.png"></p><p>这个可能是因为GitHacker直接帮我从暂存区里恢复了文件。如果工具没有这么做，那么需要手动执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 先看暂存区有什么文件</span></span><br><span class="line">git ls-files --stage</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出：</span></span><br><span class="line"><span class="comment"># 100644 fcdc85b6da930352e99e604b774f8a7dfbb97b6c 0234392428823689.txt</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 用 SHA1 取出文件内容</span></span><br><span class="line">git cat-file -p fcdc85b6da930352e99e604b774f8a7dfbb97b6c</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 直接就看到 flag 了！</span></span><br><span class="line">ctfhub&#123;XXX&#125;</span><br></pre></td></tr></table></figure><h1 id="SVN泄露"><a href="#SVN泄露" class="headerlink" title="SVN泄露"></a>SVN泄露</h1><p>题目描述：当开发人员使用 SVN 进行版本控制，对站点自动部署。如果配置不当,可能会将.svn文件夹直接部署到线上环境。这就引起了 SVN 泄露漏洞。</p><p>SVN（Subversion）是程序员常用的<strong>集中式版本控制系统</strong>。当你使用 <code>svn checkout</code> 检出代码时，会在项目目录下自动生成一个 <strong><code>.svn</code>隐藏文件夹</strong>，里面记录了：</p><ul><li>所有文件的版本历史</li><li>源代码的完整副本</li><li>提交记录、作者信息</li><li>服务器地址、用户名等元数据</li></ul><p>先扫一下。能够扫出来和svn相关的东西。</p><p><img src="/images/git_svn_dirsearch.png"></p><p>可以扫到好多和SVN相关的东西，所以本题肯定是考虑SVN泄露了。</p><p>对于这种SVN的题，第一步是确认版本，高版本和低版本对应着不同的方法。我们先访问一下<code>http://http://challenge-15c62b156835dbb5.sandbox.ctfhub.com:10800/.svn/entries</code>。如果文件内容是一个数字，如<code>12</code>，那就是高版本。如果返回类似如下内容，就是低版本：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">dir</span><br><span class="line">https://svn-server...</span><br><span class="line">index.php</span><br><span class="line">flag.txt</span><br></pre></td></tr></table></figure><p>低版本的话就很简单了，只需要下载<code>curl http://目标/.svn/text-base/flag.txt.svn-base</code>目标文件就行了。</p><p>但如果是高版本的话，就会麻烦很多，建议使用工具来做。</p><p>DVCS-Ripper工具：<a href="https://github.com/kost/dvcs-ripper">https://github.com/kost/dvcs-ripper</a></p><p>这个工具是Perl构造的，能够下载wc.db并解析；根据哈希值构造下载路径并恢复完整的目录结构。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">perl rip-svn.pl -v -u http://&lt;target&gt;/.svn       </span><br></pre></td></tr></table></figure><p>我们运行这个工具，让它解析一下。然后我们发现在当前文件夹下多了个<code>.svn</code>，这就是下载下来的。</p><p>我们可以运行tree命令看一下这个.svn的结构：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">.svn</span><br><span class="line">├── entries</span><br><span class="line">├── format</span><br><span class="line">├── pristine</span><br><span class="line">│   ├── 08</span><br><span class="line">│   │   └── 08171693cbd333701b525415321f2a29715066c2.svn-base</span><br><span class="line">│   └── bf</span><br><span class="line">│       └── bf45c36a4dfb73378247a6311eac4f80f48fcb92.svn-base</span><br><span class="line">├── text-base</span><br><span class="line">├── tmp</span><br><span class="line">└── wc.db</span><br></pre></td></tr></table></figure><p>其中，<code>pristine</code> 是 <strong>“原始的、未修改的”</strong> 的意思。在 SVN 中，<code>pristine</code> 目录就是 <strong>“文件的原始备份仓库”</strong>。SVN 会把所有文件的原始备份，用 <strong>SHA1 哈希值</strong> 作为文件名，存放在 <code>pristine/</code> 目录下。</p><p>我们可以直接用grep命令在这里搜索一下有没有flag：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">grep -a -r <span class="string">&quot;flag\|ctfhub\|Cyberpeace&quot;</span> pristine/</span><br><span class="line">pristine/08/08171693cbd333701b525415321f2a29715066c2.svn-base:ctfhub&#123;51888007d75837dc89cbf1cb&#125;</span><br></pre></td></tr></table></figure><p>本题搞定！</p><h1 id="HG泄露"><a href="#HG泄露" class="headerlink" title="HG泄露"></a>HG泄露</h1><p>题目描述：当开发人员使用 Mercurial 进行版本控制，对站点自动部署。如果配置不当,可能会将.hg 文件夹直接部署到线上环境。这就引起了 hg 泄露漏洞。</p><p>我们还是先扫一遍。</p><p><img src="/images/hg_dirsearch.png"></p><p>扫完之后，发现基本都是HG相关的，考虑HG泄漏。</p><p>值得注意的是，<code>dvcs-ripper</code>自带hg分析工具。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">perl rip-hg.pl -u http://challenge-6040f85097a0280f.sandbox.ctfhub.com:10800/.hg/</span><br><span class="line">[i] Getting correct 404 responses</span><br><span class="line">cannot find hg: No such file or directory at rip-hg.pl line 140.</span><br></pre></td></tr></table></figure><p>我们用grep搜索不到flag相关的内容，我们用<code>grep manifest</code>先查看一下。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">(base) caiguu@JACKERZHANG-MB0 .hg % hg manifest</span><br><span class="line">50x.html</span><br><span class="line">flag_28468252.txt</span><br><span class="line">index.html</span><br><span class="line">(base) caiguu@JACKERZHANG-MB0 .hg % <span class="built_in">cat</span> flag_28468252.txt</span><br><span class="line"><span class="built_in">cat</span>: flag_28468252.txt: No such file or directory</span><br></pre></td></tr></table></figure><p>因为dvcs-ripper只下载元数据，但我们不妨直接在网络环境下访问这个文件：</p><p><img src="/images/hg_flag.png"></p><p>本题搞定。后续如果遇到HG泄露相关的题目还会继续深入探索一下。而且官方题解也说了“不要过分迷信工具。”工具只能给提供一个方向，具体的细节，不要放弃动手解决！</p><h1 id="题型总结"><a href="#题型总结" class="headerlink" title="题型总结"></a>题型总结</h1><p>至此，把CTF Hub中关于信息泄露的题目全都过完了。包括目录遍历、PHPINFO、备份文件下载、Git泄漏、SVN泄露和HG泄漏。主要的思路就是先F12看看源代码有没有东西，然后拿dirsearch扫一遍，看有没有敏感文件。除了vim缓存以外，其他的泄漏基本都能扫出来。如果看到了扫出来的东西，那么使用对应工具去进行处理就好了。也看到了一些弯弯绕，例如git当前版本开了嘲讽，但是在暂存区里就是正解。所以如果能定位到信息泄露的话，结合相关的工具去多试一试，一般就能找到结果了。</p><p>这也是我学习CTF的第一个专题，进展还是很快的。万事开头难，我觉得这个开头可以说是非常不错了！</p>]]>
    </content>
    <id>https://www.caiguu.cn/CTF/web-attack-defense/ctf-info-leakage/</id>
    <link href="https://www.caiguu.cn/CTF/web-attack-defense/ctf-info-leakage/"/>
    <published>2026-03-04T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>我们正式进入Web攻防的学习！首先学习的第一个专题是信息泄露。目前的学习原则是，按照技能树进行推进，并通过这些题目掌握常见工具的使用方法。</p>
<h1 id="题单"><a href="#题单" class="headerlink" title="题单"></a>题单<]]>
    </summary>
    <title>CTF信息泄露入门题-Writeup</title>
    <updated>2026-03-05T03:02:57.647Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="CTF入门" scheme="https://www.caiguu.cn/categories/CTF/"/>
    <category term="Web攻防" scheme="https://www.caiguu.cn/categories/CTF/web-attack-defense/"/>
    <category term="CTF" scheme="https://www.caiguu.cn/tags/CTF/"/>
    <category term="Web" scheme="https://www.caiguu.cn/tags/Web/"/>
    <content>
      <![CDATA[<p>在进行Web攻防之前，有必要对HTTP的基础进行巩固，掌握必备的基础技能，为面对更多更复杂的问题打下基础。</p><h1 id="题目列表"><a href="#题目列表" class="headerlink" title="题目列表"></a>题目列表</h1><p>题目均来自于CTF Hub，在<code>技能树</code>-&gt;<code>Web</code>-&gt;<code>Web前置技能</code>-&gt;<code>HTTP协议</code>中即可获取到本题单。</p><ul><li>Cookie</li><li>请求方式</li><li>302跳转</li><li>基础认证</li><li>响应包源代码</li></ul><h1 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h1><p>题目描述：Cookie欺骗、认证、伪造</p><p>本题点开页面，提示“只有管理员才能访问”，然后F12看发送的请求，里面有一个Cookie选项，其中内容是<code>admin=0</code>。那我们发送一个Cookie内容为<code>admin=1</code>的包即可解开本题。</p><p><img src="/images/cookie_flag_1.png"></p><h1 id="请求方式"><a href="#请求方式" class="headerlink" title="请求方式"></a>请求方式</h1><p>题目描述：HTTP 请求方法, HTTP&#x2F;1.1协议中共定义了八种方法（也叫动作）来以不同方式操作指定的资源。</p><h2 id="HTTP-1-1八种请求方法"><a href="#HTTP-1-1八种请求方法" class="headerlink" title="HTTP&#x2F;1.1八种请求方法"></a>HTTP&#x2F;1.1八种请求方法</h2><p>我们先了解一下是哪几种请求方法。</p><table><thead><tr><th align="left">方法</th><th align="left">是否幂等</th><th align="left">是否有请求体</th><th align="left">是否有响应体</th><th align="left">主要用途</th></tr></thead><tbody><tr><td align="left">GET</td><td align="left">是</td><td align="left">否</td><td align="left">是</td><td align="left">获取资源</td></tr><tr><td align="left">POST</td><td align="left">否</td><td align="left">是</td><td align="left">是</td><td align="left">提交数据</td></tr><tr><td align="left">PUT</td><td align="left">是</td><td align="left">是</td><td align="left">否</td><td align="left">上传文件</td></tr><tr><td align="left">DELETE</td><td align="left">是</td><td align="left">否</td><td align="left">否</td><td align="left">删除资源</td></tr><tr><td align="left">HEAD</td><td align="left">是</td><td align="left">否</td><td align="left">否</td><td align="left">获取元信息</td></tr><tr><td align="left">OPTIONS</td><td align="left">是</td><td align="left">否</td><td align="left">是</td><td align="left">查询支持方法</td></tr><tr><td align="left">TRACE</td><td align="left">是</td><td align="left">否</td><td align="left">是</td><td align="left">回显请求</td></tr><tr><td align="left">CONNECT</td><td align="left">否</td><td align="left">否</td><td align="left">是</td><td align="left">建立隧道</td></tr></tbody></table><h2 id="题目解析"><a href="#题目解析" class="headerlink" title="题目解析"></a>题目解析</h2><p>打开题目，显示的内容是需要使用CTFH**B方法进行请求页面，但是这个不好在HackBar或者POSTMAN里改。不过有一种办法，那就是用CURL命令。</p><p><img src="/images/request_method_flag.png"></p><p>直接就找到Flag了！所以像这种自定义访问方法的，可以直接考虑用CURL工具。</p><h2 id="CURL工具"><a href="#CURL工具" class="headerlink" title="CURL工具"></a>CURL工具</h2><p><strong>curl</strong> 是一个利用 URL 语法在命令行下工作的<strong>文件传输工具</strong>，支持 HTTP、HTTPS、FTP 等几十种协议。在 CTF 中，我们主要用它来<strong>发送自定义的 HTTP 请求</strong>。</p><table><thead><tr><th align="left">参数</th><th align="left">作用</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><code>-X</code></td><td align="left">指定请求方法</td><td align="left"><code>curl -X PUT http://target.com/</code></td></tr><tr><td align="left"><code>-H</code></td><td align="left">添加请求头</td><td align="left"><code>curl -H &quot;Referer: google.com&quot; http://target.com/</code></td></tr><tr><td align="left"><code>-d</code></td><td align="left">发送 POST 数据</td><td align="left"><code>curl -d &quot;key=val&quot; http://target.com/</code></td></tr><tr><td align="left"><code>-b</code></td><td align="left">发送 Cookie</td><td align="left"><code>curl -b &quot;name=value&quot; http://target.com/</code></td></tr><tr><td align="left"><code>-c</code></td><td align="left">保存 Cookie</td><td align="left"><code>curl -c cookies.txt http://target.com/</code></td></tr><tr><td align="left"><code>-I</code></td><td align="left">只显示响应头</td><td align="left"><code>curl -I http://target.com/</code></td></tr><tr><td align="left"><code>-i</code></td><td align="left">显示完整响应信息</td><td align="left"><code>curl -i http://target.com/</code></td></tr><tr><td align="left"><code>-v</code></td><td align="left">显示详细信息</td><td align="left"><code>curl -v http://target.com/</code></td></tr><tr><td align="left"><code>-o</code></td><td align="left">保存到文件</td><td align="left"><code>curl -o output.txt http://target.com/</code></td></tr><tr><td align="left"><code>-L</code></td><td align="left">跟随重定向</td><td align="left"><code>curl -L http://target.com/</code></td></tr><tr><td align="left"><code>-k</code></td><td align="left">允许不安全的 SSL</td><td align="left"><code>curl -k https://target.com/</code></td></tr></tbody></table><h1 id="302跳转"><a href="#302跳转" class="headerlink" title="302跳转"></a>302跳转</h1><h2 id="302重定向"><a href="#302重定向" class="headerlink" title="302重定向"></a>302重定向</h2><p>当你在浏览器访问一个网址，服务器返回302状态码时，意味着：</p><blockquote><p><strong>“你请求的资源暂时在别的地方，请去这个新地址访问”</strong></p></blockquote><p>浏览器收到302响应后，会自动跳转到服务器在<code>Location</code>头中指定的新URL。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">客户端（浏览器）               服务器</span><br><span class="line">    |                           |</span><br><span class="line">    |---- 请求 /old-page -----&gt; |</span><br><span class="line">    |                           |</span><br><span class="line">    |&lt;--- 302 Found ------------|</span><br><span class="line">    |    Location: /new-page    |</span><br><span class="line">    |                           |</span><br><span class="line">    |---- 请求 /new-page -----&gt; |</span><br><span class="line">    |                           |</span><br><span class="line">    |&lt;--- 200 OK ---------------|</span><br><span class="line">    |    返回新页面内容         |</span><br></pre></td></tr></table></figure><p>点击页面里的“Give me Flag”，还会跳转到当前页面，而不能访问到<code>index.php</code>。我们打开F12看看：</p><p><img src="/images/302.png"></p><p>说明这个请求被重定向到了index.html，于是index.php中隐藏的内容无法被显示。</p><p>但是，CURL是可以禁止重定向的，如果用CURL，直接秒了！</p><p><img src="/images/302_flag-2590549.png"></p><p>为什么会这样呢？因为浏览器和curl工具对于302行为的处理不同。</p><table><thead><tr><th align="left">工具</th><th align="left">对 302 重定向的默认行为</th><th align="left">结果</th></tr></thead><tbody><tr><td align="left"><strong>浏览器</strong></td><td align="left"><strong>自动跟随</strong>重定向</td><td align="left">你被转到 index.html，看不到 index.php 的内容</td></tr><tr><td align="left"><strong>curl</strong></td><td align="left"><strong>不自动跟随</strong>重定向</td><td align="left">直接显示 index.php 的原始响应（包含 Flag）</td></tr></tbody></table><p>我们可以更进一步，展示完整的响应信息：</p><p><img src="/images/302_full_response.png"></p><p>也就是说，标准的302响应信息不包括这个响应体，而是直接去告知浏览器做跳转，因此大家也都看不到这些包的内容，且浏览器也不会保留，F12也看不到。但是curl的话，这件事就会现原形了，所以我们就能得到藏在响应体里的flag。</p><h1 id="基本认证"><a href="#基本认证" class="headerlink" title="基本认证"></a>基本认证</h1><h2 id="什么是基本认证"><a href="#什么是基本认证" class="headerlink" title="什么是基本认证"></a>什么是基本认证</h2><p><strong>基本认证</strong>是 HTTP 协议中最简单、最原生的一种<strong>身份验证机制</strong>。它通过在 HTTP 请求头中携带用户名和密码，来证明客户端的身份。</p><p>当你访问一个需要基本认证的网站时，浏览器会弹出一个登录框，这就是 Basic Authentication 的典型表现。</p><p>请求流程也很简单：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">客户端（你）                 服务器</span><br><span class="line">    |                           |</span><br><span class="line">    |---- 请求 /admin --------&gt; |</span><br><span class="line">    |                           |</span><br><span class="line">    |&lt;--- 401 Unauthorized -----|</span><br><span class="line">    |    WWW-Authenticate: Basic|</span><br><span class="line">    |                           |</span><br><span class="line">    |---- 请求 /admin --------&gt; |</span><br><span class="line">    |    Authorization: Basic   |</span><br><span class="line">    |    (加密后的用户名:密码)    |</span><br><span class="line">    |                           |</span><br><span class="line">    |&lt;--- 200 OK ---------------|</span><br><span class="line">    |    返回/admin内容         |</span><br></pre></td></tr></table></figure><ul><li><strong>用户名和密码</strong>：用冒号连接（<code>username:password</code>）</li><li><strong>编码方式</strong>：Base64 编码（<strong>不是加密！</strong>）</li><li><strong>传输位置</strong>：放在请求头的 <code>Authorization</code> 字段</li></ul><p>然后放到请求头里，大概就是这样了：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">GET</span> <span class="string">/admin</span> <span class="meta">HTTP/1.1</span></span><br><span class="line"><span class="attribute">Host</span><span class="punctuation">: </span>target.com</span><br><span class="line"><span class="attribute">Authorization</span><span class="punctuation">: </span>Basic YWRtaW46MTIzNDU2</span><br></pre></td></tr></table></figure><h2 id="题目解析-1"><a href="#题目解析-1" class="headerlink" title="题目解析"></a>题目解析</h2><p>首先点击链接，弹出登录页面，这就是基本认证：</p><p><img src="/images/basic_authentication_problem.png"></p><p>同时，还有一个附件需要下载。里面列出了最常见的弱密码，看来是想让我们去做一个爆破。</p><p>那我直接按照admin进行尝试，终于，在尝试到qwerty的时候登录进来了，直接获取到了flag。</p><p>不过虽然这个题目很简单，但是我们还是值得看一看基础认证长什么样的。</p><p>这个是一个认证失败的请求：</p><p><img src="/images/basic_authentication_fail.png"></p><p>可以看到，在请求头中有一个Authorization，这个就是我们基本认证的发送方式。</p><p>而响应中，也给了一些提示：Do u know admin?这提示了我们用户名需要是admin。<code>realm</code>一个指示要使用的用户名&#x2F;密码的字符串。至少应该包括主机名，但是可能指示具有访问权限的用户或组。</p><p>然后按照密码本去爆破，终于得到了200 OK的包，验证通过了：</p><p><img src="/images/basic_authentication_OK.png"></p><p>所以这就是基本认证的基础题目。</p><h1 id="响应包源代码"><a href="#响应包源代码" class="headerlink" title="响应包源代码"></a>响应包源代码</h1><p>打开题目是一个贪吃蛇小游戏。不管他，打开F12，答案直接出来了。</p><p><img src="/images/response_flag.png" alt="image-20260304下午20044179"></p><p>这是最简单的一种题目，直接打开F12查看页面源代码，就有答案了！</p><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>这部分的内容相对来说比较简单，具备Web的基础即可轻松搞定。通过这几道题对Web尤其是HTTP的基础知识进行复习，可以为以后打下不错的基础。当前我的学习路线就是在题目中同步点亮技能树，例如不会专门去一次性搞定所有工具，而是根据某个题目的需要，如果我认为需要某个工具来帮我做一件事，那么我就会学习使用这个工具。我想这是一个比较能够长期发展的方案。</p>]]>
    </content>
    <id>https://www.caiguu.cn/CTF/web-attack-defense/ctf-http/</id>
    <link href="https://www.caiguu.cn/CTF/web-attack-defense/ctf-http/"/>
    <published>2026-03-03T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>在进行Web攻防之前，有必要对HTTP的基础进行巩固，掌握必备的基础技能，为面对更多更复杂的问题打下基础。</p>
<h1 id="题目列表"><a href="#题目列表" class="headerlink" title="题目列表"></a>题目列表</h1><p>题]]>
    </summary>
    <title>CTF中的HTTP基础-Writeup</title>
    <updated>2026-03-04T06:10:29.829Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="CTF入门" scheme="https://www.caiguu.cn/categories/CTF/"/>
    <category term="Web攻防" scheme="https://www.caiguu.cn/categories/CTF/web-attack-defense/"/>
    <category term="CTF" scheme="https://www.caiguu.cn/tags/CTF/"/>
    <category term="Web" scheme="https://www.caiguu.cn/tags/Web/"/>
    <content>
      <![CDATA[<p>今天开个新坑吧！其实这个坑是我从很早之前就一直想入的，但苦于一直没有合适的机会。但在现在，做数据网管已有一段时间，且对基础业务相对熟练以后，便具备了向这个方向靠拢的绝佳机会。于是找来了CTF做一个入门，先看看比较简单的CTF入门题单，看看以我当前的知识储备能不能解出来，也算是对于网络安全方向的一次初步探索。</p><h1 id="题单"><a href="#题单" class="headerlink" title="题单"></a>题单</h1><p>题单是攻防世界的Web方向入门题单，链接是<a href="https://adworld.xctf.org.cn/challenges/problem-set-index?id=25%E3%80%82">https://adworld.xctf.org.cn/challenges/problem-set-index?id=25。</a></p><p>题目内容包括以下10道题目。</p><table><thead><tr><th>题目编号</th><th>题目名称</th></tr></thead><tbody><tr><td>GFSJ0474</td><td>view_source</td></tr><tr><td>GFSJ0475</td><td>get_post</td></tr><tr><td>GFSJ0476</td><td>robots</td></tr><tr><td>GFSJ0477</td><td>backup</td></tr><tr><td>GFSJ0478</td><td>cookie</td></tr><tr><td>GFSJ0479</td><td>disabled_button</td></tr><tr><td>GFSJ0480</td><td>simple_js</td></tr><tr><td>GFSJ0481</td><td>xff_referer</td></tr><tr><td>GFSJ0482</td><td>weak_auth</td></tr><tr><td>GFSJ0484</td><td>command_execution</td></tr><tr><td>GFSJ0485</td><td>simple_php</td></tr></tbody></table><h1 id="GFSJ0474-view-source"><a href="#GFSJ0474-view-source" class="headerlink" title="GFSJ0474 view_source"></a>GFSJ0474 view_source</h1><p>题目描述：X老师让小宁同学查看一个网页的源代码，但小宁同学发现鼠标右键好像不管用了。</p><p>我们进入靶机，发现页面中只有一句话，同时这个页面屏蔽了右键功能。</p><p><img src="/images/view_source_problem.png" alt="image-20260303上午94606000"></p><p>这个其实问题不大，只要F12即可，或者显示-&gt;开发者-&gt;开发者工具即可。</p><p><img src="/images/view_source_developer_tools.png"></p><p>打开开发者工具，我们会发现Flag就在这里等着我们呢！</p><p><img src="/images/view_source_flag.png"></p><p><code>cyberpeace{c3e796156c7ad83ffe6eb19a009dbd77}</code>我们把这个flag输入，解题成功！</p><h1 id="GFSJ0475-get-post"><a href="#GFSJ0475-get-post" class="headerlink" title="GFSJ0475 get_post"></a>GFSJ0475 get_post</h1><p>题目描述：X老师告诉小宁同学HTTP通常使用两种请求方法，你知道是哪两种吗？</p><p>这道题目的描述都提示了我们，需要使用get和post请求来进行相关操作。我们进入靶机，可以看到它其实已经给了我们提示：</p><p><img src="/images/get_post_problem.png"></p><p>建议安装浏览器扩展<code>HackBar</code>，具备丰富功能。</p><p><img src="/images/get_post_get.png"></p><p>然后点击<code>EXECUTE</code>，就会看到这样的页面：</p><p><img src="/images/get_post_after_get.png"></p><p>所以我们接下来要通过POST方法发个请求：</p><p><img src="/images/get_post_post.png"></p><p>看得出来我换到了Firefox浏览器，并且用了Firefox的HackBar扩展。可以使用2.1.3版本的，这个是免费使用的。这样我们就得到了FLag！本题搞定！</p><h1 id="GFSJ0476-robots"><a href="#GFSJ0476-robots" class="headerlink" title="GFSJ0476 robots"></a>GFSJ0476 robots</h1><p>题目描述：X老师上课讲了Robots协议，小宁同学却上课打了瞌睡，赶紧来教教小宁Robots协议是什么吧。</p><p>这道题很明显是需要我们找到<code>robots.txt</code>这个文件的，这是用于限制爬虫行为的文件。所以，获取靶场之后直接在根目录下输入<code>/robots.txt</code>就可以了：</p><p><img src="/images/robots_robots.png"></p><p>然后我们看到了这个文件：<code>f1ag_1s_h3re.php</code>，也就是说只要我们来访问这个文件，就能找到flag的位置了！</p><p>接下来我们直接在根目录下访问这个文件。</p><p><img src="/images/robots_flag.png"></p><p>顺利找到flag，本题搞定。</p><h1 id="GFSJ0477-backup"><a href="#GFSJ0477-backup" class="headerlink" title="GFSJ0477 backup"></a>GFSJ0477 backup</h1><p>题目描述：X老师忘记删除备份文件，他派小宁同学去把备份文件找出来,一起来帮小宁同学吧！</p><p>进入靶场，实际上页面已经提示得非常清楚了！</p><p><img src="/images/backup_problem.png"></p><p>这个文件名是什么呢？可以直接搜索一下，这个文件的备份叫做<code>index.php.bak</code>。所以我们试着直接访问这个文件，会发现直接把这个文件给我们下载下来了。那就可以直接打开这个文件了：</p><p><img src="/images/backup_flag.png"></p><p>如果使用macOS自带的文本编辑打开请注意，需要在设置里关闭将HTML自动打开为网页的选项，这样才能直接显示源代码。我们这样就得到了flag，本题搞定！</p><h1 id="GFSJ0478-cookie"><a href="#GFSJ0478-cookie" class="headerlink" title="GFSJ0478 cookie"></a>GFSJ0478 cookie</h1><p>题目描述：X老师告诉小宁他在cookie里放了些东西，小宁疑惑地想：‘这是夹心饼干的意思吗？’</p><p>这个题目也很直白地告诉了大家需要找cookie。</p><p><img src="/images/cookie_problem.png" alt="image-20260303上午103343124"></p><p>Cookie就是访问网站时会存放在浏览器当中的、包含用户相关信息的键值对。主要用于会话管理、个性化设置以及追踪和记录。</p><p>如果我们打开F12追踪网络，可以轻松地发现Cookie的存在：</p><p><img src="/images/cookie_F12.png"></p><p>这个告诉了我们请访问<code>cookie.php</code>文件，所以我们去访问一下：</p><p><img src="/images/cookie_flag.png"></p><p>然后它提示我们看HTTP的响应消息，在响应头里有一个字段叫做Flag，这个就是我们要找的内容！本题搞定！</p><p>值得注意的是，服务器会通过Set-Cookie的方法来设置存放在浏览器当中的Cookie，然后浏览器再把这个Cookie通过请求头的方式发送给服务器，这就是通过Cookie进行交互的方案。</p><h1 id="GFSJ0479-disabled-button"><a href="#GFSJ0479-disabled-button" class="headerlink" title="GFSJ0479 disabled_button"></a>GFSJ0479 disabled_button</h1><p>题目描述：X老师今天上课讲了前端知识，然后给了大家一个不能按的按钮，小宁惊奇地发现这个按钮按不下去，到底怎么才能按下去呢？</p><p>实际上这个很简单，通过F12把按钮禁用给恢复掉就可以按下去了。</p><p><img src="/images/disabled_button_problem.png" alt="image-20260303上午104037782"></p><p>把这个<code>disabled=&quot;&quot;</code>删掉就可以按下去了。</p><p><img src="/images/disabled_button_flag.png"></p><p>找到flag！本题搞定！</p><h1 id="GFSJ0480-simple-js"><a href="#GFSJ0480-simple-js" class="headerlink" title="GFSJ0480 simple_js"></a>GFSJ0480 simple_js</h1><p>题目描述：小宁发现了一个网页，但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} )</p><p>这个题目看起来和js有关，我们先进靶场看看：</p><p><img src="/images/simple_js_problem.png"></p><p>看起来需要输入一个password，但是怎么找到呢？F12看看。</p><p>在head里发现了这样一段代码：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">dechiffre</span>(<span class="params">pass_enc</span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> pass = <span class="string">&quot;70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65&quot;</span>;</span><br><span class="line">    <span class="keyword">var</span> tab  = pass_enc.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line">            <span class="keyword">var</span> tab2 = pass.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);<span class="keyword">var</span> i,j,k,l=<span class="number">0</span>,m,n,o,p = <span class="string">&quot;&quot;</span>;i = <span class="number">0</span>;j = tab.<span class="property">length</span>;</span><br><span class="line">                    k = j + (l) + (n=<span class="number">0</span>);</span><br><span class="line">                    n = tab2.<span class="property">length</span>;</span><br><span class="line">                    <span class="keyword">for</span>(i = (o=<span class="number">0</span>); i &lt; (k = j = n); i++ )&#123;o = tab[i-l];p += <span class="title class_">String</span>.<span class="title function_">fromCharCode</span>((o = tab2[i]));</span><br><span class="line">                            <span class="keyword">if</span>(i == <span class="number">5</span>)<span class="keyword">break</span>;&#125;</span><br><span class="line">                    <span class="keyword">for</span>(i = (o=<span class="number">0</span>); i &lt; (k = j = n); i++ )&#123;</span><br><span class="line">                    o = tab[i-l];</span><br><span class="line">                            <span class="keyword">if</span>(i &gt; <span class="number">5</span> &amp;&amp; i &lt; k-<span class="number">1</span>)</span><br><span class="line">                                    p += <span class="title class_">String</span>.<span class="title function_">fromCharCode</span>((o = tab2[i]));</span><br><span class="line">                    &#125;</span><br><span class="line">    p += <span class="title class_">String</span>.<span class="title function_">fromCharCode</span>(tab2[<span class="number">17</span>]);</span><br><span class="line">    pass = p;<span class="keyword">return</span> pass;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">String</span>[<span class="string">&quot;fromCharCode&quot;</span>](<span class="title function_">dechiffre</span>(<span class="string">&quot;\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30&quot;</span>));</span><br><span class="line"></span><br><span class="line">h = <span class="variable language_">window</span>.<span class="title function_">prompt</span>(<span class="string">&#x27;Enter password&#x27;</span>);</span><br><span class="line"><span class="title function_">alert</span>( <span class="title function_">dechiffre</span>(h) );</span><br></pre></td></tr></table></figure><p>我们先大概读一读这个代码。其实这个函数很有问题，首先<code>dechiffre</code>函数获取一段字符串，这个字符串除了获取长度以外，好像什么用都没有！你看，后面的处理全都是用<code>pass</code>做的，说明你输入的东西没有任何作用。相当于它一直在处理<code>pass</code>这个硬编码的字符串。我们看这个pass很像ASCII码，所以不妨做个转换，得到<code>FAUX PASSWORD HAHA</code>，它还开了嘲讽！而我们不管输入什么，最终的输出都是这段嘲讽文字。所以说我们不能被困在上面看似复杂的逻辑中。但是我们关注到底下有一段十六进制，看看有没有突破口。</p><p>我们先把十六进制转换成十进制，得到：<code>55,56,54,79,115,69,114,116,107,49,50</code>。这个看起来又像是ASCII码的组合了，所以我们再次转换，得到：<code>786OsErtk12</code>。难道这个就是flag吗？再结合前面的提示，我们拼装成<code>Cyberpeace{786OsErtk12}</code>，提交，正确！本题搞定！</p><p>回顾这道题目，首先就是要判断出来上面的代码一直都在误导你，然后找到可疑的十六进制串，再对它进行一次十六进制转ASCII，发现是个十进制串，再次执行十进制转ASCII，并包装上开头的字符串，就得到了本题的flag。</p><h1 id="GFSJ0481-xff-referer"><a href="#GFSJ0481-xff-referer" class="headerlink" title="GFSJ0481 xff_referer"></a>GFSJ0481 xff_referer</h1><p>题目描述：X老师告诉小宁其实xff和referer是可以伪造的。</p><p>我们首先要明确什么是XFF和Referer。</p><h2 id="XFF-X-Forwarded-For"><a href="#XFF-X-Forwarded-For" class="headerlink" title="XFF(X_Forwarded_For)"></a>XFF(X_Forwarded_For)</h2><p>这个请求头用于识别通过HTTP代理或者负载均衡器连接到Web服务器的客户端原始IP地址。例如：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">X-Forwarded-For</span><span class="punctuation">: </span>203.0.113.195, 70.41.3.18, 150.172.23.5</span><br></pre></td></tr></table></figure><p>表明客户端真实 IP 是 203.0.113.195，经过了两个代理服务器（70.41.3.18 和 150.172.23.5）。</p><p>但是XFF是可以伪造的，不能完全信任。</p><h2 id="Referer"><a href="#Referer" class="headerlink" title="Referer"></a>Referer</h2><p>Referer 请求头告诉服务器<strong>当前请求是从哪个页面链接过来的</strong>（即来源页面 URL）。例如：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">Referer</span><span class="punctuation">: </span>https://www.google.com/search?q=网络安全</span><br></pre></td></tr></table></figure><p>表明这个页面是通过<code>https://www.google.com/search?q=网络安全</code>找到的。</p><h2 id="解题"><a href="#解题" class="headerlink" title="解题"></a>解题</h2><p>明确了这两个背景知识，我们就可以解题了。</p><p><img src="/images/xff_referer_problem.png"></p><p>这个简单，我们直接伪造一个XFF，就能让它的源IP是这个了！</p><p><img src="/images/xff_referer_xff.png"></p><p>伪造之后直接EXECUTE，如下：</p><p><img src="/images/xff_referer_after_xff.png"></p><p>说明我们还需要修改一下referer。改！</p><p><img src="/images/xff_referer_referer.png"></p><p>得到了flag，本题搞定！</p><p><img src="/images/xff_referer_flag.png"></p><h1 id="GFSJ0482-weak-auth"><a href="#GFSJ0482-weak-auth" class="headerlink" title="GFSJ0482 weak_auth"></a>GFSJ0482 weak_auth</h1><p>题目描述：小宁写了一个登陆验证页面，随手就设了一个密码。</p><p>难道是弱密码？我随手懵了一个admin、123456：</p><p><img src="/images/weak_auth_problem.png"></p><p>竟然直接进来了？！</p><p><img src="/images/weak_auth_flag.png"></p><p>看来就是弱密码暴力破解，本题搞定！</p><p>但是实际上本题不应该靠猜，而是应该靠密码本去暴力撞。不过本博客是体验博客，所以弱口令这个的规范做法还会单开一个文章来详细讲讲！</p><h1 id="GFSJ0484-command-execution"><a href="#GFSJ0484-command-execution" class="headerlink" title="GFSJ0484 command_execution"></a>GFSJ0484 command_execution</h1><p>题目描述：小宁写了个ping功能,但没有写waf,X老师告诉她这是非常危险的，你知道为什么吗。</p><p>我们进入靶场，发现是个ping功能。</p><p><img src="/images/command_execution_problem.png"></p><p>我们试一下ping一个127.0.0.1，看看什么反馈：</p><p><img src="/images/command_execution_ping.png"></p><p>看起来是执行了一个系统的命令。那如果我利用&amp;&amp;执行多个命令，且他又没做安全措施，那不就炸了？</p><p><img src="/images/command_execution_pwd.png"></p><p>我们发现这里的确存在问题！我们可以执行其他命令了！那这样就很危险了！</p><p>我们接下来可以试着执行一下搜索flag的命令，即<code>find / -name &quot;*flag*&quot;</code>，看看有没有对应文件。</p><p><img src="/images/command_execution_find.png"></p><p>然后我们在最底下发现了这么个文件：<code>/home/flag.txt</code>，就它了！</p><p><img src="/images/command_execution_flag.png"></p><p>找到flag了！本题搞定！</p><h1 id="GFSJ0485-simple-php"><a href="#GFSJ0485-simple-php" class="headerlink" title="GFSJ0485 simple_php"></a>GFSJ0485 simple_php</h1><p>题目描述：小宁听说php是最好的语言,于是她简单学习之后写了几行php代码。</p><p>这道题看起来是需要在给定的php代码中寻求突破口，看看能不能撞出来我们想要的东西。题目中给到了这样的代码：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="title function_ invoke__">show_source</span>(<span class="keyword">__FILE__</span>);</span><br><span class="line"><span class="keyword">include</span>(<span class="string">&quot;config.php&quot;</span>);</span><br><span class="line"><span class="variable">$a</span>=@<span class="variable">$_GET</span>[<span class="string">&#x27;a&#x27;</span>];</span><br><span class="line"><span class="variable">$b</span>=@<span class="variable">$_GET</span>[<span class="string">&#x27;b&#x27;</span>];</span><br><span class="line"><span class="keyword">if</span>(<span class="variable">$a</span>==<span class="number">0</span> <span class="keyword">and</span> <span class="variable">$a</span>)&#123;</span><br><span class="line">    <span class="keyword">echo</span> <span class="variable">$flag1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span>(<span class="title function_ invoke__">is_numeric</span>(<span class="variable">$b</span>))&#123;</span><br><span class="line">    <span class="keyword">exit</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span>(<span class="variable">$b</span>&gt;<span class="number">1234</span>)&#123;</span><br><span class="line">    <span class="keyword">echo</span> <span class="variable">$flag2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">?&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>哪怕我不懂PHP，我也应该具备解出来这道题的能力——在计算机和网络领域我并不是零基础。我们发现，这段代码会接收两个变量a和b，然后对a和b做了一些逻辑判断，并返回两个flag变量。</p><p>a需要是0，同时还不能是false，这要怎么做？这涉及到PHP的一个特性，那就是弱类型比较。也就是说，如果a是”0”，就既可以满足$a&#x3D;&#x3D;0，又满足$a本身不是false。</p><p>而b呢，不许是纯数字，还要大于1234。这涉及到PHP的另一个特性，那就是如果b是一串数字+一些字母，那就满足既不是纯数字，又在这个比较中大于1234。这些利用到的PHP特性会在后面专门学习，这里仅做一个了解。</p><p>所以我们可以构造请求了：</p><p><img src="/images/simple_php_flag.png"></p><p>找到flag了！本题搞定！</p><h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>就在刚刚，我把CTF的Web入门题单的题目过了一遍，绝大多数自己就能直接做出来，毕竟还是有不少在网络领域的基础知识的积累。而有的题目需要参考一下其他人的Writeup或者了解一些额外的知识。但无论如何，我认为通过CTF去学习网络安全，对我目前的阶段来说，比直接系统性学习要更实在得多——我具备相关的基础，但缺乏实战经验。而无论这个题单多么简单，迈出这一步去写了第一个属于自己的Writeup就是好的。我也期待能够以今天的这次探索和这篇博文作为我进入网络安全领域的敲门砖，更期待着以后能够探索到更精彩的世界。</p>]]>
    </content>
    <id>https://www.caiguu.cn/CTF/web-attack-defense/hello-ctf/</id>
    <link href="https://www.caiguu.cn/CTF/web-attack-defense/hello-ctf/"/>
    <published>2026-03-02T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>今天开个新坑吧！其实这个坑是我从很早之前就一直想入的，但苦于一直没有合适的机会。但在现在，做数据网管已有一段时间，且对基础业务相对熟练以后，便具备了向这个方向靠拢的绝佳机会。于是找来了CTF做一个入门，先看看比较简单的CTF入门题单，看看以我当前的知识储备能不能解出来，也算]]>
    </summary>
    <title>CTF初探！Web攻防入门题Writeup</title>
    <updated>2026-03-03T06:00:34.412Z</updated>
  </entry>
  <entry>
    <author>
      <name>Jack Zhang</name>
    </author>
    <category term="网站维护" scheme="https://www.caiguu.cn/categories/website/"/>
    <category term="建站历程" scheme="https://www.caiguu.cn/categories/website/building/"/>
    <category term="Hexo" scheme="https://www.caiguu.cn/tags/hexo/"/>
    <content>
      <![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>时光真的好快哦！转眼间，我就从学生成为了一名上班族，走上了工作岗位。而我能够从事网络相关的工作，我本人是非常意外的。我想我大概率会成为一名软件研发工程师吧，但我的确做上了网络相关的工作。我想，这的确就是我和网络有缘吧。</p><p>经历了刚刚入职时什么都不会、业务做不完需要经常加班的阵痛期，我现在可以拥有更多的时间来思考、学习、输出，况且折腾一个新的blog就是继续熟悉网络、云计算的一个极好现实教程，于是我就有了再开一套博客的想法。我之前的<a href="http://caiguu.top/">博客</a>是基于Wordpress的，然而即便用了Markdown的插件，也需要对每篇文章进行一些微调。恰好我在2020年暑期基于Github Pages搭建过另一套博客，所以我这次想，能不能再搞一套服务器，点滴记录我工作以后的成长。</p><p>那么，就让我们开始吧！</p><h1 id="本地搭建Hexo"><a href="#本地搭建Hexo" class="headerlink" title="本地搭建Hexo"></a>本地搭建Hexo</h1><h2 id="安装Hexo"><a href="#安装Hexo" class="headerlink" title="安装Hexo"></a>安装Hexo</h2><p>第一步就是搭建本地的Hexo。由于我是MacBook，通过Homebrew安装一些前置项即可：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">brew install git</span><br><span class="line">git --version</span><br><span class="line">brew install node</span><br><span class="line">node --version  <span class="comment"># 应显示 v20.19.0 或更高</span></span><br><span class="line">npm --version   <span class="comment"># 应显示 10.x 或更高</span></span><br></pre></td></tr></table></figure><p>如果想要用Homebrew安装最新版的node.js，如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Download and install Homebrew</span></span><br><span class="line">curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash</span><br><span class="line"></span><br><span class="line"><span class="comment"># Download and install Node.js:</span></span><br><span class="line">brew install node@24</span><br><span class="line"></span><br><span class="line"><span class="comment"># Verify the Node.js version:</span></span><br><span class="line">node -v <span class="comment"># Should print &quot;v24.13.1&quot;.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Verify npm version:</span></span><br><span class="line">npm -v <span class="comment"># Should print &quot;11.8.0&quot;.</span></span><br></pre></td></tr></table></figure><p>有一个小坑，如果你的系统里有多个版本的node.js，那么可能用的是老版本的，需要你调整PATH让homebrew安装的node.js优先级最高：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">which</span> -a node <span class="comment"># 如果你观察到了多个版本，则可能需要调整</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;export PATH=&quot;/opt/homebrew/opt/node@24/bin:$PATH&quot;&#x27;</span> &gt;&gt; ~/.zshrc</span><br><span class="line">soruce ~/.zshrc</span><br></pre></td></tr></table></figure><p>接着就可以安装Hexo了：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g hexo-cli</span><br></pre></td></tr></table></figure><p>我们可以验证是否安装成功：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo --version</span><br></pre></td></tr></table></figure><p>其输出了版本，证明搭建成功。</p><h2 id="本地Hexo初始化"><a href="#本地Hexo初始化" class="headerlink" title="本地Hexo初始化"></a>本地Hexo初始化</h2><p>我们找个地方来存放Hexo的文章吧！我想放在<code>/Users/caiguu/Desktop/newblog</code>里，作为我的新博客的本地存储地。</p><p>我执行了如下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/Desktop</span><br><span class="line"><span class="built_in">mkdir</span> newblog</span><br><span class="line"><span class="built_in">cd</span> newblog</span><br><span class="line">hexo init</span><br></pre></td></tr></table></figure><p>按理来说，就会在newblog下新建一个博客了。然而，我遇到了证书过期的报错：</p><blockquote><p>error An unexpected error occurred: “<a href="https://registry.npm.taobao.org/hexo">https://registry.npm.taobao.org/hexo</a>: certificate has expired”.</p><p>WARN Failed to install dependencies. Please run ‘npm install’ in “&#x2F;Users&#x2F;caiguu&#x2F;newblog” folder.</p></blockquote><p>很显然，这个网址可能不对了。定位是镜像源的问题。我们换个源：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm config get registry</span><br><span class="line">npm config <span class="built_in">set</span> registry https://registry.npmmirror.com</span><br><span class="line">npm config get registry <span class="comment">#验证是否顺利更换源</span></span><br></pre></td></tr></table></figure><p>这次就没再报错了！看到了成功提示：</p><img src="/images/new-blog-journey-01.png" alt="" style="zoom:67%;" /><p>这是我们<code>newblog</code>文件夹下能够看到的东西：</p><img src="/images/new-blog-journey-02.png" alt="" style="zoom:50%;" /><p>接下来，我们让这个博客运行在本地！执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm install</span><br><span class="line">hexo server</span><br></pre></td></tr></table></figure><p>如果成功了，会有下面的显示：</p><p><img src="/images/new-blog-journey-03.png"></p><h2 id="本地Hexo验证"><a href="#本地Hexo验证" class="headerlink" title="本地Hexo验证"></a>本地Hexo验证</h2><p>我们打开这个网址看看：</p><p><img src="/images/new-blog-journey-04.png"></p><p>说明本地运行Hexo成功了！</p><p>至此，本地的部署就完成了，下面将进行云服务器的配置。</p><h1 id="云服务器配置"><a href="#云服务器配置" class="headerlink" title="云服务器配置"></a>云服务器配置</h1><h2 id="创建SSH密钥对"><a href="#创建SSH密钥对" class="headerlink" title="创建SSH密钥对"></a>创建SSH密钥对</h2><p>我们的云服务器创建后还没登录过，我们可以通过腾讯云默认提供的方案进行登录，不过我想在本地就能远程登录，这样我们可以利用SSH来做。我们先去创建一个SSH密钥对，并下载、保存好私钥，然后用密钥绑定实例。</p><p><img src="/images/new-blog-journey-05.png"></p><p>需要注意的是，绑定密钥对需要在实例关机的情况下操作，因此务必最开始就做好应有的绑定。而且，使用了密钥就不能单纯通过密码来进行登录了。密钥对绑定完之后，我们需要在本地电脑进行如下操作：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> 400 &lt;私钥文件&gt;</span><br></pre></td></tr></table></figure><img src="/images/new-blog-journey-06.png" alt="" style="zoom:50%;" /><p>以赋予自己读权限。</p><p>于是我们就可以登录了：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -i &lt;私钥文件&gt; root@&lt;云服务器IP&gt;</span><br></pre></td></tr></table></figure><p><img src="/images/new-blog-journey-07.png"></p><p>设置完SSH登录，此时就可以安全地访问轻量级服务器了。虽然Cent OS的包管理工具是yum，但是dnf是它的未来。</p><p>我们先做一些基础操作：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 更新系统</span></span><br><span class="line">dnf update -y</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装Git</span></span><br><span class="line">dnf install git -y</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装Nginx</span></span><br><span class="line">dnf install nginx -y</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动Nginx并设置开机自启</span></span><br><span class="line">systemctl start nginx</span><br><span class="line">systemctl <span class="built_in">enable</span> nginx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 如果防火墙开启，需要放行HTTP和HTTPS（不过我的实际没开）</span></span><br><span class="line">firewall-cmd --permanent --add-service=http</span><br><span class="line">firewall-cmd --permanent --add-service=https</span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure><p><img src="/images/new-blog-journey-08.png"></p><h2 id="创建裸Git"><a href="#创建裸Git" class="headerlink" title="创建裸Git"></a>创建裸Git</h2><p>接下来，我们为了能够在服务器上获取并解析出这些页面文件，我们需要创建一个裸Git并设置一个钩子。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建博客文件存放目录</span></span><br><span class="line"><span class="built_in">mkdir</span> -p /var/www/hexo</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建裸Git仓库</span></span><br><span class="line"><span class="built_in">cd</span> /root</span><br><span class="line">git init --bare blog.git</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建post-receive钩子</span></span><br><span class="line">vim /root/blog.git/hooks/post-receive</span><br></pre></td></tr></table></figure><img src="/images/new-blog-journey-09.png" alt="" style="zoom:67%;" /><p>这个hooks文件是个新文件，我们可以直接用vim进行编辑。</p><p><img src="/images/new-blog-journey-10.png"></p><p><img src="/images/new-blog-journey-11.png"></p><p>我们先暂且不用管它做了什么，原理会在后面解释。我们还要给这个脚本一个可以执行的权限：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x /root/blog.git/hooks/post-receive</span><br></pre></td></tr></table></figure><p>可以看到，已经具备了执行权限。</p><p><img src="/images/new-blog-journey-12.png"></p><h2 id="Nginx配置（测试页面）"><a href="#Nginx配置（测试页面）" class="headerlink" title="Nginx配置（测试页面）"></a>Nginx配置（测试页面）</h2><p>接下来我们创建一个nginx配置文件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/nginx/conf.d/hexo.conf</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line">    listen       80;  # 监听80端口（HTTP）</span><br><span class="line">    listen       [::]:80; # 同时开启IPv6访问权限</span><br><span class="line">    server_name  _;  # 将此处改为你的域名或服务器IP</span><br><span class="line">    charset utf-8;</span><br><span class="line"></span><br><span class="line">    # 网站根目录，指向我们刚刚创建的目录</span><br><span class="line">    root         /var/www/hexo;</span><br><span class="line">    index        index.html;  # 默认首页文件</span><br><span class="line"></span><br><span class="line">    # 访问和错误日志（可选，但推荐）</span><br><span class="line">    access_log   /var/log/nginx/hexo.access.log;</span><br><span class="line">    error_log    /var/log/nginx/hexo.error.log;</span><br><span class="line"></span><br><span class="line">    location / &#123;</span><br><span class="line">        try_files $uri $uri/ =404;  # 尝试访问请求的文件或目录，否则返回404</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们可以看到此云服务器的80端口默认开放的：</p><p><img src="/images/new-blog-journey-13.png"></p><p>然后我们去这个默认路径&#x2F;var&#x2F;www&#x2F;hexo里加一个默认页面index.html：</p><p><img src="/images/new-blog-journey-14.png"></p><p>我们执行如下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nginx -t</span><br><span class="line"><span class="built_in">sudo</span> systemctl reload nginx</span><br></pre></td></tr></table></figure><p>所以我们可以做一下测试：</p><p><img src="/images/new-blog-journey-15.png"></p><p>为什么是这个？因为有默认配置！默认配置存在了&#x2F;etc&#x2F;nginx&#x2F;nginx.conf下面，把默认的这个注释掉，就不会存在冲突了。</p><p>不过这至少说明了Nginx服务成功。</p><p>注释掉默认配置后，我们的配置就生效了，生效效果如下：</p><p><img src="/images/new-blog-journey-16.png"></p><p>至此，我们确认nginx已经能够顺利显示我们想要的静态页面了。</p><p>当然了，如果云服务器申请了IPv6地址，那么在有IPv6 GLA地址的设备上，也是可以通过IPv6进行访问的。对于腾讯云轻量服务器来说，这个地址必须主动申请，之后会给你分配一个GLA地址。想用IPv6进行访问，同时需要你的设备、你所在的网络和云服务器支持。</p><p><img src="/images/new-blog-journey-17.png"></p><p>至此，我们服务器的v4和v6双栈都已经顺利配置了！恭喜！</p><p>至于Nginx的结构如何，里面是怎么组织的，后面会单独开一篇博文去讲讲。</p><h1 id="博客项目Git与服务器裸Git联动"><a href="#博客项目Git与服务器裸Git联动" class="headerlink" title="博客项目Git与服务器裸Git联动"></a>博客项目Git与服务器裸Git联动</h1><h2 id="GitHub项目与本地同步"><a href="#GitHub项目与本地同步" class="headerlink" title="GitHub项目与本地同步"></a>GitHub项目与本地同步</h2><p>我们接下来要做的事情就是让本地的Hexo能够同步到服务器上。我们先创建一个GitHub项目：</p><img src="/images/new-blog-journey-18.png" alt="" style="zoom: 33%;" /><p>接着我们在本地把Hexo文件夹设置为Git文件夹。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进入你的博客目录</span></span><br><span class="line"><span class="built_in">cd</span> ~/Desktop/newblog/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 初始化Git仓库</span></span><br><span class="line">git init</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建.gitignore文件</span></span><br><span class="line"><span class="built_in">cat</span> &gt; .gitignore &lt;&lt; <span class="string">EOF</span></span><br><span class="line"><span class="string">node_modules/</span></span><br><span class="line"><span class="string">public/</span></span><br><span class="line"><span class="string">.deploy_git/</span></span><br><span class="line"><span class="string">db.json</span></span><br><span class="line"><span class="string">*.log</span></span><br><span class="line"><span class="string">.DS_Store</span></span><br><span class="line"><span class="string">Thumbs.db</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure><p>接着我们配置一下本地Git和远程Git的同步。我已经预先配置了SSH Key来登录GitHub。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote add origin git@github.com:&lt;我的GitHub账号&gt;/blog.git</span><br></pre></td></tr></table></figure><p><img src="/images/new-blog-journey-19.png"></p><p>是这个，不要搞错哦。可以看到顺利完成了操作：</p><p><img src="/images/new-blog-journey-20.png"></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看当前文件状态（确认要提交的文件）</span></span><br><span class="line">git status</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加所有文件到暂存区</span></span><br><span class="line">git add .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 提交到本地仓库</span></span><br><span class="line">git commit -m <span class="string">&quot;第一次提交：Hexo博客源码&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 推送到GitHub（第一次推送需要加 -u 参数）</span></span><br><span class="line">git push -u origin master</span><br></pre></td></tr></table></figure><img src="/images/new-blog-journey-21.png" alt="" style="zoom: 33%;" /><p>最后看看提交效果：</p><img src="/images/new-blog-journey-22.png" alt="" style="zoom:33%;" /><p>我们完成了同步，这样以后就可以用GitHub来管理博客内容了。</p><img src="/images/new-blog-journey-23.png" alt="" style="zoom: 33%;" /><h2 id="与云服务器裸Git联动"><a href="#与云服务器裸Git联动" class="headerlink" title="与云服务器裸Git联动"></a>与云服务器裸Git联动</h2><p>接着，我们希望能够通过deploy，让云服务器获取到我们需要的静态文件。所以，执行如下操作：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/Desktop/newblog</span><br><span class="line">hexo clean</span><br><span class="line">hexo generate</span><br><span class="line"><span class="built_in">ls</span> -la public/ <span class="comment"># 应该看到 index.html 和其他文件</span></span><br></pre></td></tr></table></figure><img src="/images/new-blog-journey-24.png" alt="" style="zoom:50%;" /><p>接着，去Hexo里配置云服务器的信息。编辑<code>_config.yml</code>文件，找到Deployment部分，按照如下配置：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line">  <span class="attr">repo:</span> <span class="string">root@你的服务器IP:/root/blog.git</span></span><br><span class="line">  <span class="attr">branch:</span> <span class="string">master</span></span><br><span class="line">  <span class="attr">message:</span> <span class="string">&quot;Site updated: <span class="template-variable">&#123;&#123; now(&#x27;YYYY-MM-DD HH:mm:ss&#x27;) &#125;&#125;</span>&quot;</span></span><br></pre></td></tr></table></figure><img src="/images/new-blog-journey-25.png" alt="" style="zoom:50%;" /><p>接下来，我们在本地安装一个插件：<code>npm install hexo-deployer-git --save</code>，然后执行<code>hexo deploy</code>，这样以后每次hexo deploy，就会自动同步更新到云服务器上了！</p><p><img src="/images/new-blog-journey-26.png"></p><p>当然，为了方便，我配置了~&#x2F;.ssh&#x2F;config，把密钥对的文件路径指定，这样以后只要在本用户下，无论哪个终端应用，都可以直接登录到云服务器上去了。</p><p>我们的联动配置大成功！</p><h1 id="第一篇Hexo博文"><a href="#第一篇Hexo博文" class="headerlink" title="第一篇Hexo博文"></a>第一篇Hexo博文</h1><p>如你所见，这就将是我们的第一篇博文。</p><p>这篇文章我预先在本地写的，我们先在Hexo里创建这篇文章。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new post <span class="string">&quot;文章名&quot;</span></span><br></pre></td></tr></table></figure><p>我们还做了一些其他的基础配置，例如将URL方式按照分类进行组织，而非按照日期。</p><p>就这样，第一篇博文也就是我搭建这个博客的经历啦，欢迎大家常来看看！</p>]]>
    </content>
    <id>https://www.caiguu.cn/website/building/new-blog-journey/</id>
    <link href="https://www.caiguu.cn/website/building/new-blog-journey/"/>
    <published>2026-02-24T16:00:00.000Z</published>
    <summary>
      <![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>时光真的好快哦！转眼间，我就从学生成为了一名上班族，走上了工作岗位。而我能够从事网络相关的工作，我本人是非常意外的。我想我大概率会成为一名软]]>
    </summary>
    <title>从零开始的新博客搭建！</title>
    <updated>2026-03-03T06:04:05.131Z</updated>
  </entry>
</feed>
