Initial YakPanel commit
This commit is contained in:
12
class_v2/ssl_dnsV2/__init__.py
Normal file
12
class_v2/ssl_dnsV2/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: yakpanel
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# xxx app
|
||||
# ------------------------------
|
||||
450
class_v2/ssl_dnsV2/api.py
Normal file
450
class_v2/ssl_dnsV2/api.py
Normal file
@@ -0,0 +1,450 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: yakpanel
|
||||
# -------------------------------------------------------------------
|
||||
# ------------------------------
|
||||
# aaDNS api
|
||||
# ------------------------------
|
||||
import json
|
||||
import sys
|
||||
import threading
|
||||
|
||||
if not "class/" in sys.path:
|
||||
sys.path.insert(0, "class/")
|
||||
if not "class_v2/" in sys.path:
|
||||
sys.path.insert(0, "class_v2/")
|
||||
|
||||
from public.exceptions import HintException
|
||||
from public.validate import Param
|
||||
from ssl_domainModelV2.model import DnsDomainProvider
|
||||
from ssl_domainModelV2.service import DomainValid
|
||||
from .dns_manager import DnsManager, MailManager
|
||||
from .helper import *
|
||||
|
||||
|
||||
class DnsApiObject:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def install_bind(self, get):
|
||||
log = f"{public.get_panel_path()}/logs/install_bind.log"
|
||||
if os.path.exists(log):
|
||||
public.ExecShell(f"rm -f {log}")
|
||||
install_script = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "bind_script.sh"
|
||||
)
|
||||
public.ExecShell("chmod +x {}".format(install_script))
|
||||
public.ExecShell("nohup bash {} install >>{} 2>&1 &".format(install_script, log))
|
||||
return public.success_v2(public.lang("Installing..."))
|
||||
|
||||
def install_pdns(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("act").String("in", ["install", "uninstall"]).Require(),
|
||||
Param("clean").Integer(),
|
||||
], [public.validate.trim_filter(), ])
|
||||
if not hasattr(get, "clean"):
|
||||
get.clean = 1
|
||||
else:
|
||||
get.clean = int(get.clean)
|
||||
|
||||
if get.act == "install" and os.path.exists("/www/server/panel/plugin/syssafe/config.json"):
|
||||
cf = public.readFile("/www/server/panel/plugin/syssafe/config.json")
|
||||
if cf:
|
||||
jcf = None
|
||||
try:
|
||||
import json
|
||||
jcf = json.loads(cf)
|
||||
except:
|
||||
pass
|
||||
if jcf and jcf.get("open") is True:
|
||||
raise HintException(public.lang(
|
||||
"[System hardening] is enabled, please disable it first before installing aaDNS."
|
||||
))
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
log = f"{public.get_panel_path()}/logs/install_pdns.log"
|
||||
public.writeFile(log, f"Starting {get.act}...\n")
|
||||
install_script = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "pdns_script.sh"
|
||||
)
|
||||
|
||||
public.ExecShell("chmod +x {}".format(install_script))
|
||||
public.ExecShell(f"nohup bash {install_script} {get.act} {get.clean} >>{log} 2>&1 &")
|
||||
if get.act == "install":
|
||||
public.set_module_logs(
|
||||
"sys_domain", "Install_YakPanelDns", 1
|
||||
)
|
||||
return public.success_v2(public.lang("Success!"))
|
||||
|
||||
def get_status(self, get):
|
||||
config_obj = aaDnsConfig()
|
||||
service_name = config_obj.service_path.get("service_name")
|
||||
if not service_name:
|
||||
public.success_v2({
|
||||
"service": None,
|
||||
"status": False
|
||||
})
|
||||
a, e = public.ExecShell(f"ps -ef | grep '{service_name}' | grep -v grep")
|
||||
if e:
|
||||
raise HintException(f"Failed to get aaDNS service status: {e} please try again.")
|
||||
return public.success_v2({
|
||||
"service": config_obj.install_service,
|
||||
"status": True if a else False
|
||||
})
|
||||
|
||||
def change_status(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("service_name").String("in", ["bind", "pdns"]),
|
||||
Param("status").String("in", [
|
||||
"start", "stop", "restart", "reload"
|
||||
]).Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
if not hasattr(get, "service_name"):
|
||||
service_name = "pdns"
|
||||
else:
|
||||
service_name = get.service_name
|
||||
|
||||
DnsManager().change_service_status(service_name, get.status)
|
||||
return public.success_v2(public.lang(f"Successfully {get.status} aaDNS service."))
|
||||
|
||||
@staticmethod
|
||||
def check_base_params(func):
|
||||
def wrapper(self, get):
|
||||
check_domain = ["domain", "ns1domain", "ns2domain", "soa"]
|
||||
soa_params = ["nameserver", "admin_mail"]
|
||||
for key in check_domain + soa_params:
|
||||
if hasattr(get, key) and not DomainValid.is_valid_domain(getattr(get, key)):
|
||||
raise HintException("invalid {}: {}".format(key, getattr(get, key)))
|
||||
# ip
|
||||
check_ip = ["ip", "domain_ip"]
|
||||
for key2 in check_ip:
|
||||
if hasattr(get, key2):
|
||||
if not DomainValid.is_ip4(getattr(get, key2)) and not DomainValid.is_ip6(getattr(get, key2)):
|
||||
raise HintException("invalid ip address: {}".format(getattr(get, key2)))
|
||||
# ttl, priority
|
||||
check_int_type = ["ttl", "priority"]
|
||||
soa_int_params = ["serial", "refresh", "retry", "expire", "minimum"]
|
||||
for key3 in check_int_type + soa_int_params:
|
||||
if hasattr(get, key3):
|
||||
try:
|
||||
int(getattr(get, key3))
|
||||
except:
|
||||
raise HintException("{} must be an digit.".format(key3))
|
||||
return func(self, get)
|
||||
|
||||
return wrapper
|
||||
|
||||
@staticmethod
|
||||
def init_provider(func):
|
||||
def wrapper(self, get):
|
||||
provider = DnsDomainProvider.objects.filter(name="YakPanelDns").first()
|
||||
if not provider:
|
||||
raise HintException(public.lang(
|
||||
"YakPanelDns provider not found. Please install aaDNS first."
|
||||
))
|
||||
return func(self, get, provider)
|
||||
|
||||
return wrapper
|
||||
|
||||
@check_base_params
|
||||
def add_zone(self, get):
|
||||
"""添加zone信息"""
|
||||
try:
|
||||
get.validate([
|
||||
Param("domain").String().Require(),
|
||||
Param("ns1domain").String(),
|
||||
Param("ns2domain").String(),
|
||||
Param("soa").String(),
|
||||
Param("domain_ip").String(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
manager = DnsManager()
|
||||
domain = get.domain.rstrip(".") # 去点
|
||||
soa = "ns1.{}.".format(domain)
|
||||
ip = "127.0.0.1"
|
||||
ns1 = "ns1.{}.".format(domain)
|
||||
ns2 = "ns2.{}.".format(domain)
|
||||
|
||||
if hasattr(get, "ns1") and get.ns1:
|
||||
ns1 = get.ns1
|
||||
if hasattr(get, "ns2") and get.ns2:
|
||||
ns2 = get.ns2
|
||||
if hasattr(get, "soa") and get.soa:
|
||||
soa = get.soa
|
||||
if hasattr(get, "domain_ip") and get.domain_ip:
|
||||
ip = get.domain_ip
|
||||
|
||||
# 确保FQDN格式
|
||||
for k in [ns1, ns2, soa]:
|
||||
if not k.endswith("."):
|
||||
k += "."
|
||||
res = manager.add_zone(domain, ns1, ns2, soa, ip)
|
||||
if isinstance(res, str):
|
||||
return public.success_v2(res)
|
||||
return public.success_v2(public.lang("Successfully added zone."))
|
||||
|
||||
@check_base_params
|
||||
def del_zone(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("domain").String().Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
res = DnsManager().delete_zone(get.domain)
|
||||
if isinstance(res, str):
|
||||
return public.success_v2(res)
|
||||
return public.success_v2(public.lang("Successfully deleted zone."))
|
||||
|
||||
@check_base_params
|
||||
def get_zones(self, get):
|
||||
"""获取所有已添加的域名列表"""
|
||||
try:
|
||||
get.validate([
|
||||
Param("domain").String(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
domains = DnsParser().get_zones(get.domain)
|
||||
return public.success_v2(domains)
|
||||
|
||||
@check_base_params
|
||||
def get_nameserver(self, get):
|
||||
return public.success_v2(DnsManager().get_default_nameserver())
|
||||
|
||||
@check_base_params
|
||||
def set_nameserver(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("ns1domain").String().Require(),
|
||||
Param("ns2domain").String().Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
manager = DnsManager()
|
||||
manager.set_default_nameserver(get.ns1domain, get.ns2domain)
|
||||
return public.success_v2(public.lang("Successfully set nameserver."))
|
||||
|
||||
@check_base_params
|
||||
def get_soa(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("domain").String().Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
soa = DnsManager().get_soa(get.domain)
|
||||
return public.success_v2(soa)
|
||||
|
||||
@check_base_params
|
||||
def set_soa(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("domain").String().Require(),
|
||||
Param("nameserver").String().Require(),
|
||||
Param("admin_mail").String().Require(),
|
||||
Param("serial").Integer().Require(),
|
||||
Param("refresh").Integer("between", [1200, 43200]).Require(),
|
||||
Param("retry").Integer("between", [120, 7200]).Require(),
|
||||
Param("expire").Integer("between", [1209600, 2419200]).Require(),
|
||||
Param("minimum").Integer("between", [180, 86400]).Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
for k, v in get.__dict__.items():
|
||||
if k in ["domain", "nameserver", "admin_mail"]:
|
||||
if v.endswith("."):
|
||||
setattr(get, k, v.rstrip("."))
|
||||
DnsManager().set_soa(**get.__dict__)
|
||||
return public.success_v2(public.lang("Successfully set SOA record."))
|
||||
|
||||
def get_logger(self, get):
|
||||
try:
|
||||
get.validate([
|
||||
Param("p").Integer(),
|
||||
Param("limit").Integer(),
|
||||
Param("search").String(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
if not hasattr(get, "p"):
|
||||
get.p = 1
|
||||
if not hasattr(get, "limit"):
|
||||
get.limit = 20
|
||||
if hasattr(get, "search") and get.search:
|
||||
search = str(get.search)
|
||||
else:
|
||||
search = None
|
||||
return public.success_v2(
|
||||
DnsManager().get_logger(int(get.p), int(get.limit), search)
|
||||
)
|
||||
|
||||
def clear_logger(self, get):
|
||||
if DnsManager().clear_logger():
|
||||
return public.success_v2(public.lang("Successfully cleared logs."))
|
||||
return public.fail_v2(public.lang("Failed to clear logs."))
|
||||
|
||||
@init_provider
|
||||
def add_dmarc(self, get, provider: DnsDomainProvider):
|
||||
try:
|
||||
get.validate([
|
||||
Param("policy").String("in", ["none", "quarantine", "reject"]).Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
mail_manager = MailManager()
|
||||
fails = []
|
||||
for d in provider.domains:
|
||||
try:
|
||||
setattr(mail_manager, "domain", d)
|
||||
mail_manager.add_dmarc(policy=get.policy, provider=provider)
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
fails.append(f"domain: {d} error: {ex}")
|
||||
continue
|
||||
if fails:
|
||||
return public.fail_v2(", ".join(fails))
|
||||
return public.success_v2(public.lang("Successfully added DMARC record."))
|
||||
|
||||
@init_provider
|
||||
def add_dkim_spf(self, get, provider: DnsDomainProvider):
|
||||
fails = []
|
||||
for d in provider.domains:
|
||||
try:
|
||||
MailManager(d).add_spf(provider)
|
||||
MailManager(d).add_dkim(provider)
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
fails.append(f"domain: {d} error: {ex}")
|
||||
continue
|
||||
if fails:
|
||||
return public.fail_v2(", ".join(fails))
|
||||
return public.success_v2(public.lang("Successfully added DKIM/SPF records."))
|
||||
|
||||
@init_provider
|
||||
def dns_checker(self, get, provider: DnsDomainProvider):
|
||||
try:
|
||||
get.validate([
|
||||
Param("act").String("in", ["start", "status"]).Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
status = 1 if os.path.exists(DNS_AUTH_LOCK) else 0
|
||||
if get.act == "status":
|
||||
if status:
|
||||
msg = public.lang("DNS Checker is Running. Please Wait.")
|
||||
else:
|
||||
msg = public.lang("DNS Checker is Suspend.")
|
||||
|
||||
elif get.act == "start":
|
||||
if status:
|
||||
msg = public.lang("DNS Checker is Already Running. Please Wait.")
|
||||
else:
|
||||
task = threading.Thread(
|
||||
target=DnsManager().builtin_dns_checker, args=(provider,)
|
||||
)
|
||||
task.start()
|
||||
status = 1
|
||||
msg = public.lang("DNS Checker Run Successfully.")
|
||||
else:
|
||||
raise HintException(public.lang("Invalid action."))
|
||||
|
||||
return public.success_v2({
|
||||
"checker_status": status,
|
||||
"msg": msg
|
||||
})
|
||||
|
||||
@check_base_params
|
||||
@init_provider
|
||||
def fix_zone(self, get, provider: DnsDomainProvider):
|
||||
manager = DnsManager()
|
||||
try:
|
||||
for i in provider.domains:
|
||||
manager.fix_zone(i)
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
return public.success_v2(public.lang("Successfully fixed all zones."))
|
||||
|
||||
@check_base_params
|
||||
@init_provider
|
||||
def set_ttl_batch(self, get, provider: DnsDomainProvider):
|
||||
try:
|
||||
get.validate([
|
||||
Param("ttl").String().Require(),
|
||||
Param("domains").String().Require(),
|
||||
Param("record_type").String().Require(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
get.domains = json.loads(get.domains)
|
||||
if not get.record_type:
|
||||
raise HintException(public.lang("Record type is required."))
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.fail_v2(str(ex))
|
||||
|
||||
fails = []
|
||||
manager = DnsManager()
|
||||
for d in get.domains:
|
||||
if d not in provider.domains:
|
||||
fails.append(f"domain: {d} error: not found in provider domains.")
|
||||
continue
|
||||
try:
|
||||
if not manager.domian_record_type_ttl_batch_set(
|
||||
domain=d, record_type=get.record_type, ttl=get.ttl
|
||||
):
|
||||
fails.append(f"domain: {d} error: failed to set ttl.")
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
fails.append(f"domain: {d} error: {ex}")
|
||||
continue
|
||||
if fails:
|
||||
return public.fail_v2(", ".join(fails))
|
||||
return public.success_v2(public.lang("Successfully set TTL for all domains."))
|
||||
170
class_v2/ssl_dnsV2/bind_script.sh
Normal file
170
class_v2/ssl_dnsV2/bind_script.sh
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
Install_Bind()
|
||||
{
|
||||
if command -v yum >/dev/null 2>&1; then
|
||||
# CentOS/RHEL
|
||||
echo "Detected yum, installing BIND..."
|
||||
yum install bind bind-chroot -y
|
||||
# chroot 环境配置
|
||||
mkdir -p /var/named/chroot/etc
|
||||
mkdir -p /var/named/chroot/var/named/data
|
||||
mkdir -p /var/named/chroot/var/named/dynamic
|
||||
|
||||
if [ ! -f /var/named/chroot/etc/named.rfc1912.zones ];then
|
||||
if [ -d '/usr/share/doc/bind/sample/var/named/' ];then
|
||||
cp -R /usr/share/doc/bind/sample/var/named/* /var/named/chroot/var/named/
|
||||
else
|
||||
cp -R /usr/share/doc/bind-*/sample/var/named/* /var/named/chroot/var/named/
|
||||
fi
|
||||
# 复制所有配置文件
|
||||
echo "Configuring BIND for the first time..."
|
||||
cp -p /etc/named.* /var/named/chroot/etc/
|
||||
touch /var/named/chroot/var/named/data/cache_dump.db
|
||||
touch /var/named/chroot/var/named/data/named_stats.txt
|
||||
touch /var/named/chroot/var/named/data/named_mem_stats.txt
|
||||
touch /var/named/chroot/var/named/data/named.run
|
||||
touch /var/named/chroot/var/named/dynamic/managed-keys.bind
|
||||
# 修改默认值
|
||||
NAMED_CONF_PATH="/var/named/chroot/etc/named.conf"
|
||||
sed -i 's/listen-on port 53 .*/listen-on port 53 { any; };/' "$NAMED_CONF_PATH"
|
||||
sed -i 's/allow-query .*/allow-query { any; };/' "$NAMED_CONF_PATH"
|
||||
sed -i 's/recursion yes;/recursion no;/' "$NAMED_CONF_PATH"
|
||||
fi
|
||||
|
||||
# 设置权限
|
||||
chown -R named:named /var/named/chroot
|
||||
|
||||
SERVICE_NAME="named"
|
||||
if systemctl list-unit-files | grep -q "named-chroot.service"; then
|
||||
SERVICE_NAME="named-chroot"
|
||||
fi
|
||||
|
||||
systemctl disable pdns >/dev/null 2>&1
|
||||
systemctl stop pdns >/dev/null 2>&1
|
||||
systemctl restart "$SERVICE_NAME"
|
||||
systemctl enable "$SERVICE_NAME"
|
||||
echo "bind" > /www/server/panel/class_v2/ssl_dnsV2/aadns.pl
|
||||
echo "BIND installed and configured for CentOS/RHEL."
|
||||
echo "Installed Success!"
|
||||
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
# Debian/Ubuntu
|
||||
echo "Detected apt, installing BIND9..."
|
||||
apt-get update
|
||||
apt-get install bind9 bind9utils -y
|
||||
systemctl stop bind9
|
||||
|
||||
# 创建用户组
|
||||
if ! getent group named >/dev/null; then groupadd named; fi
|
||||
if ! id -u named >/dev/null 2>&1; then useradd -g named -s /sbin/nologin -d /var/named named; fi
|
||||
|
||||
# chroot 环境配置
|
||||
CHROOT_DIR="/var/named/chroot"
|
||||
mkdir -p "$CHROOT_DIR/etc"
|
||||
mkdir -p "$CHROOT_DIR/dev"
|
||||
mkdir -p "$CHROOT_DIR/var/named/data"
|
||||
mkdir -p "$CHROOT_DIR/var/named/dynamic"
|
||||
mkdir -p "$CHROOT_DIR/var/cache/bind"
|
||||
mkdir -p "$CHROOT_DIR/var/run/named"
|
||||
|
||||
# 移动配置文件并创建符号链接
|
||||
if [ -d /etc/bind ] && [ ! -L /etc/bind ]; then
|
||||
mv /etc/bind "$CHROOT_DIR/etc/"
|
||||
ln -s "$CHROOT_DIR/etc/bind" /etc/bind
|
||||
fi
|
||||
|
||||
# 以chroot模式启动
|
||||
if [ -f /etc/default/named ]; then
|
||||
# -u: user, -t: chroot directory
|
||||
sed -i "s/OPTIONS=.*/OPTIONS=\"-u named -t \/var\/named\/chroot\"/" /etc/default/named
|
||||
fi
|
||||
|
||||
# chroot所需的设备文件
|
||||
if [ ! -c "$CHROOT_DIR/dev/null" ]; then mknod "$CHROOT_DIR/dev/null" c 1 3; fi
|
||||
if [ ! -c "$CHROOT_DIR/dev/random" ]; then mknod "$CHROOT_DIR/dev/random" c 1 8; fi
|
||||
chmod 666 "$CHROOT_DIR/dev/null" "$CHROOT_DIR/dev/random"
|
||||
|
||||
echo "\$AddUnixListenSocket $CHROOT_DIR/dev/log" > /etc/rsyslog.d/bind-chroot.conf
|
||||
systemctl restart rsyslog
|
||||
|
||||
# 首次配置时修改配置
|
||||
NAMED_CONF_OPTIONS_PATH="$CHROOT_DIR/etc/bind/named.conf.options"
|
||||
if ! grep -q "listen-on { any; };" "$NAMED_CONF_OPTIONS_PATH"; then
|
||||
echo "Configuring BIND options for the first time..."
|
||||
# sed -i '/^\s*listen-on\s/c\listen-on { any; };' "$NAMED_CONF_OPTIONS_PATH"
|
||||
# sed -i '/^\s*listen-on-v6\s/c\listen-on-v6 { none; };' "$NAMED_CONF_OPTIONS_PATH"
|
||||
# sed -i '/^\s*allow-query\s/c\allow-query { any; };' "$NAMED_CONF_OPTIONS_PATH"
|
||||
# sed -i '/^\s*recursion\s/c\recursion no;' "$NAMED_CONF_OPTIONS_PATH"
|
||||
cat > "$NAMED_CONF_OPTIONS_PATH" <<EOF
|
||||
options {
|
||||
directory "/var/cache/bind";
|
||||
listen-on { any; };
|
||||
listen-on-v6 { none; };
|
||||
allow-query { any; };
|
||||
recursion no;
|
||||
pid-file "/var/run/named/named.pid";
|
||||
|
||||
dnssec-validation auto;
|
||||
auth-nxdomain no; # conform to RFC1035
|
||||
};
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 确保权限
|
||||
chown -R named:named "$CHROOT_DIR"
|
||||
|
||||
# 处理 AppArmor
|
||||
if [ -d /etc/apparmor.d/ ]; then
|
||||
if [ ! -L /etc/apparmor.d/disable/usr.sbin.named ]; then
|
||||
echo "Disabling AppArmor for named to ensure chroot works correctly."
|
||||
ln -sf /etc/apparmor.d/usr.sbin.named /etc/apparmor.d/disable/
|
||||
apparmor_parser -R /etc/apparmor.d/usr.sbin.named
|
||||
fi
|
||||
fi
|
||||
|
||||
systemctl disable pdns >/dev/null 2>&1
|
||||
systemctl stop pdns >/dev/null 2>&1
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl restart bind9
|
||||
systemctl enable bind9
|
||||
echo "bind" > /www/server/panel/class_v2/ssl_dnsV2/aadns.pl
|
||||
echo "BIND9 with chroot installed and configured for Debian/Ubuntu."
|
||||
echo "Installed Success!"
|
||||
else
|
||||
echo "Error: Neither yum nor apt-get found. Cannot install BIND."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
Install_aaDns()
|
||||
{
|
||||
Install_Bind
|
||||
}
|
||||
|
||||
Uninstall_aaDns()
|
||||
{
|
||||
if command -v yum >/dev/null 2>&1; then
|
||||
SERVICE_NAME="named"
|
||||
if systemctl list-unit-files | grep -q "named-chroot.service"; then
|
||||
SERVICE_NAME="named-chroot"
|
||||
fi
|
||||
systemctl stop "$SERVICE_NAME"
|
||||
systemctl disable "$SERVICE_NAME"
|
||||
echo "BIND uninstalled from CentOS/RHEL."
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
systemctl stop bind9
|
||||
systemctl disable bind9
|
||||
echo "BIND9 uninstalled from Debian/Ubuntu."
|
||||
else
|
||||
echo "Error: Neither yum nor apt-get found. Cannot uninstall BIND."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${1}" == "install" ];then
|
||||
Install_aaDns
|
||||
fi
|
||||
137
class_v2/ssl_dnsV2/conf.py
Normal file
137
class_v2/ssl_dnsV2/conf.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: yakpanel
|
||||
# -------------------------------------------------------------------
|
||||
# aaDNS config
|
||||
# ------------------------------
|
||||
import json
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
if not "class_v2" in sys.path:
|
||||
sys.path.append("class_v2")
|
||||
|
||||
__all__ = [
|
||||
"aaDnsConfig",
|
||||
"zone_pattern",
|
||||
"file_pattern",
|
||||
"record_pattern",
|
||||
"ZONES_DIR",
|
||||
"ZONES",
|
||||
"APP_DIR",
|
||||
"SERVICE_INSTALL_NAME",
|
||||
"PUBLIC_SERVER",
|
||||
"DNS_AUTH_LOCK",
|
||||
"aaDNS_CONF",
|
||||
]
|
||||
|
||||
zone_pattern = re.compile(r'zone\s+"[^"]+"\s*(?:IN)?\s*\{[\s\S]*?};', re.MULTILINE)
|
||||
file_pattern = re.compile(r'file\s+"([^"]+)"')
|
||||
record_pattern = re.compile(r'^(\S+)\s+(?:(\d+)\s+)?(?:(IN)\s+)?(\S+)\s+(.*)$')
|
||||
|
||||
ZONES_DIR = "/var/named/chroot/var/named/"
|
||||
ZONES = "/var/named/chroot/etc/named.rfc1912.zones"
|
||||
|
||||
APP_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
SERVICE_INSTALL_NAME = f"{APP_DIR}/aadns.pl"
|
||||
aaDNS_CONF = os.path.join(APP_DIR, "aaDns_conf.json")
|
||||
DNS_AUTH_LOCK = f"{APP_DIR}/dns_auth.pl"
|
||||
|
||||
PUBLIC_SERVER = [
|
||||
("Google", ["8.8.8.8"]),
|
||||
("Cloudflare", ["1.1.1.1"]),
|
||||
("Quad9", ["9.9.9.9"]),
|
||||
("OpenDNS", ["208.67.222.222"]),
|
||||
("DNS.Watch", ["84.200.69.80"]),
|
||||
("Comodo Secure DNS", ["8.26.56.26"]),
|
||||
("AdGuard DNS", ["94.140.14.14"]),
|
||||
("CleanBrowsing", ["185.228.168.9"]),
|
||||
("Neustar DNS", ["207.177.68.4"]),
|
||||
("Freenom World", ["83.145.86.7"]),
|
||||
]
|
||||
|
||||
|
||||
|
||||
class aaDnsConfig:
|
||||
if os.path.exists("/etc/redhat-release"):
|
||||
os_type = "redhat"
|
||||
package = "yum"
|
||||
else:
|
||||
os_type = "ubuntu"
|
||||
package = "apt"
|
||||
|
||||
def __init__(self):
|
||||
self.install_service = None
|
||||
self.ns_server = None
|
||||
self.bind_service_name = "named"
|
||||
self.pnds_service_name = "pdns"
|
||||
self._init_env()
|
||||
|
||||
def _init_env(self):
|
||||
# RHEL/CentOS,检查 bind-chroot 服务具体名称
|
||||
if os.path.exists("/usr/lib/systemd/system/named-chroot.service"):
|
||||
self.bind_service_name = "named-chroot"
|
||||
|
||||
if os.path.exists(SERVICE_INSTALL_NAME):
|
||||
with open(SERVICE_INSTALL_NAME, "r") as f:
|
||||
self.install_service = f.read().strip()
|
||||
if self.install_service not in ["bind", "pdns"]:
|
||||
try:
|
||||
os.remove(SERVICE_INSTALL_NAME)
|
||||
except:
|
||||
pass
|
||||
self.install_service = None
|
||||
|
||||
if os.path.exists(aaDNS_CONF):
|
||||
try:
|
||||
with open(aaDNS_CONF, "r") as f:
|
||||
content = f.read().strip()
|
||||
self.ns_server = json.loads(content) if content else None
|
||||
except:
|
||||
pass
|
||||
|
||||
@property
|
||||
def pdns_paths(self):
|
||||
if self.os_type == "ubuntu": # debian
|
||||
return {
|
||||
"config": "/etc/powerdns/pdns.conf",
|
||||
"zones": ZONES,
|
||||
"zone_dir": ZONES_DIR,
|
||||
"service_name": self.pnds_service_name,
|
||||
"package_name": "pdns-server",
|
||||
}
|
||||
else: # redhat, centos
|
||||
return {
|
||||
"config": "/etc/pdns/pdns.conf",
|
||||
"zones": ZONES,
|
||||
"zone_dir": ZONES_DIR,
|
||||
"service_name": self.pnds_service_name,
|
||||
"package_name": "bind-chroot" if self.os_type == "redhat" else "bind9",
|
||||
"main": "/var/named/chroot/etc/named.conf",
|
||||
}
|
||||
|
||||
@property
|
||||
def bind_paths(self):
|
||||
return {
|
||||
"config": "/var/named/chroot/etc/named.conf",
|
||||
"zones": "/var/named/chroot/etc/named.conf.local",
|
||||
"zone_dir": ZONES_DIR,
|
||||
"service_name": self.bind_service_name,
|
||||
"package_name": "bind-chroot" if self.os_type == "redhat" else "bind9",
|
||||
"main": "/var/named/chroot/etc/named.conf",
|
||||
}
|
||||
|
||||
@property
|
||||
def service_path(self):
|
||||
if self.install_service == "bind":
|
||||
return self.bind_paths
|
||||
elif self.install_service == "pdns":
|
||||
return self.pdns_paths
|
||||
else:
|
||||
return {}
|
||||
1303
class_v2/ssl_dnsV2/dns_manager.py
Normal file
1303
class_v2/ssl_dnsV2/dns_manager.py
Normal file
File diff suppressed because it is too large
Load Diff
260
class_v2/ssl_dnsV2/helper.py
Normal file
260
class_v2/ssl_dnsV2/helper.py
Normal file
@@ -0,0 +1,260 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: yakpanel
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
import public
|
||||
from .conf import *
|
||||
|
||||
|
||||
class DnsParser:
|
||||
def __init__(self):
|
||||
self.config = aaDnsConfig()
|
||||
|
||||
# ======================= bind ===============================
|
||||
def _parser_bind_config(self, conf: str) -> dict:
|
||||
"""解析bind主配置"""
|
||||
if not conf:
|
||||
return {}
|
||||
conf = re.sub(r'//.*', '', conf)
|
||||
conf = re.sub(r'#.*', '', conf)
|
||||
conf = re.sub(r'/\*[\s\S]*?\*/', '', conf)
|
||||
# 匹配 directory, listen-on, listen-on-v6, allow-query
|
||||
pattern = re.compile(
|
||||
r'\s*(directory|listen-on|listen-on-v6|allow-query)\s+(\{[\s\S]*?}|"[^"]*"|[^;]+?)\s*;',
|
||||
re.MULTILINE
|
||||
)
|
||||
|
||||
matches = pattern.findall(conf)
|
||||
main_config = dict()
|
||||
for key, value in matches:
|
||||
# 清理值,去除多余的空格和引号
|
||||
cleaned_value = value.strip()
|
||||
if cleaned_value.startswith('"') and cleaned_value.endswith('"'):
|
||||
cleaned_value = cleaned_value[1:-1]
|
||||
elif cleaned_value.startswith('{') and cleaned_value.endswith('}'):
|
||||
# 对于块值,进一步清理内部内容
|
||||
cleaned_value = cleaned_value[1:-1].strip()
|
||||
cleaned_value = re.sub(r'\s+', ' ', cleaned_value)
|
||||
|
||||
# 如果键已存在,则将值附加到列表中
|
||||
if key in main_config:
|
||||
if isinstance(main_config[key], list):
|
||||
main_config[key].append(cleaned_value)
|
||||
else:
|
||||
main_config[key] = [main_config[key], cleaned_value]
|
||||
else:
|
||||
main_config[key] = cleaned_value
|
||||
|
||||
return main_config
|
||||
|
||||
# ======================= pdns ================================
|
||||
def _parser_pdns_config(self, conf: str):
|
||||
"""解析pdns主配置"""
|
||||
if not conf:
|
||||
return {}
|
||||
main_config = {}
|
||||
for line in conf.splitlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
parts = line.split("=", 1)
|
||||
if len(parts) == 2:
|
||||
key = parts[0].strip()
|
||||
value = parts[1].strip()
|
||||
main_config[key] = value
|
||||
return main_config
|
||||
|
||||
# ======================= public method =======================
|
||||
@staticmethod
|
||||
def ttl_parse(value: str) -> Optional[int]:
|
||||
try:
|
||||
return int(value.split()[1])
|
||||
except (ValueError, IndexError):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def soa_parse(value: str) -> dict:
|
||||
try:
|
||||
value = re.sub(r';.*', '', value)
|
||||
soa_parts = value.split()
|
||||
if len(soa_parts) >= 7:
|
||||
parsed_value = {
|
||||
"nameserver": soa_parts[0],
|
||||
"admin_mail": soa_parts[1],
|
||||
"serial": int(soa_parts[2]),
|
||||
"refresh": int(soa_parts[3]),
|
||||
"retry": int(soa_parts[4]),
|
||||
"expire": int(soa_parts[5]),
|
||||
"minimum": int(soa_parts[6])
|
||||
}
|
||||
return parsed_value
|
||||
except (ValueError, IndexError):
|
||||
return {}
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def handle_multiline_soa(lines: list, i: int, current_line: str) -> tuple[str, int]:
|
||||
"""处理多行SOA记录"""
|
||||
soa_lines = [current_line.replace("(", " ")]
|
||||
while i < len(lines):
|
||||
next_line = lines[i].strip()
|
||||
i += 1
|
||||
if not next_line:
|
||||
continue
|
||||
next_line = next_line.split(';', 1)[0].strip() # 移除注释
|
||||
if not next_line:
|
||||
continue
|
||||
soa_lines.append(next_line)
|
||||
if ")" in next_line:
|
||||
break
|
||||
line = " ".join(soa_lines).replace(")", " ")
|
||||
return line, i
|
||||
|
||||
def _parse_record(self, line: str, default_ttl: Optional[int]) -> Optional[dict]:
|
||||
"""解析单条DNS记录"""
|
||||
match = record_pattern.match(line)
|
||||
if not match:
|
||||
return None
|
||||
|
||||
name, ttl, r_class, r_type, value = match.groups()
|
||||
if r_type.upper() == "TXT":
|
||||
value = value.strip()
|
||||
if not (value.startswith('"') and value.endswith('"')):
|
||||
# 对于没有引号的 TXT 记录或其它记录,移除注释
|
||||
value = value.split(';', 1)[0].strip()
|
||||
else:
|
||||
# 对于非 TXT 记录,保持原有的注释移除逻辑
|
||||
value = value.split(';', 1)[0].strip()
|
||||
|
||||
record = {
|
||||
"name": name,
|
||||
"ttl": int(ttl) if ttl is not None else default_ttl,
|
||||
"class": r_class or "IN",
|
||||
"type": r_type,
|
||||
"value": value,
|
||||
}
|
||||
|
||||
if r_type.upper() == "SOA": # 解析特殊字段
|
||||
record.update(self.soa_parse(value))
|
||||
elif r_type.upper() == "MX":
|
||||
try:
|
||||
priority, mx_value = value.split(None, 1)
|
||||
record["priority"] = int(priority)
|
||||
record["value"] = mx_value
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
elif r_type.upper() == "SRV":
|
||||
try:
|
||||
priority, weight, port, target = value.split(None, 3)
|
||||
record["priority"] = int(priority)
|
||||
record["weight"] = int(weight)
|
||||
record["port"] = int(port)
|
||||
record["value"] = target
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
return record
|
||||
|
||||
def parser_zone_record(self, zone_file: str, witSOA: bool = False):
|
||||
"""解析zone记录"""
|
||||
zone_content = public.readFile(zone_file) or ""
|
||||
if not zone_content:
|
||||
return
|
||||
default_ttl = None
|
||||
lines = zone_content.splitlines()
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i].strip()
|
||||
i += 1
|
||||
if not line or line.startswith(";"):
|
||||
continue
|
||||
|
||||
if line.startswith("$TTL"):
|
||||
default_ttl = self.ttl_parse(line)
|
||||
continue
|
||||
try:
|
||||
if "SOA" in line and line.rstrip().endswith("("):
|
||||
line, i = self.handle_multiline_soa(lines, i, line)
|
||||
except Exception as e:
|
||||
public.print_log("Error handling multiline SOA: {}".format(e))
|
||||
continue
|
||||
|
||||
record = self._parse_record(line, default_ttl)
|
||||
if not record:
|
||||
continue
|
||||
|
||||
if not witSOA and record.get("type") == "SOA":
|
||||
continue
|
||||
elif witSOA and record.get("type") == "SOA":
|
||||
yield record
|
||||
return
|
||||
|
||||
yield record
|
||||
|
||||
def get_config(self, service_name: str = None) -> dict:
|
||||
""""获取服务的所有配置, 默认获取当前安装的服务配置"""
|
||||
config = {}
|
||||
service = service_name or self.config.install_service
|
||||
if service == "bind":
|
||||
nick_name = "bind"
|
||||
paths = self.config.bind_paths
|
||||
parser = self._parser_bind_config
|
||||
elif service == "pdns":
|
||||
nick_name = "pdns"
|
||||
paths = self.config.pdns_paths
|
||||
parser = self._parser_pdns_config
|
||||
else:
|
||||
return {}
|
||||
conf_path = paths["config"]
|
||||
if not os.path.exists(conf_path):
|
||||
return {}
|
||||
config["service_name"] = nick_name
|
||||
config["config"] = parser(public.readFile(conf_path))
|
||||
return config
|
||||
|
||||
def get_zones(self, domain: str = None) -> list:
|
||||
"""获取域名列表"""
|
||||
path = self.config.pdns_paths["zones"]
|
||||
if not os.path.exists(path):
|
||||
return []
|
||||
zones_content = public.readFile(path) or ""
|
||||
zone_matches = zone_pattern.findall(zones_content)
|
||||
domains = []
|
||||
for match in zone_matches:
|
||||
zone_declaration = match.strip()
|
||||
domain_match = re.search(r'zone\s+"([^"]+)"', zone_declaration)
|
||||
if domain_match:
|
||||
if domain and domain != domain_match.group(1):
|
||||
continue
|
||||
domains.append(domain_match.group(1))
|
||||
return domains
|
||||
|
||||
def get_zones_records(self, domain: str = None, witSOA: bool = False) -> list:
|
||||
"""获取domain zones信息记录列表"""
|
||||
for root, dirs, files in os.walk(self.config.pdns_paths["zone_dir"]):
|
||||
files.sort()
|
||||
for file in files:
|
||||
try:
|
||||
if file.startswith("db.") or file.endswith(".zone"):
|
||||
temp_domain = re.sub(r'^(db\.|zone\.)', '', str(file))
|
||||
temp_domain = re.sub(r'\.(db|zone)$', '', temp_domain)
|
||||
if temp_domain != domain:
|
||||
continue
|
||||
zone_file_path = os.path.join(root, file)
|
||||
res = list(
|
||||
self.parser_zone_record(
|
||||
zone_file=str(zone_file_path), witSOA=witSOA
|
||||
)
|
||||
)
|
||||
return res
|
||||
except Exception as e:
|
||||
public.print_log("Error parsing zone file {}: {}".format(file, e))
|
||||
continue
|
||||
return []
|
||||
42
class_v2/ssl_dnsV2/model.py
Normal file
42
class_v2/ssl_dnsV2/model.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: yakpanel
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# dns app
|
||||
# ------------------------------
|
||||
from public.aaModel import *
|
||||
|
||||
|
||||
class DnsResolve(aaModel):
|
||||
id = IntField(primary_key=True)
|
||||
domain = StrField(default="", ps="domain")
|
||||
ns_resolve = IntField(default=0, ps="NS")
|
||||
a_resolve = IntField(default=0, ps="A")
|
||||
tips = StrField(default="", ps="tips")
|
||||
|
||||
create_time = DateTimeStrField(auto_now_add=True, ps="创建时间")
|
||||
update_time = DateTimeStrField(auto_now=True, ps="更新时间")
|
||||
|
||||
@classmethod
|
||||
def update_or_create(cls, domain: str, **kwargs) -> "DnsResolve":
|
||||
obj = cls.objects.filter(domain=domain).first()
|
||||
if obj:
|
||||
for k, v in kwargs.items():
|
||||
setattr(obj, k, v)
|
||||
obj.save()
|
||||
return obj
|
||||
else:
|
||||
res = cls(domain=domain, **kwargs).save()
|
||||
return res
|
||||
|
||||
class _Meta:
|
||||
table_name = "dns_domain_resolve"
|
||||
index = [
|
||||
"domain"
|
||||
]
|
||||
170
class_v2/ssl_dnsV2/pdns_script.sh
Normal file
170
class_v2/ssl_dnsV2/pdns_script.sh
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
public_file=/www/server/panel/install/public.sh
|
||||
|
||||
if [ ! -f $public_file ];then
|
||||
wget -O $public_file https://node.yakpanel.com/install/public.sh -T 30;
|
||||
fi
|
||||
|
||||
. $public_file
|
||||
download_Url=$NODE_URL
|
||||
|
||||
|
||||
check_and_disable_resolved()
|
||||
{
|
||||
if systemctl is-active --quiet systemd-resolved; then
|
||||
echo "Found active systemd-resolved. Stopping and disabling it..."
|
||||
systemctl stop systemd-resolved
|
||||
systemctl disable systemd-resolved
|
||||
echo "systemd-resolved has been stopped and disabled."
|
||||
elif systemctl list-units --type=service --all | grep -q 'systemd-resolved.service'; then
|
||||
echo "Found inactive systemd-resolved. Disabling it..."
|
||||
systemctl disable systemd-resolved
|
||||
echo "systemd-resolved has been disabled."
|
||||
else
|
||||
echo "systemd-resolved service not found, no action needed."
|
||||
fi
|
||||
|
||||
# 删软链
|
||||
if [ -L /etc/resolv.conf ]; then
|
||||
echo "Removing symlink /etc/resolv.conf"
|
||||
rm -f /etc/resolv.conf
|
||||
echo "Set namerser 8.8.8.8 to /etc/resolv.conf"
|
||||
echo "nameserver 8.8.8.8" > /etc/resolv.conf
|
||||
fi
|
||||
# 确保上游dns
|
||||
if ! grep -q "nameserver 8.8.8.8" /etc/resolv.conf 2>/dev/null; then
|
||||
echo "Adding 8.8.8.8 to /etc/resolv.conf"
|
||||
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
|
||||
fi
|
||||
}
|
||||
|
||||
Install_Powerdns_Redhat()
|
||||
{
|
||||
yum install pdns -y
|
||||
groupadd named
|
||||
useradd -g named -s /sbin/nologin named
|
||||
mv /etc/pdns/pdns.conf /etc/pdns/pdns.conf_bt
|
||||
wget -O /etc/pdns/pdns.conf $download_Url/install/plugin/dns_manager/pdns.conf -T 30
|
||||
chmod 644 /etc/pdns/pdns.conf
|
||||
mkdir -p /var/named/chroot/etc
|
||||
mkdir -p /var/named/chroot/var/named
|
||||
chmod 755 /var/named
|
||||
chmod 755 /var/named/chroot
|
||||
chmod 755 /var/named/chroot/etc
|
||||
chmod 755 /var/named/chroot/var
|
||||
chmod 755 /var/named/chroot/var/named
|
||||
chmod -R 644 /var/named/chroot/etc/*
|
||||
chmod -R 644 /var/named/chroot/var/named/*
|
||||
if [ ! -f "/var/named/chroot/etc/named.rfc1912.zones" ];then
|
||||
touch /var/named/chroot/etc/named.rfc1912.zones
|
||||
fi
|
||||
bind_conf=$(grep 'file "/var/' /var/named/chroot/etc/named.rfc1912.zones)
|
||||
if [ "$bind_conf" == "" ];then
|
||||
sed -i 's/file\s*\"/file \"\/var\/named\/chroot\/var\/named\//g' /var/named/chroot/etc/named.rfc1912.zones
|
||||
fi
|
||||
check_and_disable_resolved
|
||||
systemctl stop named-chroot
|
||||
systemctl disable named-chroot
|
||||
systemctl enable pdns
|
||||
systemctl restart pdns
|
||||
|
||||
echo "Configured for Rehat/Centos."
|
||||
|
||||
}
|
||||
|
||||
Install_Powerdns_Ubuntu()
|
||||
{
|
||||
curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo apt-key add -
|
||||
apt-get update -y
|
||||
apt-get install pdns-server -y
|
||||
groupadd named
|
||||
useradd -g named -s /sbin/nologin named
|
||||
mv /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf_bt
|
||||
wget -O /etc/powerdns/pdns.conf $download_Url/install/plugin/dns_manager/pdns.conf -T 30
|
||||
chmod 644 /etc/powerdns/pdns.conf
|
||||
mkdir -p /var/named/chroot/etc
|
||||
mkdir -p /var/named/chroot/var/named
|
||||
if [ ! -f "/var/named/chroot/etc/named.rfc1912.zones" ];then
|
||||
touch /var/named/chroot/etc/named.rfc1912.zones
|
||||
fi
|
||||
check_and_disable_resolved
|
||||
systemctl enable pdns
|
||||
systemctl restart pdns
|
||||
|
||||
echo "Configured for Debian/Ubuntu."
|
||||
}
|
||||
|
||||
Install_Powerdns()
|
||||
{
|
||||
if [ -f '/usr/bin/yum' ];then
|
||||
Install_Powerdns_Redhat
|
||||
else
|
||||
Install_Powerdns_Ubuntu
|
||||
fi
|
||||
|
||||
echo -n "pdns" > /www/server/panel/class_v2/ssl_dnsV2/aadns.pl
|
||||
}
|
||||
|
||||
Install_DnsManager()
|
||||
{
|
||||
echo "Installing..."
|
||||
Install_Powerdns
|
||||
/usr/bin/btpip install dnspython
|
||||
grep "English" /www/server/panel/config/config.json
|
||||
sleep 3
|
||||
echo "YakPanelDns Service Success!"
|
||||
}
|
||||
|
||||
update_DnsManager()
|
||||
{
|
||||
if [ ! -f "/usr/sbin/pdns_server" ];then
|
||||
echo "Installing ..."
|
||||
Install_Powerdns
|
||||
fi
|
||||
grep "English" /www/server/panel/config/config.json
|
||||
echo "The installation is complete"
|
||||
}
|
||||
|
||||
Uninstall_DnsManager()
|
||||
{
|
||||
echo "Uninstalling..."
|
||||
clean=${1}
|
||||
if [ "$clean" == 1 ];then
|
||||
echo "Cleaning up YakPanelDns config data..."
|
||||
rm -f /var/named/chroot/etc/named.rfc1912.zones_bak
|
||||
mv /var/named/chroot/etc/named.rfc1912.zones /var/named/chroot/etc/named.rfc1912.zones_bak
|
||||
echo "Remove config: named.rfc1912.zones"
|
||||
cp /var/named/chroot/var/named/*_aadef /var/named/chroot/var/named_bak/
|
||||
cp /var/named/chroot/var/named/*zone /var/named/chroot/var/named_bak/
|
||||
echo "Remove zone config files"
|
||||
rm -rf /var/named/chroot/var/named
|
||||
else
|
||||
echo "Backing up YakPanelDns config data..."
|
||||
cp /var/named/chroot/etc/named.rfc1912.zones /var/named/chroot/etc/named.rfc1912.zones_aabak
|
||||
echo "Backup config: named.rfc1912.zones"
|
||||
mkdir -p /var/named/chroot/var/named_bak/
|
||||
echo "Backup zone config files"
|
||||
cp /var/named/chroot/var/named/*_aadef /var/named/chroot/var/named_bak/
|
||||
cp /var/named/chroot/var/named/*zone /var/named/chroot/var/named_bak/
|
||||
fi
|
||||
|
||||
rm -f /www/server/panel/class_v2/ssl_dnsV2/aadns.pl
|
||||
rm -f /www/server/panel/class_v2/ssl_dnsV2/aaDns_conf.json
|
||||
|
||||
/usr/bin/systemctl stop named-chroot
|
||||
systemctl disable named-chroot
|
||||
systemctl stop pdns
|
||||
systemctl disable pdns
|
||||
sleep 3
|
||||
echo "YakPanelDns Service Success!"
|
||||
}
|
||||
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_DnsManager
|
||||
elif [ "${1}" == 'update' ];then
|
||||
update_DnsManager
|
||||
elif [ "${1}" == 'uninstall' ];then
|
||||
Uninstall_DnsManager ${2}
|
||||
fi
|
||||
Reference in New Issue
Block a user