mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-09-10 18:34:09 +08:00
update 2026-07-28 01:38:11
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-mosdns
|
||||
PKG_VERSION:=1.7.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI Support for mosdns
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+mosdns +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
@@ -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
@@ -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
@@ -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
@@ -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})});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
@@ -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
@@ -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,459 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
const callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
function getServiceStatus() {
|
||||
return L.resolveDefault(callServiceList('mosdns'), {}).then(res => {
|
||||
let isRunning = false;
|
||||
try {
|
||||
isRunning = res['mosdns']['instances']['mosdns']['running'];
|
||||
} catch (e) { }
|
||||
return isRunning;
|
||||
});
|
||||
}
|
||||
|
||||
function renderStatus(isRunning) {
|
||||
const spanTemp = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
|
||||
let 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();
|
||||
}
|
||||
|
||||
const callMosdns = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'get_version',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
const callFlushCache = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'flush_cache',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
load() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(callMosdns(), null),
|
||||
]);
|
||||
},
|
||||
|
||||
handleFlushCache() {
|
||||
return callFlushCache().then(res => {
|
||||
if (res.success) {
|
||||
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.') + (res.error ? ': ' + res.error : '')), 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render(data) {
|
||||
let m, s, o;
|
||||
|
||||
const version = (data[0] && data[0].version) ? data[0].version : '';
|
||||
m = new form.Map('mosdns', _('MosDNS') + ' ' + version,
|
||||
_('MosDNS is a plugin-based DNS forwarder/traffic splitter.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
s.render = () => {
|
||||
setTimeout(() => {
|
||||
poll.add(() => {
|
||||
return L.resolveDefault(getServiceStatus()).then(res => {
|
||||
const 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.rmempty = false;
|
||||
|
||||
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.Value, 'listen_address', _('Listen Address'));
|
||||
o.default = '0.0.0.0';
|
||||
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.rmempty = false;
|
||||
|
||||
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 HTTP/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 list or AdGuardHome rules).') +
|
||||
'<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 = section_id => fs.trimmed('/etc/mosdns/rule/cloudflare-cidr.txt');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/cloudflare-cidr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
|
||||
});
|
||||
};
|
||||
|
||||
/* api */
|
||||
o = s.taboption('api', form.Value, 'listen_port_api', _('API Listen port'));
|
||||
o.datatype = 'and(port,min(1))';
|
||||
o.default = 52001;
|
||||
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);
|
||||
o.depends('cache', '1');
|
||||
|
||||
/* configuration */
|
||||
let configeditor = null;
|
||||
setTimeout(() => {
|
||||
const 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 = section_id => fs.trimmed('/etc/mosdns/config_custom.yaml');
|
||||
o.write = function(section_id, formvalue) {
|
||||
if (configeditor) {
|
||||
const editorContent = configeditor.getValue();
|
||||
if (editorContent === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/config_custom.yaml', editorContent.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.then(i => fs.exec('/etc/init.d/mosdns', ['restart']))
|
||||
.then(() => window.location.reload())
|
||||
.catch(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,85 @@
|
||||
'use strict';
|
||||
'require dom';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require view';
|
||||
'require rpc';
|
||||
'require ui';
|
||||
|
||||
const callPrintLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'print_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
const callCleanLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'clean_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
let scrollPosition = 0;
|
||||
let userScrolled = false;
|
||||
let logTextarea;
|
||||
|
||||
function pollLog() {
|
||||
return callPrintLog().then(res => {
|
||||
logTextarea.value = res.log || _('No log data.');
|
||||
|
||||
if (!userScrolled) {
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
} else {
|
||||
logTextarea.scrollTop = scrollPosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
handleCleanLogs() {
|
||||
return callCleanLog().then(res => {
|
||||
if (res.success) {
|
||||
logTextarea.value = ''; // Clear textarea on success
|
||||
} else {
|
||||
ui.addNotification(null, E('p', _('Failed to clean logs.') + (res.error ? ': ' + res.error : '')), 'error');
|
||||
}
|
||||
}).catch(e => ui.addNotification(null, E('p', e.message)));
|
||||
},
|
||||
|
||||
render() {
|
||||
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', () => {
|
||||
userScrolled = true;
|
||||
scrollPosition = logTextarea.scrollTop;
|
||||
});
|
||||
|
||||
const log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
|
||||
poll.add(pollLog);
|
||||
|
||||
const 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,229 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
render() {
|
||||
let 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'));
|
||||
|
||||
// --- White Lists ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/whitelist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/whitelist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/whitelist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Block Lists ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/blocklist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/blocklist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/blocklist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Grey Lists ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/greylist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/greylist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/greylist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- DDNS Lists ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/ddnslist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/ddnslist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/ddnslist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Hosts ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/hosts.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/hosts.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/hosts.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Redirect ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/redirect.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/redirect.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/redirect.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Block PTR ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/local-ptr.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/local-ptr.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/local-ptr.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Streaming Media ---
|
||||
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 = section_id => fs.trimmed('/etc/mosdns/rule/streaming.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/streaming.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/streaming.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
handleSaveApply(ev) {
|
||||
return this.handleSave(ev).then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
handleReset: null
|
||||
});
|
||||
@@ -0,0 +1,156 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
'require rpc';
|
||||
|
||||
const callStartUpdate = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'start_update',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
const callGetUpdateLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'get_update_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
handleUpdate() {
|
||||
const statusMsg = E('p', { 'class': 'spinning' }, _('Please wait, this may take a few moments...'));
|
||||
|
||||
const logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'readonly': 'readonly',
|
||||
'style': 'width: 100%; height: 300px; font-family: monospace; font-size: 12px; margin-top: 10px;',
|
||||
'placeholder': _('Starting update...')
|
||||
});
|
||||
|
||||
const closeButton = E('button', {
|
||||
'class': 'btn',
|
||||
'style': 'display: none;',
|
||||
'click': ui.hideModal
|
||||
}, _('Close'));
|
||||
|
||||
ui.showModal(_('Updating Database...'), [
|
||||
statusMsg,
|
||||
logTextarea,
|
||||
E('div', { 'class': 'right' }, [ closeButton ])
|
||||
]);
|
||||
|
||||
const pollLog = () => {
|
||||
return callGetUpdateLog().then(res => {
|
||||
if (res && res.log) {
|
||||
logTextarea.value = res.log;
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
|
||||
if (res.log.match(/UPDATE_FINISHED/)) {
|
||||
statusMsg.textContent = _('Update success');
|
||||
statusMsg.classList.remove('spinning');
|
||||
statusMsg.style.color = '#19be6b';
|
||||
statusMsg.style.fontWeight = 'bold';
|
||||
closeButton.style.display = 'inline';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res.log.match(/UPDATE_EXITED/)) {
|
||||
statusMsg.textContent = _('Update failed');
|
||||
statusMsg.classList.remove('spinning');
|
||||
statusMsg.style.color = '#ed4014';
|
||||
statusMsg.style.fontWeight = 'bold';
|
||||
closeButton.style.display = 'inline';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res.log.match(/Another update is already in progress/)) {
|
||||
statusMsg.textContent = _('Another update is already in progress.');
|
||||
statusMsg.classList.remove('spinning');
|
||||
statusMsg.style.color = '#ff9900';
|
||||
closeButton.style.display = 'inline';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
return callStartUpdate().then(res => {
|
||||
if (res.success) {
|
||||
const interval = window.setInterval(() => {
|
||||
pollLog().then(continuePolling => {
|
||||
if (!continuePolling) {
|
||||
window.clearInterval(interval);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
} else {
|
||||
statusMsg.textContent = res.error || _('Failed to start update.');
|
||||
statusMsg.classList.remove('spinning');
|
||||
statusMsg.style.color = '#ed4014';
|
||||
closeButton.style.display = 'inline';
|
||||
}
|
||||
}).catch(e => {
|
||||
statusMsg.textContent = _('Update failed: %s').format(e.message);
|
||||
statusMsg.classList.remove('spinning');
|
||||
statusMsg.style.color = '#ed4014';
|
||||
closeButton.style.display = 'inline';
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
let 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-only-cn-private';
|
||||
|
||||
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 = () => this.handleUpdate();
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,790 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:217
|
||||
msgid "360 Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:356
|
||||
msgid "ADblock Source"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:395
|
||||
msgid "API Listen port"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:138
|
||||
msgid "API Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:31
|
||||
msgid ""
|
||||
"Added domain names always permit resolution using 'local DNS' with the "
|
||||
"highest priority (one domain per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:103
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:79
|
||||
msgid ""
|
||||
"Added domain names will always use 'Remote DNS' for resolution (one domain "
|
||||
"per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:55
|
||||
msgid ""
|
||||
"Added domain names will block DNS resolution (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:175
|
||||
msgid ""
|
||||
"Added domain names will block PTR requests (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:136
|
||||
msgid "Advanced Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
msgid "Aliyun Public DNS (223.5.5.5)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:216
|
||||
msgid "Aliyun Public DNS (DNS over HTTP/3)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
msgid "Aliyun Public DNS (DNS over QUIC)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:68
|
||||
msgid "Another update is already in progress."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:198
|
||||
msgid "Apple domains optimization"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
|
||||
msgid "Auto Save Cache Interval"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:106
|
||||
msgid ""
|
||||
"Automatically update GeoIP and GeoSite databases as well as ad filtering "
|
||||
"rules through scheduled tasks."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
msgid "Baidu Public DNS (180.76.76.76)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:135
|
||||
msgid "Basic Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:14
|
||||
msgid "Basic Setting"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
|
||||
msgid ""
|
||||
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
|
||||
"using only A/AAAA records."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:19
|
||||
msgid "Block Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:24
|
||||
msgid "Block PTR"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:250
|
||||
msgid "Bootstrap DNS servers"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:251
|
||||
msgid ""
|
||||
"Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT "
|
||||
"resolvers you specify as upstreams"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
|
||||
msgid "Cache Dump"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:150
|
||||
msgid "Check And Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:148
|
||||
msgid "Check And Update GeoData."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:184
|
||||
msgid "China DNS prefer IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:203
|
||||
msgid "China DNS server"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:229
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:246
|
||||
msgid "Cisco Public DNS (208.67.220.220)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:228
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:245
|
||||
msgid "Cisco Public DNS (208.67.222.222)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:65
|
||||
msgid "Clear logs"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:35
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
msgid "CloudFlare Public DNS (1.0.0.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:222
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:239
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:260
|
||||
msgid "CloudFlare Public DNS (1.1.1.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
|
||||
msgid "Cloudflare IP Ranges"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:137
|
||||
msgid "Cloudflare Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:129
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:265
|
||||
msgid "Concurrent"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
msgid "Config File"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:426
|
||||
msgid "Configuration Editor"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:194
|
||||
msgid "Custom China DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:148
|
||||
msgid "Custom Config"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:127
|
||||
msgid ""
|
||||
"Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, "
|
||||
"supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:375
|
||||
msgid "Custom IP"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:233
|
||||
msgid "Custom Stream Media DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:21
|
||||
msgid "DDNS Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:312
|
||||
msgid "DNS Cache Size"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:175
|
||||
msgid "DNS Forward"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:266
|
||||
msgid ""
|
||||
"DNS query request concurrency, The number of upstream DNS servers that are "
|
||||
"allowed to initiate requests at the same time"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:179
|
||||
msgid "DNS redirect"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:149
|
||||
msgid "Database Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:162
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:147
|
||||
msgid "Default Config"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
|
||||
msgid "Disable RR Type 65 (HTTPS/SVCB)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:283
|
||||
msgid "Disable TLS Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:284
|
||||
msgid ""
|
||||
"Disable TLS Servers certificate validation, Can be useful if system CA "
|
||||
"certificate expires or the system time is out of order"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:272
|
||||
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:111
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:352
|
||||
msgid "Enable DNS ADblock"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:307
|
||||
msgid "Enable DNS Cache"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:290
|
||||
msgid "Enable EDNS client subnet"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:278
|
||||
msgid ""
|
||||
"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:302
|
||||
msgid "Enable this option fallback policy forces forwarding to remote DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:368
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:453
|
||||
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:448
|
||||
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:165
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:115
|
||||
msgid "Every Day"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:120
|
||||
msgid "Every Friday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:116
|
||||
msgid "Every Monday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:121
|
||||
msgid "Every Saturday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:122
|
||||
msgid "Every Sunday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:119
|
||||
msgid "Every Thursday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:117
|
||||
msgid "Every Tuesday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:118
|
||||
msgid "Every Wednesday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:449
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:454
|
||||
msgid "Export directory: /var/mosdns"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:43
|
||||
msgid "Failed to clean logs."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:89
|
||||
msgid "Failed to start update."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:403
|
||||
msgid "Flush DNS Cache"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:97
|
||||
msgid "Flushing DNS Cache Failed, Please check if MosDNS is running."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:95
|
||||
msgid "Flushing DNS Cache Success."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
|
||||
msgid ""
|
||||
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
|
||||
"cache."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:194
|
||||
msgid "Follow WAN interface DNS if not enabled"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:199
|
||||
msgid ""
|
||||
"For Apple domains equipped with Chinese mainland CDN, always responsive to "
|
||||
"Chinese CDN IP addresses"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:179
|
||||
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:175
|
||||
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:136
|
||||
msgid "Full"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:134
|
||||
msgid "Full: includes all Countries and Private IP addresses."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
msgid "GeoData Export"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
msgid "GeoIP Tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:131
|
||||
msgid "GeoIP Type"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
|
||||
msgid "GeoSite Tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:30
|
||||
msgid "Geodata Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:141
|
||||
msgid "GitHub Proxy"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
msgid "Google Public DNS (8.8.4.4)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:259
|
||||
msgid "Google Public DNS (8.8.8.8)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json:3
|
||||
msgid "Grant UCI access for luci-app-mosdns"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:20
|
||||
msgid "Grey Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:22
|
||||
msgid "Hosts"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:295
|
||||
msgid "IP Address"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
|
||||
msgid ""
|
||||
"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>"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:185
|
||||
msgid ""
|
||||
"IPv4 is preferred for China DNS resolution of dual-stack addresses, and is "
|
||||
"not affected when the destination is IPv6 only"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:190
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:271
|
||||
msgid "Idle Timeout"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:163
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:317
|
||||
msgid "Lazy Cache TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:318
|
||||
msgid ""
|
||||
"Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:157
|
||||
msgid "Listen Address"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:152
|
||||
msgid "Listen Port"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:137
|
||||
msgid "Little"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:132
|
||||
msgid "Little: only include Mainland China and Private IP addresses."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
msgid "Log Data"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:169
|
||||
msgid "Log File"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:161
|
||||
msgid "Log Level"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:38
|
||||
msgid "Logs"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:369
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
|
||||
msgid "Maximum TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
|
||||
msgid "Minimum TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
|
||||
msgid ""
|
||||
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
|
||||
msgid ""
|
||||
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:106
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:3
|
||||
msgid "MosDNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:107
|
||||
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:234
|
||||
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:27
|
||||
msgid "No log data."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:296
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:22
|
||||
msgid "Please wait, this may take a few moments..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:301
|
||||
msgid "Prevent DNS Leaks"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
msgid "Quad9 Public DNS (149.112.112.112)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
msgid "Quad9 Public DNS (9.9.9.9)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:23
|
||||
msgid "Redirect"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:75
|
||||
msgid "Refresh every %s seconds."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:189
|
||||
msgid "Remote DNS prefer IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:221
|
||||
msgid "Remote DNS server"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:11
|
||||
msgid "Rule Settings"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:22
|
||||
msgid "Rules"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
|
||||
msgid "Save the cache locally and reload the cache dump on the next startup"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:28
|
||||
msgid "Starting update..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:25
|
||||
msgid "Streaming Media"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:238
|
||||
msgid "Streaming Media DNS server"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
|
||||
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:277
|
||||
msgid "TCP/DoT Connection Multiplexing"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
msgid "Tencent Public DNS (119.28.28.28)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:204
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
msgid "Tencent Public DNS (119.29.29.29)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
msgid "Tencent Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:12
|
||||
msgid "The list of rules only apply to 'Default Config' profiles."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:297
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:442
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:72
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:96
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:115
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:120
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:144
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:163
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:216
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:114
|
||||
msgid "Update Cycle"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:105
|
||||
msgid "Update GeoIP & GeoSite databases"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:125
|
||||
msgid "Update Time"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:142
|
||||
msgid ""
|
||||
"Update data files with GitHub Proxy, leave blank to disable proxy downloads."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:59
|
||||
msgid "Update failed"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:95
|
||||
msgid "Update failed: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:50
|
||||
msgid "Update success"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:37
|
||||
msgid "Updating Database..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:199
|
||||
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 ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
|
||||
msgid ""
|
||||
"When using custom rule sources, please use rule types supported by MosDNS "
|
||||
"(domain list or AdGuardHome rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:18
|
||||
msgid "White Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
msgid "Xinfeng Public DNS (114.114.115.115)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:143
|
||||
msgid "https://gh-proxy.com"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,824 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-20 09:23+0800\n"
|
||||
"PO-Revision-Date: 2026-05-15 14:09+0800\n"
|
||||
"Last-Translator: sbwml <admin@cooluc.com>\n"
|
||||
"Language-Team: Chinese\n"
|
||||
"Language: zh_Hans\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:217
|
||||
msgid "360 Public DNS (DNS over HTTPS)"
|
||||
msgstr "360 安全 DNS(DNS over HTTPS)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:356
|
||||
msgid "ADblock Source"
|
||||
msgstr "广告过滤规则来源"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:395
|
||||
msgid "API Listen port"
|
||||
msgstr "API 监听端口"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:138
|
||||
msgid "API Options"
|
||||
msgstr "API 选项"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:31
|
||||
msgid ""
|
||||
"Added domain names always permit resolution using 'local DNS' with the "
|
||||
"highest priority (one domain per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
"加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持"
|
||||
"域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:103
|
||||
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 秒,解析结果不会进入缓"
|
||||
"存(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:79
|
||||
msgid ""
|
||||
"Added domain names will always use 'Remote DNS' for resolution (one domain "
|
||||
"per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
"加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:55
|
||||
msgid ""
|
||||
"Added domain names will block DNS resolution (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:175
|
||||
msgid ""
|
||||
"Added domain names will block PTR requests (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:136
|
||||
msgid "Advanced Options"
|
||||
msgstr "高级选项"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
msgid "Aliyun Public DNS (223.5.5.5)"
|
||||
msgstr "阿里云公共 DNS(223.5.5.5)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr "阿里云公共 DNS(223.6.6.6)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:216
|
||||
msgid "Aliyun Public DNS (DNS over HTTP/3)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTP/3)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTPS)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
msgid "Aliyun Public DNS (DNS over QUIC)"
|
||||
msgstr "阿里云公共 DNS(DNS over QUIC)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:68
|
||||
msgid "Another update is already in progress."
|
||||
msgstr "另一个更新正在进行中。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:198
|
||||
msgid "Apple domains optimization"
|
||||
msgstr "Apple 域名解析优化"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
|
||||
msgid "Auto Save Cache Interval"
|
||||
msgstr "自动保存缓存间隔(秒)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:106
|
||||
msgid ""
|
||||
"Automatically update GeoIP and GeoSite databases as well as ad filtering "
|
||||
"rules through scheduled tasks."
|
||||
msgstr "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
msgid "Baidu Public DNS (180.76.76.76)"
|
||||
msgstr "百度公共 DNS(180.76.76.76)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:135
|
||||
msgid "Basic Options"
|
||||
msgstr "基本选项"
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:14
|
||||
msgid "Basic Setting"
|
||||
msgstr "基本设置"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
|
||||
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 "
|
||||
"解析。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:19
|
||||
msgid "Block Lists"
|
||||
msgstr "黑名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:24
|
||||
msgid "Block PTR"
|
||||
msgstr "PTR 黑名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:250
|
||||
msgid "Bootstrap DNS servers"
|
||||
msgstr "Bootstrap DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:251
|
||||
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 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
|
||||
msgid "Cache Dump"
|
||||
msgstr "自动保存缓存"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:150
|
||||
msgid "Check And Update"
|
||||
msgstr "检查并更新"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:148
|
||||
msgid "Check And Update GeoData."
|
||||
msgstr "检查并更新 GeoData 数据库。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:184
|
||||
msgid "China DNS prefer IPv4"
|
||||
msgstr "国内 DNS 首选 IPv4"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:203
|
||||
msgid "China DNS server"
|
||||
msgstr "国内 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:229
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:246
|
||||
msgid "Cisco Public DNS (208.67.220.220)"
|
||||
msgstr "思科公共 DNS(208.67.220.220)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:228
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:245
|
||||
msgid "Cisco Public DNS (208.67.222.222)"
|
||||
msgstr "思科公共 DNS(208.67.222.222)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:65
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:35
|
||||
msgid "Close"
|
||||
msgstr "关闭"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
msgid "CloudFlare Public DNS (1.0.0.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.0.0.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:222
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:239
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:260
|
||||
msgid "CloudFlare Public DNS (1.1.1.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.1.1.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
|
||||
msgid "Cloudflare IP Ranges"
|
||||
msgstr "Cloudflare IP 范围"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:137
|
||||
msgid "Cloudflare Options"
|
||||
msgstr "Cloudflare 选项"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:129
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:265
|
||||
msgid "Concurrent"
|
||||
msgstr "DNS 服务器并发数(默认 2)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
msgid "Config File"
|
||||
msgstr "配置文件"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:426
|
||||
msgid "Configuration Editor"
|
||||
msgstr "配置编辑器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:194
|
||||
msgid "Custom China DNS"
|
||||
msgstr "自定义国内 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:148
|
||||
msgid "Custom Config"
|
||||
msgstr "自定义"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:127
|
||||
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(每个规则一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:375
|
||||
msgid "Custom IP"
|
||||
msgstr "自选 IP"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:233
|
||||
msgid "Custom Stream Media DNS"
|
||||
msgstr "自定义流媒体 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:21
|
||||
msgid "DDNS Lists"
|
||||
msgstr "DDNS 域名"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:312
|
||||
msgid "DNS Cache Size"
|
||||
msgstr "DNS 缓存大小"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:175
|
||||
msgid "DNS Forward"
|
||||
msgstr "DNS 转发"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:266
|
||||
msgid ""
|
||||
"DNS query request concurrency, The number of upstream DNS servers that are "
|
||||
"allowed to initiate requests at the same time"
|
||||
msgstr "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:179
|
||||
msgid "DNS redirect"
|
||||
msgstr "DNS 重定向"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:149
|
||||
msgid "Database Update"
|
||||
msgstr "数据库更新"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:162
|
||||
msgid "Debug"
|
||||
msgstr "调试"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:147
|
||||
msgid "Default Config"
|
||||
msgstr "内置预设"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
|
||||
msgid "Disable RR Type 65 (HTTPS/SVCB)"
|
||||
msgstr "禁用 RR Type 65 (HTTPS/SVCB)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:283
|
||||
msgid "Disable TLS Certificate"
|
||||
msgstr "禁用 TLS 证书"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:284
|
||||
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 证书过期或系统时间错乱时,本选项可能会有用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:272
|
||||
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
|
||||
msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:111
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr "启用自动更新"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:352
|
||||
msgid "Enable DNS ADblock"
|
||||
msgstr "启用 DNS 广告过滤"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:307
|
||||
msgid "Enable DNS Cache"
|
||||
msgstr "启用 DNS 缓存"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:290
|
||||
msgid "Enable EDNS client subnet"
|
||||
msgstr "启用 EDNS 客户端子网"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:278
|
||||
msgid ""
|
||||
"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
|
||||
msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:302
|
||||
msgid "Enable this option fallback policy forces forwarding to remote DNS"
|
||||
msgstr "启用此选项 fallback 策略会强制转发到远程 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:368
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:453
|
||||
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:448
|
||||
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:165
|
||||
msgid "Error"
|
||||
msgstr "错误"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:115
|
||||
msgid "Every Day"
|
||||
msgstr "每天"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:120
|
||||
msgid "Every Friday"
|
||||
msgstr "每周五"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:116
|
||||
msgid "Every Monday"
|
||||
msgstr "每周一"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:121
|
||||
msgid "Every Saturday"
|
||||
msgstr "每周六"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:122
|
||||
msgid "Every Sunday"
|
||||
msgstr "每周日"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:119
|
||||
msgid "Every Thursday"
|
||||
msgstr "每周四"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:117
|
||||
msgid "Every Tuesday"
|
||||
msgstr "每周二"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:118
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:449
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:454
|
||||
msgid "Export directory: /var/mosdns"
|
||||
msgstr "导出目录:/var/mosdns"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:43
|
||||
msgid "Failed to clean logs."
|
||||
msgstr "清理日志失败:%s"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:89
|
||||
msgid "Failed to start update."
|
||||
msgstr "启动更新失败"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:403
|
||||
msgid "Flush DNS Cache"
|
||||
msgstr "刷新 DNS 缓存"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:97
|
||||
msgid "Flushing DNS Cache Failed, Please check if MosDNS is running."
|
||||
msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:95
|
||||
msgid "Flushing DNS Cache Success."
|
||||
msgstr "刷新 DNS 缓存成功"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
|
||||
msgid ""
|
||||
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
|
||||
"cache."
|
||||
msgstr "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:194
|
||||
msgid "Follow WAN interface DNS if not enabled"
|
||||
msgstr "不启用则使用 WAN 接口 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:199
|
||||
msgid ""
|
||||
"For Apple domains equipped with Chinese mainland CDN, always responsive to "
|
||||
"Chinese CDN IP addresses"
|
||||
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:179
|
||||
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
|
||||
msgstr "强制将所有本地 DNS 查询重定向到 MosDNS,即 DNS 劫持。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:175
|
||||
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
|
||||
msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:136
|
||||
msgid "Full"
|
||||
msgstr "全量"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:134
|
||||
msgid "Full: includes all Countries and Private IP addresses."
|
||||
msgstr "全量:包含所有国家和私有 IP 地址。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
msgid "GeoData Export"
|
||||
msgstr "GeoData 导出"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
msgid "GeoIP Tags"
|
||||
msgstr "GeoIP 标签"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:131
|
||||
msgid "GeoIP Type"
|
||||
msgstr "GeoIP 类型"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
|
||||
msgid "GeoSite Tags"
|
||||
msgstr "GeoSite 标签"
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:30
|
||||
msgid "Geodata Update"
|
||||
msgstr "更新数据库"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:141
|
||||
msgid "GitHub Proxy"
|
||||
msgstr "GitHub 代理"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
msgid "Google Public DNS (8.8.4.4)"
|
||||
msgstr "谷歌公共 DNS(8.8.4.4)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:259
|
||||
msgid "Google Public DNS (8.8.8.8)"
|
||||
msgstr "谷歌公共 DNS(8.8.8.8)"
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json:3
|
||||
msgid "Grant UCI access for luci-app-mosdns"
|
||||
msgstr "授予 luci-app-mosdns 的 UCI 访问权限"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:20
|
||||
msgid "Grey Lists"
|
||||
msgstr "灰名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:22
|
||||
msgid "Hosts"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:295
|
||||
msgid "IP Address"
|
||||
msgstr "IP 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
|
||||
msgid ""
|
||||
"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>"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:185
|
||||
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 时不受影响"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:190
|
||||
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 时不受影响"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:271
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超时"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:163
|
||||
msgid "Info"
|
||||
msgstr "信息"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:317
|
||||
msgid "Lazy Cache TTL"
|
||||
msgstr "乐观缓存 TTL"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:318
|
||||
msgid ""
|
||||
"Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
|
||||
msgstr "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:157
|
||||
msgid "Listen Address"
|
||||
msgstr "监听地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:152
|
||||
msgid "Listen Port"
|
||||
msgstr "监听端口"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:137
|
||||
msgid "Little"
|
||||
msgstr "轻量"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:132
|
||||
msgid "Little: only include Mainland China and Private IP addresses."
|
||||
msgstr "轻量:仅包含中国大陆和私有 IP 地址。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
msgid "Log Data"
|
||||
msgstr "日志数据"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:169
|
||||
msgid "Log File"
|
||||
msgstr "日志文件"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:161
|
||||
msgid "Log Level"
|
||||
msgstr "日志等级"
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:38
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:369
|
||||
#, fuzzy
|
||||
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” 作为解"
|
||||
"析结果(实验性功能)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
|
||||
msgid "Maximum TTL"
|
||||
msgstr "覆盖最大 TTL 值(默认 0)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
|
||||
msgid "Minimum TTL"
|
||||
msgstr "覆盖最小 TTL 值(默认 0)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
|
||||
msgid ""
|
||||
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
|
||||
msgid ""
|
||||
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr "修改 DNS 应答结果的最小 TTL 值 (秒),0 表示不修改"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:106
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:3
|
||||
msgid "MosDNS"
|
||||
msgstr "MosDNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:107
|
||||
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
|
||||
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:234
|
||||
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
|
||||
msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表的 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:27
|
||||
msgid "No log data."
|
||||
msgstr "无日志数据。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:296
|
||||
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 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:22
|
||||
msgid "Please wait, this may take a few moments..."
|
||||
msgstr "请稍候,这可能需要一点时间..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:301
|
||||
msgid "Prevent DNS Leaks"
|
||||
msgstr "防止 DNS 泄漏"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
msgid "Quad9 Public DNS (149.112.112.112)"
|
||||
msgstr "Quad9 公共 DNS(149.112.112.112)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
msgid "Quad9 Public DNS (9.9.9.9)"
|
||||
msgstr "Quad9 公共 DNS(9.9.9.9)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:23
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
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(每个"
|
||||
"规则一行)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:75
|
||||
msgid "Refresh every %s seconds."
|
||||
msgstr "每 %s 秒刷新。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:189
|
||||
msgid "Remote DNS prefer IPv4"
|
||||
msgstr "远程 DNS 首选 IPv4"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:221
|
||||
msgid "Remote DNS server"
|
||||
msgstr "远程 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:11
|
||||
msgid "Rule Settings"
|
||||
msgstr "自定义规则列表"
|
||||
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:22
|
||||
msgid "Rules"
|
||||
msgstr "规则列表"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
|
||||
msgid "Save the cache locally and reload the cache dump on the next startup"
|
||||
msgstr "保存缓存到本地文件,以供下次启动时重新载入使用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:28
|
||||
msgid "Starting update..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:25
|
||||
msgid "Streaming Media"
|
||||
msgstr "流媒体"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:238
|
||||
msgid "Streaming Media DNS server"
|
||||
msgstr "流媒体 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
|
||||
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
|
||||
msgstr "支持本地文件,例如:file:///var/mosdns/example.txt"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:277
|
||||
msgid "TCP/DoT Connection Multiplexing"
|
||||
msgstr "TCP/DoT 连接复用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
msgid "Tencent Public DNS (119.28.28.28)"
|
||||
msgstr "腾讯公共 DNS(119.28.28.28)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:204
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
msgid "Tencent Public DNS (119.29.29.29)"
|
||||
msgstr "腾讯公共 DNS(119.29.29.29)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
msgid "Tencent Public DNS (DNS over HTTPS)"
|
||||
msgstr "腾讯公共 DNS(DNS over HTTPS)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:12
|
||||
msgid "The list of rules only apply to 'Default Config' profiles."
|
||||
msgstr "规则列表仅适用于 “内置预设” 配置文件。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:297
|
||||
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 上游时使用(需要上游服"
|
||||
"务器的支持)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
|
||||
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 格式的配置内容。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr "火山引擎公共 DNS(180.184.1.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr "火山引擎公共 DNS(180.184.2.2)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:442
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:72
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:96
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:115
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:120
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:144
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:163
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:216
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr "无法保存内容:%s"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:114
|
||||
msgid "Update Cycle"
|
||||
msgstr "更新周期"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:105
|
||||
msgid "Update GeoIP & GeoSite databases"
|
||||
msgstr "更新广告规则、GeoIP & GeoSite 数据库"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:125
|
||||
msgid "Update Time"
|
||||
msgstr "更新时间"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:142
|
||||
msgid ""
|
||||
"Update data files with GitHub Proxy, leave blank to disable proxy downloads."
|
||||
msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:59
|
||||
msgid "Update failed"
|
||||
msgstr "更新失败"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:95
|
||||
msgid "Update failed: %s"
|
||||
msgstr "更新失败: %s"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:50
|
||||
msgid "Update success"
|
||||
msgstr "更新成功"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:37
|
||||
msgid "Updating Database..."
|
||||
msgstr "更新数据库..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:199
|
||||
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 服务器” 进行解析"
|
||||
"(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
|
||||
msgid ""
|
||||
"When using custom rule sources, please use rule types supported by MosDNS "
|
||||
"(domain list or AdGuardHome rules)."
|
||||
msgstr ""
|
||||
"使用自定义规则来源时,请使用 MosDNS 支持的规则类型(域名列表或 AdGuardHome 规"
|
||||
"则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:18
|
||||
msgid "White Lists"
|
||||
msgstr "白名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr "信风公共 DNS(114.114.114.114)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
msgid "Xinfeng Public DNS (114.114.115.115)"
|
||||
msgstr "信风公共 DNS(114.114.115.115)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:143
|
||||
msgid "https://gh-proxy.com"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
config mosdns 'config'
|
||||
option enabled '0'
|
||||
option listen_port '5335'
|
||||
option listen_address '0.0.0.0'
|
||||
option geo_auto_update '0'
|
||||
option geo_update_week_time '*'
|
||||
option geo_update_day_time '2'
|
||||
option geoip_type 'geoip-only-cn-private'
|
||||
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
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
[ "$ACTION" = ifup ] && /etc/init.d/mosdns restart
|
||||
Executable
+836
@@ -0,0 +1,836 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2020-2022, IrineSistiana
|
||||
# Copyright (C) 2023-2026, 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.uc
|
||||
REDIRECT_LOCK_FILE=/etc/mosdns/redirect.lock
|
||||
|
||||
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 listen_address $1 listen_address "0.0.0.0"
|
||||
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 52001
|
||||
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" "127.0.0.1:$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" "adblock_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" "adblock_set"
|
||||
json_add_object "args"
|
||||
json_add_array "files"
|
||||
adlist=$($MOSDNS_SCRIPT get_adlist)
|
||||
[ -z "$adlist" ] && adlist="/var/mosdns/disable-ads.txt" # fail-safe
|
||||
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 interface_dns)
|
||||
[ -z "$local_dns" ] && local_dns="119.29.29.29 223.5.5.5" # fail-safe
|
||||
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_address:$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_address:$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"
|
||||
}
|
||||
|
||||
dhcp_setting() {
|
||||
[ ! -f "$REDIRECT_LOCK_FILE" ] && {
|
||||
printf "rebind_protection=$(uci -q get dhcp.@dnsmasq[0].rebind_protection)\n"
|
||||
printf "rebind_localhost=$(uci -q get dhcp.@dnsmasq[0].rebind_localhost)\n"
|
||||
printf "noresolv=$(uci -q get dhcp.@dnsmasq[0].noresolv)\n"
|
||||
printf "resolvfile=$(uci -q get dhcp.@dnsmasq[0].resolvfile)\n"
|
||||
printf "cachesize=$(uci -q get dhcp.@dnsmasq[0].cachesize)\n"
|
||||
} > $REDIRECT_LOCK_FILE
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
uci_set_or_del() {
|
||||
local key="$1"
|
||||
local val="$2"
|
||||
|
||||
if [ -n "$val" ]; then
|
||||
uci set "$key=$val"
|
||||
else
|
||||
uci del "$key"
|
||||
fi
|
||||
}
|
||||
|
||||
restore_dhcp_setting() {
|
||||
if [ -f "$REDIRECT_LOCK_FILE" ]; then
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
source "$REDIRECT_LOCK_FILE"
|
||||
|
||||
uci_set_or_del dhcp.@dnsmasq[0].rebind_protection "$rebind_protection"
|
||||
uci_set_or_del dhcp.@dnsmasq[0].resolvfile "$resolvfile"
|
||||
uci_set_or_del dhcp.@dnsmasq[0].rebind_localhost "$rebind_localhost"
|
||||
uci_set_or_del dhcp.@dnsmasq[0].noresolv "$noresolv"
|
||||
uci_set_or_del dhcp.@dnsmasq[0].cachesize "$cachesize"
|
||||
|
||||
uci commit dhcp
|
||||
rm -f "$REDIRECT_LOCK_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
reload_dnsmasq() {
|
||||
[ "$(/etc/init.d/dnsmasq status)" = "running" ] && /etc/init.d/dnsmasq reload
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
||||
|
||||
setcron() {
|
||||
sed -i '/mosdns.uc/d' $CRON_FILE 2>/dev/null
|
||||
[ "$geo_auto_update" -eq 1 ] && echo "0 $geo_update_day_time * * $geo_update_week_time /usr/share/mosdns/mosdns.uc update" >> $CRON_FILE
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
delcron() {
|
||||
sed -i '/mosdns.uc/d' $CRON_FILE 2>/dev/null
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load "mosdns"
|
||||
config_foreach get_config "mosdns"
|
||||
[ $enabled -ne 1 ] && return 1
|
||||
delcron ; setcron
|
||||
|
||||
rm -rf /tmp/log/mosdns*
|
||||
|
||||
$MOSDNS_SCRIPT v2dat_dump
|
||||
|
||||
[ "${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 ] && restore_dhcp_setting
|
||||
[ "$redirect" -eq 1 ] && dhcp_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 update_adlist &
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
config_load "mosdns"
|
||||
config_foreach get_config "mosdns"
|
||||
[ "$enabled" -eq "0" ] && restore_dhcp_setting
|
||||
! nft --check list table inet mosdns > "/dev/null" 2>&1 || \
|
||||
nft delete table inet mosdns
|
||||
reload_dnsmasq
|
||||
delcron
|
||||
}
|
||||
@@ -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"
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
+13
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
+354
@@ -0,0 +1,354 @@
|
||||
#!/usr/bin/env ucode
|
||||
|
||||
'use strict';
|
||||
|
||||
import { popen, mkdir, unlink, writefile, open, stat, stdout } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
import { connect } from 'ubus';
|
||||
|
||||
function to_array(val) {
|
||||
let res =[];
|
||||
if (type(val) == 'array') {
|
||||
for (let i = 0; i < length(val); i++) {
|
||||
if (type(val[i]) == 'string') {
|
||||
let s = replace(val[i], /^\s+|\s+$/g, '');
|
||||
if (s != "") push(res, s);
|
||||
}
|
||||
}
|
||||
} else if (type(val) == 'string') {
|
||||
let parts = split(val, /[ \t\n]+/);
|
||||
for (let i = 0; i < length(parts); i++) {
|
||||
if (parts[i] != "") push(res, parts[i]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function exec_sys(cmd) {
|
||||
let p = popen(cmd + " 2>&1", "r");
|
||||
if (!p) return { code: -1, stdout: "" };
|
||||
let stdout = p.read("all");
|
||||
let code = p.close();
|
||||
if (type(stdout) == 'string') {
|
||||
stdout = replace(stdout, /^\s+|\s+$/g, '');
|
||||
}
|
||||
return { code: code, stdout: stdout || "" };
|
||||
}
|
||||
|
||||
function interface_dns() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
let dns_list =[];
|
||||
|
||||
if (uci_cursor.get('mosdns', 'config', 'custom_local_dns') === '1') {
|
||||
dns_list = to_array(uci_cursor.get('mosdns', 'config', 'local_dns'));
|
||||
} else {
|
||||
uci_cursor.load('network');
|
||||
let peerdns = uci_cursor.get('network', 'wan', 'peerdns');
|
||||
let proto = uci_cursor.get('network', 'wan', 'proto');
|
||||
|
||||
if (peerdns === '0' || proto === 'static') {
|
||||
dns_list = to_array(uci_cursor.get('network', 'wan', 'dns'));
|
||||
} else {
|
||||
let ubus_conn = connect();
|
||||
if (ubus_conn) {
|
||||
let status = ubus_conn.call('network.interface.wan', 'status');
|
||||
if (status && type(status['dns-server']) == 'array' && length(status['dns-server']) > 0) {
|
||||
dns_list = status['dns-server'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (length(dns_list) === 0) {
|
||||
dns_list =['119.29.29.29', '223.5.5.5'];
|
||||
}
|
||||
print(join(" ", dns_list) + "\n");
|
||||
}
|
||||
|
||||
function get_adlist() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
let adblock = uci_cursor.get('mosdns', 'config', 'adblock');
|
||||
|
||||
if (adblock !== '1') {
|
||||
mkdir('/etc/mosdns/rule', 0755);
|
||||
exec_sys('rm -rf /etc/mosdns/rule/adlist /etc/mosdns/rule/.ad_source');
|
||||
writefile('/var/mosdns/disable-ads.txt', '');
|
||||
print("/var/mosdns/disable-ads.txt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mkdir('/etc/mosdns/rule/adlist', 0755);
|
||||
let ad_source = to_array(uci_cursor.get('mosdns', 'config', 'ad_source'));
|
||||
let adlist =[];
|
||||
|
||||
for (let i = 0; i < length(ad_source); i++) {
|
||||
let url = ad_source[i];
|
||||
if (!url) continue;
|
||||
|
||||
if (url === 'geosite.dat') {
|
||||
push(adlist, '/var/mosdns/geosite_category-ads-all.txt');
|
||||
} else if (index(url, 'file://') === 0) {
|
||||
push(adlist, substr(url, 7));
|
||||
} else {
|
||||
let parts = split(url, '/');
|
||||
let filename = parts[length(parts) - 1];
|
||||
let local_path = `/etc/mosdns/rule/adlist/${filename}`;
|
||||
if (!stat(local_path)) {
|
||||
writefile(local_path, '');
|
||||
}
|
||||
push(adlist, local_path);
|
||||
}
|
||||
}
|
||||
print(join("\n", adlist) + "\n");
|
||||
}
|
||||
|
||||
function update_adlist() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
|
||||
if (uci_cursor.get('mosdns', 'config', 'adblock') !== '1') {
|
||||
return false;
|
||||
}
|
||||
|
||||
let lock_file = '/var/lock/mosdns_ad_update.lock';
|
||||
let ad_source = to_array(uci_cursor.get('mosdns', 'config', 'ad_source'));
|
||||
let github_proxy = uci_cursor.get('mosdns', 'config', 'github_proxy') || '';
|
||||
|
||||
mkdir('/etc/mosdns/rule', 0755);
|
||||
writefile('/etc/mosdns/rule/.ad_source', '');
|
||||
|
||||
if (stat(lock_file)) return false;
|
||||
writefile(lock_file, '');
|
||||
|
||||
let tmp_res = exec_sys('mktemp -d');
|
||||
if (tmp_res.code !== 0) {
|
||||
unlink(lock_file);
|
||||
die("Failed to create temp directory for adlist.");
|
||||
}
|
||||
let ad_tmpdir = tmp_res.stdout;
|
||||
let has_update = false;
|
||||
let download_failed = false;
|
||||
|
||||
for (let i = 0; i < length(ad_source); i++) {
|
||||
let url = ad_source[i];
|
||||
if (!url) continue;
|
||||
|
||||
if (url !== 'geosite.dat' && index(url, 'file://') !== 0) {
|
||||
has_update = true;
|
||||
exec_sys(`echo "${url}" >> /etc/mosdns/rule/.ad_source`);
|
||||
|
||||
let parts = split(url, '/');
|
||||
let filename = parts[length(parts) - 1];
|
||||
let mirror = "";
|
||||
|
||||
if (match(url, /^https:\/\/raw\.githubusercontent\.com/)) {
|
||||
mirror = github_proxy ? github_proxy + '/' : '';
|
||||
}
|
||||
|
||||
print(`Downloading ${mirror}${url}\n`);
|
||||
stdout.flush();
|
||||
let curl_res = exec_sys(`curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "${ad_tmpdir}/${filename}" "${mirror}${url}"`);
|
||||
if (curl_res.code !== 0) download_failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (download_failed) {
|
||||
exec_sys(`rm -rf "${ad_tmpdir}"`);
|
||||
unlink(lock_file);
|
||||
die("Rules download failed.");
|
||||
} else {
|
||||
if (has_update) {
|
||||
mkdir('/etc/mosdns/rule/adlist', 0755);
|
||||
exec_sys('rm -rf /etc/mosdns/rule/adlist/*');
|
||||
exec_sys(`cp "${ad_tmpdir}"/* /etc/mosdns/rule/adlist/`);
|
||||
}
|
||||
}
|
||||
|
||||
exec_sys(`rm -rf "${ad_tmpdir}"`);
|
||||
unlink(lock_file);
|
||||
|
||||
return has_update;
|
||||
}
|
||||
|
||||
function update_geodat() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
|
||||
let github_proxy = uci_cursor.get('mosdns', 'config', 'github_proxy') || '';
|
||||
let mirror = github_proxy ? github_proxy + '/' : '';
|
||||
let geoip_type = uci_cursor.get('mosdns', 'config', 'geoip_type') || 'geoip-only-cn-private';
|
||||
let v2dat_dir = '/usr/share/v2ray';
|
||||
|
||||
let tmp_res = exec_sys('mktemp -d');
|
||||
if (tmp_res.code !== 0) die("Failed to create temp directory for geodata.");
|
||||
let tmpdir = tmp_res.stdout;
|
||||
|
||||
exec_sys(`mkdir -p "${v2dat_dir}"`);
|
||||
|
||||
let geoip_updated = false;
|
||||
let geoip_url = mirror + "https://github.com/Loyalsoldier/geoip/releases/latest/download/" + geoip_type + ".dat";
|
||||
|
||||
print(`Downloading ${geoip_url}.sha256sum\n`);
|
||||
stdout.flush();
|
||||
if (exec_sys(`curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "${tmpdir}/geoip.dat.sha256sum" "${geoip_url}.sha256sum"`).code !== 0) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("Failed to download geoip.dat.sha256sum");
|
||||
}
|
||||
|
||||
let geoip_sum_remote = split(exec_sys(`cat "${tmpdir}/geoip.dat.sha256sum"`).stdout, /[ \t\n]+/)[0];
|
||||
let geoip_sum_local = "";
|
||||
if (stat(`${v2dat_dir}/geoip.dat`)) {
|
||||
geoip_sum_local = split(exec_sys(`sha256sum "${v2dat_dir}/geoip.dat"`).stdout, /[ \t\n]+/)[0];
|
||||
}
|
||||
|
||||
if (geoip_sum_local === geoip_sum_remote) {
|
||||
print("geoip.dat is up to date.\n");
|
||||
stdout.flush();
|
||||
} else {
|
||||
print(`Downloading ${geoip_url}\n`);
|
||||
stdout.flush();
|
||||
if (exec_sys(`curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "${tmpdir}/geoip.dat" "${geoip_url}"`).code !== 0) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("Failed to download geoip.dat");
|
||||
}
|
||||
|
||||
let sum_downloaded = split(exec_sys(`sha256sum "${tmpdir}/geoip.dat"`).stdout, /[ \t\n]+/)[0];
|
||||
if (sum_downloaded !== geoip_sum_remote) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("geoip.dat checksum error");
|
||||
}
|
||||
geoip_updated = true;
|
||||
}
|
||||
|
||||
let geosite_updated = false;
|
||||
let geosite_url = mirror + "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat";
|
||||
|
||||
print(`Downloading ${geosite_url}.sha256sum\n`);
|
||||
stdout.flush();
|
||||
if (exec_sys(`curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "${tmpdir}/geosite.dat.sha256sum" "${geosite_url}.sha256sum"`).code !== 0) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("Failed to download geosite.dat.sha256sum");
|
||||
}
|
||||
|
||||
let geosite_sum_remote = split(exec_sys(`cat "${tmpdir}/geosite.dat.sha256sum"`).stdout, /[ \t\n]+/)[0];
|
||||
let geosite_sum_local = "";
|
||||
if (stat(`${v2dat_dir}/geosite.dat`)) {
|
||||
geosite_sum_local = split(exec_sys(`sha256sum "${v2dat_dir}/geosite.dat"`).stdout, /[ \t\n]+/)[0];
|
||||
}
|
||||
|
||||
if (geosite_sum_local === geosite_sum_remote) {
|
||||
print("geosite.dat is up to date.\n");
|
||||
stdout.flush();
|
||||
} else {
|
||||
print(`Downloading ${geosite_url}\n`);
|
||||
stdout.flush();
|
||||
if (exec_sys(`curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "${tmpdir}/geosite.dat" "${geosite_url}"`).code !== 0) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("Failed to download geosite.dat");
|
||||
}
|
||||
|
||||
let sum_downloaded = split(exec_sys(`sha256sum "${tmpdir}/geosite.dat"`).stdout, /[ \t\n]+/)[0];
|
||||
if (sum_downloaded !== geosite_sum_remote) {
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
die("geosite.dat checksum error");
|
||||
}
|
||||
geosite_updated = true;
|
||||
}
|
||||
|
||||
if (geoip_updated) {
|
||||
exec_sys(`cp -a "${tmpdir}/geoip.dat" "${v2dat_dir}/"`);
|
||||
}
|
||||
|
||||
if (geosite_updated) {
|
||||
exec_sys(`cp -a "${tmpdir}/geosite.dat" "${v2dat_dir}/"`);
|
||||
}
|
||||
|
||||
exec_sys(`rm -rf "${tmpdir}"`);
|
||||
}
|
||||
|
||||
function v2dat_dump() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
let v2dat_dir = '/usr/share/v2ray';
|
||||
let configfile = uci_cursor.get('mosdns', 'config', 'configfile') || '/var/etc/mosdns.json';
|
||||
let adblock = uci_cursor.get('mosdns', 'config', 'adblock');
|
||||
let ad_source = uci_cursor.get('mosdns', 'config', 'ad_source') || "";
|
||||
let streaming_media = uci_cursor.get('mosdns', 'config', 'custom_stream_media_dns');
|
||||
|
||||
mkdir('/var/mosdns', 0755);
|
||||
exec_sys('rm -f /var/mosdns/geo*.txt');
|
||||
|
||||
if (configfile === "/var/etc/mosdns.json") {
|
||||
exec_sys(`v2dat unpack geoip -o /var/mosdns -f cn ${v2dat_dir}/geoip.dat`);
|
||||
exec_sys(`v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' ${v2dat_dir}/geosite.dat`);
|
||||
|
||||
if (adblock === '1' && index(ad_source, 'geosite.dat') !== -1) {
|
||||
exec_sys(`v2dat unpack geosite -o /var/mosdns -f category-ads-all ${v2dat_dir}/geosite.dat`);
|
||||
}
|
||||
|
||||
if (streaming_media === '1') {
|
||||
exec_sys(`v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu ${v2dat_dir}/geosite.dat`);
|
||||
} else {
|
||||
writefile('/var/mosdns/geosite_disney.txt', '');
|
||||
writefile('/var/mosdns/geosite_netflix.txt', '');
|
||||
writefile('/var/mosdns/geosite_hulu.txt', '');
|
||||
}
|
||||
} else {
|
||||
exec_sys(`v2dat unpack geoip -o /var/mosdns -f cn ${v2dat_dir}/geoip.dat`);
|
||||
exec_sys(`v2dat unpack geosite -o /var/mosdns -f cn -f 'geolocation-!cn' ${v2dat_dir}/geosite.dat`);
|
||||
|
||||
let geoip_tags = to_array(uci_cursor.get('mosdns', 'config', 'geoip_tags'));
|
||||
if (length(geoip_tags) > 0) {
|
||||
let tags_str = "-f '" + join("' -f '", geoip_tags) + "'";
|
||||
exec_sys(`v2dat unpack geoip -o /var/mosdns ${tags_str} ${v2dat_dir}/geoip.dat`);
|
||||
}
|
||||
|
||||
let geosite_tags = to_array(uci_cursor.get('mosdns', 'config', 'geosite_tags'));
|
||||
if (length(geosite_tags) > 0) {
|
||||
let tags_str = "-f '" + join("' -f '", geosite_tags) + "'";
|
||||
exec_sys(`v2dat unpack geosite -o /var/mosdns ${tags_str} ${v2dat_dir}/geosite.dat`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let action = ARGV[0];
|
||||
|
||||
switch (action) {
|
||||
case "interface_dns":
|
||||
interface_dns();
|
||||
break;
|
||||
case "get_adlist":
|
||||
get_adlist();
|
||||
break;
|
||||
case "update":
|
||||
if (stat('/var/lock/mosdns_update.lock')) {
|
||||
print("Another update is already in progress.\n");
|
||||
exit(1);
|
||||
}
|
||||
writefile('/var/lock/mosdns_update.lock', '');
|
||||
try {
|
||||
update_geodat();
|
||||
update_adlist();
|
||||
v2dat_dump();
|
||||
print("UPDATE_FINISHED\n");
|
||||
stdout.flush();
|
||||
} catch (e) {
|
||||
print("Update failed: " + e + "\n");
|
||||
print("UPDATE_EXITED\n");
|
||||
stdout.flush();
|
||||
unlink('/var/lock/mosdns_update.lock');
|
||||
exit(1);
|
||||
}
|
||||
unlink('/var/lock/mosdns_update.lock');
|
||||
break;
|
||||
case "update_adlist":
|
||||
update_adlist();
|
||||
break;
|
||||
case "v2dat_dump":
|
||||
v2dat_dump();
|
||||
break;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"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/*": [ "read" ],
|
||||
"/usr/bin/mosdns": [ "exec" ],
|
||||
"/usr/share/mosdns/mosdns.uc": [ "exec" ],
|
||||
"/var/log/*": [ "read" ],
|
||||
"/var/mosdns/*": [ "read" ]
|
||||
},
|
||||
"ubus": {
|
||||
"file": [ "read" ],
|
||||
"service": [ "list" ],
|
||||
"luci.mosdns": [
|
||||
"clean_log",
|
||||
"flush_cache",
|
||||
"get_version",
|
||||
"print_log",
|
||||
"get_update_log",
|
||||
"start_update"
|
||||
]
|
||||
},
|
||||
"uci": [ "mosdns" ]
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/etc/mosdns/config_custom.yaml": [ "write" ],
|
||||
"/etc/mosdns/rule/*": [ "write" ],
|
||||
"/usr/share/mosdns/*": [ "write" ],
|
||||
"/usr/share/v2ray/*": [ "write" ],
|
||||
"/var/log/*": [ "write" ],
|
||||
"/var/mosdns/*": [ "write" ]
|
||||
},
|
||||
"ubus": {
|
||||
"file": [ "write" ]
|
||||
},
|
||||
"uci": [ "mosdns" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env ucode
|
||||
|
||||
'use strict';
|
||||
|
||||
import { popen, writefile, stat, readfile } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
|
||||
function to_array(val) {
|
||||
let res =[];
|
||||
if (type(val) == 'array') {
|
||||
for (let i = 0; i < length(val); i++) {
|
||||
if (type(val[i]) == 'string') {
|
||||
let s = replace(val[i], /^\s+|\s+$/g, '');
|
||||
if (s != "") push(res, s);
|
||||
}
|
||||
}
|
||||
} else if (type(val) == 'string') {
|
||||
let parts = split(val, /[ \t\n]+/);
|
||||
for (let i = 0; i < length(parts); i++) {
|
||||
if (parts[i] != "") push(res, parts[i]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function exec_sys(cmd) {
|
||||
let p = popen(cmd + " 2>&1", "r");
|
||||
if (!p) return { code: -1, stdout: "" };
|
||||
let stdout = p.read("all");
|
||||
let code = p.close();
|
||||
if (type(stdout) == 'string') {
|
||||
stdout = replace(stdout, /^\s+|\s+$/g, '');
|
||||
}
|
||||
return { code: code, stdout: stdout || "" };
|
||||
}
|
||||
|
||||
function get_logfile_path_internal() {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
let configfile = uci_cursor.get('mosdns', 'config', 'configfile');
|
||||
|
||||
if (configfile === '/var/etc/mosdns.json' || !configfile) {
|
||||
return uci_cursor.get('mosdns', 'config', 'log_file');
|
||||
} else {
|
||||
let content = readfile(configfile);
|
||||
if (content) {
|
||||
let m = match(content, /file:\s*([^\r\n]+)/);
|
||||
if (m && m[1]) {
|
||||
let log_path = m[1];
|
||||
log_path = replace(log_path, /^\s+|\s+$/g, '');
|
||||
log_path = replace(log_path, /^["']|["']$/g, '');
|
||||
if (log_path != "") {
|
||||
return log_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '/var/log/mosdns.log';
|
||||
}
|
||||
}
|
||||
|
||||
const methods = {
|
||||
flush_cache: {
|
||||
call: function() {
|
||||
try {
|
||||
let uci_cursor = cursor();
|
||||
uci_cursor.load('mosdns');
|
||||
let port = uci_cursor.get('mosdns', 'config', 'listen_port_api');
|
||||
if (!port) return { error: "API listen port not configured." };
|
||||
|
||||
let res = exec_sys(`curl -s 127.0.0.1:${port}/plugins/lazy_cache/flush`);
|
||||
if (res.code === 0) {
|
||||
return { success: true };
|
||||
} else {
|
||||
return { success: false, error: res.stdout };
|
||||
}
|
||||
} catch (e) {
|
||||
return { error: String(e) };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
print_log: {
|
||||
call: function() {
|
||||
try {
|
||||
let path = get_logfile_path_internal();
|
||||
if (path && stat(path)) {
|
||||
return { log: readfile(path) };
|
||||
} else {
|
||||
return { error: 'Log file not accessible or does not exist.' };
|
||||
}
|
||||
} catch (e) {
|
||||
return { error: String(e) };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
clean_log: {
|
||||
call: function() {
|
||||
try {
|
||||
let path = get_logfile_path_internal();
|
||||
if (path) {
|
||||
writefile(path, '');
|
||||
return { success: true };
|
||||
} else {
|
||||
return { error: 'Log file path could not be determined.' };
|
||||
}
|
||||
} catch (e) {
|
||||
return { error: String(e) };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get_version: {
|
||||
call: function() {
|
||||
let res = exec_sys('mosdns version');
|
||||
if (res.code === 0) {
|
||||
return { version: res.stdout };
|
||||
} else {
|
||||
return { error: res.stdout };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
start_update: {
|
||||
call: function() {
|
||||
try {
|
||||
if (stat('/var/lock/mosdns_update.lock')) {
|
||||
return { success: false, error: 'Another update is already in progress.' };
|
||||
}
|
||||
exec_sys('echo "" > /var/log/mosdns_update.log');
|
||||
exec_sys('/usr/share/mosdns/mosdns.uc update > /var/log/mosdns_update.log 2>&1 &');
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
return { success: false, error: String(e) };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get_update_log: {
|
||||
call: function() {
|
||||
try {
|
||||
if (stat('/var/log/mosdns_update.log')) {
|
||||
return { log: readfile('/var/log/mosdns_update.log') };
|
||||
} else {
|
||||
return { log: '' };
|
||||
}
|
||||
} catch (e) {
|
||||
return { error: String(e) };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { "luci.mosdns": methods };
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"config": "mosdns",
|
||||
"init": "mosdns"
|
||||
}
|
||||
Reference in New Issue
Block a user