2021-06-02

http-server

1. Lighttpd
	1.1 配置及验证
	1.2 测试安装结果
	1.3 基本日志记录
2. Nginx
	2.1 安装和启动
	2.2 配置及验证
		2.2.1 服务器块
		2.2.2 管理服务器入口
	2.3 FastCGI
		2.3.1 PHP实现
		2.3.2 nginx配置
		2.3.3 测试配置
3. Apache
	3.1 安装和启动
	3.2 配置及验证
		3.2.1 选项
		3.2.2 检查配置
	3.3 用户目录
	3.4 扩展PHP
		3.4.1 安装php-fpm
		3.4.2. 测试PHP是否有效

Apache Nginx, nginx-mainline Lighttpd ╦═╦ Php-fpm
/etc/httpd/conf/httpd.conf /etc/nginx/nginx.conf /etc/lighttpd/lighttpd.conf config /etc/php/php-fpm.conf
$ apachectl configtest $ nginx -t $ lighttpd -t -f /etc/lighttpd/lighttpd.conf
$ lighttpd -tt -f /etc/lighttpd/lighttpd.conf
配置验证 ../test.php
<?php phpinfo();
/srv/http ; ~/public_html /usr/share/nginx/html/ /srv/http/ root
httpd.service nginx.service lighttpd.service service php-fpm.service
http://localhost/
http://localhost/~tom/
配置工具:
https://nginxconfig.io/
示例配置:
/usr/share/doc/lighttpd/config/
Other http://127.0.0.1/test.php

1. Lighttpd

https://wiki.archlinux.org/title/Lighttpd
lighttpd是一个安全,快速,标准,且非常灵活的网页服务器,并对高性能环境做了最佳化。
相较于其他网页服务器,它占用的内存很少,且注重CPU负载量。

1.1 配置及验证

lighttpd配置文件: /etc/lighttpd/lighttpd.conf 在安装完成后它会自动生成一个用于测试的测试页面。
想要检查 lighttpd.conf 中的语法错误,可以使用以下命令来快速查找错误:
$ lighttpd -t -f /etc/lighttpd/lighttpd.conf
还可以进行更彻底的预检:
$ lighttpd -tt -f /etc/lighttpd/lighttpd.conf
示例配置文件在 /usr/share/doc/lighttpd/

1.2 测试安装结果

预设配置文件会把 /srv/http/ 指定为提供HTTP服务的文件目录。
$ sudo chmod 755 /srv/http/index.html
$ sudo echo 'Test-lighttpd' >> /srv/http/index.html

修改日志目录权限:
$ sudo chown -R http:http /var/log/lighttpd
启动服务:
$ sudo systemctl start lighttpd
然后就可以使用浏览器打开网址 localhost ,你应该能见到测试页面。
http://127.0.0.1/

1.3 基本日志记录

lighttpd 能够输出错误与访问记录到日志文件中。如下编辑/etc/lighttpd/lighttpd.conf以启用这两个日志选项:
server.modules += (
   "mod_access",
   "mod_accesslog",
)
server.errorlog   = "/var/log/lighttpd/error.log"
accesslog.filename = "/var/log/lighttpd/access.log"

2. Nginx

https://wiki.archlinux.org/title/Nginx
Nginx (读作"engine X") 由Igor Sysoev(俄罗斯)于2005年编写,是一个免费、开源、高性能的HTTP服务器和反向代理,也可以作为一个IMAP/POP3代理服务器。
Nginx因为稳定,丰富的功能集,配置简单,资源占用低而闻名世界。这篇文章描述了如何设置nginx并且如何通过#FastCGI集成PHP.

2.1 安装和启动

安装包 nginx-mainline(主线分支:新功能、更新、错误修复)或 nginx(稳定分支:仅主要错误修复)。
推荐使用主线分支。使用稳定分支的主要原因是,你关注的新功能可能产生的影响,如与第三方模块或无意引入的错误的不兼容的新功能。
注意:官方存储库中可用的所有 nginx 模块都需要nginx包(而不是nginx-mainline)作为依赖项。
在做出nginx与nginx-mainline决定之前,查看您可能需要/想要的任何模块列表可能是明智的。nginx-mainline 的模块可以在Arch User Repository 中找到。
$ sudo systemctl start nginx.service
http://127.0.0.1
访问到的默认页面是: /usr/share/nginx/html/index.html

