2021-05-28

IPv6

1. IPv6 Day
2. IPv6 deployment
3. 与IPv4比较
	3.1 IPv6编码
	3.2 IPv6格式
	3.3 IPv4映射地址
	3.4 IPv6新增了区域ID
	3.5 IPv6的省略书写
	3.6 IPv6地址的分类
	3.7 特殊地址
4. 邻居发现
5. 无状态自动配置(SLAAC)
	5.1 对于Linux客户端
	5.2 对于网关
6 Privacy extensions 隐私扩展
	6.1 dhcpcd
	6.2 NetworkManager
	6.3 systemd-networkd
	6.4. ConnMan
7. Stable private addresses 稳定的私人地址
8. Static address 静态地址
9. IPv6和PPPoE
a 前缀委派(DHCPv6-PD)
	a.1 使用dhcpcd
	a.2 systemd-networkd
	a.3. 其他客户端
b Disable 禁用 IPv6
	b.1 禁用功能
	b.2 其他程序
		b.2.1 dhcpcd
		b.2.2 NetworkManager
		b.2.3 ntpd
		b.2.4 GnuPG
		b.2.5 sshd
	b.3. systemd-networkd
c 在IPv6上优先使用IPv4

https://zh.wikipedia.org/wiki/IPv6
网际协议第6版(英语:Internet Protocol version 6,缩写:IPv6)是网际协议的最新版本,用作互联网的协议。用它来取代IPv4主要是为了解决IPv4地址枯竭问题,同时它也在其他方面对于IPv4有许多改进。

1. IPv6 Day

如今, 全球上网人数已超40亿,IPv4仅能提供约42.9亿个IP位置。NAT网络地址转换, CIDR无类别域间路由等技术延缓网络位置匮乏之现象。
为求解决根本问题...
1990年开始, 
互联网工程工作小组开始规划IPv4的下一代协议,
1994年提议, 各IPng领域的代表们于多伦多举办的IETF会议中,正式提议IPv6发展计划,该提议直到同年的11月17日才被认可。
1996年8月10日, 1994年的提议发展成为IETF的草案标准
1998年公布, 12月由互联网工程工作小组以互联网标准规范(RFC 2460)的方式正式公布IPv6
...
2011年6月8日, 世界IPv6日(英语:World IPv6 Day)是在2011年6月8日由互联网协会组织和赞助的,一次公开测试IPv6的活动。
2012年6月6日, 世界IPv6启动日. 在2011年的活动大获成功之后,互联网协会将2012年6月6日定为了世界IPv6启动日,在这一天,全球IPv6网络已正式启动。

2. IPv6 deployment

https://en.wikipedia.org/wiki/IPv6_deployment
https://zh.wikipedia.org/wiki/IPv6部署
Google的统计数据显示,截至2021年4月,根据用户的星期几(周末更大),其用户的IPv6可用性约为30.30–35.10%。下表是摘录了部分有数据的国家使用IPv6的比例. 

测试本地是否支持IPv6, 苏州的移动宽带去年测试还不通, 今天测了一下通了. 
http://test-ipv6.com/

3. 与IPv4比较

https://zh.wikipedia.org/wiki/IPv6
在Internet上,数据以分组的形式传输。IPv6定义了一种新的分组格式,目的是为了最小化路由器处理的消息标头。
由于IPv4消息和IPv6消息标头有很大不同,因此这两种协议无法互操作。但是在大多数情况下,IPv6仅仅是对IPv4的一种保守扩展。
除了嵌入了互联网地址的那些应用协议(如FTP和NTPv3,新地址格式可能会与当前协议的语法冲突)以外,大多数传输层和应用层协议几乎不怎么需要修改就可以在IPv6上运行。

3.1 IPv6编码

IPv6具有比IPv4大得多的编码地址空间。这是因为IPv6采用128位的地址, 地址空间支持2128。而IPv4使用的是32位(总地址约亿40个)。
就以地球人口70亿人计算,每人平均可分得约4.86×1028(486117667×1020)个IPv6地址。
RFC 2373和RFC 2374定义的IPv6地址有128位长;IPv6地址的表达形式一般采用32个十六进制数。
在很多场合,IPv6地址由两个逻辑部分组成:一个64位的网络前缀和一个64位的主机地址,主机地址通常根据物理地址自动生成,叫做EUI-64(或者64-位扩展唯一标识)。

3.2 IPv6格式

  • IPv4二进制是32位. 以8位位一组, 分为4组以点号"."隔开. 4组*8位=32位。通常使用: 点分十进制. 4组十进制数字用点隔开. 
  • IPv6二进制128位. 以16位为一组,分为8组以冒号":"隔开. 8组*16位=128位. 通常使用: 每组以4位十六进制方式表示。
例如:2001:0db8:86a3:08d3:1319:8a2e:0370:7344 是一个合法的IPv6地址。
类似于IPv4的点分十进制,同样也存在点分十六进制的写法,将8组4位十六进制地址的冒号去除后,每位以点号“.”分组,例如:2001:0db8:85a3:08d3:1319:8a2e:0370:7344则记为2.0.0.1.0.d.b.8.8.5.a.3.0.8.d.3.1.3.1.9.8.a.2.e.0.3.7.0.7.3.4.4,其倒序写法用于ip6.arpa子域名记录IPv6地址与域名的映射。

3.3 IPv4映射地址

如果这个地址实际上是IPv4的地址,后32位可以用10进制数表示;因此::ffff:192.168.89.9 相等于::ffff:c0a8:5909。
::ffff:1.2.3.4 格式叫做IPv4映射地址。
IPv4位址可以很容易的转化为IPv6格式。举例来说,如果IPv4的一个地址为135.75.43.52(十六进制为0x874B2B34),它可以被转化为0000:0000:0000:0000:0000:FFFF:874B:2B34 或者::FFFF:874B:2B34。同时,还可以使用混合符号(IPv4-compatible address),则地址可以为::ffff:135.75.43.52。

3.4 IPv6新增了区域ID

由于同一非全局地址可能在同一范围的多个区域中使用(例如,在两条独立的物理链路中使用链路本地地址 fe80::1),而且一个节点可能连接到同一范围的不同区域的接口(例如,一个路由器通常有多个接口连接到不同的链路)。
IPv6新增了区域ID(Zone ID)加以区分,或称作用域ID(Scope ID)。作用域ID仅用于本地链接,使用百分号追加在地址后面。
其内容特定于操作系统,例如Windows使用数字 fe80::2%3 ,Linux使用网卡名字 fe80::2%eth0 。
在URI中使用时,百分号需要进行编码,例如 fe80::a%en1 应显示为 http://[fe80::a%25en1] 。

3.5 IPv6的省略书写

每组数字前导0可以省略,省略后前导数字仍是0则继续,例如下组IPv6是等价的。
2001:0db8:02de:0000:0000:0000:0000:0e13
2001:db8:2de:0000:0000:0000:0000:e13
2001:db8:2de:000:000:000:000:e13
2001:db8:2de:00:00:00:00:e13
2001:db8:2de:0:0:0:0:e13
可以用双冒号“::”表示一组0或多组连续的0,但只能出现一次:
2001:db8:2de:0:0:0:0:e13
2001:db8:2de::e13

3.6 IPv6地址的分类

IPv6地址可分为三种: 
单播(unicast)地址
单播地址标示一个网络接口。协议会把送往地址的数据包送往给其接口。IPv6的单播地址可以有一个代表特殊地址名字的范畴,如链路本地地址(link local address)和唯一区域地址(ULA,unique local address)。单播地址包括可聚类的全球单播地址、链路本地地址等。
任播(anycast)地址
任播像是Unicast(单点传播)与Broadcast(多点广播)的综合。单点广播在来源和目的地间直接进行通信;多点广播存在于单一来源和多个目的地进行通信。
而Anycast则在以上两者之间,它像多点广播(Broadcast)一样,会有一组接收节点的地址列表,但指定为Anycast的数据包,只会发送给距离最近或发送成本最低(根据路由表来判断)的其中一个接收地址,当该接收地址收到数据包并进行回应,且加入后续的传输。该接收列表的其他节点,会知道某个节点地址已经回应了,它们就不再加入后续的传输作业。
So, 以目前的应用为例,Anycast地址只能分配给中间设备(如路由器、三层交换机等),不能分配给终端设备(手机、电脑等),而且不能作为发送端的地址。
多播(multicast)地址
多播地址也称组播地址。多播地址也被指定到一群不同的接口,送到多播地址的数据包会被发送到所有的地址。多播地址由皆为一的字节起始,亦即:它们的前置为FF00::/8。其第二个字节的最后四个比特用以标明"范畴"。
一般有node-local(0x1)、link-local(0x2)、site-local(0x5)、organization-local(0x8)和global(0xE)。多播地址中的最低112位会组成多播组群标识符,不过因为传统方法是从MAC地址产生,故只有组群标识符中的最低32位有使用。定义过的组群标识符有用于所有节点的多播地址0x1和用于所有路由器的0x2。
另一个多播组群的地址为"solicited-node多播地址",是由前置FF02::1:FF00:0/104和剩余的组群标识符(最低24位)所组成。这些地址允许经由邻居发现协议(NDP,Neighbor Discovery Protocol)来解译链接层地址,因而不用干扰到在区网内的所有节点。

