Ubuntu 2004打Patch实现FullCone Nat

于 2021-04-03 发布

参考:Centos 7当网关启用Fullcone nat

安装kernel header

对于Ubuntu来说就是linux-headers-generic。如果内核不是linux-generic,根据uname -ar的内容确定自己要安装哪个header。

安装编译依赖

安装一些必备工具,包括但不限于autoconf、libmnl-devel、libtool。如果报错PKG_CHECK_MODULES syntax error,还要装pkgconf。

编译libnftnl

别以为官方库里面有libntfnl-dev就能用,一样炸,就是报PKG_CHECK_MODULES syntax error

1
2
3
4
5
6
7
cd /usr/src
git clone git://git.netfilter.org/libnftnl.git
cd libnftnl
./autogen.sh
./configure
make
make install

编译netfilter-full-cone-nat模块

得到xt_FULLCONENAT.ko

1
2
3
4
cd /usr/src
git clone https://github.com/Chion82/netfilter-full-cone-nat.git
cd netfilter-full-cone-nat
make

可以选择此时载入模块,但是要先手动加载nf_nat

1
2
modprobe nf_nat
insmod xt_FULLCONENAT.ko

编译iptables

编译支持FULLCONE的iptables(这里将prefix写到/usr,是准备完全替换系统的iptables。所以别急着install,先把系统的iptables给卸了):

1
2
3
4
5
6
7
8
9
cd /usr/src
git clone  git://git.netfilter.org/iptables.git
cd iptables
cp ../netfilter-full-cone-nat/libipt_FULLCONENAT.c extensions
./autogen.sh
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
./configure --prefix=/usr
make

卸载自带的iptables:

1
sudo apt remove iptables

注意,在Ubuntu上这会卸掉ubuntu-standard,导致autoremove不再可靠,小心别乱用apt autoremove

之后就可以make install安装了。

补上基本的iptables规则

这是开机完成、After=network.target之后才能restore的规则,如果需要开机时、Before=network.target就封锁Input的话,要新建另外配置一个规则文件并另外配置一个systemd-unit来实现。

在for循环那一行里,可以把其他比如ssh端口添加到括号里,用逗号分隔开,就可以开放这些端口了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
iptables -P INPUT   DROP
iptables -P OUTPUT  ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
for i in {80,443};do
iptables -A INPUT -p tcp --dport $i -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport $i -m conntrack --ctstate ESTABLISHED -j ACCEPT
done

iptables -A INPUT  --match state --state ESTABLISHED,RELATED --jump ACCEPT
iptables -A OUTPUT --match state --state ESTABLISHED,RELATED --jump ACCEPT

iptables -A INPUT  --proto udp --sport 53 --jump ACCEPT

搞定之后,首先新建文件夹/etc/iptables,然后保存到文件:

1
2
mkdir -p /etc/iptables
iptables-store > /etc/iptables/rules.v4

开机自动恢复规则

编写一个systemd服务文件,让规则可以在开机时自动载入。根据archlinux的iptables.service,新建一个文件/etc/systemd/system/iptables.service,内容如下:

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Packet Filtering Framework
After=network.service
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
ExecReload=/sbin/iptables-restore /etc/iptables/rules.v4
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

然后启用它:systemctl enable iptables.service

可以检查一下是否成功:systemctl status iptables.service

注意,不需要使用命令行restore时的”<”,直接指定规则文件名字,iptables-restore就会载入它。

开机自动载入FULLCONNAT模块

首先更改/etc/modules文件,添加一行xt_FULLCONNAT

1
echo 'xt_FULLCONENAT' >> /etc/modules

将ko文件复制到内核模块文件目录,比如放在net目录下,然后运行depmod分析模块依赖(一般不会有输出内容):

1
2
cp /usr/src/netfilter-full-cone-nat/xt_FULLCONENAT.ko /lib/modules/`uname -r`/kernel/drivers/net
depmod

随后就可以reboot一下,启动之后通过lsmod | grep 'xt_FULLCONENAT'来确定是否加载了模块。

添加FULLCONE规则

假设对外网卡是eth0:

1
2
iptables -t nat -A POSTROUTING -o eth0 -j FULLCONENAT
iptables -t nat -A PREROUTING -i eth0 -j FULLCONENAT

如果需要开机应用这条规则,那就仿照上边iptables-store一下。

目录