<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>D-Veda&#39;s Blog</title>
  <icon>https://d-veda.top/logo.png</icon>
  
  <link href="https://d-veda.top/atom.xml" rel="self"/>
  
  <link href="https://d-veda.top/"/>
  <updated>2022-03-18T16:00:00.000Z</updated>
  <id>https://d-veda.top/</id>
  
  <author>
    <name>D-Veda</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Hexo+Nginx+Trojan-Go搭建总结（Debian环境）</title>
    <link href="https://d-veda.top/2022/49cb7788a599/"/>
    <id>https://d-veda.top/2022/49cb7788a599/</id>
    <published>2022-03-18T10:27:39.000Z</published>
    <updated>2022-03-18T16:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>由于平时在找资料时会经常用到一些科学上网工具，但在使用过程中发现大厂服务较贵，而其他一些个人或者小团体维护的服务虽然价格相对低廉，但没有大厂稳定。当然，还是因为价格为主等其他的原因导致体验没有达到预期的效果，所以这里自己搭建一个廉价梯子。由于之前搭建梯子时使用过SS、VMESS、VLESS等其他协议，且经常发生端口被禁的现象导致网上冲浪体验就没了，所以不沿用之前的方案，又因为这个博客有一个域名，加上想把博客移到个人服务器上等原因，所以这次选择Trojan-Go协议来搭建。</p><span id="more"></span><ul><li>科学上网不同协议的比较选择参考</li></ul><blockquote><p><a target="_blank" rel="noopener" href="https://iyideng.vip/black-technology/cgfw/vpn-ss-ssr-v2ray-trojan-wireguard-bypass-gfw.html">科学上网工具哪个好？一灯不是和尚为您科普VPN&#x2F;SS&#x2F;SSR&#x2F;V2Ray&#x2F;Xray&#x2F;Trojan&#x2F;Trojan-Go和WireGuard的前世今生、区别和关系以及梯子软件的前景 - 一灯不是和尚 (iyideng.vip)</a></p><p><a target="_blank" rel="noopener" href="https://www.techfens.com/posts/kexueshangwang.html">科学上网的主流协议大对比！这里面有你在使用的吗？ | TechFen’s Blog (techfens.com)</a></p></blockquote><p>考虑到只有一个域名且已经被用于博客了，而一个域名通常来说只解析到一个网站上。所以使用二级域名给Trojan-Go进行HTTPS的伪装，又由于想实现Hexo在个人服务器上的部署则需要使用，于是将博客同时部署到GitHub和VPS上实现网站备份的效果和科学上网。</p><p>在开始之前需要在原来的域名解析条目中添加一个指向VPS的<code>IP</code>条目，记录值是VPS的IP地址，效果类似如下。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220318213333355.png" alt="阿里云域名解析控制台"  /></div><p>这里使用的是阿里云的域名，其中主机记录为@表示直接解析域名（<code>d-veda.top</code>），如果存在多条记录值相同的记录会产生冲突（如果解析路线不同则可以消除冲突，最好一个域名对应一个地址）。</p><p><strong>注意：由于VPS只有IP能访问所以这里添加的是<code>A</code>记录，而原来域名解析指向的是域名（<code>d-veda.github.io</code>），所以用的是<code>CNAME</code>记录。这里用的境外解析路线只是避免冲突（文本所使用的方法），推荐使用二级域名指向VPS的IP地址（例如，主机记录为<code>abc</code>，已有域名为<code>xxx.com</code>，则<code>abc.xxx.com</code>为<code>xxx.com</code>的二级域名，添加一个这样的<code>A</code>记录指向VPS的IP地址即可）。</strong></p><p>添加完成后再将Hexo部署到VPS上。若不需要Hexo部署至VPS可以跳过下一节。</p><h2 id="Hexo部署推送"><a href="#Hexo部署推送" class="headerlink" title="Hexo部署推送"></a>Hexo部署推送</h2><p>Hexo是通过git推送静态网页文件到仓库的，因此，需要在VPS搭建一个git仓库（使用<code>root</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></pre></td><td class="code"><pre><span class="line">apt install git <span class="comment"># 安装git。</span></span><br><span class="line">adduser git <span class="comment"># 添加用户git，专用于git仓库管理。这里会提示添加用户信息和对应的密码。</span></span><br><span class="line">su git <span class="comment"># 使用git用户进行操作。</span></span><br><span class="line"><span class="built_in">cd</span> ~</span><br><span class="line">git init --bare blog.git <span class="comment"># 创建名称为blog的空仓库。</span></span><br></pre></td></tr></table></figure><p>这里使用<code>git</code>作为新添加的用户名是为了和常用的git代码托管平台统一，用户名可以是其他内容。使用<code>--bare</code>创建空仓库方便将仓库内容和git数据分离。</p><p>在创建好git仓库后，可以尝试在本地终端<code>git clone</code>一下VPS的仓库（这里会提示输入相关用户的密码）。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone git@IP:/home/git/blog.git</span><br></pre></td></tr></table></figure><p>这里的<code>IP</code>就是VPS的IP地址，如果VPS中的git仓库所有者不是git则需要将git修改为对应的用户名称。终端若出现如下所示的内容，则表示VPS上的仓库建立成功了。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">warning: You appear to have cloned an empty repository.</span><br></pre></td></tr></table></figure><hr><p>现在需要向本地的Hexo博客配置文件<code>_config.yml</code>中的部署参数添加VPS的git仓库信息，内容如下。</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><span class="line">6</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><br><span class="line">    <span class="attr">github:</span> <span class="string">https://github.com/D-Veda/D-Veda.github.io.git</span></span><br><span class="line">    <span class="attr">VPS:</span> <span class="string">git@IP:/home/git/blog.git</span> <span class="comment"># 新添加的git仓库地址。</span></span><br><span class="line">  <span class="attr">branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure><p>注意缩进会影响Hexo生成静态网页。<code>IP</code>替换VPS对应的IP地址，这里有两个部署的地址，前面的名称（<code>github</code>和<code>VPS</code>）是自己添加的，且可以自己定义。</p><p>配置好Hexo的部署地址后需要将VPS上新建的git仓库配置<code>git hook</code>（git钩子）。这么做是为了实现git仓库的自动部署。若不做git钩子进行自动部署，则在VPS中会找不到推送过来的文件（当然也可以不用git钩子，用自定义的脚本也可以实现对应的自动部署功能）。</p><p>配置<code>git hook</code>操作如下（使用<code>git</code>用户，不要用<code>root</code>）。</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 ~/blog.git/hooks/post-update.sample <span class="comment"># 修改post-update.sample文件中的命令。</span></span><br></pre></td></tr></table></figure><p>在<code>post-update.sample</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><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># An example hook script to prepare a packed repository for use over</span></span><br><span class="line"><span class="comment"># dumb transports.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># To enable this hook, rename this file to &quot;post-update&quot;.</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">exec</span> git --work-tree=/var/www/blog --git-dir=/home/git/blog.git checkout -f</span><br></pre></td></tr></table></figure><p><strong>注意：这里的<code>--work-tree</code>对应git仓库的工作区目录（这里使用<code>/var/www/blog</code>作为工作区目录是为了对应之后的Nginx所提供的目录，也可以使用其他目录且需要自行创建），<code>--git-dir</code>对应git仓库目录，<code>checkout</code>和<code>-f</code>用于强制覆盖原有文件。</strong></p><p>工作区目录需要根据自己的定义的位置进行创建（这里使用<code>root</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></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /var</span><br><span class="line">mkdir www &amp;&amp; <span class="built_in">cd</span> ./www <span class="comment"># 若有www目录则不用创建，cd进入即可。</span></span><br><span class="line">mkdir blog</span><br><span class="line">chown -R git:git ./blog <span class="comment"># 将blog目录的所有者变为git用户。</span></span><br></pre></td></tr></table></figure><p>编辑好<code>post-update.sample</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></pre></td><td class="code"><pre><span class="line">su git <span class="comment"># 使用git用户进行操作。</span></span><br><span class="line">mv ~/blog.git/hooks/post-update.sample ~/blog.git/hooks/post-update <span class="comment"># 重命名，去掉sample后缀。</span></span><br><span class="line">chmod +x ~/blog.git/hooks/post-update <span class="comment"># 给post-update文件添加可执行权限。</span></span><br></pre></td></tr></table></figure><p>上述操作原理参考<a target="_blank" rel="noopener" href="https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90">Git - Git 钩子 (git-scm.com)</a>。</p><p>配置完成后可以尝试使用<code>hexo d</code>进行部署，按照提示输入git用户密码后，将静态网页文件推送到VPS的git仓库中。推送成功后在之前的工作区目录（<code>/var/www/blog</code>）可以找到推送的文件，Hexo双部署到此就实现完成了。如果VPS工作区没有收到对应的推送文件则是前几步有误，需要自己排查。</p><p><strong>注意：由于Hexo是增量推送更新，所以每次<code>hexo g -d</code>如果文件内容都没有改动，Hexo不会触发git钩子进行自动部署。若要触发git钩子进行自动部署，则需要在Hexo部署前将任意内容文件稍微改动一下（随便一篇文章稍微改一下内容）并先<code>hexo clean</code>再<code>hexo g -d</code>进行生成部署。如果上述操作不能触发git钩子，则需要检查VPS中仓库的<code>post-update</code>文件、<code>hooks</code>目录和工作区目录对于<code>git</code>用户来说是否具有相应权限，还有相应文件的配置是否有误。</strong></p><h2 id="Nginx搭建部署"><a href="#Nginx搭建部署" class="headerlink" title="Nginx搭建部署"></a>Nginx搭建部署</h2><p>在Hexo成功部署到VPS后需要使用HTTP服务将静态网页文件显示出来，这里使用Nginx的HTTP服务，操作（使用<code>root</code>用户）如下。</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">apt install nginx <span class="comment"># 安装Nginx。</span></span><br></pre></td></tr></table></figure><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/nginx.conf <span class="comment"># 修改nginx.conf文件配置信息。</span></span><br></pre></td></tr></table></figure><p>将<code>nginx.conf</code>文件第一行的用户名改成<code>root</code>后保存，如下图所示。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220318235800950.png" alt="nginx.conf文件配置信息"  /></div><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/sites-available/default <span class="comment"># 修改default文件信息。</span></span><br></pre></td></tr></table></figure><p>将<code>default</code>文件中<code>root</code>改为自己git工作区目录，<code>server_name</code>改为自己的域名（此域名需要解析指向VPS的IP地址），如下图所示。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220319000623215.png" alt="default文件配置信息1"  /></div><p>将<code>default</code>文件最下面的<code>server</code>段内容去掉注释后把侦听端口号、服务器域名、根目录都修改成相应信息，这里使用的是8080端口避免Nginx默认情况下的80端口被占用，如下图所示。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220319001240346.png" alt="default文件配置信息2"  /></div><p>配置好文件后保存。使用<code>nginx -t</code>检测Nginx配置是否有误，以便故障排查。</p><hr><p>在Nginx完成HTTP服务配置之前需要确认VPS防火墙中相应的端口是否开启。</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">ufw status <span class="comment"># 使用ufw查看防火前端口规则列表。</span></span><br></pre></td></tr></table></figure><p>例如这里使用的是22、80、443、8080端口。22端口用于本地终端与VPS的SSH协议连接，80，8080用于Nginx的HTTP服务端口，443端口用于之后Trojan-Go协议的HTTPS伪装。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220319002437031.png" alt="ufw status输出信息"  /></div><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">ufw allow PORT</span><br></pre></td></tr></table></figure><p>这里的PORT替换需要放开的端口号。检查无误后重启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">nginx -s reload</span><br></pre></td></tr></table></figure><p>如果Nginx提示端口被占用的错误，则可以使用<code>netstat -nlp</code>查看相应的端口占用情况，使用<code>ps -ef | grep name</code>（<code>name</code>需要被占用对应端口的应用名称替换）将对应占用端口的进程清除即可开启Nginx服务。现在可以直接使用IP访问网站，如果加载失败则需要在之前几步进行故障排查。</p><h2 id="申请获取SSL证书"><a href="#申请获取SSL证书" class="headerlink" title="申请获取SSL证书"></a>申请获取SSL证书</h2><p>参考Trojan-Go官方文档，从Let’s Encrypt证书颁发机构中获取证书。根据Let’s Encrypt的建议，推荐使用<a target="_blank" rel="noopener" href="https://certbot.eff.org/">Certbot</a> ACME 客户端。它可以在不下线您的服务器的前提下自动执行证书颁发和安装。</p><p>根据<a target="_blank" rel="noopener" href="https://certbot.eff.org/instructions?ws=nginx&os=debianbuster">Certbot 说明 |Certbot (eff.org)</a>描述，需要先将系统自带的<code>certbot</code>版本进行删除，然后安装<code>snap</code>商店中的<code>certbot</code>进行使用，具体操作如下（使用<code>root</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><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">apt update <span class="comment"># 更新源列表。</span></span><br><span class="line">apt install snapd <span class="comment"># 安装snapd。</span></span><br><span class="line">snap install core <span class="comment"># 获取最新的core snapd。</span></span><br><span class="line">snap refresh core <span class="comment"># 检查snap是否为最新版本。</span></span><br><span class="line">apt remove certbot <span class="comment"># 删除系统自带的certbot。</span></span><br><span class="line">apt autoremove <span class="comment"># 删除多余的依赖程序。</span></span><br><span class="line">snap install --classic certbot <span class="comment"># 使用snap安装certbot。</span></span><br><span class="line">ln -s /snap/bin/certbot /usr/bin/certbot <span class="comment"># 为certbot创建软连接，便于执行。</span></span><br><span class="line">certbot certonly --nginx <span class="comment"># 只获取证书不修改Nginx服务配置</span></span><br></pre></td></tr></table></figure><p>这里采用只获取证书不修改Nginx服务配置是因为若certbot修改了Nginx服务配置则会让Nginx服务开启HTTPS协议，Nginx会占用443端口，而Trojan-Go需要伪装HTTPS也要占用443。这样会造成端口冲突，所以certbot不能直接修改Nginx服务配置。在certbot获取证书失败时，需要检查域名解析是否正常工作。至此SSL证书可以成功获取。</p><h2 id="Trojan-Go对端搭建"><a href="#Trojan-Go对端搭建" class="headerlink" title="Trojan-Go对端搭建"></a>Trojan-Go对端搭建</h2><p>Trojan-Go使用<code>Go</code>实现的完整<code>Trojan</code>代理，兼容原版<code>Trojan协议</code>及配置文件格式。安全、高效、轻巧、易用。参考<a target="_blank" rel="noopener" href="https://github.com/p4gefau1t/trojan-go">p4gefau1t&#x2F;trojan-go</a>和<a target="_blank" rel="noopener" href="https://p4gefau1t.github.io/trojan-go/">Trojan-Go Docs</a>文档进行相应配置（使用<code>root</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></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~</span><br><span class="line">wget https://github.com/p4gefau1t/trojan-go/releases/download/v0.10.6/trojan-go-linux-amd64.zip <span class="comment"># 下载Trojan-Go可执行文件。</span></span><br><span class="line">apt install unzip <span class="comment"># 安装unzip解压工具。</span></span><br><span class="line">unzip -d ./trojan-go trojan-go-linux-amd64.zip <span class="comment"># 解压官方压缩包。</span></span><br></pre></td></tr></table></figure><p>解压完成后，官方在<code>./example</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></pre></td><td class="code"><pre><span class="line">ln -s /root/trojan-go/trojan-go /usr/bin/trojan-go <span class="comment"># 创建软连接，方便运行</span></span><br><span class="line"><span class="built_in">cd</span> ~/trojan-go</span><br><span class="line">mkdir config</span><br><span class="line">cp ./example/server.json ./config</span><br><span class="line">cp ./example/trojan-go.service /usr/lib/systemd/system/</span><br></pre></td></tr></table></figure><p>将相关的配置文件放到对应的位置后，对Trojan-Go配置进行修改，操作如下。</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 /root/trojan-go/config/server.json <span class="comment"># 修改Trojan-Go配置文件信息</span></span><br></pre></td></tr></table></figure><p>参考配置如下：</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">&quot;run_type&quot;</span>: <span class="string">&quot;server&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;local_addr&quot;</span>: <span class="string">&quot;0.0.0.0&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;local_port&quot;</span>: <span class="number">443</span>,</span><br><span class="line">    <span class="attr">&quot;remote_addr&quot;</span>: <span class="string">&quot;127.0.0.1&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;remote_port&quot;</span>: <span class="number">8080</span>,</span><br><span class="line">    <span class="attr">&quot;password&quot;</span>: [</span><br><span class="line">        <span class="string">&quot;Your password&quot;</span></span><br><span class="line">    ],</span><br><span class="line">    <span class="attr">&quot;ssl&quot;</span>: &#123;</span><br><span class="line">        <span class="attr">&quot;cert&quot;</span>: <span class="string">&quot;/path/to/your/fullchain&quot;</span>,</span><br><span class="line">        <span class="attr">&quot;key&quot;</span>: <span class="string">&quot;/path/to/your/privkey&quot;</span>,</span><br><span class="line">        <span class="attr">&quot;fallback_port&quot;</span>: <span class="number">8080</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>注意：这里的<code>remote_port</code>需要和Nginx配置的8080端口相对应，<code>cert</code>和<code>key</code>填写由certbot获取到的两个密钥文件地址，<code>fallback_port</code>作为当Trojan-Go检测到通信异常时会将数据转发到对应的端口，这里需要和Nginx所配置的8080端口对应。</strong></p><p>配置完成后尝试开启trojan-go服务端，查看是否运行正常，操作如下。</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">trojan-go -config /root/trojan-go/config/server.json</span><br></pre></td></tr></table></figure><p>若出现如下提示且没有<code>[ERROR]</code>提示，则表示trojan-go服务端工作正常。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220319025437213.png" alt="trojan-go运行提示"  /></div><p>然后配置trojan-go的开机启动服务，操作如下。</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">vim /usr/lib/systemd/system/trojan-go.service</span><br></pre></td></tr></table></figure><p>将启动服务文件中的<code>User</code>中的nobody改为root，检查配置文件所在地址无误保存即可。</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">[Unit]</span><br><span class="line">Description=Trojan-Go - An unidentifiable mechanism that helps you bypass GFW</span><br><span class="line">Documentation=https://p4gefau1t.github.io/trojan-go/</span><br><span class="line">After=network.target nss-lookup.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">User=root</span><br><span class="line">CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE</span><br><span class="line">AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE</span><br><span class="line">NoNewPrivileges=true</span><br><span class="line">ExecStart=/usr/bin/trojan-go -config /root/trojan-go/config/server.json</span><br><span class="line">Restart=on-failure</span><br><span class="line">RestartSec=10s</span><br><span class="line">LimitNOFILE=infinity</span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></table></figure><p>注册开机启动服务，并检测trojan-go服务运行状态。</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">systemctl <span class="built_in">enable</span> trojan-go <span class="comment"># 开机启动</span></span><br><span class="line">service trojan-go start <span class="comment"># 立即启动服务</span></span><br><span class="line">systemctl status trojan-go <span class="comment"># 检测服务运行状态</span></span><br></pre></td></tr></table></figure><p>trojan-go服务端的基本配置就都结束了。</p><hr><p>这里使用<a target="_blank" rel="noopener" href="https://github.com/Qv2ray/Qv2ray">Qv2ray</a>作为trojan-go客户端，在安装Qv2ray后需要将其添加<a target="_blank" rel="noopener" href="https://github.com/Qv2ray/QvPlugin-Trojan-Go">QvPlugin-Trojan-Go</a>插件才能进行连接。参考<a target="_blank" rel="noopener" href="http://qv2ray.net/lang/zh/plugins/usage.html">使用插件 | Qv2ray</a>文档安装trojan-go插件后，新建连接，需要填写的内容只有主机（填服务器的IP地址或域名）和Password（填设trojan-go服务端设置的密码），点击OK保存。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/image-20220319031526005.png" alt="新建连接设置"  /></div><p>完成设置后双击新建好的连接，成功即搭建完成。</p><p>若仍有其他问题则检查服务端和客户端的相关配置是否一致等其他问题，完成整体搭建。</p><h2 id="Qv2ray其他配置参考"><a href="#Qv2ray其他配置参考" class="headerlink" title="Qv2ray其他配置参考"></a>Qv2ray其他配置参考</h2><blockquote><p><a target="_blank" rel="noopener" href="https://gist.github.com/0xbyc/2cbae071f580e71ff055cde19efc39c4">Qv2ray高级路由设置策略</a></p><p><a target="_blank" rel="noopener" href="http://qv2ray.net/lang/zh/getting-started/step4.html#%E4%BD%BF%E7%94%A8%E7%B3%BB%E7%BB%9F%E4%BB%A3%E7%90%86">解决UWP应用在Qv2ray连接时不能上网的问题</a></p><p><a target="_blank" rel="noopener" href="https://qv2ray.net/lang/zh/manual/route.html#%E5%85%A8%E5%B1%80%E8%B7%AF%E7%94%B1%E8%A7%84%E5%88%99">高级路由设置规则</a></p><p><a target="_blank" rel="noopener" href="https://github.com/v2ray/v2ray-core/issues/210">v2ray局域网共享方案（Qv2ray类似）</a></p></blockquote><hr><p>Hexo+Nginx+Trojan-Go的整体部署方案仅供参考，本文仅对搭建过程进行相关记录。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;由于平时在找资料时会经常用到一些科学上网工具，但在使用过程中发现大厂服务较贵，而其他一些个人或者小团体维护的服务虽然价格相对低廉，但没有大厂稳定。当然，还是因为价格为主等其他的原因导致体验没有达到预期的效果，所以这里自己搭建一个廉价梯子。由于之前搭建梯子时使用过SS、VMESS、VLESS等其他协议，且经常发生端口被禁的现象导致网上冲浪体验就没了，所以不沿用之前的方案，又因为这个博客有一个域名，加上想把博客移到个人服务器上等原因，所以这次选择Trojan-Go协议来搭建。&lt;/p&gt;</summary>
    
    
    
    <category term="DIY" scheme="https://d-veda.top/categories/diy/"/>
    
    
    <category term="Hexo" scheme="https://d-veda.top/tags/hexo/"/>
    
    <category term="Nginx" scheme="https://d-veda.top/tags/nginx/"/>
    
    <category term="Trojan-Go" scheme="https://d-veda.top/tags/trojan-go/"/>
    
    <category term="VPS" scheme="https://d-veda.top/tags/vps/"/>
    
    <category term="Qv2ray" scheme="https://d-veda.top/tags/qv2ray/"/>
    
  </entry>
  
  <entry>
    <title>基于MQTT协议的物联网云端串口波形显示小程序</title>
    <link href="https://d-veda.top/2022/680098d399fd/"/>
    <id>https://d-veda.top/2022/680098d399fd/</id>
    <published>2022-01-31T21:12:43.000Z</published>
    <updated>2022-03-08T16:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="系统原理和实现细节"><a href="#系统原理和实现细节" class="headerlink" title="系统原理和实现细节"></a>系统原理和实现细节</h2><p>本项目是基于<code>MQTT</code>协议实现机器到机器的物联网通信系统。由于<code>MQTT</code>是一个极其轻量级的<code>发布/订阅</code>消息传输协议，他是专门用于低带宽高延迟或者不可靠的网络环境设计的，因此在本项目中云端串口的通信质量稳定性和硬件性能都有较好的表现。 <code>MQTT</code>它已被用于通过卫星链路与代理通信的传感器、与医疗服务提供者的拨号连接，以及一系列家庭自动化和小型设备场景，因此它也是移动应用的理想选择，因为它体积小，功耗低，数据包最小，并且可以有效地将信息分配给一个或多个接收器。</p><span id="more"></span><p>在整个系统中，由于使用物联网平台进行转发，为了实现通用可靠，所以需要将波形显示相关的数据处理在边缘设备实现完成。在边缘设备上数据采集设备只需要将数据以串行的方式向物联网平台发送数据即可，而串口波形显示终端需要将经由物联网平台转发的数据信息进行提取分析和最后的显示即可实现数据波形功能。</p><h3 id="具体实现使用的产品和服务"><a href="#具体实现使用的产品和服务" class="headerlink" title="具体实现使用的产品和服务"></a>具体实现使用的产品和服务</h3><p>本项目是基于<code>移远QUECTEL BC260Y-CN</code>的<code>NB-IOT</code>模块进行开发的云端串口波形显示系统，该模块作为远程数据采集设备，用于双向通信和单向数据采集。</p><ul><li><p>双向通信：移动应用程序和物联网设备进行双向的数据传输。</p></li><li><p>单向数据采集：物联网设备向移动应用程序不断发送设备自身获取到的数据。</p></li></ul><p>这里使用<code>阿里云物联网平台</code>作为物联网通信平台，用于对数据采集设备和移动串口波形显示终端的通信数据进行转发。</p><p>移动串口波形显示终端使用<code>微信小程序</code>作为波形显示的移动终端。</p><h3 id="系统原理基础"><a href="#系统原理基础" class="headerlink" title="系统原理基础"></a>系统原理基础</h3><p>由于本系统是使用MQTT协议来完成整体数据通信，所以有必要先简单了解MQTT的通信原理和相应的通信机制。实现MQTT协议需要客户端和服务器端通讯完成，在通讯过程中，MQTT协议中有三种身份：发布者（<code>Publish</code>）、代理（<code>Broker</code>）、订阅者（<code>Subscribe</code>）。其中，消息的发布者和订阅者都是客户端，消息代理是服务器，消息发布者可以同时是订阅者。</p><p>MQTT传输的消息分为：主题（<code>Topic</code>）和负载（<code>Payload</code>）两部分：</p><ul><li><code>Topic</code>：可以理解为消息的类型，订阅者订阅（<code>Subscribe</code>）后，就会收到该主题的消息内容（<code>Payload</code>）；</li><li><code>Payload</code>：可以理解为消息的内容，是指订阅者具体要使用的内容。</li></ul><p><code>MQTT</code>整个服务会构建底层网络传输：它将建立客户端到服务器的连接，提供两者之间的一个有序的、无损的、基于字节流的双向传输。当应用数据通过<code>MQTT</code>网络发送时，<code>MQTT</code>会把与之相关的服务质量（<code>QoS</code>）和主题名（<code>Topic</code>）相关连。</p><blockquote><p>这里服务质量有三个等级，不同等级的定义内容如下：</p><p><code>QoS 1</code>：”至多一次”，消息发布完全依赖底层TCP&#x2F;IP网络。会发生消息丢失或重复。这一级别可用于如下情况，环境传感器数据，丢失一次读记录无所谓，因为不久后还会有第二次发送。这一种方式主要普通APP的推送，若智能设备在消息推送时未联网，推送过去没收到，再次联网也就收不到了。</p><p><code>QoS 2</code>：”至少一次”，确保消息到达，但消息重复可能会发生。</p><p><code>QoS 3</code>：”只有一次”，确保消息到达一次。在一些要求比较严格的计费系统中，可以使用此级别。在计费系统中，消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送，确保用户收到且只会收到一次。</p></blockquote><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/cf5bab863677591f.png" alt="系统工作框图" style="zoom: 67%;" /></div><p>基于<code>MQTT</code>协议的工作原理，物联网平台需要创建<code>MQTT</code>服务实例用于和两个边缘设备（数据采集设备和移动串口波形显示终端）建立会话连接，其作用是充当<code>MQTT</code>代理角色，在创建好的<code>MQTT</code>服务实例上需要为两个边缘设备分别定义<code>Topic</code>，这里两个设备都需要定义一个<code>tx Topic </code>和一个<code>rx Topic</code>，并同时订阅两台设备自身的<code>tx Topic</code>，这个的作用是将订阅者和发布者之间的数据内容按照数据流向进行分类，<code>tx</code>作为上传主题，<code>rx</code>作为下载主题，这样可以通过平台便于管理设备和设备之间的通信连接，同时也简化通信模式。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/7f1f69585e702031.png" alt="MQTT物联网平台连接关系" style="zoom: 80%;" /></div><p>物联网平台建立<code>Topic</code>后，两台边缘设备就可以实现与<code>MQTT</code>服务实例进行连接了。两台边缘设备通过配置与物联网平台对接的参数，再订阅每个设备自身对应的<code>rx Topic</code>，即可实现边缘设备和代理之间的通信。设备可以通过向自身的<code>tx Topic</code>发布负载内容实现向代理发送数据信息。代理从订阅的两个<code>rx Topic</code>中接收到边缘设备发送的数据信息，但此时边缘设备之间不能进行相互通信。根据物联网平台服务可以建立设备之间的<code>MQTT</code>消息规则转发，从而实现两台对等设备之间的全双工通信。物联网平台需要在<code>MQTT</code>服务实例上定义规则，将从一台边缘设备发布到代理的<code>tx Topic</code>的数据转发到另一台边缘设备订阅的<code>rx Topic</code>，反过来也是同理。这样就实现了设备与设备之间的相互通信。目前为止，设备之间可以进行简单的双向通信。但移动串口终端仍然不能将数据采集设备发送过来的数据解析并转换成波形图显示。</p><h3 id="波形显示实现"><a href="#波形显示实现" class="headerlink" title="波形显示实现"></a>波形显示实现</h3><p>由于考虑到物联网平台的影响，为了实现波形显示功能的通用性，所以必须减少对物联网平台的依赖性。因此就不能在物联网平台上进行相关的数据解析和数据处理，所以需要在设备之间可以双向通信的基础上，将数据解析和处理的部分在移动串口终端上进行实现。</p><div align="center">    <img src="https://raw.githubusercontent.com/D-Veda/D-Veda.github.io/pic/img/PicGo/96df636edffb96b2.png" alt="数据缓存更新流程" /></div><p>这里先定义一种通信标准（或者称为协议），数据采集设备上传的数据需要以数据帧的格式向代理发送数据内容，其原因是方便处理。一般的数据帧包括帧头，数据内容和尾部冗余校验。常见的通信协议帧基本都是这样的结构，由于<code>MQTT</code>协议是基于<code>TCP</code>协议封装而成的一个轻量化通信协议，<code>TCP</code>协议是一种可靠的传输协议，即确保数据能够传输到指定目标，因此，可以在常见的数据帧的结构中把尾部冗余校验去掉来降低传输数据的开销，并且保留数据帧头用于区分不同的数据帧。这样就明确了数据帧的收发格式只有帧头和数据内容。</p><p>现在可以通过数据帧头识别数据内容的起始位置，来定位读取数据内容信息。需要注意的是，由于受到网络环境，设备硬件等影响，数据采集设备如果每次发送一帧数据则会导致本地获取到的数据和云端显示的数据延迟在不断的增大，所以这里采用一次发送大量的数据帧。移动串口终端需要一次接收大量的数据帧并同时解析提取数据帧中的数据。移动终端在处理数据帧的信息解析和提取的任务之后需要将信息放在缓存区，当缓存区需要更新的时候则将缓存区的数据发送至界面上并显示波形，这里暂时先不谈从缓存区到波形如何显示。当缓存区溢出或者说是数据帧全部都移动到缓存区后会触发缓存区更新，最终实现波形更新显示。</p><p>在从缓存区更新数据到波形显示的过程中，移动串口终端每次解析大量的数据帧并把数据帧提取出来的信息按照先入先出的顺序存放至缓存区。当缓存区接收到缓存更新信号时，移动串口终端会从缓存区将数据映射到波形图界面上。</p><p>在波形图的显示方式上，由于受到通信环境等其他影响，数据采集设备向移动串口终端发送的消息不一定都是等时长的。那么可以考虑将数据波形显示时根据帧数作为参考来显示具体的波形某一帧的幅值大小，将连续的数据帧用直线段连接即可完成波形图的显示。通过发送设备的发送消息速率和一次消息发送多少帧可以估算出移动串口终端上的波形显示一帧需要多少时间。由此，如果发送的数据信息是具有周期规律的，那么可以计算出波形的周期、频率等一些必要参数。</p><p>确定了波形显示参考方式后，那么就只有具体的波形绘制方法需要解决。常见的波形显示只需要将界面等间隔的几列上将不同帧上的数据经过一定比例转换后，在一列上显示一定的高度或者距离用来表示当前帧或者时刻上的幅值信息。但由于不同情况下波形分析的不同需求，所以需要做到不同单位帧数的波形显示，此效果和示波器调整横向的时间轴效果一致。基于上述需求分析，将波形可以显示的界面宽度等间距分成不同数量后，每间隔一段相等距离更新一帧数据，最后形成一个完整波形。当需要跳帧横向单位帧数时，通过改变界面宽度的等分数量来调整列和列之间的间距最后在每一列上将数据进行转换然后绘制实现波形的拉伸。</p><p>按照上述分析就实现了云端串口波形显示系统。</p><hr><blockquote><p><a target="_blank" rel="noopener" href="https://github.com/D-Veda/Serial-over-Internet">D-Veda&#x2F;Serial-over-Internet: 使用MQTT协议基于阿里云平台实现物联网传输的云端串口调试助手 (github.com)</a></p></blockquote>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;系统原理和实现细节&quot;&gt;&lt;a href=&quot;#系统原理和实现细节&quot; class=&quot;headerlink&quot; title=&quot;系统原理和实现细节&quot;&gt;&lt;/a&gt;系统原理和实现细节&lt;/h2&gt;&lt;p&gt;本项目是基于&lt;code&gt;MQTT&lt;/code&gt;协议实现机器到机器的物联网通信系统。由于&lt;code&gt;MQTT&lt;/code&gt;是一个极其轻量级的&lt;code&gt;发布/订阅&lt;/code&gt;消息传输协议，他是专门用于低带宽高延迟或者不可靠的网络环境设计的，因此在本项目中云端串口的通信质量稳定性和硬件性能都有较好的表现。 &lt;code&gt;MQTT&lt;/code&gt;它已被用于通过卫星链路与代理通信的传感器、与医疗服务提供者的拨号连接，以及一系列家庭自动化和小型设备场景，因此它也是移动应用的理想选择，因为它体积小，功耗低，数据包最小，并且可以有效地将信息分配给一个或多个接收器。&lt;/p&gt;</summary>
    
    
    
    <category term="项目" scheme="https://d-veda.top/categories/%E9%A1%B9%E7%9B%AE/"/>
    
    
    <category term="MQTT" scheme="https://d-veda.top/tags/mqtt/"/>
    
    <category term="IOT" scheme="https://d-veda.top/tags/iot/"/>
    
    <category term="嵌入式" scheme="https://d-veda.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
    
  </entry>
  
</feed>