3.7 特殊地址

https://zh.wikipedia.org/wiki/IPv6#特殊位址
IANA维护官方的IPv6地址空间列表。全局的单播地址的分配可在各个区域互联网注册管理机构或 GRH DFP 页面找到。
https://www.iana.org/numbers
IPv6中有些地址是有特殊含义的: 
- 未指定地址
::/128-所有比特皆为零的地址称作未指定地址。这个地址不可指定给某个网络接口,并且只有在主机尚未知道其来源IP时,才会用于软件中。路由器不可转送包含未指定地址的数据包。
- 链路本地地址
::1/128-是一种单播绕回地址。如果一个应用程序将数据包送到此地址,IPv6堆栈会转送这些数据包绕回到同样的虚拟接口(相当于IPv4中的127.0.0.1/8)。
fe80::/10-这些链路本地地址指明,这些地址只在区域连线中是合法的,这有点类似于IPv4中的169.254.0.0/16。
- 唯一区域地址
fc00::/7-唯一区域地址(ULA,unique local address)只可用于本地通信,类似于IPv4的专用网络地址10.0.0.0/8、172.16.0.0/12和192.168.0.0/16。这定义在RFC 4193中,是用来取代站点本地位域。这地址包含一个40比特的伪随机数,以减少当网站合并或数据包误传到网络时碰撞的风险。这些地址除了只能用于区域外,还具备全局性的范畴,这点违反了唯一区域位域所取代的站点本地地址的定义。
- 多播地址
ff00::/8-这个前置表明定义在"IP Version 6 Addressing Architecture"(RFC 4291)中的多播地址[12]。其中,有些地址已用于指定特殊协议,如ff0X::101对应所有区域的NTP服务器(RFC 2375)。
- 请求节点多播地址(Solicited-node multicast address)
ff02::1:FFXX:XXXX-XX:XXXX为相对应的单播或任播地址中的三个最低的字节。
- IPv4转译地址
::ffff:x.x.x.x/96-用于IPv4映射地址。(参见以下的转换机制)。
https://zh.wikipedia.org/wiki/IPv6#轉換機制
2001::/32-用于Teredo隧道。
2002::/16-用于6to4。
- ORCHID
2001:10::/28-ORCHID (Overlay Routable Cryptographic Hash Identifiers)(RFC 4843)。这些是不可遶送的IPv6地址,用于加密散列识别。
- 文件
2001:db8::/32-这前置用于文件(RFC 3849)。这些地址应用于IPV6地址的示例中,或描述网络架构。
- 遭舍弃或删除的用法
::/96-这个前置曾用于IPv4兼容地址,现已删除。
fec0::/10-这个站点本地前置指明这地址只在组织内合法。它已在2004年9月的RFC3879中舍弃,并且新系统不应该支持这类型的地址。

4. 邻居发现

对多播地址执行ping操作会ff02::1导致所有本地主机在链接本地范围内做出响应。必须指定一个接口:
$ ping ff02::1%eth0
之后,您可以使用以下命令获取本地网络中所有邻居的列表:
$ ip -6 neigh
注: 若启用了ip6tables的简单防火墙, ping命令只能看到自己, 看不到局域网内其他启用了简单防火墙的用户, 但ping之后再执行: ip -6 neigh 还是能找到邻居. 

通过ping多播地址,ff02::2只有路由器会响应。
如果添加选项,则本地链接主机将使用其全局链接作用域地址进行响应。在这种情况下,可以省略该接口: -I your-global-ipv6
$ ping -I 2001:4f8:fff6::21 ff02::1

5. 无状态自动配置(SLAAC)

在网络准备好的情况下,获取IPv6地址最简单的方法是通过“无状态地址自动配置”(SLAAC)。地址会自动由路由器给出的前缀推算出,不需要其他配置,也不需要DHCP客户端。
在不适合使用IPv6无状态地址自动配置的场景下,网络可以使用有状态配置(DHCPv6),或者使用静态方法手动配置。

5.1 对于Linux客户端

如果你使用netctl管理网络,那么只需要在网络配置中加入下面这一行:
IP6=stateless
如果使用NetworkManager,它会自动检测网络情况并配置好IPv6.
注意: 只有IPv6 icmp数据包可以经过网络传输时,SLAAC才可以正常工作。所以在要配置IPv6的计算机上,必须允许ipv6-icmp数据包进入。如果你使用Simple stateful firewall或iptables,只需要加入:
-A INPUT -p ipv6-icmp -j ACCEPT

5.2 对于网关

网关需要运行一个守护进程,以确保能够将IPv6地址分发给客户端。一般使用radvd(official repositories)。配置radvd很简单。修改/etc/radvd.conf,加入如下配置:
# replace LAN with your LAN facing interface
interface LAN {
  AdvSendAdvert on;
  MinRtrAdvInterval 3;
  MaxRtrAdvInterval 10;
  prefix ::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
  };
};

这些配置可以要求客户端由64位的网络前缀自动推算并配置地址。请注意这些配置允许使用分配到局域网的所有可用的前缀。如果你不打算使用::/64,需要限制允许使用的前缀,可以注明前缀,例如2001:DB8::/64。prefix选项可以重复使用多次,分别记录不同的前缀。
要将DNS服务器通告给您的LAN客户端,您可以使用RDNSS功能。例如,添加以下行/etc/radvd.conf以播发Google的DNS v6服务器:
RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {
};

网关必须在所有的方向上允许ipv6-icmp数据包。如果你使用Simple stateful firewall或iptables,需要加入如下规则:
 -A INPUT -p ipv6-icmp -j ACCEPT
 -A OUTPUT -p ipv6-icmp -j ACCEPT
 -A FORWARD -p ipv6-icmp -j ACCEPT
使用其他防火墙也需要类似的规则。配置完成后可以开启radvd.service。

6. Privacy extensions 隐私扩展

当一个客户端使用SLAAC配置其IPv6时,它会使用网络前缀和网卡的MAC地址构造地址。
这会引起安全问题:计算机的MAC地址可以轻松通过其IPv6地址推算出。
为了解决这个问题,提出了“IPv6隐私扩展”标准(RFC 4941)。
使用这个隐私扩展,内核会从原本的IPv6地址计算生成一个“临时地址”。在连接远程服务器时,系统会优先选择这个地址以隐藏原来的地址。要启用隐私拓展,可以按照如下步骤:
向/etc/sysctl.d/40-ipv6.conf加入如下内容:
# Enable IPv6 Privacy Extensions
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.nic0.use_tempaddr = 2
...
net.ipv6.conf.nicN.use_tempaddr = 2

其中,nic0到nicN是你的网卡。您可以使用“网络配置#列出网络接口”中的说明找到它们的名称。
https://wiki.archlinux.org/title/Network_configuration#Listing_network_interfaces
all.use_tempaddr或default.use_tempaddr参数不会对已经配置好的网卡起作用。
重启之后,隐私扩展将会启用。

6.1 dhcpcd

https://wiki.archlinux.org/title/Dhcpcd
dhcpcd从6.4.0版本起就在其默认配置文件中添加了选项slaac private,实现对隐私扩展的支持,可以实现"Stable Private IPv6 Addresses instead of hardware based ones",符合RFC 7217 。(commit)。因此,没有必要修改任何配置,除非你想经常更换地址,而不是在每次连接上新网络时。

6.2 NetworkManager

https://wiki.archlinux.org/title/NetworkManager#Configuration
可以通过NetworkManager.conf(5)或连接配置文件中的ipv6.ip6-privacy设置来控制NetworkManager中IPv6隐私扩展的使用。
如果未设置全局或每个连接,则NetworkManager将回退为 /proc/sys/net/ipv6/conf/default/use_tempaddr
要在默认情况下显式启用IPv6隐私扩展,请将这些行添加到NetworkManager.conf(5):
/etc/NetworkManager/conf.d/ip6-privacy.conf
[connection]
ipv6.ip6-privacy=2
应用配置,然后重新连接到所有活动的连接。
要控制IPv6隐私扩展在单个NetworkManager管理的连接中的使用,请在中编辑所需的连接密钥文件/etc/NetworkManager/system-connections/,并将[ipv6]密钥/值对附加到其部分ip6-privacy=2:
/etc/NetworkManager/system-connections/your-ssid.nmconnection
...
[ipv6]
method=auto
ip6-privacy=2
...
重新加载连接,然后再重新连接。
注:虽然它看起来可能scope global temporary通过启用隐私扩展永远不会被更新(它永远不会转移到创建IPv6地址deprecated的状态在其任期valid_lft),它是在一个较长的时间周期,以验证该地址的确确改变。