2.2 配置及验证

https://nginx.org/en/docs/beginners_guide.html
https://wiki.nginx.org/Configuration
https://nginx.org/en/docs/
使用 nginx 的第一步在初学者指南中有所描述。您可以通过编辑中的文件来修改配置/etc/nginx/主配置文件位于/etc/nginx/nginx.conf.
更多细节和示例可以在https://wiki.nginx.org/Configuration和官方文档中找到。
下面的示例涵盖了最常见的用例。假定您使用文档的默认位置 (/usr/share/nginx/html)。如果不是这种情况,请替换您的路径。
提示: DigitalOcean 提供了一个Nginx 配置工具。https://nginxconfig.io/
配置验证
$ sudo nginx -t
2021/06/02 19:46:07 [warn] 2420#2420: could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

2.2.1 服务器块

https://www.nginx.com/resources/wiki/start/topics/examples/server_blocks/
可以使用server块为多个域提供服务。这些类似于Apache HTTP Server 中的“VirtualHosts” 。另请参阅上游示例。
在下面的示例中,服务器侦听两个域的 IPv4 和 IPv6 端口 80 上的传入连接,domainname1.dom并且domainname2.dom:
/etc/nginx/nginx.conf
...
server {
    listen 80;
    listen [::]:80;
    server_name domainname1.dom;
    root /usr/share/nginx/domainname1.dom/html;
    location / {
        index index.php index.html index.htm;
    }
}
server {
    listen 80;
    listen [::]:80;
    server_name domainname2.dom;
    root /usr/share/nginx/domainname2.dom/html;
    ...
}
重新启动 nginx.service以应用任何更改。
注意:通过设置像BIND或dnsmasq这样的 DNS 服务器来确保主机名是可解析的,或者查看网络配置#本地网络主机名解析。

2.2.2 管理服务器入口

把不同的server模块放到不同的文件里是可能的.这样的话可以让你很轻易的开启和禁用特定的站点.
创建以下文件夹:
$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled

