云服务器安装qq本地DNS缓存实战(dnsmasq SQLite 简易统计)
安全云查看服务器
一、前言
在内网部署本地 DNS 缓存能加速域名解析、减小外网 DNS 请求量并便于统计常访问域名。本文给出最简单、可落地的方案:在一台 Raspberry Pi / 小型服务器上用 dnsmasq 做 DNS 缓存并开启查询日志,然后用一个 小巧的 Python 脚本 将日志解析写入 SQLite 做统计(比如按域名计数、查看 TOPN)。适合家庭、小型办公室、实验环境。全程命令可复制粘贴。
二、适用场景
局域网加速域名解析(一个局域网 DNS 缓存)统计内网最常访问的域名(排查流量或广告域)在无法或不想使用外部 Pi-Hole/云服务时做轻量替代三、环境与依赖
一台运行 Debian/Ubuntu / Raspberry Pi OS 的机器(例如:192.168.1.10)安装软件:dnsmasq, sqlite3, python3(系统常自带)sudo apt update
sudo apt install -y dnsmasq sqlite3 python3
四、dnsmasq 快速配置(缓存 + 日志)
编辑或新建/etc/dnsmasq.d/local-cache.conf,内容如下(注:示例使用 53 端口的默认配置):
/etc/dnsmasq.d/local-cache.conf
缓存大小(条目数)
cache-size=1000
启用查询日志并写入独立日志文件
log-queries
log-facility=/var/log/dnsmasq.log
可选:对某些域做自定义解析(示例)
address=/internal.example.local/192.168.1.5
保存后重启 dnsmasq:
sudo systemctl restart dnsmasq
sudo systemctl status dnsmasq
确保日志文件存在并可写:
sudo touch /var/log/dnsmasq.log
sudo chown dnsmasq:adm /var/log/dnsmasq.log
sudo chmod 640 /var/log/dnsmasq.log
(可选)如果系统使用 systemd-journald + rsyslog,log-facility 会把日志写到指定文件,便于后续解析。
五、在客户端指向本地 DNS(示例)
把局域网内客户端的 DNS 设置为 Pi 的 IP(例如 192.168.1.10)。可以在路由器 DHCP 中设置,或在单台机器上手动设置:
Linux 示例(临时)
sudo nmcli dev show | grep DNS 查看
sudo nmcli connection modify ipv4.dns "192.168.1.10"
sudo nmcli connection up
测试解析:
dig @192.168.1.10 www.google.com +short
六、简单的日志解析与写入 SQLite(脚本)
把下面脚本保存为/opt/dns_cache/dns_log_to_sqlite.py 并赋可执行权限。脚本功能:增量读取 /var/log/dnsmasq.log,统计每个查询的域名出现次数并写入 SQLite 表 domain_stats(保留最新计数和上次出现时间)。
!/usr/bin/env python3
/opt/dns_cache/dns_log_to_sqlite.py
import os, sqlite3, re, time
LOG_FILE = "/var/log/dnsmasq.log"
DB_FILE = "/opt/dns_cache/dns_queries.db"
OFFSET_FILE = "/opt/dns_cache/.offset"
匹配 dnsmasq 查询行中的域名(常见格式)
示例日志行:
Jan 01 12:00:00 dnsmasq[1234]: query[A] www.example.com from 192.168.1.20
RE = re.compile(rquery[[AIPV4a-zA-Z]*]s+([^s]+)s+from)
def init():
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute(
CREATE TABLE IF NOT EXISTS domain_stats (
domain TEXT PRIMARY KEY,
count INTEGER,
last_ts INTEGER
云服务器提供上行
))
conn.commit()
conn.close()
ensure offset file exists
if not os.path.exists(OFFSET_FILE):
with open(OFFSET_FILE, w) as f:
f.write("0")
def read_offset():
try:
with open(OFFSET_FILE,r) as f:
return int(f.read().strip())
except:
return 0
架设云打印服务器
def write_offset(v):
with open(OFFSET_FILE,w) as f:
f.write(str(v))
def process():
if not os.path.exists(LOG_FILE):
print("log not found:", LOG_FILE); return
off = read_offset()
size = os.path.getsize(LOG_FILE)
if size < off:
off = 0 log rotated
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
with open(LOG_FILE,r,errors=ignore) as fh:
fh.seek(off)
for line in fh:
m = RE.search(line)
if not m:
continue
domain = m.group(1).lower().rstrip(.)
ts = int(time.time())
upsert
c.execute(SELECT count FROM domain_stats WHERE domain=?, (domain,))
row = c.fetchone()
if row:
c.execute(UPDATE domain_stats SET count = count + 1, last_ts = ? WHERE domain = ?, (ts, domain))
else:
c.execute(INSERT INTO domain_stats(domain, count, last_ts) VALUES (?,?,?), (domain, 1, ts))
new_off = fh.tell()
conn.commit()
conn.close()
write_offset(new_off)
if __name__ == "__main__":
init()
process()
赋权限并创建目录:
sudo mkdir -p /opt/dns_cache
sudo chown $(whoami):$(whoami) /opt/dns_cache
sudo chmod 750 /opt/dns_cache
sudo chmod +x /opt/dns_cache/dns_log_to_sqlite.py
七、定时执行(cron)
把解析脚本放到 cron 定时运行(例如每分钟),以便近实时统计:
crontab -e
添加一行(每分钟运行)
* * * * * /usr/bin/python3 /opt/dns_cache/dns_log_to_sqlite.py >/dev/null 2>&1
八、查看统计结果(示例)
用 sqlite3 查询 TOP 20 访问域名:
sqlite3 /opt/dns_cache/dns_queries.db "SELECT domain, count, datetime(last_ts,unixepoch,localtime) FROM domain_stats ORDER BY count DESC LIMIT 20;"
快速查看某个域名的计数:
sqlite3 /opt/dns_cache/dns_queries.db "SELECT count FROM domain_stats WHERE domain=www.example.com;"
九、日志轮转与安全建议
日志轮转: /var/log/dnsmasq.log 会变大,建议为其添加 logrotate 配置 /etc/logrotate.d/dnsmasq:/var/log/dnsmasq.log {
daily
rotate 7
compress
missingok
notifempty
create 640 dnsmasq adm
postrotate
systemctl restart dnsmasq >/dev/null 2>&1 || true
endscript
}
权限:确保只有可信用户能读 /var/log/dnsmasq.log 与 /opt/dns_cache 下的 DB 文件。隐私:统计仅记录域名,不记录完整请求者 IP(脚本可扩展记录 IP);若要记录 IP,请注意隐私合规。十、扩展(可选、非必须)
将 SQLite 数据定期导出到 InfluxDB / Grafana 做可视化。在脚本中记录客户端 IP(从日志中提取)以做来源分析。添加白名单/黑名单规则(dnsmasq 支持 address=/bad.site/0.0.0.0 阻断广告域)。把统计脚本做成小 Web 服务(Flask)以便在线查看 TOPN。十一、总结
本文提供了一个非常轻量、易上手的本地 DNS 缓存与统计方案:用 dnsmasq 做缓存与日志,用一个简短的 Python 脚本把查询写入 SQLite,便于快速落地、长期统计与排查。整套方案依赖少、脚本短、适合想在局域网内提升解析速度并观察访问热点的读者。
超云服务器客服

扫码关注
微信好友
关注抖音