6.3 systemd-networkd

https://wiki.archlinux.org/title/Systemd-networkd
Systemd-networkd也不遵守/etc/sysctl.d/40-ipv6.conf里的net.ipv6.conf.xxx.use_tempaddr配置,需要在配置中设置IPv6PrivacyExtensions选项。除非使用.network文件中的值设kernel置选项IPv6PrivacyExtensions
IPv6隐私扩展的其他选项如下:
net.ipv6.conf.xxx.temp_prefered_lft
net.ipv6.conf.xxx.temp_valid_lft
注意: temp_prefered_lft是变量名,首选必须拼写错误。
有关详细信息,请参见systemd- networkd和systemd.network(5)。

6.4 ConnMan

https://wiki.archlinux.org/title/ConnMan
设置在服务文件中,即: /var/lib/connman/service/settings
IPv6.privacy=preferred

7. Stable private addresses 稳定的私人地址

另一种选择是稳定的私有IP地址(RFC 7217)。这允许IP在网络内保持稳定,而不会暴露接口的MAC地址。
为了使内核生成密钥(wlan0例如,对于),我们可以设置:
$ sudo sysctl net.ipv6.conf.wlan0.addr_gen_mode=3
打开和关闭接口,运行后,您应该stable-privacy在每个IPv6地址旁边看到ip addr show dev wlan0。内核已经生成了一个128位密钥来为该接口生成ip地址,以使其运行sysctl net.ipv6.conf.wlan0.stable_secret。我们将保留此值,因此将以下行添加到/etc/sysctl.d/40-ipv6.conf:
# Enable IPv6 stable privacy mode
net.ipv6.conf.wlan0.stable_secret = <output from previous command>
net.ipv6.conf.wlan0.addr_gen_mode = 2
注意: 如果您使用dhcpcd获取IPv6地址,则该stable-privacy标志不会被分配给该IP地址。

另外: NetworkManager不接受上述设置,但是NetworkManager默认情况下使用稳定的专用地址。
$ sudo cat /etc/NetworkManager/system-connections/ssid.nmconnection 
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto

8. Static address 静态地址

有些情况下使用静态地址可以增强安全性。使用SLAAC分配动态地址时,你的计算机的地址会由其网卡MAC推算出,这不利于安全,因为即使地址的网络号改变,你的电脑依然可以被追踪到。
要想用netctl分配一个静态地址,可以参照/etc/netctl/examples/ethernet-static。如下的部分尤其重要:
...
# For IPv6 static address configuration
IP6=static
Address6=('1234:5678:9abc:def::1/64' '1234:3456::123/96')
Routes6=('abcd::1234')
Gateway6='1234:0:123::abcd'
注意: 如果你只有IPv6连接,那么你要给出IPv6的DNS服务器,例如:
DNS=('6666:6666::1' '6666:6666::2')
如果您的提供商没有给您提供IPv6 DNS,并且您没有自己运行,则可以从resolv.conf文章中进行选择。
https://wiki.archlinux.org/title/Resolv.conf

9. IPv6和PPPoE

PPPoE的软件包pppd提供了对PPPoE之上的IPv6的支持(前提是你的ISP和调制解调器支持)。只需要将如下内容加入/etc/ppp/options
+ipv6
如果你使用netctl,那么就向你的netctl配置文件加入如下内容:
PPPoEIP6=yes

a. 前缀委派(DHCPv6-PD)

注意: 这个部分是针对自行使用配置网关的内容,不是客户端。如果你使用从市场购得的路由器,请查阅其附带的文档以开启地址委派。
地址委派是一种常见的IPv6部署方式,被许多ISP所采用。具体的做法是将一个地址前缀分配给用户(局域网),即路由器配置为将不同的前缀分配给不同的子网;ISP通过DHCPv6将地址前缀(通常是/56或/64)分发出去,DHCP客户端再将前缀分配给局域网。对于一个拥有两个网卡的简单网关来说,它的工作就是将从WAN口(或虚拟接口,比如ppp)获取的前缀分配给局域网。
DHCPv6要求客户端在端口546 UDP上接收传入连接。对于基于nftables的防火墙,可以在输入链中用一行配置/etc/nftables.conf:
table inet filter {
  chain input {
    udp dport dhcpv6-client accept
    ...
  }
...
}

a.1 使用dhcpcd

Dhcpcd在IPv4之外也提供了一个完整的支持DHCPv6-PD的客户端。如果你使用dhcpcd,需要修改/etc/dhcpcd.conf。你可能已经在用dhcpcd来配置IPv4,所以只需要对现有的配置进行小幅修改: 
duid
noipv6rs
waitip 6
# Uncomment this line if you are running dhcpcd for IPv6 only.
#ipv6only
# use the interface connected to WAN
interface WAN
ipv6rs
iaid 1
# use the interface connected to your LAN
ia_pd 1 LAN
#ia_pd 1/::/64 LAN/0/64
此配置客户端会从WAN接口获取一个前缀,分配给LAN接口。如果ISP分配的是/64的地址,则需要使用第二个ia_pd instruction。这也会禁用除WAN接口之外的所有路由器请求。
提示:另请阅读dhcpcd(8)和dhcpcd.conf(5)。

a.2 systemd-networkd

配置上游(WAN)和下游(LAN)接口。这将在运行DHCPv6客户端的接口上启用DHCPv6-PD。委托前缀由IPv6路由器在下游网络上分发。
/etc/systemd/network/wan.network
[Network]
# Use 'yes' instead of 'ipv6' for both ipv4 and ipv6.
DHCP=ipv6
/etc/systemd/network/lan.network
[Network]
IPv6SendRA=yes
DHCPv6PrefixDelegation=yes

a.3 其他客户端

dhclient也可以请求前缀,但是必须使用dhclient退出脚本将该前缀或该前缀的一部分分配给接口。例如: 
https://github.com/jaymzh/v6-gw-scripts/blob/master/dhclient-ipv6

b. Disable 禁用 IPv6

注意: Arch内核直接内置了IPv6支持,因此不能将模块列入黑名单。

b.1 禁用功能

  • 添加ipv6.disable=1到内核​​行会禁用整个IPv6堆栈,如果遇到问题,这可能就是您想要的。有关更多信息,请参见内核参数。https://wiki.archlinux.org/title/Kernel_parameters
  • 或者,添加ipv6.disable_ipv6=1将保持IPv6堆栈正常运行,但不会将IPv6地址分配给您的任何网络设备。
  • 通过将以下sysctl配置添加到/etc/sysctl.d/40-ipv6.conf,可以避免系统将IPv6地址分配给特定的网络接口:
# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.nic0.disable_ipv6 = 1
...
net.ipv6.conf.nicN.disable_ipv6 = 1
重新启动systemd-sysctl.service单元以应用配置更改。
注意你必须在这里清楚地列出所有不需要分配IPv6地址的网卡,仅仅设置all.disable_ipv6并不会立刻对已经连接的网卡起作用。

注意:如果通过sysctl禁用IPv6,则应注释掉/etc/hosts中的IPv6主机。否则,可能会出现一些连接错误,因为主机已解析为无法访问的IPv6地址。
#<ip-address> <hostname.domain.org> <hostname>
127.0.0.1 localhost.localdomain localhost
#::1 localhost.localdomain localhost

b.2 其他程序

在内核中关闭IPv6功能不会阻止应用程序尝试使用IPv6。多数情况下,这样不会有问题,但如果你发现程序无法正常运行,你应该查阅该应用程序的手册页,以找到关闭IPv6的合适方法。

b.2.1 dhcpcd

dhcpcd会尝试发送IPv6路由器请求。要禁用这种行为,可以依照其手册页dhcpcd.conf (5),向/etc/dhcpcd.conf加入如下内容: 
noipv6rs
noipv6

b.2.2 NetworkManager

要在NetworkManager中禁用IPv6,请右键单击网络状态图标,然后选择: 
“编辑连接”>“有线”>“网络名称” >“编辑”>“ IPv6设置”>“方法”>“忽略/禁用”
Edit Connections > Wired > Network name > Edit > IPv6 Settings > Method > Ignore/Disabled

然后点击“保存”。

