🐶 Sync 2025-11-02 14:26:26
This commit is contained in:
22
luci-app-mosdns/Makefile
Normal file
22
luci-app-mosdns/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-mosdns
|
||||
PKG_VERSION:=1.6.16
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI Support for mosdns
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+mosdns +jsonfilter +curl +v2ray-geoip +v2ray-geosite +v2dat
|
||||
|
||||
PKG_MAINTAINER:=sbwml <admin@cooluc.com>
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/mosdns
|
||||
/etc/mosdns/cache.dump
|
||||
/etc/mosdns/config_custom.yaml
|
||||
/etc/mosdns/rule
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/display/autorefresh.min.js
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/display/autorefresh.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(u){"use strict";function f(e,t){clearTimeout(t.timeout),u.off(window,"mouseup",t.hurry),u.off(window,"keyup",t.hurry)}u.defineOption("autoRefresh",!1,function(e,t){function o(){i.display.wrapper.offsetHeight?(f(0,r),i.display.lastWrapHeight!=i.display.wrapper.clientHeight&&i.refresh()):r.timeout=setTimeout(o,r.delay)}var i,r;e.state.autoRefresh&&(f(0,e.state.autoRefresh),e.state.autoRefresh=null),t&&0==e.display.wrapper.offsetHeight&&((r=(i=e).state.autoRefresh={delay:t.delay||250}).timeout=setTimeout(o,r.delay),r.hurry=function(){clearTimeout(r.timeout),r.timeout=setTimeout(o,50)},u.on(window,"mouseup",r.hurry),u.on(window,"keyup",r.hurry))})});
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/lint.min.css
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/lint.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.CodeMirror-lint-markers{width:16px}.CodeMirror-lint-tooltip{background-color:#ffd;border:1px solid #000;border-radius:4px 4px 4px 4px;color:#000;font-family:monospace;font-size:10pt;overflow:hidden;padding:2px 5px;position:fixed;white-space:pre;white-space:pre-wrap;z-index:100;max-width:600px;opacity:0;transition:opacity .4s;-moz-transition:opacity .4s;-webkit-transition:opacity .4s;-o-transition:opacity .4s;-ms-transition:opacity .4s}.CodeMirror-lint-mark{background-position:left bottom;background-repeat:repeat-x}.CodeMirror-lint-mark-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=)}.CodeMirror-lint-mark-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==)}.CodeMirror-lint-marker{background-position:center center;background-repeat:no-repeat;cursor:pointer;display:inline-block;height:16px;width:16px;vertical-align:middle;position:relative}.CodeMirror-lint-message{padding-left:18px;background-position:top left;background-repeat:no-repeat}.CodeMirror-lint-marker-warning,.CodeMirror-lint-message-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=)}.CodeMirror-lint-marker-error,.CodeMirror-lint-message-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=)}.CodeMirror-lint-marker-multiple{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:right bottom;width:100%;height:100%}.CodeMirror-lint-line-error{background-color:rgba(183,76,81,.08)}.CodeMirror-lint-line-warning{background-color:rgba(255,211,0,.1)}
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/lint.min.js
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/lint.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}(function(p){"use strict";var h="CodeMirror-lint-markers",g="CodeMirror-lint-line-";function u(t){t.parentNode&&t.parentNode.removeChild(t)}function v(t,e,n,o){t=t,e=e,n=n,(i=document.createElement("div")).className="CodeMirror-lint-tooltip cm-s-"+t.options.theme,i.appendChild(n.cloneNode(!0)),(t.state.lint.options.selfContain?t.getWrapperElement():document.body).appendChild(i),p.on(document,"mousemove",a),a(e),null!=i.style.opacity&&(i.style.opacity=1);var i,r=i;function a(t){if(!i.parentNode)return p.off(document,"mousemove",a);var e=Math.max(0,t.clientY-i.offsetHeight-5),t=Math.max(0,Math.min(t.clientX+5,i.ownerDocument.defaultView.innerWidth-i.offsetWidth));i.style.top=e+"px",i.style.left=t+"px"}function l(){var t;p.off(o,"mouseout",l),r&&((t=r).parentNode&&(null==t.style.opacity&&u(t),t.style.opacity=0,setTimeout(function(){u(t)},600)),r=null)}var s=setInterval(function(){if(r)for(var t=o;;t=t.parentNode){if((t=t&&11==t.nodeType?t.host:t)==document.body)return;if(!t){l();break}}if(!r)return clearInterval(s)},400);p.on(o,"mouseout",l)}function a(s,t,e){for(var n in this.marked=[],(t=t instanceof Function?{getAnnotations:t}:t)&&!0!==t||(t={}),this.options={},this.linterOptions=t.options||{},o)this.options[n]=o[n];for(var n in t)o.hasOwnProperty(n)?null!=t[n]&&(this.options[n]=t[n]):t.options||(this.linterOptions[n]=t[n]);this.timeout=null,this.hasGutter=e,this.onMouseOver=function(t){var e=s,n=t.target||t.srcElement;if(/\bCodeMirror-lint-mark-/.test(n.className)){for(var n=n.getBoundingClientRect(),o=(n.left+n.right)/2,n=(n.top+n.bottom)/2,i=e.findMarksAt(e.coordsChar({left:o,top:n},"client")),r=[],a=0;a<i.length;++a){var l=i[a].__annotation;l&&r.push(l)}r.length&&!function(t,e,n){for(var o=n.target||n.srcElement,i=document.createDocumentFragment(),r=0;r<e.length;r++){var a=e[r];i.appendChild(M(a))}v(t,n,i,o)}(e,r,t)}},this.waitingFor=0}var o={highlightLines:!1,tooltips:!0,delay:500,lintOnChange:!0,getAnnotations:null,async:!1,selfContain:null,formatAnnotation:null,onUpdateLinting:null};function C(t){var n,e=t.state.lint;e.hasGutter&&t.clearGutter(h),e.options.highlightLines&&(n=t).eachLine(function(t){var e=t.wrapClass&&/\bCodeMirror-lint-line-\w+\b/.exec(t.wrapClass);e&&n.removeLineClass(t,"wrap",e[0])});for(var o=0;o<e.marked.length;++o)e.marked[o].clear();e.marked.length=0}function M(t){var e=(e=t.severity)||"error",n=document.createElement("div");return n.className="CodeMirror-lint-message CodeMirror-lint-message-"+e,void 0!==t.messageHTML?n.innerHTML=t.messageHTML:n.appendChild(document.createTextNode(t.message)),n}function l(e){var t,n,o,i,r,a,l=e.state.lint;function s(){a=-1,o.off("change",s)}!l||(t=(i=l.options).getAnnotations||e.getHelper(p.Pos(0,0),"lint"))&&(i.async||t.async?(i=t,r=(o=e).state.lint,a=++r.waitingFor,o.on("change",s),i(o.getValue(),function(t,e){o.off("change",s),r.waitingFor==a&&(e&&t instanceof p&&(t=e),o.operation(function(){c(o,t)}))},r.linterOptions,o)):(n=t(e.getValue(),l.linterOptions,e))&&(n.then?n.then(function(t){e.operation(function(){c(e,t)})}):e.operation(function(){c(e,n)})))}function c(t,e){var n=t.state.lint;if(n){for(var o,i,r=n.options,a=(C(t),function(t){for(var e=[],n=0;n<t.length;++n){var o=t[n],i=o.from.line;(e[i]||(e[i]=[])).push(o)}return e}(e)),l=0;l<a.length;++l){var s=a[l];if(s){for(var u=null,c=n.hasGutter&&document.createDocumentFragment(),f=0;f<s.length;++f){var m=s[f],d=m.severity;i=d=d||"error",u="error"==(o=u)?o:i,r.formatAnnotation&&(m=r.formatAnnotation(m)),n.hasGutter&&c.appendChild(M(m)),m.to&&n.marked.push(t.markText(m.from,m.to,{className:"CodeMirror-lint-mark CodeMirror-lint-mark-"+d,__annotation:m}))}n.hasGutter&&t.setGutterMarker(l,h,function(e,n,t,o,i){var r=document.createElement("div"),a=r;return r.className="CodeMirror-lint-marker CodeMirror-lint-marker-"+t,o&&((a=r.appendChild(document.createElement("div"))).className="CodeMirror-lint-marker CodeMirror-lint-marker-multiple"),0!=i&&p.on(a,"mouseover",function(t){v(e,t,n,a)}),r}(t,c,u,1<s.length,r.tooltips)),r.highlightLines&&t.addLineClass(l,"wrap",g+u)}}r.onUpdateLinting&&r.onUpdateLinting(e,a,t)}}function s(t){var e=t.state.lint;e&&(clearTimeout(e.timeout),e.timeout=setTimeout(function(){l(t)},e.options.delay))}p.defineOption("lint",!1,function(t,e,n){if(n&&n!=p.Init&&(C(t),!1!==t.state.lint.options.lintOnChange&&t.off("change",s),p.off(t.getWrapperElement(),"mouseover",t.state.lint.onMouseOver),clearTimeout(t.state.lint.timeout),delete t.state.lint),e){for(var o=t.getOption("gutters"),i=!1,r=0;r<o.length;++r)o[r]==h&&(i=!0);n=t.state.lint=new a(t,e,i);n.options.lintOnChange&&t.on("change",s),0!=n.options.tooltips&&"gutter"!=n.options.tooltips&&p.on(t.getWrapperElement(),"mouseover",n.onMouseOver),l(t)}}),p.defineExtension("performLint",function(){l(this)})});
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/yaml-lint.min.js
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/addon/lint/yaml-lint.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(o){"object"==typeof exports&&"object"==typeof module?o(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],o):o(CodeMirror)}(function(n){"use strict";n.registerHelper("lint","yaml",function(e){var r=[];if(!window.jsyaml)return window.console&&window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run."),r;try{jsyaml.loadAll(e)}catch(o){e=o.mark,e=e?n.Pos(e.line,e.column):n.Pos(0,0);r.push({from:e,to:e,message:o.message})}return r})});
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/codemirror.min.css
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/codemirror.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/codemirror.min.js
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/codemirror.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/libs/js-yaml.min.js
vendored
Normal file
2
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/libs/js-yaml.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/mode/yaml/yaml.min.js
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/mode/yaml/yaml.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var n=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(e,i){var t=e.peek(),r=i.escaped;if(i.escaped=!1,"#"==t&&(0==e.pos||/\s/.test(e.string.charAt(e.pos-1))))return e.skipToEnd(),"comment";if(e.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(i.literal&&e.indentation()>i.keyCol)return e.skipToEnd(),"string";if(i.literal&&(i.literal=!1),e.sol()){if(i.keyCol=0,i.pair=!1,i.pairStart=!1,e.match("---"))return"def";if(e.match("..."))return"def";if(e.match(/\s*-\s+/))return"meta"}if(e.match(/^(\{|\}|\[|\])/))return"{"==t?i.inlinePairs++:"}"==t?i.inlinePairs--:"["==t?i.inlineList++:i.inlineList--,"meta";if(0<i.inlineList&&!r&&","==t)return e.next(),"meta";if(0<i.inlinePairs&&!r&&","==t)return i.keyCol=0,i.pair=!1,i.pairStart=!1,e.next(),"meta";if(i.pairStart){if(e.match(/^\s*(\||\>)\s*/))return i.literal=!0,"meta";if(e.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==i.inlinePairs&&e.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(0<i.inlinePairs&&e.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(e.match(n))return"keyword"}return!i.pair&&e.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^\s,\[\]{}#&*!|>'"%@`])[^#:]*(?=:($|\s))/)?(i.pair=!0,i.keyCol=e.indentation(),"atom"):i.pair&&e.match(/^:\s*/)?(i.pairStart=!0,"meta"):(i.pairStart=!1,i.escaped="\\"==t,e.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});
|
||||
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/theme/dracula.min.css
vendored
Normal file
1
luci-app-mosdns/htdocs/luci-static/resources/codemirror5/theme/dracula.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;color:#f8f8f2!important;border:none}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,.1)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:#fff}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-type,.cm-s-dracula span.cm-variable-3{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:#fff!important}
|
||||
@@ -0,0 +1,457 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
var callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
function getServiceStatus() {
|
||||
return L.resolveDefault(callServiceList('mosdns'), {}).then(function (res) {
|
||||
var isRunning = false;
|
||||
try {
|
||||
isRunning = res['mosdns']['instances']['mosdns']['running'];
|
||||
} catch (e) { }
|
||||
return isRunning;
|
||||
});
|
||||
}
|
||||
|
||||
function renderStatus(isRunning) {
|
||||
var spanTemp = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
|
||||
var renderHTML;
|
||||
if (isRunning) {
|
||||
renderHTML = spanTemp.format('green', _('MosDNS'), _('RUNNING'));
|
||||
} else {
|
||||
renderHTML = spanTemp.format('red', _('MosDNS'), _('NOT RUNNING'));
|
||||
}
|
||||
|
||||
return renderHTML;
|
||||
}
|
||||
|
||||
async function loadCodeMirrorResources() {
|
||||
const styles = [
|
||||
'/luci-static/resources/codemirror5/theme/dracula.min.css',
|
||||
'/luci-static/resources/codemirror5/addon/lint/lint.min.css',
|
||||
'/luci-static/resources/codemirror5/codemirror.min.css',
|
||||
];
|
||||
const scripts = [
|
||||
'/luci-static/resources/codemirror5/libs/js-yaml.min.js',
|
||||
'/luci-static/resources/codemirror5/codemirror.min.js',
|
||||
'/luci-static/resources/codemirror5/addon/display/autorefresh.min.js',
|
||||
'/luci-static/resources/codemirror5/mode/yaml/yaml.min.js',
|
||||
'/luci-static/resources/codemirror5/addon/lint/lint.min.js',
|
||||
'/luci-static/resources/codemirror5/addon/lint/yaml-lint.min.js',
|
||||
];
|
||||
const loadStyles = async () => {
|
||||
for (const href of styles) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = href;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
};
|
||||
const loadScripts = async () => {
|
||||
for (const src of scripts) {
|
||||
const script = document.createElement('script');
|
||||
script.src = src;
|
||||
document.head.appendChild(script);
|
||||
await new Promise(resolve => script.onload = resolve);
|
||||
}
|
||||
};
|
||||
await loadStyles();
|
||||
await loadScripts();
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.exec('/usr/bin/mosdns', ['version']), null),
|
||||
]);
|
||||
},
|
||||
|
||||
handleFlushCache: function (m, section_id, ev) {
|
||||
return fs.exec('/usr/share/mosdns/mosdns.sh', ['flush'])
|
||||
.then(function (lazy_cache) {
|
||||
var res = lazy_cache.code;
|
||||
if (res === 0) {
|
||||
ui.addNotification(null, E('p', _('Flushing DNS Cache Success.')), 'info');
|
||||
} else {
|
||||
ui.addNotification(null, E('p', _('Flushing DNS Cache Failed, Please check if MosDNS is running.')), 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function (basic) {
|
||||
var m, s, o, v;
|
||||
v = '';
|
||||
|
||||
if (basic[0] && basic[0].code === 0) {
|
||||
v = basic[0].stdout.trim();
|
||||
}
|
||||
m = new form.Map('mosdns', _('MosDNS') + ' ' + v,
|
||||
_('MosDNS is a plugin-based DNS forwarder/traffic splitter.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
s.render = function () {
|
||||
setTimeout(function () {
|
||||
poll.add(function () {
|
||||
return L.resolveDefault(getServiceStatus()).then(function (res) {
|
||||
var view = document.getElementById('service_status');
|
||||
if (view) {
|
||||
view.innerHTML = renderStatus(res);
|
||||
} else {
|
||||
console.error('Element #service_status not found.');
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 100);
|
||||
|
||||
/* dynamically loading Codemirror resources */
|
||||
loadCodeMirrorResources();
|
||||
|
||||
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
|
||||
E('p', { id: 'service_status' }, _('Collecting data...'))
|
||||
]);
|
||||
}
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'mosdns');
|
||||
|
||||
s.tab('basic', _('Basic Options'));
|
||||
s.tab("advanced", _("Advanced Options"));
|
||||
s.tab("cloudflare", _("Cloudflare Options"));
|
||||
s.tab("api", _("API Options"));
|
||||
s.tab('geodata', _('GeoData Export'));
|
||||
|
||||
/* basic */
|
||||
o = s.taboption('basic', form.Flag, 'enabled', _('Enabled'));
|
||||
o.default = o.disabled;
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'configfile', _('Config File'));
|
||||
o.value('/var/etc/mosdns.json', _('Default Config'));
|
||||
o.value('/etc/mosdns/config_custom.yaml', _('Custom Config'));
|
||||
o.default = '/var/etc/mosdns.json';
|
||||
|
||||
o = s.taboption('basic', form.Value, 'listen_port', _('Listen port'));
|
||||
o.default = '5335';
|
||||
o.datatype = 'port';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'log_level', _('Log Level'));
|
||||
o.value('debug', _('Debug'));
|
||||
o.value('info', _('Info'));
|
||||
o.value('warn', _('Warning'));
|
||||
o.value('error', _('Error'));
|
||||
o.default = 'info';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('basic', form.Value, 'log_file', _('Log File'));
|
||||
o.placeholder = '/var/log/mosdns.log';
|
||||
o.default = '/var/log/mosdns.log';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'redirect', _('DNS Forward'), _('Forward Dnsmasq Domain Name resolution requests to MosDNS'));
|
||||
o.default = false;
|
||||
|
||||
if (L.hasSystemFeature('firewall4')) {
|
||||
o = s.taboption('basic', form.Flag, 'local_dns_redirect', _('DNS redirect'), _('Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking'));
|
||||
o.default = false;
|
||||
o.depends('redirect', '1');
|
||||
}
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'prefer_ipv4_cn', _('China DNS prefer IPv4'),
|
||||
_('IPv4 is preferred for China DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only'));
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'prefer_ipv4', _('Remote DNS prefer IPv4'),
|
||||
_('IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only'));
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'custom_local_dns', _('Custom China DNS'), _('Follow WAN interface DNS if not enabled'));
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'apple_optimization', _('Apple domains optimization'),
|
||||
_('For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses'));
|
||||
o.depends('custom_local_dns', '1');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'local_dns', _('China DNS server'));
|
||||
o.value('119.29.29.29', _('Tencent Public DNS (119.29.29.29)'));
|
||||
o.value('119.28.28.28', _('Tencent Public DNS (119.28.28.28)'));
|
||||
o.value('223.5.5.5', _('Aliyun Public DNS (223.5.5.5)'));
|
||||
o.value('223.6.6.6', _('Aliyun Public DNS (223.6.6.6)'));
|
||||
o.value('180.184.1.1', _('TrafficRoute Public DNS (180.184.1.1)'));
|
||||
o.value('180.184.2.2', _('TrafficRoute Public DNS (180.184.2.2)'));
|
||||
o.value('114.114.114.114', _('Xinfeng Public DNS (114.114.114.114)'));
|
||||
o.value('114.114.115.115', _('Xinfeng Public DNS (114.114.115.115)'));
|
||||
o.value('180.76.76.76', _('Baidu Public DNS (180.76.76.76)'));
|
||||
o.value('https://doh.pub/dns-query', _('Tencent Public DNS (DNS over HTTPS)'));
|
||||
o.value('quic://dns.alidns.com', _('Aliyun Public DNS (DNS over QUIC)'));
|
||||
o.value('https://dns.alidns.com/dns-query', _('Aliyun Public DNS (DNS over HTTPS)'));
|
||||
o.value('h3://dns.alidns.com/dns-query', _('Aliyun Public DNS (DNS over HTTPS/3)'));
|
||||
o.value('https://doh.360.cn/dns-query', _('360 Public DNS (DNS over HTTPS)'));
|
||||
o.default = '119.29.29.29';
|
||||
o.depends('custom_local_dns', '1');
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'remote_dns', _('Remote DNS server'));
|
||||
o.value('tls://1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
|
||||
o.value('tls://1.0.0.1', _('CloudFlare Public DNS (1.0.0.1)'));
|
||||
o.value('tls://8.8.8.8', _('Google Public DNS (8.8.8.8)'));
|
||||
o.value('tls://8.8.4.4', _('Google Public DNS (8.8.4.4)'));
|
||||
o.value('tls://9.9.9.9', _('Quad9 Public DNS (9.9.9.9)'));
|
||||
o.value('tls://149.112.112.112', _('Quad9 Public DNS (149.112.112.112)'));
|
||||
o.value('tls://208.67.222.222', _('Cisco Public DNS (208.67.222.222)'));
|
||||
o.value('tls://208.67.220.220', _('Cisco Public DNS (208.67.220.220)'));
|
||||
o.default = 'tls://8.8.8.8';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'custom_stream_media_dns', _('Custom Stream Media DNS'),
|
||||
_('Netflix, Disney+, Hulu and streaming media rules list will use this DNS'));
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'stream_media_dns', _('Streaming Media DNS server'));
|
||||
o.value('tls://1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
|
||||
o.value('tls://1.0.0.1', _('CloudFlare Public DNS (1.0.0.1)'));
|
||||
o.value('tls://8.8.8.8', _('Google Public DNS (8.8.8.8)'));
|
||||
o.value('tls://8.8.4.4', _('Google Public DNS (8.8.4.4)'));
|
||||
o.value('tls://9.9.9.9', _('Quad9 Public DNS (9.9.9.9)'));
|
||||
o.value('tls://149.112.112.112', _('Quad9 Public DNS (149.112.112.112)'));
|
||||
o.value('tls://208.67.222.222', _('Cisco Public DNS (208.67.222.222)'));
|
||||
o.value('tls://208.67.220.220', _('Cisco Public DNS (208.67.220.220)'));
|
||||
o.default = 'tls://8.8.8.8';
|
||||
o.depends('custom_stream_media_dns', '1');
|
||||
|
||||
o = s.taboption('basic', form.Value, 'bootstrap_dns', _('Bootstrap DNS servers'),
|
||||
_('Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams'));
|
||||
o.value('119.29.29.29', _('Tencent Public DNS (119.29.29.29)'));
|
||||
o.value('119.28.28.28', _('Tencent Public DNS (119.28.28.28)'));
|
||||
o.value('223.5.5.5', _('Aliyun Public DNS (223.5.5.5)'));
|
||||
o.value('223.6.6.6', _('Aliyun Public DNS (223.6.6.6)'));
|
||||
o.value('114.114.114.114', _('Xinfeng Public DNS (114.114.114.114)'));
|
||||
o.value('114.114.115.115', _('Xinfeng Public DNS (114.114.115.115)'));
|
||||
o.value('180.76.76.76', _('Baidu Public DNS (180.76.76.76)'));
|
||||
o.value('8.8.8.8', _('Google Public DNS (8.8.8.8)'));
|
||||
o.value('1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
|
||||
o.default = '119.29.29.29';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
/* advanced */
|
||||
o = s.taboption('advanced', form.Value, 'concurrent', _('Concurrent'),
|
||||
_('DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time'));
|
||||
o.datatype = 'and(uinteger,min(1),max(3))';
|
||||
o.default = '2';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'idle_timeout', _('Idle Timeout'),
|
||||
_('DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)'))
|
||||
o.datatype = 'and(uinteger,min(1))';
|
||||
o.default = '30';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'enable_pipeline', _('TCP/DoT Connection Multiplexing'),
|
||||
_('Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode'))
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'insecure_skip_verify', _('Disable TLS Certificate'),
|
||||
_('Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'enable_ecs_remote',
|
||||
_('Enable EDNS client subnet'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'remote_ecs_ip', _('IP Address'),
|
||||
_('Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote / Streaming Media DNS requests') +
|
||||
_('This feature is typically used when using a self-built DNS server as an Remote / Streaming Media DNS upstream (requires support from the upstream server)'));
|
||||
o.datatype = 'ipaddr';
|
||||
o.depends('enable_ecs_remote', '1');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'dns_leak', _('Prevent DNS Leaks'),
|
||||
_('Enable this option fallback policy forces forwarding to remote DNS'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'cache', _('Enable DNS Cache'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'cache_size', _('DNS Cache Size'));
|
||||
o.datatype = 'and(uinteger,min(0))';
|
||||
o.default = 8000;
|
||||
o.depends('cache', '1');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'lazy_cache_ttl', _('Lazy Cache TTL'),
|
||||
_('Lazy cache survival time (in second). To disable Lazy Cache, please set to 0.'));
|
||||
o.datatype = 'and(uinteger,min(0))';
|
||||
o.default = 86400;
|
||||
o.depends('cache', '1');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'dump_file', _('Cache Dump'),
|
||||
_('Save the cache locally and reload the cache dump on the next startup'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('cache', '1');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'dump_interval',
|
||||
_('Auto Save Cache Interval'));
|
||||
o.datatype = 'and(uinteger,min(0))';
|
||||
o.default = 3600;
|
||||
o.depends('dump_file', '1');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'minimal_ttl', _('Minimum TTL'),
|
||||
_('Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification'));
|
||||
o.datatype = 'and(uinteger,min(0),max(604800))';
|
||||
o.default = 0;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'maximum_ttl', _('Maximum TTL'),
|
||||
_('Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification'));
|
||||
o.datatype = 'and(uinteger,min(0),max(604800))';
|
||||
o.default = 0;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'reject_type65', _('Disable RR Type 65 (HTTPS/SVCB)'),
|
||||
_('Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force using only A/AAAA records.'));
|
||||
o.default = 0;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'adblock', _('Enable DNS ADblock'));
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.default = false;
|
||||
|
||||
o = s.taboption('advanced', form.DynamicList, 'ad_source', _('ADblock Source'),
|
||||
_('When using custom rule sources, please use rule types supported by MosDNS (domain lists).') +
|
||||
'<br>' +
|
||||
_('Support for local files, such as: file:///var/mosdns/example.txt'));
|
||||
o.depends('adblock', '1');
|
||||
o.default = 'geosite.dat';
|
||||
o.value('geosite.dat', 'v2ray-geosite');
|
||||
o.value('https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt', 'anti-AD')
|
||||
o.value('https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt', 'Cats-Team/AdRules')
|
||||
o.value('https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain', 'NEO DEV HOST')
|
||||
|
||||
/* cloudflare */
|
||||
o = s.taboption('cloudflare', form.Flag, 'cloudflare', _('Enabled'),
|
||||
_('Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, \
|
||||
use the \'Custom IP\' as the parsing result (experimental feature)'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('cloudflare', form.DynamicList, 'cloudflare_ip', _('Custom IP'));
|
||||
o.datatype = 'ipaddr';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('cloudflare', form.TextValue, '_cloudflare',
|
||||
_('Cloudflare IP Ranges'),
|
||||
_('IPv4 CIDR: <a href="https://www.cloudflare.com/ips-v4" target="_blank">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href="https://www.cloudflare.com/ips-v6" target="_blank">https://www.cloudflare.com/ips-v6</a>'));
|
||||
o.rows = 15;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/cloudflare-cidr.txt');
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/cloudflare-cidr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.then(function (i) {
|
||||
return fs.exec('/etc/init.d/mosdns', ['restart']);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/* api */
|
||||
o = s.taboption('api', form.Value, 'listen_port_api', _('API Listen port'));
|
||||
o.datatype = 'and(port,min(1))';
|
||||
o.default = 9091;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('api', form.Button, '_flush_cache', null,
|
||||
_('Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS cache.'));
|
||||
o.title = ' ';
|
||||
o.inputtitle = _('Flush DNS Cache');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleFlushCache, this, m);
|
||||
o.depends('cache', '1');
|
||||
|
||||
/* configuration */
|
||||
var configeditor = null;
|
||||
setTimeout(function () {
|
||||
var textarea = document.getElementById('widget.cbid.mosdns.config._custom');
|
||||
if (textarea) {
|
||||
configeditor = CodeMirror.fromTextArea(textarea, {
|
||||
autoRefresh: true,
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
lint: true,
|
||||
gutters: ['CodeMirror-lint-markers'],
|
||||
matchBrackets: true,
|
||||
mode: "text/yaml",
|
||||
styleActiveLine: true,
|
||||
theme: "dracula"
|
||||
});
|
||||
}
|
||||
}, 600);
|
||||
o = s.taboption('basic', form.TextValue, '_custom', _('Configuration Editor'),
|
||||
_('This is the content of the file \'/etc/mosdns/config_custom.yaml\' from which your MosDNS configuration will be generated. \
|
||||
Only accepts configuration content in yaml format.'));
|
||||
o.rows = 25;
|
||||
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/config_custom.yaml');
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
if (configeditor) {
|
||||
var editorContent = configeditor.getValue();
|
||||
if (editorContent === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/config_custom.yaml', editorContent.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.then(function (i) {
|
||||
return fs.exec('/etc/init.d/mosdns', ['restart']);
|
||||
})
|
||||
.then(function () {
|
||||
return window.location.reload();
|
||||
})
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
o = s.taboption('geodata', form.DynamicList, 'geosite_tags', _('GeoSite Tags'),
|
||||
_('Enter the GeoSite.dat category to be exported, Allow add multiple tags'),
|
||||
_('Export directory: /var/mosdns'));
|
||||
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
|
||||
|
||||
o = s.taboption('geodata', form.DynamicList, 'geoip_tags', _('GeoIP Tags'),
|
||||
_('Enter the GeoIP.dat category to be exported, Allow add multiple tags'),
|
||||
_('Export directory: /var/mosdns'));
|
||||
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
'require dom';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require view';
|
||||
|
||||
var scrollPosition = 0;
|
||||
var userScrolled = false;
|
||||
var logTextarea;
|
||||
|
||||
function pollLog() {
|
||||
return Promise.all([
|
||||
fs.exec_direct('/usr/share/mosdns/mosdns.sh', ['printlog']).then(function (res) {
|
||||
return res.trim().split(/\n/).join('\n');
|
||||
}),
|
||||
]).then(function (data) {
|
||||
logTextarea.value = data[0] || _('No log data.');
|
||||
|
||||
if (!userScrolled) {
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
} else {
|
||||
logTextarea.scrollTop = scrollPosition;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return view.extend({
|
||||
handleCleanLogs: function () {
|
||||
return fs.exec('/usr/share/mosdns/mosdns.sh', ['cleanlog'])
|
||||
.catch(function (e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
render: function () {
|
||||
logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'wrap': 'off',
|
||||
'readonly': 'readonly',
|
||||
'style': 'width: calc(100% - 20px);height: 535px;margin: 10px;overflow-y: scroll;',
|
||||
});
|
||||
|
||||
logTextarea.addEventListener('scroll', function () {
|
||||
userScrolled = true;
|
||||
scrollPosition = logTextarea.scrollTop;
|
||||
});
|
||||
|
||||
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
|
||||
poll.add(pollLog);
|
||||
|
||||
var clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
|
||||
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
|
||||
|
||||
return E([
|
||||
E('div', { 'class': 'cbi-map' }, [
|
||||
E('h2', { 'name': 'content' }, '%s - %s'.format(_('MosDNS'), _('Log Data'))),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
clear_logs_button,
|
||||
log_textarea_wrapper,
|
||||
E('div', { 'style': 'text-align:right' },
|
||||
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
|
||||
)
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleSave: null,
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
||||
@@ -0,0 +1,234 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
render: function () {
|
||||
var m, s, o;
|
||||
|
||||
m = new form.Map("mosdns", _("Rule Settings"),
|
||||
_('The list of rules only apply to \'Default Config\' profiles.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
s.sortable = true;
|
||||
|
||||
s.tab('whitelist', _('White Lists'));
|
||||
s.tab('blocklist', _('Block Lists'));
|
||||
s.tab('greylist', _('Grey Lists'));
|
||||
s.tab('ddnslist', _('DDNS Lists'));
|
||||
s.tab('hostslist', _('Hosts'));
|
||||
s.tab('redirectlist', _('Redirect'));
|
||||
s.tab('localptrlist', _('Block PTR'));
|
||||
s.tab('streamingmedialist', _('Streaming Media'));
|
||||
|
||||
o = s.taboption('whitelist', form.TextValue, '_whitelist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Added domain names always permit resolution using \'local DNS\' with the highest priority (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/whitelist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/whitelist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('blocklist', form.TextValue, '_blocklist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Added domain names will block DNS resolution (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/blocklist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/blocklist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('greylist', form.TextValue, '_greylist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Added domain names will always use \'Remote DNS\' for resolution (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/greylist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/greylist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('ddnslist', form.TextValue, '_ddnslist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Added domain names will always use \'Local DNS\' for resolution, with a forced TTL of 5 seconds, and results will not be cached (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/ddnslist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/ddnslist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('hostslist', form.TextValue, '_hostslist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/hosts.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/hosts.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('redirectlist', form.TextValue, '_redirectlist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Redirecting requests for domain names. Request domain A, but return records for domain B, for example: baidu.com qq.com (one rule per line).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/redirect.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/redirect.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('localptrlist', form.TextValue, '_localptrlist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('Added domain names will block PTR requests (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/local-ptr.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/local-ptr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
o = s.taboption('streamingmedialist', form.TextValue, '_streamingmedialist',
|
||||
null,
|
||||
'<font color=\'red\'>'
|
||||
+ _('When enabling \'Custom Stream Media DNS\', added domains will always use the \'Streaming Media DNS server\' for resolution (one domain per line, supports domain matching rules).')
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/streaming.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/streaming.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
handleSaveApply: function (ev) {
|
||||
var m = this.map;
|
||||
onclick = L.bind(this.handleSave, this, m);
|
||||
return fs.exec('/etc/init.d/mosdns', ['restart'])
|
||||
.then(function () {
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Failed to restart mosdns: %s').format(e.message)));
|
||||
});
|
||||
},
|
||||
handleReset: null
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
handleUpdate: function (m, section_id, ev) {
|
||||
return fs.exec('/usr/share/mosdns/mosdns.sh', ['geodata'])
|
||||
.then(function (i) {
|
||||
var res = i.code;
|
||||
if (res === 0) {
|
||||
ui.addNotification(null, E('p', _('Update success')), 'info');
|
||||
} else {
|
||||
ui.addNotification(null, E('p', i.stderr + '<br />' + i.stdout), 'warn');
|
||||
ui.addNotification(null, E('p', _('Update failed, Please check the network status')), 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var m, s, o;
|
||||
|
||||
m = new form.Map('mosdns', _('Update GeoIP & GeoSite databases'),
|
||||
_('Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Flag, 'geo_auto_update', _('Enable Auto Database Update'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.ListValue, 'geo_update_week_time', _('Update Cycle'));
|
||||
o.value('*', _('Every Day'));
|
||||
o.value('1', _('Every Monday'));
|
||||
o.value('2', _('Every Tuesday'));
|
||||
o.value('3', _('Every Wednesday'));
|
||||
o.value('4', _('Every Thursday'));
|
||||
o.value('5', _('Every Friday'));
|
||||
o.value('6', _('Every Saturday'));
|
||||
o.value('0', _('Every Sunday'));
|
||||
o.default = 3;
|
||||
|
||||
o = s.option(form.ListValue, 'geo_update_day_time', _('Update Time'));
|
||||
for (let t = 0; t < 24; t++) {
|
||||
o.value(t, t + ':00');
|
||||
};
|
||||
o.default = 3;
|
||||
|
||||
o = s.option(form.ListValue, 'geoip_type', _('GeoIP Type'),
|
||||
_('Little: only include Mainland China and Private IP addresses.') +
|
||||
'<br>' +
|
||||
_('Full: includes all Countries and Private IP addresses.')
|
||||
);
|
||||
o.value('geoip', _('Full'));
|
||||
o.value('geoip-only-cn-private', _('Little'));
|
||||
o.rmempty = false;
|
||||
o.default = 'geoip';
|
||||
|
||||
o = s.option(form.Value, 'github_proxy', _('GitHub Proxy'),
|
||||
_('Update data files with GitHub Proxy, leave blank to disable proxy downloads.'));
|
||||
o.value('https://gh-proxy.com', _('https://gh-proxy.com'));
|
||||
o.rmempty = true;
|
||||
o.default = '';
|
||||
|
||||
o = s.option(form.Button, '_udpate', null,
|
||||
_('Check And Update GeoData.'));
|
||||
o.title = _('Database Update');
|
||||
o.inputtitle = _('Check And Update');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleUpdate, this, m);
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
1
luci-app-mosdns/po/zh-cn
Symbolic link
1
luci-app-mosdns/po/zh-cn
Symbolic link
@@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
486
luci-app-mosdns/po/zh_Hans/mosdns.po
Normal file
486
luci-app-mosdns/po/zh_Hans/mosdns.po
Normal file
@@ -0,0 +1,486 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh_Hans\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "MosDNS"
|
||||
msgstr "MosDNS"
|
||||
|
||||
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
|
||||
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
|
||||
|
||||
msgid "Basic Setting"
|
||||
msgstr "基本设置"
|
||||
|
||||
msgid "Basic Options"
|
||||
msgstr "基本选项"
|
||||
|
||||
msgid "Advanced Options"
|
||||
msgstr "高级选项"
|
||||
|
||||
msgid "Cloudflare Options"
|
||||
msgstr "Cloudflare 选项"
|
||||
|
||||
msgid "API Options"
|
||||
msgstr "API 选项"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Listen port"
|
||||
msgstr "监听端口"
|
||||
|
||||
msgid "API Listen port"
|
||||
msgstr "API 监听端口"
|
||||
|
||||
msgid "Flush DNS Cache"
|
||||
msgstr "刷新 DNS 缓存"
|
||||
|
||||
msgid "Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS cache."
|
||||
msgstr "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存。"
|
||||
|
||||
msgid "Flushing DNS Cache Success."
|
||||
msgstr "刷新 DNS 缓存成功"
|
||||
|
||||
msgid "Flushing DNS Cache Failed, Please check if MosDNS is running."
|
||||
msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。"
|
||||
|
||||
msgid "Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, use the 'Custom IP' as the parsing result (experimental feature)"
|
||||
msgstr "将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解析结果(实验性功能)"
|
||||
|
||||
msgid "Custom IP"
|
||||
msgstr "自选 IP"
|
||||
|
||||
msgid "Cloudflare IP Ranges"
|
||||
msgstr "Cloudflare IP 范围"
|
||||
|
||||
msgid "Log Level"
|
||||
msgstr "日志等级"
|
||||
|
||||
msgid "DNS Forward"
|
||||
msgstr "DNS 转发"
|
||||
|
||||
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
|
||||
msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器"
|
||||
|
||||
msgid "DNS redirect"
|
||||
msgstr "DNS 重定向"
|
||||
|
||||
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
|
||||
msgstr "强制将所有本地 DNS 查询重定向到 MosDNS,即 DNS 劫持。"
|
||||
|
||||
msgid "Disable RR Type 65 (HTTPS/SVCB)"
|
||||
msgstr "禁用 RR Type 65 (HTTPS/SVCB)"
|
||||
|
||||
msgid "Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force using only A/AAAA records."
|
||||
msgstr "屏蔽 DNS 类型 65 记录(HTTPS/SVCB,用于 HTTP/3、ECH 等),强制仅使用 A/AAAA 解析。"
|
||||
|
||||
msgid "Enable DNS ADblock"
|
||||
msgstr "启用 DNS 广告过滤"
|
||||
|
||||
msgid "ADblock Source"
|
||||
msgstr "广告过滤规则来源"
|
||||
|
||||
msgid "When using custom rule sources, please use rule types supported by MosDNS (domain lists)."
|
||||
msgstr "使用自定义规则来源时,请使用 MosDNS 支持的规则类型(域名列表)"
|
||||
|
||||
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
|
||||
msgstr "支持本地文件,例如:file:///var/mosdns/example.txt"
|
||||
|
||||
msgid "Configuration Editor"
|
||||
msgstr "配置编辑器"
|
||||
|
||||
msgid "Edit the MosDNS custom configuration file."
|
||||
msgstr "编辑 MosDNS 自定义配置文件。"
|
||||
|
||||
msgid "Configuration have been saved."
|
||||
msgstr "配置已保存。"
|
||||
|
||||
msgid "This is the content of the file '/etc/mosdns/config_custom.yaml' from which your MosDNS configuration will be generated. Only accepts configuration content in yaml format."
|
||||
msgstr "这是文件 “/etc/mosdns/config_custom.yaml” 的内容,您的 MosDNS 配置将从此文件生成。仅接受 yaml 格式的配置内容。"
|
||||
|
||||
msgid "Geodata Update"
|
||||
msgstr "更新数据库"
|
||||
|
||||
msgid "Update GeoIP & GeoSite databases"
|
||||
msgstr "更新广告规则、GeoIP & GeoSite 数据库"
|
||||
|
||||
msgid "Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks."
|
||||
msgstr "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。"
|
||||
|
||||
msgid "Update Time"
|
||||
msgstr "更新时间"
|
||||
|
||||
msgid "Update Cycle"
|
||||
msgstr "更新周期"
|
||||
|
||||
msgid "Every Day"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Every Monday"
|
||||
msgstr "每周一"
|
||||
|
||||
msgid "Every Tuesday"
|
||||
msgstr "每周二"
|
||||
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
msgid "Every Thursday"
|
||||
msgstr "每周四"
|
||||
|
||||
msgid "Every Friday"
|
||||
msgstr "每周五"
|
||||
|
||||
msgid "Every Saturday"
|
||||
msgstr "每周六"
|
||||
|
||||
msgid "Every Sunday"
|
||||
msgstr "每周日"
|
||||
|
||||
msgid "GeoIP Type"
|
||||
msgstr "GeoIP 类型"
|
||||
|
||||
msgid "Little"
|
||||
msgstr "轻量"
|
||||
|
||||
msgid "Little: only include Mainland China and Private IP addresses."
|
||||
msgstr "轻量:仅包含中国大陆和私有 IP 地址。"
|
||||
|
||||
msgid "Full"
|
||||
msgstr "全量"
|
||||
|
||||
msgid "Full: includes all Countries and Private IP addresses."
|
||||
msgstr "全量:包含所有国家和私有 IP 地址。"
|
||||
|
||||
msgid "GitHub Proxy"
|
||||
msgstr "GitHub 代理"
|
||||
|
||||
msgid "Update data files with GitHub Proxy, leave blank to disable proxy downloads."
|
||||
msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。"
|
||||
|
||||
msgid "Database Update"
|
||||
msgstr "数据库更新"
|
||||
|
||||
msgid "Check And Update GeoData."
|
||||
msgstr "检查并更新 GeoData 数据库。"
|
||||
|
||||
msgid "Check And Update"
|
||||
msgstr "检查并更新"
|
||||
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr "启用自动更新"
|
||||
|
||||
msgid "Update success"
|
||||
msgstr "更新成功"
|
||||
|
||||
msgid "Update failed, Please check the network status"
|
||||
msgstr "更新失败,请检查网络状态"
|
||||
|
||||
msgid "Config File"
|
||||
msgstr "配置文件"
|
||||
|
||||
msgid "Default Config"
|
||||
msgstr "内置预设"
|
||||
|
||||
msgid "Custom Config"
|
||||
msgstr "自定义"
|
||||
|
||||
msgid "Log File"
|
||||
msgstr "日志文件"
|
||||
|
||||
msgid "China DNS prefer IPv4"
|
||||
msgstr "国内 DNS 首选 IPv4"
|
||||
|
||||
msgid "IPv4 is preferred for China DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only"
|
||||
msgstr "国内 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响"
|
||||
|
||||
msgid "Remote DNS prefer IPv4"
|
||||
msgstr "远程 DNS 首选 IPv4"
|
||||
|
||||
msgid "IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only"
|
||||
msgstr "远程 / 流媒体 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响"
|
||||
|
||||
msgid "Custom China DNS"
|
||||
msgstr "自定义国内 DNS"
|
||||
|
||||
msgid "Follow WAN interface DNS if not enabled"
|
||||
msgstr "不启用则使用 WAN 接口 DNS"
|
||||
|
||||
msgid "Apple domains optimization"
|
||||
msgstr "Apple 域名解析优化"
|
||||
|
||||
msgid "For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"
|
||||
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
|
||||
|
||||
msgid "China DNS server"
|
||||
msgstr "国内 DNS 服务器"
|
||||
|
||||
msgid "Remote DNS server"
|
||||
msgstr "远程 DNS 服务器"
|
||||
|
||||
msgid "Bootstrap DNS servers"
|
||||
msgstr "Bootstrap DNS 服务器"
|
||||
|
||||
msgid "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams"
|
||||
msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址"
|
||||
|
||||
msgid "Tencent Public DNS (119.29.29.29)"
|
||||
msgstr "腾讯公共 DNS(119.29.29.29)"
|
||||
|
||||
msgid "Tencent Public DNS (119.28.28.28)"
|
||||
msgstr "腾讯公共 DNS(119.28.28.28)"
|
||||
|
||||
msgid "Aliyun Public DNS (223.5.5.5)"
|
||||
msgstr "阿里云公共 DNS(223.5.5.5)"
|
||||
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr "阿里云公共 DNS(223.6.6.6)"
|
||||
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr "火山引擎公共 DNS(180.184.1.1)"
|
||||
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr "火山引擎公共 DNS(180.184.2.2)"
|
||||
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr "信风公共 DNS(114.114.114.114)"
|
||||
|
||||
msgid "Xinfeng Public DNS (114.114.115.115)"
|
||||
msgstr "信风公共 DNS(114.114.115.115)"
|
||||
|
||||
msgid "Baidu Public DNS (180.76.76.76)"
|
||||
msgstr "百度公共 DNS(180.76.76.76)"
|
||||
|
||||
msgid "Tencent Public DNS (DNS over HTTPS)"
|
||||
msgstr "腾讯公共 DNS(DNS over HTTPS)"
|
||||
|
||||
msgid "Aliyun Public DNS (DNS over QUIC)"
|
||||
msgstr "阿里云公共 DNS(DNS over QUIC)"
|
||||
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTPS)"
|
||||
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS/3)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTPS/3)"
|
||||
|
||||
msgid "360 Public DNS (DNS over HTTPS)"
|
||||
msgstr "360 安全 DNS(DNS over HTTPS)"
|
||||
|
||||
msgid "CloudFlare Public DNS (1.1.1.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.1.1.1)"
|
||||
|
||||
msgid "CloudFlare Public DNS (1.0.0.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.0.0.1)"
|
||||
|
||||
msgid "Google Public DNS (8.8.8.8)"
|
||||
msgstr "谷歌公共 DNS(8.8.8.8)"
|
||||
|
||||
msgid "Google Public DNS (8.8.4.4)"
|
||||
msgstr "谷歌公共 DNS(8.8.4.4)"
|
||||
|
||||
msgid "Quad9 Public DNS (9.9.9.9)"
|
||||
msgstr "Quad9 公共 DNS(9.9.9.9)"
|
||||
|
||||
msgid "Quad9 Public DNS (149.112.112.112)"
|
||||
msgstr "Quad9 公共 DNS(149.112.112.112)"
|
||||
|
||||
msgid "Cisco Public DNS (208.67.222.222)"
|
||||
msgstr "思科公共 DNS(208.67.222.222)"
|
||||
|
||||
msgid "Cisco Public DNS (208.67.220.220)"
|
||||
msgstr "思科公共 DNS(208.67.220.220)"
|
||||
|
||||
msgid "Concurrent"
|
||||
msgstr "DNS 服务器并发数(默认 2)"
|
||||
|
||||
msgid "DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time"
|
||||
msgstr "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量"
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超时"
|
||||
|
||||
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
|
||||
msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
|
||||
|
||||
msgid "TCP/DoT Connection Multiplexing"
|
||||
msgstr "TCP/DoT 连接复用"
|
||||
|
||||
msgid "Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
|
||||
msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式"
|
||||
|
||||
msgid "Disable TLS Certificate"
|
||||
msgstr "禁用 TLS 证书"
|
||||
|
||||
msgid "Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order"
|
||||
msgstr "禁用 TLS 服务器证书验证,当系统 CA 证书过期或系统时间错乱时,本选项可能会有用"
|
||||
|
||||
msgid "Enable EDNS client subnet"
|
||||
msgstr "启用 EDNS 客户端子网"
|
||||
|
||||
msgid "IP Address"
|
||||
msgstr "IP 地址"
|
||||
|
||||
msgid "Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote / Streaming Media DNS requests"
|
||||
msgstr "请提供您在访问国外网站时使用的 IP 地址,这个 IP 子网(0/24)将用作 远程 / 流媒体 DNS 请求的 ECS 地址"
|
||||
|
||||
msgid "This feature is typically used when using a self-built DNS server as an Remote / Streaming Media DNS upstream (requires support from the upstream server)"
|
||||
msgstr "此功能通常在使用自建 DNS 服务器作为 远程 / 流媒体 DNS 上游时使用(需要上游服务器的支持)"
|
||||
|
||||
msgid "Prevent DNS Leaks"
|
||||
msgstr "防止 DNS 泄漏"
|
||||
|
||||
msgid "Enable this option fallback policy forces forwarding to remote DNS"
|
||||
msgstr "启用此选项 fallback 策略会强制转发到远程 DNS"
|
||||
|
||||
msgid "Enable DNS Cache"
|
||||
msgstr "启用 DNS 缓存"
|
||||
|
||||
msgid "DNS Cache Size"
|
||||
msgstr "DNS 缓存大小"
|
||||
|
||||
msgid "DNS cache size (in piece)."
|
||||
msgstr "DNS 缓存大小(单位:条)"
|
||||
|
||||
msgid "Lazy Cache TTL"
|
||||
msgstr "乐观缓存 TTL"
|
||||
|
||||
msgid "Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
|
||||
msgstr "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0"
|
||||
|
||||
msgid "Cache Dump"
|
||||
msgstr "自动保存缓存"
|
||||
|
||||
msgid "Save the cache locally and reload the cache dump on the next startup"
|
||||
msgstr "保存缓存到本地文件,以供下次启动时重新载入使用"
|
||||
|
||||
msgid "Auto Save Cache Interval"
|
||||
msgstr "自动保存缓存间隔(秒)"
|
||||
|
||||
msgid "Minimum TTL"
|
||||
msgstr "覆盖最小 TTL 值(默认 0)"
|
||||
|
||||
msgid "Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification"
|
||||
msgstr "修改 DNS 应答结果的最小 TTL 值 (秒),0 表示不修改"
|
||||
|
||||
msgid "Maximum TTL"
|
||||
msgstr "覆盖最大 TTL 值(默认 0)"
|
||||
|
||||
msgid "Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification"
|
||||
msgstr "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
msgid "Log Data"
|
||||
msgstr "日志数据"
|
||||
|
||||
msgid "No log data."
|
||||
msgstr "无日志数据。"
|
||||
|
||||
msgid "Refresh every %s seconds."
|
||||
msgstr "每 %s 秒刷新。"
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "规则列表"
|
||||
|
||||
msgid "Rule Settings"
|
||||
msgstr "自定义规则列表"
|
||||
|
||||
msgid "Failed to restart mosdns: %s"
|
||||
msgstr "无法重启 MosDNS:%s"
|
||||
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr "无法保存内容:%s"
|
||||
|
||||
msgid "The list of rules only apply to 'Default Config' profiles."
|
||||
msgstr "规则列表仅适用于 “内置预设” 配置文件。"
|
||||
|
||||
msgid "White Lists"
|
||||
msgstr "白名单"
|
||||
|
||||
msgid "Added domain names always permit resolution using 'local DNS' with the highest priority (one domain per line, supports domain matching rules)."
|
||||
msgstr "加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
msgid "Block Lists"
|
||||
msgstr "黑名单"
|
||||
|
||||
msgid "Added domain names will block DNS resolution (one domain per line, supports domain matching rules)."
|
||||
msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
msgid "Grey Lists"
|
||||
msgstr "灰名单"
|
||||
|
||||
msgid "Added domain names will always use 'Remote DNS' for resolution (one domain per line, supports domain matching rules)."
|
||||
msgstr "加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
msgid "DDNS Lists"
|
||||
msgstr "DDNS 域名"
|
||||
|
||||
msgid "Added domain names will always use 'Local DNS' for resolution, with a forced TTL of 5 seconds, and results will not be cached (one domain per line, supports domain matching rules)."
|
||||
msgstr "加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓存(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
msgid "Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, supports domain matching rules)."
|
||||
msgstr "自定义 Hosts 重写,如:baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)"
|
||||
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
msgid "Redirecting requests for domain names. Request domain A, but return records for domain B, for example: baidu.com qq.com (one rule per line)."
|
||||
msgstr "重定向请求的域名。请求域名 A,但返回域名 B 的记录,如:baidu.com qq.com(每个规则一行)"
|
||||
|
||||
msgid "Block PTR"
|
||||
msgstr "PTR 黑名单"
|
||||
|
||||
msgid "Added domain names will block PTR requests (one domain per line, supports domain matching rules)."
|
||||
msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
msgid "GeoData Export"
|
||||
msgstr "GeoData 导出"
|
||||
|
||||
msgid "GeoSite Tags"
|
||||
msgstr "GeoSite 标签"
|
||||
|
||||
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签"
|
||||
|
||||
msgid "GeoIP Tags"
|
||||
msgstr "GeoIP 标签"
|
||||
|
||||
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签"
|
||||
|
||||
msgid "Export directory: /var/mosdns"
|
||||
msgstr "导出目录:/var/mosdns"
|
||||
|
||||
msgid "Custom Stream Media DNS"
|
||||
msgstr "自定义流媒体 DNS"
|
||||
|
||||
msgid "Streaming Media DNS server"
|
||||
msgstr "流媒体 DNS 服务器"
|
||||
|
||||
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
|
||||
msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表的 DNS 服务器"
|
||||
|
||||
msgid "Streaming Media"
|
||||
msgstr "流媒体"
|
||||
|
||||
msgid "When enabling 'Custom Stream Media DNS', added domains will always use the 'Streaming Media DNS server' for resolution (one domain per line, supports domain matching rules)."
|
||||
msgstr "启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析(每个域名一行,支持域名匹配规则)"
|
||||
30
luci-app-mosdns/root/etc/config/mosdns
Normal file
30
luci-app-mosdns/root/etc/config/mosdns
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
config mosdns 'config'
|
||||
option enabled '0'
|
||||
option listen_port '5335'
|
||||
option geo_auto_update '0'
|
||||
option geo_update_week_time '*'
|
||||
option geo_update_day_time '2'
|
||||
option configfile '/var/etc/mosdns.json'
|
||||
option log_level 'info'
|
||||
option log_file '/var/log/mosdns.log'
|
||||
option cache '1'
|
||||
option concurrent '2'
|
||||
option idle_timeout '30'
|
||||
option minimal_ttl '0'
|
||||
option maximum_ttl '0'
|
||||
option enable_pipeline '1'
|
||||
option insecure_skip_verify '0'
|
||||
option dns_leak '0'
|
||||
option cloudflare '0'
|
||||
option listen_port_api '9091'
|
||||
option bootstrap_dns '119.29.29.29'
|
||||
list remote_dns 'tls://8.8.8.8'
|
||||
option redirect '1'
|
||||
option prefer_ipv4 '1'
|
||||
option enable_ecs_remote '0'
|
||||
option cache_size '8000'
|
||||
option lazy_cache_ttl '86400'
|
||||
option dump_file '0'
|
||||
option reject_type65 '1'
|
||||
|
||||
2
luci-app-mosdns/root/etc/hotplug.d/iface/99-mosdns
Executable file
2
luci-app-mosdns/root/etc/hotplug.d/iface/99-mosdns
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
[ "$ACTION" = ifup ] && /etc/init.d/mosdns restart
|
||||
808
luci-app-mosdns/root/etc/init.d/mosdns
Executable file
808
luci-app-mosdns/root/etc/init.d/mosdns
Executable file
@@ -0,0 +1,808 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2020-2022, IrineSistiana
|
||||
# Copyright (C) 2023-2024, sbwml <admin@cooluc.com>
|
||||
|
||||
START=75
|
||||
USE_PROCD=1
|
||||
|
||||
PROG=/usr/bin/mosdns
|
||||
CONF=$(uci -q get mosdns.config.configfile)
|
||||
CRON_FILE=/etc/crontabs/root
|
||||
DUMP_FILE=/etc/mosdns/cache.dump
|
||||
DUMP_FILE_DEFAULT=/usr/share/mosdns/cache.dump
|
||||
MOSDNS_SCRIPT=/usr/share/mosdns/mosdns.sh
|
||||
|
||||
get_config() {
|
||||
config_get enabled $1 enabled 0
|
||||
config_get adblock $1 adblock 0
|
||||
config_get ad_source $1 ad_source ""
|
||||
config_get cache $1 cache 0
|
||||
config_get cache_size $1 cache_size 8000
|
||||
config_get lazy_cache_ttl $1 lazy_cache_ttl 86400
|
||||
config_get dump_file $1 dump_file 0
|
||||
config_get dump_interval $1 dump_interval 3600
|
||||
config_get enable_pipeline $1 enable_pipeline 0
|
||||
config_get geo_auto_update $1 geo_auto_update 0
|
||||
config_get geo_update_day_time $1 geo_update_day_time 2
|
||||
config_get geo_update_week_time $1 geo_update_week_time "*"
|
||||
config_get listen_port $1 listen_port 5335
|
||||
config_get log_file $1 log_file "/var/log/mosdns.log"
|
||||
config_get log_level $1 log_level "info"
|
||||
config_get minimal_ttl $1 minimal_ttl 0
|
||||
config_get maximum_ttl $1 maximum_ttl 0
|
||||
config_get redirect $1 redirect 0
|
||||
config_get local_dns_redirect $1 local_dns_redirect 0
|
||||
config_get prefer_ipv4_cn $1 prefer_ipv4_cn 0
|
||||
config_get prefer_ipv4 $1 prefer_ipv4 0
|
||||
config_get remote_dns $1 remote_dns "tls://8.8.8.8 tls://1.1.1.1"
|
||||
config_get custom_local_dns $1 custom_local_dns 0
|
||||
config_get apple_optimization $1 apple_optimization 0
|
||||
config_get custom_stream_media_dns $1 custom_stream_media_dns 0
|
||||
config_get stream_media_dns $1 stream_media_dns "tls://8.8.8.8"
|
||||
config_get bootstrap_dns $1 bootstrap_dns "119.29.29.29"
|
||||
config_get listen_port_api $1 listen_port_api 9091
|
||||
config_get concurrent $1 concurrent 1
|
||||
config_get insecure_skip_verify $1 insecure_skip_verify 0
|
||||
config_get idle_timeout $1 idle_timeout 30
|
||||
config_get enable_ecs_remote $1 enable_ecs_remote 0
|
||||
config_get remote_ecs_ip $1 remote_ecs_ip "110.34.181.1"
|
||||
config_get dns_leak $1 dns_leak 0
|
||||
config_get cloudflare $1 cloudflare 0
|
||||
config_get cloudflare_ip $1 cloudflare_ip ""
|
||||
config_get reject_type65 $1 reject_type65 "0"
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
# jshn shell library
|
||||
. /usr/share/libubox/jshn.sh
|
||||
# json data
|
||||
json_init
|
||||
# log
|
||||
json_add_object 'log'
|
||||
json_add_string "level" "$log_level"
|
||||
json_add_string "file" "$log_file"
|
||||
json_close_object
|
||||
# api
|
||||
json_add_object 'api'
|
||||
json_add_string "http" "0.0.0.0:$listen_port_api"
|
||||
json_close_object
|
||||
# include
|
||||
json_add_array "include"
|
||||
json_close_array
|
||||
# plugins
|
||||
json_add_array "plugins"
|
||||
# plugin: geosite_cn
|
||||
json_add_object
|
||||
json_add_string "tag" "geosite_cn"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/var/mosdns/geosite_cn.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: geoip_cn
|
||||
json_add_object
|
||||
json_add_string "tag" "geoip_cn"
|
||||
json_add_string "type" "ip_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/var/mosdns/geoip_cn.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: geosite_apple
|
||||
json_add_object
|
||||
json_add_string "tag" "geosite_apple"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/var/mosdns/geosite_apple.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: geosite_no_cn
|
||||
json_add_object
|
||||
json_add_string "tag" "geosite_no_cn"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/var/mosdns/geosite_geolocation-!cn.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: whitelist
|
||||
json_add_object
|
||||
json_add_string "tag" "whitelist"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/whitelist.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: blocklist
|
||||
json_add_object
|
||||
json_add_string "tag" "blocklist"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/blocklist.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: greylist
|
||||
json_add_object
|
||||
json_add_string "tag" "greylist"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/greylist.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: ddnslist
|
||||
json_add_object
|
||||
json_add_string "tag" "ddnslist"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/ddnslist.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: hosts
|
||||
json_add_object
|
||||
json_add_string "tag" "hosts"
|
||||
json_add_string "type" "hosts"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/hosts.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: redirect
|
||||
json_add_object
|
||||
json_add_string "tag" "redirect"
|
||||
json_add_string "type" "redirect"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/redirect.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: adlist
|
||||
json_add_object
|
||||
json_add_string "tag" "adlist"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
adlist=$($MOSDNS_SCRIPT adlist)
|
||||
for list in $adlist; do
|
||||
json_add_string "" "$list"
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: local_ptr
|
||||
json_add_object
|
||||
json_add_string "tag" "local_ptr"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/local-ptr.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: stream_media
|
||||
json_add_object
|
||||
json_add_string "tag" "stream_media"
|
||||
json_add_string "type" "domain_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/var/mosdns/geosite_disney.txt"
|
||||
json_add_string "" "/var/mosdns/geosite_netflix.txt"
|
||||
json_add_string "" "/var/mosdns/geosite_hulu.txt"
|
||||
json_add_string "" "/etc/mosdns/rule/streaming.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: cloudflare_cidr
|
||||
json_add_object
|
||||
json_add_string "tag" "cloudflare_cidr"
|
||||
json_add_string "type" "ip_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
json_add_string "" "/etc/mosdns/rule/cloudflare-cidr.txt"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: lazy_cache
|
||||
[ "$cache" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "tag" "lazy_cache"
|
||||
json_add_string "type" "cache"
|
||||
json_add_object "args"
|
||||
json_add_int "size" "$cache_size"
|
||||
json_add_int "lazy_cache_ttl" "$lazy_cache_ttl"
|
||||
[ "$dump_file" -eq 1 ] && {
|
||||
json_add_string "dump_file" "/etc/mosdns/cache.dump"
|
||||
json_add_int "dump_interval" "$dump_interval"
|
||||
}
|
||||
json_close_object
|
||||
json_close_object
|
||||
}
|
||||
# plugin: forward_xinfeng_udp
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_xinfeng_udp"
|
||||
json_add_string "type" "forward"
|
||||
json_add_object "args"
|
||||
json_add_int "concurrent" 2
|
||||
json_add_array "upstreams"
|
||||
json_add_object
|
||||
json_add_string "addr" "114.114.114.114"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "addr" "114.114.115.115"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: forward_local
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_local"
|
||||
json_add_string "type" "forward"
|
||||
json_add_object "args"
|
||||
json_add_int "concurrent" "$concurrent"
|
||||
json_add_array "upstreams"
|
||||
local_dns=$($MOSDNS_SCRIPT dns)
|
||||
for addr in $local_dns; do
|
||||
enable_http3=0
|
||||
if echo "$addr" | grep -q "^h3://"; then
|
||||
enable_http3=1
|
||||
addr=$(echo $addr | sed 's/h3:\/\//https:\/\//g')
|
||||
fi
|
||||
json_add_object
|
||||
json_add_string "addr" "$addr"
|
||||
json_add_string "bootstrap" "$bootstrap_dns"
|
||||
json_add_boolean "enable_pipeline" "$enable_pipeline"
|
||||
json_add_boolean "insecure_skip_verify" "$insecure_skip_verify"
|
||||
json_add_int "idle_timeout" "$idle_timeout"
|
||||
[ "$enable_http3" -eq 1 ] && json_add_boolean "enable_http3" "1"
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: forward_remote
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_remote"
|
||||
json_add_string "type" "forward"
|
||||
json_add_object "args"
|
||||
json_add_int "concurrent" "$concurrent"
|
||||
json_add_array "upstreams"
|
||||
for addr in $remote_dns; do
|
||||
enable_http3=0
|
||||
if echo "$addr" | grep -q "^h3://"; then
|
||||
enable_http3=1
|
||||
addr=$(echo $addr | sed 's/h3:\/\//https:\/\//g')
|
||||
fi
|
||||
json_add_object
|
||||
json_add_string "addr" "$addr"
|
||||
json_add_string "bootstrap" "$bootstrap_dns"
|
||||
json_add_boolean "enable_pipeline" "$enable_pipeline"
|
||||
json_add_boolean "insecure_skip_verify" "$insecure_skip_verify"
|
||||
json_add_int "idle_timeout" "$idle_timeout"
|
||||
[ "$enable_http3" -eq 1 ] && json_add_boolean "enable_http3" "1"
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: forward_remote_upstream
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_remote_upstream"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
[ "$prefer_ipv4" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "prefer_ipv4"
|
||||
json_close_object
|
||||
}
|
||||
[ "$enable_ecs_remote" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "ecs $remote_ecs_ip"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "exec" "\$forward_remote"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: forward_stream_media
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_stream_media"
|
||||
json_add_string "type" "forward"
|
||||
json_add_object "args"
|
||||
json_add_int "concurrent" "$concurrent"
|
||||
json_add_array "upstreams"
|
||||
for addr in $stream_media_dns; do
|
||||
enable_http3=0
|
||||
if echo "$addr" | grep -q "^h3://"; then
|
||||
enable_http3=1
|
||||
addr=$(echo $addr | sed 's/h3:\/\//https:\/\//g')
|
||||
fi
|
||||
json_add_object
|
||||
json_add_string "addr" "$addr"
|
||||
json_add_string "bootstrap" "$bootstrap_dns"
|
||||
json_add_boolean "enable_pipeline" "$enable_pipeline"
|
||||
json_add_boolean "insecure_skip_verify" "$insecure_skip_verify"
|
||||
json_add_int "idle_timeout" "$idle_timeout"
|
||||
[ "$enable_http3" -eq 1 ] && json_add_boolean "enable_http3" "1"
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: forward_stream_media_upstream
|
||||
json_add_object
|
||||
json_add_string "tag" "forward_stream_media_upstream"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
[ "$prefer_ipv4" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "prefer_ipv4"
|
||||
json_close_object
|
||||
}
|
||||
[ "$enable_ecs_remote" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "ecs $remote_ecs_ip"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "exec" "\$forward_stream_media"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: modify_ttl
|
||||
json_add_object
|
||||
json_add_string "tag" "modify_ttl"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "exec" "ttl $minimal_ttl-$maximum_ttl"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: modify_ddns_ttl
|
||||
json_add_object
|
||||
json_add_string "tag" "modify_ddns_ttl"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "exec" "ttl 5-5"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: has_resp_sequence
|
||||
json_add_object
|
||||
json_add_string "tag" "has_resp_sequence"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$ddnslist"
|
||||
json_add_string "exec" "\$modify_ddns_ttl"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "matches" "!qname \$ddnslist"
|
||||
json_add_string "exec" "\$modify_ttl"
|
||||
json_close_object
|
||||
[ "$cloudflare" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_array "matches"
|
||||
json_add_string "" "!qname \$whitelist"
|
||||
json_add_string "" "!qname \$greylist"
|
||||
json_add_string "" "!qname \$stream_media"
|
||||
json_add_string "" "resp_ip \$cloudflare_cidr"
|
||||
json_close_array
|
||||
json_add_string "exec" "black_hole $cloudflare_ip"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "matches" "has_resp"
|
||||
json_add_string "exec" "accept"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_non_local_ip
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_non_local_ip"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "exec" "\$forward_local"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "matches" "!resp_ip \$geoip_cn"
|
||||
json_add_string "exec" "drop_resp"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: fallback
|
||||
json_add_object
|
||||
json_add_string "tag" "fallback"
|
||||
json_add_string "type" "fallback"
|
||||
json_add_object "args"
|
||||
[ "$dns_leak" -eq 1 ] && json_add_string "primary" "forward_remote_upstream" || json_add_string "primary" "query_is_non_local_ip"
|
||||
json_add_string "secondary" "forward_remote_upstream"
|
||||
json_add_int "threshold" 500
|
||||
json_add_boolean "always_standby" 1
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: apple_domain_fallback
|
||||
json_add_object
|
||||
json_add_string "tag" "apple_domain_fallback"
|
||||
json_add_string "type" "fallback"
|
||||
json_add_object "args"
|
||||
json_add_string "primary" "query_is_non_local_ip"
|
||||
json_add_string "secondary" "forward_xinfeng_udp"
|
||||
json_add_int "threshold" 100
|
||||
json_add_boolean "always_standby" 1
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: query_is_apple_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_apple_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "!qname \$geosite_apple"
|
||||
json_add_string "exec" "return"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$apple_domain_fallback"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_ddns_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_ddns_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$ddnslist"
|
||||
json_add_string "exec" "\$forward_local"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_local_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_local_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
[ "$prefer_ipv4_cn" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "prefer_ipv4"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$geosite_cn"
|
||||
json_add_string "exec" "\$forward_local"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_no_local_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_no_local_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$geosite_no_cn"
|
||||
json_add_string "exec" "\$forward_remote_upstream"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_whitelist_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_whitelist_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
[ "$prefer_ipv4_cn" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "prefer_ipv4"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$whitelist"
|
||||
json_add_string "exec" "\$forward_local"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_greylist_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_greylist_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$greylist"
|
||||
json_add_string "exec" "\$forward_remote_upstream"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_reject_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_reject_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$blocklist"
|
||||
json_add_string "exec" "reject 3"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$adlist"
|
||||
json_add_string "exec" "reject 3"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_array "matches"
|
||||
json_add_string "" "qtype 12"
|
||||
json_add_string "" "qname \$local_ptr"
|
||||
json_close_array
|
||||
json_add_string "exec" "reject 3"
|
||||
json_close_object
|
||||
[ "$reject_type65" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "matches" "qtype 65"
|
||||
json_add_string "exec" "reject 3"
|
||||
json_close_object
|
||||
}
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: query_is_stream_media_domain
|
||||
json_add_object
|
||||
json_add_string "tag" "query_is_stream_media_domain"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "matches" "qname \$stream_media"
|
||||
json_add_string "exec" "\$forward_stream_media_upstream"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: main_sequence
|
||||
json_add_object
|
||||
json_add_string "tag" "main_sequence"
|
||||
json_add_string "type" "sequence"
|
||||
json_add_array "args"
|
||||
json_add_object
|
||||
json_add_string "exec" "\$hosts"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
[ "$cache" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_array "matches"
|
||||
json_add_string "" "!qname \$ddnslist"
|
||||
json_add_string "" "!qname \$blocklist"
|
||||
json_add_string "" "!qname \$adlist"
|
||||
json_add_string "" "!qname \$local_ptr"
|
||||
json_close_array
|
||||
json_add_string "exec" "\$lazy_cache"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "exec" "\$redirect"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
[ "$apple_optimization" -eq 1 ] && {
|
||||
json_add_string "exec" "\$query_is_apple_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
}
|
||||
json_add_string "exec" "\$query_is_ddns_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_whitelist_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_reject_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_greylist_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
[ "$custom_stream_media_dns" -eq 1 ] && {
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_stream_media_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
}
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_local_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$query_is_no_local_domain"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "\$fallback"
|
||||
json_close_object
|
||||
json_add_object
|
||||
json_add_string "exec" "jump has_resp_sequence"
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
# plugin: udp_server
|
||||
json_add_object
|
||||
json_add_string "tag" "udp_server"
|
||||
json_add_string "type" "udp_server"
|
||||
json_add_object "args"
|
||||
json_add_string "entry" "main_sequence"
|
||||
json_add_string "listen" ":$listen_port"
|
||||
json_close_object
|
||||
json_close_object
|
||||
# plugin: tcp_server
|
||||
json_add_object
|
||||
json_add_string "tag" "tcp_server"
|
||||
json_add_string "type" "tcp_server"
|
||||
json_add_object "args"
|
||||
json_add_string "entry" "main_sequence"
|
||||
json_add_string "listen" ":$listen_port"
|
||||
json_close_object
|
||||
json_close_object
|
||||
# close plugins array
|
||||
json_close_array
|
||||
# print json
|
||||
json_dump > /var/etc/mosdns.json
|
||||
|
||||
# init dump_file
|
||||
[ "$dump_file" -eq 1 ] && [ ! -f $DUMP_FILE ] && cp -a $DUMP_FILE_DEFAULT $DUMP_FILE
|
||||
[ "$dump_file" -eq 0 ] && \cp -a $DUMP_FILE_DEFAULT $DUMP_FILE
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "mosdns"
|
||||
}
|
||||
|
||||
restore_setting() {
|
||||
rm -f /etc/mosdns/redirect.lock
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
uci set dhcp.@dnsmasq[0].noresolv='0'
|
||||
uci del dhcp.@dnsmasq[0].cachesize
|
||||
uci commit dhcp
|
||||
}
|
||||
|
||||
redirect_setting() {
|
||||
if [ "${CONF}" = "/var/etc/mosdns.json" ]; then
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#$listen_port"
|
||||
uci set dhcp.@dnsmasq[0].rebind_protection='0'
|
||||
uci set dhcp.@dnsmasq[0].noresolv="1"
|
||||
uci set dhcp.@dnsmasq[0].cachesize='0'
|
||||
uci commit dhcp
|
||||
else
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#$(awk -F'[:" ]+' '/^\s+listen:/{for(i=1;i<=NF;i++){if($i~/^[0-9]+$/){print $i;exit}}}' $CONF)"
|
||||
uci set dhcp.@dnsmasq[0].rebind_protection='0'
|
||||
uci set dhcp.@dnsmasq[0].noresolv="1"
|
||||
uci set dhcp.@dnsmasq[0].cachesize='0'
|
||||
uci commit dhcp
|
||||
fi
|
||||
touch /etc/mosdns/redirect.lock
|
||||
}
|
||||
|
||||
reload_dnsmasq() {
|
||||
/etc/init.d/dnsmasq reload
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
||||
|
||||
setcron() {
|
||||
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
|
||||
[ "$geo_auto_update" -eq 1 ] && echo "0 $geo_update_day_time * * $geo_update_week_time $MOSDNS_SCRIPT geodata" >> $CRON_FILE
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
delcron() {
|
||||
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
v2dat_dump() {
|
||||
$MOSDNS_SCRIPT v2dat_dump
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load "mosdns"
|
||||
config_foreach get_config "mosdns"
|
||||
[ $enabled -ne 1 ] && return 1
|
||||
delcron ; setcron
|
||||
:> $($MOSDNS_SCRIPT logfile)
|
||||
if [ "${log_level}" = "error" ] || [ "${log_level}" = "warn" ]; then
|
||||
v2dat_dump > /dev/null 2>&1
|
||||
else
|
||||
v2dat_dump >> $($MOSDNS_SCRIPT logfile) 2>&1
|
||||
fi
|
||||
[ "${CONF}" = "/var/etc/mosdns.json" ] && generate_config
|
||||
|
||||
procd_open_instance mosdns
|
||||
procd_set_param env QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING=true
|
||||
procd_set_param command $PROG start
|
||||
procd_append_param command -c "$CONF"
|
||||
procd_append_param command -d "/etc/mosdns"
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance mosdns
|
||||
[ "$redirect" -ne 1 ] && [ -f "/etc/mosdns/redirect.lock" ] && restore_setting
|
||||
[ "$redirect" -eq 1 ] && redirect_setting
|
||||
reload_dnsmasq
|
||||
# dns hijack
|
||||
if [ "$local_dns_redirect" -eq 1 ] && [ -f "/sbin/fw4" ]; then
|
||||
! nft --check list table inet mosdns > "/dev/null" 2>&1 || \
|
||||
nft delete table inet mosdns
|
||||
nft add table inet mosdns
|
||||
nft add chain inet mosdns prerouting "{ type nat hook prerouting priority -95; policy accept; }"
|
||||
nft add rule inet mosdns prerouting "meta nfproto { ipv4, ipv6 } udp dport 53 counter redirect to :$listen_port comment \"DNS HIJACK\""
|
||||
fi
|
||||
# Update Adlist
|
||||
update_list=0
|
||||
if [ "$adblock" -eq 1 ]; then
|
||||
if [ -f "/etc/mosdns/rule/.ad_source" ]; then
|
||||
for url in $ad_source;
|
||||
do
|
||||
if [ "$url" = "geosite.dat" ] || [ $(echo "$url" | grep -c -E "^file://") -eq 1 ]; then
|
||||
continue
|
||||
fi
|
||||
if [ $(grep -c "$url" "/etc/mosdns/rule/.ad_source") -eq 0 ]; then
|
||||
update_list=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
update_list=1
|
||||
fi
|
||||
fi
|
||||
[ "$update_list" -eq 1 ] && $MOSDNS_SCRIPT adlist_update &> /dev/null &
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
config_load "mosdns"
|
||||
config_foreach get_config "mosdns"
|
||||
[ "$enabled" -eq "0" ] && [ -f "/etc/mosdns/redirect.lock" ] && restore_setting
|
||||
! nft --check list table inet mosdns > "/dev/null" 2>&1 || \
|
||||
nft delete table inet mosdns
|
||||
reload_dnsmasq
|
||||
delcron
|
||||
}
|
||||
143
luci-app-mosdns/root/etc/mosdns/config_custom.yaml
Normal file
143
luci-app-mosdns/root/etc/mosdns/config_custom.yaml
Normal file
@@ -0,0 +1,143 @@
|
||||
log:
|
||||
level: info
|
||||
file: "/var/log/mosdns.log"
|
||||
|
||||
# API 入口设置
|
||||
api:
|
||||
http: "0.0.0.0:9091"
|
||||
|
||||
include: []
|
||||
|
||||
plugins:
|
||||
# 国内域名
|
||||
- tag: geosite_cn
|
||||
type: domain_set
|
||||
args:
|
||||
files:
|
||||
- "/var/mosdns/geosite_cn.txt"
|
||||
|
||||
# 国内 IP
|
||||
- tag: geoip_cn
|
||||
type: ip_set
|
||||
args:
|
||||
files:
|
||||
- "/var/mosdns/geoip_cn.txt"
|
||||
|
||||
# 国外域名
|
||||
- tag: geosite_no_cn
|
||||
type: domain_set
|
||||
args:
|
||||
files:
|
||||
- "/var/mosdns/geosite_geolocation-!cn.txt"
|
||||
|
||||
# 缓存
|
||||
- tag: lazy_cache
|
||||
type: cache
|
||||
args:
|
||||
size: 20000
|
||||
lazy_cache_ttl: 86400
|
||||
dump_file: "/etc/mosdns/cache.dump"
|
||||
dump_interval: 600
|
||||
|
||||
# 转发至本地服务器
|
||||
- tag: forward_local
|
||||
type: forward
|
||||
args:
|
||||
upstreams:
|
||||
- addr: "https://doh.pub/dns-query"
|
||||
bootstrap: 180.76.76.76
|
||||
- addr: 119.29.29.29
|
||||
|
||||
# 转发至远程服务器
|
||||
- tag: forward_remote
|
||||
type: forward
|
||||
args:
|
||||
upstreams:
|
||||
- addr: tls://8.8.8.8
|
||||
enable_pipeline: false
|
||||
|
||||
# 国内解析
|
||||
- tag: local_sequence
|
||||
type: sequence
|
||||
args:
|
||||
- exec: $forward_local
|
||||
|
||||
# 国外解析
|
||||
- tag: remote_sequence
|
||||
type: sequence
|
||||
args:
|
||||
- exec: prefer_ipv4
|
||||
- exec: $forward_remote
|
||||
|
||||
# 有响应终止返回
|
||||
- tag: has_resp_sequence
|
||||
type: sequence
|
||||
args:
|
||||
- matches: has_resp
|
||||
exec: accept
|
||||
|
||||
# fallback 用本地服务器 sequence
|
||||
# 返回非国内 ip 则 drop_resp
|
||||
- tag: query_is_local_ip
|
||||
type: sequence
|
||||
args:
|
||||
- exec: $local_sequence
|
||||
- matches: "!resp_ip $geoip_cn"
|
||||
exec: drop_resp
|
||||
|
||||
# fallback 用远程服务器 sequence
|
||||
- tag: query_is_remote
|
||||
type: sequence
|
||||
args:
|
||||
- exec: $remote_sequence
|
||||
|
||||
# fallback 用远程服务器 sequence
|
||||
- tag: fallback
|
||||
type: fallback
|
||||
args:
|
||||
primary: query_is_local_ip
|
||||
secondary: query_is_remote
|
||||
threshold: 500
|
||||
always_standby: true
|
||||
|
||||
# 查询国内域名
|
||||
- tag: query_is_local_domain
|
||||
type: sequence
|
||||
args:
|
||||
- matches: qname $geosite_cn
|
||||
exec: $local_sequence
|
||||
|
||||
# 查询国外域名
|
||||
- tag: query_is_no_local_domain
|
||||
type: sequence
|
||||
args:
|
||||
- matches: qname $geosite_no_cn
|
||||
exec: $remote_sequence
|
||||
|
||||
# 主要的运行逻辑插件
|
||||
# sequence 插件中调用的插件 tag 必须在 sequence 前定义,
|
||||
# 否则 sequence 找不到对应插件。
|
||||
- tag: main_sequence
|
||||
type: sequence
|
||||
args:
|
||||
- exec: $lazy_cache
|
||||
- exec: jump has_resp_sequence
|
||||
- exec: $query_is_local_domain
|
||||
- exec: jump has_resp_sequence
|
||||
- exec: $query_is_no_local_domain
|
||||
- exec: jump has_resp_sequence
|
||||
- exec: $fallback
|
||||
|
||||
# 启动 udp 服务器。
|
||||
- tag: udp_server
|
||||
type: udp_server
|
||||
args:
|
||||
entry: main_sequence
|
||||
listen: ":5335"
|
||||
|
||||
# 启动 tcp 服务器。
|
||||
- tag: tcp_server
|
||||
type: tcp_server
|
||||
args:
|
||||
entry: main_sequence
|
||||
listen: ":5335"
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/blocklist.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/blocklist.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
22
luci-app-mosdns/root/etc/mosdns/rule/cloudflare-cidr.txt
Normal file
22
luci-app-mosdns/root/etc/mosdns/rule/cloudflare-cidr.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
173.245.48.0/20
|
||||
103.21.244.0/22
|
||||
103.22.200.0/22
|
||||
103.31.4.0/22
|
||||
141.101.64.0/18
|
||||
108.162.192.0/18
|
||||
190.93.240.0/20
|
||||
188.114.96.0/20
|
||||
197.234.240.0/22
|
||||
198.41.128.0/17
|
||||
162.158.0.0/15
|
||||
104.16.0.0/13
|
||||
104.24.0.0/14
|
||||
172.64.0.0/13
|
||||
131.0.72.0/22
|
||||
2400:cb00::/32
|
||||
2606:4700::/32
|
||||
2803:f800::/32
|
||||
2405:b500::/32
|
||||
2405:8100::/32
|
||||
2a06:98c0::/29
|
||||
2c0f:f248::/32
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/ddnslist.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/ddnslist.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/greylist.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/greylist.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/hosts.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/hosts.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
87
luci-app-mosdns/root/etc/mosdns/rule/local-ptr.txt
Normal file
87
luci-app-mosdns/root/etc/mosdns/rule/local-ptr.txt
Normal file
@@ -0,0 +1,87 @@
|
||||
0.in-addr.arpa
|
||||
10.in-addr.arpa
|
||||
127.in-addr.arpa
|
||||
16.172.in-addr.arpa
|
||||
17.172.in-addr.arpa
|
||||
18.172.in-addr.arpa
|
||||
19.172.in-addr.arpa
|
||||
20.172.in-addr.arpa
|
||||
21.172.in-addr.arpa
|
||||
22.172.in-addr.arpa
|
||||
23.172.in-addr.arpa
|
||||
24.172.in-addr.arpa
|
||||
25.172.in-addr.arpa
|
||||
26.172.in-addr.arpa
|
||||
27.172.in-addr.arpa
|
||||
28.172.in-addr.arpa
|
||||
29.172.in-addr.arpa
|
||||
30.172.in-addr.arpa
|
||||
31.172.in-addr.arpa
|
||||
64.100.in-addr.arpa
|
||||
65.100.in-addr.arpa
|
||||
66.100.in-addr.arpa
|
||||
67.100.in-addr.arpa
|
||||
68.100.in-addr.arpa
|
||||
69.100.in-addr.arpa
|
||||
70.100.in-addr.arpa
|
||||
71.100.in-addr.arpa
|
||||
72.100.in-addr.arpa
|
||||
73.100.in-addr.arpa
|
||||
74.100.in-addr.arpa
|
||||
75.100.in-addr.arpa
|
||||
76.100.in-addr.arpa
|
||||
77.100.in-addr.arpa
|
||||
78.100.in-addr.arpa
|
||||
79.100.in-addr.arpa
|
||||
80.100.in-addr.arpa
|
||||
81.100.in-addr.arpa
|
||||
82.100.in-addr.arpa
|
||||
83.100.in-addr.arpa
|
||||
84.100.in-addr.arpa
|
||||
85.100.in-addr.arpa
|
||||
86.100.in-addr.arpa
|
||||
87.100.in-addr.arpa
|
||||
88.100.in-addr.arpa
|
||||
89.100.in-addr.arpa
|
||||
90.100.in-addr.arpa
|
||||
91.100.in-addr.arpa
|
||||
92.100.in-addr.arpa
|
||||
93.100.in-addr.arpa
|
||||
94.100.in-addr.arpa
|
||||
95.100.in-addr.arpa
|
||||
96.100.in-addr.arpa
|
||||
97.100.in-addr.arpa
|
||||
98.100.in-addr.arpa
|
||||
99.100.in-addr.arpa
|
||||
100.100.in-addr.arpa
|
||||
101.100.in-addr.arpa
|
||||
102.100.in-addr.arpa
|
||||
103.100.in-addr.arpa
|
||||
104.100.in-addr.arpa
|
||||
105.100.in-addr.arpa
|
||||
106.100.in-addr.arpa
|
||||
107.100.in-addr.arpa
|
||||
108.100.in-addr.arpa
|
||||
109.100.in-addr.arpa
|
||||
110.100.in-addr.arpa
|
||||
111.100.in-addr.arpa
|
||||
112.100.in-addr.arpa
|
||||
113.100.in-addr.arpa
|
||||
114.100.in-addr.arpa
|
||||
115.100.in-addr.arpa
|
||||
116.100.in-addr.arpa
|
||||
117.100.in-addr.arpa
|
||||
118.100.in-addr.arpa
|
||||
119.100.in-addr.arpa
|
||||
120.100.in-addr.arpa
|
||||
121.100.in-addr.arpa
|
||||
122.100.in-addr.arpa
|
||||
123.100.in-addr.arpa
|
||||
124.100.in-addr.arpa
|
||||
125.100.in-addr.arpa
|
||||
126.100.in-addr.arpa
|
||||
127.100.in-addr.arpa
|
||||
2.0.192.in-addr.arpa
|
||||
168.192.in-addr.arpa
|
||||
255.255.255.255.in-addr.arpa
|
||||
domain:ip6.arpa
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/redirect.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/redirect.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/streaming.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/streaming.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
2
luci-app-mosdns/root/etc/mosdns/rule/whitelist.txt
Normal file
2
luci-app-mosdns/root/etc/mosdns/rule/whitelist.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
13
luci-app-mosdns/root/etc/uci-defaults/luci-mosdns
Executable file
13
luci-app-mosdns/root/etc/uci-defaults/luci-mosdns
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -f "/etc/config/ucitrack" ] && {
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@mosdns[-1]
|
||||
add ucitrack mosdns
|
||||
set ucitrack.@mosdns[-1].init=mosdns
|
||||
commit ucitrack
|
||||
EOF
|
||||
}
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"admin/services/mosdns": {
|
||||
"title": "MosDNS",
|
||||
"order": 30,
|
||||
"action": {
|
||||
"type": "firstchild"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-mosdns" ],
|
||||
"uci": { "mosdns": true }
|
||||
}
|
||||
},
|
||||
"admin/services/mosdns/basic": {
|
||||
"title": "Basic Setting",
|
||||
"order": 10,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mosdns/basic"
|
||||
}
|
||||
},
|
||||
"admin/services/mosdns/rules": {
|
||||
"title": "Rules",
|
||||
"order": 15,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mosdns/rules"
|
||||
}
|
||||
},
|
||||
"admin/services/mosdns/update": {
|
||||
"title": "Geodata Update",
|
||||
"order": 20,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mosdns/update"
|
||||
}
|
||||
},
|
||||
"admin/services/mosdns/logs": {
|
||||
"title": "Logs",
|
||||
"order": 25,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mosdns/logs"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
luci-app-mosdns/root/usr/share/mosdns/cache.dump
Normal file
BIN
luci-app-mosdns/root/usr/share/mosdns/cache.dump
Normal file
Binary file not shown.
210
luci-app-mosdns/root/usr/share/mosdns/mosdns.sh
Executable file
210
luci-app-mosdns/root/usr/share/mosdns/mosdns.sh
Executable file
@@ -0,0 +1,210 @@
|
||||
#!/bin/sh
|
||||
|
||||
script_action=${1}
|
||||
|
||||
logfile_path() {
|
||||
configfile=$(uci -q get mosdns.config.configfile)
|
||||
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
|
||||
uci -q get mosdns.config.log_file
|
||||
else
|
||||
[ ! -f /etc/mosdns/config_custom.yaml ] && exit 1
|
||||
awk '/^log:/{f=1;next}f==1{if($0~/file:/){print;exit}if($0~/^[^ ]/)exit}' /etc/mosdns/config_custom.yaml | grep -Eo "/[^'\"]+"
|
||||
fi
|
||||
}
|
||||
|
||||
print_logfile() {
|
||||
cat $(logfile_path);
|
||||
}
|
||||
|
||||
clean_logfile() {
|
||||
true > $(logfile_path);
|
||||
}
|
||||
|
||||
interface_dns() (
|
||||
if [ "$(uci -q get mosdns.config.custom_local_dns)" = 1 ]; then
|
||||
uci -q get mosdns.config.local_dns
|
||||
else
|
||||
peerdns=$(uci -q get network.wan.peerdns)
|
||||
proto=$(uci -q get network.wan.proto)
|
||||
if [ "$peerdns" = 0 ] || [ "$proto" = "static" ]; then
|
||||
uci -q get network.wan.dns
|
||||
else
|
||||
interface_status=$(ubus call network.interface.wan status)
|
||||
echo $interface_status | jsonfilter -e "@['dns-server'][0]"
|
||||
echo $interface_status | jsonfilter -e "@['dns-server'][1]"
|
||||
fi
|
||||
[ $? -ne 0 ] && echo "119.29.29.29 223.5.5.5"
|
||||
fi
|
||||
)
|
||||
|
||||
get_adlist() (
|
||||
adblock=$(uci -q get mosdns.config.adblock)
|
||||
if [ "$adblock" = 1 ]; then
|
||||
mkdir -p /etc/mosdns/rule/adlist
|
||||
ad_source=$(uci -q get mosdns.config.ad_source)
|
||||
for url in $ad_source;
|
||||
do
|
||||
if [ $(echo $url) = 'geosite.dat' ]; then
|
||||
echo "/var/mosdns/geosite_category-ads-all.txt"
|
||||
elif echo "$url" | grep -Eq "^file://" ; then
|
||||
echo "$url" | sed 's/file:\/\///'
|
||||
else
|
||||
echo "/etc/mosdns/rule/adlist/$(basename $url)"
|
||||
[ ! -f "/etc/mosdns/rule/adlist/$(basename $url)" ] && touch /etc/mosdns/rule/adlist/$(basename $url)
|
||||
fi
|
||||
done
|
||||
else
|
||||
rm -rf /etc/mosdns/rule/adlist /etc/mosdns/rule/.ad_source
|
||||
touch /var/mosdns/disable-ads.txt
|
||||
echo "/var/mosdns/disable-ads.txt"
|
||||
fi
|
||||
)
|
||||
|
||||
adlist_update() {
|
||||
[ "$(uci -q get mosdns.config.adblock)" != 1 ] && return 0
|
||||
lock_file=/var/lock/mosdns_ad_update.lock
|
||||
ad_source=$(uci -q get mosdns.config.ad_source)
|
||||
: > /etc/mosdns/rule/.ad_source
|
||||
if [ -f "$lock_file" ]; then
|
||||
has_update=0
|
||||
exit 0
|
||||
else
|
||||
: > $lock_file
|
||||
fi
|
||||
AD_TMPDIR=$(mktemp -d) || exit 1
|
||||
has_update=0
|
||||
for url in $ad_source;
|
||||
do
|
||||
if [ "$url" != "geosite.dat" ] && [ $(echo "$url" | grep -c -E "^file://") -eq 0 ]; then
|
||||
has_update=1
|
||||
echo "$url" >> /etc/mosdns/rule/.ad_source
|
||||
filename=$(basename $url)
|
||||
if echo "$url" | grep -Eq "^https://raw.githubusercontent.com" ; then
|
||||
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
|
||||
else
|
||||
mirror=""
|
||||
fi
|
||||
echo -e "Downloading $mirror$url"
|
||||
curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "$AD_TMPDIR/$filename" "$mirror$url"
|
||||
fi
|
||||
done
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\e[1;31mRules download failed."
|
||||
rm -rf "$AD_TMPDIR" "$lock_file"
|
||||
exit 1
|
||||
else
|
||||
[ $has_update -eq 1 ] && {
|
||||
mkdir -p /etc/mosdns/rule/adlist
|
||||
rm -rf /etc/mosdns/rule/adlist/*
|
||||
\cp $AD_TMPDIR/* /etc/mosdns/rule/adlist
|
||||
}
|
||||
fi
|
||||
rm -rf "$AD_TMPDIR" "$lock_file"
|
||||
}
|
||||
|
||||
geodat_update() (
|
||||
TMPDIR=$(mktemp -d) || exit 1
|
||||
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
|
||||
# geoip.dat - cn-private
|
||||
geoip_type=$(uci -q get mosdns.config.geoip_type || echo "geoip-only-cn-private")
|
||||
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat"
|
||||
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geoip.dat" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat"
|
||||
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
|
||||
# checksum - geoip.dat
|
||||
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat.sha256sum"
|
||||
curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "$TMPDIR/geoip.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat.sha256sum"
|
||||
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
|
||||
if [ "$(sha256sum "$TMPDIR/geoip.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geoip.dat.sha256sum" | awk '{print $1}')" ]; then
|
||||
echo -e "\e[1;31mgeoip.dat checksum error"
|
||||
rm -rf "$TMPDIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# geosite.dat
|
||||
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geosite.dat" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
|
||||
# checksum - geosite.dat
|
||||
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
|
||||
curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "$TMPDIR/geosite.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
|
||||
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
|
||||
if [ "$(sha256sum "$TMPDIR/geosite.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geosite.dat.sha256sum" | awk '{print $1}')" ]; then
|
||||
echo -e "\e[1;31mgeosite.dat checksum error"
|
||||
rm -rf "$TMPDIR"
|
||||
exit 1
|
||||
fi
|
||||
rm -rf "$TMPDIR"/*.sha256sum
|
||||
\cp -a "$TMPDIR"/* /usr/share/v2ray
|
||||
rm -rf "$TMPDIR"
|
||||
)
|
||||
|
||||
restart_service() {
|
||||
/etc/init.d/mosdns restart
|
||||
}
|
||||
|
||||
flush_cache() {
|
||||
curl -s 127.0.0.1:$(uci -q get mosdns.config.listen_port_api)/plugins/lazy_cache/flush || exit 1
|
||||
}
|
||||
|
||||
v2dat_dump() {
|
||||
# env
|
||||
v2dat_dir=/usr/share/v2ray
|
||||
adblock=$(uci -q get mosdns.config.adblock)
|
||||
ad_source=$(uci -q get mosdns.config.ad_source)
|
||||
configfile=$(uci -q get mosdns.config.configfile)
|
||||
streaming_media=$(uci -q get mosdns.config.custom_stream_media_dns)
|
||||
mkdir -p /var/mosdns
|
||||
rm -f /var/mosdns/geo*.txt
|
||||
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
|
||||
# default config
|
||||
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
|
||||
v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' $v2dat_dir/geosite.dat
|
||||
[ "$adblock" = 1 ] && [ $(echo $ad_source | grep -c geosite.dat) -ge '1' ] && v2dat unpack geosite -o /var/mosdns -f category-ads-all $v2dat_dir/geosite.dat
|
||||
[ "$streaming_media" = 1 ] && v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu $v2dat_dir/geosite.dat || \
|
||||
touch /var/mosdns/geosite_disney.txt ; touch /var/mosdns/geosite_netflix.txt ; touch /var/mosdns/geosite_hulu.txt
|
||||
else
|
||||
# custom config
|
||||
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
|
||||
v2dat unpack geosite -o /var/mosdns -f cn -f 'geolocation-!cn' $v2dat_dir/geosite.dat
|
||||
geoip_tags=$(uci -q get mosdns.config.geoip_tags)
|
||||
geosite_tags=$(uci -q get mosdns.config.geosite_tags)
|
||||
[ -n "$geoip_tags" ] && v2dat unpack geoip -o /var/mosdns $(echo $geoip_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geoip.dat
|
||||
[ -n "$geosite_tags" ] && v2dat unpack geosite -o /var/mosdns $(echo $geosite_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geosite.dat
|
||||
fi
|
||||
}
|
||||
|
||||
case $script_action in
|
||||
"dns")
|
||||
interface_dns
|
||||
;;
|
||||
"adlist")
|
||||
get_adlist
|
||||
;;
|
||||
"geodata")
|
||||
geodat_update && adlist_update && restart_service
|
||||
;;
|
||||
"logfile")
|
||||
logfile_path
|
||||
;;
|
||||
"adlist_update")
|
||||
adlist_update && [ "$has_update" -eq 1 ] && restart_service
|
||||
;;
|
||||
"flush")
|
||||
flush_cache
|
||||
;;
|
||||
"v2dat_dump")
|
||||
v2dat_dump
|
||||
;;
|
||||
"printlog")
|
||||
print_logfile
|
||||
;;
|
||||
"cleanlog")
|
||||
clean_logfile
|
||||
;;
|
||||
"version")
|
||||
mosdns version
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"luci-app-mosdns": {
|
||||
"description": "Grant UCI access for luci-app-mosdns",
|
||||
"read": {
|
||||
"file": {
|
||||
"/etc/init.d/mosdns": [ "exec" ],
|
||||
"/etc/mosdns/config_custom.yaml": [ "read" ],
|
||||
"/etc/mosdns/rule/blocklist.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/ddnslist.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/greylist.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/hosts.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/local-ptr.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/redirect.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/streaming.txt": [ "read" ],
|
||||
"/etc/mosdns/rule/whitelist.txt": [ "read" ],
|
||||
"/usr/bin/mosdns": [ "exec" ],
|
||||
"/usr/share/mosdns/mosdns.sh": [ "exec" ]
|
||||
},
|
||||
"ubus": {
|
||||
"file": [ "read" ],
|
||||
"service": [ "list" ]
|
||||
},
|
||||
"uci": [ "mosdns" ]
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/etc/mosdns/config_custom.yaml": [ "write" ],
|
||||
"/etc/mosdns/rule/blocklist.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/ddnslist.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/greylist.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/hosts.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/local-ptr.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/redirect.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/streaming.txt": [ "write" ],
|
||||
"/etc/mosdns/rule/whitelist.txt": [ "write" ]
|
||||
},
|
||||
"ubus": {
|
||||
"file": [ "write" ]
|
||||
},
|
||||
"uci": [ "mosdns" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"config": "mosdns",
|
||||
"init": "mosdns"
|
||||
}
|
||||
Reference in New Issue
Block a user