DD-WRT安装与配置

DD-WRT配置

修改DD-WRTWEB默认管理端口

1
2
3
4
5
6
# nvram set rc_startup="
> killall httpd
> cd /www
> httpd -p 8080 -h /www
> "
# nvram commit

nvram命令

nvram具有多层含义。首先它是非可变性RAM(non-volatile RAM)的缩写,这种RAM是一种持久性内存,可在断电时保留数据。路由器内的闪存就是一种nvram。nvram命令用于管理硬件设置,这些设置保存在闪存的最后一块内。这个内存段通常称为“nvram”。nvram命令有不同版本,比如IBM、Cisco、Oracle和Apple版。DD-WRT内的nvram命令非常简单,因为它只是显示和更改分配给变量的颠倒以及删除变量。无选项情况下运行它可以看到选项和参数:

ash shell
1
2
root@linksys:~# nvram
usage: nvram [get name] [set name=value] [unset name] [show]

nvram show显示了路由器上的所有设置,而且设置还不少。可以使用less将其分隔为一次一页:

ash shell
1
root@linksys:~# nvram show | less

或是用grep查找特定的变量,比如:

ash shell
1
root@linksys:~# nvram show | grep ssh

例如:如果你无意间禁用了WEB界面,但仍有telnet或SSH,可以以这种方式重新启用它:

ash shell
1
2
3
root@linksys:~# nvram set hhtp_enable=1
root@linksys:~# nvram commit
root@linksys:~# reboot

如果想清除任何值的变量可参考如下所示:

ash shell
1
2
root@linksys:~# nvram set http_enable=""
root@linksys:~# nvram commit

JFFS(Journalling Flash File System)

通常,DD-WRT映像会占据约26MB分区,即便闪存是128MB或更多,也是如此。可以在未使用的空间创建另一个分区并用其来存储文件。这应该主要是读存储(read-storage),比如无线热点splash和配置页、WEB页、额外的配置文件以及面向ipkg(针对嵌入式设备的ItsyPackage Management System)的存储空间。不要将它用于像日志文件这样能生成大量写操作的文件,因为闪存只支持数量有限的写操作并最终会出现故障。现代的闪存相当耐用,但它仍具有有限的写操作生命期限。用这个很好的旧df命令可以看到现有的文件系统:
Alt text

我的路由器具有128MB闪存,那么剩下的那些去哪了呢?它闲置在哪,等着被派上用场。访问Administrator–>Management并检查JFFS2–>Enable和Clean JFFS2–>Enable。单击Apple Setting,继而Reboot Router。当它重启时,应该会看到类似下面的结果:
Alt text

JFFS2(Journalling Flash File System 版本2)是针对闪存存储媒介设计的。我们先来看看这种闪存属于哪种媒介。它是一种特殊的设备,称为Memory Technology Device,缩写为MTD。它不是一种像硬盘和USB棒那样的块设备,也不是像键盘鼠标那样的字符设备。块设备通常以大小固定(512和1024字节)的分区组织而成。而MTD则具有大小为128KB和更大的擦写块(eraseblock)。块设备可以做两件事:读区和写区。MTD可以做三件事:从擦写块读、写到擦写块和擦除擦写块。

紧凑式闪存、SD 卡、USB 棒究其本质都是 MTD。但它们对于操作系统而言更像是块设备,因为它们具有 Flash Translation Layers (FTL),用于在闪存硬件之上模拟块设备。这种 FTL 可以位于主计算机上,也可以位于此设备内的硬件控制器的固件上。如果您愿意牺牲一个 USB 棒(为知识的进步所做的一次伟大的牺牲)并撬开它,那么您很有可能会看到一些 NAND 芯片(原始的闪存芯片)和一个微控制器。

了解有关闪存的几件事情将有助于您的 DD-WRT 探险之旅。第一,NAND 擦写块显示的是全或无(整个块必须在新的数据写上之前先被擦除)。第二,Linux 具有一个 MTD 子系统,和一个用来执行基本任务(比如擦除或向设备写映像)的 mtd 命令。可以在 DD-WRT 上运行无选项的 mtd 命令来查看语法和选项。在 DD-WRT 维基上还可以看到一些关于如何使用 mtd 命令的 how-to 文章,现在您该知道它是怎么回事了吧。第三,nvram 位于最后一个擦写块上,而无论擦写块有多大,它都被以编程的方式限制为 32KB。

使用WEB GUI界面启用JFFS

通过路由器网页启用JFFS的步骤非常具体。为了避免重置和重新编程路由器,设置备份是明智之举。通过以下步骤在DD-WRT中启用JFFS

  1. 路由器的主页中点击“管理”
  2. 向下滚动,直到看到JFFS2支持部分
  3. 点击“启动JFFS“
  4. 点击“保存”
  5. 等待几秒钟,然后单击“应用”
  6. 再等一下,返回到启用JFFS部分,并启用“Clean JFFS”
  7. 不要点击“保存”。单击“应用”,这时路由器将如上面介绍的对空间进行格式化
  8. 等到网络的GUI界面回来,然后禁用“clean JFFS”,单击“保存”
  9. 重新启动一下路由器

命令行方式启动JFFS:CLI

1
2
3
4
5
6
7
8
9
nvram set jffs_mounted=1
nvram set enable_jffs2=1
nvram set sys_enable_jff2=1
nvram set clean_jffs=1
nvram set sys_clean_jffs2=1
nvram commit
reboot
# 删除变量请使用如下命令
# nvram unset <variable>

增加JFFS空间的方法

增加1G闪存卡

加入到SD/MMC模式

  • DD-WRT V2.4或更高版本才支持1G闪存
  • 创建文件夹mkdir /mmc/jffs
  • 绑定设备到上面文件夹mount --bind /mmc/jffs /jffs
  • 进入GUI界面“管理–>JFFS2启用” 或者使用CLI命令行nvram set sys_enable_jffs2=1
  • 创建文件夹得以使用ipkgmkdir /jffs/tmp && mkdir /jffs/tmp/ipkg

添加USB存储设备

  • 首先,要启用USB设备的支持,安装USB驱动,并启动jffs

    ash shell
    1
    2
    3
    mount /dev/scsi/hosts0/bus0/target0/lun0/part1 /mnt
    mkdir /mnt/jhffs
    mount /mnt/jffs /jffs
  • 进入GUI界面“管理–>JFFS2启用” 或者使用CLI命令行nvram set sys_enable_jffs2=1

  • 创建文件夹得以使用ipkgmkdir /jffs/tmp && mkdir /jffs/tmp/ipkg

测试ipkg

1
2
3
4
cd /jffs
mkdir -p /jffs/tmp/ipkg
ipkg update
ipkg list

建议运行上述命令后重启路由器

Entware安装与配置

引言

Entware是什么?它是嵌入式设备的软件存储库,如路由器或网络附加存储,库中大约有2000个以上的可用程序包。它本身是Optware的替代品。在五年的发展中Entware成了主流,在X86、X64、MIPS、MIPSEL、ARMV5和ARMV7平台有有着很好的应用,并且目前有专门的团队进行维护。