在命令行终端下,关闭IPv6支持可以使用nmcli:
$ sudo nmcli connection edit connection0
其中,connection0是要修改的网络名称。nmcli运行后进入其命令行,输入如下命令:
nmcli> set ipv6.method ignore 
连接到该网络时,NetworkManager不会再配置该网络的IPv6地址。

b.2.3 ntpd

依照Systemd#Drop-in files,修改ntpd.service的启动方式:
$ sudo systemctl edit ntpd.service
这样会产生一个drop-in snippet,替代原有的ntpd.service来加载ntpd。参数-4关闭了ntpd的IPv6支持。向drop-in snippet中加入如下内容:
[Service]
ExecStart=
ExecStart=/usr/bin/ntpd -4 -g -u ntp:ntp
第一行清除了之前的ExecStart配置,接下来的一行将该配置设置为带有-4参数的ntpd。

b.2.4 GnuPG

在dirmngr的配置文件中禁用IPv6 :
~/.gnupg/dirmngr.conf
disable-ipv6
并重新启动用户服务 dirmngr.service。

b.2.5 sshd

通过将以下内容添加到来确保sshd使用的是ipv4 sshd_config:
/etc/ssh/ssh_config
AddressFamily inet
并重新启动sshd.service。

b.3 systemd-networkd

networkd支持在每个接口上禁用IPv6。当网络单元的[Network]部分具有LinkLocalAddressing=ipv4或LinkLocalAddressing=no时,networkd不会尝试在匹配的接口上配置IPv6。
但是请注意,即使未使用上述选项,如果未全局禁用IPv6,networkd仍将期望接收路由器通告。如果接口未接收到IPv6流量(例如,由于sysctl或ip6tables设置),它将保持配置状态,并可能导致等待网络完全配置的服务超时。为避免这种情况,IPv6AcceptRA=no还应该在[Network]中设置该选项。

c. 在IPv6上优先使用IPv4

在配置文件中/etc/gai.conf 取消注释以下行:
#
#    For sites which prefer IPv4 connections change the last line to
#
precedence ::ffff:0:0/96  100

2021-05-26

nftables-simple-firewall

1. 简单的防火墙
2. Typical workstation (separate IPv4 and IPv6)
3. 编辑规则
4. 停用iptables及ip6tables, 启动nftables. 
5. 更多链接

Arch Linux默认启用IPv6, 所以防火墙也要启用ip6.
iptables: (iptables, ip6tables); nftables: (nft的ip及ip6地址族或inet地址族).
一个同时支持nftable和iptables的图形化前端是firewalld
https://wiki.archlinux.org/title/Firewalld

1. 简单的防火墙

nftables带有存储在/etc/nftables.conf文件中的简单安全的防火墙配置。
启动nftables.service时候会从该文件中加载规则。
当前规则集可以使用以下命令打印:
$ sudo nft list ruleset
查看文件, 一个inet(IPv4/IPv6)类型的filter表, 包含3个规则链, input链包含6条规则...
$ cat /etc/nftables.conf
table inet filter {
  chain input {
1 允许 已连接及相关数据包通过
2 丢弃 失效包
3 允许 lo环路
4 允许 icmp
5 允许 ssh
6 驳回 其他情况  }
  chain forward { 丢弃 转发 }
  chain output { 放行 }}

2. Typical workstation (separate IPv4 and IPv6)

https://wiki.gentoo.org/wiki/Nftables/Examples#Typical_workstation_.28separate_IPv4_and_IPv6.29

 /etc/nftables.rules
#!/bin/nft -f

flush ruleset

# ----- IPv4 -----
table ip filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state invalid counter drop comment "early drop of invalid packets"
		ct state {established, related} counter accept comment "accept all connections related to connections made by us"
		iif lo accept comment "accept loopback"
		iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
		ip protocol icmp counter accept comment "accept all ICMP types"
		tcp dport 22 counter accept comment "accept SSH"
		counter comment "count dropped packets"
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		counter comment "count dropped packets"
	}

	# If you're not counting packets, this chain can be omitted.
	chain output {
		type filter hook output priority 0; policy accept;
		counter comment "count accepted packets"
	}
}


# ----- IPv6 -----
table ip6 filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state invalid counter drop comment "early drop of invalid packets"
		ct state {established, related} counter accept comment "accept all connections related to connections made by us"
		iif lo accept comment "accept loopback"
		iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
		ip6 nexthdr icmpv6 counter accept comment "accept all ICMP types"
		tcp dport 22 counter accept comment "accept SSH"
		counter comment "count dropped packets"
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		counter comment "count dropped packets"
	}

	# If you're not counting packets, this chain can be omitted.
	chain output {
		type filter hook output priority 0; policy accept;
		counter comment "count accepted packets"
	}
}
与安装nftables自带的增加了一条规则: drop connections to loopback not coming from loopback
另外包含计数器; IPv4和IPv6分别设置. 可以分别看到各自过滤的数据包.
要使用这个, 可以直接将内容复制到配置文件: /etc/nftables.conf; 然后重启nftables.service服务即可加载新的配置.
$ sudo nft list ruleset 

合并的inet表
https://wiki.gentoo.org/wiki/Nftables/Examples#Typical_workstation_.28combined_IPv4_and_IPv6.29
/etc/nftables.rules
#!/bin/nft -f

flush ruleset

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state invalid counter drop comment "early drop of invalid packets"
		ct state {established, related} counter accept comment "accept all connections related to connections made by us"
		iif lo accept comment "accept loopback"
		iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
		iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
		ip protocol icmp counter accept comment "accept all ICMP types"
		ip6 nexthdr icmpv6 counter accept comment "accept all ICMP types"
		tcp dport 22 counter accept comment "accept SSH"
		counter comment "count dropped packets"
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		counter comment "count dropped packets"
	}

	# If you're not counting packets, this chain can be omitted.
	chain output {
		type filter hook output priority 0; policy accept;
		counter comment "count accepted packets"
	}
}

3. 编辑规则

普通用户若不需要ssh, 可以删除相关行. 若需要增加开放端口, 也可以参照添加行, 修改好文件保存后, 重启服务. 

或者使用nft命令编辑规则...
新增规则
$ sudo nft add rule family_typetable_namechain_name handle handle_valuestatement
规则附加在处handle_value,这是可选的。如果未指定,则规则将附加到链的末尾。
插入规则
$ sudo nft insert rule family_type table_name chain_name handle handle_value statement
如果handle_value未指定,则规则在链之前。
删除
单个规则只能通过其句柄删除。该nft --handle list命令必须用于确定规则句柄。注意该--handle开关,该开关nft在其输出中告知要列出的手柄。
以下内容确定规则的句柄,然后将其删除。该--numeric参数对于查看某些数字输出(如未解析的IP地址)很有用。
$ sudo nft --handle --numeric list ruleset
$ sudo nft delete rule inet my_table my_input handle 10

Atomic reloading
Flush the current ruleset:
$ sudo echo "flush ruleset" > /tmp/nftables 
Dump the current ruleset:
$ sudo nft -s list ruleset >> /tmp/nftables
Now you can edit /tmp/nftables and apply your changes with:
$ sudo nft -f /tmp/nftables

ADDRESS FAMILIES: (family_type)
简单防火墙只需使用地址家族的前3个(ip和ip6 或者 inet).
  • ip IPv4 address family. 是默认系列,如果未指定系列,则将使用该系列。
  • ip6 IPv6 address family.
  • inet Internet (IPv4/IPv6) address family.
  • arp      ARP address family, handling IPv4 ARP packets.
  • bridge   Bridge address family, handling packets which traverse a bridge device.
  • netdev   Netdev address family, handling packets from ingress.

4. 停用iptables及ip6tables, 启动nftables.

$ sudo systemctl disable iptables.service
Removed /etc/systemd/system/multi-user.target.wants/iptables.service.
$ sudo systemctl disable ip6tables.service
Removed /etc/systemd/system/multi-user.target.wants/ip6tables.service.
$ sudo systemctl enable nftables.service
Created symlink /etc/systemd/system/multi-user.target.wants/nftables.service → /usr/lib/systemd/system/nftables.service.

5. 更多链接

https://wiki.archlinux.org/title/Nftables
https://wiki.gentoo.org/wiki/Nftables
https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes
https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Simple_IP.2FIPv6_Firewall
https://szosoft.blogspot.com/2019/05/linux-nftables.html
https://www.cnblogs.com/sztom/p/10947111.html
https://wiki.archlinux.org/title/Nftables#Simple_firewall
https://wiki.nftables.org/wiki-nftables/index.php/Moving_from_iptables_to_nftables
https://kernelnewbies.org/nftables_examples
https://wiki.gentoo.org/wiki/Nftables/Examples


