使用Linux或是VPS时的错误报告说是习得技巧
记录LaTeX中文文档有关字符显示的字体、连字、中文URL、带圈数字等问题。 请使用目录标签跳转查看。本文示例仓库见marvel084/LaTeXTest2024 (github.com) 一、LuaLaTeX vs XeLaTeX 在字符显示上 LuaTeX优点： 与csl（citeproc-lua）配合的很好 使用ctex时，支持\url直接显示URL中的汉字 TH-Times字体支持彩色emoji，且使用ZWJ的不受干扰 pmhanguljamo宏包可以正常显示（古）谚文 LuaTeX缺点： 多语言TTC字体TH-Times无法直接使用，加polyglossia包后可使用 （西文）fontspec定义的字体，不加Script参数不能正确处理“连字/位置变体”（如八思巴文 ꡂ ꡦ ꡃ -> ꡂꡦꡃ） 配合BixbLaTeX时，不能正确显示参考文献的中文URL（用的biblatex-gb7714-2015 issue方法，biblatex-gb7714-2015本身会对中文url转义，这也导致用lualatex编译会因url和urlraw不一致而报错终止）（待复现） 使用ctex（luatex-ja）后不能拼合古谚文，需调至西文ALchar显示 fontspec定义的字体（使用Script=Hangul参数）。在TeX Live 2023及以上发行版中，在使用LuaLaTeX编译时，如果一个谚文的初、中声刚好能拼成现代韩语音节（谚文音节区段，Hangul Syllables，"AC00-"D7AF），则该音节会抢先显示，把终声甩在后头，从而使古谚文无法正确拼合。 XeTeX优点： （西文）fontspec定义的字体（不加Script参数）能正确处理“连字/位置变体”（如八思巴文） （中文）xeCJK定义的字体能正确拼合古谚文（如ᄎ ᆑ ᇙ拼成ᄎᆑᇙ） 配合BibLaTeX能正确显示参考文献的中文URL（见biblatex-gb7714-2015 issue） XeTeX缺点： 不能直接使用csl（citeproc-lua）参考文献后端，但可以配置latexmkrc等方式使用 \url无法正确显示中文URL，遇中文网址需转义或改用\href pmhanguljamo宏包显示谚文会被xeCJK干扰从而显示错误，可用polyglossia分别配置语言环境解决 TH-Times字体不支持彩色emoji，polyglossia+ctex时使用ZWJ的emoji无法显示（如麻将红宝牌 🀔\char"200D🟥） 二、字体 参见： LaTeX 字体配置 | Fenglielie LaTeX札记（四）：字体 | Levitate_ (levitate-qian.github.io) tex-gyre字体族介绍：https://www.gust.org.pl/projects/e-foundry/tex-gyre latex衬线字体库：The LaTeX Font Catalogue – Serif Fonts (tug.org) 一种CJK选字体的方式：如何使用inputenc打出unicode字体 - LaTeX工作室 (latexstudio.net) 2.1 西文字体 fontspec fontspec用来配置（西文）字体，可以指定OpenType字体的参数 分别设置正文衬线、无衬线、等宽字体 \setmainfont{texgyretermes}[ %仿TimesNewRoman字体 Extension = .otf, UprightFont = *-regular, BoldFont = *-bold, ItalicFont = *-italic, BoldItalicFont = *-bolditalic, Ligatures = TeX, ]% \setsansfont{texgyreheros}[ Extension = .otf, UprightFont = *-regular, BoldFont = *-bold, ItalicFont = *-italic, BoldItalicFont = *-bolditalic, ]% \setmonofont{texgyrecursor}[ Extension = .otf, UprightFont = *-regular, BoldFont = *-bold, ItalicFont = *-italic, BoldItalicFont = *-bolditalic, Scale = MatchLowercase, Ligatures = CommonOff, ]% 对于粗体、斜体等变化可以使用Style，可以调用其他字体。 对于TrueType TTC字体没有对应的Bold字体的话，可以定义伪粗体： \setmainfont{TH-Times}[AutoFakeBold] 设置特定参数的字体 设置Script以显示特定语言 \newfontfamily\psp{TH-Times}[Script=Phags-pa] %八思巴文 TH-Times修正了NotoSansPhagsPa的错误 \newfontfamily\hangulfont{Noto Serif CJK KR}[Script=Hangul] % 谚文 天珩字库的TH-Times1对许多语言支持很好，可用于手动fallback \newfontfamily\fb{TH-Times} \newfontfamily\fbtk{TH-Times}[Language=Turkish] pandoc的字体有fallback，仅LuaTeX可用，见Pandoc - Pandoc User’s Guide LuaTeX可设置fallback feature Fallback fonts in LuaTeX via 'luaotfload.add_fallback' (was "Fontsets") (gnu.org) \directlua{ luaotfload.add_fallback ("fallbacktest", { "oldstandard:mode=harf;script=grek;color=0000FF;", "oldstandard:mode=harf;script=cyrl;color=0000FF;", "freeserif:mode=harf;script=arab;color=0000FF;", "freeserif:mode=harf;script=dev2;color=0000FF;", } ) } \setmainfont{latinmodernroman}[RawFeature={fallback=fallbacktest}] polyglossia Overleaf介绍利用polyglossia和fontspec显示多语言：Multilingual typesetting on Overleaf using polyglossia and fontspec - Overleaf polyglossia用于处理多种语言的显示，可以设置多种语言环境 \usepackage{polyglossia} \setmainlanguage{english} \setotherlanguage{korean} 使用polyglossia能解决一些问题： LuaTeX下使用多语言TrueType TTC字体TH-Times1需要搭配polyglossia xeCJK下使用pmhanguljamo宏包需要使用polyglossia配置korean环境 但与ctex会有一些冲突： polyglossia会覆盖ctex的scheme，如图表题注、目录标题会被替换成Figure、Table、Contents，需手动设置 % polyglossia参数控制图标题注，需启用setmainlanguage为english后起效 \setmainlanguage{english} \gappto\captionsenglish{\def\tablename{表}} \gappto\captionsenglish{\def\figurename{图}} \gappto\captionsenglish{\def\contentsname{目~~录}} \gappto\captionsenglish{\def\listfigurename{图~~片}} \gappto\captionsenglish{\def\listtablename{表~~格}} % 或使用caption宏包控制图标题注 \usepackage{caption} \captionsetup[figure]{name=图} \captionsetup[table]{name=表} XeTeX下polyglossia要置于ctex前，否则汉字显示失败 与xeCJK冲突，TH-Times字体使用ZWJ组合的emoji无法正常组合（如麻将红宝牌 🀔\char"200D🟥） 2.2 中文字体 LaTeX使用中文一般用ctex包，ctex在XeTeX下会包含xeCJK；而在LuaTeX下包含LuaTeX-ja，并且魔改了LuaTeX-ja的部分设置 CJK字体的设置与fontspec类似，比如设置正文为思源宋体，加粗为思源黑体，斜体为楷体 \setCJKmainfont{Source Han Serif SC}[ BoldFont={Noto Sans CJK SC}, % ItalicFont={KaiTi}, ItalicFont={AR PL KaitiM GB}, % TeX楷体 Script=CJK, ] \setCJKsansfont{Noto Sans CJK SC} \setCJKmonofont{Noto Sans Mono CJK SC} 由于ctex会把干涉字符的划分，因此要实现某些功能时，需将某些字符划给西文或中文。 ctex魔改了luatex-ja的设置，字符范围2、3 为ALchar，6为JAchar。下面是修改汉字和谚文的分区 % 给圈码数字分区，糅合THUThesis与https://www.cnblogs.com/coderzjz/p/15821966.html \ltjdefcharrange{6}{% %带圈字母数字,CJK汉字部首补充,【修改】CJK符号和标点,汉文训读符号,片假名语音扩展 "2460-"24FF, "2E80-"2EFF, "3000-"303F, "3190-"319F, "31F0-"4DBF, %CJK统一,CJK兼容,竖排形式,CJK兼容形式(竖排标点)，半角及全角字符 "4E00-"9FFF, "F900-"FAFF, "FE10-"FE1F, "FE30-"FE6F, "FF00-"FFEF, %假名补充 假名扩展A 小型假名扩展,带圈字母数字补充 带圈表意文字补充,CJK二三平面,变体选择符补充 "1B000-"1B16F, "1F100-"1F2FF, "20000-"3FFFF, "E0100-"E01EF, %【新增】圈1-10反白,CJK扩展A,注音符号,注音扩展 "2776-"277F, "3400-"4DBF, "3100-"312F, "31A0-"31BF,"1100-"11FF,"3130-"318F,"A960-"A97F} \ltjdefcharrange{3}{ "1100-"11FF,"3130-"318F,"A960-"A97F,"D7B0-"D7FF,"302E-"302F %谚文声调附点 302E 302F } \ltjdefcharrange{3}{ "AC00-"D7AF % 现代韩语音节,开启后ctex+polyglossia可谚文傍点，但正文CJK字体无法显示韩语 } 在xeCJK中使用 \xeCJKDeclareCharClass{CJK}{} 汉字分区 Unicode汉字在第0平面有CJK统一表意文字、CJK扩展A区、CJK兼容汉字；第2平面有CJK扩展B、C、D、E、F、I区和兼容增补；第3平面有扩展G、H区，总共10万余汉字。一般字体仅能支持第0平面的部分汉字，像思源宋体（Source Han Serif）只能覆盖全部的CJK统一区和扩展A，以及部分CJK兼容区汉字。Windows中有支持扩展B的SimSun-ExtB，支持第2平面的部分汉字但不全。 Unicode标准每年更新会在各区的空余处追加一些汉字，故一些旧的字体可能对已支持的区段也覆盖不全，如debian12源中Noto Serif CJK就比最新的思源宋体支持的字少。2025年将新增扩展J区，并在扩展C追加数个急用汉字2，未来第3平面将会收录篆书、金文、简帛文、陶文、鸟虫书等。3 支持全字集的字体有天珩字库、典迹汉字等，更多字体见维基百科:Unicode扩展汉字。由于字体单文件最多65536字符，想显示10万汉字只能分文件显示，TeX也支持汉字的分区设置字体，ctex为此也做了优化。 XeTeX下使用xeCJK原生设置CJK分区别名，并在字体中使用这些分区别名 %定义CJK字体分区 \xeCJKDeclareSubCJKBlock{P0-CJKpart}{"2FF0->"2FFF, "3100->"312F, "31A0->"31BF, "31C0->"31EF} %第0平面部分CJK相关 \xeCJKDeclareSubCJKBlock{CJKExtA}{"3400-> "4DBF} %CJK扩展A \xeCJKDeclareSubCJKBlock{CJKUnified}{"4E00 -> "9FFF} %CJK统一 \xeCJKDeclareSubCJKBlock{CJKCompat}{"F900-> "FAFF} %CJK兼容 \xeCJKDeclareSubCJKBlock{CJKCompat-Source}{"FA6E-> "FAFF} %CJK兼容，思源宋体不支持的部分 \xeCJKDeclareSubCJKBlock{SPUA}{ "E400 -> "E4DA , "E500 -> "E5E8 , "E600 -> "E6CE } %私用区 \xeCJKDeclareSubCJKBlock{P2}{ "20000 -> "2EE5F } %第2平面汉字（CJK扩展BCDEFI） \xeCJKDeclareSubCJKBlock{P3}{ "30000 -> "323AF } %第3平面汉字（CJK扩展GH） \xeCJKDeclareSubCJKBlock{P16}{ "100000 -> "10FFFF } %第16平面汉字（补充私用区B） %设置中文字体 \setCJKmainfont[ CJKCompat-Source=TH-Tshyn-P0, % 思源宋体CJK兼容区缺失的， P0-CJKpart=TH-Tshyn-P0, % 0平面部分字， P2=TH-Tshyn-P2, % 2平面， P3=TH-Tshyn-P1, % 3平面字交给 天珩字库 http://cheonhyeong.com/Simplified/download.html ]{Source Han Serif SC} %思源宋体 XeTeX下也可以设置fallback字体，当字集显示不全时即会调用备用字体 \xeCJKsetup{AutoFallBack} \setCJKfallbackfamilyfont{\CJKrmdefault}{{TH-Times},{TH-Tshyn-P0},{TH-Tshyn-P2},{TH-Tshyn-P1}} %CJKfallback字体列 LuaTeX下可也设置CJK字体分区，ctex为此提供了设置参数。在CJK字体设置中用AlternateFont设置分区字体 \ctexset { declarecharrange = { {P0-CJKpart} {"2FF0 -> "2FFF , "3100 -> "312F , "31A0 -> "31BF , "31C0 -> "31EF} , %P0的部分CJK {CJKCompat-Source} {"FA6E-> "FAFF}, %CJK兼容 思源宋体不支持的部分 {P2} { "20000 -> "2EE5F } , %第2平面汉字 {P3} { "30000 -> "323AF } , %第3平面汉字 } } \setCJKmainfont{Source Han Serif SC} %思源宋体 [ AlternateFont={ {P0-CJKpart,CJKCompat-Source} {TH-Tshyn-P0}, {P2} {TH-Tshyn-P2}, {P3} {TH-Tshyn-P1}, % 天珩字库 http://cheonhyeong.com/Simplified/download.html } ] 显示示例全文见：Unicode CJK扩展区 显示测试页面 - Sakiko's Blog (earlywolf.cn) 中文字体集 ctex有fontset参数指定加载的字库 windows用中易字库 ubuntu用思源宋体、思源黑体和TeX发行版自带的文鼎楷体 founder用方正字库，等等…… 预定义的中文字库还的字体预设： 基本都有的：\songti宋体，\heiti 黑体，\fangsong仿宋（ubuntu中没有）， \kaishu楷体 windows、founder 和macnew中有的：\lishu隶书，\youyuan幼圆 windows、macnew中有的：\yahei微软雅黑 macnew中有的：\pingfang苹方 ctex默认正文用宋体，粗体\textbf用黑体，斜体\textit、\textsl用楷体显示。 对于Pandoc转义的文档，粗体\textbf，斜体\emph，也会用黑体、楷体显示。 Pandoc转义的文档还会有删除线\sout，需要下面配置才能显示（如果你动过模板，输出的是\st那下面这两条重定义命令要反着写） %%删除线 \ifLuaTeX \usepackage{luacolor} \usepackage[soul]{lua-ul} %eisvogel模板所采用，配合markdown删除线 \newcommand*{\sout}[1]{\st{#1}} % \usepackage{ulem} %不支持中文 \fi \ifXeTeX \usepackage{xeCJKfntef} % \renewcommand{\st}[1]{\sout{#1}} \fi 上面说的\songti \heiti 等会调用CJK字体族zhsong zhhei等，这些也可自定义： \setCJKfamilyfont{zhsong}{Source Han Serif SC} [ UprightFont = *-Regular, BoldFont = *-Bold, ItalicFont = *-Regular, BoldItalicFont = *-BoldSC ] \setCJKfamilyfont{zhhei}{Noto Sans CJK SC} [ UprightFont = *-Regular, BoldFont = *-Bold, ItalicFont = *-Regular, BoldItalicFont = *-Bold ] 字符变形 TH-Times是天珩字库用于处理多语言复杂文本变形的字体，此节主要讨论此字体。见TH-Times核心说明书 (cheonhyeong.com)、蒙古文字变形规则说明 (cheonhyeong.com) 连字 TH-Times字体定义了多种连字，st ct Qu Th ff fi fí ft ff ffi ſ‍s 这些均会自动连字，另有数字2nd 12th等连字（2th 12nd等错误写法则不会连字） 但由于TH-Times启用了过多连字，也非像Open Type可调，因此西文正文最好用正常的字体，需要连字等特殊显示时再调用TH-Times %% 英文字体 \setmainfont{TeX Gyre Pagella}[Ligatures=TeX] \newfontfamily\fb{TH-Times} %手动fallback用TH-Times 标准化变体序列（Standardized Variation Sequence，SVS） 通过后接变体选择符来实现字符变体，变体选择符在"FE00-"FE0F有16个，另有在特殊用途平面"E0100-"E01EF扩充至256个，不过一般的字符只用到一两个 如八思巴文的反转形式是+VS01（"FE00），如 ꡖ "A856与 ꡖ︀ "A856 "FE00 位置变体 八思巴文的元音存在位置变体，词首词尾不一样 此特性可以通过[Script=Phags-pa]正常显示 \newfontfamily\psp{TH-Times}[Script=Phags-pa] %TH-Times修正了NotoSansPhagsPa的错误 彩色字符 LuaTeX下可显示彩色字符 更多特性请见本文示例仓库marvel084/LaTeXTest2024 (github.com) 谚文显示请见CTEX中文LaTeX文档中古谚文的显示、CTeX中文LaTeX文档中古谚文的显示 - 知乎 (zhihu.com) 三、带圈数字 参考：带圈数字 | Stone Zeng’s Site (stone-zeng.site) 带圈字母与数字在Unicode的码段并不连续： 样式 码段 常规 "24EA ⓪；"2460-"2473 ①-⑳；"3251-"325F ㉑-㉟；"32B1-"32BF ㊱-㊿ 反白 "24FF ⓿；"2776-"277F ❶-❿；"24EB-"24F4 ⓫-⓴ 无衬线 "1F10B 🄋； "2780-"2789 ➀-➉；等宽圈01F10D� 无衬线反白 "1F10C 🄌；"278A-" 2793 ➊-➓ 双线 "24F5-"24FE ⓵-⓾ 加框 "3248-"324F ㉈、㉉、㉊、㉋、㉌、㉍、㉎、㉏ 带圆括号 "2474-"2487 ⑴-⒇ 带点 "1F100 🄀；"2488-"249B ⒈-⒛ 带逗号 "1F101- "1F10A 🄁-🄊 带圆括号汉字 "3220-"3229㈠-㈩ 带圈汉字 "3280-"3289 ㊀-㊉ 方框汉字和六角括号汉字 "1F229 🈩 "1F214🈔 "1F22A🈪 "1F242🉂 "1F241🉁 分布在Unicode区段： U+2460..U+24FF 带圈字母数字 Enclosed Alphanumerics U+3200..U+32FF 中日韩带圈字符及月份 Enclosed CJK Letters and Months U+1F100..U+1F1FF 带圈字母数字补充 Enclosed Alphanumeric Supplement U+1F200..U+1F2FF 带圈表意文字补充 Enclosed Ideographic Supplement textcircledUnicode化 带圈数字可以由支持圈码的字体直接显示，也可以用LaTeX的\textcircled实现，不过后者会使用正文字体渲染，某些字体下（如Tex Gyre Termes）数字会突破圆圈。 xunicode-addon宏包提供了一种方式：在使用\textcircled时，如果有则自动转为Unicode对应字符显示，默认使用西文字体。ctex也会包含xunicode-addon，我们可以设置使圈码使用中文字体 首先圈码划给中文，以支持带圈数字unicode的直接显示 \usepackage{fontspec,xunicode-addon,ctex} \ifXeTeX \xeCJKDeclareCharClass{CJK}{%带圈数字划给CJK "24EA, % ⓪ "2460->"2473, % ①->⑳ "3251->"32BF, % ㉑->㊿ "24FF, % ⓿ "2776->"277F, % ❶->❿ "24EB->"24F4 % ⓫->⓴ } \fi \ifLuaTeX % 给圈码数字分区，糅合THUThesis与https://www.cnblogs.com/coderzjz/p/15821966.html % ctex 将带圈数字 U+2460–U+24FF 归入字符范围 3（ALchar），这里改回范围 6（JAchar） \ltjdefcharrange{6}{ %用不了这么多，可以适当删 %带圈字母数字,CJK汉字部首补充,【修改】CJK符号和标点,汉文训读符号,片假名语音扩展 "2460-"24FF, "2E80-"2EFF, "3000-"303F, "3190-"319F, "31F0-"4DBF, %CJK统一,CJK兼容,竖排形式,CJK兼容形式(竖排标点)，半角及全角字符 "4E00-"9FFF, "F900-"FAFF, "FE10-"FE1F, "FE30-"FE6F, "FF00-"FFEF, %假名补充 假名扩展A 小型假名扩展,带圈字母数字补充 带圈表意文字补充,CJK二三平面,变体选择符补充 "1B000-"1B16F, "1F100-"1F2FF, "20000-"3FFFF, "E0100-"E01EF, %【新增】圈1-10反白,CJK扩展A,注音符号,注音扩展 "2776-"277F, "3400-"4DBF, "3100-"312F, "31A0-"31BF,"1100-"11FF,"3130-"318F,"A960-"A97F} \fi 重定义钩子在使用 \textcircled时切换至中文字体 %% 带圈数字字体 https://stone-zeng.site/2019-02-09-circled-numbers % XeLaTeX 下需要把全体带圈数字都设置成 Default 类（上方有CJK了，不需要） % \xeCJKDeclareCharClass{Default}{"24EA, "2460->"2473, "3251->"32BF} % 将中文字体声明为（西文）字体族（我这思源宋缩放时会有问题，TH-Times会好些） % \newfontfamily\EnclosedNumbers{TH-Times} %天珩字库 \newfontfamily\EnclosedNumbers{Noto Serif CJK SC} % 放置钩子，只让带圈字符才需更换字体 \AtBeginUTFCommand[\textcircled]{\begingroup\EnclosedNumbers} \AtEndUTFCommand[\textcircled]{\endgroup} 脚注与note式参考文献脚注使用圈码及其格式配置见第3回【LaTeX参考文献格式】。 附 thuthesis模板处理圈码的方式，直接用数字往上加"245F，即使用"2460-"2469的带圈数字①-⑩显示，由于圈码的unicode区段并不连续，此方法也只能单页显示有限个脚注，这对于频用脚注的文章可能是不够的。 \newcommand\thu@circled[1]{% \ifnum#1 >10\relax \thu@warning{% Too many footnotes in this page. Keep footnote less than 10% }% \fi {\symbol{\the\numexpr#1+"245F\relax}}% } biblatex-gb7714-2015宏包提供的国标圈码脚注样式，是利用 \textcircled{\tiny\@thefnmark} 而在使用xunicode-addon宏包后，此命令生成的圈码在①-⑨会显示错误： 若仍想使用Unicode圈码，需要放弃国标样式，重新定义脚注的显示，如4中： \renewcommand\thefootnote{\textcircled{\@arabic\c@footnote}} circledtext biblatex-gb7714-2015的法学类样式示例5中使用circledtext显示圈码，这是一个中国人开发的绘制带圈数字的宏包，优势在于能显示反白圈码，能显示方、同心圆等轮廓，可以更改颜色和背景填充，功能十分丰富。 \usepackage{circledtext} \circledtextset{resize=real,height=1.5ex,boxlinewidth=0pt} \circledtext{1} 属于是一个还能看的程度。对于脚注引用，可以设置为红色。 \def\@makefnmark{\hbox{\@textsuperscript{\circledtext[charcolor=red,boxcolor=red]{\@thefnmark}}}} 四、中文URL LaTeX一般用\url{}显示URL链接，显示文内链接用\href{url}{text}，hyperref包含了url包。\url对含特殊字符的URL能正常显示，比如%可以在文中键入而不被注释。不过\url并不支持非拉丁字符，含有中文的链接一般要转义后再用\url显示。 \url{https://ctext.org/wiki.pl?if=gb&chapter=552474&remap=gb#纪载宝坻县记} \url{https://ctext.org/wiki.pl?if=gb&chapter=552474&remap=gb#%E7%BA%AA%E8%BD%BD%E5%AE%9D%E5%9D%BB%E5%8E%BF%E8%AE%B0} % #%&可以直接输入 在使用ctex宏包后，LuaTeX能显示\url中的汉字，而XeTeX中汉字无法显示，这应该与luatex-ja和xeCJK对字符的处理有关，LuaTeX汉字自动用CJK显示，XeTeX url中字符全用西文字体，特别是设置了url样式的话： \urlstyle{same} % 使用西文main字体 \urlstyle{rm} % 使用西文衬线字体 若要显示强制汉字可以换url字体： \newfontfamily\urlfontcjk{Noto Serif CJK SC} % 用于支持url的字体 \def\UrlFont{\urlfontcjk} 不过\url有个更致命的问题，无论LuaTeX还是XeTeX都无法使url在汉字处断行。想要彻底解决需换用href \url的问题： 无法在中文字符处换行 不会自动转义中文字符 cjk字符在xetex默认西文字体不支持显示 换用\href{url}{text}也有问题： 汉字处可断行，而英文处反倒无法正确换行 text中不能有特殊字符，如{ } $ & # % _ ~ ^ \ |这些 解决href无法在英文处断行的问题，biblatex-gb7714-2015 issue#50 的回复提供了一种使用seqsplit断行的方法 \usepackage{seqsplit} \href{#1}{\UrlFont\seqsplit{#1}} 不过链接中的特殊字符还需要手动转义，可以手动使用正则表达式替换，或定义钩子等方法自动替换，此处不絮。 对于参考文献条目URL含中文的情况，详见第3回【LaTeX参考文献格式】（还没写完），对biblatex和citeproc-lua引擎给出替换方法。特别是citeproc-lua能自动转义特殊字符，方便利用。下面仅简述： BibLaTeX 见biblatex-gb7714-2015 issue#50 的回复，判断URL是否会转义，会则替换成href显示原文： \usepackage{seqsplit} % \DeclareFieldFormat{urlraw}{\href{#1}{\UrlFont\seqsplit{#1}}} %url原文（urlraw）用\href显示 \renewbibmacro*{url}{% \iffieldsequal{url}{urlraw}{\printfield{url}}{\printfield{urlraw}}% 英文URL用url，含中文URL用urlraw } citeproc-lua 可以修改citeproc-lua源码，将citeproc-output.lua行2103原url改为href（需要seqsplit宏包），还利用了citeproc-lua自身的代码，将text中非法字符转义掉，就是中英文全用href显示了： function LatexWriter:write_link(inline, context) if inline.href == inline.value then -- URL - return string.format("\\url{%s}", inline.value) + return string.format("\\href{%s}{\\seqsplit{%s}}", inline.href, self:write_escaped(inline.value, context)) elseif context.engine.opt.wrap_url_and_doi then return string.format("\\href{%s}{%s}", inline.href, self:write_escaped(inline.value, context)) else return self:write_escaped(inline.value, context) end end http://cheonhyeong.com/Tools/Times.html 见TH-Times核心说明书 ↩ ↩ http://cheonhyeong.com/Simplified/download.html ↩ https://zh.wikipedia.org/wiki/中日韓統一表意文字 ↩ https://github.com/carlosal1015/latex-examples-1/blob/master/footnote-chinese-style.tex ↩ https://github.com/hushidong/biblatex-gb7714-2015/issues/183#issuecomment-1890462819 ↩
J4125 All In One主机安装软路由和代理分流的网络配置 本期为软路由系列的第二期，介绍All In One主机的网络环境与软路由网络相关配置。分为主路由的网络网络配置与旁路由的代理分流配置。 网络架构 网络拓扑 结合上期，位于客厅的软路由下接8+1光交换机，并用光纤连接至位于弱电箱的交换机用于连接各网络面板。两交换机间另使用网线相连作为冗余备用，这要求环路中的其中一台交换机具有环路功能。 布网时每个86面板预留一条CAT6网线和两条单模光纤，光模块选择拆机LC双纤光模块。 网络设备 网线：使用24AWG CAT6网线，穿线最多能2条网线1条光纤。若允许更粗网线可选择大唐电信的23AWG CAT6网线。 光纤：布线使用单模单纤光电复合缆，因此每管需要穿2条光纤。光电复合缆仅为了预留未来需求，相较光纤皮线更软更易盘旋。也可以选择并缆的单模单芯蝶形光纤。选择穿两条光纤是因为拆机二手双LC的光模块更便宜，光纤两侧直接打LC的冷接头。冷接子注意淘宝可以购买光电复合缆专用的LC冷接子，比普通光纤皮线的冷接子夹得更紧，需要预留的裸纤和涂覆层长度也与普通光纤皮线不同。 光纤冷接还需要红光笔+SC/LC转接头以测试通断。 冷接实战教程参见：家庭万兆光纤网络布网实践，附带光纤冷接教程，让光纤铺满你家，提前感受FTTR！_哔哩哔哩_bilibili 、秒掉5G？光纤布网战未来！Fiber Optical Yes！_哔哩哔哩_bilibili、万兆光纤布网实战攻略，让光纤铺满你家！_哔哩哔哩_bilibili 面板：末端光纤冷接，可以直接选择如下的法兰，插在普通的两口网络面板上。注意不要买倾斜开口的面板，这会导致打好冷接头的光纤由于86暗盒空间限制而不能插在面板上。若平式面板依然空间不足，可以考虑使用下面的异型86面板，将光纤盘在明盒中。 交换机：兮克2.5G交换机 8+1光 非管理（SKS1200-8GPY1XF）、8+1光管理型（SKS3200M-8GPY1XF） PC：另购2.5G螃蟹8156bUSB网卡，网卡驱动下载参见：TANK TR8156N Realtek USB RTL8156B 2.5G网卡 全系统驱动安装使用教程 - Tank电玩&米多贝克 (mi-d.cn)，这种2.5G网卡只是用默认驱动会导致不能跑满带宽。 主路由设置 DHCP与DNS配置 内网中架设AdGuard Home负责DNS解析，因此将路由DNS指向AdGuard服务器，并勾选DNS加速 为了区分正常用户与需要走旁路由代理的用户，将路由分为两个DHCP池，普通用户网关为主路由，DNS指向AdGuard；需要走代理的用户通过DHCP与MAC绑定接入第二个DHCP池，网关、DNS指向旁路由。这样即便旁路由挂了也不影响正常设备上网。 内网访问光猫 使路由能够DHCP到光猫的网段IP，能够互相通信。 参考：通过ikuai访问光猫管理界面 内外网设置——外网设置WAN1，接入方式选择基于物理网卡的混合模式，添加PPPoE拨号配置adsl1，同时添加DHCP配置vwan1。将PPPoE设置开启默认网关。这样软路由的WAN口会获取到光猫DHCP分配的IP地址。 防火墙 参见： iKuai爱快的IPv6防火墙设置，允许规则优先于阻断。iKuai默认不启用IPv6防火墙，必须要添加的规则： 禁止公网通过IPv6访问本地 允许本地通过IPv6访问公网 允许特定协议/端口通过IPv6访问内网特定用户 ::32c/::FFFF:FFFF:FFFF:FFFF #nginx ::741/::FFFF:FFFF:FFFF:FFFF #qbittorrent ::b05/::FFFF:FFFF:FFFF:FFFF #debian12 应用访问控制 在路由层面上禁用STUN、P2P和去广告。网页端阻止泄露IP可以使用防WebRTC泄露插件：WebRTC Control (google.com)等 接下来是代理与分流配置。 主路由代理分流（不采用） 参考：iKuai与Openwrt的有机结合：传统旁路由方案的完美替代 | JackieWu 缺点：主路由分出两个WAN口，代理数据多走一层NAT 旁路由代理分流 旁路由使用OpenClash软件做代理，同时在旁路由上启用基于DNS或流量嗅探的分流，使中国大陆的流量不过核心。 iStore扩展插件包： https://github.com/AUK9527/Are-u-ok/tree/main/x86 防火墙分流 iptables 只通过国内ipv6：探讨下有没有国内流量保留 ipv6, 国外流量禁用 ipv6 的优雅姿势 - V2EX，仅作参考 ip6tables -F FORWARD ip6tables -I FORWARD -d 240e::/18 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2408:8000::/20 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2409:8000::/20 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240a:c000::/20 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240c:c000::/20 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240a:4000::/21 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240a:8000::/21 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240b:8000::/21 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240c:8000::/21 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240d:4000::/21 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2408:4000::/22 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240c:4000::/22 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240d:8000::/24 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240f:4000::/24 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240f:8000::/24 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2400:dd00::/28 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 240c::/28 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2001:4510::/29 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2400:a980::/29 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2a0c:f480::/29 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2a0d:2480::/29 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2406:cf00::/30 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2001:250::/31 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2001:da8::/31 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -d 2403:800::/31 -j ACCEPT -m comment --comment "CHINA MAINLAND ipv6" ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ip6tables -A FORWARD -j REJECT MosDNS分流 在旁路由上搭建MosDNS服务器来做DNS分流。 参考： AdGuard-->MosDNS-->dnsmasq（主路由）：基于 DNS 的内网透明代理分流方案 (songchenwen.com) AdGuard-->dnsmasq-->MosDNS：OPenWRT 旁路由+MosDNS+open克拉什+AdGuard Home 傻瓜配置图文教程-恩山无线论坛 搭建公网DNS服务器：利用 Mosdns 和 AdGuardHome 搭建自己的 DNS (xukecheng.tech) dnsmasq-->OpenClash-->AdGuard-->MosDNS：OpenWrt: OpenClash + AdGuardHome + MosDNS + IPv6 共存配置 这里采用的方案：AdGuard-->dnsmasq-->MosDNS-->OpenClash Fake-IP，不需要分流的设备使用AdGuard192.168.2.11，利用缓存和DoH/DoT请求国内DNS；需分流设备送至旁路由192.168.2.2，经MosDNS分流后决定走Clash或是国内。 graph TD subgraph s1[AdGuard 192.168.2.11] B(AdGuard 53) end subgraph s2[旁路由 192.168.2.2] C(dnsmasq 53) D(MosDNS 5335) F[Fallback] Cl(Clash Fake-IP 7874) R[\Drop IPv6/] end A1[DNS Request]-->B B-->|需分流设备|C B--->|不分流设备|L A[DNS Request]--->C-->D D-->|国内ip|L[国内上游DNS] D-->|国内域名|L D-->|白名单|L D-->|未知|F[Fallback] F-->|国内ip|L F-->|国外ip|R D-->|国外ip|R D-->|国外域名|R D-->|黑名单|R R-->Cl-->Out[国外上游DNS] 缺点：AdGuard与MosDNS处均有缓存 优点：旁路由失效不影响正常设备上网 本方式还需要设置OpenClash防火墙规则，只允许fake-ipip流量转发到Clash iptables -t nat -D openclash -p tcp -j REDIRECT --to-ports $proxy_port #iptables -t nat -A openclash -m set --match-set telegram dst -p tcp -j REDIRECT --to-ports $proxy_port Clash DNS分流 采取方案：dnsmasq-->OpenClash-->AdGuard，用Clash的绕过大陆功能代替MosDNS分流。 启用OpenClash的绕过中国大陆功能，自定义DNS里Nameserver仅开启AdGuard Home，Fallback可勾选Cloudflare相关的。 DNS请求流程： graph LR subgraph s1[AdGuard LXC 192.168.2.11] B(AdGuard 53) end subgraph s2[旁路由 192.168.2.2] C(dnsmasq 53) D(Clash DNS 7874) F[Fallback] Cl(Clash Redirect 7892) end A1[DNS Request]---->B B--->|General|L[国内上游DNS DoH DoT] B-.->|需分流设备|C A[DNS Request]-->C-->D D-->|国内域名|B Cl-->Out[国外上游DNS DoH DoT] D-->|国外域名|Cl D-->|未知|F-->Cl 流量转发流程： graph LR A[tcp udp包] subgraph s1[旁路由 192.168.2.2] fw[防火墙]-->|国外ip|R fw-->|国外域名|R fw-->|命中规则|R fw--->|国内ip|C(出口) fw--->|国内域名|C R{{Drop IPv6}}-->B B(Clash Redirect 7892) end subgraph s2[主路由 192.168.2.1] NAT(NAT) end NAT-->Internet A-->fw B-->|代理数据|NAT C-->|原数据|NAT Openclash自动添加的NAT表 -A openclash -m set --match-set localnetwork dst -j RETURN -A openclash -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN -A openclash -p tcp -j REDIRECT --to-ports 7892 -A openclash_output -d 198.18.0.0/16 -p tcp -m owner ! --uid-owner 65534 -j REDIRECT --to-ports 7892 -A openclash_output -m set --match-set localnetwork dst -j RETURN -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN -A openclash_output -p tcp -m owner ! --uid-owner 65534 -j REDIRECT --to-ports 7892 国内流量不过Clash核心。 AdGuard 配置上游DNS并开启乐观缓存。 国内上游DNS：阿里DNS over HTTP3、DoT，dnspod DoH DoT # ali http3 h3://223.5.5.5/dns-query h3://223.6.6.6/dns-query # ali dot tls://223.5.5.5 tls://223.6.6.6 # dnspod dot tls://1.12.12.12 tls://120.53.53.53 # dnspod doh https://1.12.12.12/dns-query https://120.53.53.53/dns-query 广告屏蔽 订阅国内广告列表：GitHub - 217heidai/adblockfilters: 适用于AdGuard的去广告合并规则，每8个小时更新一次。 若观看斗鱼虎牙等PCDN直播卡顿，可用白名单放行：[误杀]虎牙、斗鱼有些直播间由于拦截，打开会很慢 · Issue #254 · privacy-protection-tools/anti-AD · GitHub Surge/Loon/Quantumult x 这些软件可在iOS客户端运行或在Mac mini上运行，充当软路由。与Clash相比在于多了插件/模块，可用于URL重写/中间人攻击/脚本，进而精确地去广告或解除地区限制。 推荐几个好用的Loon插件/模块/脚本： iRingo：GitHub - VirgilClyne/iRingo: 解锁完整的 Apple功能和集成服务 Loon插件仓库：GitHub - Peng-YM/Loon-Gallery: Loon Plugin Gallery / Loon 插件仓库 BoxJS：介绍 - BoxJs Open Clash设置 Open Clash官方Wiki：https://github.com/vernesong/OpenClash/wiki/ 配置文件结构 proxies 节点列表，包括机场订阅和自建节点 proxies-group 策略组，用于选择特定服务的出口 select 手动选择 url-test 自动选择延迟最低的节点 苹果 选择特定服务的出口 proxies-provider 订阅来源 rules 规则 RULE-SET,Spotify: 直连 RULE-SET,Apple: 苹果 rules-provider 规则集 Apple Telegram Spotify 游戏 dns nameserver fallback 基础设置 订阅、订阅转换 内核、代理模式 DNS、绕过大陆 高级设置 规则集 bbr阻塞控制 linux开启bbr echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p sysctl net.ipv4.tcp_congestion_control
J4125 All In One主机搭建pve，安装iKuai、OpenWRT、Adguard LXC、Debian12 LXC、Home Assistant OS。 本期开始是软路由安装与配置系列，一共计划三期，主要记录工控机安装虚拟化系统并搭建软路由、服务器、NAS、Docker等系统及其配置和使用过程。本文不作为教程，仅仅是up主初试All in One主机搭建的记录，仅供参考。 参考： 【软路由】J4125安装PVE7.3+iKuai+OpenWrt+NAS+Win10+Debian+CentOS_pve添加第二块硬盘_xuehu96的博客-CSDN博客 司波图文字：通用PVE AIO安装教程: 通用PVE集成软路由，KODI，基于LXC的Docker服务教程 (gitee.com) AIO从入门到如土 篇一：一文为你揭开一台all in one家庭服务器的神秘面纱_服务器_什么值得买 (smzdm.com) 一、宿主机 选用倍控J4125 4*2.5G网口小主机，安装16GB内存、2T SATA固态硬盘和螃蟹8156b 2.5GUSB网卡（做管理口用，虽然这机器USB只能跑2.0速度）。 网口接线 参考：家用软路由、NAS、All in one网络拓扑方案 - 知乎 (zhihu.com) 网口定义： 宿主机外部名称 宿主机设备名 宿主机pcie地址 软路由内设备名 ETH0 enp1s0 01:00.0 eth1 ETH1 enp2s0 02:00.0 eth2 ETH2 eno1 03:00.0 eth1 ETH3 enp4s0 04:00.0 硬盘分配 500G mSATA做宿主机系统盘和虚拟机储存空间，2T SATA固态直接挂载给LXC容器做下载空间。 flowchart LR subgraph sdb ["/dev/sdb 2TB"] O["挂载 - Debian12 LXC /mnt/ext - qbittorrent LXC /mnt/ext"] end subgraph sda ["/dev/sda 500GB"] subgraph 11[local 100G] A["100G PVE/ESXi"] end subgraph 22[local-lvm 375G] direction TB B[10G iKuai] C[2.5G OpenWRT] F[32G HAOS] G(10G qbittorrent LXC) H(10G Nginx LXC) I(20G AdGuard LXC) D("100G Debian12 LXC") end end 内存分配 LXC不会占用全部内存，KVM虚拟机会分配全部内存。 graph LR subgraph DRAM ["16GiB内存"] A[iKuai 2G] B[OpenWRT 4G] D[HAOS 4G] CDebian LXC 10G Eqbittorrent LXC 4G FNginx LXC 2G GAdGuard LXC 1G end esxi or pve？ esxi不能显示CPU温度？ 容易核显直通 esxi需封装i226、8156b驱动 esxi直通核显需要预留内存 esxi性能损失更小？但无法利用p-state，功耗更大？ 网卡驱动：关于RTL8156 USB 2.5G网卡的安装说明 - 哔哩哔哩 (bilibili.com) PVE7.3 与 ESXi7.0U3c 性能对比：https://kb.blockbridge.com/technote/proxmox-vs-vmware-nvmetcp/ PVE 8.0.3、ESXi 8.0U1、Unraid 6.12.4、Hyper-V和黑群晖 7.1.1虚拟性能的比较：https://youtu.be/hdDNNgnMPII?si=UzrYLOJv4TTvSxFt 结论：PVE在Geekbench跑分中落后ESXi 2到3个百分点，其余指标均低于ESXi百分之1以内。 二、PVE 8.0 2.1 开启IOMMU组 vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 中，添加intel_iommu=on 和 iommu=pt 2.2 虚拟机架构 graph TD AIO[(AIO)] --> PVE(PVE) ==> A([100 debian12 LXC]) PVE --> B[101 OpenWRT] PVE --> C[102 iKuai] PVE --> D[103 HAOS] PVE ==> E([104 qbittorrent]) PVE ==> F([105 Nginx]) PVE ==> G([106 AdGuard]) 2.3 PVE宿主机配置 pve8.0 Debian12 换清华源 vim /etc/apt/sources.list # 8.0清华源 deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware # security updates deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware vim /etc/apt/sources.list.d/pve-enterprise.list # 8.0官方企业付费订购源 deb https://mirrors.tuna.tsinghua.edu.cn/proxmox/debian/pve bookworm pve-no-subscription 修复： #修复更新时源报401错 echo "deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription" > /etc/apt/sources.list.d/ceph.list #下载官方授权加密秘钥证书 wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg pve-tools GitHub项目：ivanhao/pvetools: proxmox ve tools script apt update && apt -y install git && git clone https://github.com/ivanhao/pvetools.git cd pvetools ./pvetools.sh 用于显示CPU温度、调整CPU频率、快速PCI-E直通等。 2.4 PVE LXC容器 1）网络 100 Debian12 LXC 网卡eno1直通，且使用静态ip： nano /etc/pve/lxc/100.conf lxc.net.1.type: phys lxc.net.1.link: eno1 lxc.net.1.name: eth1 lxc.net.1.ipv4.address: 192.168.31.101/24 lxc.net.1.ipv4.gateway: 192.168.31.1 lxc.net.1.flags: up 容器内静态IP vim /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.2.10/24 gateway 192.168.2.1 # dns-* options are implemented by the resolvconf package, if installed dns-nameservers xxx dns-search your.search.domain.here iface eth0 inet6 dhcp firewall=1,gw=192.168.2.1, ,ip=192.168.2.10/24,ip6=dhcp 在PVE管理界面，容器的DNS设置中改为你想要的设置。 容器内网卡使用DHCP：为 LXC 配置网络 (lzz5235.github.io) vim /etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp iface eth0 inet6 auto 软路由处设置Debian12 LXC静态DHCP并网关指向旁路由，查看网关是否切换成功： # ip route show default via 192.168.2.2 dev eth0 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.100 2）核显“直通” 核显“直通”做硬解（LXC容器与pve共同使用核显） #lxc.apparmor.allow_nesting = 1 lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.apparmor.profile: unconfined pve 查看核显： # ls -l /dev/dri total 0 drwxr-xr-x 2 root root 80 Nov 23 21:39 by-path crw-rw---- 1 root video 226, 0 Nov 23 21:39 card0 crw-rw---- 1 root render 226, 128 Nov 23 21:39 renderD128 3）挂载硬盘 请采用by-id或by-uuid方式挂载分区 # by-id pct set 100 -mp0 /dev/disk/by-id/ata-GSL-2TB_0013204001102-part1,mp=/mnt/ext # by-uuid pct set 104 -mp0 /dev/disk/by-uuid/f42bcf36-3fee-400f-a8cb-bfaf2697872,mp=/mnt/ext 直接直通： brw-rw---- 1 root disk 8, 16 Nov 27 20:18 /dev/sdb brw-rw---- 1 root disk 8, 17 Nov 27 20:18 /dev/sdb1 #lxc.cgroup.devices.allow: b 8:16 rwm lxc.cgroup.devices.allow: b 8:17 rwm lxc.autodev: 1 lxc.hook.autodev: /var/lib/lxc/ID/mount-hook.sh lxc.mount.entry: /dev/sda1 /dev/sda1 bind,create=dir,optional 0 0 vim /var/lib/lxc/ID/mount-hook.sh #!/bin/sh mknod -m 777 ${LXC_ROOTFS_MOUNT}/dev/sda b 8 0 mknod -m 777 ${LXC_ROOTFS_MOUNT}/dev/sda1 b 8 1 2.5 PVE KVM虚拟机 虚拟机 CPU选Host 最小性能损耗；选项开启 QEMU GuestAgent ，虚拟机内安装qemu-guest-agent. RDM直通： qm set 101 --scsi1 /dev/disk/by-id/ata-GSL-2TB_0013204001102 核显直通： GRUB增加： intel_iommu=on initcall_blacklist=sysfb_init 更新grub update-grub 编辑黑名单：/etc/modprobe.d/pve-blacklist.conf blacklist i915 blacklist snd_hda_intel options vfio_iommu_type1 allow_unsafe_interrupts=1 更新initramfs update-initramfs -u -k all 重启pve update-pciids 101.conf args: -set device.hostpci1.x-igd-gms=1 hostpci1: 0000:00:02.0,legacy-igd=1,romfile=vbios.bin vbios 判断是否需要romfile cd /sys/bus/pci/devices/0000:00:02.0/ echo 1 > rom cat rom 三、ESXi 8.0U2 ESXi8.0U2 vCenter 封装i226-V、8156b驱动 UHD600核显直通支持 J4125 vCenter vcenter 封装驱动https://blog.csdn.net/myxsL/article/details/130989373 镜像来源：23年10月4日更新-ESXI 8.0 U2 ESXI 7.0 8.0系列，封包I225V/螃蟹USB驱动镜像-软路由,x86系统,openwrt(x86),Router OS 等-恩山无线论坛 (right.com.cn) 核显直通 开机释放核显权限： esxcli system settings kernel set -s vga -v FALSE 修改虚拟机配置文件 vi /vmfs/volumes/datastore1/debian12_esxi_xfce/debian12_esxi_xfce.vmx 添加： pciPassthru.use64bitMMIO="TRUE" pciPassthru.64bitMMIOSizeGB=64 （然而对于我的镜像和核显，这并没用，可能驱动不支持，或为reset bug，所以放弃ESXi转而投入PVE怀抱） 四、主路由 iKuai 设置WAN口与LAN口，设置WAN口PPPoE拨号账号密码，设置LAN口ip。 设置开启IPv6与DHCPv6 设置DHCP，DNS使用公共DNS，普通用户使用网关指向iKuai（192.168.2.1）；固定需要走代理的设备设置固定DHCP，并将网关指向代理服务器，本例中即旁路由OpenWRT192.168.2.2。 设置DNS服务器，可以与DHCP中设置相同，开启DNS加速。 五、旁路由 OpenWRT iStoreOS PVE官方安装教程：X86 PVE 安装 | 易有云产品中心 (linkease.com) pve下载工具 wget https://fw0.koolcenter.com/binary/other-tools/img2kvm pve下载镜像： wget https://fw0.koolcenter.com/iStoreOS/x86_64/istoreos-22.03.5-2023112413-x86-64-squashfs-combined.img.gz 虚拟机内安装Qemu-Guest-Agent opkg update opkg install qemu-ga iStore扩展插件包： https://github.com/AUK9527/Are-u-ok/tree/main/x86 六、Home Assistant OS 一键创建HAOS虚拟机脚本：Proxmox/vm/haos-vm.sh at main · tteck/Proxmox (github.com) 默认配置 2核4G 32GB硬盘 bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm.sh)" 安装插件与集成 安装ssh插件 使用第三方应用（如MobaXterm）生成ssh密钥对（为了debian12以上考虑，最好生成非RSA的），并填写SSH addon配置 username: hassio password: "" authorized_keys: - >- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO93BvbKjc//tyJ0HXTisr80F50cODQfJQcJscyTRz9V ed25519-key-20231126 sftp: false compatibility_mode: false allow_agent_forwarding: false allow_remote_port_forwarding: false allow_tcp_forwarding: false 安装HACS wget -O - https://get.hacs.xyz | bash - 通过HACS下载第三方集成需要网络代理，最好先配置好旁路由。 遇到PVE中显示内存占用高，但HomeAssistant中却显示内存占用很低，重启虚拟机即可。（与PVE的内存分配机制有关：HAOS/Proxmox ram jump usage after backup · Issue #847 · sabeechen/hassio-google-drive-backup (github.com)） Nginx反代信任 configuration.yaml文件中添加以下配置，参考：HTTP - Home Assistant (home-assistant.io) http: use_x_forwarded_for: true trusted_proxies: - 192.168.100.27 #反代服务器 - 172.30.33.0/24 #本机反代ip段 七、TrueNAS（未安装） RDM直通： qm set 104 --scsi1 /dev/disk/by-id/ata-GSL-2TB_0013204001102 qm set 105 --scsi1 /dev/disk/by-id/ata-GSL-2TB_0013204001102 TrueNAS Core基于FreeBSD，TrueNAS Scale基于Debian Linux。用TrueNAS为的是ZFS，但本机只有一块SATA硬盘，就直接挂在给Debian Server，不再考虑使用专用NAS系统。 八、Debian12 LXC 对于KVM虚拟机，需要关闭自动休眠。 关闭自动休眠 ： systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target 检查是否成功关闭 ： systemctl status sleep.target 返回信息出现sleep.target inactive(dead)即关闭成功 ssh密钥登陆 配置关闭密码访问，并生成ssh密钥对，以后客户端使用私钥登录。 编辑sshd_config vim /etc/ssh/sshd_config PermitRootLogin yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys PasswordAuthentication no # 活跃时间 ClientAliveInterval 900 ClientAliveCountMax 3 重启sshd systemctl restart sshd debian 12 openssh 9以上默认不提供RSA支持，请申请更安全的非RSA密钥。 另一方面关于 SHA-1 哈希算法，此前该算法被发现构造前缀碰撞攻击成本已降至低于 5 万美元（实际为 4.5 万美元），因此开发团队决定禁用 ssh-rsa 公钥签名算法。 有一些更好的算法可以替代，包括 RFC8332 RSA SHA-2 签名算法 rsa-sha2-256/512、ssh-ed25519 签名算法与 RFC5656 ECDSA 算法。目前这些算法在 OpenSSH 中都已经支持。 完整的更新说明查看：http://www.openssh.com/txt/release-8.2 使用ed25519算法生成密钥 ssh-keygen -t ed25519 公钥添加至授权名单 cd ~/.ssh #若使用普通用户登录，也需要相应拷贝 cat id_ed25519.pub > authorized_keys 将私钥id_ed25519拷贝至客户端用于ssh登录. 本地化 locale重设 dpkg-reconfigure locales 空格选中 en_US.UTF-8 UTF-8 zh_CN.UTF-8 UTF-8，defalut选择 en_US.UTF-8 UTF-8 时区重设 dpkg-reconfigure tzdata 选择Asia/Shanghai apt换源：与上文PVE换源相同 创建并使用普通账户 # 家目录/mnt/ext/gakki 创建账户 useradd -m -b /mnt/ext gakki # 若已有目录可选择不创建家目录 使用-M useradd -M -b /mnt/ext gakki # 创建密码 passwd gakki # 修改默认sh为zsh chsh -s /bin/zsh gakki Docker 安装docker与docker-compose apt update && apt install curl #curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh apt install docker-compose 换国内镜像源 vim /etc/docker/daemon.json { "registry-mirrors": [ "https://dockerproxy.com", "https://hub-mirror.c.163.com", "https://mirror.baidubce.com", "https://ccr.ccs.tencentyun.com" ] } 安装Jellyfin、Nextcloud、qbittorrent等容器将在下下期展开。 Syncthing 使用普通用户启用，避免权限问题 apt install syncthing 临时启动服务 systemctl enable syncthing@gakki --now vim ~/.config/syncthing/config.xml 找到127.0.0.1:8384，改为0.0.0.0:8384 重新启用服务 systemctl restart syncthing@gakki 九、各应用LXC qbittorrent 使用新建LXC搭建qbittorrent而非在Debian LXC中使用Docker安装qbittorrent，为的是获取完整的带宽与独立的IPv4与IPv6地址，从而更方便地设置不经过旁路由直连外网。 依旧使用Proxmox VE Helper脚本一键搭建： bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/qbittorrent.sh)" 默认配置2核2G，8GB存储。本例中qbittorrent LXC与旁路由共享eno1网口，因此现在pve中设置桥接自eno1的新Linux Bridge vmbr1 安装完成后挂载SATA硬盘作为下载存储，pve宿主机操作： pct set 104 -mp0 /dev/disk/by-uuid/f42bcf36-3fee-400f-a8cb-bfaf2697872,mp=/mnt/ext 默认WebUI登录账户密码admin changeme 为了pt下载可以在设置中更换掉默认监听端口，并且在主路由iKuai的ACL增加监听端口的传入规则（见下期）。 AdGuard LXC PVE Helper一键脚本，默认单核512MiB内存，2G硬盘。为了后期系统更新着想，请使用Manual模式手动改大内存、硬盘容量。 bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard.sh)" 安装完可以把WebUI端口调为80，方便HA使用。
本文记录梅林固件华硕路由器配置ipv6、防火墙、DDNSv6、Cloudflare代理与Nginx配置。 原本自2017年以来使用的联通300M宽带，EPON，有公网IP、可以多拨，能稳定700M下行，于是利用端口转发内网的文件服务器使用了很长时间。但自2023年9月起，天津联通部分地区拨号不再提供公网ipv4地址，因此将路由改为获取ipv6使用。 本例中光猫桥接，路由拨号并获取到公网ipv6，服务器获取到全球单播地址。域名配置 AAAA 记录指向服务器ipv6，服务器定期向域名DNS更新ip，并且正确配置路由器ipv6防火墙使只允许指向服务器的特定端口放行。 graph LR 1(域名) --> |AAAA| 2路由器防火墙 -->|放行| 3[服务器] 3 -.-> |DDNS更新| 1 ipv6构成 2408:8210:8433:160::1/64，2408:8210:8f03:20ed:6d4:c49d:2c42:a650/64 ipv6为128位ip地址，上面为两个典型的示例ipv6地址，/64为子网掩码表示该地址前64位是固定的。一般前64位为子网ID，表示某个具体的子网；后64位为接口ID，可以由设备MAC地址计算得到，表示用户的唯一标识。 上网设备的ipv6地址分为单播、组播和任播地址。由运营商得到每个设备的ipv6全球唯一单播地址，均为公网ip，以二进制001开头，即16进制2000::/3，如2408:8xxx 即为联通的网络。除此之外还有链路本地地址fe80::1/10、私网地址 fc0d::/7（类比ipv4的192.168.x.x）。 一般可以从运营商处获得/60的子网，有空余的4位可以最多再划分成最多16个子网，不过一般路由器倾向于只保留一个子网。 如240e:3c1:5665:1cd/60子网可划分成: 240e:3c1:5665:1cdf/64给IoT设备、240e:3c1:5665:1cd3/64给语音、240e:3c1:5665:1cd0/64用于上网 接口ID可以由MAC自动生成（如EUI-64算法），无需DHCPv6，这也是ipv6无状态自动配置的一大特点。华硕路由中ipv6地址的获取分为stateless和stateful，无状态获得的地址会自动变化，而有状态的地址可以划定地址池固定不变。为了能更好地写路由器ipv6防火墙配置，本文中采用stateful获取ipv6地址。 路由器设置 在华硕/梅林路由器中，开启ipv6，获取模式为native，状态为stateful，这样每个设备能获取到不变的接口ID。 IPV6防火墙 参考：路由器梅林固件如何设置IPV6端口转发_路由器_什么值得买 (smzdm.com) 服务器有后缀不变的公网ipv6后，还需配置路由器的ipv6防火墙使得服务器对应端口能被正确访问。在ipv6防火墙规则处添加你想放行的端口，内网ip和子网掩码实测这样写能够正常配置，注意前面ip的0不可省略。 0:0:0:0:0:0:0:1234/::FFFF:FFFF:FFFF:FFFF （上面参考文章中的方法实测iptables会录入不全，可以ssh进路由器，使用ip6tables --list 查看记录） 外网访问 DDNSv6 你内网的服务器现在有了公网ipv6，如何能访问到它呢？因为这是一个纯ipv6站，所以需要你的访问设备也支持ipv6，没有ipv6地址的设备是无法访问纯ipv6站点的。 可以使用 https://ipw.cn/ 和 https://ipv6ready.me/ 来检测自己设备对ipv6的支持状况。 若显示OK则您的设备可以正常访问ipv6网站！倘若您的设备没有通过测试（像是使用纯ipv4的代理服务器访问时）也是有办法能公网访问ipv6服务器的。 这里我们采用DNSPOD做域名解析，在服务器上使用ddns-go程序负责DDNSv6。 先在DNSPOD上配置一条指向服务器的AAAA记录 AAAA ddnsv6.example.com 2408:8210:8333:4cda::1234 之后在服务器上配置DDNS项目，本次使用ddns-go项目： https://github.com/jeessy2/ddns-go ddns-go也可以很方便的使用docker部署： sudo docker run -d --name ddns-go --restart=always --net=host -v /opt/ddns-go:/root jeessy/ddns-go 启动成功后通过 http://[server ip]:9876 访问web界面 这里填入DNSPOD的domain id和API Token，勾选启用IPV6并填如你需要DDNS到的子域名。 ddns-go也可以使用webhook启用通知功能，下面以方糖Server酱为例，可传入的参数可参考ddns-go说明文档。 https://sctapi.ftqq.com/YOUR_KEY.send?title=你的公网IP变了&desp=主人IPv6变了#{ipv6Addr},域名更新结果:#{ipv6Result},涉及变更的子域名为#{ipv6Domains} 这样每当ip地址变化时，你可以通过微信公众号等方式得到通知。 Nginx 反代 在ipv4配合端口转发使用时，我们采取单一子域名，使用不同映射端口配合Nginx反向代理来实现外网访问服务器的不同功能。而在使用ipv6+防火墙放行时，可以采用固定传输端口，不同子域名对应不同业务的方式访问服务器。 对于某些地区ipv6开放80、443端口，使用后者方法会更加方便，而天津联通矢志不渝地封禁80、8080和443端口，这一方法似乎也不很优雅。不过事实上固定传输端口有另外的好处。 前面说过纯ipv4设备无法直接访问纯ipv6站点，这一困境可以通过Cloudflare CDN来实现，即通过Cloudflare的代理实现6to4，让你的源站拥有ipv4，而Cloudflare仅能代理固定的几个端口。 我们给不同服务安排了不同的子域名，并在DNSPOD上申请了免费证书（期限一年不用白不用），在nginx中配置反向代理，把https端口挪到8443，在路由器防火墙只放行https端口，不放行http端口。 子域名与反向代理可以灵活搭配，例如访问 https://ddns.example.com:8443/ 为提示页面 访问 https://ddns.example.com:8443/ddns-go为ddns-go管理页面 访问https://ha.example.com:8443/为homeassistant管理页面 下面是一个含有反向代理地示例： # ddns.example.com server { listen [::]:880; listen [::]:8443 ssl http2; server_name ddns.example.com; #填写你需要的泛域名 charset utf-8; ssl_certificate /root/cert/ddns.example.com_nginx/ddns.example.com_bundle.pem; ssl_certificate_key /root/cert/ddns.example.com_nginx/ddns.example.com.key; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; ###### MCS Daemon deepin Reverse Proxy ###### location /mcs-daemon { #proxy_redirect off; proxy_pass http://127.0.0.1:24444/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #proxy_set_header Host $Host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Sec-WebSocket-Protocol wss; } } 阻止纯ip访问： 在Nginx 1.19.4或更高版本中可以直接使用ssl_reject_handshake on阻止握手，防止通过IP访问握手获得网站证书，进而同时获得网站域名与IP地址，参见 Cloudflare证书与Nginx安全 不过本deepin服务器使用debian10的古老源，只能设置返回错误页面来阻止纯ip访问。 # default ip access server { listen [::]:880 default_server; listen [::]:8443 ssl http2 default_server; server_name _; #SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则 # 阻止握手 # ssl_reject_handshake on; return 444; } Cloudflare 6to4 为了使无ipv6设备也能访问你的纯ipv6服务器，我们可以借助Cloudflare提供的免费的CDN代理，缺点是你需要另外一个域名，而且流量会在国外绕一圈，延迟更高。 在Cloudflare的DNS中新建一条CNAME记录，记得要开启小云朵Proxy： CNAME ddnscf.cloudflare.com ddns.example.com 之后我们就可以通过访问https://ddnscf.cloudflare.com:8443到达源服务器了。注意Cloudflare支持代理的端口有限，一定要将https端口设置成Cloudflare支持的端口： Network ports · Cloudflare Fundamentals docs 你可以直接使用Cloudflare解析做DDNS，也可以使用443转8443来绕过端口限制等等。
本文为Minecraft服务器搭建系列的第三篇。本文介绍了使用第三方面板管理Minecraft服务端的方法，本服务器采用的是MCSManager管理面板。 若Mermaid图表无法正常显示，刷新页面即可。 MCSManager 管理面板：MCSManager - A Lightweight Web Panel for Minecraft Server and more MCSManager是一个开源，分布式，轻量级，快速部署，支持大部分游戏服务端和控制台程序的管理面板，支持中英语言，一直在为 Minecraft，Terraria，Steam 游戏服务器管理员，运维人员和个人开发者提供健康的软件支持。 使用MCSManager管理Minecraft服务端进程。面板分为面板前端和守护进程，默认端口为23333和24444 如果你使用MCDR来管理Minecraft服务端，也可以使用次管理面板，即把启动服务端的脚本替换成启动MCDR的命令。 安装 一键安装： wget -qO- https://gitee.com/mcsmanager/script/raw/master/setup.sh | bash 安装后使用 systemd 启动： systemctl start mcsm-{daemon,web}.service // 启动面板 systemctl stop mcsm-{daemon,web}.service // 停止面板 systemctl restart mcsm-{daemon,web}.service // 重启面板 systemctl restart mcsm-web.service // 只重启面板 Web 服务 systemctl restart mcsm-daemon.service // 只重启面板守护进程服务 面板基本设置请参考官方文档：MCSManager 官方文档 在面板中可以设置崩溃后自动重启、开机自动启动等功能。 反代、配置TLS 参考： 配置 HTTPS (mcsmanager.com) 在VPS本地安装MCS面板，在Minecraft服务器也安装MCS面板。将Minecraft服务器的MCS daemon通过 frp TCP穿透到VPS，在VPS中配置Nginx反代与TLS，访问VPS的MCS面板前端，添加节点使用 wss. 管理面板 服务端（VPS）： flowchart LR client{{client}} --> |https://mc.domain| p1 p1--> |proxy| p2(443) subgraph Cloudflare p1(443) end subgraph VPS Nginx p2 --> |proxy_pass| p3[http://127.0.0.1:23333] end p3 --> p4[Node.js project] 使用Cloudflare代理，在DNS中添加指向VPS IP的A记录 配置VPS的Nginx主文件 TLS加密使用完全加密，服务器上使用Cloudflare申请的15年Origin证书。配置反代至MCSManager面板前端的端口 23333 # MCS 反代 server { listen 80; listen 443 ssl http2; server_name mc.域名; ssl_certificate /www/server/panel/vhost/cert/frps.goodnickname.ga/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/frps.goodnickname.ga/privkey.pem; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; location / { proxy_pass http://127.0.0.1:23333; proxy_redirect http://$host/ http://$http_host/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; } } 之后可通过 https://mc.domain 访问面板 守护程序 将Minecraft服务器的MCS守护程序由 frp 穿透至VPS，之后在VPS面板上访问远程节点。 服务端（VPS） graph LR p1--> |proxy| p2(443) subgraph Cloudflare p1(443) end subgraph VPS Nginx p2 --> |proxy_pass| p3[http://127.0.0.1:8088] end subgraph frps server p5(8088) end p3 ..-> p5 p5 --> bind_port([bind_port]) client{{client}} -->|wss://mcsd.domain|p1 设置frps服务端 [common] bind_port =端口 bind_addr = 0.0.0.0 vhost_http_port = http端口 vhost_https_port = https端口 authentication_method = token token = xxxxxxxxxxxxxxxxxxx heartbeat_timeout = 90 user_conn_timeout = 10a tcp_mux = true #log_file = /dev/null log_level = info log_max_days = 3 配合Minecraft服务器上的frpc，将客户端的 8082 端口，穿透至VPS的 8088 端口。 添加proxiedA记录 mcsd.域名 ，之后配置Nginx，将 mcsd.域名 的 443 反代至 8088，用以访问远程的MCS daemon # deepin MCS dameon Reverse Proxy server { listen 80; listen 443 ssl http2; server_name mcsd.域名; #填写你需要的泛域名 charset utf-8; ssl_certificate /www/server/panel/vhost/cert/frps.goodnickname.ga/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/frps.goodnickname.ga/privkey.pem; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; location / { resolver 8.8.8.8; proxy_ssl_server_name on; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8088; #端口号（5678）替换为daemon服务穿透的端口 } #access_log /.log; #若去除行首的注释符，则需要修改成你想要存放日志的位置 } 客户端（MC服务器） graph LR subgraph frpc client p4[frpc] end subgraph client Nginx p6(8082)-->|proxy_pass| p7[24444] end bind_port([bind_port])--> p4 -->|192.168.50.130|p6 在MC服务器中配置反代，将8082反代至24444。之后将8082穿透至VPS。 frpc 由于前文MC服务器已将25565穿透至腾讯云服务器，现使用副路由（192.168.50.13）配置frpc，将MC服务器（192.168.50.130:8082）穿透至面板所在VPS # frpc configuration [common] server_addr = VPS地址 server_port = 端口 token = xxxxxxxxxxxxxxxxx log_file = /dev/null log_level = info log_max_days = 3 tcp_mux = true protocol = tcp login_fail_exit = true user = ac86u-minor [mcsdaemon] type = tcp local_ip = 192.168.50.130 local_port = 8082 remote_port = 8088 use_encryption = true use_compression = true MC服务器客户端反代，将 8082 指向 24444 server { # Daemon 端公网访问端口 listen 8082; location / { # Daemon 端反向代理目标（配置与 Web 端处同理） proxy_pass http://localhost:24444/; root html; index index.html index.htm; proxy_set_header Host localhost; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header X-Cache $upstream_cache_status; add_header Cache-Control no-cache; expires 12h; } } frpc Client 为 AC86U 代理 至 192.168.50.130; frp 采用全tcp连接，无TLS； 不用http因为需要域名走443，不用https因为client不好用证书（http2https） 之后在VPS MCS 面板前端，添加远程节点，输入： wss://mcsd.域名 port:443 更新 如果您采用一键脚本更新，那么将天然支持 git 自动更新，前往 /opt/mcsmanager/web 和 /opt/mcsmanager/daemon 分别执行 git 拉取命令即可。 systemctl stop mcsm-{web,daemon} cd /opt/mcsmanager/web git pull npm install cd /opt/mcsmanager/daemon git pull npm install systemctl start mcsm-{web,daemon}复制到剪贴板错误已复制 如果您采用手动自定义安装，则需要手动进入两个目录中，执行 git pull 命令即可。 如果有多个节点，则需要覆盖所有 daemon 文件。 Linux 更新注意： 请勿使用一键安装脚本来更新，这样做的后果将会导致您的数据全部丢失。
本文为Minecraft服务器搭建系列的第二篇。本文介绍了Minecraft服务器的模组安装与服务器通过公网域名访问和frp内网穿透的相关操作。 若Mermaid图表无法正常显示，刷新页面即可。 MOD 承接上文，Minecraft服务端发的MOD基于Fabric，MOD可以在 CurseForge 和 Modrinth 上下载，可以在MC百科|最大的Minecraft中文MOD百科上查看详细的MOD介绍与依赖关系。另外如果你使用 HMCL 启动器，可以很方便的搜索和下载MOD，无法显示MOD列表的可将HMCL设置为测试版更新后重试。 目前服务器端安装的MOD如下： $ tree ./mods ./mods ├── architectury-6.3.49-fabric.jar ├── BBOutlineReloaded-2.5-1.19.2-fabric.jar ├── cammies-minecart-tweaks-1.7.jar ├── carpet-tis-addition-mc1.19.2-v1.42.0.jar ├── cloth-config-8.2.88-fabric.jar ├── create-fabric-0.5.0g-791+1.19.2.jar ├── CustomSkinLoader_Fabric-14.15-SNAPSHOT-348.jar ├── emotecraft-for-MC1.19.2-2.2.5-fabric.jar ├── fabric-api-0.66.0+1.19.2.jar ├── fabric-api-0.67.1+1.19.2.jar ├── fabric-carpet-1.19.2-1.4.84+v221018.jar ├── farmers-delight-fabric-1.19.X-1.3.9.jar ├── g4mespeed-1.3.2-mc1.19.jar ├── Geyser-Fabric.jar ├── holograms-1.4.0+1.19.2.jar ├── Jade-1.19.1-fabric-8.6.2.jar ├── journeymap-1.19.1-5.9.0beta2-fabric.jar ├── litematica-fabric-1.19.2-0.12.5.jar ├── lithium-fabric-mc1.19.2-0.10.2.jar ├── magiclib-0.5.37.jar ├── malilib-fabric-1.19.2-0.13.0.jar ├── midnightlib-fabric-1.0.0.jar ├── minimotd-fabric-mc1.19.2-2.0.9.jar ├── plusls-carpet-addition-1.19.2-0.2.5-alpha 0a76b23.jar ├── RoughlyEnoughItems-9.1.572.jar ├── starlight-1.1.1+fabric.ae22326.jar ├── syncmatica-1.19.1-0.3.5.jar ├── tweakeroo-fabric-1.19.2-0.14.3.jar ├── viafabric-0.4.9+21-main.jar ├── whereisit-1.19.2-1.14.13.jar └── worldedit-mod-7.2.12.jar 玩家想要进入服务器，需要安装如下的客户端MOD，本列表与服务端同步更新： 文件 - Nextcloud (goodnickname.cn) 采用的是HMCL的服务端可更新mod整合包，以后再出文介绍。 生存 · 信息辅助型MOD 可以参考黑山大叔的 1.19.3基础整合包 ，乔哥的 2021年推荐生存必装模组 上 、下，「啾」答疑：MC的一些配置 等，都非常详细。 S for Server, C for Client BBOutlineReloaded：BBOR，显示群系、光照强度、史莱姆区块等 【C，S可选】 fabric-carpet ：地毯模组，生存红石必备【SC】 Jade ：抬头显示【SC】 journeymap ：小地图和大地图，但1.19.2下会与BBOR冲突，不建议使用【SC】 plusls-carpet-addition ：PCA，自有协议与客户端同步服务端信息，如箱子物品预览（1.19.2需去Github里找）【SC】 carpet-tis-addition ：TIS Carpet扩展【SC】 RoughlyEnoughItems ：REI 物品管理器，显示合成配方【SC】 syncmatica ：共享投影原理图【SC】 whereisit ： 高亮显示附近物品容器【SC】 Durability Viewer ：耐久信息显示【C】 EasierVillagerTrading ：简单村民交易【C】 Inventory Profiles Next ：IPN，一件背包整理【C】 Replay Mod ：录像、回放【C】 Xaero's Minimap ：小地图【SC】 Xaero's World Map ：大地图【SC】 VoxelMap ：体素地图，优点是可以三界共享坐标，自动换算；更新缓慢【C】 mema全家桶： tweakeroo ：原版修改【SC】 Item Scroller ：物品快速合成 litematica ：投影，创建和还原建造蓝图 【SC】 Masa Gadget ：Masa全家桶的补充【C】 MiniHUD ：显示各种信息【C】 增强型MOD CustomSkinLoader ：非正版用户显示自定义皮肤【C】 emotecraft ：动作模组【SC】 g4mespeed ：改变服务器tick，其实此功能已有其他MOD提供【SC】 lithium-fabric ：锂，优化以提高帧数【SC】 starlight ：光照【SC】 holograms ：全息图，固定地点显示浮空标题【S】 viafabric ：跨版本兼容【SC】 worldedit ：创世神，快速建造【SC】 Better Beds ：床优化 【C】 Better Sodium Video Settings Button ：视频界面按钮调整【C】 Continuity ：连续的玻璃【C】 Controlling ：键位冲突显示【C】 Falling Leaves ：落叶【C】 Sodium ：钠，视频优化【C】 Sodium Extra ：钠 · 扩展【C】 Indium ：铟，钠的附属模组【C】 Iris Shaders ：Fabric的光影【C】 LambDynamicLights ：LDL，动态光源【C】 ModMenu ：列出安装的MOD【C】 Reese's Sodium Options ：RSO，Reese的钠视频界面【C】 API（基本两端需装）： architectury fabric-api magiclib malilib-fabric midnightlib Cloth Config API Fabric Language Kotlin libIPN 【C】 服务器美化： minimotd ：彩色自定义服务器描述与icon【S】 配置文件 config/MiniMOTD/main.conf icon文件目录 config/MiniMOTD/icons，需要存放 64*64 大小的图片 motd显示部分： motds=[ { # Set the icon to use with this MOTD # Either use 'random' to randomly choose an icon, or use the name # of a file in the icons folder (excluding the '.png' extension) # ex: icon="myIconFile" icon=random line1="<rainbow>1.19 Fabric 机械生存友好型服务器" line2="Fabric Create FarmerDelight Survival <gradient:blue:red>Server" }, { # Set the icon to use with this MOTD # Either use 'random' to randomly choose an icon, or use the name # of a file in the icons folder (excluding the '.png' extension) # ex: icon="myIconFile" icon=random line1="<blue>Early~ Wolf~ <red>有意思吗！" line2="管理面板： <gradient:red:green><click:open_url:'http://mc.goodnickname.ga'>https://mc.goodnickname.ga</click>" } ] Hologram Simplified Text Format - Placeholder API (pb4.eu) 额外模组 Cammie's Minecart Tweaks ：矿车锁链、速度调整 【SC】 farmers-delight-fabric ：农夫乐事 最高1.19.2【SC】 create-fabric ：机械动力 最高1.19.2 【SC】 间歇泉 使用Geyser模组可以使Bedrock版用户连接至JAVA服务器，但是需要二者版本对应，如果JAVA固定版本而Bedrock端版本随时更新，请配合ViaVersion插件使用，注意如果要持续提供Geyser互通服务，最好JAVA端保持纯净，不安装机械动力等内容型MOD。安装额外内容MOD的JAVA端服务器，即使使用Geyser与ViaVersion也无法完美互通。 Geyser-Fabric ：基岩版与JAVA版互通 参考：[Geyser-Farbic - Geyser Wiki (superiormc.cn)](https://geyser.superiormc.cn/other/geyser-farbic) 注意Geyser无法翻译MOD数据，配置文件在 config/Geyser-Fabric/config.yml 基岩版默认端口为19132，UDP 公网访问 VPS有公网IP，可以方便的从公网访问。本服务器部署在本地，需要使用DDNS或内网穿透的方式将服务器暴露在公网。之后可通过ip地址访问Minecraft服务器。若想通过域名连接Minecraft服务器，还需配置域名解析。 端口转发 由于我的出口宽带有公网IP，可以借助华硕路由器的华硕DDNS实现公网访问，仅需要在路由中做端口转发： 服务名称 外部端口 内部端口 本地 IP 地址 通信协议 来源 IP Minecraft 25565 25565 192.168.50.130 TCP Minecraft-Bedrock 19132 19132 192.168.50.130 UDP 内网穿透 如无公网IP，可以使用内网穿透的方案，需要一台服务器作为中转，将客户端的端口点对点穿透，也相当于反代。 我是用腾讯云的VPS作为服务器，使用 frp 穿透，国内访问延迟很低，但是速度受限于VPS的带宽。 参考：文档 | frp (gofrp.org) frp安装 从Github下载压缩包：Releases · fatedier/frp (github.com) wget https://github.com/fatedier/frp/releases/download/v0.46.1/frp_0.46.1_linux_amd64.tar.gz 解压缩下载的压缩包，将其中的 frpc 拷贝到内网服务所在的机器上，将 frps 拷贝到具有公网 IP 的机器上，放置在任意目录。 tar -xzvf frp_0.46.1_linux_amd64.tar.gz 编写配置文件，先通过 ./frps -c ./frps.ini 启动服务端，再通过 ./frpc -c ./frpc.ini 启动客户端。 frps 服务端配置 [common] # 穿透服务的端口 bind_port =端口 bind_addr = 0.0.0.0 # http服务的端口（本例不适用） vhost_http_port = 端口 # 认证方式：token authentication_method = token token = xxxxxxxxxxxx heartbeat_timeout = 90 user_conn_timeout = 10a tcp_mux = true # 服务端管理面板 端口 dashboard_addr = 0.0.0.0 dashboard_port = 端口 # dashboard对应的用户名/密码 dashboard_user = admin dashboard_pwd = password 服务端通过./frps -c ./frps.ini 启动。 使用 systemd 管理 frps 服务： vim /etc/systemd/system/frps.service [Unit] # 服务名称，可自定义 Description = frp server After = network.target syslog.target Wants = network.target [Service] Type = simple Restart=on-failure RestartSec=5s # 启动frps的命令，需修改为您的frps的安装路径 ExecStart = /path/to/frps -c /path/to/frps.ini [Install] WantedBy = multi-user.target 使用 systemctl start frps 启动服务。 frpc 客户端 [common] # 公网服务器的地址 server_addr = 地址 server_port = 端口 authentication_method = token token = xxxxxxxxxxxxxxxxxx protocol = tcp tcp_mux = true user = deepin #log_file = /dev/null log_level = info log_max_days = 3 # TCP穿透 [mcjava] type = tcp local_ip = 127.0.0.1 local_port = 25565 remote_port = 25565 [mcbedrock] type = udp local_ip = 127.0.0.1 local_port = 19132 remote_port = 19132 客户端通过 ./frpc -c ./frpc.ini 启动。 域名解析 添加指向Minecraft服务器IP地址的A记录，如果是家用服务器，可以使用DDNS或内网穿透。 如果您的Minecraft服务器不使用默认端口25565，可以配置SRV解析： _minecraft._tcp.xxx.com 300 class SRV 1 0 25565 mc.goodnickname.cn
本文利用回退源使用第二域名DDNS指向Cloudflare实现自选IP，并借助定时脚本自动优选最佳IP 使用Cloudflare做DNS解析的域名，开启Proxy小云朵后可以获得CDN服务，以提高线路不好或是被墙的ip的访问性。当然启用Proxy后连接的好坏也取决于用户到Cloudflare的连接质量，Cloudflare提供了一些固定的泛播ip，用户如果连接至延迟更高的ip反而会获得“减速”效果。因此本文提供一种方式来定期优选Cloudflare ip并指向自己的域名。 一、Cloudflare回退源设置自定义主机名 Cloudflare Saas文档：Cloudflare for SaaS · Cloudflare for Platforms docs 参考：Cloudflare for SaaS实现CF自选IP | CDN - 放养平凡 (btwoa.com) 已往可以使用Worker等方法，现在似乎不再奏效，但现在可以使用Cloudflare提供的回退源即SaaS功能实现DDNS和优选IP。你需要两个域名： 域名A： a.com 使用Cloudflare解析，作为回退源 域名B：b.com 使用其他DNS解析（本文以DNSPod为例），作为自定义域名 使用回退源的方法能够实现多个替身指向同一二级域名，如1.b.com 2.c.com 均指向 fallback.a.com，你可以把fallback.a.com作为你需要加速的博客等网站。如果你的网站大多时间是在国内访问，那完全可以隐藏作为中转的fallback.a.com，仅向用户透露b.com，这样也便于统一做SEO。 自定义域名与回退源的关系如下图所示： graph LR A(Client) --> B --> |A记录|C D --> |proxy|E(Server) subgraph DNSPOD B(1.b.com) end subgraph Cloudflare C[泛播IP 自选] --> |回退源|D(fallback.a.com) end 设置回退源 本文中回退源为fallback.a.com，需要是在Cloudflare中添加DNS记录并开启Proxy的二级域名。 在CLoudflare设置面板的SSL/TLS --> 自定义主机名 中添加回退源并等待初始化完成即可。初次使用可能要求绑定银行卡或PayPal账户，选择免费的套餐即可。 添加自定义域名 本文中使用的自定义域名为1.b.com ，当然你可以添加多个自定义域名。在CLoudflare设置面板的SSL/TLS --> 自定义主机名 中添加自定义主机名： 在这里选择TXT验证，Cloudflare会提供你用于鉴权和证书验证的两条TXT记录，将其添加至你的DNS解析（如DNSPod） _cf-custom-hostname.1 xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx 1 "ca3-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 接下来需要先将自定义域名CNAME到回退源，待Cloudflare验证成功后删除CNAME记录，再添加指向Cloudflare泛播IP的A记录。 1 CNAME fallback.a.com 之后在使用Cloudflare自选IP的时候，记得先禁用此CNAME记录。 二、Cloudflare 自选 IP Cloudflare提供了一些泛播IP（参见官方公布的IP 范围 | Cloudflare），通过脚本测试优选延迟最低的ip，并设置自定义域名 1.b.com指向这些ip便可实现优化Clouflare连接的作用。 优选IP脚本使用项目：XIU2/CloudflareSpeedTest: 「自选优选 IP」测试 Cloudflare CDN 延迟和速度，获取最快 IP ！ 按照项目说明使用，克隆到本地： git clone https://github.com/XIU2/CloudflareSpeedTest.git 在关掉代理的电脑上运行此脚本，得到本机连接Cloudlfare最优的ip，将最优的ip添加至自定义主机名的A记录 1 A 103.21.244.0 并禁用此前的CNAME记录，用户在访问1.b.com时即可获得指向Cloudflare站点的最优连接。 CloudflareST脚本的使用语法： #设置单个IP延迟测试的次数为10 ./CloudflareST -t 10 三、DDNS-Cloudflare-Dnspod 为了定时优选Cloudflare IP并自动修改DNS解析，我们需要DDNS脚本来完成这一操作。 采取方案：openwrt定时优选Cloudflare IP并更新到dnspod_哔哩哔哩_bilibili 作者提供了使用CloudflareST优选ip，并通过DNSPod的API调整A记录指向，实现DDNS的功能。 忠告：请不要使用freenom的免费域名使用Cloudflare服务。 使用前请务必观看原作者视频或阅读博客。若原作者博客打不开，可以从这里下载原作者提供的脚本。 本文此脚本部署在国内的VPS上，方便定时DDNS，不同终端优选的IP可能在不同网络环境下访问性不同（可以选择不同线路分开解析）。 具体使用步骤为： 3.1 下载脚本并初始配置 下载ddns脚本压缩包，将其解压至与CloudflareST同一目录 编辑 ip.sh，关闭停用openwrt代理插件功能：我们仅借用脚本的ddns功能，故需将下面一行 ##openwrt科学上网插件配置 #优选节点时是否自动停止科学上网服务 true=自动停止 false=不停止 默认为 true pause=true 改为false 3.2 获取DNSPod参数 a) 配置DNSPod Token： 在https://console.dnspod.cn/account/token/token页面，选择DNSPod Token，新建一个，记住名称、ID和Token。 编辑 ip.sh，将ID、Token填入下面一行： #登录令牌"ID,Token" LOGIN_TOKEN="替换密钥ID,替换密钥Token" b) 配置域名ID 在DNSPod的域名/域名设置里可以找到Domain ID 编辑 ip.sh，将Domain ID填入下面一行： #域名ID DOMAIN_ID=替换域名ID 子域名为二级自定义主机名，本例中即 1.b.com ，将 1填入下面一行 #子域名 SUB_DOMAIN=替换子域名 c) 配置子域名ID 在上面几条配置好后，编辑 ip.sh 最后一行，将其改为 ##执行 . ip_sub 获取子域名ID . ip_ddns 测速并DDNS . ip_sub 保存后，运行 ip.sh： bash ip.sh 在返回的消息中即可获得 id 替换到ip.sh #子域名ID RECORD_ID=替换子域名ID 注意：如果你有多个线路的A记录，并分别优选IP（例如联通指向104.16.35.219，默认指向162.159.58.70），那么执行ip_sub会返回两个id ，请确认你选择了正确的那一个。 3.3 定时运行脚本 待上述配置完成后，将ip.sh最后一行改回 ##执行 . ip_sub 获取子域名ID . ip_ddns 测速并DDNS . ip_ddns 将测试延迟次数改大以获得更精确的丢包率结果 #延迟测速次数；单个 IP 延迟测速次数，为 1 时将过滤丢包的IP，TCP协议；(默认 4 次 ) CFST_T=5 之后，运行脚本，等待结果，查看DNSPod是否有更改日志 bash ip.sh 添加crontab每小时执行脚本1次 crontab -e 0 * * * * cd /home/gakki/Documents/scripts_archive/CloudFlareST && bash ip.sh &>/dev/null 2>&1
介绍Cloudflare提供的几种网站HTTPS加密方法与提高网站安全性的方式，同时介绍防止通过域名暴露IP的方法，和阻断IP访问握手，进而防止获取域名的方法，提高网站的安全性。 Cloudflare的TLS安全设置 使用Cloudflare解析域名的一大重要原因就是其免费的CDN（Proxy）功能，这需要至少访问者到Cloudflare之间使用TLS加密。Cloudflare提供了灵活、完全和严格三种方案。灵活（flexible）表示用户浏览器与Cloudflare使用Cloudflare提供的证书加密，而完全（Full）和严格（strict）需要Cloudflare与源服务器通信也需要加密。 使用灵活模式加密的站点不需要服务器配置证书，若服务器申请了证书，请选择完全加密模式。 源服务器证书 Cloudflare 源证书是 Cloudflare 颁发的免费 TLS 证书，可以安装在源服务器上，以方便使用 HTTPS 的访问者进行端到端加密。 Cloudflare提供的源服务器证书有效期为15年，供严格加密模式使用。只能用于通过Cloudflare代理的TLS加密。 新增选择泛域名 example.com、*.example.com ，新增PEM格式证书和私钥。您可以粘贴至宝塔面板等应用。 客户端证书——防止暴露IP 参见：如何避免Cloudflare背后的源站被恶意访问 | Mayx的博客 Cloudflare 官方文档：Authenticated origin pull · Cloudflare SSL/TLS docs Cloudflare提供了经过身份验证的源服务器拉取功能，即Authenticated Origin Pulls (mTLS)，根据官方文档介绍，简单原理即为在TLS的基础上增加一层握手，能够有效的防止泄露源站IP。 部署步骤： 根据Cloudflare部署步骤，下载Cloudflare提供的证书，并部署在源服务器上 以Nginx为例，先将证书转换成crt格式： openssl x509 -in authenticated_origin_pull_ca.pem -out cloudflare.crt 将Nginx server 中启用客端验证： # Cloudflare 客户端认证 ssl_client_certificate /etc/nginx/certs/cloudflare.crt; ssl_verify_client on; 在Cloudflare/TLS/源服务器页面下，开启“经过身份验证的源服务器拉取”后，即可保护源站。 DNSSEC 域名系统安全扩展（英语：Domain Name System Security Extensions，缩写为DNSSEC）是Internet工程任务组（IETF）的对确保由域名系统 （DNS）中提供的关于互联网协议（IP）网络使用特定类型的信息规格包。它是对DNS提供给DNS客户端（解析器）的DNS数据来源进行认证，并验证不存在性和校验数据完整性验证，但不提供机密性和可用性。 DNSSEC 验证可以保护 DNS 数据，也可使这类数据在 DNS 以外的应用程序中值得信赖，因此，为域名部署 DNSSEC，有利于互联网安全，并可加强应对攻击能力。 请阅读Cloudflare文档了解DNSSEC是如何工作的，开启DNSSEC需要去域名注册商添加Cloudflare提供的认证信息。 在腾讯云注册的域名可以参考此文配置：Cloudflare配置DNSSEC-腾讯云开发者社区-腾讯云 (tencent.com) 需要注意Cloudflare给出的配置与腾讯云对应的是： 关键标签：密钥标记 加密算法：算法 摘要类型：摘要类型 摘要：摘要 其中加密算法13 在腾讯云中的对应是 ECDSA Curve P-256 with SHA-25 HSTS HSTS 是 HTTP 严格传输安全（HTTP Strict Transport Security）的缩写。启用HSTS后服务器会拒绝未加密的连接，强制HTTPS加密访问，用户不能绕过无效的证书。 如何从浏览器的 HSTS 缓存中删除域？ 参考：什么是HSTS，为什么要使用它？ - 知乎 (zhihu.com) 在设置 HSTS 并测试它时，可能需要清除浏览器中的 HSTS 缓存。 如果你设置 HSTS 不正确，你可能会访问网站出错，除非你清除数据。 下面是几种常用浏览器的方法。 还要注意，如果你的域在 HSTS 预加载列表中，清除 HSTS 缓存将是无效的，并且无法强制进行 HTTP 连接。 要从 Chrome HSTS 缓存中删除一个域名，请按照以下步骤操作： 访问 chrome://net-internals/#hsts 在 Delete domain security policies下的文本框中输入要删除的域 点击文本框旁边的 Delete 按钮 之后，你可以检查移除是否成功： 在 Query HSTS/PKP domain 下的文本框中输入要验证的域 点击文本框旁边的 Query 按钮 返回应该是 not found Nginx配置HTTPS安全 IP访问时拒绝握手 需要Nginx版本大于 1.19.4可以使用本功能，本例中Nginx 版本1.22.1，添加default_server服务器，对443端口拒绝握手 # Block IP access server { listen 80 default_server; server_name _; server_name 1.2.3.4; #return 403; return 301 https://$host$request_uri; } server{ listen 443 ssl http2 default_server; server_name _; server_name 1.2.3.4; #SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则 # 阻止握手 ssl_reject_handshake on; # Cloudflare 客户端认证 ssl_client_certificate /www/server/panel/vhost/cert/cloudflare.crt; ssl_verify_client on; #tmp tls ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; error_page 497 https://$host$request_uri; #SSL-END }
记录在LaTeX使用中的心得，仅为笔记，文章有待重排。 Mac VSCode+LaTeX Workshop 引用文献编译方式 参照：https://www.bilibili.com/video/BV1TD4y1D7YV/ 在 settings.conf 中的 latex-workshop.latex.recipes 里添加： { "name": "xelatex -> bibtex -> xelatex*2", "tools": [ "xelatex", "bibtex", "xelatex", "xelatex" ] }, 使用xelatex编译，再使用bib生成引用文献，再使用xelatex两次，编译成功。 引用的方式： 啦啦啦\cite{hadoop-env} \bibliographystyle{IEEEtran} %引用风格 \bibliography{thesis} %./thesis.bib (beamer同样适用) 多文档管理 参照TJU-Thesis GIT管理 git ignore文件 .DS_Store .texpadtmp .stfolder .vscode # main.pdf tjumain.pdf # tmp files of ppt,excel documents ~$* ~$figures.xlsx ~$figures.pptx *.toc *.synctex(busy) *.aux *.bbl *.blg *.log *.synctex.gz *.fls *.fdb_latexmk *.out *.thm $\LaTeX$ 公式 妈咪说LaTeXLive帮助文档：在线LaTeX公式编辑器-帮助文档 (latexlive.com) 不同字体： \begin{array}{c} \mathscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathbb{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ ABCDEFGHIJKLMNOPQRSTUVWXYZ \\ \boldsymbol{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \end{array} $$ \begin{array}{c} \mathscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathbb{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ ABCDEFGHIJKLMNOPQRSTUVWXYZ \\ \boldsymbol{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \\ \mathsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ} \end{array} $$ 文件格式排布 页眉 小写c表示只有中央，大写C表示除了中央，还可能有两边。 \pagestyle{fancy} \fancyhead[c]{ \includegraphics[scale=0.5]{figures/school} \@cheading} % 首页页眉格式 \fancyfoot[c]{\thepage} lstlisting [firstnumber=100] %第一个数字为100 [firstnumber=last] %起始行数为上一段lstlisting环境结尾的行数 [caption={MyCode1}] %说明 [caption={[Code2] An very important code}] %可分别添加一个短的和长的caption [label=Code1] % 标签 [title=Code1] %可以去掉label产 \begin{lstlisting}[language=Python,caption=Import \lstinline{meta_demos},label={lst:df_list}] #导入数据表 #表头 meta_header = sc.textFile("/ZHANGYIMING/csgodata/archive/esea_meta_demos.part1.csv").first() #raw data 创建RDD meta_1_RDD = sc.textFile("/ZHANGYIMING/csgodata/archive/esea_meta_demos.part1.csv").filter(lambda x:x !=meta_header).map(lambda x: x.split(",")) meta_2_RDD = sc.textFile("/ZHANGYIMING/csgodata/archive/esea_meta_demos.part2.csv").filter(lambda x:x !=meta_header).map(lambda x: x.split(",")) \end{lstlisting} \begin{lstlisting}[language=Python,firstnumber=last] meta_df.show(5) \end{lstlisting} 行间代码（抄写） 普通\verb可能产生缩进。 \verb| | \lstinline{} 图片 \begin{figure}[htpb] \centering \includegraphics[width=\linewidth]{figures/hierachical} \caption{Hierachical Structure} \label{fig:hirs} \end{figure} 图片组 \begin{figure}[htbp] \centering %图片全局居中 \subfigbottomskip=2pt %两行子图之间的行间距 \subfigcapskip=-5pt %设置子图与子标题之间的距离 \subfigure[\lstinline{dmg} Schema]{ \includegraphics[width=0.48\linewidth]{figures/dmg-schema}} \subfigure[\lstinline{kill} Schema]{ \includegraphics[width=0.48\linewidth]{figures/kill-schema}} \\ \subfigure[\lstinline{grenades} Schema]{ \includegraphics[width=0.48\linewidth]{figures/gre-schema}} %\quad \subfigure[\lstinline{mm} Schema]{ \includegraphics[width=0.48\linewidth]{figures/mm-schema}} \caption{Schemas of the rest of DataFrames} \label{fig:othsche} \end{figure} 两行两列 \begin{figure}[htbp] \centering %图片全局居中 \subfloat[\lstinline{dmg} Schema]{ \includegraphics[width=0.48\linewidth]{figures/dmg-schema}} \subfloat[\lstinline{kill} Schema]{ \includegraphics[width=0.48\linewidth]{figures/kill-schema}} \\ \subfloat[\lstinline{grenades} Schema]{ \includegraphics[width=0.48\linewidth]{figures/gre-schema}} %\quad \subfloat[\lstinline{mm} Schema]{ \includegraphics[width=0.48\linewidth]{figures/mm-schema}} \caption{Schemas of the rest of DataFrames} \label{fig:othsche} \end{figure} subcaptionbox \begin{figure}[htbp] \centering %图片全局居中 \subcaptionbox{hitbox records}{ \includegraphics[height=16em]{figures/hitbox-ct}} \subcaptionbox{hitbox damages}{ \includegraphics[height=16em]{figures/hitbox-sum}} \caption{Records and damages counting of different hitbox}\label{fig:hitbox-raw} \end{figure} 表格组 \begin{table}[htbp] \caption{Hitboxes Statistics}\label{tab:pwnono1} \vspace{1em} \centering \begin{subtable}[c]{0.3\textwidth} \centering \begin{tabular}{llr} \toprule hitbox & count \\ \midrule Chest & 4225631 \\ Stomach & 1811283 \\ Head & 1478655 \\ Generic & 1394708 \\ RightArm & 715480 \\ RightLeg & 333583 \\ LeftLeg & 298783 \\ LeftArm & 258125 \\ 8 & 21934 \\ \bottomrule \end{tabular} \caption{records} \end{subtable}\hspace*{0.4cm} \begin{subtable}[c]{0.7\textwidth} \centering \begin{tabular}{llrrr} \toprule hitbox & tot\_dmg & hp\_dmg & arm\_dmg \\ \midrule Chest & 115286584.0 & 102746528.0 & 12540056.0 \\ Head & 110507583.0 & 96296187.0 & 14211396.0 \\ Stomach & 57601555.0 & 50948744.0 & 6652811.0 \\ RightArm & 19570309.0 & 17501191.0 & 2069118.0 \\ Generic & 17688686.0 & 14860317.0 & 2828369.0 \\ RightLeg & 7112794.0 & 7112794.0 & 0.0 \\ LeftArm & 6935885.0 & 6165103.0 & 770782.0 \\ LeftLeg & 6319436.0 & 6319436.0 & 0.0 \\ 8 & 566094.0 & 496159.0 & 69935.0 \\ \bottomrule \end{tabular} \caption{damages} \end{subtable} \hfill \vspace{\baselineskip} \end{table} 跨栏表格 \begin{multicols}{2} %\caption{Example }\label{tab:hahahahaha} \vspace{0.5em}\centering % \resizebox{\textwidth}{12em}{ \let\mcnewpage=\newpage \makeatletter \renewcommand \newpage{ %欺骗分栏为分页 \if@firstcolumn \hrule width\linewidth height0pt \columnbreak \else \mcnewpage \fi } \begin{supertabular}{llr} \toprule {} & wp & count\_h \\ \midrule 2 & USP & 130791 \\ 15 & P2000 & 15398 \\ 2 & USP & 130791 \\ 15 & P2000 & 15398 \\ 3 & Glock & 116769 \\ \bottomrule \end{supertabular}%} \vspace{\baselineskip} inner site or outer site. Before we do that though, we have to define what is considered Inner/Outer site. Using some basic rectangles, I can draw sites on the map and then define them via simple top-left, bottom-right coordinates. First determine the boundaries of bomb sites. Defining the callout and make up a function returning callout flag. \end{multicols} 图表并排 (11条消息) Latex图表并列_御风而行Carrie的博客-CSDN博客_latex 图表并列 并排显示使，minipage 间不要空行！ \begin{figure}[h!] \centering \begin{minipage}[t]{.49\linewidth} \centering \tabcaption{Winning rounds}\label{tab:winrd-site} \begin{tabular}{lrr} \toprule {} & \multicolumn{2}{l}{count} \\ bomb\_site & A & B \\ map & & \\ \midrule de\_cache & 1819 & 1375 \\ de\_cbble & 346 & 434 \\ de\_dust2 & 2123 & 1537 \\ de\_inferno & 1065 & 938 \\ de\_mirage & 2544 & 1955 \\ de\_overpass & 428 & 557 \\ de\_train & 257 & 204 \\ \bottomrule \end{tabular} \end{minipage} \begin{minipage}[t]{.49\linewidth} \centering \figcaption{Bomb Planting Counts}\label{fig:bscount2} \includegraphics[height=18em]{figures/xiuzheng} \end{minipage} \end{figure} textwidth：版面宽度 linewidth：栏宽 正则表达式 \\subfloat\[([\s\S]*?)\]\{ 空 空行 \vspace{2em} 空格 \quad 颜色 settings "latex-utilities.liveReformat.enabled": true, "latex-utilities.formattedPaste.image.template": [ "\\begin{figure}[!htb]", "\t\\centering", "\t\\includegraphics[$1]{${imageFilePath}}", "\t\\caption{${imageFileNameWithoutExt/[-]/ /}}", "\t\\label{fig:${imageFileNameWithoutExt}}", "\\end{figure}", "" ], "latex-utilities.formattedPaste.useAsDefault": true,
Minecraft服务器搭建相关文章已分开发布，此为本系列的第一篇。本文介绍了Minecraft JAVA Fabric端MOD服务器的基本搭建过程。 若Mermaid图表无法正常显示，刷新页面即可。 概览 目前服务器已无人问津，暂不考虑升版本，现在此文仅作为一个记录。 服务器地址：mc.goodnickname.cn 模式：自我定位为模组 生电 · 机械 服 版本：JAVA 1.19.2 Fabric MOD：机械动力（create），农夫乐事（delight）和诸多辅助性mod 注意事项： 客户端需安装相应MOD才能服务器 服务器不定期开放，无白名单，无正版验证 在机械动力没有新版的fabric支持前，暂不升级1.20 服务器 本次开服经历仅抱着试验的态度，若想要人数更多、更稳定、跑MOD的Minecraft服务器，请选择更强性能的物理服务器，本文仅供参考。 以下是FAQ： 为什么选择笔记本？ 闲置不用，作为家庭x86服务器，刚好尝试搭建Minecraft服务端 为什么选择Linux系统？ 配置老旧只能装Linux，而且Linux能提供更多的服务 目前Minecraft服务端运行在本地（旧笔记本上），存档定期会存到Aternos上的镜像服和腾讯云的“冷备份”服务器中。 电脑为2012年的ThinkPad X230，配置为4核8G，CPU i5-3230M，内存 两条DDR3 ，加装了SATA SSD。 系统为基于Debian的Deepin Linux 20.8 （19年为了体验Deepin装的，就一直没换） $ uname -a Linux deepin-server 5.15.77-amd64-desktop #1 SMP Wed Nov 9 15:59:34 CST 2022 x86_64 GNU/Linux 运行状态： 服务器峰值功耗在20W以内，高负载运行温度也基本在50多度，使用10年后依然能平稳运行。 系统盘换成SSD后，游戏不再崩溃，各服务的运行速度明显增加。 由于服务器还承担下载服务和Home Assistant服务，因此最多给MC开6GB内存，对于模组服少量用户也可以使用。 搭建过程 因为想要传统生电服的性能提高mod和后期加装机械动力这样的mod，于是选择了fabric端开服，一般来说这对服务器的性能要求很高，但介于玩家人数不多，也能正常运行。 JAVA环境 高版本Minecraft需要Java16以上的环境，这里选择直接安装jdk-18，debian系可以从Oracle官网下载 .deb 包 Java Archive Downloads - Java SE 18 (oracle.com) wget https://download.oracle.com/java/18/archive/jdk-18.0.2.1_linux-x64_bin.deb 然后使用 dpkg 安装 sudo dpkg -i jdk-18.0.2.1_linux-x64_bin.deb 添加环境 sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-18/bin/java 1100 将默认JAVA环境切换到jdk-18 sudo update-alternatives --config java 选择路径为 /usr/lib/jvm/jdk-18/bin/java 作为 /usr/bin/java 之后启动Minecraft服务端会自动选择JAVA 1.18 安装Minecraft Server 我们致力于构建比较vanilla的 生存 服务器，所以选择了Fabric 端用于安装辅助MOD Fabric is a lightweight, experimental modding toolchain for Minecraft. 在Minecraft官网（或是官方启动器中）下载服务器 jar 包 官方：https://www.minecraft.net/en-us/download/server 版本存档：https://mcversions.net/ 可不执行此步骤，之后通过Fabric Installer下载Minecraft服务器包 下载Fabric Installer Fabric Installer 下载：https://fabricmc.net/use/server/ curl -o installer.jar https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.1/fabric-installer-0.11.1.jar 运行Installer 创建Minecraft文件目录 mkdir -p ~/minecraft/mc-119-fabric cd ~/minecraft/mc-119-fabric 安装MC服务端 # 运行 Fabric Installer java -jar installer.jar server -mcversion 1.19.2 -downloadMinecraft # 删除 Fabric Installer rm installer.jar 启动服务器 参考 Installing a Fabric Server without a GUI # 重命名 Jar 文件 mv server.jar vanilla.jar mv fabric-server-launch.jar server.jar echo "serverJar=vanilla.jar" > fabric-server-launcher.properties 同意EULA协议： Eula | Minecraft echo "eula=true" > eula.txt 启动 Minecarft 服务器 java -jar server.jar nogui 首次启动时间较长，请耐心等待，当出现如下提示时即启动成功 [03:11:12] [Server thread/INFO]: Done (15.698s)! For help, type "help" 启动成功后会生成配置文件，确认可成功启动后，先输入 stop 关闭服务端。 修改 server.properties 参考wiki：server.properties - Minecraft Wiki，最详细的我的世界百科 (fandom.com) 主要修改以下几项： #允许飞行 allow-flight=true #游戏难度 困难 difficulty=hard #设定函数的默认权限等级 建议更改为4 function-permission-level=4 #服务器最大玩家数限制 max-players=10 #在线（正版）验证 开启后会禁止非正版用户登录 online-mode=false #是否开启白名单 white-list=false 服务器端口默认为 25565 ，若不做SRV解析的话，使用默认就好。 启动脚本 如果不使用MCDR、MCSManager这种第三方管理工具或面板，那么可以新建个脚本方便启动Minecraft服务端。当然后文会介绍使用MCSManager和MCDR管理Minecraft服务端的方法。 参考：教程/架设服务器 - Minecraft Wiki，最详细的我的世界百科 (fandom.com) 编辑 run.sh # ~/minecraft/mc-119-fabric/run.sh java -Xmx6200M -jar server.jar nogui 基础参数： -Xms 初始内存大小，-Xmx 最大内存大小 性能优化参数： java -jar -Xms(视情况) -Xmx(视情况) -server -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M <jar文件> nogui 为了使服务端后台运行，可以使用虚拟屏幕 screen，基本操作为： #建立新进程 screen -S mc119 #重新连接进程，如没有则新建 screen -r mc119 #列出进程 screen -ls 将进程切到后台：Ctrl + A + D 结束进程： kill 进程号即可，进程号由 screen -ls 查看 当然如果使用MCSM守护程序管理Minecraft服务端的话，便不需要使用screen命令了。