准备工作

  1. 登录到路由器的GUI界面,服务–>USB,确保核心USB支持、USB存储和自动驱动器安装都已经启用。如果一个或多个没有启用,那么请启用它并单击“应用”使之生效。
  2. 重新分区格式化USB相关设备,确保USB设备的分区格式为Ext2或者是Ext3或NTFS。如果它是硬盘驱动器,分区时要设置为主分区,不要设置逻辑分区。如果你希望EntWare自动安装到相关分区,那么请在此分区设置标签,标签值为“Optware”
    图片(DD-WRT USB设置)

安装

  1. 在路由器中插入USB设备,可能需要重新启动路由器。检查服务-USB,看看它是否出现,记下当前的挂载点/tmp/mnt/sda_part1,如果正确这里应为/tmp/mnt/opt
  2. 打开SSH终端到路由器。使用上面的挂载点链入以下命令

    ash shell
    1
    2
    3
    4
    5
    6
    7
    cd /opt
    wget {link to std install script for your router} (click enter)
    sh generic.sh (click enter)
    # 我的路由器是EA6500,Broadcom单核,因此我使用如下地址:
    cd /opt
    wget http://bin.entware.net/mipselsf-k3.4/installer/generic.sh (click enter)
    sh generic.sh
  3. 安装完成,运行更新

    ash shell
    1
    2
    opkg update (click enter)
    opkg upgrade (click enter)
  4. 最后一步是将以下命令添加到启动脚本(管理–>命令)。睡眠值可以调整,但对于大多数USB硬件/路由器来说,10是足够长的。

    ash shell
    1
    2
    sleep 10
    /opt/etc/init.d/rc.unslung start

注意:

  • 不要向PATH或LD_LIBRARY_PATH变量添加任何内容,它们已经包括了必要的文件夹的位置;
  • 安装完毕可以通过连接http://bin.entware.net/mipselsf-k3.4/Packages.html,查看全部包信息
  • 你可以使用opkg list查看包列表

DD-WRT固件升及对于Entware的影响

在升级DD-WRT固件以前,最好删除Entware驱动或者禁用USB的支持。升级DD-WRT不会给Entware安装带来任何问题,只要开发人员不要更改上面提到的PATH或LD_LIBRARY_PATH变量。升级后只需再次启用USB支持即可。然后打开SSH终端并发出以下命令:

ash shell
1
2
opkg update
opkg upgrade

EntWare WiKi

Entware Wiki : https://github.com/Entware/Entware/wiki

启动脚本

在DD-WRT中有三种方法让它们自动运行。

在路由器上加载脚本的WEB界面方法


1. 先决条件

  • 可以访问Web界面
  • 知道启动时运行的命令
  • 在命令行中测试命令以确保正确的操作


2. 操作指南

  • 使用Web界面,转到管理选项卡
  • 转到命令子选项卡
  • 在命令对话框中键入希望运行每次启动命令(使用enter键将每个命令放在换行符上,如果该命令不是暂时停止运行的命令,则在命令后面加上“&”)
  • 如果希望将命令保存到rc_startup变量,请单击页面底部的“存储启动命令”按钮。保存防火墙将命令保存到RCI防火墙变量中。


3. 工作原理
这样做是将您的命令串保存到闪存中的RCL启动变量(也称为NVRAM变量)。由于闪存在启动时不会被擦除,所以你的“startup script”将在每次启动时一直存在,并且总是执行。在命令框中单击“运行命令”按钮。


4. 定制脚本

  • 如果你的中由器一个保存自定义脚本按钮,你可以将命令保存在/tmp/custom.sh
  • 你可以通过在命令框中键入sh /tmp/custom.sh。追在一个“&”符命令会把它放在后台:sh /tmp/custom.sh &

NVRAM方法


1. 先决条件

  • 用于登陆路由器工具telnet或SSH
  • 了解每一次启动你想要运行的命令
  • 测试运行命令(可选)


2. 操作指南

  1. 使用Telnet/SSH登陆路由器
  2. 叵要设置启动脚本,请使用以下内容:
    ash shell
    1
    2
    3
    4
    5
    6
    nvram set rc_startup="
    <command 1>
    <command 2>
    ...
    <command n>
    "

提交NVRAM命令后,RCL启动变量保存在闪存中,在重新启动时将保留。
nvram commit


3. 工作原理
当你发出第一个命令时,你注意到提示符更改为“>”,从这里起,您键入的每一行都被添加到rc_startup变量中。从技术上讲,你仍然在同一个命令行上键入,即使你正在使用多行。当你键入最后一个双引号并点击回车键后,你将看到提示符更改返回,并且已经执行了第一个命令。也就是说,脚本已经添加到变量RCL启动中。
此时,你可以通过发出命令检查RCL启动的内容:
~# nvram get rc_startup


4. 自动化的WEB界面
为了自动化或测试Web界面,可以使用免费的IMACROS Firefox插件。您可以在Web界面中记录和重放你的活动,你可以下载它:
https://addons.mozilla.org/firefox/3863/

Shell脚本方法

简单的nvram脚本适合于短脚本,但是如果你想体大量的工作,或者如果你想轻松地管理启动程序,最好的方法就是使用shell脚本。

Shell脚本使编写长脚本变得更加容易,长脚本又可以从互联网上获取可执行文件或脚本,或安装ipkg -d内存安装,从闪存分区复制预制的配置文件等,然后才能最终运行程序,并在每次启动时都这样做。

这意味着你不必在路由器闪存空间(nvram,这是相当有限的)中保存那么多的东西,但是您可以替代地填充更流得的RAM,而不必在每次重新启动时手动重新安装和配置程序。

而且,由于每个程序都有自己的脚本,因此在下一次引导中删除程序就如同删除、移动或重命名启动脚本文件一样简单。


1. 先决条件

  • 使用telnet或ssh登陆路由器
  • 了解你在启动时运行的命令
  • 使用SCP、WinSCP或其他方法将文件复制到路由器上。
  • 启用JFFS并正常工作。
  • 编辑脚本
  • 测试你的命令以确呆正确操作


2. 编写Shell脚本
编写每个程序的shell脚本。脚本以后缀名“*.startup”的文件
shell脚本应该看起来像这样:

ash shell
1
2
3
4
5
6
7
#!/bin/sh
<command 1>
<command 2>
<command 3>
...
killall <command n program name>
<command n>

由于DD-WRT系统的设计,你的shell脚本可能最终会定期运行,而不仅权是在引导时运行,这意味着,你需要确保每次只运行1次程序

killall命令确保不同时运行不止一次。这假设在执行之后立即退出之前出现在脚本中的所有命令(例如cp、wget或iptables)

例如下面脚本举例:kismet_server.startup

ash shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
# Make the /tmp/usr/bin folder and move there
mkdir /tmp/usr
mkdir /tmp/usr/bin
cd /tmp/usr/bin

#copy the executable file from my home web server
wget http://192.168.1.2/kismet_server

#kill and previously-running instances of kismet_server
killall -q kismet_server

#execute kismet_server using /jffs/etc/kismet.conf as the configuration file.
/tmp/usr/bin/kismet_server -n -f /jffs/etc/kismet.conf


3. 保存脚本
/jffs/etc/config目录中保存脚本。如果没有你可以创建此目录。

4. 使脚本可执行
~ # chmod 700 /jffs/etc/config/<scriptname>.startup

配置脚本的不同目录

  • /etc/config/
  • /jffs/etc/config/
  • /mmc/etc/config/
  • /tmp/etc/config/