2021-05-23

ip6tables-simple-stateful-firewall

 
1. Disable IPv6
2. 参照IPv4生成IPv6配置文件
	2.1 对比表
	2.2 行描述
	2.3 补充raw表
3. 保存规则并启用服务

摘录自: https://wiki.archlinux.org/title/Simple_stateful_firewall#IPv6

1. Disable IPv6

如果不使用IPv6,则可以考虑将其禁用,否则请按照以下步骤启用IPv6防火墙规则。
https://wiki.archlinux.org/title/IPv6#Disable_IPv6
https://wiki.archlinux.org/title/Disabling_IPv6

2. 参照IPv4生成IPv6配置文件

复制此示例中使用的IPv4规则作为基础,并将所有IP从IPv4格式更改为IPv6格式:
$ sudo cp /etc/iptables/iptables.rules /etc/iptables/ip6tables.rules

2.1 对比表

L4 $ cat /etc/iptables/iptables.rules 描述 L6 $ cat /etc/iptables/ip6tables.rules

*filter

*filter

:INPUT DROP [0:0] 丢弃所有入站
:INPUT DROP [0:0]

:FORWARD DROP [0:0] 丢弃所有转发
:FORWARD DROP [0:0]

:OUTPUT ACCEPT [0:0] 允许本地出站, 信任局域网
:OUTPUT ACCEPT [0:0]

:TCP - [0:0] TCP端口的自定义链
:TCP - [0:0]

:UDP - [0:0] UDP端口的自定义链
:UDP - [0:0]
1 -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 允许已连接及相关通讯 1 -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
2 -A INPUT -i lo -j ACCEPT 允许本地环回 2 -A INPUT -i lo -j ACCEPT
3 -A INPUT -m conntrack --ctstate INVALID -j DROP 丢掉失效包... 3 -A INPUT -m conntrack --ctstate INVALID -j DROP
4 -A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT 仅允许ping; || 允许ICMPv6流量 4 -A INPUT -s fe80::/10 -p ipv6-icmp -j ACCEPT


|| 允许DHCPv6 5 -A INPUT -p udp -m udp --sport 547 --dport 546 -j ACCEPT
5 -A INPUT -p udp -m conntrack --ctstate NEW -j UDP 仅允许新的UDP请求. 6 -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
6 -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP 仅允许新的TCP请求. 7 -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
7 -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable 驳回udp: icmp不可达 || ICMPv6码 8 -A INPUT -p udp -j REJECT --reject-with icmp6-adm-prohibited
8 -A INPUT -p tcp -j REJECT --reject-with tcp-reset 驳回tcp 9 -A INPUT -p tcp -j REJECT --reject-with tcp-reset
9 -A INPUT -j REJECT --reject-with icmp-proto-unreachable 驳回:icmp不可达 || ICMPv6码 10 -A INPUT -j REJECT --reject-with icmp6-adm-prohibited


|| … 11 -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT

COMMIT

COMMIT
相同的行(IPv4 = IPv6)为绿色; 不同的行用橙色描述. 下面是不同的行的描述。

2.2 行描述

- IPv6第(8, 10)行, 对应IPv4版本的第(7, 9)行
ICMP协议已在IPv6中进行了更新,取代了与IPv4一起使用的ICMP协议。拒绝错误返回代码--reject-with icmp-port-unreachable和--reject-with icmp-proto-unreachable必须转换到的ICMPv6码。
RFC 4443中列出了可用的ICMPv6错误代码,该代码指定应使用被防火墙规则阻止的连接尝试--reject-with icmp6-adm-prohibited。这样做基本上可以通知远程系统该连接已被防火墙而不是侦听服务拒绝。
如果最好不要明确告知防火墙过滤器的存在,则也可以在没有以下消息的情况下拒绝该数据包:
 -A INPUT -j REJECT
上面的代码将拒绝,默认返回错误为--reject-with icmp6-port-unreachable。但是,您应该注意,识别防火墙是端口扫描应用程序的基本功能,并且大多数人都会识别它。

- IPv6第(11)行, 确保将协议和扩展名更改为适用于关于所有新的传入ICMP回显请求(ping)的规则的IPv6:
$ sudo ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT

- IPv6第(4)行, Netfilter conntrack似乎没有跟踪ICMPv6邻居发现协议(ARP的IPv6等效协议),因此我们需要允许ICMPv6流量,而不管所有直接连接的子网的状态如何。在放置在--ctstate INVALID之后,但在任何其他DROP或REJECT目标之前,应插入以下内容,以及每个直接连接的子网的对应行:
$ sudo ip6tables -A INPUT -s fe80::/10 -p ipv6-icmp -j ACCEPT

- IPv6第(5)行
, 如果要启用DHCPv6,则需要接受UDP端口546上的传入连接:
$ sudo ip6tables -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT

2.3 补充raw表

由于没有针对IPv6的内核反向路径过滤器,因此您可能需要在ip6tables中启用以下内容:
$ sudo ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT
$ sudo ip6tables -t raw -A PREROUTING -j DROP

3. 保存规则并启用服务

现在,规则集已完成,应将其保存到文件中,以便可以在每次引导时加载它们。
$ sudo ip6tables-save -f /etc/iptables/ip6tables.rules
$ sudo ip6tables -nvL --line-numbers

最后别忘了启用[enable]并启动[start] iptables.service和ip6tables.service。检查服务的状态[status],以确保正确加载了规则。
$ sudo systemctl status ip6tables.service

2021-05-21

iptables-simple-stateful-firewall

 
1. 补充一些基本概念
	1.1 OSI开放系统互联7层模型
	1.2 IPv4地址
2. iptables
	2.1 iptables 语法
	2.2 filter表对规则链的操作
	2.3 filter表对规则的操作
	2.4 filter表的基本匹配操作
3. 其他filter表匹配操作
	3.1 tcp filter表匹配操作
	3.2 udp filter表匹配操作
	3.3 icmp filter表匹配操作
4. filter 表目标扩展
5. filter 表匹配扩展
	5.1 multiport
	5.2 limit
	5.3 state
	5.4 mac
	5.5 owner
	5.6 mark
	5.7 tos
	5.8 addrtype
	5.9 iprange
	5.a length
	5.b. conntrack
6 简单防火墙
	6.1 准备
	6.2 一台机器的防火墙
	6.3 临时许可某端口


1. 补充一些基本概念

1.1 OSI开放系统互联7层模型

  • 7 应用层 软件:界面
  • 6 表示层 软件:加密/解密
  • 5 会话层 软件:
  • 4 传输层 系统:端口 TCP/UDP
  • 3 网络层 硬件:路由器 IP/ICMP
  • 2 链路层 硬件:网卡 MAC
  • 1 物理层 硬件:网线

一些名词

  • 面向连接协议: TCP
  • 无连接协议: UDP, IP
  • ICMP: 控制报文协议 (Internet Control Message Protocol) 主要用于ping
  • UDP: 用于DNS查询, SNMP(简单网络管理协议), RADIUS(远程用户拨号认证系统)等
  • MAC(48bit): Media Access Control 介质访问控制
  • ARP: 地址解析协议 Address Resolution Protocol 用于关联一个物理设备网卡和IP, $ cat /proc/net/arp

1.2 IPv4地址

IPv4 共32位: 4 * 8 bit; 总共约40亿, 减去私有地址和D,E类, 只有约30亿. 
但由于NAT技术, 使得私有地址可以反复无限制的使用, 使得IP总数成为无限... 
但是增加的网络复杂程度.出错率.损失了网速.
IPv6 共128位: 8组冒号分隔的十六进制表示. 数量足够大, 目前的技术还用不完.
IPv4 还在向 IPv6 过渡... 

IPv4的5类地址, 私有地址及其他地址: 

cl IP-Begin IP-End 默认子网演码 子网数量 单网容量 总容量 备注
A 0.0.0.0 127.255.255.255 255.0.0.0 126 16387064 2064770064 互联网使用
B 128.0.0.0 191.255.255.255 255.255.0.0 14994 64516 967352904
C 192.0.0.0 223.255.255.255 255.255.255.0 7874 254 1999996
D 224.0.0.0 239.255.255.255
15

组播
E 240.0.0.0 255.255.255.255
15

实验
cl 私有-起 私有-止 默认子网演码 子网数量 单网容量 总容量 备注
A 10.0.0.0 10.255.255.255 255.0.0.0 1 16387064 16387064 跨国公司
B 172.16.0.0 172.31.255.255 255.255.0.0 16 64516 1032256 大型公司
C 192.168.0.0 192.168.255.255 255.255.255.0 1 254 254 小公司,家庭
cl IP-Begin IP-End 默认子网演码 子网数量 单网容量 总容量 备注
A 100.64.0.0 100.127.255.255 运营商级NAT 63 64516 4064508
B 169.254.0.0 169.254.255.255 链路本地网络地址


