nftables 上手小记

February 27, 2019
Servers

Internet 可不是个平静的地方。

最开始体会到是 22 端口被爆破。

后来是自建 DNS 之后经常造访的 Scanner 和没事儿喜欢爆破别人 53 端口的家伙。

22 端口好说,用密钥登陆,禁止 root 登陆,禁止密码登陆,基本就能高枕无忧。闲的蛋疼还可以扔个 honeypot,比如这位仁兄 What I Learned After Using an SSH Honeypot for 7 Days

DNS 这个着实让我犯了难。设置防火墙是最好的选择。但是如何不把自己人给防了是个问题。

nft 初步接触

照理说,主流的防火墙应该是 iptables。

不过我看 Wiki 说 nftables 是用来取代 iptables 的,blabla。。。那就 nftables 吧。

看 nftables 官方的 Wiki 还真是有点儿头大。当初刚接触 Linux 就觉得防火墙好复杂,往后的实践,能避开这玩意儿都避开了。

不过好在有样例,有样例就能照猫画虎。

https://wiki.gentoo.org/wiki/Nftables/Examples

https://wiki.archlinux.org/index.php/Nftables#Examples

那么针对海外的自用鸡 /etc/nftables.conf:

flush ruleset

table ip filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        ct state invalid drop
        iifname lo accept
        iifname != lo ip daddr 127.0.0.1/8 drop
        ip protocol icmp accept
        tcp dport { 22, 80, 443, 8443, 8080, xxxxx, xxxxx, xxxxx, xxxxx } ct state new accept
        udp dport {xxxxx, xxxxx, 80, 443, 8443, 8080, xxxxx } accept 
        ip saddr {X.X.X.X/24, A.B.C.D} udp dport 53 accept
        ip saddr {X.X.X.X/24, A.B.C.D} tcp dport 53 accept
        #reject with icmpx type port-unreachable
    }
}

input 链中从上往下

BTW,套路云的话,据说在合适的位置插一行可以有效屏蔽安骑士

ip saddr { 140.205.201.0-140.205.201.23, 140.205.201.32/28, 140.205.225.183-140.205.225.206} drop

插在哪一行就看需求了。

关于 ct state established,related accept 这行。。。

由于有 ct state new accept 所以没这行那就是真的把自己防外面了。。。

即便没有 ct state new accept ,也会导致无法从本机发起网络连接,因为别人响应的进来的包都被扔掉了

以及这个配置文件的格式要求太严格了,tab space 混用会报错,最后没留一个空行也会报错。。

进阶

不得不说,照葫芦画瓢,照猫画虎真的是不错的方案。。。

DNS 不止我一个人在用,而且我也嫌麻烦,所以 Port Knocker 这种方案肯定 pass。

由于 DNS 的服务器为了根除国内厂商插的流氓插件,给换了系统,跑的是 Arch,还和 Ubuntu 有点不一样。

具体参考之前的文章。

然后需要开启 daemon。

sudo systemctl enable cronie
sudo systemctl start cronie

嗯。。然后呢。。。我自个儿魔改了从网上扣来的一个 Perl 脚本。。。这个脚本是以前找来做透明代理的,结果出处找不到了。。。

命名为 dns.pl 扔在 /opt 目录下

#!/usr/bin/perl -w
use strict;

# curl http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | perl /opt/dns.pl > /etc/nftables.conf && nft -f /etc/nftables.conf

my @noss = (                        # 不需要重定向的预定义地址,
    "127.0.0.0/8",
    "10.0.0.0/8",
    "172.16.0.0/12",
    "192.168.0.0/16",
    "169.254.0.0/16",
    "224.0.0.0/4",
    "240.0.0.0/4",
);

my %prefixlen;
foreach (1..31) {
    $prefixlen{2**$_} = 32-$_;
}

while(<>) {                         # 从 apnic 下载地址信息处理下
    chomp;
    next unless /^apnic\|CN\|ipv4/;
    my @ent = split /\|/;
    push @noss, sprintf "%s/%s", $ent[3], $prefixlen{$ent[4]};
}

my $result = <<__NFT;
flush ruleset

table ip dns {
    chain autopilot {
        type filter hook input priority 0;
        ct state invalid drop
        ip saddr != { NOSS_ADDRESSES } udp dport 53 drop
        ip saddr != { ANOSS_ADDRESSES } tcp dport 53 drop
    }
}
__NFT

my $noss_addresses = join ", ", @noss;
$result =~ s/NOSS_ADDRESSES/$noss_addresses/;

my $anoss_addresses = join ", ", @noss;
$result =~ s/ANOSS_ADDRESSES/$anoss_addresses/;

print $result;

BTW,Arch 自带的 kernel 不包含 nftables 的模块。需要手动切换到 LTS kernel

运行

/usr/bin/curl http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | /usr/bin/perl /opt/dns.pl > /etc/nftables.conf && /usr/bin/nft -f /etc/nftables.conf

就可以以中国 IP 为白名单放行,拦截所有国外 IP 的请求。

哦对了,上面那行命令加进 crontab 应该可以跑,我设置了一个,明天应该就知道有没有成功了,懒得接着费劲儿测试了。 跑通了。

后记

开年后学校的网络出口正式变成了电信通(鹏博士长城宽带)AS17964AS17816AS4847

至此,学校网络完成了 纯教育网 -> 不知名的国内电信国外联通的三级运营商 -> 鹏博士长宽 的转变。

也由于使用自己的 DNS,收到了大量的来自国内的 Scanner 的造访。估计是运营商干的。

最让人在意的,莫过于一条 p*rnhub 的查询。当然,他得到了正确的结果。

至于为啥说是运营商,因为 IP 是 AS17816 的。。。高精度查询为 中国北京北京海淀区电信科学技术研究院(高校学院)

属专线出口类型,非 IDC 段。。。

学生日益增长的上网需求与学校的荷包之间冲突不小啊

后记2

前一阵子有一个自称腾讯云的人给我打了个电话。由于直接道出我大名,所以应该是真的。

称 53 端口的域名解析业务需要备案,备案需要企业资质。

所以,这些东西就没有后续啦 ~。。。

TLS Certificate and Public Key Pinning

November 27, 2019
Servers

自力更生的 Seedbox 指南

September 22, 2019
Servers

使用 Cron 设置定时任务

当初还是小白的时候看这个好高端的
Servers
comments powered by Disqus.
Can't load? Check your connectivity and try again.