后缀名 解释
.startup 将在系统启动、正常启动时间和防火墙配置之前执行
.prewall 每当WAN接口up并在防火墙之前执行
.wanup 每当WAN接口up并在防火墙之后执行
.if 将在任何接口和防火墙之后执行(不再在源代码中,必须删除)
.ipup 当PPP连接在断开和防火墙之后重新建立时运行
.ipdown 当PPP连接被关闭时运行。(不再在源代码中,必须删除吗?)
.sesbutton 在按下“SES/AOSS/EZ-SETUP”按钮时执行

注意:需要使用chmod命令更改脚本的执行权限。当脚本.wanup启动时,脚本可以运行多次。
参见:http://www.dd-wrt.com/phpBB2/viewtopic.php?p=433984

使用不同扩展名或不同文件夹执行脚本
如果要执行具有不同扩展名的脚本或位于其他文件夹中的脚本,可以创建此脚本。

ash shell
1
2
3
for I in `/bin/ls /jffs/etc/config/*.myextension`;do
sh $I &
done

举例:samba启动脚本

在文件夹/jffs/etc/config下,建立名为samba.startup脚本

ash shell
1
2
3
#!/bin/sh
/usr/sbin/smbd -D --configfile=/tmp/smb.conf
/usr/sbin/nmbd -D --configfile=/tmp/smb.conf

没有放在/etc/config下原因这个目录是read-only的
没有放在/tmp/etc/config/的原因为这个目录是临时的,重启之后这个目录里的东西就没了。

举例:nginx启动脚本

假设你安装一个 nginx , 它会在 init.d 目录创建一个名为 S80nginx 的服务脚本(数字可能不一样)。配置上述的脚本以后它会开机启动。但是,如果手动操作这个服务脚本呢?只需要:
/opt/etc/init.d/S80nginx start|restart|stop
执行它,给它相应参数即可。
但是,这样做未免太麻烦了。因为不仅仅是 init.d 目录不在 PATH 中,而是每个服务由于优先级的原因命名很麻烦。如果想手动 启动/停止/重启 某个服务还需要记住它的数字,打上大写的 S 也很麻烦。总之,这种手动直接运行服务文件的方式很麻烦。于是,我为了方便管理服务写了一个 lua 脚本,它基于这些服务文件,可以像其他发型版中的 service 一样根据正常服务名称管理服务:

ash shell
1
2
3
4
root@DD-WRT:~# ser privoxy restart
Shutting down privoxy... done.
Starting privoxy... done.
root@DD-WRT:~#

可以看到, ser 管理服务不需要绝对路径,不需要服务文件名,而是以服务应该有的名字(S + 数字之后的部分)。我们在 /opt/bin 目录创建文件 ser :

ash shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env lua
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
return string.sub(s, 0, string.len(s) - 1)
end
PATH = '/opt/etc/init.d/'
function handler(s_name, operation)
local out = os.capture('ls ' .. PATH, false)
local flag = false
for s in string.gmatch(out, '%S+') do
local prefix = string.match(s, '^S%d+')
if prefix then
local service_name = string.sub(s, string.len(prefix) + 1)
if service_name == s_name then
print(os.capture(PATH .. s .. ' ' .. operation))
flag = true
end
end
end
if not flag then
print('No service: ' .. s_name)
end
end
handler(arg[1], arg[2])

添加执行权限:chmod +x /opt/bin/ser
后就可以使用它了。当然,由于它是一个 lua 脚本,你需要安装 lua :opkg install lua
这样子管理服务就方便得多了

Entware安装应用设置开机启用

通过Entware安装的软件在 /opt/etc/init.d 下生成了服务脚本,它仍然在开关机时不会得到执行。
我们可以基于 DD 提供的 ‘Commands’ 功能做到这一点:

1. 创建相关目录(启用 jffs 的目的是用来存放这些固定的永久储存的东西):

ash shell
1
2
3
4
5
cd /jffs 
mkdir scripts
cd scripts
mkdir shutdown
mkdir startup


2. 在 scripts 目录创建 operator.sh 脚本(控制 shutdown 目录或者startup 目录的脚本执行):