DHCP异常
C 192.0.2.0 192.0.2.255 测试网络地址



特殊地址还有:0; 127; 255

  • 0:网络地址 IPv4[0.0.0.0]; IPv6[::/0]
  • 127:回环地址 IPv4[127.0.0.1]; IPv6[::1]
  • 255:广播地址 IPv4[~255]; IPv6不使用广播, 使用组播.

2. iptables

Netfilter 防火墙; iptables 防火墙管理程序. Linux3.13, 新的过滤机制被加入: nftables.
Netfilter(iptables)使用了3个内置的过滤器链: input, output, forward.
Netfilter防火墙有3个独立的表: (filter:默认基础表, nat:NAT转换, mangle:对数据包特殊处理); 其他表: (raw, security).
https://wiki.archlinux.org/title/Iptables
https://www.netfilter.org/projects/iptables/index.html
https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
https://en.wikipedia.org/wiki/Iptables
2种处理不需要的包的方式
  • REJECT 驳回 Rejecting 数据包被丢弃, 返回ICMP错误消息; 
  • DROP 丢弃 Denying 静静的丢掉数据包... 

2.1 iptables 语法

iptables <option> <chain> <matching criteria> <target>

  • option 选项, 1个或多个: -A 追加
  • chain 规则链, : input, output, forward, 其他自定义...
  • match 匹配标准集, 应用条件: 端口等...
  • target 目标或处置disposition: drop 丢弃; accept 接受

2.2 filter表对规则链的操作

  • -N <chain>  创建一个用户自定义的规则链
  • -F <chain>  清空此规则链中的规则, 如果没有指定规则链, 则清空所有规则链中的规则
  • -X <chain>  删除用户自定义规则链, 如果没有指定规则链, 则删除所有用户自定义规则链
  • -P <chain> <policy>  为内建规则链(INPUT, OUTPUT, FORWARD)设置默认策略: ACCETP or DROP
  • -L <chain>  列出此规则链中的规则, 如果没有指定规则链, 则列出所有规则链中的规则
  • -Lnv <chain>  同上, n显示IP及端口号而不是名称, v显示数据包和字节数.
  • -L --line-numbers 显示规则在规则链中的行号
  • -S <chain>  以iptables save格式显示
  • -Z <chain>  重置与每个规则链相关的数据包和字节计数器. 
  • -h | <some command> -h  列出相关命令和选项
  • -E <old chain>  重命名用户自定义规则链

2.3 filter表对规则的操作

  • -A <chain> <rule specification>  将一条规则添加到规则链的末尾
  • -I <chain> [<rule number>]  将一条规则插入到规则行号前. 若不指定行号, 则插入为第一条规则
  • -R <chain> <rule number>  替换规则链中的该行号的规则
  • -D <chain> <rule number>  删除规则链中的该行号的规则
  • -C <chain> <rule specification>  检查规则链中是否有某条规则匹配<rule specification>

2.4 filter表的基本匹配操作

  • -i <interface>  在INPUT, FORWARD或用户自定义规则链中, 对传入数据包指定规则将应用到的接口名. 如果没有指定接口名, 规则默认应用与所有接口.
  • -o <interface>  在OUTPUT, FORWARD或用户自定义规则链中, 对传出数据包指定规则将应用到的接口名. 如果没有指定接口名, 规则默认应用与所有接口.
  • -p [<protocol>]  制定规则应用到的IP协议, 内建协议有TCP, UDP, ICMP等. 协议值可以是名称或数值: $ cat /etc/protocols
  • -s [!] <address>[</mask>]  指定IP报头中的主机或网络源地址
  • -d [!] <address>[</mask>]  指定IP报头中的主机或网络目的地址
  • -j <target>  jump 如果数据包匹配规则, 则设置此数据包的处置策略, 默认目标包括内建的策略, 扩展策略, 或用户自定义规则链
  • -g <chain>  goto 指明此过程应该在指定的规则链中继续, 但不必发挥处理.(类似-j选项)
  • -m <match>  使用扩展来测试是否匹配
  • [!] -f  指定数据包的第二个和其余的分片. 否定的版本指定了非分片的数据包.
  • -c <packets> <bytes>  初始化数据包和字节计数器

规则目标是可选的: 如果数据包匹配了没有目标处置的某条规则, 则数据包计数器会被更新, 但规则链的遍历则会继续进行.

3. 其他filter表匹配操作

3.1 tcp filter表匹配操作

$ iptables -p tcp -h
tcp match options:
[!] --tcp-flags mask comp match when TCP flags & mask == comp 对屏蔽列表位进行测试, 其中下列位必须设置为1, 才能够实现匹配
(Flags: SYN ACK FIN RST URG PSH ALL NONE)
[!] --syn match when only SYN flag set  在初始连接请求中, 必须设置SYN标志.
(equivalent to --tcp-flags SYN,RST,ACK,FIN SYN)
[!] --source-port port[:port]   指明源端口
 --sport ... match source port(s)
[!] --destination-port port[:port]  指明目的端口
 --dport ... match destination port(s)
[!] --tcp-option number        match if TCP option set  tcp唯一的合法选项是发送方能接受的数据包的最大值

3.2 udp filter表匹配操作

$ iptables -p udp -h
udp match options:
[!] --source-port port[:port]
 --sport ... match source port(s)
[!] --destination-port port[:port]
 --dport ... match destination port(s)

3.3 icmp filter表匹配操作

$ iptables -p icmp -h
icmp match options:
[!] --icmp-type typename match icmp type  指定ICMP名称, ICMP类型被用于代替源端口号
[!] --icmp-type type[/code] (or numeric type or type/code) 或类型号.
Valid ICMP Types:
...

4. filter 表目标扩展

iptables -j <TARGET> -h

  • $ iptables -j LOG -h  日志记录
  • $ iptables -j REJECT -h  驳回
  • $ iptables -j ULOG -h  扩展日志记录

5. filter 表匹配扩展

$ iptables -m icmp -h
$ iptables -m tcp -h
$ iptables -m udp -h

5.1 multiport

$ iptables -m multiport -h
multiport match options:
[!] --source-ports port[,port:port,port...]
 --sports ... match source port(s)  指定源端口
[!] --destination-ports port[,port:port,port...]
 --dports ... match destination port(s)  指定目的端口
[!] --ports port[,port:port,port] match both source and destination port(s)  源端口和目的端口相同, 并和列表中的端口匹配

5.2 limit

$ iptables -m limit -h
limit match options:
--limit avg max average match rate: default 3/hour  在指定时间内匹配数据包的最大值
                                [Packets per second unless followed by /sec /minute /hour /day postfixes]
--limit-burst number number to match in a burst, default 5  在应用限制前匹配的初始数据包的最大值

5.3 state

$ iptables -m state -h
state match options:
 [!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...] State(s) to match 如果连接状态在列表中, 则进行匹配

5.4 mac

$ iptables -m mac -h
mac match options:
[!] --mac-source XX:XX:XX:XX:XX:XX Match source MAC address  匹配二层MAC地址, 在传入以太帧中以xx...xx(6组8进制)形式指定

5.5 owner

$ iptables -m owner -h
owner match options:
[!] --uid-owner userid[-userid]      Match local UID
[!] --gid-owner groupid[-groupid]    Match local GID
[!] --socket-exists                  Match if socket exists
    --suppl-groups                   Also match supplementary groups set with --gid-owner

5.6 mark

$ iptables -m mark -h
mark match options:
[!] --mark value[/mask]    Match nfmark value with optional mask

5.7 tos

$ iptables -m tos -h
tos match options:
[!] --tos value[/mask]    Match Type of Service/Priority field value
[!] --tos symbol          Match TOS field (IPv4 only) by symbol
                          Accepted symbolic names for value are:
                          (0x10) 16 Minimize-Delay
                          (0x08)  8 Maximize-Throughput
                          (0x04)  4 Maximize-Reliability
                          (0x02)  2 Minimize-Cost
                          (0x00)  0 Normal-Service

5.8 addrtype

$ iptables -m addrtype -h
Address type match options:
 [!] --src-type type[,...]      Match source address type
 [!] --dst-type type[,...]      Match destination address type
     --limit-iface-in           Match only on the packet's incoming device
     --limit-iface-out          Match only on the packet's outgoing device
