写在开始
使用Hyper-V的时候他会自动分配一个Default Switch
这么一个网卡用于NAT, 然而这个网卡的ip似乎每次重启都会自动更换, 所以这个就挺令人烦恼了, 毕竟如果Hyper-V虚拟机里面是一堆linux的话那每次都是自动更换ip的, 连接起来还是很麻烦的。 所以我打算在内网给解决掉这个问题, 把IP地址至少可以接近静态的, 之前那个连IP段都要变确实有点受不了。
技术选型
其实这个可以直接在虚拟机里跑一个OpenWRT之类的东西的, 但是鉴于我有一个这样子的虚拟机, 而且还被我莫名其妙搞坏了, 这次我就手动搭建一个路由器系统了。
至于选哪个系统, Linux用的比FreeBSD之类的熟悉一点, Windows太占资源。 然后基于节约资源的角度考虑, 我用了 Alpine Linux。 毕竟这个系统的体积小。 而且这个系统我在玩Docker镜像的时候经常用, 所以也不算陌生。
其他的东西也就是用vagrant来操作hyper-v了, 这样子会简单点。
那开始吧
下载 Alpine Linux 的 Box
先去找找有没有现成的Vagrant的Box, 然后我发现了这个Box, 这个Alpine Linux的Box支持Hyper-V的版本。 所以就用这个了。
那首先随便找个目录, 然后输入
vagrant init generic/alpine310
sudo vagrant up --provider=hyperv
因为不是用管理员打开的这个终端, 然后如果操作Hyper-V的虚拟机的话需要管理员权限, 所以需要提权。 这里推荐一下这个人的sudo脚本。 感觉还是挺好用的。
顺便一提, vagrant是用curl来下载box的。
Hyper-V部分的设置
在vagrant下载box的这一会去设置一下Hyper-V那边的东西。
打开Hyper-V管理器, 在右侧找到虚拟交换机管理器
点开之后创建一个内部的交换机
名称随意, 注意是要设置成内部网络, 就像这样
然后点确定就好。
Vagrant Box 下载完成后
vagrant up
执行过程中会打印出类似以下的输出
这个时候选择 Default Switch就好然后接下来会出来一堆输出, 其实也不用在意是啥。
然后sudo vagrant halt
关闭这个虚拟机, 接下来往里面添加一个给内网用户使用的网卡。
首先要在Hyper-V控制台里面找到这个虚拟机, 然后点击它, 右边会出来一排按钮
选择设置。 然后选择添加硬件
里面有一个网络适配器, 点击之后选择添加。
然后选择之前创建的那个内部网络。
选择完成之后大概长这个样子
然后点击确定, 回到这里
点击启动重启开机。
接下来就sudo vagrant ssh
进入这个虚拟机里操作就好。
构建一个简易的软路由器的基本思路
首先要有一个DHCP服务器给内网设备分配IP用, 然后要有一个DNS服务器给内网设备提供DNS服务, 最重要的还要有一个NAT和转发来让内网设备可以通过NAT来连接到外部网络, 然后还需要能够回来。 这样子一个路由器就完成了。
那么我们一步一步做就好
软路由构成的基本选型
使用Dnsmasq来给内网设备提供DHCP和DNS, 然后用iptables创建一个NAT和处理请求转发。
曾经还考虑过使用AdGuardHome来提供DHCP和DNS服务来着, 奈何它的DHCP看起来不工作的样子, 也很不稳定的样子, 所以我就抛弃了这个选择。
那么就进入软路由里进行操作吧
毕竟是个国外的Box, 所以自带的软件源自然不会很快, 这里换成中科大的源。
首先看一下这个源是啥
cat /etc/apk/repositories
然后他输出了
https://dl-4.alpinelinux.org/alpine/v3.10/main
https://dl-4.alpinelinux.org/alpine/v3.10/community
中科大官方提供的一键脚本是这样的
sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
这样子很明显不能成功替换, 所以要修改成这样子
sudo sed -i 's/dl-4.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
替换完成之后执行
sudo apk update
更新完成之后就可以准备安装软件了。
需要安装的软件
因为这个Box非常精简, 精简到连iptables都没有, 所以要装这些东西:
- dnsmasq
- iptables
- ip6tables
那么就一条命令加上去吧
sudo apk add dnsmasq iptables ip6tables
Dnsmasq 配置
接下来配置一下Dnsmasq。 在这之前先确认一下自己的网卡
ip addr
然后输出了三个网卡, 一个是lo, 一个是eth0, 一个是eth1。
eth0是走了Default Swtich的, 算是路由器的WAN口, eth1是走了内部网络的, 算是路由器的LAN口, 确定了这个之后开始配置Dnsmasq。
sudo vim /etc/dnsmasq.conf
接下来我就贴一下我改了的配置, 然后一条一条说好了。
resolv-file=/etc/resolv.conf
interface=eth1
dhcp-range=192.168.1.50,192.168.1.150,255.255.255.0,12h
dhcp-option=option:router,192.168.1.1
cache-size=500
conf-dir=/etc/dnsmasq.d/,*.conf
这些是整个dnsmasq.conf
里面使用的参数。
resolv-file
是声明了上游DNS服务器的地方, 这个我直接用了系统自动配置的DNS, 反正能上网, 所以问题不大。
interface
是声明DHCP服务器启动的接口, 这里要设置LAN口的, 所以是eth1
dhcp-range
这个就挺好懂了, 就是设置DHCP自动分配的一些设置, 第一个是起始IP, 第二个是结束IP, 第三个是子网掩码, 第四个是DHCP过期时间。
dhcp-option
这个是提供了一些别的参数, 这个是为了给下游设备提供网关的一个设置, 最后面是设置网关IP的, 我设置为192.168.1.1
, 过会我会把路由器的 LAN IP 设置为这个的。
cache-size
这个好像是DHCP缓存, 会让你缓存之前DHCP分配的历史记录, 下一次这个设备重新获取IP的时候会先走缓存找到上次的IP。 这个后面的数字随缘设置就好, 算是个可以优化的点吧。 我就随便设置了个500, 不改也可以。
conf-dir
这个默认就带着的, 会读取这个目录下面的conf文件, 来自定义配置Dnsmasq, 我也没改, 就放上去了。
配置完之后保存就好, 接下来设置LAN口的静态IP。
配置 LAN 口的静态 IP
那就直接进interface文件里加上这个接口的静态IP就好了
sudo vim /etc/network/interfaces
打开之后你会看到这样的东西
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
hostname alpine310.localdomain
然后在后面添加上
auto eth1
iface eth1 inet static
address 192.168.1.1
network 192.168.1.0
netmask 255.255.255.0
broadcast 192.168.1.255
这算是一个很经典的配置方式了吧。
address
设置这个接口的静态IP
network
这玩意其实我也不知道是啥, 但是应当是设置为这个网络的起始IP的前一个, 也就是常见的监听整个网络的那个IP。
netmask
这个是子网掩码
broadcast
这个是广播地址
这些配置完之后重启一下network服务
sudo service network restart
然后你就可以启动Dnsmasq了
sudo service dnsmasq start
接下来配置 iptables
因为只配置IPv4, 所以我就没有管IPv6的转发,
直接执行下面四条命令就可以了
sudo iptables -A FORWARD -i eth1 -s 192.168.1.0/255.255.255.0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -d 192.168.1.0/255.255.255.0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo /etc/init.d/iptables save
第一条是允许从eth1进来的来源于那个子网的连接
第二条是允许从eth0的数据到那个子网里
就是一条允许出一条允许进
第三条就是把这个挂到POSTROUTING链上
第四条是保存这个iptables记录。
这个东西多少还是有点晕。 其实我自己也说不太清楚。
所以引用一句这位老哥的话
第三条表示把数据最终的POSTROUTING定向到eth0也就是WAN口上,使用MASQUERADE转译是为了保证NAT出去的地址是固定的。
(其实好多细节也是从这里看到的, 还有这里)
然后启动开内核的IP转发, 这个版本的 Alpine Linux 有一个/etc/sysctl.d
文件夹, 里面有一个00-alpine.conf
的文件, 所以你可以仿照着这种文件格式添加一个01-router.conf
之类的文件添加上这些东西, 或者也可以直接添加到00-alpine.conf
里面, 看你的个人爱好了。
然后在那个配置文件里添加上这么一条
net.ipv4.ip_forward=1
似乎这时候sysctl -p
并不生效, 所以还是要重启一下比较好。
给这两个东西加一个开机自启
Alpine Linux 的服务管理器是OpenRC, 一个比较轻量而且经典的进程管理器。
rc-update add dnsmasq
rc-update add iptables
给自己的宿主机设置一个静态IP
这个就随缘设置一个就好, 右键托盘里的网络
打开"网络和 Internet"设置
找到里面的更改适配器选项。
然后找到内部网路右键属性
双击 Internet 协议版本 4
简单配置一下就好了, 这个时候不建议设置网关和DNS, 设置了DNS的话可能会导致系统DNS走了这个, 导致出现循环。 网关也是。
其实到这里就结束了, 但是我还需要另一个东西
接下来装一下vlmcsd, 懂得都懂, 不知道的就不用管了。
直接抄一下人家的Dockerfile其实就好, 直接在终端输入
sudo su
apk update \
&& apk upgrade \
&& apk add --no-cache build-base gcc abuild binutils cmake git \
&& cd / \
&& git clone https://github.com/Wind4/vlmcsd.git vlmgit \
&& cd vlmgit \
&& make \
&& chmod +x bin/vlmcsd \
&& mv bin/vlmcsd / \
&& cd / \
&& apk del build-base gcc abuild binutils cmake git \
&& rm -rf /vlmgit \
&& rm -rf /var/cache/apk/*
等着结束之后会在根目录下出现一个vlmcsd, 然后mv /vlmcsd /usr/local/bin/
放到一个比较正常的目录下。 配置一下service。
于是就进入/etc/init.d
里面创建一个文件, 内容大概这样子就好。
#!/sbin/openrc-run
description="vlmcsd Server"
pidfile="/run/$RC_SVCNAME.pid"
command="/usr/local/bin/vlmcsd"
command_args=" -D -d -t 3 -e -v"
command_background=true
extra_commands="checkconfig"
depend() {
need net
after firewall
}
stop() {
if [ "${RC_CMD}" = "restart" ] ; then
checkconfig || return 1
fi
ebegin "Stopping $RC_SVCNAME"
start-stop-daemon --stop --exec "$command" \
--pidfile "$pidfile" --quiet
eend $?
}
创建完成之后给他加个可执行权限
chmod +x vlmcsd
然后启动
service vlmcsd start
添加开机自启
rc-update add vlmcsd
就完工了。
写在最后
之前一直以为人工做一个软路由很麻烦来着, 结果这么操作了一下发现还是很简单的, 至少现在思路明确了, 整体来说就简单好多了。
10 comments
配置成路由倒是挺简单的,就是好像没啥比较好的去广告方案,像 KP/KPR 好像都没适配标准 Linux 发行版,只有 OP 这种路由器发行版,其它 Hosts/DNS 去广告效果又不够好。
本来路由器层面去广告效果就不好,所以我也没考虑解决,非mitm去广告跟没有似的,不过加个Adguard Home处理一下个别追踪还好。mitm去广告还得给内网每个设备加上自签名CA,也是很麻烦。不过kp都是x64的二进制,想移植过来也可以的|´・ω・)ノ
感谢文章的帮助。有缘再会
有缘再见OωO
我刚刚就是新建虚拟机交换机那里新建一个内部的虚拟网卡,在windows控制面板里设置好静态IP,然后在/etc/network=/interface 配置上eth1的静态IP,
如果你就一台机器的话这样子操作就可以了, 在物理机这边这样做相当于两个电脑用一个网线连对等机。 我当时这么做的时候是因为下面有好几台虚拟机都要这样连的。OωO
照着其中几步做好了,没看懂文章是中间用到Vagrant Box,这不是另外一个虚拟机么,看了半天没看懂
我用vagrant就是为了偷懒的, 只是我嫌用alpine自己的iso装系统麻烦点。就直接用vagrant下了个装好了的alpine linux来用罢了。 vagrant的后端可以指定是使用hyper-v的, 虽然默认是vbox吧。(ノ°ο°)ノ
巧了,我也在hyper-v里装了alpine,想固定IP,不过你这太麻烦了|´・ω・)ノ
同类型的解决方案还有一个是hyper-v开个openwrt, 有个koolshare的lede的镜像, 直接用他那个vhdx开个虚拟机就可以用, 不过我是嫌里面小问题有点多就换掉了。