在sites-available文件夹下创建一个文件包含一个或更多服务器模块:
/etc/nginx/sites-available/example.conf
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
}
把include sites-enabled/*;放到http 模块的末尾:
/etc/nginx/nginx.conf
...
http {
    ...
    include sites-enabled/*;
}
...
如果要启用一个网站, 只需要简单的创建一个符号链接:
$ sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/example.conf
如果要移除一个网站
$ sudo unlink /etc/nginx/sites-enabled/example.conf
Reload/restart nginx.service 来让配置生效.

2.3 FastCGI

FastCGI,也称为 FCGI,是一种用于将交互式程序与 Web 服务器连接的协议。FastCGI 是早期通用网关接口(CGI) 的变体;FastCGI 的主要目标是减少与 Web 服务器和 CGI​​ 程序接口相关的开销,允许服务器一次处理更多的网页请求。
FastCGI 技术被引入 nginx 以与许多外部工具一起工作,例如Perl、PHP和Python。

2.3.1 PHP实现

PHP-FPM是作为PHP 的FastCGI 服务器运行的推荐解决方案。
安装 php-fpm并确保PHP已正确安装和配置。PHP-FPM 的主要配置文件是/etc/php/php-fpm.conf. 对于基本使用,默认配置应该足够了。
$ sudo systemctl status php-fpm.service

2.3.2 nginx配置

当服务一个PHP web程序时,一个PHP-FPM的location应该包括在 #server代码块里,比如.:
/etc/nginx/sites-available/example.conf
server {
    root /usr/share/nginx/html;
    location / {
        index index.html index.htm index.php;
    }
    location ~ \.php$ {
        # 404
        try_files $fastcgi_script_name =404;
        # default fastcgi_params
        include fastcgi_params;
        # fastcgi settings
        fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        # fastcgi params
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        #fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
    }
}

若需要处理PHP以外的文件(html, htm): 
location ~ [^/]\.(php|html|htm)(/|$) {
    ...
}

非 .php 的PHP-FPM扩展处理都需要被直接加入到 /etc/php/php-fpm.d/www.conf:
security.limit_extensions = .php .html .htm

2.3.3 测试配置

重新启动php-fpm.service和nginx.service服务,以应用新配置。
要测试 FastCGI 实现,在web的根目录下(nginx.conf配置文件里server块的root项)创建包含如下信息的文件: test.php
<?php phpinfo();
在浏览器中导航此文件,您应该会看到包含当前 PHP 配置的信息页面。
http://127.0.0.1/test.php
PHP Version 8.0.6
System Linux tompc 5.12.8-arch1-1 #1 SMP PREEMPT Fri, 28 May 2021 15:10:20 +0000 x86_64
...

3. Apache

https://www.apache.org/
https://httpd.apache.org/docs/2.4/
https://wiki.apache.org/httpd/
https://wiki.apache.org/httpd/CommonMisconfigurations
https://wiki.archlinux.org/title/Apache_HTTP_Server
LAMP: 是指在许多web 服务器上使用的一个软件组合:Linux,Apache,MySQL/MariaDB以及PHP。
Apache HTTP 服务器,简称 Apache,是非常流行的Web服务器软件。
本文档描述了怎样安装设置 Apache 网页服务器。以及选择安装 PHP 并集成到Apache服务器中。

3.1 安装和启动

$ sudo pacman -Ss apache |grep installed
extra/apache 2.4.47-1 [installed]
$ sudo systemctl start httpd

3.2 配置及验证

Apache 配置文件位于/etc/httpd/conf. 主要配置文件是/etc/httpd/conf/httpd.conf,其中包括各种其他配置文件。
对于简单的设置,默认配置文件应该没问题。默认情况下,它会将目录/srv/http提供给访问您网站的任何人。
$ sudo systemctl start httpd
Apache 现在应该正在运行。通过在 Web 浏览器中访问http://localhost/。它应该显示一个简单的索引页面。
http://localhost/

3.2.1 选项

请参阅Apache 配置指令的完整列表和指令快速参考。

常用设置: /etc/httpd/conf/httpd.conf

  • User http: 出于安全原因,若 Apache 由 root 用户(直接或通过启动脚本)启动,它就会切换到此 UID。默认用户是http,它是在安装过程中自动创建的。
  • Listen 80: 这是 Apache 将侦听的端口。使用路由器访问互联网,您必须转发端口。 如果您想为本地开发设置 Apache,您可能希望它只能从您的计算机访问。 然后将此行更改为Listen 127.0.0.1:80.
  • ServerAdmin you@example.com: 这是管理员的电子邮件地址,可以在例如错误页面上找到。
  • DocumentRoot "/srv/http": 这是您放置网页的目录。可修改,但不要忘记也更改<Directory "/srv/http">,否则可能会收到403错误缺乏权限)。 将Require all denied行更改为Require all granted,或收到403。 注: DocumentRoot 目录及其父文件夹必须允许其他人执行权限(chmod o+x /path/to/DocumentRoot),否则您将收到403错误。
  • AllowOverride None: <Directory>部分中的此指令会导致 Apache 完全忽略.htaccess文件。 请注意,这现在是 Apache 2.4 的默认设置,因此如果您打算使用.htaccess文件,则需要明确允许覆盖。 如果您打算mod_rewrite在.htaccess文件中使用或 其他设置,您可以允许该文件中声明的哪些指令可以覆盖服务器配置。

更多设置: /etc/httpd/conf/extra/httpd-default.conf

  • ServerSignature Off: 关闭服务器的签名
  • ServerTokens Prod: 隐藏 Apache 和 PHP 版本等服务器信息

3.2.2 检查配置

$ apachectl configtest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

3.3 用户目录

默认情况下,用户目录可通过http://localhost/~yourusername/ 访问并显示内容~/public_html(这可以在 中更改/etc/httpd/conf/extra/httpd-userdir.conf)。
如果您不希望用户目录在 Web 上可用,请在/etc/httpd/conf/httpd.conf中注释掉以下行:
Include conf/extra/httpd-userdir.conf

必须确保您的主目录权限设置正确,以便 Apache 可以到达那里。您的主目录~/public_html必须对其他人可执行:
$ chmod o+x ~
$ chmod o+x ~/public_html
$ chmod -R o+r ~/public_html
$ ls -l /home/

drwxr-xr-x 21 tom  users  4096 Jun  2 14:16 tom
$ ls -l /home/tom/
drwxr-xr-x  2 tom  users  4096 Jun  2 14:17 public_html
$ ls -l /home/tom/public_html/
-rw-r--r-- 1 tom users 17 Jun  2 13:54 test.php
-rwxr-xr-x 1 tom users 48 Jun  2 08:17 tom.html

重新启动httpd.service以应用任何更改。另请参阅Umask#Set the mask value。
https://wiki.archlinux.org/title/Umask#Set_the_mask_value

注: 不必+x为每个用户都设置,通过 ACL 只为 web 服务器设置它就足够了(请参阅访问控制列表#授予 web 服务器私有文件的执行权限)。
https://wiki.archlinux.org/title/Access_Control_Lists#Granting_execution_permissions_for_private_files_to_a_web_server

3.4 扩展PHP

3.4.1 安装php-fpm

使用 php-fpm 和 mod_proxy_fcgi,这种方法提供了“PHP FastCGI 实现,具有一些附加功能(大部分)对高负载站点有用”。
注意: 与 ProxyPass 的广泛设置不同,SetHandler 的代理配置尊重其他 Apache 指令,如 DirectoryIndex。这确保了与为 libphp、mod_fastcgi 和 mod_fcgid 设计的软件更好的兼容性。如果您仍想尝试 ProxyPass,请尝试如下一行:
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/srv/http/$1


安装 php-fpm。启用代理模块:
/etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

使用以下内容创建: /etc/httpd/conf/extra/php-fpm.conf
DirectoryIndex index.php index.html
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>
并将其包含在以下内容的底部/etc/httpd/conf/httpd.conf:
Include conf/extra/php-fpm.conf
注意: sock和fcgi之间不允许有空格!localhost可以用任何字符串替换。
更多配置在这里: /etc/php/php-fpm.d/www.conf,但默认设置应该可以正常工作。
启动并启用php-fpm.service. 重新启动 httpd.service。

3.4.2 测试PHP是否有效

要测试 PHP 是否已正确配置,请在您的 ApacheDocumentRoot目录(例如/srv/http/或~<username>/public_html/)中创建一个文件test.php,其中包含以下内容: 
<?php phpinfo();
然后根据需要转到http://localhost/test.php或 http://localhost/~<username>/test.php
http://127.0.0.1/~tom/
http://127.0.0.1/~tom/test.php

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


2021-04-25

The-text-Compatibility-of-Linux-and-Windows

The-text-Compatibility-of-Linux-and-Windows

1. 字符编码问题: Linux系统与windows系统的默认编码不同。 	1.1 Linux系统下查看文件编码命令file 	1.2 文件字符编码转换 		1.2.1 文件内容的字符编码转换: iconv 		1.2.2 文件名称的字符编码转换: convmv 	1.3 操作系统的字符集问题 2. 换行格式问题 	2.1 现象 	2.2 原因 	2.3 举例 	2.4 转换 	2.5 换行历史 3. 混用供参考 

 

在同时使用Windows与Linux双系统时,会遇到2种系统下文本文件互相不太兼容的问题。
主要是字符编码(文件内容及文件名)问题; 还有文件内容的换行格式问题。
注: 使用chrome可以查看几乎所有编码格式的文本文件, 只是不能编辑。

1. 字符编码问题: Linux系统与windows系统的默认编码不同。

  • Windows系统的字符编码默认是GBK(gb2312),
  • 而Linux系统的字符编码默认是UTF-8。

如果在双系统的其中一个系统下能正常现实中文,而在另外一个系统下则显示为乱码,通常是文件的编码有问题。

1.1 Linux系统下查看文件编码命令file


新版本的Unix命令File做字符编码的检测.(cygwin与mac都有此命令)

$ file linux.txt
linux.txt: Unicode text, UTF-8 text
这个文件的字符编码是UTF-8,在Linux系统下查看应该没有问题。

$ file win.txt
win.txt: ISO-8859 text, with CRLF line terminators
这个文件的字符编码ISO-8859, 不是UTF-8, 在Linux系统下使用gedit, geany, notepadqq等查看显示为乱码;但使用pluma可正常查看.

1.2 文件字符编码转换

1.2.1 文件内容的字符编码转换: iconv

Linux系统下命令: (iconv), 程序与编程API,用于字符编码转换
$ iconv -f GB2312 -t UTF-8 win-old.txt -o lin-new.txt
$ file lin-new.txt
lin-new.txt: Unicode text, UTF-8 text, with CRLF line terminators

另外: windows系统下: 直接使用记事本另存为即可, 使用记事本打开文件->另存为,编码方式选择UTF-8。

1.2.2 文件名称的字符编码转换: convmv

将文件名从一种编码转换为另一种。
convmv -f 源编码 -t 新编码 [选项] 文件名
常用参数:
-r 递归处理子文件夹
–notest 真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。
–list 显示所有支持的编码
–unescap 可以做一下转义,比如把%20变成空格

1.3 操作系统的字符集问题

另外,文件出现编码错误的原因还可能是当前操作系统的字符集有问题. 可参考此文处理: Locale
https://www.cnblogs.com/sztom/p/12174045.html

2. 换行格式问题

2.1 现象

在Linux环境下使用图形界面的文本编辑器或许看不出差异, 但若在Terminal终端下查看Windows格式(即CRLF回车换行)的文本文件,每行行尾都会多出个^M; 普通文本或许影响不大, 但若是脚本文件, 使用时就会报错了.
而在Windows环境下查看Linux格式(即LF换行)的文本文件, 就非常不方便了, 只有长长的一行了(相当于没有了所有的换行).

2.2 原因

  • 在Linux中,文本文件换行用"\n": [换行LF (Line feed, U+000A) 0x0a (10)]
  • 而Windows用"\r\n"表示回车换行: [回车CR (Carriage Return, U+000D) 0x0d (13); 换行LF (Line feed, U+000A) 0x0a (10)]

2.3 举例

还是拿上面用过的文件举例,已经转换为UTF-8, 使用文本编辑器查看是没有问题了,
$ file lin-new.txt
lin-new.txt: Unicode text, UTF-8 text, with CRLF line terminators
这里看到行尾是CRLF, 即回车换行, 还是Windows的格式, 所以vi等命令行下查看时, 将多出来的的回车识别为(^M)

2.4 转换

如下2个命令将文本在 DOS 和 Unix 格式之间转换。
dos2unix : CRLF --> LF
unix2dos : LF --> CRLF

$ file lin-new.txt
lin-new.txt: Unicode text, UTF-8 text, with CRLF line terminators
$ dos2unix lin-new.txt
dos2unix: converting file lin-new.txt to Unix format...
$ file lin-new.txt
lin-new.txt: Unicode text, UTF-8 text

注: 还有更多相关命令: tr, od, awk, seg, vim, enca...

  • type: 可查看命令类型
  • file: 查看文件编码及格式
  • stat: 查看文件状态

2.5 换行历史

回车"(Carriage Return)和"换行"(Line Feed)这两个概念的来历和区别。
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33,Linux/Unix下的tty概念也来自于此)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。

于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做"回车",告诉打字机把打印头定位在左边界;另一个叫做"换行",告诉打字机把纸向下移一行。这就是"换行"和"回车"的来历,从它们的英语名字上也可以看出一二。

后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。

Unix系统里,每行结尾只有"<换行>",即"\n";Windows系统里面,每行结尾是"<回车><换行>",即"\r\n";Mac系统里,每行结尾是"<回车>",即"\r";。一个直接后果是,Unix/Mac系统下的文件在 Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

3. 混用供参考

普通文件: 字符编码都使用UTF-8(Linux默认模式); 换行保持CTLF(Windows模式)。这样2种系统下都可以正常查看并编辑。
脚本文件: 字符编码都使用UTF-8(Linux默认模式); 若是bat的windows脚本使用CTLF(Windows模式); 若是sh的Linux脚本则使用LF(Linux模式)。
注: 脚本文件尽量使用全英文的就不会有编码问题了。

https://www.cnblogs.com/sztom/p/12154470.html#210
Unicode \ 3.2 字符转换工具
https://zh.wikipedia.org/wiki/字符编码#字符转换工具
https://en.wikipedia.org/wiki/Character_encoding#Character_encoding_translation

Locale
https://www.cnblogs.com/sztom/p/12174045.html

==========
下文有提供更多种转换方式: 如何将文本文件在 Unix 和 DOS(Windows)格式之间转换
作者: Magesh Maruthamuthu 译者: LCTT geekpi | 2020-08-27
https://linux.cn/article-12558-1.html


AC-power

导航 (返回顶部) 1. AC 1.1 Alternating current 1.2 简谐交流电 1.3 频率 1.4 峰值和有效值 2. 交流电相位分类 2.1 单相电 2.2 三相电 2.3 比较 2.4 220v交流电的3个电压值 2.5 相电压与...