Valid types:           
                                UNSPEC
                                UNICAST
                                LOCAL 本地地址
                                BROADCAST 广播地址
                                ANYCAST 任意数据包
                                MULTICAST 组播地址
                                BLACKHOLE 黑洞地址
                                UNREACHABLE 不可达地址
                                PROHIBIT 禁止地址
                                THROW
                                NAT
                                XRESOLVE

5.9 iprange

$ iptables -m iprange -h
iprange match options:
[!] --src-range ip[-ip]    Match source IP in the specified range
[!] --dst-range ip[-ip]    Match destination IP in the specified range

5.a length

$ iptables -m length -h
length match options:
[!] --length length[:length]    Match packet length against value or range of values (inclusive)

5.b conntrack

$ iptables -m conntrack -h
conntrack match options:
[!] --ctstate {INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED|SNAT|DNAT}[,...] State(s) to match 匹配状态
[!] --ctproto proto            Protocol to match; by number or name, e.g. "tcp"
[!] --ctorigsrc address[/mask]
[!] --ctorigdst address[/mask]
[!] --ctreplsrc address[/mask]
[!] --ctrepldst address[/mask] Original/Reply source/destination address
[!] --ctorigsrcport port
[!] --ctorigdstport port
[!] --ctreplsrcport port
[!] --ctrepldstport port TCP/UDP/SCTP orig./reply source/destination port
[!] --ctstatus {NONE|EXPECTED|SEEN_REPLY|ASSURED|CONFIRMED}[,...] Status(es) to match
[!] --ctexpire time[:time]     Match remaining lifetime in seconds against value or range of values (inclusive)
    --ctdir {ORIGINAL|REPLY}   Flow direction of packet

6. 简单防火墙

$ ll /etc/iptables/
lrwxrwxrwx  1 root root   36 2021-01-21 05:31 empty.rules -> ../../usr/share/iptables/empty.rules
-rw-r--r--  1 root root  105 2021-01-21 05:31 ip6tables.rules
-rw-r--r--  1 root root  728 2021-05-20 22:59 iptables.rules
lrwxrwxrwx  1 root root   46 2021-01-21 05:31 simple_firewall.rules -> ../../usr/share/iptables/simple_firewall.rules
$ cat /usr/share/iptables/simple_firewall.rules 
这里的simple_firewall.rules就是系统自带的可用于普通用户电脑的简单防火墙. 
最简单的使用方式就是用这个文件覆盖iptables.rules, 然后重新运行iptable服务即可. 

下面是摘录自arch页面用于单台计算机的防火墙的内容, 或许比上面那个最简单的稍微好一点点. 更重要的是, 每个步骤都有说明.
https://wiki.archlinux.org/title/Simple_stateful_firewall

6.1 准备

本文假定当前没有设置iptables规则. 要检查当前规则集并验证当前没有规则, 请运行以下命令:
$ sudo iptables-save
or
$ sudo iptables -nvL --line-numbers
如果有规则, 则可以通过加载默认规则集来重置规则:
$ sudo iptables-restore < /etc/iptables/empty.rules

6.2 一台机器的防火墙

注意: 由于iptables以线性顺序处理规则(从上到下), 因此建议将频繁访问的规则放在链的开头附近. 
当然, 有一个限制, 具体取决于要实现的逻辑. 而且, 规则具有相关的运行时成本, 因此不应仅基于对字节/数据包计数器的经验观察来对规则进行重新排序. 
创建必要的链: 对于此基本设置, 我们将创建两个用户定义的链, 这些链将用于打开防火墙中的端口. 
$ sudo iptables -N TCP
$ sudo iptables -N UDP

转发链: 
$ sudo iptables -P FORWARD DROP

输出链: 在这个简单的示例中, 我们将OUTPUT链的默认策略设置为ACCEPT, 以允许所有出站流量. 这不太安全, 但是与许多系统高度兼容. 
$ sudo iptables -P OUTPUT ACCEPT

输入链: 与以前的链类似, 我们将INPUT链的默认策略设置为DROP, 以防某些情况导致我们的规则滑脱. 丢弃所有流量并指定允许的内容是制造安全防火墙的最佳方法. 这里暂不考虑ssh等服务.
$ sudo iptables -P INPUT DROP

如果任何网络接口接收到的每个数据包都发往本机, 则它将首先通过INPUT链. 在此链中, 我们确保仅接受所需的数据包.
添加到INPUT链的第一个规则将允许属于已建立连接的流量, 或与这些连接相关的新有效流量.
例如ICMP错误或回显答复(主机被ping后返回的数据包). ICMP代表Internet控制消息协议. 一些ICMP消息非常重要, 有助于管理拥塞和MTU, 并且被以下规则接受: 
$ sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

连接状态ESTABLISHED表示, 另一个规则先前允许进行初始(--ctstate NEW)连接尝试, 或者该连接已经处于活动状态(例如, 活动的远程SSH连接).
第二条规则将接受来自“环回”(lo)接口的所有流量, 这对于许多应用程序和服务都是必需的. 
$ sudo iptables -A INPUT -i lo -j ACCEPT

第三条规则将丢弃状态匹配为“INVALID”的所有流量.
流量可以分为四个“状态”state: (NEW 新的, ESTABLISHED 已建立的, RELATED 相关的 或 INVALID无效的), 这就是使它成为“有状态”防火墙而不是不太安全的“无状态”防火墙的原因.
使用“nf_conntrack_ *”内核模块跟踪状态, 这些模块在添加规则时由内核自动加载.
$ sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

下一条规则将接受所有新的传入ICMP回显请求, 也称为ping. 只有第一个数据包将被视为新数据包, 其他数据包将由RELATED, ESTABLISHED规则处理. 由于计算机不是路由器, 因此不需要允许其他状态为NEW的ICMP通信.
$ sudo iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT

现在, 我们将TCP和UDP链附加到INPUT链, 以处理所有新的传入连接. 一旦连接被TCP或UDP链接受, 则由RELATED/ESTABLISHED通信规则处理. TCP和UDP链将接受新的传入连接, 或者有礼貌地拒绝它们. 新的TCP连接必须以SYN数据包开始.
注意: NEW(不是SYN)是INVALID状态未涵盖的唯一无效TCP标志. 这是因为它们很少是恶意数据包, 不应仅被丢弃. 取而代之的是, 它们将由下一条规则简单地通过TCP RESET拒绝.
$ sudo iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
$ sudo iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP

如果未打开端口, 我们将拒绝带有TCP RESET数据包的TCP连接和带有ICMP端口不可达消息的UDP流. 这模仿了默认的Linux行为(符合RFC), 并允许发送方快速关闭连接并进行清理.
$ sudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
$ sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

对于其他协议, 我们向INPUT链添加最终规则, 以拒绝icmp协议不可达消息的所有剩余传入流量. 这模仿了Linux的默认行为.
$ sudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable

生成的iptables.rules文件, 首先查看: 
$ sudo iptables -nvL --line-numbers
$ sudo iptables -S

该文件可以通过以下方式生成和保存: 
$ sudo iptables-save -f /etc/iptables/iptables.rules

6.3 临时许可某端口

若在局域网内有与其他局域网分享文件的需要, 可以使用时手动添加相应的端口, 这些临时开放的规则不必保存到文件.
要在Web服务器的端口8000上接受传入的TCP连接, 请执行以下操作:
$ sudo iptables -A TCP -p tcp --dport 8000 -j ACCEPT

若不再需要了可进行删除操作: 若不删除, 这个没有保存到配置文件的, 重启后也不会存在.
$ sudo iptables -nvL --line-numbers
$ sudo iptables -D <rule number>

最后别忘了重启服务
$ sudo systemctl status iptables.service
$ sudo systemctl restart iptables.service
$ sudo systemctl enable iptables.service

2021-05-18

Two-PC-direct-connection

1. 双机直连
2. 网线
3. 查看网卡
	3.1 lspci命令, 查看板载及PCI网卡
	3.2 lsusb命令, 查看USB网卡
	3.3 dmesg,lsmod, 查看硬件加载信息
4. 手动设置IP地址
5. 开启简单网络服务
6. 其他

1. 双机直连

Q: 当前有2台电脑都是Windows与Linux双系统, 有时会需要互相之间传递文件.

硬件: 通过一条网线直连, 不依赖额外的路由器.
系统: 因为2台都是双系统, 所以有如下3种情况随时发生...

  • (Linux to Linux)
  • (Windows to Windows)
  • (Linux to Windows) or (Windows to Linux)

IP设置: 这里看到同一台电脑, 双系统的IP设置为相同, 被访问时, 都是相同的地址.

  • 电脑A(Windows & Linux): 192.168.1.1/24
  • 电脑B(Windows & Linux): 192.168.1.3/24

软件: python https://www.python.org/downloads/