ash shell
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env sh
SCRIPTS_HOME=/jffs/scripts
run_all(){
for SCRIPT in "$SCRIPTS_HOME"/"$1"/*;
do
if [ -f "$SCRIPT" -a -x "$SCRIPT" ]
then
$SCRIPT
fi
done
}
run_all "$1"


3. 在 startup 目录分别创建 S10service 和 S30swapon:

ash shell
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh
RC='/opt/etc/init.d/rc.unslung'
i=30
until [ -x "$RC" ] ; do
i=$(($i-1))
if [ "$i" -lt 1 ] ; then
logger "Could not start Entware"
exit
fi
sleep 1
done
$RC start

ash shell
1
2
3
4
5
6
#!/bin/sh
# Turn On Usage Of Swapfile
if [ -f "/opt/swapfile" ];then
swapon /opt/swapfile
echo "Turning Swapfile On"
fi

它们分别是启动 init.d 中的服务和启用 swap (交换空间)的脚本。

4. 设置开/关机执行脚本
路由器 WEB UI -> Tag: Administration - Commands , 分别添加以下两个命令,先后保存为 Startup 和 Shutdown :
/jffs/scripts/operator.sh startup
/jffs/scripts/operator.sh shutdown
其实就是开机执行 operator.sh 脚本添加 startup 参数 和 关机执行 operator.sh 添加 shutdown 参数。而 operator.sh的流程其实就是遍历参数目录(例如 startup 和 shutdown)中所有的脚本并且依次执行。如果你看明白了,就会知道只要将脚本放进 startup 目录它就会开机执行,只要放进 shutdown 它就会关机时执行。

有关脚本执行顺序需要特意说明一下,这是我的目录结构:

ash shell
1
2
3
4
5
6
7
8
9
root@DD-WRT:/jffs/scripts# tree -L 3
.
|-- operator.sh
|-- shutdown
| |-- S10service
| `-- S30swapoff
`-- startup
|-- S10service
`-- S30swapon

可以注意到,开机执行的脚本都是以 S + 数字 +名称来命名的。这样做的目的是方便遍历时排序,数字低的会被先遍历并执行,也就是根据命名做到了启动优先级。至于前缀的大写字母 S 可以用其他字母替代,但是要统一。是否后缀 .sh 也无所谓。其实这里我就是模仿的 init.d 里边的服务命名方式,因为它们就是用这种方式决定启动优先级的。这样做了以后,就在路由器固件原生不内置相关功能的情况下做到了一样的效果。安装的所有服务可以正常开机启动,并且可以自己添加任意的脚本让它们自动执行。(例如从上面的文件中可以看出来,我还在关机时运行了两个脚本)

DNSMasq配置本地网络

DD-WRT配置界面

1. 启动dnsmasq

服务–>服务–>DNSMasq 启动

2. 启动本地DNS

服务–>服务–>本地DNS 启动

3. DNSMasq 附加选项:

dnsmasq会自动读取/tmp/hosts文件,重启后/tmp中的内容将会重置。因此建议开启jffs,并指定hosts,在Additional DNSMasq Options中填写

1
addn-hosts=/jffs/dnsmasq.hosts

也可以设置不读取resolv.conf文件,直接在dnsmasq中设置dns服务器,在Additional DNSMasq Options中填写

1
2
3
no-resolv
server=8.8.8.8
server=8.8.4.4

还可以将某个域名提交给指定的dns服务器解析,在Additional DNSMasq Options中填写

1
2
server=/.google.com/208.67.222.222#443
server=/.google.com.hk/208.67.222.222#443

如果Additional DNSMasq Options里的内容太多,也可指定一个目录来读取这些配置信息

1
conf-dir=/opt/etc/dnsmasq.d

dnsmasq详解及配置

Dnsmasq提供DNS缓存和DHCP服务功能。作为域名解析服务器(DNS),dnsmasq可以通过缓存DNS计法度来提高对访问过的网址的连接速度。作为DHCP服务器,dnsmasq可以用于为局域网电脑分配内网IP地址和提供路由。DNS和DHCP两个功能可以同时或分别单独实现。dnsmasq轻量且易配置,适用于个人用户或少于50台主机的网络,此外它还自带了一个PXE服务器。

Dnsmasq的主要作用

  1. 将Dnsmasq作为本地DNS服务器使用,直接个改电脑的本地DNS的IP地址即可。
  2. 应对ISP的DNS劫持(反DNS劫持),输入一个不存在的域名,正常情况下浏览器是显示无法连接,DNS劫持会眺转到一个广告页面。先随便nslookup一个不存在的域名,看看ISP商劫持的IP地址
  3. 智能DNS加快解析速度,打开/etc/dnsmasq.conf文件,server=后面添加指定DNS,例如国外不同网站使用不同的DNS

    1
    2
    3
    4
    5
    6
    7
    # 国内指定DNS
    server=/cn/114.114.114.114
    server=/taobao.com/114.114.114
    server=/taobaocdn.com/114.114.114
    # 国外指定DNS
    server=/google.com/8.8.8.8
    server=/youtube.com/8.8.8.8
  4. 屏蔽网页广告,将指广告的URL指定127这个IP,就可以将网页上讨厌的广告去掉了。

    1
    2
    address=/ad.youku.com/127.0.0.1
    address=/ad.iqiyi.com/127.0.0.1
  5. 指定域名解析到特定的IP上。这个功能可以让你控制一些网站的访问,非法的DNS就经常把一些正规的网站解析到不正确的IP上。

    1
    address=/freehao123.com/123.123.123.123
  6. 管理控制内网DNS,首先将局域网中的所有的设备的本地DNS设置为已经安装的Dnsmasq的服务器IP地址。然后修改已经安装Dnsmasq的服务器Hosts文件:/etc/hosts,指定域名琶特定的iP中。例如想让局域网的所有用户访问www.freehao123.com时跳转到192.168.0.2,添加:192.168.0.2 www.freehao123.com在Hosts文件中既可,整个过程也可以说是“DNS劫持”。

Dnsmasq的解析流程

dnsmasq先去解析hosts文件,再去解析/etc/dnsmasq.d/下的*.conf文件,并且这些文件的优先级要高于dnsmasq.conf,我们自定义的resolv.dnsmasq.conf中的DNS也被称为上游DNS,这是最后去查询解析的;

如果不想用hosts文件做解析,我们可以在/etc/dnsmasq.conf中加入no-hosts这条语句,这样的话就直接查询上游DNS了,如果我们不想做上游查询,就是不想做正常的解析。我们就可以加入no-reslov这条语句。

Dnsmasq的参数及常用设置说明

编辑dnsmasq的配置文件/etc/dnsmasq.conf。这个文件有大量的选项注释。

经常修改的比较重要的参数说明

具体参数 参数说明
resolv-file 定义dnsmasq从哪里获取上游DNS服务器地址,默认从/etc/resolv.conf获取。
strict-order 表示严格按照resolv-file文件中的顺序从上到下进行DNS解析,直到第一个解析成功为止
listen-address 定义dnsmasq监听的地址,默认是监控本机的所有网卡上。
address 启用泛域名解析,即自定义解析a记录,例如:address=/long.com/192.168.115.10访问long.com时的所有域名都会被解析成192.168.115.10
bogus-nxdomain 对于任何被解析到此的IP域名,将响应NXDOMAIN使其解析失效,可以多次指定。通常用于对于访问不存在的域名,禁止其跳转到运营商的广告站点
server 指定使用哪个DNS服务器进行解析,对不不同的网站可以使用不同的域名对应解析。例如:server=/google.com/8.8.8.8 #表示对于google的服务,使用谷歌的DNS解析。

查看配置文件语法是否正确,可执行下列命令

1
2
[root@localhost~]# dnsmasq --test
dnsmasq: syntax check OK.

DNS缓存设置

要在单台电脑上以守护进程方式启动dnsmasq做DNS缓存服务器,编辑/etc/dnsmasq.conf,添加监听地址:

1
listen-address=127.0.0.1

如果用此主机为局域网提供默认DNS,请为该主机绑定固定IP地址,设置

1
listen-address=192.168.x.x

多个IP地址设置:

1
listen-address=127.0.0.1, 192.168.x.x

三个以上域名服务器

linux处理DNS请求时有个限制,在resolv.conf中最多只能配置三个域名服务器(nameserver)。作为一种变通方法,可以在resolv.conf文件中只保留localhost作为域名服务器,然后为外部域名服务器另外创建resolv-file文件。首先,为dnsmasq新建一个域名解析文件:

1
2
3
4
[root@localhost~]# vim /etc/resolv.dnsmasq.conf
# Google's nameservers, for example
nameserver 8.8.8.8
nameserver 8.8.4.4

然后编辑/etc/dnsmasq.conf让dnsmasq使用新创建的域名解析文件:

1
2
3
[root@localhost~]# vim /etc/dnsmasq.conf
...
resolv-file=/etc/resolv.dnsmasq.conf

使用dhcpcd

dhcpcd可以通过创建(或编辑)/etc/resolv.conf.head文件或/etc/resolv.conf.tail文件来指定dns服务器,使/etc/resolv.conf不会被每次都被dhcpcd重写。
echo "nameserver 127.0.0.1" > /etc/resolv.conf.head 设置dns服务器为127.0.0.1

使用dhclient

要使用dhclient,取消/etc/dhclient.conf文件中如下行的注释:
prepend domain-name-servers 127.0.0.1;

使用NetworkManager

NetworkManager可以靠自身配置文件的设置项启动dnsmasq。在NetworkManager.conf文件的[main]节段添加dns=dnsmasq配置语句,然后禁用由systemd启动的dnsmasq.service:

1
2
3
4
[root@localhost ~]# vim /etc/NetworkManager/NetworkManager.conf
[main]
plugins=keyfile
dns=dnsmasq

可以在/etc/NetworkManager/dnsmasq.d/目录下为dnsmasq创建自定义配置文件。例如,调整DNS缓存大小(保存在内存中):

1
2
[root@localhost~]# vim /etc/NetworkManager/dnsmasq.d/cache
cache-size=1000

dnsmasq 被 NetworkManager 启动后,此目录下配置文件中的配置将取代默认配置。

IPv6

启用 dnsmasq 在 NetworkManager 可能会中断仅持IPv6的DNS查询 (例如 dig -6 [hostname]) 否则将工作。 为了解决这个问题,创建以下文件将配置 dnsmasq 总是监听IPv6的loopback:

1
2
[root@localhost ~]# vim /etc/NetworkManager/dnsmasq.d/ipv6_listen.conf
listen-address=::1

此外, dnsmasq不优先考虑上游IPv6的DNS。不幸的是NetworkManager已不这样做 (Ubuntu Bug)。 一种解决方法是将禁用IPv4 DNS的NetworkManager的配置,假设存在。

其他方式

另一种选择是在NetworkManagers“设置(通常通过右键单击小程序)和手动输入设置。设置将取决于前端中使用的类型;这个过程通常涉及右击小程序,编辑(或创建)一个配置文件,然后选择DHCP类型为“自动(指定地址)。”DNS地址将需要输入,通常以这种形式:127.0.0.1, DNS-server-one, ….

DHCP服务器设置

dnsmasq默认关闭DHCP功能,如果该主机需要为局域网中的其他设备提供IP和中由,应该对dnsmasq配置文件(/etc/dnsmasq.conf)必要的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost~]# vim /etc/dnsmasq.conf
# Only listen to routers' LAN NIC. Doning so opens up tcp/udp port 53 to
# localhost and udp port 67 to world:

interface=<LAN-NIC>
# dnsmasq will open tcp/upd port 53 and udp port 67 to world to help with
# dynamic interfaces (assigning dynamic ips). Dnsmasq will discard world
# requests to them, but the parranoid might like to close them and let the
# kernel handle them:
bind-interfaces

# Dynamic range of IPs to make available to LAN pc
dhcp-range=192.168.111.50,192.168.111.100,12h

# if you'd like to have dnsmasq assign static IPs, bind the LAN computer's
# NIC MAC address:
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.111.50

查看租约

1
[root@localhost~]# cat /var/lib/misc/dnsmasq.leases

添加自定义域

它可以将一个自定义域添加到主机中的(本地)网络:

1
2
local=/home.lan/
domain=home.lan

启动守护进程

设置开机启动:

1
[root@localhost~]# systemctl enable dnsmasq

立即启动dnsmasq:

1
[root@localhost~]# systemctl start dnsmasq

需要重启网络服务以使DHCP客户端重建一个新的/etc/resolv.conf,查看dnsmasq是否启动正常,查看系统日志:

1
[root@localhost~]# joumalctl -u d

dnsmasq的配置文件/etc/dnsmasq.conf详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
# 不加载本地的/etc/hosts文件
#no-hosts
# 添加读取额外的hosts文件路径,可以多次指定。如果指定为目录,则读取目录中的所有文件。
#addn-hosts=/etc/dnsmasq.hosts.d
# 读取目录中的所有文件,文件更新将自动读取
#hostsdir=/etc/dnsmasq.hosts.d
# 例如,/etc/hosts中的os01将扩展成os01.example.com
#expand-hosts

# 缓存时间设置,一般不需要设置
# 本地hosts文件的缓存时间,通常不要求缓存本地,这样更改hosts文件后就即时生效
#local-ttl=3600
# 同local-ttl仅影响DHCP租约
#dhcp-ttl=<time>
# 对于上游返回的值没有ttl时,dnsmasq给一个默认的ttl,一般不需要设置
#neg-ttl=<time>
# 指定返回给客户端的ttl时间,一般不需要设置
#max-ttl=<time>
# 设置在缓存中的条目的最大TTL
#max-cache-ttl=<time>
# 不需要设置,除非你知道你在做什么
#min-cache-ttl=<time>
# 一般不需要设置
#auth-ttl=<time>

# 记录dns查询日志,如果指定log-queries=extra那么在每行开始处都有额外的日志信息
#log-queries
# 设置日志记录器,'-'为stderr,也可以是文件路径。默认为:DAEMON,调试时使用LOCAL0
#log-facility=<facility>
#log-facility=/var/log/dnsmasq/dnsmasq.log
# 异步log,缓解阻塞,提高性能。默认为5,最大100
#log-async[=<lines>]
#log-async=50

#指定用户和组
#user=nobody
#group=nobody

# 指定DNS的端口,默认53,设置port=0将完全禁用DNS功能,仅使用DHCP/TFTP
#port=53
# 指定EDNS.0 UDP包的最大尺寸,默认是随机端口,指定后降低安全性、加快速度、减少资源消耗
# 设置为'0'由操作系统分配。
#query-port=53535
# 指定向上游查询的UDP的端口范围,方便防火墙设置。
#min-port=<port>
#max-port=<port>
# 指定接口,指定后同时附加lo接口,可以使用'*'通配符
# 不能使用接口别名(例好:“eth1:0”),请用listen-address选项替代
#interface=wlp2s0
# 指定排除的接口,排除优先级高,可以使用“*”通配符
#except-interface=
# 仅接受同一子网的DNS请求。
# 仅在未指定interface、excet-interface、listen-address或者auth-server时有效
#local-service
# 指定不提供DHCP或TFTP服务的接口,仅提供DNS服务。
#no-dhcp-interface=enp3s0
# 指定IP地址,可以多次指定
# interface选项和listen-address选项可以同时使用。
# 下面两行与指定interface选项的作用类似。
listen-address=192.168.10.17
#listen-address=127.0.0.1
# 通常情况下即使设置了interface选项(例如:interface=wlp2s0)
# 将仍然绑定到通配符地址(例如:*:53)
# 开启此项将仅监听指定的接口
# 适用于在同一主机的不同接口或IP地址上运行多个dns服务器
bind-interfaces
# 对于新添加的接口不进行绑定。仅linux系统支持,其他系统等同于bind-interfaces选项
#bind-dynamic

##############################################################################
# 如果 hosts 中的主机有多个 IP 地址,仅返回对应子网的 IP 地址。
localise-queries
# 如果反向查找的是私有地址例如192.168.X.X,仅从 hosts 文件查找,不再转发到上游服务器
#bogus-priv
# 对于任何被解析到此 IP 的域名,将响应 NXDOMAIN 使其解析失效,可以多次指定
# 通常用于对于访问不存在的域名,禁止其跳转到运营商的广告站点。
#bogus-nxdomain=64.94.110.11
# 忽略包含指定地址的 A 记录查询的回复。
# 例如上游有台 dns 服务器伪造 www.baidu.com 的 IP 为 1.1.1.1 并且响应速度非常快。
# 指定 ignore-address=1.1.1.1 可以忽略它的响应信息,
# 从而等待 www.baidu.com 正确的查询结果。
#ignore-address=<ipaddr>
filterwin2k

#############################################################################
# 指定 resolv-file 文件路径,默认/etc/resolv.conf
#resolv-file=/etc/resolv.conf
# 不读取 resolv-file 来确定上游服务器
#no-resolv
# 在编译时需要启用 DBus 支持。
#enable-dbus[=<service-name>]
# 严格按照resolv.conf中的顺序进行查找
#strict-order
# 向所有上游服务器发送查询,而不是一个。
all-servers
# 启用转发循环检测
#dns-loop-detect

##############################################################################
# 这项安全设置是拒绝解析包含私有 IP 地址的域名,
# 这些IP地址包括如下私有地址范围:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16。
# 其初衷是要防止类似上游DNS服务器故意将某些域名解析成特定私有内网IP而劫持用户这样的安全攻击。
# 直接在配置文件中注销 stop-dns-rebind 配置项从而禁用该功能。
# 这个方法确实可以一劳永逸的解决解析内网 IP 地址的问题,
# 但是我们也失去了这项安全保护的特性,所以在这里我不推荐这个办法。
# 使用 rebind-domain-ok 进行特定配置,顾名思义该配置项可以有选择的忽略域名的 rebind 行为
stop-dns-rebind
rebind-localhost-ok
#rebind-domain-ok=[<domain>]|[[/<domain>/[<domain>/]
rebind-domain-ok=/.test.com/
##############################################################################

# 也不要检测 /etc/resolv.conf 的变化
#no-poll
# 重启后清空缓存
clear-on-reload
# 完整的域名才向上游服务器查找,如果仅仅是主机名仅查找hosts文件
domain-needed

##############################################################################

# IP地址转换
#alias=[<old-ip>]|[<start-ip>-<end-ip>],<new-ip>[,<mask>]

##############################################################################

#local=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
#server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
server=/test.com/192.168.10.117
server=/10.168.192.in-addr.arpa/192.168.10.117
#rev-server=<ip-address>/<prefix-len>,<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
# 将任何属于 <domain> 域名解析成指定的 <ipaddr> 地址。
# 也就是将 <domain> 及其所有子域名解析成指定的 <ipaddr> IPv4 或者 IPv6 地址,通常用于屏蔽特定的域名。
# 一次只能指定一个 IPv4 或者 IPv6 地址,要同时返回 IPv4 和IPv6 地址,请多次指定 address= 选项。
# 注意: /etc/hosts 以及 DHCP 租约将覆盖此项设置。
#address=/<domain>/[domain/][<ipaddr>]
#ipset=/<domain>/[domain/]<ipset>[,<ipset>]
#mx-host=<mx name>[[,<hostname>],<preference>]
#mx-target=<hostname>
# SRV 记录
#srv-host=<_service>.<_prot>.[<domain>],[<target>[,<port>[,<priority>[,<weight>]]]]
# A, AAAA 和 PTR 记录
#host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
# TXT 记录
#txt-record=<name>[[,<text>],<text>]
# PTR 记录
#ptr-record=<name>[,<target>]
#naptr-record=<name>,<order>,<preference>,<flags>,<service>,<regexp>[,<replacement>]
# CNAME 别名记录
#cname=<cname>,<target>[,<TTL>]
#dns-rr=<name>,<RR-number>,[<hex data>]
#interface-name=<name>,<interface>[/4|/6]
#synth-domain=<domain>,<address range>[,<prefix>]
#add-mac[=base64|text]
#add-cpe-id=<string>
#add-subnet[[=[<IPv4 address>/]<IPv4 prefix length>][,[<IPv6 address>/]<IPv6 prefix length>]]
##############################################################################

# 缓存条数,默认为150条,cache-size=0 禁用缓存。
cache-size=1000
# 不缓存未知域名缓存,默认情况下dnsmasq缓存未知域名并直接返回为客户端。
no-negcache
# 指定DNS同属查询转发数量
dns-forward-max=1000

##############################################################################

#dnssec
#trust-anchor=[<class>],<domain>,<key-tag>,<algorithm>,<digest-type>,<digest>
#dnssec-check-unsigned
#dnssec-no-timecheck
#dnssec-timestamp=<path>
#proxy-dnssec
#dnssec-debug

##############################################################################

#auth-server=<domain>,<interface>|<ip-address>
#auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
#auth-zone=<domain>[,<interface name>[/6|/4][,<interface name>[/6|/4].....]]
#auth-soa=<serial>[,<hostmaster>[,<refresh>[,<retry>[,<expiry>]]]]
#auth-sec-servers=<domain>[,<domain>[,<domain>...]]
#auth-peer=<ip-address>[,<ip-address>[,<ip-address>...]]
# 启用连接跟踪,读取 Linux 入栈 DNS 查询请求的连接跟踪标记,
# 并且将上游返回的响应信息设置同样的标记。
# 用于带宽控制和防火墙部署。
# 此选项必须在编译时启用 conntrack 支持,并且内核正确配置并加载 conntrack。
# 此选项不能与 query-port 同时使用。
#conntrack

##############################################################################
#
# DHCP 选项
#
##############################################################################

# 设置 DHCP 地址池,同时启用 DHCP 功能。
# IPv4 <mode> 可指定为 static|proxy ,当 <mode> 指定为 static 时,
# 需用 dhcp-host 手动分配地址池中的 IP 地址。
# 当 <mode> 指定为 proxy 时,为指定的地址池提供 DHCP 代理。
#dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
#dhcp-range=172.16.0.2,172.16.0.250,255.255.255.0,1h
#dhcp-range=192.168.10.150,192.168.10.180,static,255.255.255.0,1h
# 根据 MAC 地址或 id 固定分配客户端的 IP 地址、主机名、租期。
# IPv4 下指定 id:* 将忽略 DHCP 客户端的 ID ,仅根据 MAC 来进行 IP 地址分配。
# 在读取 /etc/hosts 的情况,也可以根据 /etc/hosts 中的主机名分配对应 IP 地址。
# 指定 ignore 将忽略指定客户端得 DHCP 请求。
#dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
#dhcp-hostsfile=<path>
#dhcp-hostsdir=<path>
# 读取 /etc/ethers 文件 与使用 dhcp-host 的作用相同。IPv6 无效。
#read-ethers
# 指定给 DHCP 客户端的选项信息,
# 默认情况下 dnsmasq 将发送:子网掩码、广播地址、DNS 服务器地址、网关地址、域等信息。
# 指定此选项也可覆盖这些默认值并且设置其他选项值。
# 重要:可以使用 option:<option-name>或者 option号 来指定。
# <option-name> 和 option号的对应关系可使用命令:
# dnsmasq --help dhcp 以及 dnsmasq --help dhcp6 查看,这点很重要。
# 例如设置网关参数,既可以使用 dhcp-option=3,192.168.4.4 也可以使用 dhcp-option = option:router,192.168.4.4。
# 0.0.0.0 意味着当前运行 dnsmasq 的主机地址。
# 如果指定了多个 tag:<tag> 必须同时匹配才行。
# [encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],] 有待继续研究。
#dhcp-option=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],][<opt>|option:<opt-name>|option6:<opt>|option6:<opt-name>],[<value>[,<value>]]
#dhcp-option-force=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],]<opt>,[<value>[,<value>]]
#dhcp-optsfile=<path>
#dhcp-optsdir=<path>
#dhcp-option=3,1.2.3.4
#dhcp-option=option:router,1.2.3.4
#dhcp-option=option:router,192.168.10.254
#dhcp-option=option:dns-server,192.168.10.254,221.12.1.227,221.12.33.227

##############################################################################

# (IPv4 only) 禁用重用服务器名称和文件字段作为额外的 dhcp-option 选项。
# 一般情况下 dnsmasq 从 dhcp-boot 移出启动服务器和文件信息到 dhcp-option 选项中。
# 这使得在 dhcp-option 选项封包中有额外的选项空间可用,但是会使老的客户端混淆。
# 此选项将强制使用简单并安全的方式来避免此类情况。可以认为是一个兼容性选项。
#dhcp-no-override
##############################################################################

# 配置 DHCP 中继。
# <local address> 是运行 dnsmasq 的接口的 IP 地址。
# 所有在 <local address> 接口上接收到的 DHCP 请求将中继到 <server address> 指定的远程 DHCP 服务器。
# 可以多次配置此选项,使用同一个 <local address> 转发到多个不同的 <server address> 指定的远程 DHCP 服务器。
# <server address> 仅允许使用 IP 地址,不能使用域名等其他格式。
# 如果是 DHCPv6,<server address> 可以是 ALL_SERVERS 的多播地址 ff05::1:3 。
# 在这种情况下必须指定接口 <interface> ,不能使用通配符,用于直接多播到对应的 DHCP 服务器所在的接口。
# <interface> 指定了仅允许接收从 <interface> 接口的 DHCP 服务器相应信息。
#dhcp-relay=<local address>,<server address>[,<interface>]
##############################################################################

# 设置标签
#dhcp-vendorclass=set:<tag>,[enterprise:<IANA-enterprise number>,]<vendor-class>
#dhcp-userclass=set:<tag>,<user-class>
#dhcp-mac=set:<tag>,<MAC address>
#dhcp-circuitid=set:<tag>,<circuit-id>
#dhcp-remoteid=set:<tag>,<remote-id>
#dhcp-subscrid=set:<tag>,<subscriber-id>
#dhcp-match=set:<tag>,<option number>|option:<option name>|vi-encap:<enterprise>[,<value>]
#tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]]
#dhcp-proxy[=<ip addr>]......

##############################################################################
# 不分配匹配这些 tag:<tag> 的 DHCP 请求。
#dhcp-ignore=tag:<tag>[,tag:<tag>]
#dhcp-ignore-names[=tag:<tag>[,tag:<tag>]]
#dhcp-generate-names=tag:<tag>[,tag:<tag>]
# IPv4 only 使用广播与匹配 tag:<tag> 的客户端通信。一般用于兼容老的 BOOT 客户端。
#dhcp-broadcast[=tag:<tag>[,tag:<tag>]]

##############################################################################
# IPv4 only 设置 DHCP 服务器返回的 BOOTP 选项,
# <servername> <server address> 可选,
# 如果未设置服务器名称将设为空,服务器地址设为 dnsmasq 的 IP 地址。
# 如果指定了多个 tag:<tag> 必须同时匹配才行。
# 如果指定 <tftp_servername> 将按照 /etc/hosts 中对应的 IP 地址进行轮询负载均衡。
#dhcp-boot=[tag:<tag>,]<filename>,[<servername>[,<server address>|<tftp_servername>]]
# 根据不同的类型使用不同的选项。
# 使用示例:
# dhcp-match=set:EFI_x86-64,option:client-arch,9
# dhcp-boot=tag:EFI_x86-64,uefi/grubx64.efi
# #dhcp-match=set:EFI_Xscale,option:client-arch,8
# #dhcp-boot=tag:EFI_Xscale,uefi/grubx64.efi
# #dhcp-match=set:EFI_BC,option:client-arch,7
# #dhcp-boot=tag:EFI_BC,uefi/grubx64.efi
# #dhcp-match=set:EFI_IA32,option:client-arch,6
# #dhcp-boot=tag:EFI_IA32,uefi/grubx64.efi
# #dhcp-match=set:Intel_Lean_Client,option:client-arch,5
# #dhcp-boot=tag:Intel_Lean_Client,uefi/grubx64.efi
# #dhcp-match=set:Arc_x86,option:client-arch,4
# #dhcp-boot=tag:Arc_x86,uefi/grubx64.efi
# #dhcp-match=set:DEC_Alpha,option:client-arch,3
# #dhcp-boot=tag:DEC_Alpha,uefi/grubx64.efi
# #dhcp-match=set:EFI_Itanium,option:client-arch,2
# #dhcp-boot=tag:EFI_Itanium,uefi/grubx64.efi
# #dhcp-match=set:NEC/PC98,option:client-arch,1
# #dhcp-boot=tag:NEC/PC98,uefi/grubx64.efi
# dhcp-match=set:Intel_x86PC,option:client-arch,0
# dhcp-boot=tag:Intel_x86PC,pxelinux.0
##############################################################################

# DHCP 使用客户端的 MAC 地址的哈希值为客户端分配 IP 地址,
# 通常情况下即使客户端使自己的租约到期,客户端的 IP 地址仍将长期保持稳定。
# 在默认模式下,IP 地址是随机分配的。
# 启用 dhcp-sequential-ip 选项将按顺序分配 IP 地址。
# 在顺序分配模式下,客户端使租约到期更像是仅仅移动一下 IP 地址。
# 在通常情况下不建议使用这种方式。
#dhcp-sequential-ip

##############################################################################
# 多数情况下我们使用 PXE,只是简单的允许 PXE 客户端获取 IP 地址,
# 然后 PXE 客户端下载 dhcp-boot 选项指定的文件并执行,也就是 BOOTP 的方式。
# 然而在有适当配置的 DHCP 服务器支持的情况下,PXE 系统能够实现更复杂的功能。
# pxe-service 选项可指定 PXE 环境的启动菜单。
# 为不同的类型系统设定不同的启动菜单,并且覆盖 dhcp-boot 选项。
# <CSA> 为客户端系统类型:x86PC, PC98, IA64_EFI, Alpha, Arc_x86, Intel_Lean_Client,
# IA32_EFI, X86-64_EFI, Xscale_EFI, BC_EFI, ARM32_EFI 和 ARM64_EFI,其他类型可能为一个整数。
# <basename> 引导 PXE 客户端使用 tftp 从 <server address> 或者 <server_name> 下载文件。
# 注意:"layer" 后缀 (通常是 ".0") 由 PXE 提供,也就是 PXE 客户端默认在文件名附加 .0 后缀。
# 示例:pxe-service=x86PC, "Install Linux", pxelinux (读取 pxelinux.0 文件并执行)
# pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4(不适用于老的PXE)
# <bootservicetype> 整数,PXE 客户端将通过广播或者通过 <server address>
# 或者 <server_name> 搜索对应类型的适合的启动服务。。
# 示例:pxe-service=x86PC, "Install windows from RIS server", 1
# pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4
# 未指定 <basename>、<bootservicetype> 或者 <bootservicetype> 为 “0”,将从本地启动。
# 示例:pxe-service=x86PC, "Boot from local disk"
# pxe-service=x86PC, "Boot from local disk", 0
# 如果指定 <server_name> 将按照 /etc/hosts 中对应的 IP 地址进行轮询负载均衡。
#pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>|<server_name>]
# 在 PXE 启动后弹出提示,<prompt> 为提示内容,<timeout> 为超时时间,为 0 则立即执行。
# 如果未指定此选项,在有多个启动选项的情况下等待用户选择,不会超时。
#pxe-prompt=[tag:<tag>,]<prompt>[,<timeout>]
# 根据不同的类型使用不同的菜单,使用示例:
# #pxe-prompt="What system shall I netboot?", 120
# # or with timeout before first available action is taken:
# pxe-prompt="Press F8 or Enter key for menu.", 60
# pxe-service=x86PC, "Now in x86PC (BIOS mode), boot from local", 0
# pxe-service=x86PC, "Now in x86PC (BIOS mode)", pxelinux
# pxe-service=PC98, "Now in PC98 mode", PC98
# pxe-service=IA64_EFI, "Now in IA64_EFI mode", IA64_EFI
# pxe-service=Alpha, "Now in Alpha mode", Alpha
# pxe-service=Arc_x86, "Now in Arc_x86 mode", Arc_x86
# pxe-service=Intel_Lean_Client, "Now in Intel_Lean_Client mode", Intel_Lean_Client
# pxe-service=IA32_EFI, "Now in IA32_EFI mode", IA32_EFI
# pxe-service=X86-64_EFI, "Now in X86-64_EFI (UEFI mode), boot from local", 0
# pxe-service=X86-64_EFI, "Now in X86-64_EFI (UEFI mode)", grub/grub-x86_64.efi
# pxe-service=Xscale_EFI, "Now in Xscale_EFI mode", Xscale_EFI
# pxe-service=BC_EFI, "Now in BC_EFI mode", BC_EFI
# # CentOS7 系统不支持下列两个选项
# #pxe-service=ARM32_EFI,"Now in ARM32_EFI mode",ARM32_EFI
# #pxe-service=ARM64_EFI,"Now in ARM64_EFI mode",ARM64_EFI

##############################################################################
# 默认为150,即最多分配150个ip地址出去,最大1000个ip
#dhcp-lease-max=150
# (IPv4 only) 指定DHCP端口,默认为67和68。如果不指定则为1067和1068,单指定一个,第二个加1
#dhcp-alternate-port[=<server port>[,<client port>]]
# 谨慎使用此选项,避免 IP 地址浪费。(IPv4 only) 允许动态分配 IP 地址给 BOOTP 客户端。
# 注意:BOOTP 客户端获取的 IP 地址是永久的,将无法再次分配给其他客户端。
#bootp-dynamic[=<network-id>[,<network-id>]]
# 谨慎使用此选项。
# 默认情况下 DHCP 服务器使用 ping 的方式进行确保 IP 未被使用的情况下将 IP 地址分配出去。
# 启用此选项将不使用 ping 进行确认。
#no-ping

##############################################################################
# 记录额外的 dhcp 日志,记录所有发送给 DHCP 客户端的选项(option)以及标签(tag)信息
#log-dhcp
# 禁止记录日常操作日志,错误日志仍然记录。启用 log-dhcp 将覆盖下列选项。
#quiet-dhcp
#quiet-dhcp6
#quiet-ra
# 修改 DHCP 默认租约文件路径,默认情况下无需修改
#dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases
# (IPv6 only)
#dhcp-duid=<enterprise-id>,<uid>

##############################################################################
#dhcp-script=<path>
#dhcp-luascript=<path>
#dhcp-scriptuser=root
#script-arp
#leasefile-ro
#bridge-interface=<interface>,<alias>[,<alias>]

##############################################################################
# 给 DHCP 服务器指定 domain 域名信息,也可以给对应的 IP 地址池指定域名。
# 直接指定域名
# 示例:domain=thekelleys.org.uk
# 子网对应的域名
# 示例:domain=wireless.thekelleys.org.uk,192.168.2.0/24
# ip范围对应的域名
# 示例:domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200
#domain=<domain>[,<address range>[,local]]
# 在默认情况下 dnsmasq 插入普通的客户端主机名到 DNS 中。
# 在这种情况下主机名必须唯一,即使两个客户端具有不同的域名后缀。
# 如果第二个客户端使用了相同的主机名,DNS 查询将自动更新为第二个客户端的 IP 地址。
# 如果设置了 dhcp-fqdn 选项,普通的主机名将不再插入到 DNS 中去,
# 仅允许合格的具有域名后缀的主机名插入到 DNS 服务器中。
# 指定此选项需同时指定不含 <address range> 地址范围的 domain 选项。
#dhcp-fqdn
# 通常情况下分配 DHCP 租约后,dnsmasq 设置 FQDN 选项告诉客户端不要尝试 DDNS 更新主机名与 IP 地址。
# 这是因为 name-IP 已自动添加到 dnsmasq 的 DNS 视图中的。
# 设置此选项将允许客户端 DDNS 更新,
# 在 windows 下允许客户端更新 windows AD 服务器是非常有用的。
# 参看 RFC 4702 。
#dhcp-client-update
#enable-ra
#ra-param=<interface>,[high|low],[[<ra-interval>],<router lifetime>]

##############################################################################
#
# TFTP 选项
#
##############################################################################

# 对于绝大多数的配置,仅需指定 enable-tftp 和 tftp-root 选项即可。
# 是否启用内置的 tftp 服务器,可以指定多个逗号分隔的网络接口
#enable-tftp[=<interface>[,<interface>]]
#enable-tftp
#enable-tftp=enp3s0,lo
# 指定 tftp 的根目录,也就是寻找传输文件时使用的相对路径,可以附加接口,
#tftp-root=<directory>[,<interface>]
#tftp-root=/var/lib/tftpboot/
# 如果取消注释,那么即使指定的 tftp-root 无法访问,仍然启动 tftp 服务。
#tftp-no-fail
# 附加客户端的 IP 地址作为文件路径。此选项仅在正确设置了 tftp-root 的情况下可用,
# 示例:如果 tftp-root=/tftp,客户端为 192.168.1.15 请求 myfile.txt 文件时,
# 将优先请求 /tftp/192.168.1.15/myfile.txt 文件, 其次是 /tftp/myfile.txt 文件。
# 感觉没什么用。
#tftp-unique-root
# 启用安全模式,启用此选项,仅允许 tftp 进程访问属主为自己的文件。
# 不启用此选项,允许访问所有 tftp 进程属主可读取的文件。
# 如果 dnsmasq 是以 root 用户运行,tftp-secure 选项将允许访问全局可读的文件。
# 一般情况下不推荐以 root 用户运行 dnsmasq。
# 在指定了 tftp-root 的情况下并不是很重要。
#tftp-secure
# 将所有文件请求转换为小写。对于 Windows 客户端来说非常有用,建议开启此项。
# 注意:dnsmasq 的 TFTP 服务器总是将文件路径中的“\”转换为“/”。
#tftp-lowercase
# 允许最大的连接数,默认为 50 。
# 如果将连接数设置的很大,需注意每个进程的最大文件描述符限制,详见文档手册。
#tftp-max=<connections>
#tftp-max=50
# 设置传输时的 MTU 值,建议不设置或按需设置。
# 如果设定的值大于网络接口的 MTU 值,将按照网络接口的 MTU 值自动分片传输(不推荐)。
#tftp-mtu=<mtu size>
# 停止 tftp 服务器与客户端协商 "blocksize" 选项。启用后,防止一些古怪的客户端出问题。
#tftp-no-blocksize
# 指定 tftp 的连接端口的范围,方便防火墙部署。
# tftp 侦听在 69/udp ,连接端口默认是由系统自动分配的,
# 非 root 用户运行时指定的连接端口号需大于 1025 最大 65535。
#tftp-port-range=<start>,<end>

###############################################################################

#conf-dir=<directory>[,<file-extension>......]
#conf-file=/etc/dnsmasq.more.conf
conf-dir=/etc/dnsmasq.d
#servers-file=<file>