打开/关闭搜索
搜索
打开/关闭菜单
54
677
62
1925
md5.pw
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
上传文件
打开/关闭外观设置菜单
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
登录
请求账号
查看“︁服务器安全-防火墙 nftables”︁的源代码
来自md5.pw
分享此页面
更多语言
查看
阅读
查看源代码
查看历史
associated-pages
页面
讨论
更多操作
←
服务器安全-防火墙 nftables
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
== 什么是防火墙 == 网络中的数据 就像在水管中运行的水 而防火墙是可以监控和控制网络流量'''进入'''和'''流出'''的一个工具 == 为什么使用防火墙 == 拦截进入系统且具有恶意的网络请求 防止他们进入系统后利用软件或内核漏洞获取服务器控制权 == 防火墙的主要功能 == * '''流量过滤:''' 根据IP地址、端口号、协议类型等标识控制网络流量的进入和流出或转发等其他行动 * '''日志记录:''' 记录网络流量进入和流出或其他的的动作以便审计和分析 == 常见的词语 == * ip地址 分为ipv4和ipv6两种 ipv4 1.1.1.1 ipv6 2606:4700:4700::11·11 用来在网上找到你的电脑手机等 * 端口号 0-65535 用ip地址+端口号 找到你的电脑或是手机上的 哪个软件 就像是 手机有软件浏览器 有聊天软件 IP是一样的比如 2.2.2.2 如果只用ip 2.2.2.2不知道是浏览器还是聊天软件 所以 用ip地址+端口号来确定 比如ip+端口号是2.2.2.2:50000 浏览器是60000 聊天软件是50000 就知道是聊天软件的信息了 * tcp协议 udp协议 流量传输的方式….传输不同就有不同的处理方式 == 进入(input)和流出(output) == 想象一下 当你用浏览器 访问某个网站时的动作 按下回车或确定的时候 你就相当于 流出 了 一个网络流量 这个 网络流量 经过多个节点 最终 进入 了 服务器 服务器处理完后把数据返回 就是流出了一个网络流量这个网络流量经过多个服务器最终进入了你的电脑或手机或者vps等 '''关键点来了:''' 这时候,这股进入的流量对于电脑或者手机或者vps来说,如果不加辨别,它就是一个“外来闯入者”。 如果你的 INPUT 规则是默认拒绝(DROP),防火墙会无情地把这个网络流量(网页内容)挡在门外——这就导致了“虽然我发出了请求,但我收不到回复” 请记住这个 后面有一条防火墙规则就是为了解决它的 == 四种防火墙工具 四选一 本文选择的是nftables == 四种防火墙工具的规则最终都会变成内核Netfilter的规则 === 近原生引擎 === * '''nftables''': 是目前 Linux 内核官方推荐的新一代数据包过滤框架。它旨在取代旧的 '''iptables''' 框架,拥有更高效的虚拟机指令集和更简洁的代码结构。 * '''iptables (Legacy)''': 是老牌的内核框架,'''nftables'''之前也就是旧版本Linux所使用的。 === 方便个人用户和初学者使用的 === * '''ufw:Ubuntu/Debian 系默认。''' * '''firewalld:RHEL/CentOS 系默认。''' == 使用防火墙的风险 == * 会把正常进入服务器的流量关在防火墙外面.比如:自己的ssh流量 或 其他的流量 * 和docker使用时 使用 清空全部防火墙 的指令 会导致docker的防火墙规则被清除 == 风险的解决办法 == * 被关在防火墙外 ** 登录搬瓦工后台使用kiwivm面板执行 清空防火墙指令(sudo nft flush ruleset)就可以不用重启恢复了 可以参考 [[搬瓦工 KiwiVM 面板 Root shell 远程终端功能详解与使用教程|https://md5.pw/index.php?title=搬瓦工_KiwiVM_面板_Root_shell_远程终端功能详解与使用教程]] ** 在没有设置开机自动运行的情况下只要重启就会失效了 ('''重启这会导致您未保存的数据丢失''') * 和docker使用时 ** 不要使用 清空全部防火墙 的指令 应改为 清空某个表 避免docker的防火墙规则被清空 ** 不慎使用 只需要systemctl restart docker 重启docker就可以让docker重新把规则写入防火墙了 == 使用防火墙前 == === 切换到拥有权限的用户 === ==== 如何检查我是不是 root? ==== 输入命令'''whoami'''如果返回不是root请务必使用sudo [[File:Whoami.png|border]] * '''如果你是直接登录的 root 账号:''' 直接输入命令即可。 * '''如果你使用的是非 root 账号(如 admin/ubuntu):''' 请在所有命令前加上 <code>sudo</code>(例如 <code>sudo nft list ruleset</code>),或者先执行 <code>sudo -i</code> 切换到 root 模式。 [[File:Testcmd1.png|border]] 输入当前用户的密码 [[File:Noper.png|border]] 提示这个说明用户没有权限 你需要切回 Root 账号,给 [用户名] (文本是haidao)授权。 '''步骤如下:''' # '''切回 Root 身份:''' 输入:<code>su -</code> (输入 Root 密码) # '''给 用户 授权(把 user 加入 sudo 组):''' 输入: 如果你是 '''Debian/Ubuntu''' 用户,请执行: <code>usermod -aG sudo [用户名]</code> 如果你是 '''CentOS/AlmaLinux''' 用户,请执行: <code>usermod -aG wheel [用户名]</code> #* <code>usermod</code>: 修改用户属性 #* <code>aG</code>: append to Group (追加到组) #* <code>sudo 或是 wheel</code>: 组名(Debian系叫 sudo,CentOS系叫 wheel) #* '''<code>用户名</code>''': 你的用户名 就是whoami 输出的那个 # '''退出 Root,回到 你自己的用户名 :''' 输入:<code>exit</code> # '''再次尝试:''' 现在你是 你自己的用户名 了,再次输入: <code>sudo nft list ruleset</code> 这次它就会让你输密码,然后成功执行了。 其他的组怎么查看<syntaxhighlight lang="bash"> grep -E '^(sudo|wheel):' /etc/group sudo:x:27: #这说明是 sudo wheel:x:10: #这说明是 wheel </syntaxhighlight> ===== '''如果输入sudo -i 显示 -bash: sudo: command not found''' ===== 说明系统提示找不到 <code>sudo</code> 命令 你可以使用传统的 '''<code>su</code> (Switch User)''' 命令临时切换回 Root 身份来操作防火墙 然后下文中就不要在指令中使用sudo 比如<code>sudo nft list ruleset</code> 就要变成 <code>nft list ruleset</code> * 输入命令:<code>su -</code>''(注意:su 后面有个空格和减号,这很重要,代表同时切换环境变量)'' * 输入 Root 密码(输入时看不见)。 * 此时你的提示符会变成 <code>#</code>,代表你又是 Root 了。 * 直接输入防火墙命令(不需要加 sudo),例如 <code>nft list ruleset</code> [[File:Su-.png|border]] ===== '''(可选)切换到root账户后 安装sudo''' ===== '''Debian / Ubuntu / Armbian 系''' <code>apt update && apt install sudo -y</code> '''Red Hat / AlmaLinux / Rocky / CentOS 系''' <code>yum install sudo -y</code> ''(注:在较新的 Red Hat 系中也可以用 <code>dnf install sudo -y</code>,效果是一样的。)'' === 检查是否安装了其他的防火墙 === 多个防火墙可能造成冲突所以要先关闭其他的防火墙..如果你正在使用其他的防火墙..关闭了的话 会导致防火墙规则失效..可能造成连接中断等问题 '''中断无法连接的话请参考上面风险的解决办法''' 输入 <code>sudo systemctl status firewalld ufw iptables nftables</code> ==== [[File:Seeallfirewall.png|border]]如果显示 -bash: systemctl: command not found ==== 就是没有安装systemctl 可能是因为系统版本老..或者不是用systemctl管理系统服务的..那么本文可能不适合你..因为防火墙指令可能有略微差距…输入ufw或者firewalld或者iptables或者nftables看看还会-bash: 你输入的名字: command not found 这样么 这样就是没有安装的意思…. '''关闭所有防火墙的持久化 如果你正在使用其他的防火墙 关闭可能造成连接中断 中断无法连接的话请参考上面风险的解决办法''' # Unit ufw.service cloud not be found 没有安装ufw的意思 # firewalld.service 前面的那个圆圈是灰色的 证明没有启动 disabled 不会开机自动启动 # iptables.service 同上 # nftables.service 绿色的圆圈正在运行 enabled 开机自动启动 输入<code>sudo systemctl stop firewalld ufw iptables nftables</code> 关闭所有的防火墙 输出这个 没关系..失败停止ufw.service 因为它没安装 不会影响其他的 [[File:Stopallfirewall.png|border]] 如果Failed to stop nftables.service:Unit nftables.service not loaded也这样的话那就是nftables没有安装 '''如果此时后悔不想弄了.重新启动就可以了 因为没有改变它的 开机设定就是 disable和enabled 就是图片中蓝色圆圈的地方 <code>sudo systemctl stop firewalld ufw iptables nftables</code> 这个指令只是暂时关闭了''' '''重新启动后 它会回到原本的设定(这里指 防火墙的设定,不包括上面用户的设定)''' === 如果没有安装nftables === '''Debian / Ubuntu 系统'''<syntaxhighlight lang="bash"> # 更新软件源 sudo apt update #安装 nftables sudo apt install nftables -y </syntaxhighlight>'''CentOS / AlmaLinux / Rocky Linux 系统'''<syntaxhighlight lang="bash"> # CentOS 7 使用 yum sudo yum install nftables -y </syntaxhighlight>'''CentOS 8/9, AlmaLinux, Rocky 使用 dnf (yum 也行)'''<syntaxhighlight lang="bash"> sudo dnf install nftables -y </syntaxhighlight>'''检查是否安装成功''' <code>sudo nft --version</code> * 如果显示类似 <code>nftables v0.9.8 (E.G.O.)</code>,说明安装成功。 * 如果提示 <code>command not found</code>,请检查上面的安装步骤是否报错 == 使用nft查看防火墙规则与添加 == 输入<code>sudo nft list ruleset</code> 查看全部规则 默认情况下应该没有内容…如果有的话…..可能是其他防火墙工具带的…一般情况下防火墙默认规则不会干扰… 先来看一个基础的防火墙配置 [[File:Nft list ruleset.png|border]][[File:Nftaddrule.png|border]] * <code>table inet filter</code> 定义一个名字叫做filter 管理 ipv4 和ipv6 的 表 ** <code>table</code> 代表它是一个表 表中有很多链(chain) 链中有很多规则(rule) ** <code>inet</code> 代表它是ipv4和ipv6的混合表 还有其他可选项 ip 代表ipv4 只管ipv4 ip6代表ipv6 只管ipv6 ** <code>filter</code> 自己给这个表起的名字 可以改成别的 ** 表的类型inet + filter 名字 代表了唯一的表名 不能重复 但是可以ip filter ip6 filter 输入指令 '''<code>sudo nft add table inet my_firewall</code> 创建表''' ** sudo 高权限 ** nft nftables工具的缩写 ** add 添加 ** table 表 ** inet 代表 可以同时管理ipv4和ipv6 ** my_firewall 自己起的名字 [[File:Nftcreatechain.png|border]] * <code>chain input</code> 在表中 定义了 一个 名字叫做input的链 可以定义多个链 在同一个表中名字不要重复 ** <code>chain</code> 固定写法 表示 它是一个 链 ** <code>input</code> 链的名字 可以叫别的比如 my_input ** 其他的chain allowed_ip chain allowed_mobile和它一样就不多介绍了 * <code>type filter hook input priority filter; policy accept</code>; 设定链的默认规则等 …一般管理进入的网络流量都这样写 只有写了的这个chain 的规则才生效 并不是所有的chain都需要写一条这个 像chain allowed_ip chain allowed_mobile 原本是不生效的 但是因为在chain input里面有jump allowed_ip jump allowed_mobile 这两个链才生效 jump代表 调用或者跳转到另外一个chain 所以不用每个chain都写 写的了那个就是 检查进入流量的入口 然后可以在入口(chain)中调用别的入口(chain) ** <code>type filter</code> 代表这个链是过滤的 ** <code>hook input</code> 代表 过滤 的 位置 在input input就是进入流量的门口 ** <code>priority filter</code> 执行的优先级(顺序)。<code>filter</code> 在这里其实代表一个数字(0)。 ** <code>policy accept</code> 默认策略 如果所有规则都走完(从上到下)没有对应的 默认就是policy后面的 可以是accept[接受] 或者 drop[丢弃] 或别的 输入指令 '''<code>sudo nft 'add chain inet my_firewall my_input { type filter hook input priority 0; policy accept; }'</code> 创建my_input链的同时添加那条''' 设定链的默认规则等 ‘’单引号是防止shell转义问题.. [[File:Nftcreatechain2.png|border]] 输入指令 <code>sudo nft add chain inet my_firewall allowed_ip</code> 单独创建一个链 [[File:Nftaddrule1.png|border]] * <code>iifname "lo" accept comment "Allow loopback traffic”</code> ** <code>iifname</code> 检查流量是从哪个网卡进入的 ** <code>lo</code> 它专门用于'''本机内部通信'''。也就是大家常说的 <code>127.0.0.1</code> 或者 <code>localhost</code>。 ** <code>accept</code> 允许通过防火墙 ** <code>comment</code> 注释的意思 要自己写 表示它规则是干嘛的 输入 <code>sudo nft 'add rule inet my_firewall my_input iifname "lo" accept comment "Allow loopback traffic"'</code> 创建一条允许系统内部 自己 进入 自己 的流量 比如curl 访问自己的127.0.0.1服务 [[File:Nftaddrule2.png|border]] * <code>ct state established,related accept comment "Allow established/related connections”</code> 还记得上面说的关键点么 这时候,这股进入的流量对于电脑或者手机或者vps来说,如果不加辨别,它就是一个“外来闯入者”**。 如果你的 INPUT 规则是默认拒绝(DROP),防火墙会无情地把这个网络流量(网页内容)挡在门外——这就导致了“虽然我发出了请求,但我收不到回复” 这个规则就是解决这个问题的 “这条规则的核心作用,就是允许服务器‘主动发起(访问/流出)’的连接,能够顺利收到‘回信’(返回的内容)。” ** '''<code>ct</code> (Connection Tracking)''': 意思是启用内核的“记性”。防火墙不再是死板地只看 IP,而是会去查阅“记录本”,看看这个包是不是属于之前某个流出的那个目标ip。 ** '''<code>state established</code>''': 代表“已建立连接”。即:双方已经打过招呼了,不是新来的骚扰电话,而是正在进行的通话。 ** '''<code>state related</code>''': 代表“衍生连接”。比如你用 FTP 下载文件,控制命令走一个通道,数据传输走另一个通道。虽然数据通道是新的,但它是由控制通道派生出来的,所以也算“自己人”。 输入 <code>sudo nft 'add rule inet my_firewall my_input ct state established,related accept comment "Allow established/related connections"'</code> [[File:Nftipv4ping.png|border]] * <code>ip protocol icmp icmp type echo-request accept comment "Allow IPv4 Ping"</code>只允许ping请求 就是用ping vpsip的那个 ** <code>ip</code> 代表 用ipv4的方式管理 ** <code>protocol icmp</code> 代表他是icmp协议 ** <code>type echo-request</code> icmp协议包含很多类型(比如差错控制、时间戳等),而 <code>echo-request</code> 专指ping ** <code>accept</code> 允许 ** <code>comment</code> 注释 注释的内容是允许ipv4ping 输入 <code>sudo nft 'add rule inet my_firewall my_input ip protocol icmp icmp type echo-request accept comment "Allow IPv4 Ping"'</code> === 最重要的允许ssh端口 === 最开始的规则图片里面没有允许ssh端口这个 因为我图片里面 用的是白名单模式… 首先 你应该输入 <code>ss -tlnp | grep sshd</code> [[File:Seesshport.png|border]] 查看ssh端口用的是哪个 [[File:Nftaddrule3.png|border]] 然后先将22 换成你的端口号 再输入 <code>sudo nft 'add rule inet my_firewall my_input tcp dport 22 accept comment "Allow SSH"'</code> 这样就开放了22端口号 * <code>sudo</code> 使用高权限 * <code>nft nftables</code>工具 * <code>‘’</code>引号是防止””被命令行破坏… * <code>add</code> 添加 * <code>rule</code> 代表 添加的是 规则 * <code>inet my_firewall</code> 表的类型+表的名字 组成 的唯一表 这就意味着可以有ip my_firewall ip6 my_firewall….. * <code>my_input</code> 代表 唯一表中的那个链 * <code>tcp</code> 代表进入的网络流量协议是tcp ssh是tcp 但是你要允许别的服务器可以把他改成udp之类的 * <code>dport</code> 代表 要进入我的端口号 还有一个sport是代表 来自的端口号 就是 从它的哪个端口号流出的 * <code>22</code> 代表 端口号 * <code>accept</code>是允许 * <code>comment</code>是注释 * 合起来就是 在inet my_firewall表my_input链中 添加一个规则 规则是 允许任何ip(因为没有做限制,nftables可以做限制)用tcp协议进入我的22端口 '''这里没有设置 来自哪个ip用Tcp访问我的22端口号 所以其实还是有风险的,因为世界上任何一个ip仍然可以通过知道你的ssh端口然后尝试..请结合更多的安全方式 例如:修改只允许密钥登录ssh [[SSH KEY LOGIN]] 或 使用白名单(只允许特定的ip的所有进入流量)''' === 危险操作 把input默认策略修改为drop(丢弃) === <code>type filter hook input priority filter; policy accept</code> 之前说到最后这个policy accept是默认允许 就是所有的规则走完(从上到下的寻找) 没找到匹配的 就会允许 所以相当于和没开防火墙一样(防火墙默认也是全部允许) 现在我们把它改成drop 如果规则错误就有失去连接的可能.所以在此之前我们要先做一个保险 '''请先看完整段在输入指令''' 因为60秒后会自动把policy drop 恢复成 accept 允许 就无法验证了 输入 <code>(sleep 60 && sudo nft add chain inet my_firewall my_input { policy accept\\; } && echo "救援生效:策略已恢复为 Accept") & disown</code> [[File:Disown.png|border]] 出现这样的数字 你就可以继续把默认指令修改为drop了 这个意思是 暂停60秒 然后 把默认策略修改为允许 & disown 意思是 放到后台和ssh断开连接 防止因为防火墙设置错误导致的结束此指令 然后输入 <code>sudo nft add chain inet my_firewall my_input { policy drop\\; }</code> 将默认策略修改为drop [[File:Nftdrop.png|border]] 因为这条规则原因 <code>ct state established,related accept comment "Allow established/related connections”</code> 你不会被断开连接 所以需要手动输入exit或关闭ssh软件从而断开ssh连接 如果顺利的话 你应该可以立刻用ssh登录 如果无法重新连接 等待60秒后再连接 如果成功了的话 '''你也要等待60秒后'''..再次输入 <code>sudo nft add chain inet my_firewall my_input { policy drop\\; }</code> 就可以把默认策略修改为drop也不会把自己关在外面了 '''好啦 可以去准备好代码 然后在执行 验证就可以轻松的在60秒内解决''' === 继续查看规则 我把drop改回accept了…下图里都是accept === [[File:Ipv6ping.png|border]] * <code>ip6 nexthdr ipv6-icmp accept</code> 允许ipv6的icmp协议 如果你有ipv6地址就必须加 没有ipv6地址可以不加 它影响ipv6很多东西 不知道有没有ipv6可以加上 ** 使用 <code>sudo nft 'add rule inet my_firewall my_input ip6 nexthdr ipv6-icmp accept comment "Allow IPv6 ICMP"'</code> [[File:Dhcpv6.png|border]] * <code>ip6 saddr fe80::/64 udp sport 547 udp dport 546 accept</code> 也和ipv6相关重要 ipv6必须加 如果不知道有没有ipv6也可以直接加上 ** <code>ip6</code> 代表防火墙用ipv6的方式去处理这条规则 ** <code>saddr</code> 代表流出的ip地址 ** <code>fe80::/64</code> ipv6的本地ip就像ipv4的127.0.0.1 ** <code>udp sport 547</code> udp代表udp协议 sport代表流出的端口号 ** <code>udp dport 546</code> udp还是代表udp协议 dport代表 要进入的端口号 ** <code>accept</code> 允许 ** 合起来就是允许 来自从<code>fe80::/64</code>(本地)流出使用udp协议端口号是547的网络流量 进入 我的udp的546端口 ** 使用 <code>sudo nft 'add rule inet my_firewall my_input ip6 saddr fe80::/64 udp sport 547 udp dport 546 accept comment "Allow DHCPv6"'</code> [[File:Nftjump.png|border]] * <code>jump allowed_ip</code>意思是 跳转到其他链 本来应该去找默认规则accept或drop了 但是主动让它跳转到别的链中寻找其他规则 如果在其他链中找到就走那个规则 没找到还是回来找默认的规则accept或drop ** 既然如此为什么还要写多个chain 直接写一个不就行了? *** 可以用chain 管理 用于不同目的的规则 *** 可以使用 <code>sudo nft flush chain inet my_firewall allowed_ip</code> 只清空这一个chain 把永远不会变的且总是被触发的(防火墙遵循从上到下上面的最好放经常触发的这样快) '''清空chain 不会清空 默认策略 如果你的默认策略是drop 清空了包含允许ssh端口号的链 也就是''' <code>sudo nft 'add rule inet my_firewall my_input tcp dport 22 accept comment "Allow SSH"'</code> '''这个链是my_input 那么你就失联了 因为允许进入22端口规则清空了 默认策略又是drop 所以可以考虑不要清空 主要的chain 把永远不会变的放在那里''' *** 配合 清空链 可以做一个白名单机制 ** 使用 <code>sudo nft add rule inet my_firewall my_input jump allowed_ip</code> 添加规则 === 以下2个 可以不加 要了解指令的意思 === [[File:Nftipsaddr.png|border]] * <code>ip saddr [xxx.xxx.xx.xxx](<<nowiki>http://xxx.xxx.xx.xxx/</nowiki>>) accept</code> 意思是 允许从ipv4地址xxx.xxx.xx.xxx流出 进入我的 流量。 没有其他限制 这个ip的任何流量都会被允许 不管是tcp还是udp 所有端口(从0到65535) 都会被允许的 只要符合这个条件(网络流量是从ip xxx.xxx.xx.xx流出进入我的)就允许 反过来如果是 <code>ip saddr xxx.xxx.xx.xxx drop</code> 就是只要是从ip xxx.xxx.xx.xxx流出进入我的 就丢弃(不允许) 当然如果你默认策略是policy accept 这条规则没有找到 往下走继续找 找完所有规则都没找到就会走默认的accept允许了… ** <code>ip</code>ipv4协议 表示 防火墙用ipv4的方式去处理这条规则 ** <code>saddr xxx.xxx.xx.xxx</code> 从xxx.xxx.xx.xxx流出 ** <code>accept</code> 允许 ** 使用 <code>sudo nft add rule inet my_firewall allowed_ip ip saddr 1.1.1.1 accept</code> 可选(允许1.1.1.1)的流量..理论上这里应该替换成你自己的ipv4 [[File:Nftip6saddr.png|border]] * <code>ip6 saddr xxxx:xxxx:xxxx:xxxx::/128 accept</code> 允许从ipv6地址 <code>xxxx:xxxx:xxxx:xxxx::/128</code> 流出 进入我的流量 ** <code>ip6</code> ipv6协议 表示让防火墙用ipv6的方式去处理这条规则 ** <code>saddr xxxx:xxxx:xxxx:xxxx::/128</code> 从<code>xxxx:xxxx:xxxx:xxxx::/128</code> 流出 *** /64和/128的区别 **** '''<code>/128</code>''':代表只放行'''一台设备''' **** '''<code>/64</code>''':代表放行'''整个子网'''。相当于 64长度的ip一样就可以 一般你要是想让连接家庭路由器的所有设备都允许 选这个 ** <code>accept</code> 允许 ** 使用 <code>sudo nft add rule inet my_firewall allowed_ip ip6 saddr 2606:4700:4700::1111/128 accept</code> 可选(允许<code>2606:4700:4700::1111/128</code>)的流量..理论上这里应该替换成你自己的ipv6 === 另外查看防火墙规则的指令 === [[File:Otherseenftrule.png|border]] <code>sudo nft list table inet my_firewall</code> 查看表my_firewall 从nft list ruleset(全部) 把ruleset改成 table 表示查看表 后面inet my_firewall 是看哪个表 [[File:Seenftchain.png|border]] <code>sudo nft list chain inet my_firewall my_input</code> 查看指定的链 不显示其他的链 在inet my_firewall中的my_input链 把table又变成了chain 表示查看 链 inet my_firewall 要先告诉它 这个链 在那个表中 最后在告诉它 链的名字 [[File:Seenftchain2.png|border]] sudo nft list chain inet my_firewall allowed_ip 同上 这次看allowed_ip === 关于注释 === * <code>sudo nft 'add rule inet my_firewall my_input tcp dport 22 accept comment "Allow SSH"'</code> <code>sudo nft add rule inet my_firewall my_input tcp dport 22 accept</code> ** nft(工具) add(添加的动作) rule(代表是添加规则) inet my_firewall(添加到表的唯一名) my_input(inet my_firewall表中的链) tcp(协议名) dport(进入我的哪个端口号) 22(端口号) accept(允许) *** 顺序是这样的,可以从中添加别的指令进行组合 比如 <code>sudo nft add rule inet my_firewall my_input ip saddr 1.1.1.1 tcp dport 22 accept</code> 增加了<code>ip saddr 1.1.1.1</code> 那么在原始的基础上限制了 只有从1.1.1.1流出的网络流量并且是tcp协议进入我的22端口 才允许 如果是相反的 <code>ip saddr 1.1.1.1 tcp dport 22 drop</code> 那么就是只有 从1.1.1.1流出的进入我的22端口的就丢弃(不允许) 如果它是要进入我的23 因为这条规则不是23 就会往下找 找完所有没有23的 就要看默认策略(policy accpet) 如果是accept就会允许 drop就不允许 ** 第一条需要单引号是因为双引号 在命令行执行可能会破坏结构..所以用单引号括起来,如果你不需要注释 你可以像第二条那样 去掉comment之后的 也可以去掉单引号了 === 删除规则 === 如果最后两条ip不是自己的ip或者错误的允许了别的ip 我现在不想允许它了怎么办呢 先输入 <code>sudo nft -a list ruleset</code> [[File:Nftdel1.png|border]] 可以看到加上-a后 每个后面都多出来 # handle 数字 我们需要得到这个数字才能删除 然后输入 <code>sudo nft delete rule inet my_firewall allowed_ip handle 11</code> delete 删除的意思 rule 规则 inet my_firewall 表的唯一名 allowed_ip 链的名 handle 11 handle固定写法.. 11就是那条规则的id [[File:Nftdel2.png|border]] === 修改规则 === 你可以先删除 再添加对吧….. 还是像删除那样 获取handle id 输入 <code>sudo nft -a list ruleset</code> [[File:Nfthandle2.png|border]] <code>sudo nft replace rule inet my_firewall allowed_ip handle 12 ip6 saddr 2606:4700:4700::1001 accept</code> replace 替换 rule 规则 inet my_firewall 表的名字 allowed_ip 表中链的名字 handle 12 规则的id 后面就是新的规则 === [[File:Nftreplace.png|border]] === === 把当前的防火墙规则保存到文件中 === 现在可以输入 <code>sudo nft list ruleset</code> 查看一下应该就不是空的了 在没有设置的情况下 每次重启都会丢失这些规则 我们先把防火墙规则保存到一个文件 每次重启的时候让防火墙 自动读取 加载 这个文件 就可以了 输出 <code>sudo nft list ruleset > backup.nft</code> 导出到当前文件夹下 输入 <code>ls</code> 查看导出的文件 输入 <code>cat backup.nft</code> 查看文件内容 可以看到文件中是不包含sudo nft add rule inet my_firewall之类的 [[File:Nftsave.png|border]] 你可以直接这里面填写 ..我想你应该明白指令都是啥意思了吧…..如果你要直接修改的话最好先备份一下 执行 <code>sudo cp backup.nft backup.nft_bak</code> 然后你就可以在这里面修改了输入 <code>nano backup.nft</code> 用方向键 移动光标 ==== 如果你输入nano backup.nft提示 -bash: nano: command not found ==== 说明你没有安装nano.. nano 是一个文本编辑器 以下命令安装nano '''Debian / Ubuntu / Armbian 系''' <code>sudo apt update && sudo apt install nano -y</code> '''Red Hat / AlmaLinux / Rocky / CentOS 8+ 系''' <code>sudo dnf install nano -y</code> [[File:Nano.png|border]] <code>ctrl+o</code> 保存 [[File:Nanosave.png|border]] 这里是问你保存的文件名 直接保存到原文件就直接回车就行 <code>ctrl+x</code> 退出 == 从文件中读取规则 == 先输入 <code>sudo nft -c -f backup.nft</code> 正常情况下什么都不会发生 [[File:Nftreadsuccess.png|border]]如果有错误的话 [[File:Nftreaderror.png|border]] 就会这样了 他会指出你哪里有错误 <code>backup.nft:16:1-1: Error:syntax error, unexpected end of file</code> 我的这个错误的意思是 '''backup.nft有错误 错误从第16行的第一个字符开始到第一个字符结束 错误:语法错误,意外的文件结束”'''。 前面的16:1-1是错误坐标 就是我的文件最后少了一个右括号 } 每个括号都是一对{} 成对出现的 [[File:Nftreaderror2.png|border]] <code>backup.nft:6:3-7:Error:syntax error, unexpected dport</code> '''“语法错误,这里不该出现 <code>dport</code> 这个词”'''。 这个就是缺少了一个指令 tcp [[File:Nftreaderror3.png|border]]tcp的顺序不对..你可以看到这两个 错误信息是一样的都是 <code>backup.nft:6:3-7: Error: syntax error, unexpected dport</code> 原因类似 具体不同 这个就是tcp应该在前面 tcp dport 22 accept comment “Allow SSH” 一般都是 指令的顺序或者是缺少指令或者是多了指令或者是拼写错误 '''检测无误后 什么事情也没有发生 什么也没有输出''' 清空规则集 <code>sudo nft flush ruleset</code> 清空规则集 不会像清空链引发默认drop挡在防火墙外的 然后执行 <code>sudo nft -f backup.nft</code> [[File:Nftreadok2.png|border]]防火墙规则就回来了 == 编辑防火墙规则文件 == 比如说你有另外一个防火墙规则完整的片段从table开始的<syntaxhighlight lang="bash"> define INGRESS_INTERFACE="eth0" define PORT_RANGE=20000-45000 define PORT=8663 table inet portopping{ chain prerouting { type nat hook prerouting priority dstnat; policy accept; iifname $INGRESS_INTERFACE udp dport $PORT_RANGE counter redirect to :$PORT } } </syntaxhighlight>你可以直接复制到backup.nft末尾 [[File:Nftedit.png|border]] 当然你也可以对 表的类型 inet 表的名字my_firewall 和表中 链的名字 my_input进行修改 修改好后 按<code>ctrl+o</code> 保存 然后回车就是直接保存到原文件上 然后先测试<code>sudo nft -c -f backup.nft</code> 没问题就清空 <code>sudo nft flush ruleset</code> 读取 <code>sudo nft -f backup.nft</code> 查看 <code>sudo nft list ruleset</code> [[File:Nfteditok.png|border]] == 配置开机自动启动 == # '''备份原文件(给自己留条后路):''' <code>sudo cp /etc/nftables.conf /etc/nftables.conf.bak</code> # '''将当前规则写入系统配置:''' #* 由于权限问题,直接用 <code>sudo ... > ...</code> 可能会报权限不足,建议用下面这句“万能命令”: <code>sudo sh -c "nft list ruleset > /etc/nftables.conf"</code> 这个是把当前防火墙的规则写入默认的配置文件中 每次开机自动启动用的就是当前防火墙的规则. 执行一次<code>sudo nft flush ruleset</code> 以后就不需要了 不然规则会重复的 规则重复 因为你的防火墙有规则 在运行sudo systemctl start nftables它又去读取了一边 所有规则重复了..可以在<code>sudo systemctl start nftables</code> [[File:Nftstart.png|border]] 3.启用开机自启(如果还没开的话): 开启开机自启 <code>sudo systemctl enable nftables</code> 立刻启动nftables服务(执行的内容就是立刻加载/etc/nftables.conf 文件中的防火墙规则) <code>sudo systemctl start nftables</code> = 恭喜...走完这写你已经有了一个基础的防火墙了… = 如果还需要进阶 可以参考 使用搬瓦工api操作nftables实现更新白名单ip 实现后就可以关闭ssh端口了
返回
服务器安全-防火墙 nftables
。
查看“︁服务器安全-防火墙 nftables”︁的源代码
来自md5.pw