Linux下通常都会安装; windows下只需下载解压缩版本, 不必安装, 解压即可, 将目录添加到电脑属性的路径中.

2. 网线

8P8C,常被误称为RJ45,是以太网使用双绞线连接时常用的一种连接器插头。
8P8C(8 position 8 contact)的意思是8个位置(Position,指8个凹槽)、8个触点(Contact,指8个金属接点)。

  • 在T568A中,与之相连的8根线分别定义为:白绿、绿;白橙、蓝;白蓝、橙;白棕、棕。
  • 在T568B中,与之相连的8根线分别定义为:白橙、橙;白绿、蓝;白蓝、绿;白棕、棕。

连线信号

在百兆以太网(Fast Ethernet、10/100M Ethernet)中,仅使用1、2、3、6这四根线,以差分信号传输方式减少电磁干扰,其中1、2为TX(发送)(拧在一起),3、6为RX(接收)拧在一起。
因此平行线就是两端同为EIA-568-A或者EIA-568-B,而跳线就是一端使用EIA-568-A,另一端使用EIA-568-B的连接方法。
在千兆以太网(Gigabit Ethernet、1000M Ethernet)或者以太网供电(PoE, Power over Ethernet)中,全部的四对差分对都被使用。

3. 查看网卡

Windows系统下都是图形操作, 这里只记录Linux系统的命令行方式. 

3.1 lspci命令, 查看板载及PCI网卡

$ lspci -v
$ lspci -k
00:19.0 Ethernet controller: Intel Corporation 82562GT 10/100 Network Connection (rev 03)
Subsystem: Hewlett-Packard Company Device 30d8
Kernel driver in use: e1000e
Kernel modules: e1000e
10:00.0 Network controller: Intel Corporation PRO/Wireless 3945ABG [Golan] Network Connection (rev 02)
Subsystem: Hewlett-Packard Company Device 135d
Kernel driver in use: iwl3945
Kernel modules: iwl3945

3.2 lsusb命令, 查看USB网卡

$ lsusb
Bus 002 Device 016: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n Wireless Network Adapter

$ lsusb
Bus 002 Device 018: ID 148f:3070 Ralink Technology, Corp. RT2870/RT3070 Wireless Adapter

$ lsusb.py
  2-1               0bda:8179 00 1IF  [USB 2.00,   480 Mbps, 500mA] (Realtek 802.11n NIC 00E04C0001)

$ lsusb.py
  2-1               148f:3070 00 1IF  [USB 2.00,   480 Mbps, 450mA] (Ralink 802.11 n WLAN)

3.3 dmesg,lsmod, 查看硬件加载信息

$ sudo dmesg |grep iwl3945
$ sudo dmesg |grep e1000e
[    6.980802] e1000e: Intel(R) PRO/1000 Network Driver
[    6.980808] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    6.981191] e1000e 0000:00:19.0: Interrupt Throttling Rate (ints/sec) set to dynamic conservative mode
[    7.285699] e1000e 0000:00:19.0 eth0: (PCI Express:2.5GT/s:Width x1) 00:1a:4b:60:a3:a6
[    7.285717] e1000e 0000:00:19.0 eth0: Intel(R) PRO/10/100 Network Connection
[    7.285746] e1000e 0000:00:19.0 eth0: MAC: 6, PHY: 7, PBA No: FFFFFF-0FF
[    7.626080] e1000e 0000:00:19.0 enp0s25: renamed from eth0

$ sudo dmesg |grep -C 5 8179
[  678.524400] usb 2-1: new high-speed USB device number 16 using ehci-pci
[  678.675318] usb 2-1: New USB device found, idVendor=0bda, idProduct=8179, bcdDevice= 0.00
[  678.675329] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  678.675333] usb 2-1: Product: 802.11n NIC|
[  678.675336] usb 2-1: Manufacturer: Realtek
[  678.675339] usb 2-1: SerialNumber: 00E04C0001
[  678.726735] lib80211: common routines for IEEE802.11 drivers
[  678.726741] lib80211_crypt: registered algorithm 'NULL'
[  678.776406] r8188eu: module is from the staging directory, the quality is unknown, you have been warned.
[  678.783575] Chip Version Info: CHIP_8188E_Normal_Chip_TSMC_A_CUT_1T1R_RomVer(0)
[  678.824238] usbcore: registered new interface driver r8188eu

$ sudo dmesg |grep -C 5 3070
[  716.127755] usb 2-1: new high-speed USB device number 18 using ehci-pci
[  716.301386] usb 2-1: New USB device found, idVendor=148f, idProduct=3070, bcdDevice= 1.01
[  716.301395] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  716.301399] usb 2-1: Product: 802.11 n WLAN
[  716.301401] usb 2-1: Manufacturer: Ralink
[  716.524433] usb 2-1: reset high-speed USB device number 18 using ehci-pci
[  716.680507] ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 3070, rev 0201 detected
[  716.709018] ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 0005 detected
[  716.709300] ieee80211 phy1: Selected rate control algorithm 'minstrel_ht'
[  716.710382] usbcore: registered new interface driver rt2800usb

$ lsmod

Module                  Size  Used by
rt2800usb              28672  0
rt2x00usb              28672  1 rt2800usb
rt2800lib             139264  1 rt2800usb
rt2x00lib              90112  3 rt2800usb,rt2x00usb,rt2800lib
r8188eu               483328  0
lib80211               16384  1 r8188eu
iwl3945               122880  0
iwlegacy              147456  1 iwl3945
mac80211             1163264  5 iwl3945,iwlegacy,rt2x00lib,rt2x00usb,rt2800lib
cfg80211             1036288  5 iwl3945,iwlegacy,rt2x00lib,mac80211,r8188eu
e1000e                303104  0

4. 手动设置IP地址

列出网络设备
$ ip link

打开网卡
$ sudo ip link set enp0s25 up

手动设置IP地址
$ sudo ip address add 192.168.1.3/24 dev enp0s25

查看路由
$ ip route show
192.168.1.0/24 dev enp0s25 proto kernel scope link src 192.168.1.3 linkdown 

添加路由
$ sudo ip route add default via 192.168.1.1 dev enp0s25
$ ip route show
default via 192.168.1.1 dev enp0s25 linkdown
192.168.1.0/24 dev enp0s25 proto kernel scope link src 192.168.1.3 linkdown 

查看IP地址
$ ip address show

如果有安装相关的桌面版软件, 则可以如同Windows下一样, 图形化属性对话框内设置.
network-manager-applet, networkmanager...

5. 开启简单网络服务

进入需要分享的文件目录,开启简单网络服务(Windows与Linux下操作相似)
$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

按照上面IP设置为: 192.168.1.3, 开启简单网络服务默认端口为8000, 则同一网段其他主机可通过如下地址访问该文件目录: http://192.168.1.3:8000

这种分享文件的方式简单,安全,适应如下多种环境。
(Linux to Linux); (Windows to Windows); (Linux to Windows)

注: Window服务器的server服务, 默认是打开的, 且所有盘符都默认开启隐藏共享, 只要有权限的账户, 在局域网内任何一台机器都可以无限制的访问所有目录. 故建议将server服务关闭. 或者手动删除隐藏共享. 

更多更专业也更复杂的网络服务

6. 其他

如何设置一个本地测试服务器?
https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/set_up_a_local_testing_server

编辑 Web 服务器配置文件
https://www.ibm.com/docs/zh/was/9.0.5?topic=in-editing-web-server-configuration-files

https://wiki.archlinux.org/title/Network_configuration#IP_address_aliasing
将 IP 地址从接口中删除:
$ sudo ip address del address/prefix_len dev interface

删除所有符合条件的地址,例如某个特定接口的地址:
$ sudo ip address flush dev interface

要手动设置别名,可以使用 iproute2 执行:
$ sudo ip addr add 192.168.2.101/24 dev eth0 label eth0:1

删除别名:
$ sudo ip addr del 192.168.2.101/24 dev eth0:1

无线网卡命令有iw, iwd的iwctl, rfkill等
$ rfkill --output-all
ID TYPE DEVICE  TYPE-DESC         SOFT    HARD
 0 wlan hp-wifi Wireless LAN unblocked blocked
 1 wlan phy0    Wireless LAN unblocked blocked
$ rfkill --output-all
ID TYPE DEVICE  TYPE-DESC         SOFT      HARD
 0 wlan hp-wifi Wireless LAN unblocked unblocked
 1 wlan phy0    Wireless LAN unblocked unblocked


Diode

导航 (返回顶部) 1. Diode 1.1 Diode 概述 1.2 肖克利二极管方程 1.3 缩写 Abbreviations 2. 主要功能 2.1 单向电流 (Unidirectional current flow) 2.2 阈值电压 (Threshold...