https://wiki.archlinux.org/api.php?action=feedcontributions&user=Arisaka&feedformat=atom
ArchWiki - User contributions [en]
2024-03-29T12:58:28Z
User contributions
MediaWiki 1.41.0
https://wiki.archlinux.org/index.php?title=TigerVNC_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=680593
TigerVNC (简体中文)
2021-06-14T01:45:57Z
<p>Arisaka: 修复超链接</p>
<hr />
<div>[[Category:Remote desktop (简体中文)]]<br />
[[Category:Servers (简体中文)]]<br />
[[de:VNC]]<br />
[[en:TigerVNC]]<br />
[[es:TigerVNC]]<br />
[[ja:TigerVNC]]<br />
{{TranslationStatus (简体中文)|TigerVNC|2021-06-13|669441}}<br />
{{Related articles start}}<br />
{{Related|x11vnc}}<br />
{{Related articles end}}<br />
<br />
[https://tigervnc.org/ TigerVNC] 是 [[Wikipedia:Virtual Network Computing|Virtual Network Computing]] (VNC) 协议的一种实现。本文着重介绍服务端的功能。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|tigervnc}} 软件包。<br />
<br />
== 为虚拟(无界面)会话运行 vncserver ==<br />
<br />
=== 初始设置 ===<br />
<br />
{{注意|在内存允许的条件下,Linux 系统可以启动任意数量的 VNC 服务端,它们同时并行运行,互不干扰。}}<br />
<br />
简易教程如下。推荐用户阅读 vncserver 的 man 手册来了解所有的配置项。<br />
<br />
# 用 {{ic|vncpasswd}} 创建密码,它会将哈希处理之后的密码存储在 {{ic|~/.vnc/passwd}}。<br />
# 编辑 {{ic|/etc/tigervnc/vncserver.users}} 来定义用户映射。该文件中定义的每个用户都会拥有对应的端口来运行会话。该文件中的数字对应的是 TCP 端口。默认情况下,:1 是 TCP 端口 5901 (5900+1)。如果需要运行一个并行的服务端,第二个实例可以运行在下一个最大的、未被占用的端口,即 5902 (5900+2)。<br />
# 创建 {{ic|~/.vnc/config}},其中至少要有一行定义会话的类型,比如 {{ic|1=session=foo}} (将foo替换为你想要运行的桌面环境)。你可以通过查看 {{ic|/usr/share/xsessions/}} 里的 {{ic|.desktop}} 文件来知道有哪些桌面环境在当前系统上可以使用。<br />
文件内容举例:<br />
<br />
{{hc|~/.vnc/config|2=<br />
session=lxqt<br />
geometry=1920x1080<br />
localhost<br />
alwaysshared}}<br />
<br />
=== 启动与停止 tigervnc ===<br />
<br />
[[start]] {{ic|vncserver@.service}},如果需要让它随系统启动,[[enable]] 它。注意 {{ic|/etc/tigervnc/vncserver.users}} 中定义的编号需要在@符号后面指定,比如启动:1的命令是:<br />
# systemctl start vncserver@:1<br />
<br />
{{注意|已经不再支持直接调用 {{ic|/usr/bin/vncserver}} 了,因为这样做不会建立完整可用的会话环境。systemd 服务是唯一受支持的使用 TigerVNC 的方式。参见 [https://github.com/TigerVNC/tigervnc/issues/1096 Issue #1096]。}}<br />
<br />
== 直接转发本地显示内容 ==<br />
<br />
Tigervnc 带有 libvnc.so,它可以在 X 初始化过程中直接加载,以提供更好的性能。<br />
创建如下文件并重启 X:<br />
{{hc|/etc/X11/xorg.conf.d/10-vnc.conf|<br />
Section "Module"<br />
Load "vnc"<br />
EndSection<br />
<br />
Section "Screen"<br />
Identifier "Screen0"<br />
Option "UserPasswdVerifier" "VncAuth"<br />
Option "PasswordFile" "/root/.vnc/passwd"<br />
EndSection}}<br />
<br />
== 运行 x0vncserver 来直接控制本地显示内容 ==<br />
<br />
{{pkg|tigervnc}} 同时也提供 {{ic|x0vncserver}},允许直接控制物理 X 会话。在使用 ''vncpasswd'' 定义了会话密码后,请这样启动服务端:<br />
$ x0vncserver -rfbauth ~/.vnc/passwd<br />
<br />
更多信息请参阅 {{man|1|x0vncserver}}。<br />
<br />
{{注意|<br />
* [[x11vnc]] 是另一个可以直接控制当前 X 会话的 VNC 服务端。<br />
* {{ic|x0vncserver}} 目前不支持客户端和服务端之间的剪贴板共享(即使有 {{ic|autocutsel}} 支持也不行)。参阅 [https://github.com/TigerVNC/tigervnc/issues/529 Issue #529]。}}<br />
<br />
=== 从 xprofile 启动 x0vncserver ===<br />
<br />
一种启动 ''x0vncserver'' 的简单方法是在某个 [[xprofile]] 文件中添加如下行:<br />
<br />
{{hc|~/.xprofile|<br />
...<br />
x0vncserver -rfbauth ~/.vnc/passwd &}}<br />
<br />
=== 通过 systemd 启动与停止 x0vncserver ===<br />
<br />
对大多数用户来说,快速远程访问当前桌面的最简单方法是运行 ''x0vncserver'' 来得到一个 VNC 服务器。为此可以创建一个 systemd unit,将其中的用户和选项替换为实际值:<br />
<br />
{{hc|~/.config/systemd/user/x0vncserver.service|2=<br />
[Unit]<br />
Description=Remote desktop service (VNC)<br />
<br />
[Service]<br />
Type=simple<br />
# wait for Xorg started by ${USER}<br />
ExecStartPre=/bin/sh -c 'while ! pgrep -U "$USER" Xorg; do sleep 2; done'<br />
ExecStart=/usr/bin/x0vncserver -rfbauth %h/.vnc/passwd<br />
# or login with your username & password<br />
#ExecStart=/usr/bin/x0vncserver -PAMService=login -PlainUsers=${USER} -SecurityTypes=TLSPlain<br />
<br />
[Install]<br />
WantedBy=default.target}}<br />
<br />
在 [[Systemd/User]] 模式下 [[start]] 并 [[enable]] {{ic|x0vncserver.service}} 服务,也就是带上 {{ic|--user}} 参数。<br />
<br />
== 使用 XDMCP 为需要的会话运行 Xvnc ==<br />
<br />
可以让 ''systemd'' socket activation 与 [[XDMCP]] 结合使用,为每个想登录的用户自动生成 VNC 服务器,这样无需为每个用户都准备服务器或端口。这种方法使用显示管理器来验证用户和登录,所以也不需要设置 VNC 密码。这种方法的缺点是会话无法在服务器上保持运行,退出后无法重新连接到它。<br />
<br />
该方法首先需要设置 [[XDMCP]],并确保显示管理器正在运行。<br />
然后创建:<br />
{{hc|/etc/systemd/system/xvnc.socket|2=<br />
[Unit]<br />
Description=XVNC Server<br />
<br />
[Socket]<br />
ListenStream=5900<br />
Accept=yes<br />
<br />
[Install]<br />
WantedBy=sockets.target}}<br />
{{hc|/etc/systemd/system/xvnc@.service|2=<br />
[Unit]<br />
Description=XVNC Per-Connection Daemon<br />
<br />
[Service]<br />
ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1920x1080 -once -SecurityTypes=None<br />
User=nobody<br />
StandardInput=socket<br />
StandardError=syslog}}<br />
使用 systemctl 来 [[start]] 并 [[enable]] {{ic|xvnc.socket}}。现在多个用户同时连接到 5900 端口,均可获得单独的桌面。<br />
<br />
如果 VNC 服务器直接暴露在公网,请在 {{ic|xvnc@.service}} 里给 {{ic|Xvnc}} 添加 {{ic|-localhost}} 选项(注意 {{ic|-query localhost}} 和 {{ic|-localhost}} 是不同的开关),然后遵循 [[#通过 SSH 隧道连接到 vncserver]]。由于我们只在连接后才选择用户,所以 VNC 服务端以 ''nobody'' 用户运行,且直接使用了 {{ic|Xvnc}} 而不是 {{ic|vncserver}} 脚本,所以忽略了 {{ic|~/.vnc}} 中的选项。或者也可以 [[autostart|自动启动]] ''vncconfig'' 来打开剪贴板共享(在非 VNC 会话中 ''vncconfig'' 将立即退出)。一种自动启动的方法是创建:<br />
{{hc|/etc/X11/xinit/xinitrc.d/99-vncconfig.sh|<br />
#!/bin/sh<br />
vncconfig -nowin &}}<br />
<br />
== 连接到 vncserver ==<br />
<br />
{{警告|TigerVNC 默认的连接方式不安全,它缺乏身份验证,且在连接建立过程中无法防止中间人攻击。请确保知晓当前服务器的安全设置,并且不要以不安全的方式连接到可信网络之外的 vncserver。}}<br />
<br />
{{注意|TigerVNC 默认使用 ''TLSVnc'' 作为验证和加密方式,也可以用 {{ic|SecurityTypes}} 参数来改成其他方式。''TLSVnc'' 意味着标准的 VNC 身份验证,使用 GNUTLS 加密流量,但不会验证服务器的身份。TigerVNC 支持更换其他安全方案,如 ''X509Vnc'',它结合了标准 VNC 身份验证、GNUTLS 加密、服务器身份识别,推荐将它用于安全连接。<br />
<br />
如果服务器上的 {{ic|SecurityTypes}} 设置了非加密方式(如 ''None'', ''VncAuth'', ''Plain'', ''TLSNone'', ''TLSPlain'', ''X509None'', ''X509Plain'')为高优先级,这样无法使用加密,是不明智的。运行 ''vncviewer'' 时,更安全的方式是明确指定 {{ic|SecurityTypes}} 且不接受未加密的流量。其他的模式仅在 [[#通过 SSH 隧道连接到 vncserver]] 时使用。}}<br />
<br />
连接到 vncserver 的客户端不限数量。下面是一个简单的例子,其中 vncserver 运行在 10.1.10.2 的 5901 端口上,端口可以用缩写 :1 来表示: <br />
$ vncviewer 10.1.10.2:1<br />
<br />
=== 无密码验证 ===<br />
<br />
{{ic|-passwd}} 开关允许我们定义服务器上 {{ic|~/.vnc/passwd}} 文件的位置。用户在服务器上必须有权访问该文件,可以是通过 [[Secure Shell (简体中文)|SSH]] 访问,也可以是实体访问。两种情况下都应将该文件放在客户端文件系统的一个安全位置,比如一个仅给期望用户以读取权限的位置。<br />
<br />
$ vncviewer -passwd ''/path/to/server-passwd-file''<br />
<br />
直接提供密码也是可以的。<br />
<br />
{{注意|下方的密码输入方式是不安全的,本机上任何可以运行 {{ic|ps}} 的人都可以看到密码。}}<br />
<br />
$ vncviewer -passwd <(echo MYPASSWORD | vncpasswd -f)<br />
<br />
=== 图形界面客户端示例 ===<br />
<br />
* {{Pkg|gtk-vnc}}<br />
* {{Pkg|krdc}}<br />
* {{Pkg|vinagre}}<br />
* [[remmina]]<br />
* {{Pkg|virt-viewer}}<br />
* {{AUR|vncviewer-jar}}<br />
<br />
TigerVNC 的 vncviewer 也带有一个简单的图形界面,不带参数运行即可:<br />
$ vncviewer<br />
<br />
== 通过 SSH 隧道连接到 vncserver ==<br />
<br />
对于提供 SSH 的服务器来说,这种方法有一个优点,除了已经打开的 SSH 端口外不需要再打开其他端口,因为 VNC 流量是在 SSH 隧道中传输的。<br />
<br />
=== 服务端配置 ===<br />
<br />
服务端必须运行 ''vncserver'' 或 ''x0vncserver''。<br />
<br />
无论运行哪个服务端,都建议在 {{ic|~/.vnc/config}} 添加 {{ic|localhost}} 选项或使用 {{ic|-localhost}} 开关(适用于 ''x0vncserver''),只允许来自 localhost 的连接,这样可以确保连接都来自于 ssh 或实体机上认证过的用户。例如: <br />
<br />
{{hc|~/.vnc/config|2=<br />
session=lxqt<br />
geometry=1920x1080<br />
localhost<br />
alwaysshared}}<br />
<br />
确保已经 [[start]] 或 [[restart]] {{ic|vncserver@.service}}。例如(参见 [[#初始设置]]):<br />
# systemctl start vncserver@:1<br />
<br />
对于 ''x0vncserver'' 则是:<br />
$ x0vncserver '''-localhost''' -SecurityTypes none<br />
<br />
=== 客户端配置 ===<br />
<br />
远程计算机上的 VNC 服务端已被设置为仅接受本地连接。<br />
现在,客户端必须与远程计算机(本例中为 10.1.10.2)建立 SSH 连接,并在客户端的某个端口(如 9901)和服务器的 5901 端口之间建立隧道。关于该功能的详细信息,参见 [[OpenSSH#Forwarding other ports]] 和 {{man|1|ssh}}。<br />
<br />
$ ssh 10.1.10.2 -L 9901:localhost:5901<br />
<br />
当通过 SSH 建立连接后,请保持该 shell 窗口打开,它现在是与服务器之间的安全隧道。或者也可以使用 {{ic|-f}} 选项直接在后台运行 SSH。客户端要想通过这一加密隧道连接到服务端,请指定 ''vncviewer'' 连接到客户端 localhost 上的转发端口。<br />
<br />
$ vncviewer localhost:9901<br />
<br />
实际上就是 vncviewer 连接到了本地的 9901 端口,而该端口映射到了服务器本地的 5901 端口。通过 SSH,向正确的端口建立了连接。<br />
<br />
{{Tip|只用一行命令即可实现在连接期间保持端口转发,在连接关闭后立即关闭转发:<br />
{{bc|$ ssh -fL 9901:localhost:5901 10.1.10.2 sleep 10; vncviewer localhost:9901}}<br />
上述命令中 {{ic|-f}} 选项使 ssh 在后台运行,它将因为 {{ic|sleep 10}} 而保持运行。接着运行 vncviewer,在 vncviewer 使用隧道期间,ssh 在后台继续运行。当隧道不再使用,ssh 将关闭,这正是我们所需要的行为。<br />
<br />
另外,vncviewer 的 {{ic|-via}} 选项提供了上述命令的快捷方式:<br />
{{bc|$ vncviewer -via 10.1.10.2 localhost::5901}}<br />
(注意双冒号:vncviewer 的语法是 {{ic|[host]:[display#]}} 或 {{ic|[host]::[port]}}。)<br />
}}<br />
<br />
=== 从 Android 设备通过 SSH 连接到 vncserver ===<br />
<br />
为了用 Android 设备作为客户端,通过 SSH 连接到 VNC 服务端,可以进行以下设置:<br />
# 服务器运行 SSH<br />
# 服务器运行 vncserver(带有 {{ic|-localhost}} 标志以确保安全)<br />
# Android 设备上的 SSH 客户端:''ConnectBot'' 是一个流行的选择,本例中将使用它<br />
# Android 设备上的 VNC 客户端:此处采用 ''androidVNC''<br />
<br />
在 ''ConnectBot'' 中连接到目标主机。轻点 options 按钮,选择 ''Port Forwards'' 并添加一个端口:<br />
Type: Local<br />
Source port: 5901<br />
Destination: 127.0.0.1:5901<br />
<br />
在 ''androidVNC'' 中连接到 VNC 端口,即 SSH 连接中设置的本地端口:<br />
Password: the vncserver password<br />
Address: 127.0.0.1<br />
Port: 5901<br />
<br />
== 提示和技巧 ==<br />
<br />
=== 连接到 OS X 系统 ===<br />
<br />
参见 https://help.ubuntu.com/community/AppleRemoteDesktop。 已在 Remmina 上测试。<br />
<br />
=== 推荐的安全设置 ===<br />
<br />
[[#通过 SSH 隧道连接到 vncserver]] 中,SSH 处理身份验证和加密,如果没有采用该方法,则建议用 ''X509Vnc'',因为 ''TLSVnc'' 缺乏身份验证。 <br />
<br />
$ vncserver -x509key ''/path/to/key.pem'' -x509cert ''/path/to/cert.pem'' -SecurityTypes X509Vnc :1<br />
<br />
颁发 x509 证书超出了本指南的范围,而 [[wikipedia:Let's Encrypt|Let's Encrypt]] 提供了一种简便方法。也可以使用 [[OpenSSL]] 来颁发证书,然后与客户端共享公钥并使用 {{ic|-X509CA}} 参数指定证书。下面是一个示例(服务器运行在 10.1.10.2 上):<br />
$ vncviewer 10.1.10.2 -X509CA ''/path/to/cert.pem''<br />
<br />
=== 切换全屏 ===<br />
<br />
从 VNC 客户端的菜单可以切换全屏。默认快捷键是 {{ic|F8}}。<br />
<br />
=== 鼠标后退和前进按钮失效的解决方法 ===<br />
<br />
VNC 协议目前只支持 7 个鼠标按钮(左、中、右、向上滚动、向下滚动、向左滚动、向右滚动),如果鼠标有后退和前进按钮,这些按钮无法使用,按钮的输入将被忽略。<br />
<br />
在单击鼠标后退/前进按钮时,[https://www.bedroomlan.org/projects/evrouter/ evrouter] 将其改为键盘按键发送,可以解决此限制。如果需要,可以在服务器上使用 {{Pkg|xautomation}} 和 {{Pkg|xbindkeys}} 中的 xte 将键盘按键映射回鼠标单击。 <br />
<br />
==== 用键盘 XF86Back/XF86Forward 按键代替鼠标后退/前进按钮 ====<br />
<br />
如果只需要在用 Web 浏览器或文件浏览器时后退/前进,则此方法既简单又合适。<br />
<br />
客户端安装 {{AUR|evrouter}} 和 {{Pkg|xautomation}}。配置 evrouter,想知道如何查找设备名称、窗口名称、按钮名称等,请参阅 [[Mouse buttons#evrouter]] 和 evrouter 手册页。以下是示例配置:<br />
{{hc|~/.evrouterrc|Window "OtherComputer:0 - TigerVNC": # 筛选窗口标题<br />
<br />
# 使用 Shell 防止重复按键(参见 evrouter 手册)<br />
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Back'"<br />
"USB mosue" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Forward'"<br />
<br />
# 如果需要重复按键,请使用下面的 XKey(参见 evrouter 手册)<br />
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/275 "XKey/XF86Back"<br />
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/276 "XKey/XF86Forward"}}<br />
<br />
客户端启动 evrouter。按照上面的配置,点击鼠标后退按钮时,向 VNC 服务器发送键盘按键 XF86Back,点击前进按钮时发送 XF86Forward。 <br />
<br />
==== 在服务端将键盘按键映射回的鼠标点击 ====<br />
<br />
必要时可以在服务端将键盘按键映射回鼠标点击。此时最好使用客户端或服务端都不使用的按键值。下面的例子将按键值 XF86Launch8/XF86Launch9 用作鼠标按钮 8/9。<br />
<br />
客户端上的 evrouter 配置:<br />
{{hc|~/.evrouterrc|Window "OtherComputer:0 - TigerVNC": # 窗口标题<br />
<br />
# 使用 Shell 防止重复按键(参见 evrouter 手册)<br />
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Launch8'"<br />
"USB mosue" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Launch9'"}}<br />
<br />
服务端安装 {{Pkg|xautomation}} 和 {{Pkg|xbindkeys}}。配置 xbindkeys,配置中使用 xte 将键盘按键 XF86Launch8/XF86Launch9 映射到鼠标按钮 8/9。 <br />
{{hc|~/.xbindkeysrc|<br />
"xte 'mouseclick 8'"<br />
XF86Launch8<br />
<br />
"xte 'mouseclick 9'"<br />
XF86Launch9<br />
}}<br />
启用 xbindkeys {{ic|$ xbindkeys -f ~/.xbindkeysrc}}。服务端将 XF86Launch8/XF86Launch9 映射为鼠标按钮 8/9。<br />
<br />
== 疑难解答 ==<br />
<br />
=== vncserver 内的终端起始于 / (根目录) ===<br />
<br />
这是上游引入的已知问题。参阅:https://github.com/TigerVNC/tigervnc/issues/1108<br />
<br />
=== 无法输入 '<' 符号 ===<br />
<br />
如果在客户端上按下 {{ic|<}} 却发送了 {{ic|>}} 字符,请尝试重新映射键盘 [https://insaner.com/blog/2013/05.html#20130422063137]{{Dead link|2020|04|03|status=404}}:<br />
<br />
$ x0vncserver -RemapKeys="0x3c->0x2c"<br />
<br />
=== 窗口显示为黑色方框 ===<br />
<br />
这种情况很可能是应用程序依赖于 Xorg 的 Composite 扩展。如基于 webkit 的应用程序:midori、psi-plus 等。<br />
<br />
这种情况下使用下列命令重启 vncserver:<br />
<br />
$ vncserver -geometry ... -depth 24 :1 +extension Composite<br />
<br />
VNC 下的 Composite 扩展仅在 24 位色深时才能正常工作。<br />
<br />
=== 没有鼠标指针 ===<br />
<br />
当使用 {{ic|x0vncserver}} 时没有可见的鼠标指针,请使用下列命令启动 vncviewer:<br />
<br />
$ vncviewer DotWhenNoCursor=1 <server><br />
<br />
或者将 {{ic|DotWhenNoCursor<nowiki>=</nowiki>1}} 写入 tigervnc 配置文件,配置文件默认存放在 {{ic|~/.vnc/default.tigervnc}}。<br />
<br />
=== 从远程主机复制剪贴板内容 ===<br />
<br />
如果无法从远程主机复制到本地,请在服务端运行 {{ic|autocutsel}},如 [https://bbs.archlinux.org/viewtopic.php?id=101243] 中所述:<br />
<br />
$ autocutsel -fork<br />
<br />
然后按下 F8 打开 VNC 菜单,选择 {{ic|Clipboard: local -> remote}} 选项。<br />
<br />
=== 启动 GNOME 3 时显示 "Authentication is required to create a color managed device" 对话框 ===<br />
<br />
一种解决方法是创建一个 "vnc" 组,将 gdm 用户和其他使用 vnc 的用户添加到该组。按如下方式 [https://github.com/TurboVNC/turbovnc/issues/47] 修改 {{ic|/etc/polkit-1/rules.d/gnome-vnc.rules}}:<br />
<br />
polkit.addRule(function(action, subject) {<br />
if ((action.id == "org.freedesktop.color-manager.create-device" ||<br />
action.id == "org.freedesktop.color-manager.create-profile" ||<br />
action.id == "org.freedesktop.color-manager.delete-device" ||<br />
action.id == "org.freedesktop.color-manager.delete-profile" ||<br />
action.id == "org.freedesktop.color-manager.modify-device" ||<br />
action.id == "org.freedesktop.color-manager.modify-profile") &&<br />
subject.isInGroup("vnc")) {<br />
return polkit.Result.YES;<br />
}<br />
});<br />
<br />
=== 没有窗口装饰/边框/标题栏/无法移动窗口 ===<br />
<br />
启动一个窗口管理器来修复一个空的 xterm frame。例如在 xfce 上,可在终端中运行 `xfwm4 &`。 <br />
<br />
=== 按用户运行 systemd service unit ===<br />
<br />
$ sudo nano /usr/lib/systemd/system/tigervnc@.service<br />
<br />
[Unit]<br />
Description=Remote desktop service (VNC)<br />
After=syslog.target network.target<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=/sbin/runuser -l USERNAME -c "/usr/bin/vncserver %i"<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
<br />
假设在 display 9 上启动服务:<br />
$ sudo systemctl start tigervnc@:9<br />
<br />
在启动时运行:<br />
$ sudo systemctl enable tigervnc@:9<br />
<br />
== 另外参见 ==<br />
<br />
* https://github.com/TigerVNC/tigervnc</div>
Arisaka
https://wiki.archlinux.org/index.php?title=TigerVNC_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=680592
TigerVNC (简体中文)
2021-06-14T01:37:50Z
<p>Arisaka: Update translation</p>
<hr />
<div>[[Category:Remote desktop (简体中文)]]<br />
[[Category:Servers (简体中文)]]<br />
[[de:VNC]]<br />
[[en:TigerVNC]]<br />
[[es:TigerVNC]]<br />
[[ja:TigerVNC]]<br />
{{TranslationStatus (简体中文)|TigerVNC|2021-06-13|669441}}<br />
{{Related articles start}}<br />
{{Related|x11vnc}}<br />
{{Related articles end}}<br />
<br />
[https://tigervnc.org/ TigerVNC] 是 [[Wikipedia:Virtual Network Computing|Virtual Network Computing]] (VNC) 协议的一种实现。本文着重介绍服务端的功能。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|tigervnc}} 软件包。<br />
<br />
== 为虚拟(无界面)会话运行 vncserver ==<br />
<br />
=== 初始设置 ===<br />
<br />
{{注意|在内存允许的条件下,Linux 系统可以启动任意数量的 VNC 服务端,它们同时并行运行,互不干扰。}}<br />
<br />
简易教程如下。推荐用户阅读 vncserver 的 man 手册来了解所有的配置项。<br />
<br />
# 用 {{ic|vncpasswd}} 创建密码,它会将哈希处理之后的密码存储在 {{ic|~/.vnc/passwd}}。<br />
# 编辑 {{ic|/etc/tigervnc/vncserver.users}} 来定义用户映射。该文件中定义的每个用户都会拥有对应的端口来运行会话。该文件中的数字对应的是 TCP 端口。默认情况下,:1 是 TCP 端口 5901 (5900+1)。如果需要运行一个并行的服务端,第二个实例可以运行在下一个最大的、未被占用的端口,即 5902 (5900+2)。<br />
# 创建 {{ic|~/.vnc/config}},其中至少要有一行定义会话的类型,比如 {{ic|1=session=foo}} (将foo替换为你想要运行的桌面环境)。你可以通过查看 {{ic|/usr/share/xsessions/}} 里的 {{ic|.desktop}} 文件来知道有哪些桌面环境在当前系统上可以使用。<br />
文件内容举例:<br />
<br />
{{hc|~/.vnc/config|2=<br />
session=lxqt<br />
geometry=1920x1080<br />
localhost<br />
alwaysshared}}<br />
<br />
=== 启动与停止 tigervnc ===<br />
<br />
[[start]] {{ic|vncserver@.service}},如果需要让它随系统启动,[[enable]] 它。注意 {{ic|/etc/tigervnc/vncserver.users}} 中定义的编号需要在@符号后面指定,比如启动:1的命令是:<br />
# systemctl start vncserver@:1<br />
<br />
{{注意|已经不再支持直接调用 {{ic|/usr/bin/vncserver}} 了,因为这样做不会建立完整可用的会话环境。systemd 服务是唯一受支持的使用 TigerVNC 的方式。参见 [https://github.com/TigerVNC/tigervnc/issues/1096 Issue #1096]。}}<br />
<br />
== 直接转发本地显示内容 ==<br />
<br />
Tigervnc 带有 libvnc.so,它可以在 X 初始化过程中直接加载,以提供更好的性能。<br />
创建如下文件并重启 X:<br />
{{hc|/etc/X11/xorg.conf.d/10-vnc.conf|<br />
Section "Module"<br />
Load "vnc"<br />
EndSection<br />
<br />
Section "Screen"<br />
Identifier "Screen0"<br />
Option "UserPasswdVerifier" "VncAuth"<br />
Option "PasswordFile" "/root/.vnc/passwd"<br />
EndSection}}<br />
<br />
== 运行 x0vncserver 来直接控制本地显示内容 ==<br />
<br />
{{pkg|tigervnc}} 同时也提供 {{ic|x0vncserver}},允许直接控制物理 X 会话。在使用 ''vncpasswd'' 定义了会话密码后,请这样启动服务端:<br />
$ x0vncserver -rfbauth ~/.vnc/passwd<br />
<br />
更多信息请参阅 {{man|1|x0vncserver}}。<br />
<br />
{{注意|<br />
* [[x11vnc]] 是另一个可以直接控制当前 X 会话的 VNC 服务端。<br />
* {{ic|x0vncserver}} 目前不支持客户端和服务端之间的剪贴板共享(即使有 {{ic|autocutsel}} 支持也不行)。参阅 [https://github.com/TigerVNC/tigervnc/issues/529 Issue #529]。}}<br />
<br />
=== 从 xprofile 启动 x0vncserver ===<br />
<br />
一种启动 ''x0vncserver'' 的简单方法是在某个 [[xprofile]] 文件中添加如下行:<br />
<br />
{{hc|~/.xprofile|<br />
...<br />
x0vncserver -rfbauth ~/.vnc/passwd &}}<br />
<br />
=== 通过 systemd 启动与停止 x0vncserver ===<br />
<br />
对大多数用户来说,快速远程访问当前桌面的最简单方法是运行 ''x0vncserver'' 来得到一个 VNC 服务器。为此可以创建一个 systemd unit,将其中的用户和选项替换为实际值:<br />
<br />
{{hc|~/.config/systemd/user/x0vncserver.service|2=<br />
[Unit]<br />
Description=Remote desktop service (VNC)<br />
<br />
[Service]<br />
Type=simple<br />
# wait for Xorg started by ${USER}<br />
ExecStartPre=/bin/sh -c 'while ! pgrep -U "$USER" Xorg; do sleep 2; done'<br />
ExecStart=/usr/bin/x0vncserver -rfbauth %h/.vnc/passwd<br />
# or login with your username & password<br />
#ExecStart=/usr/bin/x0vncserver -PAMService=login -PlainUsers=${USER} -SecurityTypes=TLSPlain<br />
<br />
[Install]<br />
WantedBy=default.target}}<br />
<br />
在 [[Systemd/User]] 模式下 [[start]] 并 [[enable]] {{ic|x0vncserver.service}} 服务,也就是带上 {{ic|--user}} 参数。<br />
<br />
== 使用 XDMCP 为需要的会话运行 Xvnc ==<br />
<br />
可以让 ''systemd'' socket activation 与 [[XDMCP]] 结合使用,为每个想登录的用户自动生成 VNC 服务器,这样无需为每个用户都准备服务器或端口。这种方法使用显示管理器来验证用户和登录,所以也不需要设置 VNC 密码。这种方法的缺点是会话无法在服务器上保持运行,退出后无法重新连接到它。<br />
<br />
该方法首先需要设置 [[XDMCP]],并确保显示管理器正在运行。<br />
然后创建:<br />
{{hc|/etc/systemd/system/xvnc.socket|2=<br />
[Unit]<br />
Description=XVNC Server<br />
<br />
[Socket]<br />
ListenStream=5900<br />
Accept=yes<br />
<br />
[Install]<br />
WantedBy=sockets.target}}<br />
{{hc|/etc/systemd/system/xvnc@.service|2=<br />
[Unit]<br />
Description=XVNC Per-Connection Daemon<br />
<br />
[Service]<br />
ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1920x1080 -once -SecurityTypes=None<br />
User=nobody<br />
StandardInput=socket<br />
StandardError=syslog}}<br />
使用 systemctl 来 [[start]] 并 [[enable]] {{ic|xvnc.socket}}。现在多个用户同时连接到 5900 端口,均可获得单独的桌面。<br />
<br />
如果 VNC 服务器直接暴露在公网,请在 {{ic|xvnc@.service}} 里给 {{ic|Xvnc}} 添加 {{ic|-localhost}} 选项(注意 {{ic|-query localhost}} 和 {{ic|-localhost}} 是不同的开关),然后遵循 [[#Accessing vncserver via SSH tunnels]]。由于我们只在连接后才选择用户,所以 VNC 服务端以 ''nobody'' 用户运行,且直接使用了 {{ic|Xvnc}} 而不是 {{ic|vncserver}} 脚本,所以忽略了 {{ic|~/.vnc}} 中的选项。或者也可以 [[autostart|自动启动]] ''vncconfig'' 来打开剪贴板共享(在非 VNC 会话中 ''vncconfig'' 将立即退出)。一种自动启动的方法是创建:<br />
{{hc|/etc/X11/xinit/xinitrc.d/99-vncconfig.sh|<br />
#!/bin/sh<br />
vncconfig -nowin &}}<br />
<br />
== 连接到 vncserver ==<br />
<br />
{{警告|TigerVNC 默认的连接方式不安全,它缺乏身份验证,且在连接建立过程中无法防止中间人攻击。请确保知晓当前服务器的安全设置,并且不要以不安全的方式连接到可信网络之外的 vncserver。}}<br />
<br />
{{注意|TigerVNC 默认使用 ''TLSVnc'' 作为验证和加密方式,也可以用 {{ic|SecurityTypes}} 参数来改成其他方式。''TLSVnc'' 意味着标准的 VNC 身份验证,使用 GNUTLS 加密流量,但不会验证服务器的身份。TigerVNC 支持更换其他安全方案,如 ''X509Vnc'',它结合了标准 VNC 身份验证、GNUTLS 加密、服务器身份识别,推荐将它用于安全连接。<br />
<br />
如果服务器上的 {{ic|SecurityTypes}} 设置了非加密方式(如 ''None'', ''VncAuth'', ''Plain'', ''TLSNone'', ''TLSPlain'', ''X509None'', ''X509Plain'')为高优先级,这样无法使用加密,是不明智的。运行 ''vncviewer'' 时,更安全的方式是明确指定 {{ic|SecurityTypes}} 且不接受未加密的流量。其他的模式仅在 [[#Accessing vncserver via SSH tunnels]] 时使用。}}<br />
<br />
连接到 vncserver 的客户端不限数量。下面是一个简单的例子,其中 vncserver 运行在 10.1.10.2 的 5901 端口上,端口可以用缩写 :1 来表示: <br />
$ vncviewer 10.1.10.2:1<br />
<br />
=== 无密码验证 ===<br />
<br />
{{ic|-passwd}} 开关允许我们定义服务器上 {{ic|~/.vnc/passwd}} 文件的位置。用户在服务器上必须有权访问该文件,可以是通过 [[SSH]] 访问,也可以是实体访问。两种情况下都应将该文件放在客户端文件系统的一个安全位置,比如一个仅给期望用户以读取权限的位置。<br />
<br />
$ vncviewer -passwd ''/path/to/server-passwd-file''<br />
<br />
直接提供密码也是可以的。<br />
<br />
{{注意|下方的密码输入方式是不安全的,本机上任何可以运行 {{ic|ps}} 的人都可以看到密码。}}<br />
<br />
$ vncviewer -passwd <(echo MYPASSWORD | vncpasswd -f)<br />
<br />
=== 图形界面客户端示例 ===<br />
<br />
* {{Pkg|gtk-vnc}}<br />
* {{Pkg|krdc}}<br />
* {{Pkg|vinagre}}<br />
* [[remmina]]<br />
* {{Pkg|virt-viewer}}<br />
* {{AUR|vncviewer-jar}}<br />
<br />
TigerVNC 的 vncviewer 也带有一个简单的图形界面,不带参数运行即可:<br />
$ vncviewer<br />
<br />
== 通过 SSH 隧道连接到 vncserver ==<br />
<br />
对于提供 SSH 的服务器来说,这种方法有一个优点,除了已经打开的 SSH 端口外不需要再打开其他端口,因为 VNC 流量是在 SSH 隧道中传输的。<br />
<br />
=== 服务端配置 ===<br />
<br />
服务端必须运行 ''vncserver'' 或 ''x0vncserver''。<br />
<br />
无论运行哪个服务端,都建议在 {{ic|~/.vnc/config}} 添加 {{ic|localhost}} 选项或使用 {{ic|-localhost}} 开关(适用于 ''x0vncserver''),只允许来自 localhost 的连接,这样可以确保连接都来自于 ssh 或实体机上认证过的用户。例如: <br />
<br />
{{hc|~/.vnc/config|2=<br />
session=lxqt<br />
geometry=1920x1080<br />
localhost<br />
alwaysshared}}<br />
<br />
确保已经 [[start]] 或 [[restart]] {{ic|vncserver@.service}}。例如(参见 [[#Initial setup]]):<br />
# systemctl start vncserver@:1<br />
<br />
对于 ''x0vncserver'' 则是:<br />
$ x0vncserver '''-localhost''' -SecurityTypes none<br />
<br />
=== 客户端配置 ===<br />
<br />
远程计算机上的 VNC 服务端已被设置为仅接受本地连接。<br />
现在,客户端必须与远程计算机(本例中为 10.1.10.2)建立 SSH 连接,并在客户端的某个端口(如 9901)和服务器的 5901 端口之间建立隧道。关于该功能的详细信息,参见 [[OpenSSH#Forwarding other ports]] 和 {{man|1|ssh}}。<br />
<br />
$ ssh 10.1.10.2 -L 9901:localhost:5901<br />
<br />
当通过 SSH 建立连接后,请保持该 shell 窗口打开,它现在是与服务器之间的安全隧道。或者也可以使用 {{ic|-f}} 选项直接在后台运行 SSH。客户端要想通过这一加密隧道连接到服务端,请指定 ''vncviewer'' 连接到客户端 localhost 上的转发端口。<br />
<br />
$ vncviewer localhost:9901<br />
<br />
实际上就是 vncviewer 连接到了本地的 9901 端口,而该端口映射到了服务器本地的 5901 端口。通过 SSH,向正确的端口建立了连接。<br />
<br />
{{Tip|只用一行命令即可实现在连接期间保持端口转发,在连接关闭后立即关闭转发:<br />
{{bc|$ ssh -fL 9901:localhost:5901 10.1.10.2 sleep 10; vncviewer localhost:9901}}<br />
上述命令中 {{ic|-f}} 选项使 ssh 在后台运行,它将因为 {{ic|sleep 10}} 而保持运行。接着运行 vncviewer,在 vncviewer 使用隧道期间,ssh 在后台继续运行。当隧道不再使用,ssh 将关闭,这正是我们所需要的行为。<br />
<br />
另外,vncviewer 的 {{ic|-via}} 选项提供了上述命令的快捷方式:<br />
{{bc|$ vncviewer -via 10.1.10.2 localhost::5901}}<br />
(注意双冒号:vncviewer 的语法是 {{ic|[host]:[display#]}} 或 {{ic|[host]::[port]}}。)<br />
}}<br />
<br />
=== 从 Android 设备通过 SSH 连接到 vncserver ===<br />
<br />
为了用 Android 设备作为客户端,通过 SSH 连接到 VNC 服务端,可以进行以下设置:<br />
# 服务器运行 SSH<br />
# 服务器运行 vncserver(带有 {{ic|-localhost}} 标志以确保安全)<br />
# Android 设备上的 SSH 客户端:''ConnectBot'' 是一个流行的选择,本例中将使用它<br />
# Android 设备上的 VNC 客户端:此处采用 ''androidVNC''<br />
<br />
在 ''ConnectBot'' 中连接到目标主机。轻点 options 按钮,选择 ''Port Forwards'' 并添加一个端口:<br />
Type: Local<br />
Source port: 5901<br />
Destination: 127.0.0.1:5901<br />
<br />
在 ''androidVNC'' 中连接到 VNC 端口,即 SSH 连接中设置的本地端口:<br />
Password: the vncserver password<br />
Address: 127.0.0.1<br />
Port: 5901<br />
<br />
== 提示和技巧 ==<br />
<br />
=== 连接到 OS X 系统 ===<br />
<br />
参见 https://help.ubuntu.com/community/AppleRemoteDesktop。 已在 Remmina 上测试。<br />
<br />
=== 推荐的安全设置 ===<br />
<br />
[[#Accessing vncserver via SSH tunnels]] 中,SSH 处理身份验证和加密,如果没有采用该方法,则建议用 ''X509Vnc'',因为 ''TLSVnc'' 缺乏身份验证。 <br />
<br />
$ vncserver -x509key ''/path/to/key.pem'' -x509cert ''/path/to/cert.pem'' -SecurityTypes X509Vnc :1<br />
<br />
颁发 x509 证书超出了本指南的范围,而 [[wikipedia:Let's Encrypt|Let's Encrypt]] 提供了一种简便方法。也可以使用 [[OpenSSL]] 来颁发证书,然后与客户端共享公钥并使用 {{ic|-X509CA}} 参数指定证书。下面是一个示例(服务器运行在 10.1.10.2 上):<br />
$ vncviewer 10.1.10.2 -X509CA ''/path/to/cert.pem''<br />
<br />
=== 切换全屏 ===<br />
<br />
从 VNC 客户端的菜单可以切换全屏。默认快捷键是 {{ic|F8}}。<br />
<br />
=== 鼠标后退和前进按钮失效的解决方法 ===<br />
<br />
VNC 协议目前只支持 7 个鼠标按钮(左、中、右、向上滚动、向下滚动、向左滚动、向右滚动),如果鼠标有后退和前进按钮,这些按钮无法使用,按钮的输入将被忽略。<br />
<br />
在单击鼠标后退/前进按钮时,[https://www.bedroomlan.org/projects/evrouter/ evrouter] 将其改为键盘按键发送,可以解决此限制。如果需要,可以在服务器上使用 {{Pkg|xautomation}} 和 {{Pkg|xbindkeys}} 中的 xte 将键盘按键映射回鼠标单击。 <br />
<br />
==== 用键盘 XF86Back/XF86Forward 按键代替鼠标后退/前进按钮 ====<br />
<br />
如果只需要在用 Web 浏览器或文件浏览器时后退/前进,则此方法既简单又合适。<br />
<br />
客户端安装 {{AUR|evrouter}} 和 {{Pkg|xautomation}}。配置 evrouter,想知道如何查找设备名称、窗口名称、按钮名称等,请参阅 [[Mouse buttons#evrouter]] 和 evrouter 手册页。以下是示例配置:<br />
{{hc|~/.evrouterrc|Window "OtherComputer:0 - TigerVNC": # 筛选窗口标题<br />
<br />
# 使用 Shell 防止重复按键(参见 evrouter 手册)<br />
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Back'"<br />
"USB mosue" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Forward'"<br />
<br />
# 如果需要重复按键,请使用下面的 XKey(参见 evrouter 手册)<br />
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/275 "XKey/XF86Back"<br />
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/276 "XKey/XF86Forward"}}<br />
<br />
客户端启动 evrouter。按照上面的配置,点击鼠标后退按钮时,向 VNC 服务器发送键盘按键 XF86Back,点击前进按钮时发送 XF86Forward。 <br />
<br />
==== 在服务端将键盘按键映射回的鼠标点击 ====<br />
<br />
必要时可以在服务端将键盘按键映射回鼠标点击。此时最好使用客户端或服务端都不使用的按键值。下面的例子将按键值 XF86Launch8/XF86Launch9 用作鼠标按钮 8/9。<br />
<br />
客户端上的 evrouter 配置:<br />
{{hc|~/.evrouterrc|Window "OtherComputer:0 - TigerVNC": # 窗口标题<br />
<br />
# 使用 Shell 防止重复按键(参见 evrouter 手册)<br />
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Launch8'"<br />
"USB mosue" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Launch9'"}}<br />
<br />
服务端安装 {{Pkg|xautomation}} 和 {{Pkg|xbindkeys}}。配置 xbindkeys,配置中使用 xte 将键盘按键 XF86Launch8/XF86Launch9 映射到鼠标按钮 8/9。 <br />
{{hc|~/.xbindkeysrc|<br />
"xte 'mouseclick 8'"<br />
XF86Launch8<br />
<br />
"xte 'mouseclick 9'"<br />
XF86Launch9<br />
}}<br />
启用 xbindkeys {{ic|$ xbindkeys -f ~/.xbindkeysrc}}。服务端将 XF86Launch8/XF86Launch9 映射为鼠标按钮 8/9。<br />
<br />
== 疑难解答 ==<br />
<br />
=== vncserver 内的终端起始于 / (根目录) ===<br />
<br />
这是上游引入的已知问题。参阅:https://github.com/TigerVNC/tigervnc/issues/1108<br />
<br />
=== 无法输入 '<' 符号 ===<br />
<br />
如果在客户端上按下 {{ic|<}} 却发送了 {{ic|>}} 字符,请尝试重新映射键盘 [https://insaner.com/blog/2013/05.html#20130422063137]{{Dead link|2020|04|03|status=404}}:<br />
<br />
$ x0vncserver -RemapKeys="0x3c->0x2c"<br />
<br />
=== 窗口显示为黑色方框 ===<br />
<br />
这种情况很可能是应用程序依赖于 Xorg 的 Composite 扩展。如基于 webkit 的应用程序:midori、psi-plus 等。<br />
<br />
这种情况下使用下列命令重启 vncserver:<br />
<br />
$ vncserver -geometry ... -depth 24 :1 +extension Composite<br />
<br />
VNC 下的 Composite 扩展仅在 24 位色深时才能正常工作。<br />
<br />
=== 没有鼠标指针 ===<br />
<br />
当使用 {{ic|x0vncserver}} 时没有可见的鼠标指针,请使用下列命令启动 vncviewer:<br />
<br />
$ vncviewer DotWhenNoCursor=1 <server><br />
<br />
或者将 {{ic|DotWhenNoCursor<nowiki>=</nowiki>1}} 写入 tigervnc 配置文件,配置文件默认存放在 {{ic|~/.vnc/default.tigervnc}}。<br />
<br />
=== 从远程主机复制剪贴板内容 ===<br />
<br />
如果无法从远程主机复制到本地,请在服务端运行 {{ic|autocutsel}},如 [https://bbs.archlinux.org/viewtopic.php?id=101243] 中所述:<br />
<br />
$ autocutsel -fork<br />
<br />
然后按下 F8 打开 VNC 菜单,选择 {{ic|Clipboard: local -> remote}} 选项。<br />
<br />
=== 启动 GNOME 3 时显示 "Authentication is required to create a color managed device" 对话框 ===<br />
<br />
一种解决方法是创建一个 "vnc" 组,将 gdm 用户和其他使用 vnc 的用户添加到该组。按如下方式 [https://github.com/TurboVNC/turbovnc/issues/47] 修改 {{ic|/etc/polkit-1/rules.d/gnome-vnc.rules}}:<br />
<br />
polkit.addRule(function(action, subject) {<br />
if ((action.id == "org.freedesktop.color-manager.create-device" ||<br />
action.id == "org.freedesktop.color-manager.create-profile" ||<br />
action.id == "org.freedesktop.color-manager.delete-device" ||<br />
action.id == "org.freedesktop.color-manager.delete-profile" ||<br />
action.id == "org.freedesktop.color-manager.modify-device" ||<br />
action.id == "org.freedesktop.color-manager.modify-profile") &&<br />
subject.isInGroup("vnc")) {<br />
return polkit.Result.YES;<br />
}<br />
});<br />
<br />
=== 没有窗口装饰/边框/标题栏/无法移动窗口 ===<br />
<br />
启动一个窗口管理器来修复一个空的 xterm frame。例如在 xfce 上,可在终端中运行 `xfwm4 &`。 <br />
<br />
=== 按用户运行 systemd service unit ===<br />
<br />
$ sudo nano /usr/lib/systemd/system/tigervnc@.service<br />
<br />
[Unit]<br />
Description=Remote desktop service (VNC)<br />
After=syslog.target network.target<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=/sbin/runuser -l USERNAME -c "/usr/bin/vncserver %i"<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
<br />
假设在 display 9 上启动服务:<br />
$ sudo systemctl start tigervnc@:9<br />
<br />
在启动时运行:<br />
$ sudo systemctl enable tigervnc@:9<br />
<br />
== 另外参见 ==<br />
<br />
* https://github.com/TigerVNC/tigervnc</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Security_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)&diff=565782
Security (Русский)
2019-02-04T01:58:57Z
<p>Arisaka: Add link of zh-hans.</p>
<hr />
<div>[[Category:Security (Русский)]]<br />
[[Category:File systems (Русский)]]<br />
[[Category:Networking (Русский)]]<br />
[[Category:Русский]]<br />
[[en:Security]]<br />
[[fa:امنیت]]<br />
[[ja:セキュリティ]]<br />
[[zh-hans:Security]]<br />
{{Related articles start (Русский)}}<br />
{{Related|List of applications/Security (Русский)}}<br />
{{Related|:Category:Security (Русский)}}<br />
{{Related articles end}}<br />
{{Translateme (Русский)|Перевод устарел.}}<br />
{{Unmaintained (Русский)}}<br />
Описываются возможные методы повышения уровня безопасности и защиты информации в системах на базе ArchLinux.<br />
<br />
==Защита информации==<br />
*Приемы, увеличивающие безопасность вашей системы, снижают удобство ее использования. Важно соблюсти баланс между безопасностью и удобством. Запомните: ''безопасный компьютер - не работающий компьютер''.<br />
*Существует множество способов обезопасить компьютер, но наибольшая угроза всегда будет исходить от самого пользователя. Ведь злоумышленникам нужен не компьютер, а Ваши данные. Представьте, что ваша система безопасности имеет слои: если некоторые из них удалось обойти, остальных должно быть достаточно для защиты. Тем не менее вы никогда не сможете сделать систему ''абсолютно'' безопасной, ведь для этого вам придется отключить ее ото всех сетей, закрыть в сейфе и никогда не пользоваться.<br />
*Будьте немного параноиком и с осторожностью относитесь ко всему. Если что-то звучит слишком хорошо, чтобы быть правдой, то оно правдой может и не быть.<br />
*Ознакомьтесь с [https://ru.wikipedia.org/wiki/Принцип_минимальных_привилегий принципом минимальных привилегий].<br />
<br />
==Физическая безопасность==<br />
{{Note (Русский)|Вы можете пропустить эту секцию, если вас интересует только защита от удаленных угроз.}}<br />
Физический доступ к компьютеру обычно предполагает доступ с правами root. Можно ограничить доступ таким образом, чтобы злоумышленник мог получить информацию только сняв ваш жесткий диск (см. также шифрование) или сбросив настройки BIOS. Оба варианта предполагают вскрытие системного блока, так что, возможно, замок на системном блоке будет не лишним.<br />
<br />
===Блокировка BIOS===<br />
<br />
Установка пароля на BIOS препятствует изменению его настроек и загрузке с помощью съемных устройств для получения root-доступа к файловой системе. Вы должны убедиться, что ваш диск является первым загрузочным устройством в списке (или вообще отключите возможность загрузки с других устройств).<br />
<br />
===Пароль загрузчика===<br />
<br />
Очень важно защитить загрузчик. Существует волшебный параметр ядра '''init=/bin/sh'''. Он делает использование разграничений прав бесполезным.<br />
<br />
Надежные пароли можно сгенерировать с помощью пакета {{AUR|apg}} или другого автоматического генератора паролей.<br />
<br />
==== GRUB ====<br />
<br />
[[GRUB (Русский)#Защита загрузчика паролем]].<br />
<br />
=== Отключение CTRL-ALT-DEL ===<br />
<br />
Чтобы запретить использование CTRL-ALT-DEL для перезагрузки машины, вы можете использовать файл {{ic|/etc/inittab}}. Используется в производственной среде, где оператор работает с клавиатурой, в то время как сам компьютер обычно защищен.<br />
<br />
Откройте файл {{ic|/etc/inittab}} и найдите линию:<br />
<br />
ca::ctrlaltdel:/sbin/shutdown -t3 -r now<br />
<br />
Закоментируйте строку, вставив символ #.<br />
Изменения вступят в силу после перезагрузки. Для того, чтобы применить их сейчас, выполните:<br />
<br />
{{bc|# /sbin/init -q}}<br />
<br />
Разумеется, кто-то может получить физический доступ к вашему компьютеру и ему будет достаточно нажать кнопку питания, чтобы выключить систему.<br />
<br />
=== Автоматическая деавторизация в виртуальной консоли (и SSH) ===<br />
Если вы не используете bash или zsh, вы можете настроить TMOUT, и вы, таким образом, не забудете выйти из оболочки (когда xscreensaver не запускается и не может вас защитить).<br />
<br />
Вот пример скрипта, который можно поместить, например, сюда: {{ic|/etc/profile.d/shell-timeout.sh}}<br />
<br />
TMOUT="$(( 60*10 ))";<br />
[ -z "$DISPLAY" ] && export TMOUT;<br />
case $( /usr/bin/tty ) in<br />
/dev/tty[0-9]*) export TMOUT;;<br />
esac<br />
<br />
Если вы хотите использовать таймаут в любом терминале bash/zsh (даже в X), используйте просто:<br />
<br />
export TMOUT="$(( 60*10 ))";<br />
<br />
Обратите внимание, что скрипт не сработает, если в оболочке выполняется команда (например: ssh-сессия или закачка wget). Если вы используете виртуальные консоли в основном для перезагрузки зависших GDM/Xorg, это может быть весьма полезно.<br />
<br />
==Дисковые разделы==<br />
<br />
Все директории в которые может записывать информацию обычный пользователь, должны монтироваться отдельно от корня чтобы избежать уязвимостей жестких ссылок и атак типа «отказ в обслуживании» (квоты не мешают пользователю вызывать DoS, если существуют доступные для записи каталоги).<br />
<br />
Минимальное число разделов, необходимых для «безопасной» системы:<br />
:'''/'''<br />
:'''/var''': /var/spool/mail, /var/lock и /var/tmp - право записи имеют все пользователи системы (доступны для записи); избыток логов может быть использован для атаки переполнения раздела.<br />
:'''/tmp''': право записи имеют все пользователи системы (доступны для записи)<br />
:'''/home''': право записи имеют обычные пользователи<br />
<br />
{{Note (Русский)|/tmp может быть смонтирован как tmpfs, так что такой раздел на диске безопасней не делать. См. [[fstab (Русский)|fstab]].}}<br />
<br />
===Опции монтирования===<br />
Следуя принципу наименьших привилегий, разделы должны быть смонтированы с наиболее ограничивающими опциями, насколько это возможно (без ущерба для функциональности).<br />
<br />
====Монтирование====<br />
<br />
*'''nodev:''' Данная опция предполагает что на монтируемой файловой системе не будут созданы файлы устройств (/dev). Корневой каталог и целевая директория команды chroot всегда должны монтироваться с опцией dev или defaults.<br />
*'''nosuid:''' Запрещает операции с set-user-identifier и set-group-identifier битами.<br />
*'''noexec:''' Бинарные файлы не выполняются. НИКОГДА не используйте эту опцию на вашей корневой системе!<br />
<br />
====Пример использования====<br />
<br />
{{Note (Русский)|Разделы на которых предполагается лишь хранение данных должны монтироваться с параметрами {{ic|nodev,nosuid,noexec}}.}}<br />
<br />
{|<br />
| align="center" style="background:#f0f0f0;"|'''Раздел'''<br />
| align="center" style="background:#f0f0f0;"|'''nodev'''<br />
| align="center" style="background:#f0f0f0;"|'''nosuid'''<br />
| align="center" style="background:#f0f0f0;"|'''noexec'''<br />
|-<br />
| /var||да||да||да<br />
|- style="background:#e4e4e4"<br />
| /home||да||да||да, если вы не пишете программы или не используете [[Wine (Русский)|wine]]<br />
|-<br />
| /dev/shm||да||да||да<br />
|- style="background:#e4e4e4"<br />
| /tmp||да||да||возможно, но запрещает компиляцию и некоторые другие вещи<br />
|-<br />
| /boot||да||да||да<br />
|-<br />
|}<br />
<br />
==Настройка доступа к файловой системе==<br />
Параметры доступа по умолчанию предоставляют доступ на чтение практически для всего и изменение прав доступа может скрыть ценную информацию от злоумышленника, получившего доступ в правами не-root пользователя такого как http или nobody.<br />
<br />
Например:<br />
<br />
{{bc|# chmod 700 /boot /etc/{iptables,arptables} }}<br />
<br />
==Шифрование диска==<br />
Вы должны знать, что шифрование является единственным способом для защиты ваших данных от людей, которые имеют физический доступ к компьютеру. Шифрованные тома должны монтироваться только в условиях когда ни вам ни вашим данным ничего не угрожает: только вы имеете физический и root-доступ к системе (root сам по себе небезопасен, не используйте его без острой необходимости).<br />
<br />
*[[System Encryption with LUKS]]<br />
*[[EncFS]]<br />
*[[System Encryption with eCryptfs (Русский)]]<br />
<br />
==Пароли==<br />
{{Note (Русский)|Лучший способ забыть пароль - это нажать на кнопку запомнить пароль.}}<br />
Используйте надежный пароль. Составляйте его с помощью специальных сервисов или самостоятельно, но не используйте пароли которые легко подобрать, например набор обычных слов или имя вашей любимой тещи. Так как любой, кто знает вашу тёщу может догадаться использовать ее имя как пароль (даже она сама). Словом, опасайтесь тёщ и социальной инженерии.<br />
В пароле должно быть не менее 8 символов, но лучше 12 и более. Также стоит использовать буквы разного регистра, цифры и специальные символы. Дело в том, что при переборе пароля взломщик указывает, какие наборы символов может содержать подбираемый пароль. Обычно эти наборы: цифры, буквы (в одном или разных регистрах), специальные знаки. Некоторые люди в своих паролях используют даже редкие символы юникода (вроде неразрывного пробела), недоступные для простого набора с клавиатуры. Удлинение пароля даже на один символ ''значительно'' усложняет задачу взломщика, но не переусердствуйте со сложностью.<br />
<br />
Не забывайте использовать мнемонические правила запоминания. Например, можно использовать первые буквы из слов в стишках которые вы учили в детстве. Обычно такое не забывается.<br />
<br />
==Запрет входа root в оболочку==<br />
Отключение возможности входа root в оболочку еще больше урежет возможности злоумышленнику. Кроме того, логин пользователя может быть неизвестен, что еще больше усложнит задачу взломщика. Для контроля над возможностью входа root в консоль используется файл {{ic|/etc/securetty}}. Закоментируйте tty, чтобы запретить вход от root:<br />
Затем измените:<br />
<br />
tty1<br />
<br />
в<br />
<br />
#tty1<br />
<br />
Повторите для каждого tty который хотите заблокировать.<br />
<br />
Чтобы убедиться в эффекте этого изменения, перейдите к соответствующей консоли. При попытке логина от имени root система выведет сообщение “Login incorrect”. Теперь, когда мы убедились что это работает, закоментируйте остальные tty. Но стоит помнить что если система зависнет или даст сбой данная блокировка заставит вас изрядно помучатся.<br />
<br />
==Блокировка пользователя после трех неудачных попыток входа==<br />
Чтобы еще больше повысить безопасность системы, можно блокировать логин пользователя после нескольких неудачных попыток ввода пароля. Учетная запись может быть заблокирована на некоторый промежуток времени или до тех пор, пока root не разблокирует пользователя вручную. Чтобы блокировать учетную запись пользователя на определенный промежуток времени, после трех неудачных попыток ввода, изменить файл {{ic|/etc/pam.d/system-login}}. Найдите следующую строку:<br />
<br />
#auth required pam_tally.so deny=3 unlock_time=1200 onerr=succeed file=/var/log/faillog<br />
<br />
и удалите решетку #. Если её нет, то добавьте. Затем перейдите к этой строке:<br />
<br />
auth required pam_tally.so onerr=succeed file=/var/log/faillog<br />
<br />
и вставьте символ # в ее начале. Если вы не сделаете этого, каждая неудачная попытка будет считаться за две. На этом все. Можете проверить как работает блокировка если есть желание.<br />
Чтобы разблокировать от root, используйте команду:<br />
<br />
{{bc|# pam_tally --reset --user [пользователь]}}<br />
<br />
Удалите {{ic|unlock_time}} чтобы пользователь не мог авторизоваться, пока его не разблокирует root.<br />
<br />
==Использование sudo для системных команд==<br />
Чтобы позволить пользователю запускать некоторые системные команды с правами root, рекомендуется использовать sudo. Так как пользователь должен будет вводить только свой пароль, вы сможете сохранить в секрете пароль root. Если вы являетесь единственным пользователем компьютера, то sudo позволяет как можно реже обращаться к учетной записи root. Таким образом, вы не забудете вернуться к учетной записи обычного пользователя.<br />
<br />
Настроить sudo легко. Просто выполните команду {{ic|visudo}} чтобы открыть конфигурационный файл в редакторе Vi.<br />
В файле есть пример, который можно использовать. Например, если вы хотите монтировать samba-разделы по сети, войдя под обычным пользователем, используйте следующую строку:<br />
<br />
%users ALL=/sbin/mount.cifs,/sbin/umount.cifs<br />
<br />
Это разрешает всем членам группы пользователя who are members of the group users to run the commands ''/sbin/mount.cifs'' and ''/sbin/umount.cifs'' from any machine(ALL).<br />
Если вы не умеете или не любите использовать редактор Vi, для использования другого редактора (например, nano), воспользуйтесь:<br />
<br />
export EDITOR=nano<br />
<br />
Тем не менее, это само по себе недостаточно безопасно. См. объяснения ниже.<br />
<br />
По умолчанию, visudo не следует по директории, указанной в переменной EDITOR. Это брешь в безопасности, ведь в противном случае все что угодно может быть использовано в качестве редактора (привет, руткиты!). Лучше всего задать редактор по умолчанию в файле {{ic|/etc/sudoers}} (используйте полный путь к редактору):<br />
<br />
Defaults editor=/usr/bin/nano<br />
<br />
Теперь используйте только команду visudo.<br />
<br />
Пожалуйста, будьте осторожны и не давайте пользователю право использовать '''все''' команды. Иначе, какой смысл создавать обычного пользователя?<br />
<br />
==Хеши паролей==<br />
Переход с [https://ru.wikipedia.org/wiki/MD5 MD5] на [[SHA password hashes|SHA]]-тип хеширования пароля усложняет задачу восстановить из хеша ваш пароль.<br />
<br />
==Контроль доступа==<br />
*[[AppArmor]] (путь)<br />
*[[SELinux]] (метки)<br />
*[[Tomoyo]] (путь)<br />
<br />
==Kernel hardening==<br />
[[grsecurity]]<br />
<br />
==Firewall==<br />
*См. [[Simple stateful firewall]] гид по настройке netfilter (iptables) firewall'a.<br />
*См. [[Firewalls]] для других способов настройки Firewall.<br />
*См. [[iptables]] для общей информации.<br />
*См. [https://ru.wikipedia.org/wiki/Iptables Iptables] на Википедии.<br />
<br />
==Упрочнение стека TCP/IP==<br />
<br />
[[Sysctl#TCP/IP stack hardening|TCP/IP stack hardening]]<br />
<br />
==Безопасность пакетов на зеркалах==<br />
Пакеты ArchLinux не имеют цифровой подписи. Это значит, что при обновлении с вашего любимого зеркала вам могут подсунуть ''особый'' пакет. Последствия такого обновления непредсказуемы и можно достоверно утверждать лишь то, что ваша система больше не будет являться безопасной. С релизом Pacman 4 данная проблема должна решится.<br />
Пока функция подписи пакетов только добавляется в ArchLinux. Используйте [http://igurublog.wordpress.com/downloads/script-paccheck/ paccheck] ([https://aur.archlinux.org/packages.php?ID=46763 AUR], [https://bbs.archlinux.org/viewtopic.php?id=113917 Forum]) рекомендуется, чтобы помочь аутентифицировать и сравнивать пакеты, загруженные с разных зеркал.<br />
Скрипт сравнивает базы данных pacman sync и файлы package desc на различных зеркалах и в кеше pacman.<br />
<br />
==Источники==<br />
* Securing and Hardening Red Hat Linux Production Systems <br />http://www.puschitz.com/SecuringLinux.shtml<br />
* Безопасный Linux, часть 1: Introduction <br />http://www.ibm.com/developerworks/linux/library/l-seclnx1.html<br />
* Оптимизаиция и безопасность Linux <br />http://www.faqs.org/docs/securing/index.html<br />
* Проверка безопасности UNIX and Linux v3.0 <br />http://www.auscert.org.au/5816</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Security_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=565781
Security (简体中文)
2019-02-04T01:56:28Z
<p>Arisaka: Create this page & sync with English version.</p>
<hr />
<div>[[Category:Security (简体中文)]]<br />
[[Category:File systems (简体中文)]]<br />
[[Category:Networking (简体中文)]]<br />
[[en:Security]]<br />
[[fa:امنیت]]<br />
[[ja:セキュリティ]]<br />
[[ru:Security]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Arch Security Team}}<br />
{{Related|General recommendations (简体中文)}}<br />
{{Related|PAM (简体中文)}}<br />
{{Related|Capabilities (简体中文)}}<br />
{{Related|List of Applications/Security}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Security|2019-02-04|565780}}<br />
<br />
本文主要包括 [[Wikipedia:Hardening (computing)|加固]] Arch Linux 系统的常用建议与最佳实践。<br />
<br />
== 基本概念 ==<br />
<br />
* 有可能出现不停地加强系统安全性而导致系统无法正常使用的情况,因此不能过度加强安全。<br />
* 提高安全性的方法有很多,但最致命的弱点永远在于人(用户)。考虑安全问题时,需要考虑多个层次。当一层防护被攻破时,另一层应该能够阻止攻击,但即使如此仍无法保证系统 100% 安全,除非把机器从网络上断开,锁进保险柜并不再使用它。<br />
* 一点点的偏执和多疑有助于发现问题。如果某件事看起来太过完美,那可能问题就出在这。<br />
* [[Wikipedia:Principle of least privilege|最小权限原则]]:系统的每一部分仅能访问到必要的内容,其他内容则不可见。<br />
<br />
== 密码 ==<br />
<br />
密码是加强 Linux 系统的安全性的关键。它可以保护你的[[Users and groups (简体中文)|用户账户]]、[[Disk encryption|加密的文件系统]]和[[SSH keys|SSH]]/[[GPG]] 密钥。密码也是让计算机信任使用者的主要方式,所以大多数安全问题都出在如何选择高强度的密码并保护它们不被泄露上。<br />
<br />
=== 选择高强度的密码 ===<br />
<br />
当安全措施依赖于密码时,密码必须足够复杂,不能轻易地被猜中(比如和个人信息有关的密码),也不能轻易地被暴力尝试等方法 [[Wikipedia:Password cracking|破解]],强密码的基本原则基于 ''长度'' 和 ''随机性'',在密码学中,密码的质量与它的 [[Wikipedia:Entropic security|熵安全性]] 有关。<br />
<br />
不安全的密码主要包括:<br />
<br />
* 个人身份信息(如:狗的名字,出生日期,区号,最喜欢的视频游戏)<br />
* 对一个单词简单地替换一些字符(如:{{ic|k1araj0hns0n}})<br />
* 几个基本的常见字符,在它们的前后加上数字,符号或其他字符(如:{{ic|DG091101%}})<br />
* 在语法上相关的常用短语(如:{{ic|all of the lights}}),换掉了部分字符也不行。<br />
<br />
好的密码首先要长(8~20 个字符,长度取决于重要程度),并且看起来完全随机。<br />
有个方法可以产生安全性好的、看起来随机的密码,那就是从一句句子的每一个词中提炼出一个符号。<br />
例如 “the girl is walking down the rainy street” 这句话可以转换为 {{ic|t6!WdtR5}} 或是更加复杂的 {{ic|t&6!RrlW@dtR,57}}。<br />
这种方法可以更为简单地帮助记忆密码,但是请注意,不同字母出现在单词开头的概率不同 ([[Wikipedia:Letter frequency#Relative frequencies of the first letters of a word in the English language|Wikipedia:Letter frequency]])。同时也要考虑 [http://world.std.com/~reinhold/diceware.html Diceware Passphrase] 中提到的方法,使用足够数量的单词。<br />
<br />
更好的方法是使用 {{Pkg|pwgen}} 或 {{AUR|apg}} 等工具生成伪随机密码:为了记住它们,一种方法(仅针对经常输入的密码)是生成一个长密码并记住一小段(这一小段要能保证最低限度的安全),暂时把完整的密码写下来。随着时间推移,输入次数增加,密码会随着肌肉记忆根深蒂固。这种方法很难,但是能保证密码不会出现在破解用的字典里,也可以抵御能“智能地”组合单词并替换部分字符的暴力破解。<br />
<br />
将生成与记忆密码两者结合的 [[password manager|密码管理器]] 也很有用,它可以保存长而复杂的随机密码,同时被一个方便记忆的密码保护着,该密码必须仅用于此密码管理器,特别注意要避免通过任何网络传输这个密码。当然这个方法限制了只能从存有密码库的电脑上使用已保存的密码(另一方面,这也可以视为额外的安全特性)。<br />
<br />
可以看下 Bruce Schneier 的文章 [https://www.schneier.com/blog/archives/2014/03/choosing_secure_1.html Choosing Secure Passwords],[https://www.iusmentis.com/security/passphrasefaq/ The passphrase FAQ] 或 [[Wikipedia:Password strength]] 获取额外背景信息。<br />
<br />
=== 维护密码安全 ===<br />
<br />
一旦你选择了一个强密码,一定要保证它的安全。当心 [[Wikipedia:Keylogger|键盘记录器]](软件或硬件层面上的),[[Wikipedia:Social engineering (security)|社会工程]],[[Wikipedia:Shoulder surfing (computer security)|肩窥]],并避免使用一样的密码,这样不安全的服务器就无法泄漏超出其范围的信息。[[List of applications/Security#Password managers|密码管理器]] 可以帮助管理大量复杂密码:将密码从管理器复制粘贴到其他程序中时,请确保每次粘贴完都清除复制缓冲区,并确保它们不会保存在日志记录里面(例如,不要将它们粘贴在普通的终端命令中,因为这些命令会存到 {{ic|.bash_history}} 等文件里)。<br />
<br />
最好不要因为安全性强的密码难记而选择不安全的密码,密码是它们之间的一种平衡。与拥有许多相似的弱密码相比,更好的做法是建立一个加密的安全密码数据库,数据库由密钥和一个强主密码保护着。把密码写下来可能同样有效[https://www.schneier.com/blog/archives/2005/06/write_down_your.html],这样就避开了软件中的潜在漏洞,同时增加了物理安全性要求。<br />
<br />
衡量密码强度的另一个指标是它能不能轻易从其他地方恢复。<br />
如果你的登录密码和用于磁盘加密的密码相同(这在登录时自动挂载加密分区或目录很有用),请确保 {{ic|/etc/shadow}} 也在加密分区上,或者使用强哈希算法(即 sha512/bcrypt,而不是 md5)来存储密码(详细信息请参阅 [[SHA password hashes]])。<br />
<br />
如果要备份密码数据库,请勿将备份的副本存储在密码保护之下(比如存储在加密的驱动器或需要身份验证的远程存储服务),而解锁副本的密码又存储在副本中,这样在需要时将无法访问它。一个有用的技巧是,使用主密码的简单哈希来加密存储着密码数据库的驱动器或在线帐户。维护一份记录备份位置的列表:如果有一天担心主密码被泄露,一是要更改所有数据库备份的密码,二是要使用从新主密码派生的新哈希来保护存有数据库的位置。以安全的方式控制数据库的版本可能非常复杂:如果你这样做,那你必须有办法更新所有数据库版本的主密码。主密码泄露时可能并不能马上反映:为了降低其他人更早发现密码的风险,可以选择定期更改密码。如果你担心自己失去了对数据库副本的控制权,则需要在特定时间内更改其中包括的所有密码,这一特定时间是暴力破解主密码所用的时间,取决于主密码的熵。<br />
<br />
=== 密码的散列值 ===<br />
<br />
{{Expansion|提起 [[Wikipedia:Key derivation function|密钥导出函数]],特别是 PBKDF2、bcrypt 和 scrypt,应当提及用法、优缺点,基于定制硬件的暴力攻击应当特别提及。}}<br />
<br />
默认情况下,Arch 将用户密码散列值存储在仅 root 可读的 {{ic|/etc/shadow}} 文件中,与存储在所有人可读的 {{ic|/etc/passwd}} 文件中的其他用户参数分开,请参阅 [[Users and groups (简体中文)#用户信息存储]]。另请参阅 [[#限制 root 权限]]。<br />
<br />
密码应使用 '''passwd''' 命令来设置,该命令使用 [[Wikipedia:Crypt (C)|crypt]] 函数对密码进行 [[Wikipedia:Key stretching|拉伸]],然后将它们保存在 {{ic|/etc/shadow}} 中。请参阅 [[SHA password hashes]]。密码也被 [[Wikipedia:Salt (cryptography)|salted(加盐)]],以抵御 [[Wikipedia:Rainbow table|彩虹表]] 攻击。<br />
<br />
另请参阅 [http://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils How are passwords stored in Linux (Understanding hashing with shadow utils)]。<br />
<br />
=== 用 pam_cracklib 强制使用强密码 ===<br />
<br />
''pam_cracklib'' 提供针对 [[Wikipedia:Dictionary attack|字典攻击]] 的保护,并可用于配置在整个系统中实施的密码策略。<br />
<br />
{{警告|''root'' 账户不会受此策略影响。}}<br />
{{注意|可以用 ''root'' 帐户来帮助想绕过策略的用户设置他们的密码。这在设置临时密码时很有用。}}<br />
<br />
举个例子,假设要强制执行下面的策略:<br />
<br />
* 如果密码错误,请提示 2 次<br />
* 最小长度为10个字符(minlen 选项)<br />
* 输入新密码时,新密码应至少有 6 个字符与旧密码不同(difok 选项)<br />
* 至少 1 个数字(dcredit 选项)<br />
* 至少 1 个大写字母(ucredit 选项)<br />
* 至少 1 个特殊字符(ocredit 选项)<br />
* 至少 1 个小写字母(lcredit 选项)<br />
<br />
编辑 {{ic|/etc/pam.d/passwd}} 文件,把它改成:<br />
<br />
{{bc|1=<br />
#%PAM-1.0<br />
password required pam_cracklib.so retry=2 minlen=10 difok=6 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1<br />
password required pam_unix.so use_authtok sha512 shadow<br />
}}<br />
<br />
{{ic|password required pam_unix.so use_authtok}} 用来告诉 ''pam_unix'' 模块不要显示输入密码的提示符,而是采用来自 ''pam_cracklib'' 的密码。<br />
<br />
更多信息可以参考 {{man|8|pam_cracklib}} 和 {{man|8|pam_unix}} 手册页。<br />
<br />
== 存储 ==<br />
<br />
=== 磁盘加密 ===<br />
<br />
进行[[Disk encryption|磁盘加密]]时最好使用[[#密码|强密码]]进行全盘加密,这是保护数据免受物理恢复的唯一方法。这也可以在计算机关闭或相关硬盘卸载时充分保护数据安全。<br />
<br />
当然,一旦计算机启动,磁盘挂载完毕,这些数据就像存储在未加密的磁盘上一样易受攻击。因此,最佳做法是在不需要用到数据分区时立即卸载它们。<br />
<br />
部分程序,比如 [[dm-crypt]],允许用户加密 Loop 文件并将其作为虚拟卷使用。当系统只有特定的部分需要加密时,这种方法可以替代全盘加密。<br />
<br />
=== 文件系统 ===<br />
<br />
如果用 sysctl 启用了内核的 {{ic|fs.protected_hardlinks}} 和 {{ic|fs.protected_symlinks}} 选项,内核就可以防止出现硬链接和软链接(符号链接)相关的安全问题。因此独立出一个全局可写的目录不再具有安全方面的优势。<br />
<br />
文件系统中包含的全局可写的目录,仍然可以作为一种防止磁盘空间耗尽的粗略手段。但是,把 {{ic|/var}} 或 {{ic|/tmp}} 所在分区塞满也足以使系统停止响应。处理这种问题的更灵活的机制是存在的(比如 [[Disk quota|磁盘配额]]),并且某些 [[File systems (简体中文)|文件系统]] 自身就带有类似功能(Btrfs 的子卷可以设置配额)。<br />
<br />
==== 挂载点 ====<br />
<br />
根据最小权限原则,挂载文件系统时应该采用最为严格的挂载选项(在不损失功能的情况下)。<br />
<br />
相关的挂载选项有:<br />
<br />
* {{ic|nodev}}: 文件系统中,禁止解释任何字符或屏蔽特殊设备。<br />
* {{ic|nosuid}}: 禁止 set-user-identifier 或 set-group-identifier 标志位生效。<br />
* {{ic|noexec}}: 禁止文件系统里的任何二进制文件直接运行。<br />
** 在 {{ic|/home}} 上设置 {{ic|noexec}} 选项会禁用可执行脚本,影响 [[Wine]]* 和 [[Steam]] 正常运行。<br />
** 部分软件包(比如编译 {{Pkg|nvidia-dkms}})可能需要 {{ic|/var}} 有 {{ic|exec}} 权限。<br />
<br />
{{注意|Wine 运行 Windows 应用时不需要该应用带有 {{ic|exec}} (可执行)标识,仅在 Wine 自身安装在 {{ic|/home}} 时需要有可执行权限。}}<br />
<br />
用于存放数据的文件系统应该坚持使用 {{ic|nodev}}、{{ic|nosuid}} 和 {{ic|noexec}} 挂载。<br />
<br />
文件系统划分参考:<br />
<br />
* {{ic|/var}}<br />
* {{ic|/home}}<br />
* {{ic|/dev/shm}}<br />
* {{ic|/tmp}}<br />
* {{ic|/boot}}<br />
<br />
=== 文件访问权限 ===<br />
<br />
默认的 [[file permissions|文件权限]] 对几乎所有文件都赋予了读权限,修改文件权限可以在取得了非 root 账户({{ic|http}} 或 {{ic|nobody}} 账户)的攻击者前隐藏部分信息。<br />
<br />
例如:<br />
<br />
# chmod 700 /boot /etc/{iptables,arptables}<br />
<br />
可以修改默认的 [[Umask]] {{ic|0022}} 来为新建的文件提高安全性。[https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf NSA RHEL5 Security Guide] 建议将 umask 设置为 {{ic|0077}} 以获得最充分的安全性,这将使得新文件无法被创建者之外的用户读取。要修改 umask,参见 [[Umask#Set the mask value]]。<br />
<br />
== 账户安全设置 ==<br />
<br />
安装后,请创建一个普通账户用于日常使用,不要日常使用 root 账户。<br />
<br />
=== 在失败的登录尝试后强制延时一段时间 ===<br />
<br />
将下方的行添加至 {{ic|/etc/pam.d/system-login}} 即可在失败的登录尝试后延时至少 4 秒:<br />
<br />
{{hc|/etc/pam.d/system-login|<br />
2=auth optional pam_faildelay.so delay=4000000<br />
}}<br />
<br />
{{ic|4000000}} 是延时的微秒数。<br />
<br />
=== 在三次登录尝试失败后锁定用户 ===<br />
<br />
为了进一步提高安全性,可以在指定次数的登录尝试失败后锁定用户。普通账户可以被持续锁定直到 root 解锁它,也可以设置在指定的时间后自动解锁。<br />
<br />
要在三次登录尝试失败后将用户锁定十分钟,需要将 {{ic|/etc/pam.d/system-login}} 改为:<br />
<br />
{{hc|/etc/pam.d/system-login|<br />
2=#%PAM-1.0<br />
<br />
auth required pam_tally2.so deny=3 unlock_time=600 onerr=succeed<br />
account required pam_tally2.so<br />
}}<br />
<br />
pam_tally 已被弃用并被 pam_tally2 取代,因此需要注释掉 pam_tally 行:<br />
<br />
#auth required pam_tally.so onerr=succeed file=/var/log/faillog<br />
<br />
全部工作就是这些。如果你有探索精神,请尝试三次登录失败,然后看看会发生什么。要手动解锁用户请执行:<br />
<br />
# pam_tally2 --reset --user ''username''<br />
<br />
{{ic|unlock_time}} 的单位为秒。如果你想在 3 次登录尝试失败后永久锁定用户,请删除该行的 {{ic|unlock_time}} 部分。在 root 解锁该账户前,该账户将无法登录。<br />
<br />
=== 限制进程数量 ===<br />
<br />
在有很多不可信用户的系统上,限制每个用户可运行的进程数量非常重要,因为这样可以防止 [[Wikipedia:Fork bomb|fork bombs]] 以及其他拒绝服务攻击。{{ic|/etc/security/limits.conf}} 决定了每个用户或组可以运行的进程数,默认情况下为空(有用注释除外)。将以下行添加到此文件将限制所有用户每位最多运行 100 个活动进程,除非他们使用 {{ic|prlimit}} 命令将此次会话的最大值显式地提高到 200。可以根据用户需要运行的进程数量或当前管理的系统的硬件条件来确定这些值。<br />
<br />
* soft nproc 100<br />
* hard nproc 200<br />
<br />
当前每个用户运行的进程数量可以使用 {{ic|ps --no-headers -Leo user {{!}} sort {{!}} uniq -c}} 查看。这可以帮助确定合适的进程限额。<br />
<br />
=== 避免用 root 运行 Xorg ===<br />
<br />
由于其架构和过时的设计,[[Xorg (简体中文)|Xorg]] 通常 [https://security.stackexchange.com/questions/4641/why-are-people-saying-that-the-x-window-system-is-not-secure/4646#4646 被认为是不安全的]。因此建议避免以 root 身份运行它。<br />
<br />
有关如何在没有 root 权限的情况下运行 Xorg 的详细信息,请参阅 [[Xorg#Rootless Xorg]]。<br />
<br />
== 限制 root 权限 ==<br />
<br />
按照系统的设计,root 用户是系统中最强大的用户。因为这样,有许多方法可以既保持 root 用户的权限,同时限制其造成破坏的能力,或者至少可以追溯 root 用户的操作。<br />
<br />
=== 用 sudo 替代 su ===<br />
<br />
{{Merge|sudo|这是一篇专门说明 sudo 的文章。}}<br />
<br />
出于 [[su (简体中文)#另一个选择:Sudo|多种原因]],使用 [[Sudo (简体中文)|sudo]] 进行特权访问比 [[su (简体中文)|su]] 更好。<br />
<br />
* sudo 记录了普通权限用户运行每个特权命令的日志。<br />
* root 用户的密码不需要告知每个请求 root 权限的用户。<br />
* {{ic|sudo}} 可以防止用户意外地以 ''root'' 身份执行无需该权限的命令,因为 sudo 并没有为 root 创建完整的终端。这符合 [[Wikipedia:Principle of least privilege|最小权限原则]]。<br />
* <br />
可以为单个用户启用单个程序的 root 权限,而不用为了运行一个程序启用该用户对 root 的完整访问权。例如,要授予用户 ''alice'' 对特定程序的访问权限:<br />
<br />
# visudo<br />
<br />
{{hc|/etc/sudoers|<br />
alice ALL &#61; NOPASSWD: /path/to/program<br />
}}<br />
<br />
另外,也可以为所有用户开放单个程序。例如允许以普通用户身份从服务器挂载 Samba 共享:<br />
<br />
%users ALL=/sbin/mount.cifs,/sbin/umount.cifs<br />
<br />
这将允许 users 组中的所有用户从任何机器 (ALL) 运行此系统的 {{ic|/sbin/mount.cifs}} 和 {{ic|/sbin/umount.cifs}} 命令。<br />
<br />
{{提示|<br />
要 {{ic|visudo}} 使用指定版本的 {{ic|nano}} 而不是 {{ic|vi}},<br />
<br />
{{hc|/etc/sudoers|<br />
2=Defaults editor=/usr/bin/rnano<br />
}}<br />
<br />
Export {{ic|1=# EDITOR=nano visudo}} 被认为存在严重安全风险,因为任何程序都可以作为 {{ic|EDITOR}}。<br />
}}<br />
<br />
==== 使用 sudo 编辑文件 ====<br />
<br />
以 root 身份运行文本编辑器可能会变成安全漏洞,因为许多编辑器可以运行任意 shell 命令或更改正在编辑的文件以外的文件。要避免这一风险,请用 {{ic|sudoedit filename}}(等同于 {{ic|sudo -e filename}})编辑文件。这将使用普通用户的权限来编辑文件的副本,在编辑器关闭后会使用 sudo 覆盖原始文件。可以通过设置 {{ic|SUDO_EDITOR}} 环境变量来更改所使用的编辑器:<br />
<br />
$ export SUDO_EDITOR=vim<br />
<br />
也可以使用类似 {{ic|rvim}} 这样的编辑器,它功能受限,以便以 root 用户身份安全运行。<br />
<br />
=== 限制 root 登录 ===<br />
<br />
正确配置 [[sudo]] 后,完全的 root 权限就可以被严格限制或停用,且不会损失太多可用性。要禁用 root 而允许使用 [[sudo]],可以运行 {{ic|passwd -l root}}。<br />
<br />
==== 仅允许特定用户 ====<br />
<br />
[[PAM]] 的 {{ic|pam_wheel.so}} 模块可以做到仅允许 {{ic|wheel}} 组中的用户使用 {{ic|su}} 登录。编辑 {{ic|/etc/pam.d/su}} 和 {{ic|/etc/pam.d/su-l}} 两份文件,去掉以下行的注释:<br />
<br />
{{bc|<nowiki><br />
# Uncomment the following line to require a user to be in the "wheel" group.<br />
auth required pam_wheel.so use_uid<br />
</nowiki>}}<br />
<br />
这一行表示只有已经能够运行特权命令的用户才能以 root 用户身份登录。<br />
<br />
==== 拒绝 SSH 登录 ====<br />
<br />
即使你不想禁止 root 用户在本地登录,也最好 [[Secure Shell (简体中文)#禁用 root 登录|禁止 root 通过 SSH 登录]]。这样做的目的是在用户可以在远程完全破坏系统之前添加额外的一层安全保护。<br />
<br />
== 强制访问控制 ==<br />
<br />
[[Wikipedia:Mandatory Access Control|Mandatory access control]](MAC, 强制访问控制)是一种安全策略,它与 Arch 以及大部分 Linux 发行版默认使用的 [[Wikipedia:Discretionary Access Control|Discretionary access control]] (DAC, 自主访问控制)有很大的不同。MAC 本质上是对照着一个安全规则集,检查程序的每一个可能对系统造成影响的操作。与 DAC 方式相比,用户不能修改 MAC 的规则集。使用几乎任何强制访问控制系统都将显著提高计算机的安全性,尽管它们的实现方式存在差异。<br />
<br />
=== 基于路径的强制访问控制 ===<br />
<br />
基于路径的访问控制是一种简单的访问控制形式,它根据文件的路径提供相应的权限。这种方式有个缺点,就是当文件改变路径以后相应的权限并没有随着文件一起移动。从积极的方面来说,基于路径的 MAC 可以在更广泛的文件系统上实现,这与基于标签的另一种可选方案是不同的。<br />
<br />
* <br />
[[AppArmor]] 是一个由 [[Wikipedia:Canonical|Canonical]] 维护的 MAC 实现,它被看做是 SELinux 的简化版替代方案。<br />
* <br />
[[Tomoyo]] 是另一种提供访问控制的系统,简单而易用。它的使用方式和内部实现都被设计得足够简单,需要的依赖也很少。<br />
<br />
=== 基于标签的强制访问控制 ===<br />
<br />
基于标签的访问控制意味着每份文件都带有扩展属性用于决定它的安全权限。虽然这类系统应该比基于路径的控制更灵活,但它只适用于支持这些扩展属性的文件系统。<br />
<br />
* <br />
[[SELinux]] 是一个基于 [[Wikipedia:NSA|NSA]] 的项目,用于提高 Linux 的安全性。它完整实现了 MAC,将系统用户与角色独立开来。它实现了一个非常强大的多级 MAC 策略,可以在系统扩大和改变得超出其原始配置时也能轻松控制系统。<br />
<br />
=== 访问控制表 (ACLs) ===<br />
<br />
[[Access Control Lists]](ACLs,访问控制表)是以某种方式将规则直接附加到文件系统的一种可选方法。ACLs 将程序的实际操作与允许的操作对照,来实现访问控制。<br />
<br />
== 内核加固 ==<br />
<br />
=== 内核自我保护 / 漏洞防护 ===<br />
<br />
{{pkg|linux-hardened}} 相较于 {{pkg|linux}} 使用了 [https://github.com/anthraxx/linux-hardened 基本内核加固补丁集] 和更多安全相关的编译时配置选项。也可以使用自定义编译选项来把握安全性和性能之间的平衡,而不是使用强调安全性的默认选项。<br />
<br />
如果你用了内核代码树以外的驱动,比如 [[NVIDIA (简体中文)|NVIDIA]],可能会需要切换到它的 [[Dynamic Kernel Module Support (简体中文)|DKMS]] 包。<br />
<br />
==== 用户空间 ASLR 比较 ====<br />
<br />
{{pkg|linux-hardened}} 包为用户空间进程提供了改进的 ASLR(Address Space Layout Randomization,地址空间布局随机化)实现。{{pkg|paxtest}} 命令可用于获取所提供熵的估计值:<br />
<br />
===== 64 位进程 =====<br />
<br />
{{hc|linux-hardened|<br />
Anonymous mapping randomization test : 32 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 26 quality bits (guessed)<br />
Heap randomization test (PIE) : 40 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 32 quality bits (guessed)<br />
Shared library randomization test : 32 quality bits (guessed)<br />
VDSO randomization test : 32 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 40 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 40 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 44 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 44 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 32 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 34 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 32 bits (guessed)<br />
Randomization under memory exhaustion @0 : 32 bits (guessed)<br />
}}<br />
<br />
{{hc|linux|<br />
Anonymous mapping randomization test : 28 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 13 quality bits (guessed)<br />
Heap randomization test (PIE) : 28 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 28 quality bits (guessed)<br />
Shared library randomization test : 28 quality bits (guessed)<br />
VDSO randomization test : 20 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 30 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 30 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 22 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 22 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 28 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 28 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 28 bits (guessed)<br />
Randomization under memory exhaustion @0 : 28 bits (guessed)<br />
}}<br />
<br />
===== 32 位进程(运行在 x86_64 内核上) =====<br />
<br />
{{hc|linux-hardened|<br />
Anonymous mapping randomization test : 16 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 22 quality bits (guessed)<br />
Heap randomization test (PIE) : 27 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 18 quality bits (guessed)<br />
Shared library randomization test : 16 quality bits (guessed)<br />
VDSO randomization test : 16 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 24 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 24 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 28 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 28 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 18 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 16 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 18 bits (guessed)<br />
Randomization under memory exhaustion @0 : 18 bits (guessed)<br />
}}<br />
<br />
{{hc|linux|<br />
Anonymous mapping randomization test : 8 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 13 quality bits (guessed)<br />
Heap randomization test (PIE) : 13 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 8 quality bits (guessed)<br />
Shared library randomization test : 8 quality bits (guessed)<br />
VDSO randomization test : 8 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 19 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 19 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 11 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 11 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 8 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 13 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: No randomization<br />
Randomization under memory exhaustion @0 : No randomization<br />
}}<br />
<br />
=== 限制访问内核日志 ===<br />
<br />
{{注意|这个功能在 {{pkg|linux-hardened}} 中是默认打开的。}}<br />
<br />
内核日志包含了那些试图利用内核漏洞(如敏感内存地址)的攻击者的有用信息。{{ic|kernel.dmesg_restrict}} 标记可以禁止不带 {{ic|CAP_SYS_ADMIN}} 能力的进程访问内核日志(默认只有 root 运行的进程带有该能力)。<br />
<br />
{{hc|/etc/sysctl.d/50-dmesg-restrict.conf|2=<br />
kernel.dmesg_restrict = 1<br />
}}<br />
<br />
=== 限制访问 proc 文件系统中的内核指针 ===<br />
<br />
{{注意|{{pkg|linux-hardened}} 默认设置是 {{ic|1=kptr_restrict=2}} 而不是 {{ic|0}}。}}<br />
<br />
将 {{ic|kernel.kptr_restrict}} 设置为 1 将针对没有 {{ic|CAP_SYSLOG}} 的普通用户隐藏 {{ic|/proc/kallsyms}} 中的内核符号地址,这使得利用内核漏洞动态解析地址/符号变得更加困难。这对预编译好的 Arch Linux 内核没有多大帮助,因为攻击者可以直接下载到内核包并从那里手动获取符号,但如果你正在编译自己的内核,这可以帮助减轻本地根攻击。这样做以后会影响非 root 用户运行部分 {{Pkg|perf}} 命令(虽然很多 {{Pkg|perf}} 功能本身就需要 root 权限)。更多信息请参见 {{Bug|34323}}。<br />
<br />
将 {{ic|kernel.kptr_restrict}} 设置为 2 将隐藏 {{ic|/proc/kallsyms}} 中的内核符号地址,而忽略用户的权限。<br />
<br />
{{hc|/etc/sysctl.d/50-kptr-restrict.conf|2=<br />
kernel.kptr_restrict = 1<br />
}}<br />
<br />
=== 禁用 BPF 即时编译 ===<br />
<br />
Linux 内核有一个功能,就是将 BPF/Seccomp 规则集编译为原生代码来优化性能。{{ic|net.core.bpf_jit_enable}} 标志位应设置为 {{ic|0}} 以获得最大安全性。<br />
<br />
BPF/Seccomp 编译在特定领域中很有用,比如各类动态服务(类似 Mesos 和 Kubernetes 这样的集群管理平台),它通常不适用于桌面用户或静态服务。JIT 编译器为攻击者提供了进行堆喷射攻击 (Heap spraying attack) 的可能性。在这种攻击中,他们用恶意代码填充内核堆,然后利用另一个漏洞执行此代码,比如解除引用一个不正确的函数指针。2018 年早先公布的 [[Wikipedia:Spectre (security vulnerability)|幽灵]] 漏洞,是其最为突出的一次利用过程。<br />
<br />
<br />
=== ptrace 的可调用范围 ===<br />
<br />
Arch 默认启用了 Yama LSM,提供了 {{ic|kernel.yama.ptrace_scope}} 标志位作为开关。默认情况下这个开关是打开的,它可以使得没有 {{ic|CAP_SYS_PTRACE}} 能力的进程无法对其作用域之外的其他进程执行 {{ic|ptrace}} 调用。虽然许多调试工具需要 {{ic|ptrace}} 来实现某些功能,但这一修改显著提高了安全性。如果没有此功能,且不使用命名空间等额外隔离层的情况下,同一用户运行的进程之间基本没有隔离。调试器可以附加到现有进程的能力证明了这个弱点确实存在。<br />
<br />
==== 示例:由于上述原因功能受限的程序 ====<br />
<br />
{{注意|你仍然可以以 root 身份执行这些命令(例如允许某些用户使用 [[sudo]],且无论是否需要密码)。}}<br />
<br />
* {{ic|gdb -p $PID}}<br />
* {{ic|strace -p $PID}}<br />
* {{ic|perf trace -p $PID}}<br />
* {{ic|reptyr $PID}}<br />
<br />
=== 隐藏进程 ===<br />
<br />
{{警告|<br />
* 这可能会导致某些应用程序出现问题,例如在沙盒和 [[Xorg]] 中运行的应用程序(请参阅解决方法)。<br />
* 当所使用的 {{Pkg|systemd}} 版本大于 237.64-1 时,这可能会导致 [[D-Bus]]、[[PulseAudio]] 和 [[bluetooth]] 出现问题。}}<br />
<br />
其他用户的进程通常可以在 {{ic|/proc}} 访问到,而内核有能力向非特权用户隐藏这些进程,按照 [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt#n1919 此处] 记录的方法以 {{ic|1=hidepid=}} 和 {{ic|1=gid=}} 选项挂载 {{ic|proc}} 文件系统即可。<br />
<br />
这使得入侵者收集正在运行的进程信息变得异常艰难,同样艰难的还包括判断是否存在特权运行的守护进程、其他用户是否正在运行敏感程序,甚至无法捕捉到其他用户运行的任何程序,更无法捕捉到特定的程序是否正在运行(假设该程序不会因为其自身行为暴露自己),并且作为额外的优势,那些通过外部参数传递敏感信息的、写得不那么好的程序现在可以防范本地窃听了。<br />
<br />
由 {{Pkg|filesystem}} 软件包提供的 {{ic|proc}} [[Users_and_groups#System_groups|用户组]] 相当于一个白名单,包含了有权访问其他用户进程信息的用户。如果用户或服务需要访问除自身以外的 {{ic|/proc/<pid>}} 目录,请 [[Users_and_groups#Group_management|将他们加入该用户组]]。<br />
<br />
例如,把除了 {{ic|proc}} 组中用户之外的其他用户的进程信息都隐藏起来:<br />
<br />
{{hc|/etc/fstab|2=<br />
proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=proc 0 0<br />
}}<br />
<br />
要使用户会话正常工作,需要为 ''systemd-logind'' 添加例外:<br />
<br />
{{hc|/etc/systemd/system/systemd-logind.service.d/hidepid.conf|2=<br />
[Service]<br />
SupplementaryGroups=proc<br />
}}<br />
<br />
== 沙盒程序 ==<br />
<br />
另请参阅 [[Wikipedia:Sandbox (computer security)]]。<br />
<br />
{{注意|用户命名空间配置项 {{ic|CONFIG_USER_NS}} 当前在 {{Pkg|linux}}(v4.14.5或更高版本)、{{Pkg|linux-lts}}(v4.14.15或更高版本)和 {{Pkg|linux-hardened}} 中启用。关闭它可能会导致程序无法开启某些沙盒功能。由于会增加本地提权的可能性,非特权用法默认是禁用的,启用它需要将 {{ic|kernel.unprivileged_userns_clone}} [[sysctl]] 设置为 {{ic|1}}。}}<br />
<br />
=== Firejail ===<br />
<br />
[[Firejail]] 是一个易于使用的、简单的工具,用于沙盒化程序和服务器。建议将 Firejail 也用于浏览器以及其他网络应用程序,就像对待正在运行的服务器程序一样。<br />
<br />
=== bubblewrap ===<br />
<br />
[[bubblewrap]] 是一个由 [[Wikipedia:Flatpak|Flatpak]] 开发的基于 setuid 的沙盒程序,其资源占用比 Firejail 更小。虽然它缺少某些功能,例如文件路径白名单,但 bubblewrap 确实提供了 bind mounts 的功能,能够创建 user/IPC/PID/network/cgroup 命名空间,并且可以支持简单和 [https://github.com/projectatomic/bubblewrap/blob/master/demos/bubblewrap-shell.sh 复杂的沙盒]。<br />
<br />
=== chroots ===<br />
<br />
手动构造 [[Chroot (简体中文)|chroot]] jail 也是可以的。<br />
<br />
=== Linux containers ===<br />
<br />
在不使用 KVM 和 VirtualBox 又需要更大程度隔离的情况下,[[Linux Containers]](Linux 软件容器)是一个不错的选择。LXC 使用自己的虚拟硬件,在现有内核之上的 pseudo-chroot 内运行。<br />
<br />
=== 其他虚拟化技术 ===<br />
<br />
使用类似 [[VirtualBox (简体中文)|VirtualBox]]、[[KVM (简体中文)|KVM]]、[[Xen (简体中文)|Xen]] 或 [https://www.qubes-os.org/ Qubes OS](基于 Xen)的完全虚拟化技术,可以在运行有风险的应用程序或浏览危险网站时提高隔离性和安全性。<br />
<br />
== 网络与防火墙 ==<br />
<br />
=== 防火墙 ===<br />
<br />
虽然源里面的 Arch 内核能够启用 [[Wikipedia:Netfilter|Netfilter]] 的 [[iptables]] 和 [[nftables]],但它们默认是关闭的。因此强烈建议配置防火墙来保护系统上运行的服务。许多资料(包括 ArchWiki)没有明确说明哪些服务值得保护,因此启用防火墙是一个很好的预防措施。<br />
<br />
* 参阅 [[Iptables (简体中文)|iptables]] 和 [[nftables]] 来获取一般信息。<br />
* 参阅 [[Simple stateful firewall (简体中文)|Simple stateful firewall]] 来获取配置 iptables 防火墙的指南。<br />
* 参阅 [[:Category:Firewalls]] 来获取设置 netfilter 的其他方法。<br />
* 参阅 [[Ipset (简体中文)|Ipset]] 以设置 IP 地址黑名单,内容可参考来自 Bluetack 的名单。<br />
<br />
=== 内核参数 ===<br />
<br />
作用于网络的内核参数可以使用 [[Sysctl]] 来设置。要查询具体方法,请参阅 [[Sysctl#TCP/IP stack hardening]]。<br />
<br />
=== SSH ===<br />
<br />
为了减轻 [[Wikipedia:Brute-force attack|暴力攻击]],建议强制使用基于密钥的身份验证。对于 OpenSSH,请参阅 [[OpenSSH#Force public key authentication]]。另外,[[Fail2ban]] 或 [[Sshguard]] 通过监控日志并写入 [[Iptables|iptables 规则]] 提供了较少形式的保护,但这样做可能会使服务器拒绝服务,因为攻击者可以伪装成管理员的地址并发送欺骗性的数据包。<br />
<br />
你可以用双因素身份验证来进一步强化身份验证。[[Google Authenticator]](Google 身份验证器)使用一次性密码 (OTP) 提供两步验证过程。<br />
<br />
拒绝 root 登录也是一种很好的做法,既可以跟踪入侵,也可以在 root 访问之前添加额外的安全层。对于 OpenSSH,请参阅 [[OpenSSH#Deny]]。<br />
<br />
=== DNS ===<br />
<br />
{{Accuracy|由于 [[HSTS]] 技术,浏览器可能可以识别出 DNS 欺骗。}}<br />
<br />
默认情况下,多数系统上的 [[DNS]] 查询请求的发送和接收是不加密的,并且不验证数据是否来自规范的服务器,这可能导致 [[Wikipedia:Man-in-the-middle_attack|中间人攻击]],攻击者拦截用户的 DNS 查询并修改响应数据为 [[Wikipedia:Phishing|钓鱼]] 网站的 IP 地址,导致钓鱼网站收集用户的宝贵信息。用户和浏览器/其他软件都不会知道发生了什么,因为 DNS 协议始终将查询结果视为合法的。<br />
<br />
[[DNSSEC]] 是一套标准,要求 DNS 服务器向客户端出示 DNS 数据的原始验证证明、曾经的验证失败记录和数据完整性。然而这一标准尚未广泛使用。启用 DNSSEC 后,攻击者无法修改您的 DNS 查询请求和返回的结果,但仍可以读取它们。<br />
<br />
[[DNSCrypt (简体中文)|DNSCrypt]] 以及后来的替代协议 ''DNS over TLS'' 和 ''DNS over HTTPS'',使用加密技术来保护与 DNS 服务器的通信,系统层面上通常只采用其中一种协议。有关实现这些协议的软件,请参阅 [[Domain name resolution#DNS servers]]。<br />
<br />
如果你有一个域名,请设置 [[Sender Policy Framework]](发件人策略框架)来抵御电子邮件欺骗。<br />
<br />
=== 代理 ===<br />
<br />
代理通常用作应用程序和网络之间的附加层,拦截不受信任的来源的数据。从攻击面上看,以较低权限运行的小代理的攻击面明显小于使用最终用户权限运行的复杂应用程序。<br />
<br />
例如,DNS 解析器是在 {{Pkg|glibc}} 中实现的,它与应用程序链接(可能以root身份运行),因此 DNS 解析器中的 bug 可能导致本机执行远程代码。而这可以安装充当代理的 DNS 缓存服务器(例如 [[dnsmasq]])来避免。[https://googleonlinesecurity.blogspot.it/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html]<br />
<br />
=== 管理 SSL 证书 ===<br />
<br />
{{Merge|Transport Layer Security|有一篇专门介绍传输层安全协议的文章。}}<br />
<br />
请参阅 [[OpenSSL (简体中文)|OpenSSL]] 和 [[Network Security Services]](NSS,网络安全服务)来管理各自的服务器端 SSL 证书。值得注意的是,与此相关的 [[Let’s Encrypt]] 项目也支持这些协议。<br />
<br />
默认的 Internet SSL 证书信任链由 {{Pkg|ca-certificates}} 包及其依赖项提供。请注意,Arch 依赖于信任源(例如 {{Pkg|ca-certificates-mozilla}})来提供受系统信任的证书。<br />
<br />
有时你可能需要暂时更改默认设置。例如,当你读到这一 [https://www.theregister.co.uk/2016/05/27/blue_coat_ca_certs/ 新闻] 并希望手动解除证书信任,而不是等到信任源提供商这样做,在 Arch 的体系里非常简单:<br />
<br />
# 以 .crt 格式获取相应的证书(示例:[https://crt.sh/?id=19538258 查看], [https://crt.sh/?d=19538258 下载];如果是现有的受信任的根证书颁发机构,你也可以在系统路径中找到它) <br />
# 将其复制到 {{ic|/etc/ca-certificates/trust-source/blacklist/}} <br />
# 以 root 身份运行 ''update-ca-trust''。<br />
<br />
要检查黑名单是否按预期那样工作,请重新打开浏览器并通过其 GUI 执行此操作,现在浏览器应显示其为不受信任。<br />
<br />
== 软件包验证 ==<br />
<br />
如果没有正确地对包进行签名,包管理器就有可能 [https://www.cs.arizona.edu/stork/packagemanagersecurity/attacks-on-package-managers.html#overview 受到攻击],甚至可能会影响原本具有 [https://www.cs.arizona.edu/stork/packagemanagersecurity/faq.html 签名机制] 的包管理器。Arch 默认采用软件包签名机制,并依赖来自 5 个可信主密钥的信任网络。详情请参阅 [[pacman/Package signing (简体中文)]]。<br />
<br />
== 订阅漏洞告警 ==<br />
<br />
订阅国家漏洞数据库 (National Vulnerability Database) 提供的常见漏洞和披露 (Common Vulnerabilities and Exposure, CVE) 安全警报更新,相关内容可以在 [https://nvd.nist.gov/download.cfm NVD 下载页] 上找到。[https://security.archlinux.org/ Arch Linux Security Tracker] 是一个特别有用的资源,它结合了 Arch Linux 安全通报 (ASA),Arch Linux 漏洞组 (AVG) 以及 CVE 数据集,且以表格形式呈现。另请参阅 [[Arch Security Team]](Arch 安全团队)。<br />
<br />
{{警告|不要试图进行 [[System maintenance (简体中文)#不支持部分升级|部分升级]],因为 Arch Linux 不支持部分升级且可能导致系统不稳定,要升级组件时应升级整个系统。另外,系统更新不及时可能会使以后的更新过程更加复杂。}}<br />
<br />
== 物理安全 ==<br />
<br />
理论上如果有足够的时间和计算资源,对计算机的物理访问都将会变成 root 权限的访问。但通过设置足够的障碍可以获得切实的安全保障。<br />
<br />
攻击者只需连接恶意的 IEEE 1394(火线接口),Thunderbolt 或 PCI Express 设备即可在下次启动时完全控制计算机,因为它们可以完全访问内存。[https://www.breaknenter.org/projects/inception/] 你无法阻止类似这样的操作,包括修改硬件本身的操作(比如将恶意固件刷到设备上)。但是,绝大多数攻击者都没有这样的知识和信心。<br />
<br />
[[#磁盘加密]] 将在计算机被盗时保护数据,但经验丰富的攻击者可以给计算机安装恶意固件,在用户下次登录时获取加密的数据。<br />
<br />
=== 锁定 BIOS ===<br />
<br />
向 BIOS 添加密码可防止其他人启动到可移动设备,否则这和其他人对计算机具有 root 访问权限基本相同。你应该确保你的磁盘在引导顺序中处于第一位,并且可以的话禁用其他引导设备。<br />
<br />
=== 引导加载程序 (Bootloader) ===<br />
<br />
保护引导加载程序非常重要。因为有一个神奇的内核参数叫做 {{ic|1=init=/bin/sh}},它会使得任何用户的登录限制完全无用。<br />
<br />
==== Syslinux ====<br />
<br />
Syslinux 支持 [[Syslinux#Security|用密码保护引导加载程序]]。它允许为每个菜单项设置密码或为整个引导程序设置密码。<br />
<br />
==== GRUB ====<br />
<br />
[[GRUB (简体中文)|GRUB]] 也可以设置引导密码。详情请参阅 [[GRUB/Tips and tricks#Password protection of GRUB menu]]。它还支持 [[GRUB#Encrypted /boot|加密的 /boot]],这样只会使引导程序的部分代码保持未加密状态。GRUB 的配置、[[Kernels (简体中文)|内核]] 和 [[Arch boot process (简体中文)#initramfs|initramfs]] 都是加密的。<br />
<br />
=== 启动分区置于可移动闪存上 ===<br />
<br />
一个较为流行的做法是将启动分区放在可移动闪存上,在没有它的情况下系统便无法启动。这个想法的支持者经常使用 [[#磁盘加密|全盘加密]],有些还用到了放在启动分区上的 [[Dm-crypt/Specialties#Encrypted_system_using_a_detached_LUKS_header|分离加密头]]。<br />
<br />
=== 自动注销 ===<br />
<br />
如果你用的是 [[Bash (简体中文)|Bash]] 或 [[Zsh (简体中文)|Zsh]],则可以设置 {{ic|TMOUT}} 的值,使 shell 在超时后自动注销。<br />
<br />
例如,下面的脚本内容将使用户自动从虚拟控制台(非 X11 中的终端模拟器)注销:<br />
<br />
{{hc|/etc/profile.d/shell-timeout.sh|<nowiki><br />
TMOUT="$(( 60*10 ))";<br />
[ -z "$DISPLAY" ] && export TMOUT;<br />
case $( /usr/bin/tty ) in<br />
/dev/tty[0-9]*) export TMOUT;;<br />
esac<br />
</nowiki>}}<br />
<br />
如果确实想要所有 Bash/Zsh 提示符(包括 X 中的)都有超时,请使用:<br />
<br />
$ export TMOUT="$(( 60*10 ))";<br />
<br />
请注意,shell 中运行的某些命令(例如:SSH 会话或没有 {{ic|TMOUT}} 支持的其他 shell)将使上述设置失效。但是如果你主要使用 VC 以 root 身份重新启动僵死的 GDM/Xorg,那么这非常有用。<br />
<br />
=== 防范恶意 USB 设备 ===<br />
<br />
请安装 [[USBGuard]],这是一个软件框架,通过基于设备属性的基本白名单和黑名单功能,帮助保护计算机免受恶意 USB 设备(例如 [https://srlabs.de/badusb BadUSB]、[https://github.com/samyk/poisontap PoisonTap] 或 [https://lanturtle.com/ LanTurtle])的侵害。<br />
<br />
== 重新构建软件包 ==<br />
<br />
软件包可以去除不需要的功能并重新构建,这样可以缩小受攻击范围。例如,{{Pkg|bzip2}} 可以在没有 {{ic|bzip2recover}} 的情况下重新构建,以试图规避 [https://security.archlinux.org/CVE-2016-3189 CVE-2016-3189] 漏洞。强化安全的自定义编译参数也可以手动或通过包装器在编译时加入。<br />
<br />
== 参考资料 ==<br />
<br />
* [https://security.archlinux.org/ Arch Linux Security Tracker]<br />
* [https://wiki.centos.org/HowTos/OS_Protection CentOS Wiki: OS Protection]<br />
* [https://www.ibm.com/developerworks/linux/tutorials/l-harden-desktop/index.html Hardening the Linux desktop]<br />
* [https://www.ibm.com/developerworks/linux/tutorials/l-harden-server/index.html Hardening the Linux server]<br />
* [https://github.com/lfit/itpol/blob/master/linux-workstation-security.md Linux Foundation: Linux workstation security checklist]<br />
* [https://www.privacytools.io/ privacytools.io Privacy Resources]<br />
* [https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/ Red Hat Enterprise Linux 7 Security Guide]<br />
* [https://www.debian.org/doc/manuals/securing-debian-howto/securing-debian-howto.en.pdf Securing Debian Manual (PDF)]<br />
* [https://web.archive.org/web/20140220055801/http://crunchbang.org:80/forums/viewtopic.php?id=24722 The paranoid #! Security Guide]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Security&diff=565780
Security
2019-02-04T01:31:42Z
<p>Arisaka: Add link of zh-hans.</p>
<hr />
<div>[[Category:Security]]<br />
[[Category:File systems]]<br />
[[Category:Networking]]<br />
[[fa:امنیت]]<br />
[[ja:セキュリティ]]<br />
[[ru:Security]]<br />
[[zh-hans:Security]]<br />
{{Related articles start}}<br />
{{Related|Arch Security Team}}<br />
{{Related|General recommendations}}<br />
{{Related|PAM}}<br />
{{Related|Capabilities}}<br />
{{Related|List of Applications/Security}}<br />
{{Related articles end}}<br />
This article contains recommendations and best practices for [[Wikipedia:Hardening (computing)|hardening]] an Arch Linux system.<br />
<br />
== Concepts ==<br />
<br />
* It ''is'' possible to tighten the security so much as to make your system unusable. The trick is to secure it without overdoing it.<br />
* There are many other things that can be done to heighten the security, but the biggest threat is, and will always be, the user. When you think security, you have to think layers. When one layer is breached, another should stop the attack. But you can never make the system 100% secure unless you unplug the machine from all networks, lock it in a safe and never use it.<br />
* Be a little paranoid. It helps. And be suspicious. If anything sounds too good to be true, it probably is!<br />
* The [[Wikipedia:Principle of least privilege|principle of least privilege]]: each part of a system should only be able to access what is required to use it, and nothing more.<br />
<br />
== Passwords ==<br />
<br />
Passwords are key to a secure Linux system. They secure your [[Users and groups|user accounts]], [[Disk encryption|encrypted filesystems]], and [[SSH keys|SSH]]/[[GPG]] keys. They are the main way a computer chooses to trust the person using it, so a big part of security is just about picking secure passwords and protecting them.<br />
<br />
=== Choosing secure passwords ===<br />
<br />
When relying on a passphrase, it must be complex enough to not be easily guessed from e.g. personal information, or [[Wikipedia:Password cracking|cracked]] using methods like brute-force attacks. The tenets of strong passphrases are based on ''length'' and ''randomness''. In cryptography the quality of a passphrase is referred to as its [[Wikipedia:Entropic security|entropic security]]. <br />
<br />
Insecure passwords include those containing:<br />
<br />
* Personally identifiable information (e.g., your dog's name, date of birth, area code, favorite video game)<br />
* Simple character substitutions on words (e.g., {{ic|k1araj0hns0n}})<br />
* Root "words" or common strings followed or preceded by added numbers, symbols, or characters (e.g., {{ic|DG091101%}})<br />
* Common phrases or short phrases of grammatically related words (e.g. {{ic|all of the lights}}), and even with character substitution.<br />
<br />
The right choice for a password is something long (8-20 characters, depending on importance) and seemingly completely random.<br />
A good technique for building secure, seemingly random passwords is to base them on characters from every word in a sentence.<br />
Take for instance “the girl is walking down the rainy street” could be translated to {{ic|t6!WdtR5}} or, less simply, {{ic|t&6!RrlW@dtR,57}}.<br />
This approach could make it easier to remember a password, but note that the various letters have very different probabilities of being found at the start of words ([[Wikipedia:Letter frequency#Relative frequencies of the first letters of a word in the English language|Wikipedia:Letter frequency]]). Also consider the [http://world.std.com/~reinhold/diceware.html Diceware Passphrase] method, using a sufficient number of words.<br />
<br />
A better approach is to generate pseudo-random passwords with tools like {{Pkg|pwgen}} or {{AUR|apg}}: for memorizing them, one technique (for ones typed often) is to generate a long password and memorize a minimally secure number of characters, temporarily writing down the full generated string. Over time, increase the number of characters typed - until the password is ingrained in muscle memory and need not be remembered. This technique is more difficult, but can provide confidence that a password will not turn up in wordlists or "intelligent" brute force attacks that combine words and substitute characters.<br />
<br />
It is also very effective to combine these two techniques by saving long, complex random passwords with a [[password manager]], which will be in turn accessed with a mnemonic password that will have to be used only for that purpose, especially avoiding to ever transmit it over any kind of network. This method of course limits the use of the stored passwords to the terminals where the database is available for reading (which on the other hand could be seen as an added security feature).<br />
<br />
See Bruce Schneier's article [https://www.schneier.com/blog/archives/2014/03/choosing_secure_1.html Choosing Secure Passwords], [https://www.iusmentis.com/security/passphrasefaq/ The passphrase FAQ] or [[Wikipedia:Password strength]] for some additional background.<br />
<br />
=== Maintaining passwords ===<br />
<br />
Once you pick a strong password, be sure to keep it safe. Watch out for [[Wikipedia:Keylogger|keyloggers]] (software and hardware), [[Wikipedia:Social engineering (security)|social engineering]], [[Wikipedia:Shoulder surfing (computer security)|shoulder surfing]], and avoid reusing passwords so insecure servers cannot leak more information than necessary. [[List of applications/Security#Password managers|Password managers]] can help manage large numbers of complex passwords: if you are copy-pasting the stored passwords from the manager to the applications that need them, make sure to clear the copy buffer every time, and ensure they are not saved in any kind of log (e.g. do not paste them in plain terminal commands, which would store them in files like {{ic|.bash_history}}).<br />
<br />
As a rule, do not pick insecure passwords just because secure ones are harder to remember. Passwords are a balancing act. It is better to have an encrypted database of secure passwords, guarded behind a key and one strong master password, than it is to have many similar weak passwords. Writing passwords down is perhaps equally effective[https://www.schneier.com/blog/archives/2005/06/write_down_your.html], avoiding potential vulnerabilities in software solutions while requiring physical security.<br />
<br />
Another aspect of the strength of the passphrase is that it must not be easily recoverable from other places.<br />
If you use the same passphrase for disk encryption as you use for your login password (useful e.g. to auto-mount the encrypted partition or folder on login), make sure that {{ic|/etc/shadow}} either also ends up on an encrypted partition, or uses a strong hash algorithm (i.e. sha512/bcrypt, not md5) for the stored password hash (see [[SHA password hashes]] for more info).<br />
<br />
If you are backing up your password database, make sure that each copy is not stored behind any other passphrase which in turn is stored in it, e.g. an encrypted drive or an authenticated remote storage service, or you will not be able to access it in case of need; a useful trick is to protect the drives or accounts where the database is backed up using a simple cryptographic hash of the master password. Maintain a list of all the backup locations: if one day you fear that the master passphrase has been compromised you will have to change it immediately on all the database backups and the locations protected with keys derived from the master password. Version-controlling the database in a secure way can be very complicated: if you choose to do it, you must have a way to update the master password of all the database versions. It may not always be immediately clear when the master password is leaked: to reduce the risk of somebody else discovering your password before you realize that it leaked, you may choose to change it on a periodical basis. If you fear that you have lost control over a copy of the database, you will need to change all the passwords contained in it within the time that it may take to brute-force the master password, according to its entropy.<br />
<br />
=== Password hashes ===<br />
<br />
{{Expansion|Mention [[Wikipedia:Key derivation function|key derivation functions]], in particular PBKDF2, bcrypt and scrypt, how to use them, advantages and disadvantages, especially regarding custom-hardware-based brute-force attacks.|section=Removal of incorrect warning}}<br />
<br />
By default, Arch stores the hashed user passwords in the root-only-readable {{ic|/etc/shadow}} file, separated from the other user parameters stored in the world-readable {{ic|/etc/passwd}} file, see [[Users and groups#User database]]. See also [[#Restricting root]].<br />
<br />
Passwords are set with the '''passwd''' command, which [[Wikipedia:Key stretching|stretches]] them with the [[Wikipedia:Crypt (C)|crypt]] function and then saves them in {{ic|/etc/shadow}}. See also [[SHA password hashes]]. The passwords are also [[Wikipedia:Salt (cryptography)|salted]] in order to defend them against [[Wikipedia:Rainbow table|rainbow table]] attacks.<br />
<br />
See also [http://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils How are passwords stored in Linux (Understanding hashing with shadow utils)].<br />
<br />
=== Enforcing strong passwords using pam_cracklib ===<br />
<br />
''pam_cracklib'' provides protection against [[Wikipedia:Dictionary attack|Dictionary attacks]] and helps configure a password policy that can be enforced throughout the system.<br />
<br />
{{Warning|The ''root'' account is not affected by this policy.}}<br />
{{Note|You can use the ''root'' account to set a password for a user that bypasses the desired/configured policy. This is useful when setting temporary passwords.}}<br />
<br />
If for example you want to enforce this policy:<br />
<br />
* prompt 2 times for password in case of an error<br />
* 10 characters minimum length (minlen option)<br />
* at least 6 characters should be different from old password when entering a new one (difok option)<br />
* at least 1 digit (dcredit option)<br />
* at least 1 uppercase (ucredit option)<br />
* at least 1 other character (ocredit option)<br />
* at least 1 lowercase (lcredit option)<br />
<br />
Edit the {{ic|/etc/pam.d/passwd}} file to read as:<br />
<br />
{{bc|1=<br />
#%PAM-1.0<br />
password required pam_cracklib.so retry=2 minlen=10 difok=6 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1<br />
password required pam_unix.so use_authtok sha512 shadow<br />
}}<br />
<br />
The {{ic|password required pam_unix.so use_authtok}} instructs the ''pam_unix'' module to not prompt for a password but rather to use the one provided by ''pam_cracklib''.<br />
<br />
You can refer to the {{man|8|pam_cracklib}} and {{man|8|pam_unix}} man pages for more information.<br />
<br />
== Storage ==<br />
<br />
=== Disk encryption ===<br />
<br />
[[Disk encryption]], preferably full disk encryption with a [[#Passwords|strong passphrase]], is the only way to guard data against physical recovery. This provides complete security when the computer is turned off or the disks in question are unmounted.<br />
<br />
Once the computer is powered on and the drive is mounted, however, its data becomes just as vulnerable as an unencrypted drive. It is therefore best practice to unmount data partitions as soon as they are no longer needed.<br />
<br />
Certain programs, like [[dm-crypt]], allow the user to encrypt a loop file as a virtual volume. This is a reasonable alternative to full disk encryption when only certain parts of the system need be secure.<br />
<br />
=== File systems ===<br />
<br />
The kernel now prevents security issues related to hardlinks and symlinks if the {{ic|fs.protected_hardlinks}} and {{ic|fs.protected_symlinks}} sysctl switches are enabled, so there is no longer a major security benefit from separating out world-writable directories.<br />
<br />
File systems containing world-writable directories can still be kept separate as a coarse way of limiting the damage from disk space exhaustion. However, filling {{ic|/var}} or {{ic|/tmp}} is enough to take down services. More flexible mechanisms for dealing with this concern exist (like [[Disk quota|quotas]]), and some [[file systems]] include related features themselves (Btrfs has quotas on subvolumes).<br />
<br />
==== Mount options ====<br />
<br />
Following the principle of least privilege, file systems should be mounted with the most restrictive mount options possible (without losing functionality).<br />
<br />
Relevant mount options are:<br />
<br />
* {{ic|nodev}}: Do not interpret character or block special devices on the file system.<br />
* {{ic|nosuid}}: Do not allow set-user-identifier or set-group-identifier bits to take effect.<br />
* {{ic|noexec}}: Do not allow direct execution of any binaries on the mounted file system.<br />
** Setting {{ic|noexec}} on {{ic|/home}} disallows executable scripts and breaks [[Wine]]* and [[Steam]].<br />
** Some packages (building {{Pkg|nvidia-dkms}} for example) may require {{ic|exec}} on {{ic|/var}}.<br />
<br />
{{Note|Wine does not need the {{ic|exec}} flag for opening Windows executables. It is only needed when Wine itself is installed in {{ic|/home}}.}}<br />
<br />
File systems used for data should always be mounted with {{ic|nodev}}, {{ic|nosuid}} and {{ic|noexec}}.<br />
<br />
Potential file system mounts to consider:<br />
<br />
* {{ic|/var}}<br />
* {{ic|/home}}<br />
* {{ic|/dev/shm}}<br />
* {{ic|/tmp}}<br />
* {{ic|/boot}}<br />
<br />
=== File access permissions ===<br />
<br />
The default [[file permissions]] allow read access to almost everything and changing the permissions can hide valuable information from an attacker who gains access to a non-root account such as the {{ic|http}} or {{ic|nobody}} users.<br />
<br />
For example:<br />
<br />
# chmod 700 /boot /etc/{iptables,arptables}<br />
<br />
The default [[Umask]] {{ic|0022}} can be changed to improve security for newly created files. The [https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf NSA RHEL5 Security Guide] suggests a umask of {{ic|0077}} for maximum security, which makes new files not readable by users other than the owner. To change this, see [[Umask#Set the mask value]].<br />
<br />
== User setup ==<br />
<br />
After installation make a normal user for daily use. Do not use the root user for daily use.<br />
<br />
=== Enforce a delay after a failed login attempt ===<br />
<br />
Add the following line to {{ic|/etc/pam.d/system-login}} to add a delay of at least 4 seconds between failed login attempts:<br />
<br />
{{hc|/etc/pam.d/system-login|<br />
2=auth optional pam_faildelay.so delay=4000000<br />
}}<br />
<br />
{{ic|4000000}} is the time in microseconds to delay.<br />
<br />
=== Lockout user after three failed login attempts ===<br />
<br />
To further heighten the security it is possible to lockout a user after a specified number of failed login attempts. The user account can either be locked until the root user unlocks it, or automatically be unlocked after a set time.<br />
<br />
To lockout a user for ten minutes after three failed login attempts you have to modify {{ic|/etc/pam.d/system-login}} to read as:<br />
<br />
{{hc|/etc/pam.d/system-login|<br />
2=#%PAM-1.0<br />
<br />
auth required pam_tally2.so deny=3 unlock_time=600 onerr=succeed<br />
account required pam_tally2.so<br />
}}<br />
<br />
pam_tally is deprecated and superseded by pam_tally2, so you will want to comment out the pam_tally line:<br />
<br />
#auth required pam_tally.so onerr=succeed file=/var/log/faillog<br />
<br />
That is all there is to it. If you feel adventurous, make three failed login attempts. Then you can see for yourself what happens. To unlock a user manually do:<br />
<br />
# pam_tally2 --reset --user ''username''<br />
<br />
{{ic|unlock_time}} is specified in seconds. If you want to permanently lockout a user after 3 failed login attempts remove the {{ic|unlock_time}} part of the line. The user is then unable to login until root unlocks the account.<br />
<br />
=== Limit amount of processes ===<br />
<br />
On systems with many, or untrusted users, it is important to limit the number of processes each can run at once, therefore preventing [[Wikipedia:Fork bomb|fork bombs]] and other denial of service attacks. {{ic|/etc/security/limits.conf}} determines how many processes each user, or group can have open, and is empty (except for useful comments) by default. adding the following lines to this file will limit all users to 100 active processes, unless they use the {{ic|prlimit}} command to explicitly raise their maximum to 200 for that session. These values can be changed according to the appropriate number of processes a user should have running, or the hardware of the box you are administrating. <br />
<br />
* soft nproc 100<br />
* hard nproc 200<br />
<br />
The current number of threads for each user can be found with {{ic|ps --no-headers -Leo user {{!}} sort {{!}} uniq -c}}. This may help with determining appropriate values for the limits.<br />
<br />
=== Run Xorg rootless ===<br />
<br />
[[Xorg]] is commonly [https://security.stackexchange.com/questions/4641/why-are-people-saying-that-the-x-window-system-is-not-secure/4646#4646 considered insecure] because of its architecture and dated design. Thus it is recommended to avoid running it as root.<br />
<br />
See [[Xorg#Rootless Xorg]] for more details how to run it without root privileges.<br />
<br />
== Restricting root ==<br />
<br />
The root user is, by definition, the most powerful user on a system. Because of this, there are a number of ways to keep the power of the root user while limiting its ability to cause harm, or at least to make root user actions more traceable.<br />
<br />
=== Use sudo instead of su ===<br />
<br />
{{Merge|sudo|There's a dedicated article.}}<br />
<br />
Using [[sudo]] for privileged access is preferable to [[su]] for [[Su#Sudo, an alternative|a number of reasons]].<br />
<br />
* It keeps a log of which normal privilege user has run each privileged command.<br />
* The root user password need not be given out to each user who requires root access.<br />
* {{ic|sudo}} prevents users from accidentally running commands as ''root'' that do not need root access, because a full root terminal is not created. This aligns with the [[Wikipedia:Principle of least privilege|principle of least privilege]].<br />
* Individual programs may be enabled per user, instead of offering complete root access just to run one command. For example, to give the user ''alice'' access to a particular program:<br />
<br />
# visudo<br />
<br />
{{hc|/etc/sudoers|<br />
alice ALL &#61; NOPASSWD: /path/to/program<br />
}}<br />
<br />
Or, individual commands can be allowed for all users. To mount Samba shares from a server as a regular user:<br />
<br />
%users ALL=/sbin/mount.cifs,/sbin/umount.cifs<br />
<br />
This allows all users who are members of the group users to run the commands {{ic|/sbin/mount.cifs}} and {{ic|/sbin/umount.cifs}} from any machine (ALL).<br />
<br />
{{Tip|<br />
To use restricted version of {{ic|nano}} instead of {{ic|vi}} with {{ic|visudo}},<br />
<br />
{{hc|/etc/sudoers|<br />
2=Defaults editor=/usr/bin/rnano<br />
}}<br />
<br />
Exporting {{ic|1=# EDITOR=nano visudo}} is regarded as a severe security risk since everything can be used as an {{ic|EDITOR}}.<br />
}}<br />
<br />
==== Editing files using sudo ====<br />
<br />
Running a text editor as root can be a security vulnerability as many editors can run arbitrary shell commands or affect files other than the one you intend to edit. To avoid this, use {{ic|sudoedit filename}} (equivalently, {{ic|sudo -e filename}}) to edit files. This edits a copy of the file using your normal user privileges and then overwrites the original using sudo only after the editor is closed. You can change the editor this uses by setting the {{ic|SUDO_EDITOR}} environment variable:<br />
<br />
$ export SUDO_EDITOR=vim<br />
<br />
Alternatively, use an editor like {{ic|rvim}} which has restricted capabilities in order to be safe to run as root.<br />
<br />
=== Restricting root login ===<br />
<br />
Once [[sudo]] is properly configured, full root access can be heavily restricted or denied without losing much usability. To disable root, but still allowing to use [[sudo]], you can use {{ic|passwd -l root}}.<br />
<br />
==== Allow only certain users ====<br />
<br />
The [[PAM]] {{ic|pam_wheel.so}} lets you allow only users in the group {{ic|wheel}} to login using {{ic|su}}. Edit both {{ic|/etc/pam.d/su}} and {{ic|/etc/pam.d/su-l}}, then uncomment the line:<br />
<br />
{{bc|<nowiki><br />
# Uncomment the following line to require a user to be in the "wheel" group.<br />
auth required pam_wheel.so use_uid<br />
</nowiki>}}<br />
<br />
This means only users who are already able to run privileged commands may login as root.<br />
<br />
==== Denying SSH login ====<br />
<br />
Even if you do not wish to deny root login for local users, it is always good practice to [[OpenSSH#Deny|deny root login via SSH]]. The purpose of this is to add an additional layer of security before a user can completely compromise your system remotely.<br />
<br />
== Mandatory access control ==<br />
<br />
[[Wikipedia:Mandatory Access Control|Mandatory access control]] (MAC) is a type of security policy that differs significantly from the [[Wikipedia:Discretionary Access Control|discretionary access control]] (DAC) used by default in Arch and most Linux distributions. MAC essentially means that every action a program could perform that affects the system in any way is checked against a security ruleset. This ruleset, in contrast to DAC methods, cannot be modified by users. Using virtually any mandatory access control system will significantly improve the security of your computer, although there are differences in how it can be implemented.<br />
<br />
=== Pathname MAC ===<br />
<br />
Pathname-based access control is a simple form of access control that offers permissions based on the path of a given file. The downside to this style of access control is that permissions are not carried with files if they are moved about the system. On the positive side, pathname-based MAC can be implemented on a much wider range of filesystems, unlike labels-based alternatives.<br />
<br />
* [[AppArmor]] is a [[Wikipedia:Canonical|Canonical]]-maintained MAC implementation seen as an "easier" alternative to SELinux.<br />
* [[Tomoyo]] is another simple, easy-to-use system offering mandatory access control. It is designed to be both simple in usage and in implementation, requiring very few dependencies.<br />
<br />
=== Labels MAC ===<br />
<br />
Labels-based access control means the extended attributes of a file are used to govern its security permissions. While this system is arguably more flexible in its security offerings than pathname-based MAC, it only works on filesystems that support these extended attributes.<br />
<br />
* [[SELinux]], based on a [[Wikipedia:NSA|NSA]] project to improve Linux security, implements MAC completely separate from system users and roles. It offers an extremely robust multi-level MAC policy implementation that can easily maintain control of a system that grows and changes past its original configuration.<br />
<br />
=== Access Control Lists ===<br />
<br />
[[Access Control Lists]] (ACLs) are an alternative to attaching rules directly to the filesystem in some way. ACLs implement access control by checking program actions against a list of permitted behavior.<br />
<br />
== Kernel hardening ==<br />
<br />
=== Kernel self-protection / exploit mitigation ===<br />
<br />
The {{pkg|linux-hardened}} package uses a [https://github.com/anthraxx/linux-hardened basic kernel hardening patch set] and more security-focused compile-time configuration options than the {{pkg|linux}} package. A custom build can be made to choose a different compromise between security and performance than the security-leaning defaults.<br />
<br />
If you use an out-of-tree driver such as [[NVIDIA]], you may need to switch to its [[DKMS]] package.<br />
<br />
==== Userspace ASLR comparison ====<br />
<br />
The {{pkg|linux-hardened}} package provides an improved implementation of Address Space Layout Randomization for userspace processes. The {{pkg|paxtest}} command can be used to obtain an estimate of the provided entropy:<br />
<br />
===== 64-bit processes =====<br />
<br />
{{hc|linux-hardened|<br />
Anonymous mapping randomization test : 32 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 26 quality bits (guessed)<br />
Heap randomization test (PIE) : 40 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 32 quality bits (guessed)<br />
Shared library randomization test : 32 quality bits (guessed)<br />
VDSO randomization test : 32 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 40 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 40 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 44 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 44 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 32 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 34 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 32 bits (guessed)<br />
Randomization under memory exhaustion @0 : 32 bits (guessed)<br />
}}<br />
<br />
{{hc|linux|<br />
Anonymous mapping randomization test : 28 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 13 quality bits (guessed)<br />
Heap randomization test (PIE) : 28 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 28 quality bits (guessed)<br />
Shared library randomization test : 28 quality bits (guessed)<br />
VDSO randomization test : 20 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 30 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 30 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 22 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 22 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 28 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 28 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 28 bits (guessed)<br />
Randomization under memory exhaustion @0 : 28 bits (guessed)<br />
}}<br />
<br />
===== 32-bit processes (on an x86_64 kernel) =====<br />
<br />
{{hc|linux-hardened|<br />
Anonymous mapping randomization test : 16 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 22 quality bits (guessed)<br />
Heap randomization test (PIE) : 27 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 18 quality bits (guessed)<br />
Shared library randomization test : 16 quality bits (guessed)<br />
VDSO randomization test : 16 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 24 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 24 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 28 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 28 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 18 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 16 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: 18 bits (guessed)<br />
Randomization under memory exhaustion @0 : 18 bits (guessed)<br />
}}<br />
<br />
{{hc|linux|<br />
Anonymous mapping randomization test : 8 quality bits (guessed)<br />
Heap randomization test (ET_EXEC) : 13 quality bits (guessed)<br />
Heap randomization test (PIE) : 13 quality bits (guessed)<br />
Main executable randomization (ET_EXEC) : No randomization<br />
Main executable randomization (PIE) : 8 quality bits (guessed)<br />
Shared library randomization test : 8 quality bits (guessed)<br />
VDSO randomization test : 8 quality bits (guessed)<br />
Stack randomization test (SEGMEXEC) : 19 quality bits (guessed)<br />
Stack randomization test (PAGEEXEC) : 19 quality bits (guessed)<br />
Arg/env randomization test (SEGMEXEC) : 11 quality bits (guessed)<br />
Arg/env randomization test (PAGEEXEC) : 11 quality bits (guessed)<br />
Offset to library randomisation (ET_EXEC): 8 quality bits (guessed)<br />
Offset to library randomisation (ET_DYN) : 13 quality bits (guessed)<br />
Randomization under memory exhaustion @~0: No randomization<br />
Randomization under memory exhaustion @0 : No randomization<br />
}}<br />
<br />
=== Restricting access to kernel logs ===<br />
<br />
{{Note|This is enabled by default in {{pkg|linux-hardened}}.}}<br />
<br />
The kernel logs contain useful information for an attacker trying to exploit kernel vulnerabilities, such as sensitive memory addresses. The {{ic|kernel.dmesg_restrict}} flag was to forbid access to the logs without the {{ic|CAP_SYS_ADMIN}} capability (which only processes running as root have by default).<br />
<br />
{{hc|/etc/sysctl.d/50-dmesg-restrict.conf|2=<br />
kernel.dmesg_restrict = 1<br />
}}<br />
<br />
=== Restricting access to kernel pointers in the proc filesystem ===<br />
<br />
{{Note|{{pkg|linux-hardened}} sets {{ic|1=kptr_restrict=2}} by default rather than {{ic|0}}.}}<br />
<br />
Setting {{ic|kernel.kptr_restrict}} to 1 will hide kernel symbol addresses in {{ic|/proc/kallsyms}} from regular users without {{ic|CAP_SYSLOG}}, making it more difficult for kernel exploits to resolve addresses/symbols dynamically. This will not help that much on a pre-compiled Arch Linux kernel, since a determined attacker could just download the kernel package and get the symbols manually from there, but if you are compiling your own kernel, this can help mitigating local root exploits. This will break some {{Pkg|perf}} commands when used by non-root users (but many {{Pkg|perf}} features require root access anyway). See {{Bug|34323}} for more information.<br />
<br />
Setting {{ic|kernel.kptr_restrict}} to 2 will hide kernel symbol addresses in {{ic|/proc/kallsyms}} regardless of privileges.<br />
<br />
{{hc|/etc/sysctl.d/50-kptr-restrict.conf|2=<br />
kernel.kptr_restrict = 1<br />
}}<br />
<br />
=== Keep BPF JIT compiler disabled ===<br />
<br />
The Linux kernel includes the ability to compile BPF/Seccomp rule sets to native code as a performance optimization. The {{ic|net.core.bpf_jit_enable}} flag should be set to {{ic|0}} for a maximum level of security.<br />
<br />
BPF/Seccomp compilation can be useful in specific domains, such as dynamic servers (e.g. orchestration platforms like Mesos and Kubernetes). It is not usually useful for desktop users or for static servers. A JIT compiler opens up the possibility for an attacker to perform a heap spraying attack, where they fill the kernel's heap with malicious code. This code can then potentially be executed via another exploit, like an incorrect function pointer dereference. The [[Wikipedia:Spectre (security vulnerability)|Spectre]] attacks, published early 2018, are prominent respective exploits.<br />
<br />
=== ptrace scope ===<br />
<br />
Arch enables the Yama LSM by default, providing a {{ic|kernel.yama.ptrace_scope}} flag. This flag is enabled by default and prevents processes from performing a {{ic|ptrace}} call on other processes outside of their scope without {{ic|CAP_SYS_PTRACE}}. While many debugging tools require this for some of their functionality, it is a significant improvement in security. Without this feature, there is essentially no separation between processes running as the same user without applying extra layers like namespaces. The ability to attach a debugger to an existing process is a demonstration of this weakness.<br />
<br />
==== Examples of broken functionality ====<br />
<br />
{{Note|You can still execute these commands as root (such as allowing them through [[sudo]] for certain users, with or without a password).}}<br />
<br />
* {{ic|gdb -p $PID}}<br />
* {{ic|strace -p $PID}}<br />
* {{ic|perf trace -p $PID}}<br />
* {{ic|reptyr $PID}}<br />
<br />
=== hidepid ===<br />
<br />
{{Warning|<br />
* This may cause issues for certain applications like an application running in a sandbox and [[Xorg]] (see workaround).<br />
* This causes issues with [[D-Bus]], [[PulseAudio]] and [[bluetooth]] when using {{Pkg|systemd}} > 237.64-1.<br />
}}<br />
<br />
The kernel has the ability to hide other users' processes, normally accessible via {{ic|/proc}}, from unprivileged users by mounting the {{ic|proc}} filesystem with the {{ic|1=hidepid=}} and {{ic|1=gid=}} options documented [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt#n1919 here]. <br />
<br />
This greatly complicates an intruder's task of gathering information about running processes, whether some daemon runs with elevated privileges, whether other user runs some sensitive program, whether other users run any program at all, makes it impossible to learn whether any user runs a specific program (given the program does not reveal itself by its behaviour), and, as an additional bonus, poorly written programs passing sensitive information via program arguments are now protected against local eavesdroppers.<br />
<br />
The {{ic|proc}} [[Users_and_groups#System_groups|group]], provided by the {{Pkg|filesystem}} package, acts as a whitelist of users authorized to learn other users' process information. If users or services need access to {{ic|/proc/<pid>}} directories beyond their own, [[Users_and_groups#Group_management|add them to the group]].<br />
<br />
For example, to hide process information from other users except those in the {{ic|proc}} group:<br />
<br />
{{hc|/etc/fstab|2=<br />
proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=proc 0 0<br />
}}<br />
<br />
For user sessions to work correctly, an exception needs to be added for ''systemd-logind'':<br />
<br />
{{hc|/etc/systemd/system/systemd-logind.service.d/hidepid.conf|2=<br />
[Service]<br />
SupplementaryGroups=proc<br />
}}<br />
<br />
== Sandboxing applications ==<br />
<br />
See also [[Wikipedia:Sandbox (computer security)]].<br />
<br />
{{Note|The user namespace configuration item {{ic|CONFIG_USER_NS}} is currently enabled in {{Pkg|linux}} (v4.14.5 or later), {{Pkg|linux-lts}} (v4.14.15 or later) and {{Pkg|linux-hardened}}. Lack of it may prevent certain sandboxing features from being made available to applications. Unprivileged usage is disabled by default unless the {{ic|kernel.unprivileged_userns_clone}} [[sysctl]] is set to {{ic|1}}, since it greatly increases the attack surface for local privilege escalation.}}<br />
<br />
=== Firejail ===<br />
<br />
[[Firejail]] is an easy to use and simple tool for sandboxing applications and servers alike. Firejail is suggested for browsers and internet facing applications, as well as any servers you may be running.<br />
<br />
=== bubblewrap ===<br />
<br />
[[bubblewrap]] is a setuid sandbox application developed from [[Wikipedia:Flatpak|Flatpak]] with an even smaller resource footprint than Firejail. While it lacks certain features such as file path whitelisting, bubblewrap does offer bind mounts as well as the creation of user/IPC/PID/network/cgroup namespaces and can support both simple and [https://github.com/projectatomic/bubblewrap/blob/master/demos/bubblewrap-shell.sh complex sandboxes].<br />
<br />
=== chroots ===<br />
<br />
Manual [[chroot]] jails can also be constructed.<br />
<br />
=== Linux containers ===<br />
<br />
[[Linux Containers]] are another good option when you need more separation than the other options (short of KVM and VirtualBox) provide. LXC's run on top of the existing kernel in a pseudo-chroot with their own virtual hardware.<br />
<br />
=== Other virtualization options ===<br />
<br />
Using full virtualization options such as [[VirtualBox]], [[KVM]], [[Xen]] or [https://www.qubes-os.org/ Qubes OS] (based on Xen) can also improve isolation and security in the event you plan on running risky applications or browsing dangerous websites.<br />
<br />
== Network and firewalls ==<br />
<br />
=== Firewalls ===<br />
<br />
While the stock Arch kernel is capable of using [[Wikipedia:Netfilter|Netfilter]]'s [[iptables]] and [[nftables]], they are not enabled by default. It is highly recommended to set up some form of firewall to protect the services running on the system. Many resources (including ArchWiki) do not state explicitly which services are worth protecting, so enabling a firewall is a good precaution.<br />
<br />
* See [[iptables]] and [[nftables]] for general info.<br />
* See [[Simple stateful firewall]] for a guide on setting up an iptables firewall.<br />
* See [[:Category:Firewalls]] for other ways of setting up netfilter.<br />
* See [[Ipset]] for blocking lists of ip addresses, such as those from Bluetack.<br />
<br />
=== Kernel parameters ===<br />
<br />
Kernel parameters which affect networking can be set using [[Sysctl]]. For how to do this, see [[Sysctl#TCP/IP stack hardening]].<br />
<br />
=== SSH ===<br />
<br />
To mitigate [[Wikipedia:Brute-force attack|brute-force attacks]] it is recommended to enforce key-based authentication. For OpenSSH, see [[OpenSSH#Force public key authentication]]. Alternatively [[Fail2ban]] or [[Sshguard]] offer lesser forms of protection by monitoring logs and writing [[Iptables|iptables rules]] but open up the potential for a denial of service, since an attacker can spoof packets as if they came from the administrator after identifying their address.<br />
<br />
You may want to harden authentication even more by using two-factor authentication. [[Google Authenticator]] provides a two-step authentication procedure using one-time passcodes (OTP).<br />
<br />
Denying root login is also a good practice, both for tracing intrusions and adding an additional layer of security before root access. For OpenSSH, see [[OpenSSH#Deny]].<br />
<br />
=== DNS ===<br />
<br />
{{Accuracy|Your browser might notice DNS spoofing with [[HSTS]].}}<br />
<br />
[[DNS]] queries are, by default on most systems, sent and received unencrypted and without checking for authentication of receipt from qualified servers. This could then allow [[Wikipedia:Man-in-the-middle_attack|man-in-the-middle attacks]], whereby an attacker intercepts your DNS queries and modifies the responses to deliver you an IP address leading to a [[Wikipedia:Phishing|phishing]] page to collect your valuable information. Neither you nor the browser/other software would be aware since the DNS protocol takes the legitimacy of query results for granted.<br />
<br />
[[DNSSEC]] is a set of standards in place that requires DNS servers to provide clients with origin authentication of DNS data, authenticated denial of existence, and data integrity. It, however, is not yet widely used. With DNSSEC enabled, an attacker can not make modifications to your DNS queries and the returning results, but would still be able to read them.<br />
<br />
[[DNSCrypt]], as well as later alternative protocol developments ''DNS over TLS'' and ''DNS over HTTPS'', use cryptography to secure communications with DNS servers. Usually only one protocol is employed on a system level. See [[Domain name resolution#DNS servers]] for supporting software.<br />
<br />
If you have a domain name, set a [[Sender Policy Framework]] policy to combat email spoofing.<br />
<br />
=== Proxies ===<br />
<br />
Proxies are commonly used as an extra layer between applications and the network, sanitizing data from untrusted sources. The attack surface of a small proxy running with lower privileges is significantly smaller than a complex application running with the end user privileges.<br />
<br />
For example the DNS resolver is implemented in {{Pkg|glibc}}, that is linked with the application (that may be running as root), so a bug in the DNS resolver might lead to a remote code execution. This can be prevented by installing a DNS caching server, such as [[dnsmasq]], which acts as a proxy. [https://googleonlinesecurity.blogspot.it/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html]<br />
<br />
=== Managing SSL certificates ===<br />
<br />
{{Merge|Transport Layer Security|There's a dedicated article.}}<br />
<br />
See [[OpenSSL]] and [[Network Security Services]] (NSS) for managing custom server-side SSL certificates. Notably, the related [[Let’s Encrypt]] project is also supported. <br />
<br />
The default internet SSL certificate trustchains are provided by the {{Pkg|ca-certificates}} package and its dependencies. Note that Arch relies on trust-sources (e.g. {{Pkg|ca-certificates-mozilla}}) providing the certificates to be trusted per default by the system. <br />
<br />
There may be occasions when you want to deviate from the default. For example, you may read some [https://www.theregister.co.uk/2016/05/27/blue_coat_ca_certs/ news] and want to distrust a certificate rather than wait until the trust-source providers do. The Arch infrastructure makes such easy:<br />
<br />
# Obtain the respective certificate in .crt format (Example: [https://crt.sh/?id=19538258 view], [https://crt.sh/?d=19538258 download]; in case of an existing trusted root certificate authority, you may also find it extracted in the system path), <br />
# Copy it to {{ic|/etc/ca-certificates/trust-source/blacklist/}} and <br />
# Run ''update-ca-trust'' as root. <br />
<br />
To check the blacklisting works as intended, you may re-open your preferred browser and do so via its GUI, which should show it as '''untrusted''' now.<br />
<br />
== Authenticating packages ==<br />
<br />
[https://www.cs.arizona.edu/stork/packagemanagersecurity/attacks-on-package-managers.html#overview Attacks on package managers] are possible without proper use of package signing, and can affect even package managers with [https://www.cs.arizona.edu/stork/packagemanagersecurity/faq.html proper signature systems]. Arch uses package signing by default and relies on a web of trust from 5 trusted master keys. See [[Pacman-key]] for details.<br />
<br />
== Follow vulnerability alerts ==<br />
<br />
Subscribe to the Common Vulnerabilities and Exposure (CVE) Security Alert updates, made available by National Vulnerability Database, and found on the [https://nvd.nist.gov/download.cfm NVD Download webpage]. The [https://security.archlinux.org/ Arch Linux Security Tracker] serves as a particularly useful resource in that it combines Arch Linux Security Advisory (ASA), Arch Linux Vulnerability Group (AVG) and CVE data sets in tabular format. See also [[Arch Security Team]].<br />
<br />
{{Warning|Do not be tempted to perform [[partial upgrades]], as they are not supported by Arch Linux and may cause instability: the whole system should be upgraded when upgrading a component. Also note that infrequent system updates can complicate the update process.}}<br />
<br />
== Physical security ==<br />
<br />
Physical access to a computer is root access given enough time and resources. However, a high ''practical'' level of security can be obtained by putting up enough barriers.<br />
<br />
An attacker can gain full control of your computer on the next boot by simply attaching a malicious IEEE 1394 (FireWire), Thunderbolt or PCI Express device as they are given full memory access.[https://www.breaknenter.org/projects/inception/] There is little you can do from preventing this, or modification of the hardware itself - such as flashing malicious firmware onto a drive. However, the vast majority of attackers will not be this knowledgeable and determined.<br />
<br />
[[#Disk encryption]] will prevent access to your data if the computer is stolen, but malicious firmware can be installed to obtain this data upon your next log in by a resourceful attacker.<br />
<br />
=== Locking down BIOS ===<br />
<br />
Adding a password to the BIOS prevents someone from booting into removable media, which is basically the same as having root access to your computer. You should make sure your drive is first in the boot order and disable the other drives from being bootable if you can.<br />
<br />
=== Bootloaders ===<br />
<br />
It is highly important to protect your bootloader. There is a magic kernel parameter called {{ic|1=init=/bin/sh}}. This makes any user/login restrictions totally useless.<br />
<br />
==== Syslinux ====<br />
<br />
Syslinux supports [[Syslinux#Security|password-protecting your bootloader]]. It allows you to set either a per-menu-item password or a global bootloader password.<br />
<br />
==== GRUB ====<br />
<br />
[[GRUB]] supports bootloader passwords as well. See [[GRUB/Tips and tricks#Password protection of GRUB menu]] for details. It also has support for [[GRUB#Encrypted /boot|encrypted /boot]], which only leaves some parts of the bootloader code unencrypted. GRUB's configuration, [[kernel]] and [[initramfs]] are encrypted.<br />
<br />
=== Boot partition on removable flash drive ===<br />
<br />
One popular idea is to place the boot partition on a flash drive in order to render the system unbootable without it. Proponents of this idea often use [[#Disk encryption|full disk encryption]] alongside, and some also use [[Dm-crypt/Specialties#Encrypted_system_using_a_detached_LUKS_header|detached encryption headers]] placed on the boot partition. <br />
<br />
=== Automatic logout ===<br />
<br />
If you are using [[Bash]] or [[Zsh]], you can set {{ic|TMOUT}} for an automatic logout from shells after a timeout.<br />
<br />
For example, the following will automatically log out from virtual consoles (but not terminal emulators in X11):<br />
<br />
{{hc|/etc/profile.d/shell-timeout.sh|<nowiki><br />
TMOUT="$(( 60*10 ))";<br />
[ -z "$DISPLAY" ] && export TMOUT;<br />
case $( /usr/bin/tty ) in<br />
/dev/tty[0-9]*) export TMOUT;;<br />
esac<br />
</nowiki>}}<br />
<br />
If you really want EVERY Bash/Zsh prompt (even within X) to timeout, use:<br />
<br />
$ export TMOUT="$(( 60*10 ))";<br />
<br />
Note that this will not work if there is some command running in the shell (eg.: an SSH session or other shell without {{ic|TMOUT}} support). But if you are using VC mostly for restarting frozen GDM/Xorg as root, then this is very useful.<br />
<br />
=== Protect against rogue USB devices ===<br />
<br />
Install [[USBGuard]], which is a software framework that helps to protect your computer against rogue USB devices (a.k.a. [https://srlabs.de/badusb BadUSB], [https://github.com/samyk/poisontap PoisonTap] or [https://lanturtle.com/ LanTurtle]) by implementing basic whitelisting and blacklisting capabilities based on device attributes.<br />
<br />
== Rebuilding packages ==<br />
<br />
Packages can be rebuilt and stripped of undesired functions and features as a means to reduce attack surface. For example, {{Pkg|bzip2}} can be rebuilt without {{ic|bzip2recover}} in an attempt to circumvent [https://security.archlinux.org/CVE-2016-3189 CVE-2016-3189]. Custom hardening flags can also be applied either manually or via a wrapper.<br />
<br />
== See also ==<br />
<br />
* [https://security.archlinux.org/ Arch Linux Security Tracker]<br />
* [https://wiki.centos.org/HowTos/OS_Protection CentOS Wiki: OS Protection]<br />
* [https://www.ibm.com/developerworks/linux/tutorials/l-harden-desktop/index.html Hardening the Linux desktop]<br />
* [https://www.ibm.com/developerworks/linux/tutorials/l-harden-server/index.html Hardening the Linux server]<br />
* [https://github.com/lfit/itpol/blob/master/linux-workstation-security.md Linux Foundation: Linux workstation security checklist]<br />
* [https://www.privacytools.io/ privacytools.io Privacy Resources]<br />
* [https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/ Red Hat Enterprise Linux 7 Security Guide]<br />
* [https://www.debian.org/doc/manuals/securing-debian-howto/securing-debian-howto.en.pdf Securing Debian Manual (PDF)]<br />
* [https://web.archive.org/web/20140220055801/http://crunchbang.org:80/forums/viewtopic.php?id=24722 The paranoid #! Security Guide]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=XFS_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539086
XFS (简体中文)
2018-09-01T03:31:17Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:File systems (简体中文)]]<br />
[[en:XFS]]<br />
[[it:XFS]]<br />
[[ja:XFS]]<br />
[[ru:XFS]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|File systems (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|XFS|2018-09-01|523873}}<br />
<br />
XFS 是由硅谷图形公司 (Silicon Graphics, Inc.) 开发的高性能日志式文件系统。XFS 因其基于分配组 (allocation group) 的设计而特别擅长并行 IO。当该文件系统跨越多个存储设备时,这种设计使得 IO 线程数、文件系统带宽、文件和文件系统大小都具有极大的可伸缩性。<br />
<br />
== 安装 ==<br />
<br />
用于管理 XFS 分区的工具位于 {{Pkg|xfsprogs}} 软件包中,该包默认已经安装在基本系统中。<br />
<br />
== 数据损坏 ==<br />
<br />
如果遇到了任何原因的引起的数据损坏,就需要手动修复文件系统。<br />
<br />
=== 修复 XFS 文件系统 ===<br />
<br />
先卸载 XFS 文件系统:<br />
# umount /dev/sda3<br />
<br />
卸载后,运行 {{man|8|xfs_repair}} 工具来修复:<br />
# xfs_repair -v /dev/sda3<br />
<br />
=== 在线元数据检查 (scrub) ===<br />
<br />
{{警告|该程序目前是'''实验性'''的,这意味着它的行为和接口可能随时发生变化。参见 {{man|8|xfs_scrub}}。}}<br />
<br />
{{ic|xfs_scrub}} 请求内核检查 [[File systems (简体中文)|文件系统]] 中的所有元数据对象。内核会扫描元数据记录以查找明显错误的值,然后与其他元数据进行交叉引用。其目的是通过检查单个元数据记录与文件系统中其他元数据的一致性,建立对整个文件系统一致性的合理置信度。如果存在完整的冗余数据结构,则可以根据其他元数据重建损坏的元数据。<br />
<br />
[[systemd (简体中文)#使用单元|Enable]] {{ic|xfs_scrub_all.timer}} 以定期在线检查所有文件系统元数据。有时可能需要[[systemd (简体中文)#修改现存单元文件|编辑]] {{ic|xfs_scrub_all.timer}},因为它仅在每周日上午 3:10 运行。<br />
<br />
== 数据完整性 ==<br />
<br />
xfsprogs 3.2.0 引入了一种新型磁盘格式 (v5),其包含了称为 [https://www.kernel.org/doc/Documentation/filesystems/xfs-self-describing-metadata.txt 自描述元数据 (Self-Describing Metadata)] 的元数据校验方案。<br />
基于 CRC32,它提供的额外保护措施可以在意外断电时防止元数据损坏。当使用 xfsprogs 3.2.3 或更高版本时,这种校验默认是打开的。如果需要在旧版内核中挂载 XFS 为可读写,可以在调用 {{man|8|mkfs.xfs}} 时加上 {{ic|1=-m crc=0}} 来关闭校验特性。<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
自 Linux Kernel 3.15 起,XFS v5 磁盘格式被视作稳定特性,可用于生产环境。<br />
<br />
{{注意|与 [[Btrfs (简体中文)|Btrfs]] 和 [[ZFS (简体中文)|ZFS]] 不同,XFS 中的 CRC32 校验仅用于元数据而非实际数据。}}<br />
<br />
== 性能 ==<br />
<br />
要获得最佳速度,只要这样创建 XFS 文件系统:<br />
<br />
# mkfs.xfs /dev/''target_partition''<br />
<br />
对,就是这么简单 - 因为所有 [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E 新特性默认都是开启的]。<br />
<br />
{{警告|关闭写入屏障 (barrier)、关闭访问时间记录 (atime) 以及其他性能增强功能会导致数据损坏和丢失的可能性更大。}}<br />
<br />
根据 [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E XFS wiki],可以考虑更改默认的 CFQ [[Improving performance#Input/output schedulers|I/O 调度器]](比如改成 [[wikipedia:Deadline_scheduler|Deadline]]、[[wikipedia:NOOP_scheduler|Noop]] 或 [[Linux-ck#How to enable the BFQ I/O Scheduler|BFQ]])来发挥 XFS 的所有优势,特别是在 [[Solid State Drives (简体中文)|SSD]] 上。<br />
<br />
=== 带区大小和宽度 ===<br />
<br />
如果这个文件系统位于条带化的 RAID 上,可以在 {{man|8|mkfs.xfs}} 命令中指定带区大小来获得显著的性能提升。<br />
<br />
参考 [http://xfs.org/index.php/XFS_FAQ#Q:_How_to_calculate_the_correct_sunit.2Cswidth_values_for_optimal_performance How to calculate the correct sunit,swidth values for optimal performance]<br />
<br />
=== 关闭写入屏障 (Barrier) ===<br />
<br />
可以通过关闭文件系统的写入屏障来提高性能,方法是向 [[fstab (简体中文)|fstab]] 中添加 {{ic|nobarrier}} 挂载选项。<br />
<br />
=== 访问时间记录 ===<br />
<br />
某些文件系统可以通过在 {{ic|/etc/fstab}} 文件中添加 {{ic|noatime}} 挂载选项来增强性能。对于 XFS 文件系统来说,默认的访问时间记录行为是 {{ic|relatime}},与 noatime 相比这几乎没有额外开销,且仍然可以记录正确的访问时间。所有 Linux 文件系统现在都以这个选项为默认值(从大约 2.6.30 版本开始),但是 XFS 从 2006 年开始就采用了类似 relatime 的特性,因此不需要出于性能考虑而在 XFS 上使用 noatime。<br />
<br />
另外,{{ic|noatime}} 包含了 {{ic|nodiratime}},所以指定了 '''noatime''' 时就不需要指定 '''nodiratime'''。<br />
<br />
=== 磁盘碎片整理 ===<br />
<br />
尽管 XFS 本质上基于区段 (Extent) 并且延迟分配策略很大程度上增强了它对磁盘碎片的抗性,XFS 仍然提供了磁盘碎片整理程序(''xfs_fsr'',XFS filesystem reorganizer 的缩写),它可以在已挂载且活动的 XFS 文件系统上整理碎片。定期查看 XFS 碎片也很有用。<br />
<br />
{{man|8|xfs_fsr}} 改进了已挂载文件系统的文件组织。该重组织算法一次操作一份文件,对文件进行压缩或改进文件区段布局(改成连续数据块)。<br />
<br />
==== 检查碎片程度 ====<br />
<br />
查看当前文件系统中有多少磁盘碎片:<br />
# xfs_db -c frag -r /dev/sda3<br />
<br />
==== 进行碎片整理 ====<br />
<br />
要启动碎片整理,使用 {{man|8|xfs_fsr}} 命令:<br />
# xfs_fsr /dev/sda3<br />
<br />
=== B+树(用于索引未用 inode) ===<br />
<br />
自 Linux 3.16 起,XFS 增加了 B+树用于索引未被使用的 inode。它等同于索引已使用 inode 的 B+树,不同之处在于索引未用 inode 的 B+树至少包含一个未用 inode。这一设计的目的是改进分配 inode 时寻找未用 inode 簇的性能。它可以提高长期使用后的文件系统性能,比如你在数月或数年之间已经向文件系统写入或删除了数百万的文件。使用这个功能不会影响整个文件系统的可靠性程度或恢复能力。<br />
<br />
这个功能依赖于新的 v5 磁盘格式,自 Linux Kernel 3.15 起它被视作可用于生产环境的稳定特性。它没有改变磁盘上原本的数据结构,但会添加一个新的结构来使它与 B+树(用于分配 inode)保持兼容;因此,旧版本的内核只能将带有 B+树功能的文件系统挂载为只读模式。<br />
<br />
当使用 xfsprogs 3.2.3 或更高版本时这个功能默认是开启的。如果你需要一个旧版本内核可写入的文件系统,这个功能可以在格式化 XFS 分区时用 {{ic|1=finobt=0}} 开关来关闭。你还需要把它和 {{ic|1=crc=0}} 一起用。<br />
# mkfs.xfs -m crc=0,finobt=0 /dev/''target_partition''<br />
也可以简写({{ic|crc}} 包含了 {{ic|finobt}})<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
== 故障排除 ==<br />
<br />
=== 根文件系统配额 ===<br />
<br />
XFS 配额挂载选项({{ic|uquota}}、{{ic|gquota}}、{{ic|prjquota}} 等)会在重新挂载文件系统时失效。要对根文件系统启用配额功能,这个挂载选项需要作为 [[Kernel parameters (简体中文)|内核参数]] {{ic|1=rootflags=}} 传递给初始化内存盘 (initramfs)。在随后的启动过程中,这个选项不需要在 {{ic|/etc/fstab}} 中挂载根 ({{ic|/}}) 文件系统的选项里再次列出。<br />
<br />
{{注意|XFS 配额相较于标准 Linux [[Disk quota|磁盘配额]] 有一些区别,这篇文章 http://inai.de/linux/adm_quota 或许值得一读。}}<br />
<br />
== 参考资料 ==<br />
<br />
* [http://xfs.org/index.php/XFS_FAQ XFS FAQ]<br />
* [http://xfs.org/index.php/Improving_Metadata_Performance_By_Reducing_Journal_Overhead Improving Metadata Performance By Reducing Journal Overhead]<br />
* [[wikipedia:XFS|XFS Wikipedia Entry]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=RAID_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539085
RAID (简体中文)
2018-09-01T03:05:55Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:Storage virtualization (简体中文)]]<br />
[[en:RAID]]<br />
[[es:RAID]]<br />
[[it:RAID]]<br />
[[ja:RAID]]<br />
[[ru:RAID]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Software RAID and LVM}}<br />
{{Related|LVM#RAID}}<br />
{{Related|Installing with Fake RAID}}<br />
{{Related|Convert a single drive system to RAID}}<br />
{{Related|ZFS}}<br />
{{Related|ZFS/Virtual disks}}<br />
{{Related|Swap#Striping}}<br />
{{Related|Btrfs (简体中文)#RAID}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|RAID|2018-09-01|539084}}<br />
{{Style|Non-standard headers, other [[Help:Style]] issues}}<br />
<br />
独立磁盘冗余阵列 (Redundant Array of Independent Disks, [[Wikipedia:RAID|RAID]]) 是一种将多个磁盘驱动器组件(通常是多块硬盘或多个分区)组合为一个逻辑单元的存储技术。根据 RAID 的部署情况,这个逻辑单元可以是单个的文件系统,也可以是一个能在其上建立多个分区的透明中间层。根据所需的冗余量和性能要求,数据按照 [[#RAID 级别]] 中的某一种方式分布在驱动器中。所选的 RAID 级别决定了是否可以防止数据丢失(硬盘故障时)、是否提高性能或结合两者优势。<br />
<br />
本文介绍如何使用 mdadm 创建并管理一个软件磁盘阵列。<br />
<br />
{{警告|确保在操作前 [[Backup programs|备份]] 所有数据。}}<br />
<br />
== RAID 级别 ==<br />
<br />
尽管大部分 RAID 级别都或多或少地包含了数据冗余,RAID 并不能完全保证数据安全。如果遇到火灾、计算机被盗或者多块硬盘同时损坏,RAID 将无法保护数据。此外,配置一个带有 RAID 的系统是一个复杂的过程,可能会破坏现有数据。<br />
<br />
=== 基本 RAID 级别 ===<br />
<br />
有多种不同的 [[Wikipedia:Standard RAID levels|基本 RAID 级别]],下面列出了最常用的几种。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 0|RAID 0]]<br />
: 将多块硬盘组合为一个带区卷,尽管它 ''并不提供数据冗余'',它仍可以被当做是 RAID,而且它确实提供了 ''巨幅的速度提升''。如果提高速度比数据安全更重要(比如作为 [[swap]] 分区),可以选择这种 RAID 级别。在服务器上,RAID 1 和 RAID 5 阵列更加合适。在 RAID 0 阵列中,块设备的大小是最小组成分区的大小乘以组成分区的数量。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 1|RAID 1]]<br />
: 这是最直接的 RAID 级别:完全镜像。与其他 RAID 级别一样,它只在分区位于不同物理硬盘上才有效。如果某一块硬盘损坏,由 RAID 阵列提供的块设备将不受影响。可以使用 RAID 1 的情境包括了除 [[swap]] 和临时文件外的其他所有情境。请注意,如果使用由软件实现的 RAID,引导分区只能选择 RAID 1,因为读取引导分区的引导器通常无法辨识 RAID,但一个 RAID 1 的组成分区可以像常规分区一样读取。RAID 1 阵列块设备的大小是最小组成分区的大小。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 5|RAID 5]]<br />
: 需要至少 3 块物理硬盘,并结合了 RAID 1 的数据冗余和 RAID 0 的速度与可用空间上的优势。RAID 5 使用了类似 RAID 0 的条带化技术,同时也将奇偶校验块''分布式地存储在每一块磁盘上''。如果遭遇硬盘损坏,这些奇偶校验块就可以用来在替代的新磁盘上重建损坏的数据。RAID 5 仅可弥补一个组成磁盘损坏带来的损失。<br />
: {{注意|RAID 5 是结合了速度与数据冗余优势的常用选择。但值得注意的是,当一块硬盘损坏而没有及时更换,此时若再有硬盘损坏,则所有数据都将丢失。此外,考虑到现代磁盘的超大容量和消费级硬盘无法恢复的读取错误率 (Unrecoverable read error, URE),超过 4TiB 的阵列在重建数据时出现至少一处读取错误 (URE) 的概率几乎在'''预料之中'''(概率大于 50%)。因此,存储行业不再推荐使用 RAID 5。}}<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 6|RAID 6]]<br />
: 需要至少 4 块物理硬盘,提供了和 RAID 5 一样的优势并且在两块硬盘损坏时仍能保证数据安全。RAID 6 使用了和 RAID 5 类似的条带化技术,但是把两个不同的奇偶校验块 ''分布式地存储在每一块磁盘上''。如果磁盘发生故障,这些奇偶校验块将用于重建替换磁盘上的数据。RAID 6 可以承担两个组成磁盘的损失。在抵御无法恢复的读取错误 (Unrecoverable read error, URE) 时也某种程度上更加可靠,因为磁盘阵列在重建某一块损坏硬盘的数据时仍然有奇偶校验块可以校验数据。但是,总体而言,RAID 6 开销较大,大多数时候 far2 布局的 RAID 10(参见下文)提供了更快的速度和更强的可靠性,因此更倾向于采用 RAID 10。<br />
<br />
=== 嵌套 RAID 级别 ===<br />
<br />
; [[Wikipedia:Nested RAID levels#RAID 10 (RAID 1+0)|RAID 1+0]]<br />
: RAID1+0 是一种结合了两种基本 RAID 级别的嵌套级别,它相对基本级别提高了性能且增加了冗余量。它通常被称为 ''RAID10'',但是,Linux MD(内核自带的 RAID 实现)支持的 RAID10 不是简单的两层 RAID 重叠,请看下文。<br />
<br />
; [[Wikipedia:Non-standard RAID levels#Linux MD RAID 10|RAID 10]]<br />
: Linux 下的 RAID10 建立在 RAID1+0 的概念上,但它将其实现为单一的一层,这一层可以有多种不同的布局。可参考 [https://www.suse.com/zh-cn/documentation/sles11/stor_admin/data/raidmdadmr10cpx.html 创建复杂 RAID 10]。<br />
: 在 Y 块硬盘上的 ''近 X 布局'' 在不同硬盘上重复储存每个数据块 X 次,但不需要 Y 可以被 X 整除。数据块放在所镜像的磁盘上几乎相同的位置,这就是 ''近布局'' 名字的来源。它可以工作在任意数量的磁盘上,最少是 2 块。在 2 块硬盘上的近 2 布局相当于 RAID1,4 块硬盘上的近 2 布局相当于 RAID1+0。<br />
: 在 Y 块硬盘上的 ''远 X 布局'' 设计用于在镜像阵列中提供与条带化技术一样快的读取速度。它通过把每块硬盘分成前后两部分来实现这一点,写入第一块硬盘前半部分数据也会写入第二块硬盘的后半部分,反之亦然。这样可以达到一个效果,那就是把对连续数据的读取条带化,而这正是 RAID0 和 RAID5 读取性能高的原因。它的缺点在于写入连续数据时有轻微性能损失,因为硬盘磁头要运动到另一片区域来写入镜像。当数据读取性能和可用性/冗余性一样重要时,比起 RAID1+0 '''和''' RAID5,更应该优先考虑远 2 布局的 RAID10。需注意这种方式仍无法代替备份。详情请阅读维基百科相关页面。<br />
<br />
=== RAID 级别对比 ===<br />
<br />
{| class="wikitable"<br />
! RAID 级别!!数据冗余!!物理设备利用率!!读取性能!!写入性能!!最少磁盘数量<br />
|-<br />
| '''0'''||{{No}}||100%||n 倍<br />
<br />
'''最优'''<br />
||n 倍<br />
<br />
'''最优'''<br />
||2<br />
|-<br />
| '''1'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍<br />
||1 倍||2<br />
|-<br />
| '''5'''||{{Yes}}||67% - 94%||(n−1) 倍<br />
<br />
'''较优'''<br />
||(n−1) 倍<br />
<br />
'''较优'''<br />
||3<br />
|-<br />
| '''6'''||{{Yes}}||50% - 88%||(n−2) 倍||(n−2) 倍||4<br />
|-<br />
| '''10,far2'''||{{Yes}}||50%||n 倍<br />
'''最优;''' 与 RAID0 相当但加入了数据冗余<br />
||(n/2) 倍||2<br />
|-<br />
| '''10,near2'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍||(n/2) 倍||2<br />
|}<br />
<br />
<nowiki>*</nowiki> 其中 ''n'' 表示用于组成阵列的磁盘数量。<br />
<br />
== 实现方式 ==<br />
<br />
RAID 设备可以用不同方式来管理:<br />
<br />
; 软件 RAID<br />
: 这是最简单的实现方式,因为它不依赖于专用固件或专有软件。这种阵列由操作系统通过以下方式进行管理:<br />
:* 通过抽象层管理(比如 [[#安装|mdadm]]); {{注意|这是在本指南下文将要使用的方法。}}<br />
:* 通过逻辑卷管理器来管理(比如 [[LVM#RAID|LVM]]);<br />
:* 通过文件系统的某个组件来管理(比如 [[ZFS (简体中文)|ZFS]],[[Btrfs#RAID|Btrfs]])。<br />
<br />
; 硬件 RAID<br />
: 这种阵列由安装在计算机上的专用硬件卡直接管理,硬盘直接连接在该计算机上。RAID 的处理逻辑由板载的处理器完成,它独立于 [[Wikipedia:Central processing unit|主处理器 (CPU)]]。尽管这种方案独立于任何操作系统,但却需要驱动程序来使硬件 RAID 控制器正常工作。取决于不同的制造商,硬件 RAID 阵列可以在 option ROM 里设置或者操作系统安装完成后另行安装配套软件来设置。这种设置是独立于 Linux 内核的:内核并不能看到单独的每块硬盘。<br />
<br />
; [[Fakeraid|FakeRAID]]<br />
: 这种类型的 RAID 应当称为 BIOS 或板载 RAID,却常被错误地当做硬件 RAID 来宣传。这种阵列由伪 RAID 控制器来管理,RAID 逻辑由 option ROM 或[http://www.win-raid.com/t19f13-Intel-EFI-RAID-quot-SataDriver-quot-BIOS-Modules.html 安装了 EFI Sata 驱动程序的] 固件本身([[Unified Extensible Firmware Interface (简体中文)|UEFI]] 情况下)来完成,但并不是实现了 ''所有'' RAID 功能的完整硬件 RAID 控制器。因此,这种 RAID 有时被称为 FakeRAID。来自 [[official repositories (简体中文)|官方仓库]] 的 {{Pkg|dmraid}} 用于处理这种控制器。这里列出一些 FakeRAID 控制器:[[Wikipedia:Intel Rapid Storage Technology|Intel Rapid Storage]],JMicron JMB36x RAID ROM,AMD RAID,ASMedia 106x 和 NVIDIA MediaShield。<br />
<br />
=== 我正在使用哪一种 RAID? ===<br />
<br />
由于软件 RAID 是由用户部署的,因此用户很容易就知道 RAID 的类型。<br />
<br />
但是,辨别 FakeRAID 和真正的硬件 RAID 是很困难的。如上所述,制造商经常错误地混淆这两种类型的 RAID,还可能进行虚假宣传。这种情况下应该采取的最好方式是运行 {{ic|lspci}} 命令并在输出信息中找到你的 RAID 控制器,然后根据这些信息进行更进一步的搜索。硬件 RAID 控制器会在这一列表中出现,但 FakeRAID 不会。同时,真正的硬件 RAID 控制器通常价格很高,如果这个系统是自行组装的,那么很可能安装一个硬件 RAID 会使电脑的价格显著提高。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|mdadm}}。''mdadm'' 用于管理在纯块设备上建立起来的纯软件 RAID:底层硬件不提供任何 RAID 逻辑,只是一些磁盘而已。''mdadm'' 可以在任何块设备集合上工作,甚至是那些非常规的设备。比如,你可以用一堆 U 盘来建立 RAID 阵列。<br />
<br />
=== 准备设备 ===<br />
<br />
{{警告|这些步骤会擦除指定设备上的所有数据,输入命令请小心!}}<br />
<br />
如果设备是旧设备重用或刚从一个现有的阵列上拆下来,请擦除所有旧的 RAID 配置信息:<br />
<br />
# mdadm --misc --zero-superblock /dev/<drive><br />
<br />
或者是删除设备上的某个特定的分区:<br />
<br />
# mdadm --misc --zero-superblock /dev/<partition><br />
<br />
{{注意|<br />
* 清除一个分区的 superblock 不会影响到磁盘上的其他分区。<br />
* 考虑到 RAID 本身的功能特点,在运行中的磁盘阵列中完全地 [[securely wipe disk|安全擦除磁盘]] 是很困难的。请在创建阵列前考虑要不要安全擦除磁盘。<br />
}}<br />
<br />
=== 对磁盘进行分区 ===<br />
<br />
强烈推荐对用于阵列的硬盘进行分区。考虑到大多数 RAID 用户会用到超过 2 TiB 的硬盘,因此推荐并要求使用 GPT。参阅 [[Partitioning (简体中文)]] 获取关于磁盘分区的更多信息以及可供使用的 [[Partitioning (简体中文)#分区工具|分区工具]]。<br />
<br />
{{注意|也可以在裸磁盘(没有分区的磁盘)上直接创建 RAID,但不推荐这么做,因为这样可能会导致更换损坏硬盘时出现问题}}<br />
<br />
{{注意|当更换 RAID 中的某块损坏的硬盘时,新硬盘的大小必须恰好等于或大于损坏的硬盘,否则无法完成阵列重建过程。即使是同一厂商相同型号的硬盘也可能有容量上的细微差别。通过在磁盘末尾保留一些未分配的空间可以消除磁盘容量上的细微差异,这样可以使替代磁盘的型号选择更加容易。因此,最好在磁盘末尾留出大约 100 MiB 的未分配空间。}}<br />
<br />
==== GUID 分区表 ====<br />
<br />
* 创建分区以后,这些分区的 [[Wikipedia:GUID Partition Table#Partition type GUIDs|类型标识符 (GUID)]] 应该是 {{ic|A19D880F-05FC-4D3B-A006-743F0F84911E}}(在 ''fdisk'' 里将分区类型改为 {{ic|Linux RAID}} 或在 ''gdisk'' 里改为 {{ic|FD00}} 可以给所选分区分配这个标识符)。<br />
* 如果使用了一个更大的磁盘阵列,可以考虑分配 [[Persistent block device naming (简体中文)#by-label|文件系统标签]] 或 [[Persistent block device naming (简体中文)#by-partlabel|分区标签]] 用于以后区分每块单独的硬盘。<br />
* 建议在每个设备上创建大小相同的分区。<br />
<br />
==== 主引导记录 (MBR) ====<br />
<br />
对于在使用 MBR 的硬盘上创建分区的用户,可用的 [[Wikipedia:Partition type|分区类型 ID]] 包括:<br />
<br />
* {{ic|0xFD}}: 自动检测的 RAID(''fdisk'' 中称为 {{ic|Linux raid autodetect}})<br />
* {{ic|0xDA}}: 无文件系统(''fdisk'' 中称为 {{ic|Non-FS data}})<br />
<br />
更多信息请参阅 [https://raid.wiki.kernel.org/index.php/Partition_Types Linux Raid Wiki:Partition Types]。<br />
<br />
=== 创建阵列 ===<br />
<br />
使用 {{ic|mdadm}} 来创建阵列。参阅 {{man|8|mdadm}} 获取支持的选项。下面列出部分使用范例。<br />
<br />
{{警告|不要简单地复制/粘贴下面的示例,确保你已经使用正确的选项和设备名称替代了示例中相应的内容。}}<br />
<br />
{{注意|<br />
* 如果有一个从 [[Syslinux (简体中文)|Syslinux]] 启动的 RAID1 阵列,在 syslinux v4.07 中要求元数据值为 1.0,而不是默认的 1.2。<br />
* 当用 [[Archiso (简体中文)|Arch 安装镜像]] 创建磁盘阵列时,请使用 {{ic|1=--homehost=''myhostname''}} 选项设置 [[hostname|主机名]](或者 {{ic|1=--homehost=any}} 选项无论在什么主机上都用相同的主机名),否则主机名称 {{ic|archiso}} 会被写入阵列的元数据中。<br />
}}<br />
<br />
{{提示|要为 RAID 设备指定一个自定义的名称,可以使用 {{ic|1=--name=''MyRAIDName''}} 选项或将 RAID 设备路径改为 {{ic|/dev/md/''MyRAIDName''}}。Udev 会使用该名称创建指向 {{ic|/dev/md/}} 内 RAID 阵列的符号链接。如果 {{ic|homehost}} 与当前 [[hostname|主机名]] 匹配(或者 homehost 设为了 {{ic|any}})则链接将会是 {{ic|/dev/md/''name''}},如果 homehost 不匹配那么链接将会是 {{ic|/dev/md/''homehost'':''name''}}。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立 RAID1 阵列:<br />
<br />
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1<br />
<br />
下面这个例子展示了使用 4 块磁盘作为工作 (active) 磁盘,1 块作为备用 (spare) 磁盘建立 RAID5 阵列:<br />
<br />
# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1<br />
<br />
{{提示|{{ic|--chunk}} 可用于修改默认的区块大小。更多关于优化区块大小的内容请参阅 [http://www.zdnet.com/article/chunks-the-hidden-key-to-raid-performance/ Chunks: the hidden key to RAID performance]。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立远 2 布局的 RAID10 阵列 (RAID10, far2):<br />
<br />
# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1<br />
<br />
这样,阵列就会在虚拟设备 {{ic|/dev/mdX}} 下建立起来,容量已经合并且可以使用(但处于降级模式)。mdadm 在后台同步数据时你已经可以直接开始使用这个阵列了。储存奇偶校验位可能要花很长时间,可以用这个命令查看进度:<br />
<br />
$ cat /proc/mdstat<br />
<br />
=== 更新配置文件 ===<br />
<br />
默认情况下,{{ic|mdadm.conf}} 中的大部分内容都被注释掉了,它应该只包含如下内容:<br />
<br />
{{hc|/etc/mdadm.conf|<br />
...<br />
DEVICE partitions<br />
...<br />
}}<br />
<br />
这一指令告诉 mdadm 检查由 {{ic|/proc/partitions}} 引用的所有设备并尽可能将其中的阵列组合起来。如果你确实想启动所有可用的阵列并且确信不存在意料之外的超级块(比如安装了新的存储设备),那么这样的配置就很好。当然有一种更精准的控制方法,就是显式地将阵列添加到 {{ic|/etc/mdadm.conf}}:<br />
<br />
# mdadm --detail --scan >> /etc/mdadm.conf<br />
<br />
这将会在配置中添加类似这样的内容:<br />
<br />
{{hc|/etc/mdadm.conf|2=<br />
...<br />
DEVICE partitions<br />
...<br />
ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe<br />
}}<br />
<br />
这也会使 mdadm 检查由 {{ic|/proc/partitions}} 引用的设备。但是,只有超级块的 UUID 是 {{ic|27664…}} 的设备才会被组合成激活的阵列。<br />
<br />
更多信息请参阅 {{man|5|mdadm.conf}}。<br />
<br />
=== 组合成磁盘阵列 ===<br />
<br />
更新配置文件后即可用 mdadm 组合磁盘阵列:<br />
<br />
# mdadm --assemble --scan<br />
<br />
=== 格式化 RAID 上的文件系统 ===<br />
<br />
现在磁盘阵列已经可以像普通分区一样被格式化成某个 [[File systems (简体中文)|文件系统]],但要记住:<br />
<br />
* 不是所有文件系统都支持超大分区(参阅 [[Wikipedia:Comparison of file systems#Limits]])。<br />
* 文件系统需要支持在线增大和收缩(参阅 [[Wikipedia:Comparison of file systems#Features]])。<br />
* 应合理计算跨度大小和带区宽度来获得最佳性能。<br />
<br />
==== 计算 stride(跨度大小)和 stripe width(带区宽度) ====<br />
<br />
优化文件系统结构以适应底层 RAID 结构需要 2 个参数:''stride'' 和 ''stripe width''。它们对应于 RAID 的 ''chunk size(区块大小)'' 、文件系统的 ''block size(块大小)'' 以及 ''"data disks"(数据盘)的数量''。<br />
<br />
Chunk size(RAID 区块大小)是 RAID 阵列的一个属性,在阵列创建时就已经定好了。目前 {{ic|mdadm}} 默认该值为 512 KiB。这个参数可以用 {{ic|mdadm}} 读取:<br />
<br />
# mdadm --detail /dev/mdX | grep 'Chunk Size'<br />
<br />
Block size(块大小)是文件系统的一个属性,在文件系统创建时就已经定好了。在大部分文件系统上(包括 ext4)默认是 4 KiB。更多关于当前系统 ext4 的信息可以查看 {{ic|/etc/mke2fs.conf}} 文件。<br />
<br />
"Data disks"(数据盘)的数量指的是阵列能够完全重建数据所要求的最少可用设备。例如,对于 N 个设备的 raid0 来说这个数量是 N,对于 raid5 来说是 N-1。<br />
<br />
当你获得了这三个参数时,stride 和 stripe width 可以用下列公式来计算:<br />
<br />
stride = chunk size / block size<br />
stripe width = number of data disks * stride<br />
<br />
===== 范例 1. RAID0 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID0 阵列是由 2 块物理硬盘组成的。<br />
* Chunk size(RAID 区块大小)是 64 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 64/4 = 16。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 2*16 = 32。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.5 -b 4096 -E stride=16,stripe-width=32 /dev/md0<br />
<br />
===== 范例 2. RAID5 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID5 阵列由 4 块物理硬盘组成,3 块是数据盘,1 块是奇偶校验盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 3*128 = 384.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=384 /dev/md0<br />
<br />
关于 stride 和 stripe width 的更多信息,请参阅:[http://wiki.centos.org/HowTos/Disk_Optimization RAID Math]。<br />
<br />
===== 范例 3. RAID10,far2 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID10 阵列由 2 块物理硬盘组成。考虑到远 2 布局的 RAID10 的自身特性,两块硬盘都是数据盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
<br />
{{hc|# mdadm --detail /dev/md0 {{!}} grep 'Chunk Size'|<br />
Chunk Size : 512K<br />
}}<br />
<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。<br />
在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。<br />
在这个例子中,stripe width 的大小是 2*128 = 256。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/md0<br />
<br />
== 在 Live CD 中挂载 RAID ==<br />
<br />
如果你需要在 Live CD 中挂载 RAID 分区,用这个命令:<br />
<br />
# mdadm --assemble /dev/<disk1> /dev/<disk2> /dev/<disk3> /dev/<disk4><br />
<br />
如果缺一块盘的 RAID 1 被错误地识别为了 RAID 1(参照 {{ic|mdadm --detail /dev/md<number>}})并报告为非活动状态(参照 {{ic|cat /proc/mdstat}}),需要先停止磁盘阵列:<br />
<br />
# mdadm --stop /dev/md<number><br />
<br />
== 在 RAID 上安装 Arch Linux ==<br />
<br />
{{注意|本节仅适用于根文件系统在磁盘阵列上的情况。如果你的磁盘阵列上只是一个数据分区,那么可以跳过本节。}}<br />
<br />
你应该在安装过程中的 [[Partitioning (简体中文)|分区]] 和 [[File systems (简体中文)#创建文件系统|格式化]] 步骤之间创建 RAID 阵列。这将会把一个位于 RAID 阵列上的分区格式化成根文件系统,而不是直接格式化一个分区。<br />
按照 [[#安装]] 一节的步骤创建 RAID 阵列。,然后继续安装过程,直到 pacstrap 步骤完成。<br />
当使用 [[Unified Extensible Firmware Interface (简体中文)|UEFI 启动]] 时,还需要阅读 [[EFI system partition (简体中文)#RAID 上的 ESP]]。<br />
<br />
=== 更新配置文件 ===<br />
<br />
{{注意|这些操作应该在 chroot 以外完成,因此要在文件路径前加上 {{ic|/mnt}}。}}<br />
<br />
在基本系统安装完成以后,RAID 的默认配置文件 {{ic|mdadm.conf}} 需要这样来更新:<br />
<br />
# mdadm --detail --scan >> /mnt/etc/mdadm.conf<br />
<br />
在运行这个命令以后一定要用文本编辑器检查 {{ic|mdadm.conf}} 配置文件来确保它的内容看起来是合理的。<br />
<br />
{{注意|为防止系统启动时 {{ic|mdmonitor.service}} 启动失败(默认设为自动启动),你需要取消 {{ic|MAILADDR}} 的注释,并且在 {{ic|mdadm.conf}} 结尾留下可处理磁盘阵列出错通知的邮件地址和/或应用程序。参阅 [[#启用事件邮件通知]]。}}<br />
<br />
现在继续安装过程直到 [[Installation guide (简体中文)#Initramfs]] 步骤之前为止,然后按照下一节的步骤做。<br />
<br />
=== 配置 mkinitcpio ===<br />
<br />
{{注意|这些操作应该在 chroot 时完成。}}<br />
<br />
向 {{ic|mkinitcpio.conf}} 中的 [[mkinitcpio (简体中文)#钩子(HOOKS)|HOOKS]] 部分添加 {{ic|mdadm_udev}} 来为初始化内存盘添加 mdadm 支持:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
HOOKS=(base udev autodetect keyboard modconf block '''mdadm_udev''' filesystems fsck)<br />
...<br />
}}<br />
<br />
如果在一个 FakeRAID 阵列上使用 {{ic|mdadm_udev}} 钩子,建议在 [[mkinitcpio (简体中文)#附加文件(BINARIES、FILES)|BINARIES]] 列表中添加 ''mdmon'':<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
BINARIES=('''mdmon''')<br />
...<br />
}}<br />
<br />
然后 [[mkinitcpio (简体中文)#创建和启用镜像|重新生成初始化内存盘]]。<br />
<br />
参考 [[mkinitcpio (简体中文)#使用 RAID 磁盘阵列]]。<br />
<br />
=== 配置 boot loader ===<br />
<br />
将 {{ic|root}} 参数指向映射的磁盘,例如:<br />
<br />
root=/dev/md/''MyRAIDArray''<br />
<br />
如果按上述用内核设备节点来指定映射磁盘的方法之后,从软件 RAID 分区启动失败了,那就用 [[Persistent block device naming (简体中文)|持久化命名块设备]] 中的某种方法来指定映射的磁盘,例如:<br />
<br />
root=LABEL=Root_Label<br />
<br />
参考 [[GRUB#RAID]]。<br />
<br />
== 维护 RAID ==<br />
<br />
=== 数据清扫 (Scrubbing) ===<br />
<br />
定期运行数据 [[wikipedia:Data_scrubbing|清扫 (Scrubbing)]] 来检查并修复错误是一种很好的做法。一次完整数据清扫可能会花费数个小时,具体取决于磁盘阵列的大小和配置。<br />
<br />
启动数据清扫:<br />
<br />
# echo check > /sys/block/md0/md/sync_action<br />
<br />
数据检查操作会扫描驱动器来检查坏扇区并自动修复它们。如果找到了包含损坏数据的好扇区(本扇区中的数据与另一块硬盘中记录本扇区应有的数据不符,例如奇偶校验块和另一块数据块相结合可以证明本数据块是错误的),那就不动作,但记录下这一事件(见下文)。这种“不动作”允许管理员自行检查坏扇区中原本的数据和从冗余数据中重建的数据,然后决定保留哪个。<br />
<br />
与许多 mdadm 相关的任务/事项一样,数据清扫的进度也可以通过查看 {{ic|/proc/mdstat}} 文件来查询。<br />
<br />
例如:<br />
<br />
{{hc|$ cat /proc/mdstat|<nowiki><br />
Personalities : [raid6] [raid5] [raid4] [raid1]<br />
md0 : active raid1 sdb1[0] sdc1[1]<br />
3906778112 blocks super 1.2 [2/2] [UU]<br />
[>....................] check = 4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec<br />
bitmap: 0/30 pages [0KB], 65536KB chunk<br />
</nowiki>}}<br />
<br />
安全地停止当前的数据清扫操作:<br />
<br />
# echo idle > /sys/block/md0/md/sync_action<br />
<br />
{{注意|如果在数据清扫暂停时重启了系统,将继续进行清扫。}}<br />
<br />
数据清扫完成后,管理员可以检查有多少数据块(如果有的话)被标记为坏块:<br />
<br />
# cat /sys/block/md0/md/mismatch_cnt<br />
<br />
==== 关于数据清扫的一般说明 ====<br />
<br />
{{注意|用户也可以 echo '''repair''' 到 {{ic|/sys/block/md0/md/sync_action}} 里面,但是这是不明智的,因为一旦遇到数据不一致就被自动改写为一致。危险之处在于我们实际并不知道奇偶校验块和数据块哪个是对的(在 RAID1 中是不知道哪个数据块是对的)。因此自动清扫操作能不能用正确数据替换错误数据取决于运气。}}<br />
<br />
以 root 身份设定一个 cron 任务来定期执行清扫是很好的。{{AUR|raid-check}} 会对此有所帮助。如果要用 systemd 定时器而不是 cron 来执行定期清扫,{{AUR|raid-check-systemd}} 中包含了相同的脚本和配套的 systemd 定时器单元文件。<br />
<br />
{{注意|对于常规的大容量驱动器,清扫工作耗时大约 '''6 秒每 GB'''(即每 TB 大约需要 1 小时 45 分钟),因此应合理确定 cron 任务或定时器的开始时间。}}<br />
<br />
==== 对清扫 RAID1 和 RAID10 的说明 ====<br />
<br />
由于 RAID1 和 RAID10 本质上就是没有数据缓冲的,所以即使阵列工作正常,它的不匹配计数仍然可能是个非零值。这些不匹配计数只存在于正在写入数据的区域,且它们不反映任何问题。但是,我们无法区分非零的不匹配计数到底代表正在写入数据还是确实存在问题。这是造成 RAID1 和 RAID10 阵列误报错误的根源。即使如此,仍然建议定期清扫以发现并纠正驱动器上可能出现的坏扇区。<br />
<br />
=== 从阵列中移除设备 ===<br />
<br />
要从阵列中移除一个设备,先将这个设备标记为 faulty(故障):<br />
<br />
# mdadm --fail /dev/md0 /dev/sdxx<br />
<br />
现在从阵列中移除这个设备:<br />
<br />
# mdadm --remove /dev/md0 /dev/sdxx<br />
<br />
永久移除设备(比如想把一个设备拿出来单独使用):<br />
先使用上述两个命令,然后:<br />
<br />
# mdadm --zero-superblock /dev/sdxx<br />
<br />
{{警告|<br />
* 不要在 RAID0 阵列或者其他线性存放数据的阵列中进行这个操作!否则数据会丢失!<br />
* 重新使用已经移除的硬盘却不清除它的超级块将会导致下次启动时丢失所有数据。(因为 mdadm 将会把它当做磁盘阵列的一部分来使用)。<br />
}}<br />
<br />
停止使用某个阵列:<br />
<br />
# 卸载 (umount) 目标阵列<br />
# 用这个命令停止磁盘阵列运行:{{ic|mdadm --stop /dev/md0}}<br />
# 将本节开头的三个命令在每块硬盘上都运行一遍。<br />
# 将 {{ic|/etc/mdadm.conf}} 中的相关行移除。<br />
<br />
=== 向阵列中添加设备 ===<br />
<br />
可以在系统正在运行且设备已经挂载的情况下使用 mdadm 添加新设备。<br />
按照前文所述的方法,使用现有阵列中相同的布局对新设备进行分区。<br />
<br />
如果 RAID 阵列尚未组合,先组合它们:<br />
<br />
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1<br />
<br />
向阵列中添加新设备:<br />
<br />
# mdadm --add /dev/md0 /dev/sdc1<br />
<br />
这一步 mdadm 不会花费很长时间。<br />
<br />
根据不同的 RAID 类型(比如 RAID1),mdadm 可能会把部分设备添加为备用设备,而不在这些设备上存放数据。可以使用 {{ic|--grow}} 加上 {{ic|--raid-devices}} 选项来增加 RAID 利用的磁盘数量。例如,将一个阵列增加至四块硬盘:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices=4<br />
<br />
可以这样检查进度:<br />
<br />
# cat /proc/mdstat<br />
<br />
用这个命令检查已经添加的设备:<br />
<br />
# mdadm --misc --detail /dev/md0<br />
<br />
{{注意|对于 RAID0 设备可能会收到以下错误信息:<br />
<br />
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument<br />
<br />
这是由于上述命令会将新磁盘添加为 "spare"(备用)盘,但是 RAID0 中不存在备用盘。如果想往 RAID0 阵列中添加磁盘,你需要同时使用 "grow" 和 "add" 参数。如下所示:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices<nowiki>=</nowiki>3 --add /dev/sdc1<br />
<br />
}}<br />
<br />
=== 增大 RAID 卷的大小 ===<br />
<br />
如果给阵列安装了更大的磁盘,或者增大了分区大小,可能就需要增大 RAID 卷的大小以适应更大的可用空间。这一过程可用首先按照上文中关于更换磁盘的步骤来做。当 RAID 卷在更大的磁盘上重建完成后,这个卷需要 "grow" 来填充多出来的空间。<br />
<br />
# mdadm --grow /dev/md0 --size=max<br />
<br />
接着,在 RAID 卷 {{ic|/dev/md0}} 上的现有分区可能需要调整大小。参阅 [[Partitioning (简体中文)]] 获取更多信息。最后,上述分区上的文件系统也需要重新调整大小。如果用 {{ic|gparted}} 来完成分区操作,这些都会自动完成。如果用的是其他工具,请手动卸载 (unmount) 文件系统并调整其大小。<br />
<br />
# umount /storage<br />
# fsck.ext4 -f /dev/md0p1<br />
# resize2fs /dev/md0p1<br />
<br />
=== 修改同步速度限制 ===<br />
<br />
同步工作需要一定的时间。如果本机不需要完成其他任务,可以提高速度限制值。<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 0.0% (77696/155042219) finish=265.8min speed=9712K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
查看当前速度限制:<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_min|<br />
1000<br />
}}<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_max|<br />
200000<br />
}}<br />
<br />
提高限制值:<br />
<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_min<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_max<br />
<br />
然后查看同步速度和预计完成时间:<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 1.3% (2136640/155042219) finish=158.2min speed=16102K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
更多信息可参阅 [[sysctl#MDADM]]。<br />
<br />
== 监视运行情况 ==<br />
<br />
可以显示当前 RAID 设备状态的一行简单命令:<br />
<br />
{{hc|# awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat<br />
|md1: [UU]<br />
md0: [UU]<br />
}}<br />
<br />
=== 用 watch 监视 mdstat ===<br />
<br />
# watch -t 'cat /proc/mdstat'<br />
<br />
或者最好用 {{pkg|tmux}}<br />
<br />
# tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"<br />
<br />
=== 用 iotop 追踪 IO ===<br />
<br />
{{pkg|iotop}} 可以显示各个进程的输入输出状态。请用这个命令来查看 RAID 线程的输入输出。<br />
<br />
# iotop -a -p $(sed 's, , -p ,g' <<<`pgrep "_raid|_resync|jbd2"`)<br />
<br />
=== 用 iostat 追踪 IO ===<br />
<br />
{{Pkg|sysstat}} 包中的 ''iostat'' 实用程序可以显示各个设备和分区的输入输出统计。<br />
<br />
# iostat -dmy 1 /dev/md0<br />
# iostat -dmy 1 # all<br />
<br />
=== 启用事件邮件通知 ===<br />
<br />
要完成发送邮件的任务需要一个 smtp 邮件服务器或至少需要一个 ssmtp/msmtp 邮件转发器。大概最简单的解决方案是使用 {{AUR|dma}},它非常小巧(安装完只占用 0.08 MiB)且不需要设置。<br />
<br />
编辑 {{ic|/etc/mdadm.conf}} 来添加用于接收通知的邮件地址。<br />
<br />
{{注意|如果用的是上文提到的 dma,用户可以直接将邮件发送到本机 (localhost) 的某个用户名 (username) 中,不一定非要发到外部邮件地址。}}<br />
<br />
测试配置是否正确:<br />
<br />
# mdadm --monitor --scan --oneshot --test<br />
<br />
mdadm 使用 {{ic|mdmonitor.service}} 来完成监控任务,所以现在你无需进行更多设置了。如果你没有在 {{ic|/etc/mdadm.conf}} 设置邮件地址,那么这个 service 就会出错。如果你不想接收 mdadm 一般事件通知,可以忽略这个错误;如果不想接收一般事件通知但是需要接收故障信息,可以 [[Systemd (简体中文)#使用单元|mask(屏蔽)]] 这个 unit。<br />
<br />
==== 其他实现方式 ====<br />
<br />
为避免安装 smtp 邮件服务器或邮件转发器的麻烦,可以使用系统上已经安装的 [[S-nail]] 工具(不要忘了设置它)。<br />
<br />
创建 {{ic|/etc/mdadm_warning.sh}} 文件:<br />
<br />
{{hc|/etc/mdadm_warning.sh|<nowiki><br />
#!/bin/bash<br />
event=$1<br />
device=$2<br />
<br />
echo " " | /usr/bin/mailx -s "$event on $device" '''destination@email.com'''<br />
</nowiki>}}<br />
<br />
然后给它执行权限:{{ic|chmod +x /etc/mdadm_warning.sh}}<br />
<br />
然后在 mdadm.conf 中添加这一行:<br />
<br />
PROGRAM /etc/mdadm_warning.sh<br />
<br />
用前述的方法测试并启用它。<br />
<br />
== 故障排除 ==<br />
<br />
如果你在重启计算机时遇到类似 "invalid raid superblock magic" 的错误,并且除了已经配置好的硬盘外又接了其他硬盘,请检查硬盘顺序是不是正确的。在安装 RAID 时,硬盘编号可能是 hdd、hde 和 hdf,但是重启后它们的编号可能变成了 hda、hdb 和 hdc。请相应地调整你的内核参数。这种情况经常发生。<br />
<br />
=== Error: "kernel: ataX.00: revalidation failed" ===<br />
<br />
如果你突然(在重启、修改 BIOS 设置后)遇到类似错误信息:<br />
<br />
Feb 9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)<br />
<br />
这并不意味着设备已经损坏。尽管你可能会在网上看到一些讲内核崩溃的链接指向最坏的结果,但总而言之,并不是内核崩溃。可能你不知怎么的在 BIOS 里或内核参数里修改了 APIC 或 ACPI 设置。把它改回来就好了。通常关闭 APIC 和/或 ACPI 就好了。<br />
<br />
=== 磁盘阵列以只读模式启动 ===<br />
<br />
当由 md 启动磁盘阵列时,超级块将被改写,数据同步可能已经开始了。要以只读模式启动,可以向内核模块 {{ic|md_mod}} 传递参数 {{ic|start_ro}}。设置了这个参数以后,新的磁盘阵列进入 'auto-ro' 模式,该模式停止了所有内部读写操作(更新超级块、再同步、数据恢复),并且会在第一个写入请求到来时自动切换至 'rw' (读写)模式。<br />
<br />
{{注意|在第一个写入请求到来前使用 {{ic|mdadm --readonly}} 命令可以将阵列设置为真正的 'ro' (只读)模式,还可以用 {{ic|mdadm --readwrite}} 命令直接开始再同步而不用等待写入请求。}}<br />
<br />
要在启动时设置该参数,在内核启动参数中添加 {{ic|1=md_mod.start_ro=1}}。<br />
<br />
也可以在模块加载时传递该参数,可以从 {{ic|/etc/modprobe.d/}} 下的文件中传递,也可以直接从 {{ic|/sys/}} 传递:<br />
<br />
# echo 1 > /sys/module/md_mod/parameters/start_ro<br />
<br />
=== 在损坏或缺失磁盘的情况下恢复 RAID ===<br />
<br />
当磁盘阵列中的一个驱动器由于任何原因损坏时,也可能会发生上述错误。如果在缺失一块硬盘的情况下你仍需要强制启动磁盘阵列,输入以下命令(根据实际修改):<br />
<br />
# mdadm --manage /dev/md0 --run<br />
<br />
现在你应该可以用类似下面的命令来挂载它(如果在 fstab 里有它的话):<br />
<br />
# mount /dev/md0<br />
<br />
现在磁盘阵列应该已经工作并且可以使用,但仍旧是缺一块盘的状态。因此需要按照上文 [[#准备设备]] 所述再添加一个磁盘分区,然后就可以将新磁盘分区加入到磁盘阵列中:<br />
<br />
# mdadm --manage --add /dev/md0 /dev/sdd1<br />
<br />
如果输入:<br />
<br />
# cat /proc/mdstat<br />
<br />
你就能看到磁盘阵列已经激活并正在重建。<br />
<br />
你可能还需要更新你的配置文件(参阅:[[#更新配置文件]])。<br />
<br />
== 基准测试 ==<br />
<br />
用于 RAID 基准测试的工具有很多种。不同 RAID 最显著的不同是多个线程在读取 RAID 卷时的速度提升程度。<br />
<br />
{{AUR|tiobench}}{{Broken package link|package not found}} 通过测量磁盘的全线程读写 (fully-threaded I/O) 来专门测试多线程性能提升程度。<br />
<br />
{{Pkg|bonnie++}} 测试对一个或多个数据库类型文件的读写,以及对小文件的创建、读取、删除,这样可以模拟 Squid、INN 和 Maildir format e-mail 等程序的文件读写。其附带的 [http://www.coker.com.au/bonnie++/zcav/ ZCAV] 程序可以测试硬盘不同区域的性能,且不用向硬盘写入任何数据。<br />
<br />
'''不应该''' 使用 {{ic|hdparm}} 来对 RAID 进行基准测试,因为它多次返回的结果会非常不一致。<br />
<br />
== 参考资料 ==<br />
<br />
{{Out of date|许多链接太旧且无效。}}<br />
<br />
* [http://www.gentoo.org/doc/en/articles/software-raid-p1.xml Software RAID in the new Linux 2.4 kernel, Part 1]{{Dead link|2018|03|10}} and [http://www.gentoo.org/doc/en/articles/software-raid-p2.xml Part 2]{{Dead link|2018|03|10}} in the Gentoo Linux Docs<br />
* [http://raid.wiki.kernel.org/index.php/Linux_Raid Linux RAID wiki entry] on The Linux Kernel Archives<br />
* [https://raid.wiki.kernel.org/index.php/Write-intent_bitmap How Bitmaps Work]<br />
* [http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-raid.html Chapter 15: Redundant Array of Independent Disks (RAID)] of Red Hat Enterprise Linux 6 Documentation<br />
* [http://tldp.org/FAQ/Linux-RAID-FAQ/x37.html Linux-RAID FAQ] on the Linux Documentation Project<br />
* [http://support.dell.com/support/topics/global.aspx/support/entvideos/raid?c=us&l=en&s=gen Dell.com Raid Tutorial]{{Dead link|2018|03|10}} - Interactive Walkthrough of Raid<br />
* [http://www.miracleas.com/BAARF/ BAARF]{{Dead link|2018|03|10}} including ''[http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt Why should I not use RAID 5?]''{{Dead link|2018|03|10}} by Art S. Kagel<br />
* [http://www.linux-mag.com/id/7924/ Introduction to RAID], [http://www.linux-mag.com/id/7931/ Nested-RAID: RAID-5 and RAID-6 Based Configurations], [http://www.linux-mag.com/id/7928/ Intro to Nested-RAID: RAID-01 and RAID-10], and [http://www.linux-mag.com/id/7932/ Nested-RAID: The Triple Lindy] in Linux Magazine<br />
* [http://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html HowTo: Speed Up Linux Software Raid Building And Re-syncing]<br />
* [http://fomori.org/blog/?p=94 RAID5-Server to hold all your data]<br />
* [[Wikipedia:Non-RAID drive architectures]]<br />
<br />
'''mdadm'''<br />
* [http://anonscm.debian.org/gitweb/?p=pkg-mdadm/mdadm.git;a=blob_plain;f=debian/FAQ;hb=HEAD Debian mdadm FAQ]<br />
* [http://www.kernel.org/pub/linux/utils/raid/mdadm/ mdadm source code]<br />
* [http://www.linux-mag.com/id/7939/ Software RAID on Linux with mdadm] in Linux Magazine<br />
* [[Wikipedia:mdadm|Wikipedia - mdadm]]<br />
<br />
'''Forum threads'''<br />
* [http://forums.overclockers.com.au/showthread.php?t=865333 Raid Performance Improvements with bitmaps]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=125445 GRUB and GRUB2]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=123698 Can't install grub2 on software RAID]<br />
* [http://forums.gentoo.org/viewtopic-t-888624-start-0.html Use RAID metadata 1.2 in boot and root partition]<br />
<br />
'''RAID with encryption'''<br />
* [http://www.shimari.com/dm-crypt-on-raid/ Linux/Fedora: Encrypt /home and swap over RAID with dm-crypt] by Justin Wells</div>
Arisaka
https://wiki.archlinux.org/index.php?title=RAID&diff=539084
RAID
2018-09-01T03:03:55Z
<p>Arisaka: Fix Template:hc used on "/etc/mdadm_warning.sh"</p>
<hr />
<div>[[Category:Storage virtualization]]<br />
[[es:RAID]]<br />
[[it:RAID]]<br />
[[ja:RAID]]<br />
[[ru:RAID]]<br />
[[zh-hans:RAID]]<br />
{{Related articles start}}<br />
{{Related|Software RAID and LVM}}<br />
{{Related|LVM#RAID}}<br />
{{Related|Installing with Fake RAID}}<br />
{{Related|Convert a single drive system to RAID}}<br />
{{Related|ZFS}}<br />
{{Related|ZFS/Virtual disks}}<br />
{{Related|Swap#Striping}}<br />
{{Related|Btrfs#RAID}}<br />
{{Related articles end}}<br />
{{Style|Non-standard headers, other [[Help:Style]] issues}}<br />
<br />
Redundant Array of Independent Disks ([[Wikipedia:RAID|RAID]]) is a storage technology that combines multiple disk drive components (typically disk drives or partitions thereof) into a logical unit. Depending on the RAID implementation, this logical unit can be a file system or an additional transparent layer that can hold several partitions. Data is distributed across the drives in one of several ways called [[#RAID levels]], depending on the level of redundancy and performance required. The RAID level chosen can thus prevent data loss in the event of a hard disk failure, increase performance or be a combination of both.<br />
<br />
This article explains how to create/manage a software RAID array using mdadm.<br />
<br />
{{Warning|Be sure [[Backup programs|to back up]] all data before proceeding.}}<br />
<br />
== RAID levels ==<br />
<br />
Despite redundancy implied by most RAID levels, RAID does not guarantee that data is safe. A RAID will not protect data if there is a fire, the computer is stolen or multiple hard drives fail at once. Furthermore, installing a system with RAID is a complex process that may destroy data.<br />
<br />
=== Standard RAID levels ===<br />
<br />
There are many different [[Wikipedia:Standard RAID levels|levels of RAID]], please find hereafter the most commonly used ones.<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 0|RAID 0]]<br />
: Uses striping to combine disks. Even though it ''does not provide redundancy'', it is still considered RAID. It does, however, ''provide a big speed benefit''. If the speed increase is worth the possibility of data loss (for [[swap]] partition for example), choose this RAID level. On a server, RAID 1 and RAID 5 arrays are more appropriate. The size of a RAID 0 array block device is the size of the smallest component partition times the number of component partitions.<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 1|RAID 1]]<br />
: The most straightforward RAID level: straight mirroring. As with other RAID levels, it only makes sense if the partitions are on different physical disk drives. If one of those drives fails, the block device provided by the RAID array will continue to function as normal. The example will be using RAID 1 for everything except [[swap]] and temporary data. Please note that with a software implementation, the RAID 1 level is the only option for the boot partition, because bootloaders reading the boot partition do not understand RAID, but a RAID 1 component partition can be read as a normal partition. The size of a RAID 1 array block device is the size of the smallest component partition.<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 5|RAID 5]]<br />
: Requires 3 or more physical drives, and provides the redundancy of RAID 1 combined with the speed and size benefits of RAID 0. RAID 5 uses striping, like RAID 0, but also stores parity blocks ''distributed across each member disk''. In the event of a failed disk, these parity blocks are used to reconstruct the data on a replacement disk. RAID 5 can withstand the loss of one member disk.<br />
: {{Note|RAID 5 is a common choice due to its combination of speed and data redundancy. The caveat is that if one drive were to fail and another drive failed before that drive was replaced, all data will be lost. Furthermore, with modern disk sizes and expected unrecoverable read error (URE) rates on consumer disks, the rebuild of a 4TiB array is '''expected''' (i.e. higher than 50% chance) to have at least one URE. Because of this, RAID 5 is no longer advised by the storage industry.}}<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 6|RAID 6]]<br />
: Requires 4 or more physical drives, and provides the benefits of RAID 5 but with security against two drive failures. RAID 6 also uses striping, like RAID 5, but stores two distinct parity blocks ''distributed across each member disk''. In the event of a failed disk, these parity blocks are used to reconstruct the data on a replacement disk. RAID 6 can withstand the loss of two member disks. The robustness against unrecoverable read errors is somewhat better, because the array still has parity blocks when rebuilding from a single failed drive. However, given the overhead, RAID 6 is costly and in most settings RAID 10 in far2 layout (see below) provides better speed benefits and robustness, and is therefore preferred.<br />
<br />
=== Nested RAID levels ===<br />
<br />
; [[Wikipedia:Nested RAID levels#RAID 10 (RAID 1+0)|RAID 1+0]]<br />
: RAID1+0 is a nested RAID that combines two of the standard levels of RAID to gain performance and additional redundancy. It is commonly referred to as ''RAID10'', however, Linux MD RAID10 is slightly different from simple RAID layering, see below.<br />
<br />
; [[Wikipedia:Non-standard RAID levels#Linux MD RAID 10|RAID 10]]<br />
: RAID10 under Linux is built on the concepts of RAID1+0, however, it implements this as a single layer, with multiple possible layouts.<br />
: The ''near X'' layout on Y disks repeats each chunk X times on Y/2 stripes, but does not need X to divide Y evenly. The chunks are placed on almost the same location on each disk they are mirrored on, hence the name. It can work with any number of disks, starting at 2. Near 2 on 2 disks is equivalent to RAID1, near 2 on 4 disks to RAID1+0.<br />
: The ''far X'' layout on Y disks is designed to offer striped read performance on a mirrored array. It accomplishes this by dividing each disk in two sections, say front and back, and what is written to disk 1 front is mirrored in disk 2 back, and vice versa. This has the effect of being able to stripe sequential reads, which is where RAID0 and RAID5 get their performance from. The drawback is that sequential writing has a very slight performance penalty because of the distance the disk needs to seek to the other section of the disk to store the mirror. RAID10 in far 2 layout is, however, preferable to layered RAID1+0 '''and''' RAID5 whenever read speeds are of concern and availability / redundancy is crucial. However, it is still not a substitute for backups. See the wikipedia page for more information.<br />
<br />
=== RAID level comparison ===<br />
<br />
{| class="wikitable"<br />
! RAID level!!Data redundancy!!Physical drive utilization!!Read performance!!Write performance!!Min drives<br />
|-<br />
| '''0'''||{{No}}||100%||nX<br />
<br />
'''Best'''<br />
||nX<br />
<br />
'''Best'''<br />
||2<br />
|-<br />
| '''1'''||{{Yes}}||50%||Up to nX if multiple processes are reading, otherwise 1X<br />
||1X||2<br />
|-<br />
| '''5'''||{{Yes}}||67% - 94%||(n−1)X<br />
<br />
'''Superior'''<br />
||(n−1)X<br />
<br />
'''Superior'''<br />
||3<br />
|-<br />
| '''6'''||{{Yes}}||50% - 88%||(n−2)X||(n−2)X||4<br />
|-<br />
| '''10,far2'''||{{Yes}}||50%||nX<br />
'''Best;''' on par with RAID0 but redundant<br />
||(n/2)X||2<br />
|-<br />
| '''10,near2'''||{{Yes}}||50%||Up to nX if multiple processes are reading, otherwise 1X||(n/2)X||2<br />
|}<br />
<br />
<nowiki>*</nowiki> Where ''n'' is standing for the number of dedicated disks.<br />
<br />
== Implementation ==<br />
<br />
The RAID devices can be managed in different ways:<br />
<br />
; Software RAID<br />
: This is the easiest implementation as it does not rely on obscure proprietary firmware and software to be used. The array is managed by the operating system either by:<br />
:* by an abstraction layer (e.g. [[#Installation|mdadm]]); {{Note|This is the method we will use later in this guide.}}<br />
:* by a logical volume manager (e.g. [[LVM#RAID|LVM]]);<br />
:* by a component of a file system (e.g. [[ZFS]], [[Btrfs#RAID|Btrfs]]).<br />
<br />
; Hardware RAID<br />
: The array is directly managed by a dedicated hardware card installed in the PC to which the disks are directly connected. The RAID logic runs on an on-board processor independently of [[Wikipedia:Central processing unit|the host processor (CPU)]]. Although this solution is independent of any operating system, the latter requires a driver in order to function properly with the hardware RAID controller. The RAID array can either be configured via an option rom interface or, depending on the manufacturer, with a dedicated application when the OS has been installed. The configuration is transparent for the Linux kernel: it does not see the disks separately.<br />
<br />
; [[Fakeraid|FakeRAID]]<br />
: This type of RAID is properly called BIOS or Onboard RAID, but is falsely advertised as hardware RAID. The array is managed by pseudo-RAID controllers where the RAID logic is implemented in an option rom or in the firmware itself [http://www.win-raid.com/t19f13-Intel-EFI-RAID-quot-SataDriver-quot-BIOS-Modules.html with a EFI SataDriver] (in case of [[UEFI]]), but are not full hardware RAID controllers with ''all'' RAID features implemented. Therefore, this type of RAID is sometimes called FakeRAID. {{Pkg|dmraid}} from the [[official repositories]], will be used to deal with these controllers. Here are some examples of FakeRAID controllers: [[Wikipedia:Intel Rapid Storage Technology|Intel Rapid Storage]], JMicron JMB36x RAID ROM, AMD RAID, ASMedia 106x, and NVIDIA MediaShield.<br />
<br />
=== Which type of RAID do I have? ===<br />
<br />
Since software RAID is implemented by the user, the type of RAID is easily known to the user.<br />
<br />
However, discerning between FakeRAID and true hardware RAID can be more difficult. As stated, manufacturers often incorrectly distinguish these two types of RAID and false advertising is always possible. The best solution in this instance is to run the {{ic|lspci}} command and looking through the output to find the RAID controller. Then do a search to see what information can be located about the RAID controller. Hardware RAID controllers appear in this list, but FakeRAID implementations do not. Also, true hardware RAID controller are often rather expensive, so if someone customized the system, then it is very likely that choosing a hardware RAID setup made a very noticeable change in the computer's price.<br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|mdadm}}. ''mdadm'' is used for administering pure software RAID using plain block devices: the underlying hardware does not provide any RAID logic, just a supply of disks. ''mdadm'' will work with any collection of block devices. Even if unusual. For example, one can thus make a RAID array from a collection of thumb drives.<br />
<br />
=== Prepare the devices ===<br />
<br />
{{Warning|These steps erase everything on a device, so type carefully!}}<br />
<br />
If the device is being reused or re-purposed from an existing array, erase any old RAID configuration information:<br />
<br />
# mdadm --misc --zero-superblock /dev/<drive><br />
<br />
or if a particular partition on a drive is to be deleted:<br />
<br />
# mdadm --misc --zero-superblock /dev/<partition><br />
<br />
{{Note|<br />
* Zapping a partition's superblock should not affect the other partitions on the disk.<br />
* Due to the nature of RAID functionality it is very difficult to [[securely wipe disk]]s fully on a running array. Consider whether it is useful to do so before creating it.<br />
}}<br />
<br />
=== Partition the devices ===<br />
<br />
It is highly recommended to partition the disks to be used in the array. Since most RAID users are selecting disk drives larger than 2 TiB, GPT is required and recommended. See [[Partitioning]] for the more information on partitioning and the available [[partitioning tools]].<br />
<br />
{{Note|It is also possible to create a RAID directly on the raw disks (without partitions), but not recommended because it can cause problems when swapping a failed disk.}}<br />
<br />
{{Tip|When replacing a failed disk of a RAID, the new disk has to be exactly the same size as the failed disk or bigger — otherwise the array recreation process will not work. Even hard drives of the same manufacturer and model can have small size differences. By leaving a little space at the end of the disk unallocated one can compensate for the size differences between drives, which makes choosing a replacement drive model easier. Therefore, it is good practice to leave about 100 MiB of unallocated space at the end of the disk.}}<br />
<br />
==== GUID Partition Table ====<br />
<br />
* After creating the partitions, their [[Wikipedia:GUID Partition Table#Partition type GUIDs|partition type GUIDs]] should be {{ic|A19D880F-05FC-4D3B-A006-743F0F84911E}} (it can be assigned by selecting partition type {{ic|Linux RAID}} in ''fdisk'' or {{ic|FD00}} in ''gdisk'').<br />
* If a larger disk array is employed, consider assigning [[Persistent block device naming#by-label|filesystem labels]] or [[Persistent block device naming#by-partlabel|partition labels]] to make it easier to identify an individual disk later.<br />
* Creating partitions that are of the same size on each of the devices is recommended.<br />
<br />
==== Master Boot Record ====<br />
<br />
For those creating partitions on HDDs with a MBR partition table, the [[Wikipedia:Partition type|partition types IDs]] available for use are:<br />
<br />
* {{ic|0xFD}} for raid autodetect arrays ({{ic|Linux raid autodetect}} in ''fdisk'')<br />
* {{ic|0xDA}} for non-fs data ({{ic|Non-FS data}} in ''fdisk'')<br />
<br />
See [https://raid.wiki.kernel.org/index.php/Partition_Types Linux Raid Wiki:Partition Types] for more information.<br />
<br />
=== Build the array ===<br />
<br />
Use {{ic|mdadm}} to build the array. See {{man|8|mdadm}} for supported options. Several examples are given below.<br />
<br />
{{Warning|Do not simply copy/paste the examples below; make sure you use substitute the correct options and drive letters.}}<br />
<br />
{{Note|<br />
* If this is a RAID1 array which is intended to boot from [[Syslinux]] a limitation in syslinux v4.07 requires the metadata value to be 1.0 rather than the default of 1.2.<br />
* When creating an array from [[Archiso|Arch installation medium]] use the option {{ic|1=--homehost=''myhostname''}} (or {{ic|1=--homehost=any}} to always have the same name regardless of the host) to set the [[hostname]], otherwise the hostname {{ic|archiso}} will be written in the array metadata.<br />
}}<br />
<br />
{{Tip|You can specify a custom raid device name using the option {{ic|1=--name=''MyRAIDName''}} or by setting the raid device path to {{ic|/dev/md/''MyRAIDName''}}. Udev will create symlinks to the raid arrays in {{ic|/dev/md/}} using that name. If {{ic|homehost}} matches the current [[hostname]] (or if homehost is set to {{ic|any}}) the link will be {{ic|/dev/md/''name''}}, if the hostname does not match the link be {{ic|/dev/md/''homehost'':''name''}}.}}<br />
<br />
The following example shows building a 2-device RAID1 array:<br />
<br />
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1<br />
<br />
The following example shows building a RAID5 array with 4 active devices and 1 spare device:<br />
<br />
# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1<br />
<br />
{{Tip|{{ic|--chunk}} is used to change the chunk size from the default value. See [http://www.zdnet.com/article/chunks-the-hidden-key-to-raid-performance/ Chunks: the hidden key to RAID performance] for more on chunk size optimisation.}}<br />
<br />
The following example shows building a RAID10,far2 array with 2 devices:<br />
<br />
# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1<br />
<br />
The array is created under the virtual device {{ic|/dev/mdX}}, assembled and ready to use (in degraded mode). One can directly start using it while mdadm resyncs the array in the background. It can take a long time to restore parity. Check the progress with:<br />
<br />
$ cat /proc/mdstat<br />
<br />
=== Update configuration file ===<br />
<br />
By default, most of {{ic|mdadm.conf}} is commented out, and it contains just the following:<br />
<br />
{{hc|/etc/mdadm.conf|<br />
...<br />
DEVICE partitions<br />
...<br />
}}<br />
<br />
This directive tells mdadm to examine the devices referenced by {{ic|/proc/partitions}} and assemble as many arrays as possible. This is fine if you really do want to start all available arrays and are confident that no unexpected superblocks will be found (such as after installing a new storage device). A more precise approach is to explicitly add the arrays to {{ic|/etc/mdadm.conf}}:<br />
<br />
# mdadm --detail --scan >> /etc/mdadm.conf<br />
<br />
This results in something like the following:<br />
<br />
{{hc|/etc/mdadm.conf|2=<br />
...<br />
DEVICE partitions<br />
...<br />
ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe<br />
}}<br />
<br />
This also causes mdadm to examine the devices referenced by {{ic|/proc/partitions}}. However, only devices that have superblocks with a UUID of {{ic|27664…}} are assembled in to active arrays.<br />
<br />
See {{man|5|mdadm.conf}} for more information.<br />
<br />
=== Assemble the array ===<br />
<br />
Once the configuration file has been updated the array can be assembled using mdadm:<br />
<br />
# mdadm --assemble --scan<br />
<br />
=== Format the RAID filesystem ===<br />
<br />
The array can now be formatted with a [[file system]] like any other partition, just keep in mind that:<br />
<br />
* Due to the large volume size not all filesystems are suited (see: [[Wikipedia:Comparison of file systems#Limits]]).<br />
* The filesystem should support growing and shrinking while online (see: [[Wikipedia:Comparison of file systems#Features]]).<br />
* One should calculate the correct stride and stripe-width for optimal performance.<br />
<br />
==== Calculating the stride and stripe width ====<br />
<br />
Two parameters are required to optimise the filesystem structure to fit optimally within the underlying RAID structure: the ''stride'' and ''stripe width''. These are derived from the RAID ''chunk size'', the filesystem ''block size'', and the ''number of "data disks"''.<br />
<br />
The chunk size is a property of the RAID array, decided at the time of its creation. {{ic|mdadm}}'s current default is 512 KiB. It can be found with {{ic|mdadm}}:<br />
<br />
# mdadm --detail /dev/mdX | grep 'Chunk Size'<br />
<br />
The block size is a property of the filesystem, decided at ''its'' creation. The default for many filesystems, including ext4, is 4 KiB. See {{ic|/etc/mke2fs.conf}} for details on ext4.<br />
<br />
The number of "data disks" is the minimum number of devices in the array required to completely rebuild it without data loss. For example, this is N for a raid0 array of N devices and N-1 for raid5.<br />
<br />
Once you have these three quantities, the stride and the stripe width can be calculated using the following formulas:<br />
<br />
stride = chunk size / block size<br />
stripe width = number of data disks * stride<br />
<br />
===== Example 1. RAID0 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
<br />
* Hypothetical RAID0 array is composed of 2 physical disks.<br />
* Chunk size is 64 KiB.<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size. In this example, the math is 64/4 so the stride = 16.<br />
<br />
stripe width = # of physical '''data''' disks * stride. In this example, the math is 2*16 so the stripe width = 32.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.5 -b 4096 -E stride=16,stripe-width=32 /dev/md0<br />
<br />
===== Example 2. RAID5 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
<br />
* Hypothetical RAID5 array is composed of 4 physical disks; 3 data discs and 1 parity disc.<br />
* Chunk size is 512 KiB.<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size. In this example, the math is 512/4 so the stride = 128.<br />
<br />
stripe width = # of physical '''data''' disks * stride. In this example, the math is 3*128 so the stripe width = 384.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=384 /dev/md0<br />
<br />
For more on stride and stripe width, see: [http://wiki.centos.org/HowTos/Disk_Optimization RAID Math].<br />
<br />
===== Example 3. RAID10,far2 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
<br />
* Hypothetical RAID10 array is composed of 2 physical disks. Because of the properties of RAID10 in far2 layout, both count as data disks.<br />
* Chunk size is 512 KiB.<br />
<br />
{{hc|# mdadm --detail /dev/md0 {{!}} grep 'Chunk Size'|<br />
Chunk Size : 512K<br />
}}<br />
<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size.<br />
In this example, the math is 512/4 so the stride = 128.<br />
<br />
stripe width = # of physical '''data''' disks * stride.<br />
In this example, the math is 2*128 so the stripe width = 256.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/md0<br />
<br />
== Mounting from a Live CD ==<br />
<br />
Users wanting to mount the RAID partition from a Live CD, use:<br />
<br />
# mdadm --assemble /dev/<disk1> /dev/<disk2> /dev/<disk3> /dev/<disk4><br />
<br />
If your RAID 1 that is missing a disk array was wrongly auto-detected as RAID 1 (as per {{ic|mdadm --detail /dev/md<number>}}) and reported as inactive (as per {{ic|cat /proc/mdstat}}), stop the array first:<br />
<br />
# mdadm --stop /dev/md<number><br />
<br />
== Installing Arch Linux on RAID ==<br />
<br />
{{Note|The following section is applicable only if the root filesystem resides on the array. Users may skip this section if the array holds a data partition(s).}}<br />
<br />
You should create the RAID array between the [[Partitioning]] and [[File systems#Create a file system|formatting]] steps of the Installation Procedure. Instead of directly formatting a partition to be your root file system, it will be created on a RAID array.<br />
Follow the section [[#Installation]] to create the RAID array. Then continue with the installation procedure until the pacstrap step is completed.<br />
When using [[Unified Extensible Firmware Interface|UEFI boot]], also read [[EFI system partition#ESP on RAID]].<br />
<br />
=== Update configuration file ===<br />
<br />
{{Note|This should be done outside of the chroot, hence the prefix {{ic|/mnt}} to the filepath.}}<br />
<br />
After the base system is installed the default configuration file, {{ic|mdadm.conf}}, must be updated like so:<br />
<br />
# mdadm --detail --scan >> /mnt/etc/mdadm.conf<br />
<br />
Always check the {{ic|mdadm.conf}} configuration file using a text editor after running this command to ensure that its contents look reasonable.<br />
<br />
{{Note|To prevent failure of {{ic|mdmonitor.service}} at boot (enabled by default), you will need to uncomment {{ic|MAILADDR}} and provide an e-mail address and/or application to handle notification of problems with your array at the bottom of {{ic|mdadm.conf}}. See [[#Mailing on events]].}}<br />
<br />
Continue with the installation procedure until you reach the step [[Installation guide#Initramfs]], then follow the next section.<br />
<br />
=== Configure mkinitcpio ===<br />
<br />
{{Note|This should be done whilst chrooted.}}<br />
<br />
Add {{ic|mdadm_udev}} to the [[mkinitcpio#HOOKS|HOOKS]] section of the {{ic|mkinitcpio.conf}} to add support for mdadm into the initramfs image:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
HOOKS=(base udev autodetect keyboard modconf block '''mdadm_udev''' filesystems fsck)<br />
...<br />
}}<br />
<br />
If you use the {{ic|mdadm_udev}} hook with a FakeRAID array, it is recommended to include ''mdmon'' in the [[mkinitcpio#BINARIES and FILES|BINARIES]] array:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
BINARIES=('''mdmon''')<br />
...<br />
}}<br />
<br />
Then [[Regenerate the initramfs]].<br />
<br />
See also [[mkinitcpio#Using RAID]].<br />
<br />
=== Configure the boot loader ===<br />
<br />
Point the {{ic|root}} parameter to the mapped device. E.g.:<br />
<br />
root=/dev/md/''MyRAIDArray''<br />
<br />
If booting from a software raid partition fails using the kernel device node method above, an alternative way is to use one of the methods from [[Persistent block device naming]], for example:<br />
<br />
root=LABEL=Root_Label<br />
<br />
See also [[GRUB#RAID]].<br />
<br />
== RAID Maintenance ==<br />
<br />
=== Scrubbing ===<br />
<br />
It is good practice to regularly run data [[wikipedia:Data_scrubbing|scrubbing]] to check for and fix errors. Depending on the size/configuration of the array, a scrub may take multiple hours to complete.<br />
<br />
To initiate a data scrub:<br />
<br />
# echo check > /sys/block/md0/md/sync_action<br />
<br />
The check operation scans the drives for bad sectors and automatically repairs them. If it finds good sectors that contain bad data (the data in a sector does not agree with what the data from another disk indicates that it should be, for example the parity block + the other data blocks would cause us to think that this data block is incorrect), then no action is taken, but the event is logged (see below). This "do nothing" allows admins to inspect the data in the sector and the data that would be produced by rebuilding the sectors from redundant information and pick the correct data to keep.<br />
<br />
As with many tasks/items relating to mdadm, the status of the scrub can be queried by reading {{ic|/proc/mdstat}}.<br />
<br />
Example:<br />
<br />
{{hc|$ cat /proc/mdstat|<nowiki><br />
Personalities : [raid6] [raid5] [raid4] [raid1]<br />
md0 : active raid1 sdb1[0] sdc1[1]<br />
3906778112 blocks super 1.2 [2/2] [UU]<br />
[>....................] check = 4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec<br />
bitmap: 0/30 pages [0KB], 65536KB chunk<br />
</nowiki>}}<br />
<br />
To stop a currently running data scrub safely:<br />
<br />
# echo idle > /sys/block/md0/md/sync_action<br />
<br />
{{Note|If the system is rebooted after a partial scrub has been suspended, the scrub will start over.}}<br />
<br />
When the scrub is complete, admins may check how many blocks (if any) have been flagged as bad:<br />
<br />
# cat /sys/block/md0/md/mismatch_cnt<br />
<br />
==== General notes on scrubbing ====<br />
<br />
{{Note|Users may alternatively echo '''repair''' to {{ic|/sys/block/md0/md/sync_action}} but this is ill-advised since if a mismatch in the data is encountered, it would be automatically updated to be consistent. The danger is that we really do not know whether it is the parity or the data block that is correct (or which data block in case of RAID1). It is luck-of-the-draw whether or not the operation gets the right data instead of the bad data.}}<br />
<br />
It is a good idea to set up a cron job as root to schedule a periodic scrub. See {{AUR|raid-check}} which can assist with this. To perform a periodic scrub using systemd timers instead of cron, See {{AUR|raid-check-systemd}} which contains the same script along with associated systemd timer unit files.<br />
<br />
{{Note|For typical platter drives, scrubbing can take approximately '''six seconds per gigabyte''' (that is one hour forty-five minutes per terabyte) so plan the start of your cron job or timer appropriately.}}<br />
<br />
==== RAID1 and RAID10 notes on scrubbing ====<br />
<br />
Due to the fact that RAID1 and RAID10 writes in the kernel are unbuffered, an array can have non-0 mismatch counts even when the array is healthy. These non-0 counts will only exist in transient data areas where they do not pose a problem. However, we cannot tell the difference between a non-0 count that is just in transient data or a non-0 count that signifies a real problem. This fact is a source of false positives for RAID1 and RAID10 arrays. It is however still recommended to scrub regularly in order to catch and correct any bad sectors that might be present in the devices.<br />
<br />
=== Removing devices from an array ===<br />
<br />
One can remove a device from the array after marking it as faulty:<br />
<br />
# mdadm --fail /dev/md0 /dev/sdxx<br />
<br />
Now remove it from the array:<br />
<br />
# mdadm --remove /dev/md0 /dev/sdxx<br />
<br />
Remove device permanently (for example, to use it individually from now on):<br />
Issue the two commands described above then:<br />
<br />
# mdadm --zero-superblock /dev/sdxx<br />
<br />
{{Warning|<br />
* Do not issue this command on linear or RAID0 arrays or data loss will occur!<br />
* Reusing the removed disk without zeroing the superblock will cause loss of all data on the next boot. (After mdadm will try to use it as the part of the raid array).<br />
}}<br />
<br />
Stop using an array:<br />
<br />
# Umount target array<br />
# Stop the array with: {{ic|mdadm --stop /dev/md0}}<br />
# Repeat the three command described in the beginning of this section on each device.<br />
# Remove the corresponding line from {{ic|/etc/mdadm.conf}}.<br />
<br />
=== Adding a new device to an array ===<br />
<br />
Adding new devices with mdadm can be done on a running system with the devices mounted.<br />
Partition the new device using the same layout as one of those already in the arrays as discussed above.<br />
<br />
Assemble the RAID array if it is not already assembled:<br />
<br />
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1<br />
<br />
Add the new device the array:<br />
<br />
# mdadm --add /dev/md0 /dev/sdc1<br />
<br />
This should not take long for mdadm to do. <br />
<br />
Depending on the type of RAID (for example, with RAID1), mdadm may add the device as a spare without syncing data to it. You can increase the number of disks the RAID uses by using {{ic|--grow}} with the {{ic|--raid-devices}} option. For example, to increase an array to four disks:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices=4<br />
<br />
You can check the progress with:<br />
<br />
# cat /proc/mdstat<br />
<br />
Check that the device has been added with the command:<br />
<br />
# mdadm --misc --detail /dev/md0<br />
<br />
{{Note|For RAID0 arrays you may get the following error message:<br />
<br />
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument<br />
<br />
This is because the above commands will add the new disk as a "spare" but RAID0 does not have spares. If you want to add a device to a RAID0 array, you need to "grow" and "add" in the same command. This is demonstrated below:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices<nowiki>=</nowiki>3 --add /dev/sdc1<br />
<br />
}}<br />
<br />
=== Increasing size of a RAID volume ===<br />
<br />
If larger disks are installed in a RAID array or partition size has been increased, it may be desirable to increase the size of the RAID volume to fill the larger available space. This process may be begun by first following the above sections pertaining to replacing disks. Once the RAID volume has been rebuilt onto the larger disks it must be "grown" to fill the space.<br />
<br />
# mdadm --grow /dev/md0 --size=max<br />
<br />
Next, partitions present on the RAID volume {{ic|/dev/md0}} may need to be resized. See [[Partitioning]] for details. Finally, the filesystem on the above mentioned partition will need to be resized. If partitioning was performed with {{ic|gparted}} this will be done automatically. If other tools were used, unmount and then resize the filesystem manually.<br />
<br />
# umount /storage<br />
# fsck.ext4 -f /dev/md0p1<br />
# resize2fs /dev/md0p1<br />
<br />
=== Change sync speed limits ===<br />
<br />
Syncing can take a while. If the machine is not needed for other tasks the speed limit can be increased.<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 0.0% (77696/155042219) finish=265.8min speed=9712K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
Check the current speed limit.<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_min|<br />
1000<br />
}}<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_max|<br />
200000<br />
}}<br />
<br />
Increase the limits.<br />
<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_min<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_max<br />
<br />
Then check out the syncing speed and estimated finish time.<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 1.3% (2136640/155042219) finish=158.2min speed=16102K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
See also [[sysctl#MDADM]].<br />
<br />
== Monitoring ==<br />
<br />
A simple one-liner that prints out the status of the RAID devices:<br />
<br />
{{hc|# awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat<br />
|md1: [UU]<br />
md0: [UU]<br />
}}<br />
<br />
=== Watch mdstat ===<br />
<br />
# watch -t 'cat /proc/mdstat'<br />
<br />
Or preferably using {{pkg|tmux}}<br />
<br />
# tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"<br />
<br />
=== Track IO with iotop ===<br />
<br />
The {{pkg|iotop}} package displays the input/output stats for processes. Use this command to view the IO for raid threads.<br />
<br />
# iotop -a -p $(sed 's, , -p ,g' <<<`pgrep "_raid|_resync|jbd2"`)<br />
<br />
=== Track IO with iostat ===<br />
<br />
The ''iostat'' utility from {{Pkg|sysstat}} package displays the input/output statistics for devices and partitions.<br />
<br />
# iostat -dmy 1 /dev/md0<br />
# iostat -dmy 1 # all<br />
<br />
=== Mailing on events ===<br />
<br />
A smtp mail server (sendmail) or at least an email forwarder (ssmtp/msmtp) is required to accomplish this. Perhaps the most simplistic solution is to use {{AUR|dma}} which is very tiny (installs to 0.08 MiB) and requires no setup.<br />
<br />
Edit {{ic|/etc/mdadm.conf}} defining the email address to which notifications will be received.<br />
<br />
{{Note|If using dma as mentioned above, users may simply mail directly to the username on the localhost rather than to an external email address.}}<br />
<br />
To test the configuration:<br />
<br />
# mdadm --monitor --scan --oneshot --test<br />
<br />
mdadm includes {{ic|mdmonitor.service}} to perform the monitoring task, so at this point, you have nothing left to do. If you do not set a mail address in {{ic|/etc/mdadm.conf}}, that service will fail. If you do not want to receive mail on mdadm events, the failure can be ignored; if you do not want notifications and are sensitive about failure messages, you can [[mask]] the unit.<br />
<br />
==== Alternative method ====<br />
<br />
To avoid the installation of a smtp mail server or an email forwarder you can use the [[S-nail]] tool (do not forget to setup) already on your system.<br />
<br />
Create a file named {{ic|/etc/mdadm_warning.sh}}:<br />
<br />
{{hc|/etc/mdadm_warning.sh|<nowiki><br />
#!/bin/bash<br />
event=$1<br />
device=$2<br />
<br />
echo " " | /usr/bin/mailx -s "$event on $device" '''destination@email.com'''<br />
</nowiki>}}<br />
<br />
And give it execution permissions {{ic|chmod +x /etc/mdadm_warning.sh}}<br />
<br />
Then add this to the mdadm.conf<br />
<br />
PROGRAM /etc/mdadm_warning.sh<br />
<br />
To test and enable use the same as in the previous method.<br />
<br />
== Troubleshooting ==<br />
<br />
If you are getting error when you reboot about "invalid raid superblock magic" and you have additional hard drives other than the ones you installed to, check that your hard drive order is correct. During installation, your RAID devices may be hdd, hde and hdf, but during boot they may be hda, hdb and hdc. Adjust your kernel line accordingly. This is what happened to me anyway.<br />
<br />
=== Error: "kernel: ataX.00: revalidation failed" ===<br />
<br />
If you suddenly (after reboot, changed BIOS settings) experience Error messages like:<br />
<br />
Feb 9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)<br />
<br />
Is does not necessarily mean that a drive is broken. You often find panic links on the web which go for the worst. In a word, No Panic. Maybe you just changed APIC or ACPI settings within your BIOS or Kernel parameters somehow. Change them back and you should be fine. Ordinarily, turning ACPI and/orACPI off should help.<br />
<br />
=== Start arrays read-only ===<br />
<br />
When an md array is started, the superblock will be written, and resync may begin. To start read-only set the kernel module {{ic|md_mod}} parameter {{ic|start_ro}}. When this is set, new arrays get an 'auto-ro' mode, which disables all internal io (superblock updates, resync, recovery) and is automatically switched to 'rw' when the first write request arrives.<br />
<br />
{{Note|The array can be set to true 'ro' mode using {{ic|mdadm --readonly}} before the first write request, or resync can be started without a write using {{ic|mdadm --readwrite}}.}}<br />
<br />
To set the parameter at boot, add {{ic|1=md_mod.start_ro=1}} to your kernel line.<br />
<br />
Or set it at module load time from {{ic|/etc/modprobe.d/}} file or from directly from {{ic|/sys/}}:<br />
<br />
# echo 1 > /sys/module/md_mod/parameters/start_ro<br />
<br />
=== Recovering from a broken or missing drive in the raid ===<br />
<br />
You might get the above mentioned error also when one of the drives breaks for whatever reason. In that case you will have to force the raid to still turn on even with one disk short. Type this (change where needed):<br />
<br />
# mdadm --manage /dev/md0 --run<br />
<br />
Now you should be able to mount it again with something like this (if you had it in fstab):<br />
<br />
# mount /dev/md0<br />
<br />
Now the raid should be working again and available to use, however with one disk short! So, to add that one disc partition it the way like described above in [[#Prepare the devices]]. Once that is done you can add the new disk to the raid by doing:<br />
<br />
# mdadm --manage --add /dev/md0 /dev/sdd1<br />
<br />
If you type:<br />
<br />
# cat /proc/mdstat<br />
<br />
you probably see that the raid is now active and rebuilding.<br />
<br />
You also might want to update your configuration (see: [[#Update configuration file]]).<br />
<br />
== Benchmarking ==<br />
<br />
There are several tools for benchmarking a RAID. The most notable improvement is the speed increase when multiple threads are reading from the same RAID volume.<br />
<br />
{{AUR|tiobench}}{{Broken package link|package not found}} specifically benchmarks these performance improvements by measuring fully-threaded I/O on the disk.<br />
<br />
{{Pkg|bonnie++}} tests database type access to one or more files, and creation, reading, and deleting of small files which can simulate the usage of programs such as Squid, INN, or Maildir format e-mail. The enclosed [http://www.coker.com.au/bonnie++/zcav/ ZCAV] program tests the performance of different zones of a hard drive without writing any data to the disk.<br />
<br />
{{ic|hdparm}} should '''NOT''' be used to benchmark a RAID, because it provides very inconsistent results.<br />
<br />
== See also ==<br />
<br />
{{Out of date|A lot of old and dead links.}}<br />
<br />
* [http://www.gentoo.org/doc/en/articles/software-raid-p1.xml Software RAID in the new Linux 2.4 kernel, Part 1]{{Dead link|2018|03|10}} and [http://www.gentoo.org/doc/en/articles/software-raid-p2.xml Part 2]{{Dead link|2018|03|10}} in the Gentoo Linux Docs<br />
* [http://raid.wiki.kernel.org/index.php/Linux_Raid Linux RAID wiki entry] on The Linux Kernel Archives<br />
* [https://raid.wiki.kernel.org/index.php/Write-intent_bitmap How Bitmaps Work]<br />
* [http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-raid.html Chapter 15: Redundant Array of Independent Disks (RAID)] of Red Hat Enterprise Linux 6 Documentation<br />
* [http://tldp.org/FAQ/Linux-RAID-FAQ/x37.html Linux-RAID FAQ] on the Linux Documentation Project<br />
* [http://support.dell.com/support/topics/global.aspx/support/entvideos/raid?c=us&l=en&s=gen Dell.com Raid Tutorial]{{Dead link|2018|03|10}} - Interactive Walkthrough of Raid<br />
* [http://www.miracleas.com/BAARF/ BAARF]{{Dead link|2018|03|10}} including ''[http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt Why should I not use RAID 5?]''{{Dead link|2018|03|10}} by Art S. Kagel<br />
* [http://www.linux-mag.com/id/7924/ Introduction to RAID], [http://www.linux-mag.com/id/7931/ Nested-RAID: RAID-5 and RAID-6 Based Configurations], [http://www.linux-mag.com/id/7928/ Intro to Nested-RAID: RAID-01 and RAID-10], and [http://www.linux-mag.com/id/7932/ Nested-RAID: The Triple Lindy] in Linux Magazine<br />
* [http://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html HowTo: Speed Up Linux Software Raid Building And Re-syncing]<br />
* [http://fomori.org/blog/?p=94 RAID5-Server to hold all your data]<br />
* [[Wikipedia:Non-RAID drive architectures]]<br />
<br />
'''mdadm'''<br />
* [http://anonscm.debian.org/gitweb/?p=pkg-mdadm/mdadm.git;a=blob_plain;f=debian/FAQ;hb=HEAD Debian mdadm FAQ]<br />
* [http://www.kernel.org/pub/linux/utils/raid/mdadm/ mdadm source code]<br />
* [http://www.linux-mag.com/id/7939/ Software RAID on Linux with mdadm] in Linux Magazine<br />
* [[Wikipedia:mdadm|Wikipedia - mdadm]]<br />
<br />
'''Forum threads'''<br />
* [http://forums.overclockers.com.au/showthread.php?t=865333 Raid Performance Improvements with bitmaps]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=125445 GRUB and GRUB2]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=123698 Can't install grub2 on software RAID]<br />
* [http://forums.gentoo.org/viewtopic-t-888624-start-0.html Use RAID metadata 1.2 in boot and root partition]<br />
<br />
'''RAID with encryption'''<br />
* [http://www.shimari.com/dm-crypt-on-raid/ Linux/Fedora: Encrypt /home and swap over RAID with dm-crypt] by Justin Wells</div>
Arisaka
https://wiki.archlinux.org/index.php?title=RAID_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539083
RAID (简体中文)
2018-09-01T02:53:45Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:Storage virtualization (简体中文)]]<br />
[[en:RAID]]<br />
[[es:RAID]]<br />
[[it:RAID]]<br />
[[ja:RAID]]<br />
[[ru:RAID]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Software RAID and LVM}}<br />
{{Related|LVM#RAID}}<br />
{{Related|Installing with Fake RAID}}<br />
{{Related|Convert a single drive system to RAID}}<br />
{{Related|ZFS}}<br />
{{Related|ZFS/Virtual disks}}<br />
{{Related|Swap#Striping}}<br />
{{Related|Btrfs (简体中文)#RAID}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|RAID|2018-09-01|533662}}<br />
{{Style|Non-standard headers, other [[Help:Style]] issues}}<br />
<br />
独立磁盘冗余阵列 (Redundant Array of Independent Disks, [[Wikipedia:RAID|RAID]]) 是一种将多个磁盘驱动器组件(通常是多块硬盘或多个分区)组合为一个逻辑单元的存储技术。根据 RAID 的部署情况,这个逻辑单元可以是单个的文件系统,也可以是一个能在其上建立多个分区的透明中间层。根据所需的冗余量和性能要求,数据按照 [[#RAID 级别]] 中的某一种方式分布在驱动器中。所选的 RAID 级别决定了是否可以防止数据丢失(硬盘故障时)、是否提高性能或结合两者优势。<br />
<br />
本文介绍如何使用 mdadm 创建并管理一个软件磁盘阵列。<br />
<br />
{{警告|确保在操作前 [[Backup programs|备份]] 所有数据。}}<br />
<br />
== RAID 级别 ==<br />
<br />
尽管大部分 RAID 级别都或多或少地包含了数据冗余,RAID 并不能完全保证数据安全。如果遇到火灾、计算机被盗或者多块硬盘同时损坏,RAID 将无法保护数据。此外,配置一个带有 RAID 的系统是一个复杂的过程,可能会破坏现有数据。<br />
<br />
=== 基本 RAID 级别 ===<br />
<br />
有多种不同的 [[Wikipedia:Standard RAID levels|基本 RAID 级别]],下面列出了最常用的几种。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 0|RAID 0]]<br />
: 将多块硬盘组合为一个带区卷,尽管它 ''并不提供数据冗余'',它仍可以被当做是 RAID,而且它确实提供了 ''巨幅的速度提升''。如果提高速度比数据安全更重要(比如作为 [[swap]] 分区),可以选择这种 RAID 级别。在服务器上,RAID 1 和 RAID 5 阵列更加合适。在 RAID 0 阵列中,块设备的大小是最小组成分区的大小乘以组成分区的数量。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 1|RAID 1]]<br />
: 这是最直接的 RAID 级别:完全镜像。与其他 RAID 级别一样,它只在分区位于不同物理硬盘上才有效。如果某一块硬盘损坏,由 RAID 阵列提供的块设备将不受影响。可以使用 RAID 1 的情境包括了除 [[swap]] 和临时文件外的其他所有情境。请注意,如果使用由软件实现的 RAID,引导分区只能选择 RAID 1,因为读取引导分区的引导器通常无法辨识 RAID,但一个 RAID 1 的组成分区可以像常规分区一样读取。RAID 1 阵列块设备的大小是最小组成分区的大小。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 5|RAID 5]]<br />
: 需要至少 3 块物理硬盘,并结合了 RAID 1 的数据冗余和 RAID 0 的速度与可用空间上的优势。RAID 5 使用了类似 RAID 0 的条带化技术,同时也将奇偶校验块''分布式地存储在每一块磁盘上''。如果遭遇硬盘损坏,这些奇偶校验块就可以用来在替代的新磁盘上重建损坏的数据。RAID 5 仅可弥补一个组成磁盘损坏带来的损失。<br />
: {{注意|RAID 5 是结合了速度与数据冗余优势的常用选择。但值得注意的是,当一块硬盘损坏而没有及时更换,此时若再有硬盘损坏,则所有数据都将丢失。此外,考虑到现代磁盘的超大容量和消费级硬盘无法恢复的读取错误率 (Unrecoverable read error, URE),超过 4TiB 的阵列在重建数据时出现至少一处读取错误 (URE) 的概率几乎在'''预料之中'''(概率大于 50%)。因此,存储行业不再推荐使用 RAID 5。}}<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 6|RAID 6]]<br />
: 需要至少 4 块物理硬盘,提供了和 RAID 5 一样的优势并且在两块硬盘损坏时仍能保证数据安全。RAID 6 使用了和 RAID 5 类似的条带化技术,但是把两个不同的奇偶校验块 ''分布式地存储在每一块磁盘上''。如果磁盘发生故障,这些奇偶校验块将用于重建替换磁盘上的数据。RAID 6 可以承担两个组成磁盘的损失。在抵御无法恢复的读取错误 (Unrecoverable read error, URE) 时也某种程度上更加可靠,因为磁盘阵列在重建某一块损坏硬盘的数据时仍然有奇偶校验块可以校验数据。但是,总体而言,RAID 6 开销较大,大多数时候 far2 布局的 RAID 10(参见下文)提供了更快的速度和更强的可靠性,因此更倾向于采用 RAID 10。<br />
<br />
=== 嵌套 RAID 级别 ===<br />
<br />
; [[Wikipedia:Nested RAID levels#RAID 10 (RAID 1+0)|RAID 1+0]]<br />
: RAID1+0 是一种结合了两种基本 RAID 级别的嵌套级别,它相对基本级别提高了性能且增加了冗余量。它通常被称为 ''RAID10'',但是,Linux MD(内核自带的 RAID 实现)支持的 RAID10 不是简单的两层 RAID 重叠,请看下文。<br />
<br />
; [[Wikipedia:Non-standard RAID levels#Linux MD RAID 10|RAID 10]]<br />
: Linux 下的 RAID10 建立在 RAID1+0 的概念上,但它将其实现为单一的一层,这一层可以有多种不同的布局。可参考 [https://www.suse.com/zh-cn/documentation/sles11/stor_admin/data/raidmdadmr10cpx.html 创建复杂 RAID 10]。<br />
: 在 Y 块硬盘上的 ''近 X 布局'' 在不同硬盘上重复储存每个数据块 X 次,但不需要 Y 可以被 X 整除。数据块放在所镜像的磁盘上几乎相同的位置,这就是 ''近布局'' 名字的来源。它可以工作在任意数量的磁盘上,最少是 2 块。在 2 块硬盘上的近 2 布局相当于 RAID1,4 块硬盘上的近 2 布局相当于 RAID1+0。<br />
: 在 Y 块硬盘上的 ''远 X 布局'' 设计用于在镜像阵列中提供与条带化技术一样快的读取速度。它通过把每块硬盘分成前后两部分来实现这一点,写入第一块硬盘前半部分数据也会写入第二块硬盘的后半部分,反之亦然。这样可以达到一个效果,那就是把对连续数据的读取条带化,而这正是 RAID0 和 RAID5 读取性能高的原因。它的缺点在于写入连续数据时有轻微性能损失,因为硬盘磁头要运动到另一片区域来写入镜像。当数据读取性能和可用性/冗余性一样重要时,比起 RAID1+0 '''和''' RAID5,更应该优先考虑远 2 布局的 RAID10。需注意这种方式仍无法代替备份。详情请阅读维基百科相关页面。<br />
<br />
=== RAID 级别对比 ===<br />
<br />
{| class="wikitable"<br />
! RAID 级别!!数据冗余!!物理设备利用率!!读取性能!!写入性能!!最少磁盘数量<br />
|-<br />
| '''0'''||{{No}}||100%||n 倍<br />
<br />
'''最优'''<br />
||n 倍<br />
<br />
'''最优'''<br />
||2<br />
|-<br />
| '''1'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍<br />
||1 倍||2<br />
|-<br />
| '''5'''||{{Yes}}||67% - 94%||(n−1) 倍<br />
<br />
'''较优'''<br />
||(n−1) 倍<br />
<br />
'''较优'''<br />
||3<br />
|-<br />
| '''6'''||{{Yes}}||50% - 88%||(n−2) 倍||(n−2) 倍||4<br />
|-<br />
| '''10,far2'''||{{Yes}}||50%||n 倍<br />
'''最优;''' 与 RAID0 相当但加入了数据冗余<br />
||(n/2) 倍||2<br />
|-<br />
| '''10,near2'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍||(n/2) 倍||2<br />
|}<br />
<br />
<nowiki>*</nowiki> 其中 ''n'' 表示用于组成阵列的磁盘数量。<br />
<br />
== 实现方式 ==<br />
<br />
RAID 设备可以用不同方式来管理:<br />
<br />
; 软件 RAID<br />
: 这是最简单的实现方式,因为它不依赖于专用固件或专有软件。这种阵列由操作系统通过以下方式进行管理:<br />
:* 通过抽象层管理(比如 [[#安装|mdadm]]); {{注意|这是在本指南下文将要使用的方法。}}<br />
:* 通过逻辑卷管理器来管理(比如 [[LVM#RAID|LVM]]);<br />
:* 通过文件系统的某个组件来管理(比如 [[ZFS (简体中文)|ZFS]],[[Btrfs#RAID|Btrfs]])。<br />
<br />
; 硬件 RAID<br />
: 这种阵列由安装在计算机上的专用硬件卡直接管理,硬盘直接连接在该计算机上。RAID 的处理逻辑由板载的处理器完成,它独立于 [[Wikipedia:Central processing unit|主处理器 (CPU)]]。尽管这种方案独立于任何操作系统,但却需要驱动程序来使硬件 RAID 控制器正常工作。取决于不同的制造商,硬件 RAID 阵列可以在 option ROM 里设置或者操作系统安装完成后另行安装配套软件来设置。这种设置是独立于 Linux 内核的:内核并不能看到单独的每块硬盘。<br />
<br />
; [[Fakeraid|FakeRAID]]<br />
: 这种类型的 RAID 应当称为 BIOS 或板载 RAID,却常被错误地当做硬件 RAID 来宣传。这种阵列由伪 RAID 控制器来管理,RAID 逻辑由 option ROM 或[http://www.win-raid.com/t19f13-Intel-EFI-RAID-quot-SataDriver-quot-BIOS-Modules.html 安装了 EFI Sata 驱动程序的] 固件本身([[Unified Extensible Firmware Interface (简体中文)|UEFI]] 情况下)来完成,但并不是实现了 ''所有'' RAID 功能的完整硬件 RAID 控制器。因此,这种 RAID 有时被称为 FakeRAID。来自 [[official repositories (简体中文)|官方仓库]] 的 {{Pkg|dmraid}} 用于处理这种控制器。这里列出一些 FakeRAID 控制器:[[Wikipedia:Intel Rapid Storage Technology|Intel Rapid Storage]],JMicron JMB36x RAID ROM,AMD RAID,ASMedia 106x 和 NVIDIA MediaShield。<br />
<br />
=== 我正在使用哪一种 RAID? ===<br />
<br />
由于软件 RAID 是由用户部署的,因此用户很容易就知道 RAID 的类型。<br />
<br />
但是,辨别 FakeRAID 和真正的硬件 RAID 是很困难的。如上所述,制造商经常错误地混淆这两种类型的 RAID,还可能进行虚假宣传。这种情况下应该采取的最好方式是运行 {{ic|lspci}} 命令并在输出信息中找到你的 RAID 控制器,然后根据这些信息进行更进一步的搜索。硬件 RAID 控制器会在这一列表中出现,但 FakeRAID 不会。同时,真正的硬件 RAID 控制器通常价格很高,如果这个系统是自行组装的,那么很可能安装一个硬件 RAID 会使电脑的价格显著提高。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|mdadm}}。''mdadm'' 用于管理在纯块设备上建立起来的纯软件 RAID:底层硬件不提供任何 RAID 逻辑,只是一些磁盘而已。''mdadm'' 可以在任何块设备集合上工作,甚至是那些非常规的设备。比如,你可以用一堆 U 盘来建立 RAID 阵列。<br />
<br />
=== 准备设备 ===<br />
<br />
{{警告|这些步骤会擦除指定设备上的所有数据,输入命令请小心!}}<br />
<br />
如果设备是旧设备重用或刚从一个现有的阵列上拆下来,请擦除所有旧的 RAID 配置信息:<br />
<br />
# mdadm --misc --zero-superblock /dev/<drive><br />
<br />
或者是删除设备上的某个特定的分区:<br />
<br />
# mdadm --misc --zero-superblock /dev/<partition><br />
<br />
{{注意|<br />
* 清除一个分区的 superblock 不会影响到磁盘上的其他分区。<br />
* 考虑到 RAID 本身的功能特点,在运行中的磁盘阵列中完全地 [[securely wipe disk|安全擦除磁盘]] 是很困难的。请在创建阵列前考虑要不要安全擦除磁盘。<br />
}}<br />
<br />
=== 对磁盘进行分区 ===<br />
<br />
强烈推荐对用于阵列的硬盘进行分区。考虑到大多数 RAID 用户会用到超过 2 TiB 的硬盘,因此推荐并要求使用 GPT。参阅 [[Partitioning (简体中文)]] 获取关于磁盘分区的更多信息以及可供使用的 [[Partitioning (简体中文)#分区工具|分区工具]]。<br />
<br />
{{注意|也可以在裸磁盘(没有分区的磁盘)上直接创建 RAID,但不推荐这么做,因为这样可能会导致更换损坏硬盘时出现问题}}<br />
<br />
{{注意|当更换 RAID 中的某块损坏的硬盘时,新硬盘的大小必须恰好等于或大于损坏的硬盘,否则无法完成阵列重建过程。即使是同一厂商相同型号的硬盘也可能有容量上的细微差别。通过在磁盘末尾保留一些未分配的空间可以消除磁盘容量上的细微差异,这样可以使替代磁盘的型号选择更加容易。因此,最好在磁盘末尾留出大约 100 MiB 的未分配空间。}}<br />
<br />
==== GUID 分区表 ====<br />
<br />
* 创建分区以后,这些分区的 [[Wikipedia:GUID Partition Table#Partition type GUIDs|类型标识符 (GUID)]] 应该是 {{ic|A19D880F-05FC-4D3B-A006-743F0F84911E}}(在 ''fdisk'' 里将分区类型改为 {{ic|Linux RAID}} 或在 ''gdisk'' 里改为 {{ic|FD00}} 可以给所选分区分配这个标识符)。<br />
* 如果使用了一个更大的磁盘阵列,可以考虑分配 [[Persistent block device naming (简体中文)#by-label|文件系统标签]] 或 [[Persistent block device naming (简体中文)#by-partlabel|分区标签]] 用于以后区分每块单独的硬盘。<br />
* 建议在每个设备上创建大小相同的分区。<br />
<br />
==== 主引导记录 (MBR) ====<br />
<br />
对于在使用 MBR 的硬盘上创建分区的用户,可用的 [[Wikipedia:Partition type|分区类型 ID]] 包括:<br />
<br />
* {{ic|0xFD}}: 自动检测的 RAID(''fdisk'' 中称为 {{ic|Linux raid autodetect}})<br />
* {{ic|0xDA}}: 无文件系统(''fdisk'' 中称为 {{ic|Non-FS data}})<br />
<br />
更多信息请参阅 [https://raid.wiki.kernel.org/index.php/Partition_Types Linux Raid Wiki:Partition Types]。<br />
<br />
=== 创建阵列 ===<br />
<br />
使用 {{ic|mdadm}} 来创建阵列。参阅 {{man|8|mdadm}} 获取支持的选项。下面列出部分使用范例。<br />
<br />
{{警告|不要简单地复制/粘贴下面的示例,确保你已经使用正确的选项和设备名称替代了示例中相应的内容。}}<br />
<br />
{{注意|<br />
* 如果有一个从 [[Syslinux (简体中文)|Syslinux]] 启动的 RAID1 阵列,在 syslinux v4.07 中要求元数据值为 1.0,而不是默认的 1.2。<br />
* 当用 [[Archiso (简体中文)|Arch 安装镜像]] 创建磁盘阵列时,请使用 {{ic|1=--homehost=''myhostname''}} 选项设置 [[hostname|主机名]](或者 {{ic|1=--homehost=any}} 选项无论在什么主机上都用相同的主机名),否则主机名称 {{ic|archiso}} 会被写入阵列的元数据中。<br />
}}<br />
<br />
{{提示|要为 RAID 设备指定一个自定义的名称,可以使用 {{ic|1=--name=''MyRAIDName''}} 选项或将 RAID 设备路径改为 {{ic|/dev/md/''MyRAIDName''}}。Udev 会使用该名称创建指向 {{ic|/dev/md/}} 内 RAID 阵列的符号链接。如果 {{ic|homehost}} 与当前 [[hostname|主机名]] 匹配(或者 homehost 设为了 {{ic|any}})则链接将会是 {{ic|/dev/md/''name''}},如果 homehost 不匹配那么链接将会是 {{ic|/dev/md/''homehost'':''name''}}。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立 RAID1 阵列:<br />
<br />
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1<br />
<br />
下面这个例子展示了使用 4 块磁盘作为工作 (active) 磁盘,1 块作为备用 (spare) 磁盘建立 RAID5 阵列:<br />
<br />
# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1<br />
<br />
{{提示|{{ic|--chunk}} 可用于修改默认的区块大小。更多关于优化区块大小的内容请参阅 [http://www.zdnet.com/article/chunks-the-hidden-key-to-raid-performance/ Chunks: the hidden key to RAID performance]。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立远 2 布局的 RAID10 阵列 (RAID10, far2):<br />
<br />
# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1<br />
<br />
这样,阵列就会在虚拟设备 {{ic|/dev/mdX}} 下建立起来,容量已经合并且可以使用(但处于降级模式)。mdadm 在后台同步数据时你已经可以直接开始使用这个阵列了。储存奇偶校验位可能要花很长时间,可以用这个命令查看进度:<br />
<br />
$ cat /proc/mdstat<br />
<br />
=== 更新配置文件 ===<br />
<br />
默认情况下,{{ic|mdadm.conf}} 中的大部分内容都被注释掉了,它应该只包含如下内容:<br />
<br />
{{hc|/etc/mdadm.conf|<br />
...<br />
DEVICE partitions<br />
...<br />
}}<br />
<br />
这一指令告诉 mdadm 检查由 {{ic|/proc/partitions}} 引用的所有设备并尽可能将其中的阵列组合起来。如果你确实想启动所有可用的阵列并且确信不存在意料之外的超级块(比如安装了新的存储设备),那么这样的配置就很好。当然有一种更精准的控制方法,就是显式地将阵列添加到 {{ic|/etc/mdadm.conf}}:<br />
<br />
# mdadm --detail --scan >> /etc/mdadm.conf<br />
<br />
这将会在配置中添加类似这样的内容:<br />
<br />
{{hc|/etc/mdadm.conf|2=<br />
...<br />
DEVICE partitions<br />
...<br />
ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe<br />
}}<br />
<br />
这也会使 mdadm 检查由 {{ic|/proc/partitions}} 引用的设备。但是,只有超级块的 UUID 是 {{ic|27664…}} 的设备才会被组合成激活的阵列。<br />
<br />
更多信息请参阅 {{man|5|mdadm.conf}}。<br />
<br />
=== 组合成磁盘阵列 ===<br />
<br />
更新配置文件后即可用 mdadm 组合磁盘阵列:<br />
<br />
# mdadm --assemble --scan<br />
<br />
=== 格式化 RAID 上的文件系统 ===<br />
<br />
现在磁盘阵列已经可以像普通分区一样被格式化成某个 [[File systems (简体中文)|文件系统]],但要记住:<br />
<br />
* 不是所有文件系统都支持超大分区(参阅 [[Wikipedia:Comparison of file systems#Limits]])。<br />
* 文件系统需要支持在线增大和收缩(参阅 [[Wikipedia:Comparison of file systems#Features]])。<br />
* 应合理计算跨度大小和带区宽度来获得最佳性能。<br />
<br />
==== 计算 stride(跨度大小)和 stripe width(带区宽度) ====<br />
<br />
优化文件系统结构以适应底层 RAID 结构需要 2 个参数:''stride'' 和 ''stripe width''。它们对应于 RAID 的 ''chunk size(区块大小)'' 、文件系统的 ''block size(块大小)'' 以及 ''"data disks"(数据盘)的数量''。<br />
<br />
Chunk size(RAID 区块大小)是 RAID 阵列的一个属性,在阵列创建时就已经定好了。目前 {{ic|mdadm}} 默认该值为 512 KiB。这个参数可以用 {{ic|mdadm}} 读取:<br />
<br />
# mdadm --detail /dev/mdX | grep 'Chunk Size'<br />
<br />
Block size(块大小)是文件系统的一个属性,在文件系统创建时就已经定好了。在大部分文件系统上(包括 ext4)默认是 4 KiB。更多关于当前系统 ext4 的信息可以查看 {{ic|/etc/mke2fs.conf}} 文件。<br />
<br />
"Data disks"(数据盘)的数量指的是阵列能够完全重建数据所要求的最少可用设备。例如,对于 N 个设备的 raid0 来说这个数量是 N,对于 raid5 来说是 N-1。<br />
<br />
当你获得了这三个参数时,stride 和 stripe width 可以用下列公式来计算:<br />
<br />
stride = chunk size / block size<br />
stripe width = number of data disks * stride<br />
<br />
===== 范例 1. RAID0 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID0 阵列是由 2 块物理硬盘组成的。<br />
* Chunk size(RAID 区块大小)是 64 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 64/4 = 16。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 2*16 = 32。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.5 -b 4096 -E stride=16,stripe-width=32 /dev/md0<br />
<br />
===== 范例 2. RAID5 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID5 阵列由 4 块物理硬盘组成,3 块是数据盘,1 块是奇偶校验盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 3*128 = 384.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=384 /dev/md0<br />
<br />
关于 stride 和 stripe width 的更多信息,请参阅:[http://wiki.centos.org/HowTos/Disk_Optimization RAID Math]。<br />
<br />
===== 范例 3. RAID10,far2 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID10 阵列由 2 块物理硬盘组成。考虑到远 2 布局的 RAID10 的自身特性,两块硬盘都是数据盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
<br />
{{hc|# mdadm --detail /dev/md0 {{!}} grep 'Chunk Size'|<br />
Chunk Size : 512K<br />
}}<br />
<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。<br />
在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。<br />
在这个例子中,stripe width 的大小是 2*128 = 256。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/md0<br />
<br />
== 在 Live CD 中挂载 RAID ==<br />
<br />
如果你需要在 Live CD 中挂载 RAID 分区,用这个命令:<br />
<br />
# mdadm --assemble /dev/<disk1> /dev/<disk2> /dev/<disk3> /dev/<disk4><br />
<br />
如果缺一块盘的 RAID 1 被错误地识别为了 RAID 1(参照 {{ic|mdadm --detail /dev/md<number>}})并报告为非活动状态(参照 {{ic|cat /proc/mdstat}}),需要先停止磁盘阵列:<br />
<br />
# mdadm --stop /dev/md<number><br />
<br />
== 在 RAID 上安装 Arch Linux ==<br />
<br />
{{注意|本节仅适用于根文件系统在磁盘阵列上的情况。如果你的磁盘阵列上只是一个数据分区,那么可以跳过本节。}}<br />
<br />
你应该在安装过程中的 [[Partitioning (简体中文)|分区]] 和 [[File systems (简体中文)#创建文件系统|格式化]] 步骤之间创建 RAID 阵列。这将会把一个位于 RAID 阵列上的分区格式化成根文件系统,而不是直接格式化一个分区。<br />
按照 [[#安装]] 一节的步骤创建 RAID 阵列。,然后继续安装过程,直到 pacstrap 步骤完成。<br />
当使用 [[Unified Extensible Firmware Interface (简体中文)|UEFI 启动]] 时,还需要阅读 [[EFI system partition (简体中文)#RAID 上的 ESP]]。<br />
<br />
=== 更新配置文件 ===<br />
<br />
{{注意|这些操作应该在 chroot 以外完成,因此要在文件路径前加上 {{ic|/mnt}}。}}<br />
<br />
在基本系统安装完成以后,RAID 的默认配置文件 {{ic|mdadm.conf}} 需要这样来更新:<br />
<br />
# mdadm --detail --scan >> /mnt/etc/mdadm.conf<br />
<br />
在运行这个命令以后一定要用文本编辑器检查 {{ic|mdadm.conf}} 配置文件来确保它的内容看起来是合理的。<br />
<br />
{{注意|为防止系统启动时 {{ic|mdmonitor.service}} 启动失败(默认设为自动启动),你需要取消 {{ic|MAILADDR}} 的注释,并且在 {{ic|mdadm.conf}} 结尾留下可处理磁盘阵列出错通知的邮件地址和/或应用程序。参阅 [[#启用事件邮件通知]]。}}<br />
<br />
现在继续安装过程直到 [[Installation guide (简体中文)#Initramfs]] 步骤之前为止,然后按照下一节的步骤做。<br />
<br />
=== 配置 mkinitcpio ===<br />
<br />
{{注意|这些操作应该在 chroot 时完成。}}<br />
<br />
向 {{ic|mkinitcpio.conf}} 中的 [[mkinitcpio (简体中文)#钩子(HOOKS)|HOOKS]] 部分添加 {{ic|mdadm_udev}} 来为初始化内存盘添加 mdadm 支持:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
HOOKS=(base udev autodetect keyboard modconf block '''mdadm_udev''' filesystems fsck)<br />
...<br />
}}<br />
<br />
如果在一个 FakeRAID 阵列上使用 {{ic|mdadm_udev}} 钩子,建议在 [[mkinitcpio (简体中文)#附加文件(BINARIES、FILES)|BINARIES]] 列表中添加 ''mdmon'':<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
BINARIES=('''mdmon''')<br />
...<br />
}}<br />
<br />
然后 [[mkinitcpio (简体中文)#创建和启用镜像|重新生成初始化内存盘]]。<br />
<br />
参考 [[mkinitcpio (简体中文)#使用 RAID 磁盘阵列]]。<br />
<br />
=== 配置 boot loader ===<br />
<br />
将 {{ic|root}} 参数指向映射的磁盘,例如:<br />
<br />
root=/dev/md/''MyRAIDArray''<br />
<br />
如果按上述用内核设备节点来指定映射磁盘的方法之后,从软件 RAID 分区启动失败了,那就用 [[Persistent block device naming (简体中文)|持久化命名块设备]] 中的某种方法来指定映射的磁盘,例如:<br />
<br />
root=LABEL=Root_Label<br />
<br />
参考 [[GRUB#RAID]]。<br />
<br />
== 维护 RAID ==<br />
<br />
=== 数据清扫 (Scrubbing) ===<br />
<br />
定期运行数据 [[wikipedia:Data_scrubbing|清扫 (Scrubbing)]] 来检查并修复错误是一种很好的做法。一次完整数据清扫可能会花费数个小时,具体取决于磁盘阵列的大小和配置。<br />
<br />
启动数据清扫:<br />
<br />
# echo check > /sys/block/md0/md/sync_action<br />
<br />
数据检查操作会扫描驱动器来检查坏扇区并自动修复它们。如果找到了包含损坏数据的好扇区(本扇区中的数据与另一块硬盘中记录本扇区应有的数据不符,例如奇偶校验块和另一块数据块相结合可以证明本数据块是错误的),那就不动作,但记录下这一事件(见下文)。这种“不动作”允许管理员自行检查坏扇区中原本的数据和从冗余数据中重建的数据,然后决定保留哪个。<br />
<br />
与许多 mdadm 相关的任务/事项一样,数据清扫的进度也可以通过查看 {{ic|/proc/mdstat}} 文件来查询。<br />
<br />
例如:<br />
<br />
{{hc|$ cat /proc/mdstat|<nowiki><br />
Personalities : [raid6] [raid5] [raid4] [raid1]<br />
md0 : active raid1 sdb1[0] sdc1[1]<br />
3906778112 blocks super 1.2 [2/2] [UU]<br />
[>....................] check = 4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec<br />
bitmap: 0/30 pages [0KB], 65536KB chunk<br />
</nowiki>}}<br />
<br />
安全地停止当前的数据清扫操作:<br />
<br />
# echo idle > /sys/block/md0/md/sync_action<br />
<br />
{{注意|如果在数据清扫暂停时重启了系统,将继续进行清扫。}}<br />
<br />
数据清扫完成后,管理员可以检查有多少数据块(如果有的话)被标记为坏块:<br />
<br />
# cat /sys/block/md0/md/mismatch_cnt<br />
<br />
==== 关于数据清扫的一般说明 ====<br />
<br />
{{注意|用户也可以 echo '''repair''' 到 {{ic|/sys/block/md0/md/sync_action}} 里面,但是这是不明智的,因为一旦遇到数据不一致就被自动改写为一致。危险之处在于我们实际并不知道奇偶校验块和数据块哪个是对的(在 RAID1 中是不知道哪个数据块是对的)。因此自动清扫操作能不能用正确数据替换错误数据取决于运气。}}<br />
<br />
以 root 身份设定一个 cron 任务来定期执行清扫是很好的。{{AUR|raid-check}} 会对此有所帮助。如果要用 systemd 定时器而不是 cron 来执行定期清扫,{{AUR|raid-check-systemd}} 中包含了相同的脚本和配套的 systemd 定时器单元文件。<br />
<br />
{{注意|对于常规的大容量驱动器,清扫工作耗时大约 '''6 秒每 GB'''(即每 TB 大约需要 1 小时 45 分钟),因此应合理确定 cron 任务或定时器的开始时间。}}<br />
<br />
==== 对清扫 RAID1 和 RAID10 的说明 ====<br />
<br />
由于 RAID1 和 RAID10 本质上就是没有数据缓冲的,所以即使阵列工作正常,它的不匹配计数仍然可能是个非零值。这些不匹配计数只存在于正在写入数据的区域,且它们不反映任何问题。但是,我们无法区分非零的不匹配计数到底代表正在写入数据还是确实存在问题。这是造成 RAID1 和 RAID10 阵列误报错误的根源。即使如此,仍然建议定期清扫以发现并纠正驱动器上可能出现的坏扇区。<br />
<br />
=== 从阵列中移除设备 ===<br />
<br />
要从阵列中移除一个设备,先将这个设备标记为 faulty(故障):<br />
<br />
# mdadm --fail /dev/md0 /dev/sdxx<br />
<br />
现在从阵列中移除这个设备:<br />
<br />
# mdadm --remove /dev/md0 /dev/sdxx<br />
<br />
永久移除设备(比如想把一个设备拿出来单独使用):<br />
先使用上述两个命令,然后:<br />
<br />
# mdadm --zero-superblock /dev/sdxx<br />
<br />
{{警告|<br />
* 不要在 RAID0 阵列或者其他线性存放数据的阵列中进行这个操作!否则数据会丢失!<br />
* 重新使用已经移除的硬盘却不清除它的超级块将会导致下次启动时丢失所有数据。(因为 mdadm 将会把它当做磁盘阵列的一部分来使用)。<br />
}}<br />
<br />
停止使用某个阵列:<br />
<br />
# 卸载 (umount) 目标阵列<br />
# 用这个命令停止磁盘阵列运行:{{ic|mdadm --stop /dev/md0}}<br />
# 将本节开头的三个命令在每块硬盘上都运行一遍。<br />
# 将 {{ic|/etc/mdadm.conf}} 中的相关行移除。<br />
<br />
=== 向阵列中添加设备 ===<br />
<br />
可以在系统正在运行且设备已经挂载的情况下使用 mdadm 添加新设备。<br />
按照前文所述的方法,使用现有阵列中相同的布局对新设备进行分区。<br />
<br />
如果 RAID 阵列尚未组合,先组合它们:<br />
<br />
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1<br />
<br />
向阵列中添加新设备:<br />
<br />
# mdadm --add /dev/md0 /dev/sdc1<br />
<br />
这一步 mdadm 不会花费很长时间。<br />
<br />
根据不同的 RAID 类型(比如 RAID1),mdadm 可能会把部分设备添加为备用设备,而不在这些设备上存放数据。可以使用 {{ic|--grow}} 加上 {{ic|--raid-devices}} 选项来增加 RAID 利用的磁盘数量。例如,将一个阵列增加至四块硬盘:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices=4<br />
<br />
可以这样检查进度:<br />
<br />
# cat /proc/mdstat<br />
<br />
用这个命令检查已经添加的设备:<br />
<br />
# mdadm --misc --detail /dev/md0<br />
<br />
{{注意|对于 RAID0 设备可能会收到以下错误信息:<br />
<br />
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument<br />
<br />
这是由于上述命令会将新磁盘添加为 "spare"(备用)盘,但是 RAID0 中不存在备用盘。如果想往 RAID0 阵列中添加磁盘,你需要同时使用 "grow" 和 "add" 参数。如下所示:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices<nowiki>=</nowiki>3 --add /dev/sdc1<br />
<br />
}}<br />
<br />
=== 增大 RAID 卷的大小 ===<br />
<br />
如果给阵列安装了更大的磁盘,或者增大了分区大小,可能就需要增大 RAID 卷的大小以适应更大的可用空间。这一过程可用首先按照上文中关于更换磁盘的步骤来做。当 RAID 卷在更大的磁盘上重建完成后,这个卷需要 "grow" 来填充多出来的空间。<br />
<br />
# mdadm --grow /dev/md0 --size=max<br />
<br />
接着,在 RAID 卷 {{ic|/dev/md0}} 上的现有分区可能需要调整大小。参阅 [[Partitioning (简体中文)]] 获取更多信息。最后,上述分区上的文件系统也需要重新调整大小。如果用 {{ic|gparted}} 来完成分区操作,这些都会自动完成。如果用的是其他工具,请手动卸载 (unmount) 文件系统并调整其大小。<br />
<br />
# umount /storage<br />
# fsck.ext4 -f /dev/md0p1<br />
# resize2fs /dev/md0p1<br />
<br />
=== 修改同步速度限制 ===<br />
<br />
同步工作需要一定的时间。如果本机不需要完成其他任务,可以提高速度限制值。<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 0.0% (77696/155042219) finish=265.8min speed=9712K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
查看当前速度限制:<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_min|<br />
1000<br />
}}<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_max|<br />
200000<br />
}}<br />
<br />
提高限制值:<br />
<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_min<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_max<br />
<br />
然后查看同步速度和预计完成时间:<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 1.3% (2136640/155042219) finish=158.2min speed=16102K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
更多信息可参阅 [[sysctl#MDADM]]。<br />
<br />
== 监视运行情况 ==<br />
<br />
可以显示当前 RAID 设备状态的一行简单命令:<br />
<br />
{{hc|# awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat<br />
|md1: [UU]<br />
md0: [UU]<br />
}}<br />
<br />
=== 用 watch 监视 mdstat ===<br />
<br />
# watch -t 'cat /proc/mdstat'<br />
<br />
或者最好用 {{pkg|tmux}}<br />
<br />
# tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"<br />
<br />
=== 用 iotop 追踪 IO ===<br />
<br />
{{pkg|iotop}} 可以显示各个进程的输入输出状态。请用这个命令来查看 RAID 线程的输入输出。<br />
<br />
# iotop -a -p $(sed 's, , -p ,g' <<<`pgrep "_raid|_resync|jbd2"`)<br />
<br />
=== 用 iostat 追踪 IO ===<br />
<br />
{{Pkg|sysstat}} 包中的 ''iostat'' 实用程序可以显示各个设备和分区的输入输出统计。<br />
<br />
# iostat -dmy 1 /dev/md0<br />
# iostat -dmy 1 # all<br />
<br />
=== 启用事件邮件通知 ===<br />
<br />
要完成发送邮件的任务需要一个 smtp 邮件服务器或至少需要一个 ssmtp/msmtp 邮件转发器。大概最简单的解决方案是使用 {{AUR|dma}},它非常小巧(安装完只占用 0.08 MiB)且不需要设置。<br />
<br />
编辑 {{ic|/etc/mdadm.conf}} 来添加用于接收通知的邮件地址。<br />
<br />
{{注意|如果用的是上文提到的 dma,用户可以直接将邮件发送到本机 (localhost) 的某个用户名 (username) 中,不一定非要发到外部邮件地址。}}<br />
<br />
测试配置是否正确:<br />
<br />
# mdadm --monitor --scan --oneshot --test<br />
<br />
mdadm 使用 {{ic|mdmonitor.service}} 来完成监控任务,所以现在你无需进行更多设置了。如果你没有在 {{ic|/etc/mdadm.conf}} 设置邮件地址,那么这个 service 就会出错。如果你不想接收 mdadm 一般事件通知,可以忽略这个错误;如果不想接收一般事件通知但是需要接收故障信息,可以 [[Systemd (简体中文)#使用单元|mask(屏蔽)]] 这个 unit。<br />
<br />
==== 其他实现方式 ====<br />
<br />
为避免安装 smtp 邮件服务器或邮件转发器的麻烦,可以使用系统上已经安装的 [[S-nail]] 工具(不要忘了设置它)。<br />
<br />
创建 {{ic|/etc/mdadm_warning.sh}} 文件:<br />
<br />
{{hc|/etc/mdadm_warning.sh|2=<br />
#!/bin/bash<br />
event=$1<br />
device=$2<br />
<br />
echo " " | /usr/bin/mailx -s "$event on $device" '''destination@email.com'''<br />
}}<br />
<br />
然后给它执行权限:{{ic|chmod +x /etc/mdadm_warning.sh}}<br />
<br />
然后在 mdadm.conf 中添加这一行:<br />
<br />
PROGRAM /etc/mdadm_warning.sh<br />
<br />
用前述的方法测试并启用它。<br />
<br />
== 故障排除 ==<br />
<br />
如果你在重启计算机时遇到类似 "invalid raid superblock magic" 的错误,并且除了已经配置好的硬盘外又接了其他硬盘,请检查硬盘顺序是不是正确的。在安装 RAID 时,硬盘编号可能是 hdd、hde 和 hdf,但是重启后它们的编号可能变成了 hda、hdb 和 hdc。请相应地调整你的内核参数。这种情况经常发生。<br />
<br />
=== Error: "kernel: ataX.00: revalidation failed" ===<br />
<br />
如果你突然(在重启、修改 BIOS 设置后)遇到类似错误信息:<br />
<br />
Feb 9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)<br />
<br />
这并不意味着设备已经损坏。尽管你可能会在网上看到一些讲内核崩溃的链接指向最坏的结果,但总而言之,并不是内核崩溃。可能你不知怎么的在 BIOS 里或内核参数里修改了 APIC 或 ACPI 设置。把它改回来就好了。通常关闭 APIC 和/或 ACPI 就好了。<br />
<br />
=== 磁盘阵列以只读模式启动 ===<br />
<br />
当由 md 启动磁盘阵列时,超级块将被改写,数据同步可能已经开始了。要以只读模式启动,可以向内核模块 {{ic|md_mod}} 传递参数 {{ic|start_ro}}。设置了这个参数以后,新的磁盘阵列进入 'auto-ro' 模式,该模式停止了所有内部读写操作(更新超级块、再同步、数据恢复),并且会在第一个写入请求到来时自动切换至 'rw' (读写)模式。<br />
<br />
{{注意|在第一个写入请求到来前使用 {{ic|mdadm --readonly}} 命令可以将阵列设置为真正的 'ro' (只读)模式,还可以用 {{ic|mdadm --readwrite}} 命令直接开始再同步而不用等待写入请求。}}<br />
<br />
要在启动时设置该参数,在内核启动参数中添加 {{ic|1=md_mod.start_ro=1}}。<br />
<br />
也可以在模块加载时传递该参数,可以从 {{ic|/etc/modprobe.d/}} 下的文件中传递,也可以直接从 {{ic|/sys/}} 传递:<br />
<br />
# echo 1 > /sys/module/md_mod/parameters/start_ro<br />
<br />
=== 在损坏或缺失磁盘的情况下恢复 RAID ===<br />
<br />
当磁盘阵列中的一个驱动器由于任何原因损坏时,也可能会发生上述错误。如果在缺失一块硬盘的情况下你仍需要强制启动磁盘阵列,输入以下命令(根据实际修改):<br />
<br />
# mdadm --manage /dev/md0 --run<br />
<br />
现在你应该可以用类似下面的命令来挂载它(如果在 fstab 里有它的话):<br />
<br />
# mount /dev/md0<br />
<br />
现在磁盘阵列应该已经工作并且可以使用,但仍旧是缺一块盘的状态。因此需要按照上文 [[#准备设备]] 所述再添加一个磁盘分区,然后就可以将新磁盘分区加入到磁盘阵列中:<br />
<br />
# mdadm --manage --add /dev/md0 /dev/sdd1<br />
<br />
如果输入:<br />
<br />
# cat /proc/mdstat<br />
<br />
你就能看到磁盘阵列已经激活并正在重建。<br />
<br />
你可能还需要更新你的配置文件(参阅:[[#更新配置文件]])。<br />
<br />
== 基准测试 ==<br />
<br />
用于 RAID 基准测试的工具有很多种。不同 RAID 最显著的不同是多个线程在读取 RAID 卷时的速度提升程度。<br />
<br />
{{AUR|tiobench}}{{Broken package link|package not found}} 通过测量磁盘的全线程读写 (fully-threaded I/O) 来专门测试多线程性能提升程度。<br />
<br />
{{Pkg|bonnie++}} 测试对一个或多个数据库类型文件的读写,以及对小文件的创建、读取、删除,这样可以模拟 Squid、INN 和 Maildir format e-mail 等程序的文件读写。其附带的 [http://www.coker.com.au/bonnie++/zcav/ ZCAV] 程序可以测试硬盘不同区域的性能,且不用向硬盘写入任何数据。<br />
<br />
'''不应该''' 使用 {{ic|hdparm}} 来对 RAID 进行基准测试,因为它多次返回的结果会非常不一致。<br />
<br />
== 参考资料 ==<br />
<br />
{{Out of date|许多链接太旧且无效。}}<br />
<br />
* [http://www.gentoo.org/doc/en/articles/software-raid-p1.xml Software RAID in the new Linux 2.4 kernel, Part 1]{{Dead link|2018|03|10}} and [http://www.gentoo.org/doc/en/articles/software-raid-p2.xml Part 2]{{Dead link|2018|03|10}} in the Gentoo Linux Docs<br />
* [http://raid.wiki.kernel.org/index.php/Linux_Raid Linux RAID wiki entry] on The Linux Kernel Archives<br />
* [https://raid.wiki.kernel.org/index.php/Write-intent_bitmap How Bitmaps Work]<br />
* [http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-raid.html Chapter 15: Redundant Array of Independent Disks (RAID)] of Red Hat Enterprise Linux 6 Documentation<br />
* [http://tldp.org/FAQ/Linux-RAID-FAQ/x37.html Linux-RAID FAQ] on the Linux Documentation Project<br />
* [http://support.dell.com/support/topics/global.aspx/support/entvideos/raid?c=us&l=en&s=gen Dell.com Raid Tutorial]{{Dead link|2018|03|10}} - Interactive Walkthrough of Raid<br />
* [http://www.miracleas.com/BAARF/ BAARF]{{Dead link|2018|03|10}} including ''[http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt Why should I not use RAID 5?]''{{Dead link|2018|03|10}} by Art S. Kagel<br />
* [http://www.linux-mag.com/id/7924/ Introduction to RAID], [http://www.linux-mag.com/id/7931/ Nested-RAID: RAID-5 and RAID-6 Based Configurations], [http://www.linux-mag.com/id/7928/ Intro to Nested-RAID: RAID-01 and RAID-10], and [http://www.linux-mag.com/id/7932/ Nested-RAID: The Triple Lindy] in Linux Magazine<br />
* [http://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html HowTo: Speed Up Linux Software Raid Building And Re-syncing]<br />
* [http://fomori.org/blog/?p=94 RAID5-Server to hold all your data]<br />
* [[Wikipedia:Non-RAID drive architectures]]<br />
<br />
'''mdadm'''<br />
* [http://anonscm.debian.org/gitweb/?p=pkg-mdadm/mdadm.git;a=blob_plain;f=debian/FAQ;hb=HEAD Debian mdadm FAQ]<br />
* [http://www.kernel.org/pub/linux/utils/raid/mdadm/ mdadm source code]<br />
* [http://www.linux-mag.com/id/7939/ Software RAID on Linux with mdadm] in Linux Magazine<br />
* [[Wikipedia:mdadm|Wikipedia - mdadm]]<br />
<br />
'''Forum threads'''<br />
* [http://forums.overclockers.com.au/showthread.php?t=865333 Raid Performance Improvements with bitmaps]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=125445 GRUB and GRUB2]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=123698 Can't install grub2 on software RAID]<br />
* [http://forums.gentoo.org/viewtopic-t-888624-start-0.html Use RAID metadata 1.2 in boot and root partition]<br />
<br />
'''RAID with encryption'''<br />
* [http://www.shimari.com/dm-crypt-on-raid/ Linux/Fedora: Encrypt /home and swap over RAID with dm-crypt] by Justin Wells</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539082
Mathematica (简体中文)
2018-09-01T02:37:11Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:Mathematics and science (简体中文)]]<br />
[[en:Mathematica]]<br />
[[it:Mathematica]]<br />
[[ja:Mathematica]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Scientific Applications (简体中文)}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Mathematica|2018-09-01|525644}}<br />
<br />
[http://www.wolfram.com/mathematica/ Mathematica] 是用于科学,工程和数学领域的商业软件。在这里我们说明如何安装它。<br />
<br />
== 安装 ==<br />
<br />
由于 Mathematica 是专有软件,升级可能会产生成本,因此本节列出了不同可用版本的说明。<br />
<br />
=== Mathematica 6 ===<br />
<br />
==== 挂载 iso 文件 ====<br />
<br />
挂载 Mathematica {{ic|.iso}} 的一种方式是创建 {{ic|/media/iso}} 目录用于挂载,并在 [[fstab]] 中增加这几行:<br />
/''location/of/mathematica.iso'' /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
然后就可以这样挂载它:<br />
# mount /media/iso<br />
<br />
==== 运行安装程序 ====<br />
<br />
进入这个目录来启动安装程序:<br />
/Unix/Installer<br />
运行 ''MathInstaller'':<br />
sh ./MathInstaller<br />
{{注意|如果没有把 "sh" 放在前面,那么会得到一个关于解释器出错 (bad interpreter) 的错误信息。}}<br />
<br />
==== 字体 ====<br />
<br />
向 FontPath 里添加包含 Type1 和 BDF 字体的目录。<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 安装起来非常方便。<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
按照指示完成即可。<br />
<br />
KDE 用户注意,Mathematica 的图标可能会出现在 ''Lost & Found'' 分类里面。解决方法是以 root 用户身份运行下列命令:<br />
<br />
# ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
=== Mathematica 8 ===<br />
<br />
Mathematica 8 的一个问题是执行 WolframAlpha[ ] 函数时会出现崩溃,这个崩溃可以重现。Mathematica 的默认配置为,在设置如何连接到互联网以获取数据时,检测系统的代理设置。但是在调用库函数时存在一个 bug,最终会使 Mathematica 崩溃。解决方法是通过将 Mathematica 配置为“直接连接”到互联网来完全避免此库调用 (''Edit > Preferences > Internet Connectivity > Proxy Settings'')。这个错误已经报告给 Wolfram。<br />
<br />
=== Mathematica 10 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}} (需要旧版本)。需要 {{ic|Mathematica_10.XX.YY_LINUX.sh}} 安装脚本,从 Wolfram.com 或某大学的站点上下载。同时你还需要一个激活密钥。<br />
<br />
=== Mathematica 11 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}}。从 Wolfram Research 获取 {{ic|Mathematica_11.XX.YY_LINUX.sh}} 和激活密钥。成功的安装可能也会抛出一些不严重的错误:xdg-icon-resource, mkdir, xdg-desktop-menu 等。<br />
<br />
Mathematica 11 在 [https://reference.wolfram.com/language/ref/$UserDocumentsDirectory.html $UserDocumentsDirectory] 自动创建 'Wolfram Mathematica' 文件夹,Mathematica 根据 [[XDG user directories]] 自动设置了这个变量。<br />
<br />
== 故障排除 == <br />
<br />
=== "Missing symbols" 错误 ===<br />
<br />
如果出现字体渲染问题,某些符号无法显示(比如 {{ic|/}} 显示为正方形),请尝试卸载 {{Pkg|font-mathematica}}。<br />
<br />
同时,尝试 [http://mathematica.stackexchange.com/questions/1158/invisible-conjugate-glyph-in-the-linux-frontend 这种] 方案。其中还说明了 Mathematica 版本 9 修复了这个问题。<br />
<br />
尝试让应用程序使用抗锯齿。<br />
对于 KDE 用户: ''System Settings > Application Appearance > Fonts > Use anti-aliasing (Enabled)''<br />
<br />
=== HiDPI / Retina 屏幕 ===<br />
<br />
如果你有一块 [[HiDPI]] 屏幕,比如 Apple Retina 屏幕,而且 Mathematica 里面的文字非常小,这样就能解决:<br />
<br />
* 打开 ''Edit → Preferences''<br />
* 在 ''Advanced'' 选项卡里单击 ''Open Option Inspector''<br />
* 在右侧的树状列表中找到 ''Formatting Options → Font Options → Font Properties''<br />
* 改变 ''"ScreenResolution"'' 的值到它原来的两倍大小,比如 72 → 144。你也可以用 <code>xdpyinfo | grep resolution</code> 来获得一个更精确的数字(也要变成原来的两倍大小)。<br />
<br />
=== 与系统库冲突导致的问题 ===<br />
<br />
Mathematica 软件包包含了一系列其自有的库,存放在 <INSTALL_DIR>/SystemFiles/Libraries/Linux-x86-64 里面。它们可能会导致一些兼容性问题,并且可能需要将某些库回退到系统现有版本。<br />
<br />
==== Symbol lookup error: /usr/lib/libfontconfig.so.1: undefined symbol: FT_Done_MM_Var ====<br />
<br />
强制 Mathematica 使用系统自有的 freetype 库。<br />
<br />
# cd <INSTALL_DIR>/SystemFiles/Libraries/Linux-x86-64<br />
# mv libfreetype.so.6 libfreetype.so.6.old<br />
<br />
==== Mathematica/11.3/SystemFiles/Libraries/Linux-x86-64/libz.so.1: version `ZLIB_1.2.9' not found (required by /usr/lib/libpng16.so.16) ====<br />
<br />
强制 Mathematica 使用系统自有的 zlib 库。<br />
<br />
# cd <INSTALL_DIR>/SystemFiles/Libraries/Linux-x86-64<br />
# mv libz.so.1 libz.so.1.old<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Official site]<br />
* [http://www.wolfram.com/support/ Official Support]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Getty_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539062
Getty (简体中文)
2018-08-31T17:35:15Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Boot process (简体中文)]]<br />
[[Category:Linux console]]<br />
[[en:Getty]]<br />
[[ja:Getty]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Display manager (简体中文)}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|Getty|2018-08-31|532676}}<br />
<br />
[[w:getty (Unix)|getty]] 是管理终端线路及其所连终端的程序的通用名称。其目的是保护系统,防止未经授权的访问。通常,每个 getty 进程由 [[systemd (简体中文)|systemd]] 启动,一个进程管理一条终端线路。<br />
<br />
== 安装 ==<br />
<br />
{{Style|TTY 设置和“台阶效应”在这里没有涉及到。TTY 的默认数量可以移到 [[#添加额外的虚拟控制台]] 一节,因为它不依赖于 agetty。}}<br />
<br />
''agetty'' 是 Arch Linux 中默认的 getty 程序,它是 {{Pkg|util-linux}} 包的一部分。它在等待登录时修改 TTY 设置,使得换行符不会转换为 CR-LF,否则会使打印到控制台的消息产生“阶梯效应”。Agetty 管理着虚拟控制台,Arch Linux 中默认提供六个虚拟控制台。一般按 {{ic|Ctrl+Alt+F1}} 到 {{ic|Ctrl+Alt+F6}} 来访问它们。<br />
<br />
其他可选替代包括:<br />
<br />
* {{App|mingetty|一个允许自动登录的最小化 getty。|{{AUR|mingetty}}|{{AUR|mingetty}}}}<br />
* {{App|fbgetty|类似于 mingetty,支持帧缓冲。|http://projects.meuh.org/fbgetty/|{{AUR|fbgetty}}}}<br />
* {{App|mgetty|在 Unix 下处理调制解调器各个方面功能的程序。|http://mgetty.greenie.net/|{{AUR|mgetty}}}}<br />
<br />
== 添加额外的虚拟控制台 ==<br />
<br />
打开 {{ic|/etc/systemd/logind.conf}} 文件并将 '''NAutoVTs=6''' 设置为你想要在启动时得到的虚拟控制台数量。<br />
<br />
如果你想临时获取一个控制台,可以为所需的 TTY 启动一个 getty 服务,执行:<br />
<br />
$ systemctl start getty@ttyN.service<br />
<br />
== 自动登录到虚拟控制台 ==<br />
<br />
配置自动登录要使用 systemd 的 [[Systemd (简体中文)#修改现存单元文件|附加代码片段 (drop-in snippet)]] 功能来重写传递给 ''agetty'' 的默认参数。<br />
<br />
虚拟控制台和串口控制台的配置是不同的。大多数情况下,你应该是想在虚拟控制台下设置自动登录(这种控制台的设备名称为 {{ic|tty''N''}},其中 {{ic|''N''}} 是一个数字)。串口控制台的自动登录配置稍有不同,它们的设备名称类似于 {{ic|ttyS''N''}},其中 {{ic|''N''}} 是一个数字。<br />
<br />
=== 虚拟控制台 ===<br />
<br />
{{注意|1=[https://bbs.archlinux.org/viewtopic.php?id=238576 根据用户报告]这种方法可能会影响系统休眠。}}<br />
<br />
要 [[Systemd (简体中文)#修改现存单元文件|修改现存单元文件]],可以手动创建下列附加文件,或执行 {{ic|systemctl edit getty@tty1}} 并输入附加代码片段 (drop-in snippet) 的内容:<br />
<br />
{{hc|/etc/systemd/system/getty@tty1.service.d/override.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/usr/bin/agetty --autologin ''username'' --noclear %I $TERM<br />
}}<br />
<br />
{{提示|默认 {{ic|getty@.service}} 中的 {{ic|1=Type=idle}} 选项将会推迟该服务的启动时间,直到所有任务(该单元的前置任务)已经完成,防止启动信息淹没了登录提示符。当 [[Start X at login|自动启动 X]] 时,可以通过添加 {{ic|1=Type=simple}} 到 [[Systemd (简体中文)#修改现存单元文件|附加代码片段 (drop-in snippet)]] 来立即启动 {{ic|getty@tty1.service}},因为此时 init 进程和 ''startx'' 都被 [[Silent boot|屏蔽]] 了输出,避免残留启动时的信息。}}<br />
<br />
如果你想用 ''tty'' 而不是 ''tty1'',请参阅 [[Systemd FAQ (简体中文)#如何修改默认的 tty 控制台(getty)数量?|Systemd 常见问题]]。<br />
<br />
=== 串口控制台 ===<br />
<br />
创建以下文件(及目录):<br />
<br />
{{hc|/etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/usr/bin/agetty --autologin ''username'' -s %I 115200,38400,9600 vt102<br />
}}<br />
<br />
=== Nspawn 控制台 ===<br />
<br />
要为 [[systemd-nspawn]] 容器配置自动登录,需要重写 ''console-getty'' 服务:<br />
<br />
{{hc|/etc/systemd/system/console-getty.service.d/override.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/sbin/agetty --noclear --autologin ''username'' --keep-baud console 115200,38400,9600 $TERM<br />
}}<br />
<br />
== 将引导消息保留在 tty1 上 ==<br />
<br />
默认情况下,Arch 会启动 {{ic|getty@tty1}} 服务。该服务单元文件已经写入了 {{ic|--noclear}} 参数,它可以阻止 agetty 清空屏幕。但是 [[systemd (简体中文)|systemd]] 会在启动该服务之前清空屏幕。要关闭这项特性,请创建 {{ic|/etc/systemd/system/getty@tty1.service.d/noclear.conf}} 文件:<br />
<br />
{{hc|1=/etc/systemd/system/getty@tty1.service.d/noclear.conf|2=<br />
[Service]<br />
TTYVTDisallocate=no<br />
}}<br />
<br />
这将仅改写 TTY1 上的 ''agetty'' 的 {{ic|TTYVTDisallocate}} 参数,并保持全局服务文件 {{ic|/usr/lib/systemd/system/getty@.service}} 不变。可参阅 [[Systemd (简体中文)#修改现存单元文件]]。<br />
<br />
{{注意|<br />
* 确保从 [[Kernel parameters (简体中文)|内核参数]] 中移除了 {{ic|quiet}}。<br />
* KMS 晚启动可能会造成部分早期启动信息丢失。请参阅 [[Kernel mode setting (简体中文)#KMS 早启动]] 或 [[Kernel mode setting (简体中文)#禁用 KMS]]。<br />
}}<br />
<br />
== 参考资料 ==<br />
<br />
* [[Systemd (简体中文)#修改默认运行级别/目标]]<br />
* [http://www.linusakesson.net/programming/tty/ The TTY demystified]<br />
* [[Wikipedia:Tty (unix)]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Git_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539061
Git (简体中文)
2018-08-31T17:27:11Z
<p>Arisaka: Sync with English page.(move Bisecting bugs with Git from See also to Related articles)</p>
<hr />
<div>[[Category:Version Control System (简体中文)]]<br />
[[en:Git]]<br />
[[es:Git]]<br />
[[ja:Git]]<br />
{{TranslationStatus (简体中文)|Git|2018-08-31|536424}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Bisecting bugs with Git}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion (简体中文)}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}<br />
<br />
[[wikipedia:Git (software)|Git]] 是一个由 Linux 内核作者 Linus Torvalds 编写的版本控制系统(VCS),现在被用来维护 [[AUR]] 软件包以及数以千计的其他项目,其中包括 Linux 内核。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|git}} 软件包。要使用开发版本,请安装 {{AUR|git-git}} 软件包。当使用 ''git svn''、''git gui'' 和 ''gitk'' 等工具时请检查可选依赖项是否安装。<br />
<br />
=== 图形化前端 ===<br />
<br />
参考 [https://git-scm.com/download/gui/linux git GUI Clients]。<br />
<br />
* {{App|Giggle|用于 git 的 GTK+ 前端。|https://wiki.gnome.org/Apps/giggle/|{{Pkg|giggle}}}}<br />
* {{App|Git Cola|用 Python 编写的丝滑而强大的 git 图形前端。|https://git-cola.github.io/|{{AUR|git-cola}}}}<br />
* {{App|Git Extensions|允许用户不使用命令行就可以完成 git 各项操作的图形前端。|https://gitextensions.github.io/|{{AUR|gitextensions}}}}<br />
* {{App|gitg|用于查看 git 仓库的 GNOME GUI 客户端。|https://wiki.gnome.org/Apps/Gitg|{{Pkg|gitg}}}}<br />
* {{App|git-gui|Tcl/Tk 库编写的可移植 git 图形前端。|https://git-scm.com/docs/git-gui|{{Pkg|git}} + {{Pkg|tk}}}}<br />
:{{注意|要打开 ''git-gui'' 的拼写检查功能,请安装 {{Pkg|aspell}},同时还需要与 {{ic|LC_MESSAGES}} [[Environment variables (简体中文)|环境变量]] 相对应的字典文件。参阅 {{Bug|28181}} 和 [[aspell (简体中文)]]。}}<br />
* {{App|gitk|Tcl/Tk 库编写的 Git 仓库查看器。|https://git-scm.com/docs/gitk|{{Pkg|git}} + {{Pkg|tk}}}}<br />
* {{App|QGit|可图形化地按照不同开发分支显示修订历史记录、查阅补丁内容、查看被修改文件的 Git GUI 查看器。|https://github.com/tibirna/qgit|{{Pkg|qgit}}}}<br />
* {{App|[[Wikipedia:RabbitVCS|RabbitVCS]]|一组图形化工具,用于轻松、直接地访问您使用的版本控制系统。|http://rabbitvcs.org/|{{AUR|rabbitvcs}}}}<br />
* {{App|Tig|基于 ncurses 的 git 字符模式前端。|https://jonas.github.io/tig/|{{Pkg|tig}}}}<br />
* {{App|ungit|在不牺牲 git 各种功能的情况下使其变得更加友好。|https://github.com/FredrikNoren/ungit|{{AUR|nodejs-ungit}}}}<br />
<br />
<br />
<br />
== 配置 ==<br />
<br />
你至少需要设置好姓名和邮箱之后才能开始使用 Git:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@example.com''"<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE 起步 - 初次运行 Git 前的配置]。<br />
<br />
更多设置选项可参阅 [[#提示与技巧]]。<br />
<br />
== 基本用法 ==<br />
<br />
一个 Git 版本库包含在一个名为 {{ic|.git}} 的目录内,该目录包含了修订历史以及其他元数据。版本库所跟踪的目录(默认为父目录)称为工作目录。在工作树进行的更改在被提交 (commit) 前需要先暂存 (stage) 起来。Git 还可以让你恢复以前提交的工作树文件。<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E5%9F%BA%E7%A1%80 起步 - Git 基础]。<br />
<br />
=== 获取一个 Git 仓库 ===<br />
<br />
* 初始化一个版本库<br />
:{{ic|git init}},参阅 {{man|1|git-init}}<br />
* 克隆 (clone) 一个现有的版本库<br />
:{{ic|git clone ''repository''}},参阅 {{man|1|git-clone}}<br />
<br />
=== 记录更改 ===<br />
<br />
Git 管理的项目存在一个暂存区 (staging area),即 git 目录中的 {{ic|index}} 文件,其中保存了即将包含在你下一次提交中的文件更改。要将某个修改过的文件记录下来,首先需要将修改后的文件添加到 index(暂存它),然后用 {{ic|git commit}} 命令将当前的 index 保存为一次新的提交。<br />
<br />
==== 暂存 (stage) 更改 ====<br />
<br />
* 将工作树中的文件更改添加至 index<br />
:{{ic|git add ''pathspec''}},参阅 {{man|1|git-add}}<br />
* 移除 index 中记录的文件更改<br />
:{{ic|git reset ''pathspec''}},参阅 {{man|1|git-reset}}<br />
* 显示即将提交的更改、未暂存的更改以及未被 git 跟踪的文件<br />
:{{ic|git status}},参阅 {{man|1|git-status}}<br />
<br />
可以用 {{ic|.gitignore}} 文件来让 git 忽略某些未跟踪的文件,请参阅 {{man|5|gitignore}}。<br />
<br />
Git 不会跟踪文件移动。合并时的文件移动检测仅基于内容的相似性。{{ic|git mv}} 命令仅仅是为了方便,它相当于:<br />
<br />
$ mv -i foo bar<br />
$ git reset -- foo<br />
$ git add bar<br />
<br />
==== 提交 (commit) 更改 ====<br />
<br />
{{ic|git commit}} 命令将暂存区的更改保存至版本库,参阅 {{man|1|git-commit}}。<br />
<br />
* {{ic|-m}} – 后面跟上提交消息作为参数直接提交,而不是打开默认的文本编辑器来写提交信息后再提交<br />
* {{ic|-a}} – 自动暂存已更改或已删除的文件(不会添加未跟踪的文件)<br />
* {{ic|--amend}} – 重做上次提交,用于修改提交消息或修改提交的文件<br />
<br />
{{提示|建议经常性的提交小更改,并附上有意义的提交信息。}}<br />
<br />
==== 选择修订版本 ====<br />
<br />
Git 提供了多种方式来指定修订版本,参阅 {{man|7|gitrevisions}} 和 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC 选择修订版本]。<br />
<br />
许多 Git 命令需要用修订版本作为参数。一次提交记录可以用下列任何一种方式表示:<br />
<br />
* 某次提交的 SHA-1 哈希值(前7位通常足以唯一标识它)<br />
* 任意提交时的标签,如分支名称或 tag 名称<br />
* 标签 {{ic|HEAD}} 总是指向当前 check out 的提交(通常是分支的头部,除非你使用 ''git checkout'' 跳回到历史记录中的旧提交)<br />
* 以上任意一种表示方式加上 {{ic|~}} 都可以表示之前的提交。例如,{{ic|HEAD~}} 指向 {{ic|HEAD}} 的前一次提交,{{ic|HEAD~5}} 指向 {{ic|HEAD}} 5 次前的提交。<br />
<br />
==== 查看更改 ====<br />
<br />
查看不同提交间的修改处:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
或者查看暂存区和工作树之间的不同:<br />
<br />
$ git diff<br />
<br />
查看修改历史(其中 "''-N''" 指定最近的 n 次修改):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
=== 撤销修改 ===<br />
<br />
* {{ic|git reset}} - 重置当前 HEAD 指针到指定状态,参阅 {{man|1|git-reset}}<br />
<br />
* {{ic|git checkout}} - 恢复工作树中的文件,参阅 {{man|1|git-checkout}}<br />
<br />
=== 分支 (branch) ===<br />
<br />
Bug 修复和新功能通常在不同分支里测试。当一切就绪时它们就可以合并至默认(主)分支。<br />
<br />
创建一个分支,其名称准确地反映了其目的:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
列出已存在的分支:<br />
<br />
$ git branch<br />
<br />
切换分支:<br />
<br />
$ git checkout ''branch''<br />
<br />
新建分支并切换至该分支:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
将一个分支合并回主分支:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
如果不存在冲突的话,所有更改将被合并。否则 Git 将显示一条错误信息,并通过给工作树中的文件加注释来记录冲突。添加的注释可以用 {{ic|git diff}} 显示。要解决冲突,必须编辑文件,删除注释,并提交最终版本。请参阅下面的 [[#处理合并 (merge)]]。<br />
<br />
当一个分支使用完毕,可以这样删除:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== 多人合作 ===<br />
<br />
一个典型的 Git 工作流像这样:<br />
<br />
# 创建一个新仓库或克隆一个远程仓库。<br />
# 新建一个分支用于修改文件,然后提交这些修改。<br />
# 将多次提交合并在一起,这样更便于组织项目或更好地理解。<br />
# 把提交的分支合并回主分支。<br />
# (可选)将更改推送至远程服务器。<br />
<br />
==== 合并请求 (pull requests) ====<br />
<br />
在做出并提交更改后,贡献者可以请求原作者合并更改。这被称为 ''合并请求 (pull request)''。<br />
<br />
如果用 pull:<br />
<br />
$ git pull ''location'' master<br />
<br />
''pull'' 命令相当于 ''fetch'' 和 ''merge'' 命令的结合。如果存在冲突(比如原作者在同一时间段内在相同位置做了更改),那就有必要手动解决冲突。<br />
<br />
另一种方式是,原作者可以选择想要合并的更改。通过使用 ''fetch'' 命令(以及带有特殊 {{ic|FETCH_HEAD}} 标记的 ''log'' 命令),可以在决定如何处理合并请求 (pull request) 前查看该请求的内容:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== 使用远程仓库 (remote) ====<br />
<br />
远程 (remote) 是和本地相关联的远程仓库的别名。其实就是创建一个 ''label'' 来定义一个位置。这些 label 用于标识经常访问的仓库。<br />
<br />
添加一个远程仓库:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
获取远程库里的内容:<br />
<br />
$ git fetch ''label''<br />
<br />
显示本地主分支与远程主分支之间的差异:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
查看当前仓库相关联的远程仓库:<br />
<br />
$ git remote -v<br />
<br />
当设置的远程仓库是本仓库的 fork 来源(项目的领导者),这个远程仓库会被定义为 ''upstream''(上游)。<br />
<br />
==== 向某个仓库推送 (push) 修改 ====<br />
<br />
从原作者处获得推送修改的权限之后,使用以下命令推送修改:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
当使用 ''git clone'' 获得这个仓库后,git 会把仓库的原始地址记录在名为 {{ic|origin}} 的变量中。<br />
<br />
所以一次 ''典型的'' 推送可以这样做: <br />
<br />
$ git push origin master<br />
<br />
如果使用了 {{ic|-u}} ({{ic|--set-upstream-to}}) 选项,地址将会被记录下来,下次只要使用 {{ic|git push}} 就可以了。<br />
<br />
==== 处理合并 (merge) ====<br />
<br />
可以查看 Git Book 的 [https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6#遇到冲突时的分支合并 遇到冲突时的分支合并] 部分了解如何处理合并冲突。合并操作通常是可逆的,如果想返回合并前,可以使用 {{ic|--abort}} 命令(比如 {{ic|git merge --abort}} 或 {{ic|git pull --abort}})。<br />
<br />
=== 历史记录和版本记录 ===<br />
<br />
==== 在历史记录中搜索 ====<br />
<br />
{{ic|git log}} 命令可以显示历史记录信息,其中包含每次提交的校验和、作者、日期,以及简略信息。''校验和'' 就是一次提交对象的 "对象名称",通常是一个 40 位的 SHA-1 哈希值。<br />
<br />
对于具有较长信息的历史记录(其中 "''checksum''" 可以截取前几位,只要它是唯一的):<br />
<br />
$ git show (''checksum'')<br />
<br />
在被跟踪的文件中搜索 ''pattern'':<br />
<br />
$ git grep ''pattern''<br />
<br />
在 {{ic|.c}} 和 {{ic|.h}} 文件中搜索:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== 使用标签 (tag) ====<br />
<br />
给某次提交打标签来标记这个版本:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tag'' 通常是用于 [https://www.drupal.org/node/1066342 发布/标记版本] 的,但它可以是任何字符串。通常使用带注释的标签,因为它们会被添加到 Git 数据库中。<br />
<br />
标记当前的提交:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
列出标签:<br />
<br />
$ git tag -l<br />
<br />
删除某个标签:<br />
<br />
$ git tag -d 2.08<br />
<br />
更新远程库中的标签:<br />
<br />
$ git push --tags<br />
<br />
==== 重新组织 commit ====<br />
<br />
在提交合并请求之前,可能需要合并/重新组织 commit。这是通过 ''git rebase''(变基){{ic|--interactive}}完成的:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
然后会打开文本编辑器,其中包含指定范围内所有提交的摘要;这种情况下会包括最新提交 ({{ic|HEAD}}),但不包括 {{ic|''checksum''}} 表示的那次 commit。也可以使用数字来标记,例如用 {{ic|HEAD~3}},这会把最后三次提交变基:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
修改第一栏中的动作可以决定如何执行变基操作。可选的动作有:<br />
<br />
* {{ic|pick}} — 原样保留每次提交(默认)。<br />
* {{ic|edit}} — 编辑文件和/或 commit 信息。<br />
* {{ic|reword}} — 编辑 commit 信息。<br />
* {{ic|squash}} — 合并/折叠到先前的提交中。<br />
* {{ic|fixup}} — 合并/折叠到先前的提交中并丢弃它们的信息。<br />
<br />
提交会被重新排序或从历史记录中擦除(所以要非常小心)。编辑文件后,Git 将执行指定的操作;如果提示有合并问题待解决,请解决它们并使用 {{ic|git rebase --continue}} 来继续,或使用 {{ic|git rebase --abort}} 命令来取消操作。<br />
<br />
{{注意|合并多次提交的操作只能应用于本地提交,它会导致其他人共享的存储库出现问题。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
=== 使用 git-config ===<br />
<br />
Git 从 4 个 ini 类型的配置文件里读取配置:<br />
<br />
* {{ic|/etc/gitconfig}} 是应用于整个系统的默认配置文件<br />
* {{ic|~/.gitconfig}} 和 {{ic|~/.config/git/config}} (自 1.7.12 起)是应用于特定用户的配置文件<br />
* {{ic|.git/config}} 是应用于特定仓库的配置文件<br />
<br />
这些文件可以直接编辑,但是更常用的方法是使用 ''git config'',下面是一些示范。<br />
<br />
列出当前已配置的变量:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
将默认文本编辑器从 [[vim]] 改成 [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
设置默认的推送 (push) 行为:<br />
<br />
$ git config --global push.default simple<br />
<br />
设置不同的 ''git difftool'' 工具(默认是 ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
更多信息请参阅 {{man|1|git-config}} 和 [https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git 配置 Git]。<br />
<br />
=== 保持良好的礼仪 ===<br />
<br />
* 当你想为一个现有的项目贡献时,请先阅读并理解这个项目的许可,因为它可能会过度限制你更改代码的权力。有些许可会在代码的所有权方面引起争议。<br />
* 理解这个项目的社区,以及你可以融入其中的程度。要了解项目的主要方向,可以阅读所有文档甚至是代码库的 [[#历史记录和版本记录|log]]。<br />
* 当发起一个合并请求,或者提交一个补丁时,保证它是小改动并且有完善的文档;这将有助于项目维护者理解你的改动,并决定是否合并这些改动或是让你再改一下。<br />
* 如果贡献被拒绝,不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清楚和耐心地讨论这次贡献的理由,最终可能通过这种方法解决问题。<br />
<br />
=== 加快身份验证 ===<br />
<br />
每次向 Git 服务器推送时都要认证身份,你可能会想要避免这种麻烦。<br />
<br />
* 如果你是用 SSH 密钥来认证的,请使用 [[SSH keys (简体中文)#SSH agents|SSH agents]]。参阅 [[Secure Shell (简体中文)#加速 SSH]] 和 [[Secure Shell (简体中文)#保持在线]]。<br />
* 如果你是用账号和密码来认证的,在服务器支持 SSH 的情况下请切换至 [[SSH keys (简体中文)|SSH keys]], 否则请尝试 [https://git-scm.com/docs/git-credential-cache git-credential-cache] 或 [https://git-scm.com/docs/git-credential-store git-credential-store]。<br />
<br />
=== 默认通讯协议 ===<br />
<br />
如果你正在使用一个上述那种复用的 SSH 连接,让 Git 使用 SSH 可能比使用 HTTPS 更快。同时,一些服务器(比如 AUR)只允许通过 SSH 推送更改。例如,像下面这样配置可以使得 Git 通过 SSH 访问 AUR 上的任何仓库。<br />
<br />
{{hc|~/.gitconfig|<nowiki><br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
</nowiki>}}<br />
<br />
=== Bash 自动补全 ===<br />
<br />
要启用 Bash 的自动补全,请在 [[Bash#Configuration_files|Bash 启动文件]] 里用 source 加载 {{ic|/usr/share/git/completion/git-completion.bash}} 文件。或者也可以安装 {{pkg|bash-completion}}。<br />
<br />
=== Git 提示符 ===<br />
<br />
Git 包带有一个提示符脚本。要启用它,请用 source 加载 {{ic|/usr/share/git/completion/git-prompt.sh}} 脚本,然后使用 {{ic|%s}} 参数设置一个自定义 shell 提示符:<br />
<br />
* [[Bash]] 用户: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* [[zsh]] 用户: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
要自动完成这项工作,请参阅 [[Command-line shell#Configuration files]]。<br />
<br />
当切换至一个 Git 仓库所在目录时,shell 提示符会变成所在分支名称。也可以配置提示符来显示其他信息:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || 已暂存 (staged) 显示 '''+''',未暂存 (unstaged) 显示 '''*'''。<br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || 已储藏 (stashed) 显示 '''$'''。<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || 有未跟踪文件时显示 '''%'''。<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' 分别表示落后于上游、领先于上游、偏离上游。<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} 需要设置为 {{ic|auto}} 才能使更改生效。<br />
<br />
{{注意|如果发生了 {{ic|$(__git_ps1)}} 返回 {{ic|((unknown))}} 的情况,是因为有一个 {{ic|.git}} 文件夹在你当前的文件夹里面,但却不包含任何存储库,因此 Git 不认识它。这有可能发生在你把 {{ic|~/.git/config}} 误认为是 Git 的配置文件而不是 {{ic|~/.gitconfig}}。}}<br />
<br />
你也可以使用来自 [[AUR]] 的自定义 git shell 提示符软件包,例如 {{AUR|bash-git-prompt}} 或 {{AUR|gittify}}。<br />
<br />
=== 可视化显示 ===<br />
<br />
要了解已经完成了多少工作:<br />
<br />
$ git diff --stat<br />
<br />
带有 fork 显示的 ''git log'':<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
给图形化的 ''git log'' 做一个别名(使用 ''git graph'' 即可显示经过修饰的 log):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
=== 关于提交 (commit) 的小提示 ===<br />
<br />
重置为以前的提交(非常危险,这将会擦除所有内容并改写为特定提交):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
如果远程仓库的地址发生变化,可以这样更新它的位置:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
自动附加签名行到提交(将某个 姓名-电邮 签名添加到提交中,某些项目会要求这样做):<br />
<br />
$ git commit -s<br />
<br />
自动附加签名到补丁(使用 {{ic|git format-patch ''commit''}} 时生效):<br />
<br />
$ git config --local format.signoff true<br />
<br />
提交已更改文件的特定部分。如果有大量更改时,最好拆分成多个提交,这种情况下这个命令通常很有用:<br />
<br />
$ git add -p<br />
<br />
=== 对提交 (commit) 签名 ===<br />
<br />
Git 允许使用 [[GnuPG (简体中文)|GnuPG]] 对提交和标签进行签名,请参见 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C 签署工作]。<br />
<br />
{{注意|<br />
如果是借助 {{Pkg|pinentry}} 来进行 GPG 签名,请确保 {{ic|1=export GPG_TTY=$(tty)}}(或者使用 pinentry-tty),否则当 GPG 处于锁定状态时签名这一步会失败(因为它无法在 shell 提示符里询问 pin 码)。}}<br />
<br />
配置 Git 使它自动对提交进行签名:<br />
<br />
$ git config --global commit.gpgSign true<br />
<br />
=== 在非主分支上工作 ===<br />
<br />
偶尔项目维护人员会要求你在其他分支上完成工作。这些分支通常被称为 {{ic|devel}} 或 {{ic|testing}}。首先要克隆存储库。<br />
<br />
要进入不是主分支的分支(''git clone'' 只会显示主分支,但其他分支其实也是存在的,用 {{ic|git branch -a}} 可以显示出来):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
然后就可以像平常一样编辑文件,但是要使得整个仓库都保持同步,下面这两个命令都要用:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
=== 直接将补丁发送至邮件列表 ===<br />
<br />
如果你想直接将补丁发送至一个邮件列表,需要安装以下软件包:{{Pkg|perl-authen-sasl}},{{Pkg|perl-net-smtp-ssl}} 和 {{Pkg|perl-mime-tools}}。<br />
<br />
确保你已经配置了用户名和邮件地址,可参阅 [[#配置]]。<br />
<br />
配置你的邮箱设置:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.example.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@example.com''<br />
<br />
现在你应该可以将补丁发送至某个邮件列表了(可参阅[http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
=== 远程库很大时的注意事项 ===<br />
<br />
{{Style|<br />
此处使用了非正式的表达、缩写、HTML 标签(而不是代码模板),且没有使用 wiki 内链接。}}<br />
<br />
当远程库很大时该怎么办?请参考这一节。其中的示例来自于 linux kernel。<br />
<br />
==== 最简单的方式:接收整个仓库 ====<br />
<br />
你可以这样接收整个仓库:<br />
<br />
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git<br />
<br />
下载时间会很长,而且 "git clone" 无法断点续传(截止至 2018 年 8 月),还会占用很多硬盘空间。<br />
<br />
可以用这个命令更新仓库<br />
$ git pull<br />
<br />
==== 部分接收 ====<br />
也许你想把本地仓库的大小限制得小一点,比如只保留 v4.14 以后的代码来分离出一个 bug,那么可以这么做:<br />
<br />
$ git clone --shallow-exclude v4.13 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # 这样就只会下载 v4.14 及以后的文件,v4.13 以前的不会下载。<br />
<br />
也许你只需要最新的仓库快照,忽略所有的历史记录。(如果有压缩包提供且足够使用,那就下载压缩包,获取 git 仓库快照开销要大一点。)可以这样做:<br />
<br />
$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git<br />
<br />
之后也可以这样获取历史提交记录:<br />
<br />
$ git fetch --tags --shallow-exclude v4.1 # 获取 v4.1 之后的提交记录<br />
$ git fetch --tags --shallow-since 2016-01-01<br />
<br />
如果没有 <code>--tags</code>,那么就接收不到 tags。<br />
<br />
==== 获取其他分支 ====<br />
在上面的示例中,你本地的仓库仅跟踪主线内核,即“最近开发完成”的内核。假设你想获取最近的 “LTS” 版内核,比如最新的 4.14 分支,可以这么做:<br />
<br />
$ git remote set-branches --add origin linux-4.17.y<br />
$ git fetch<br />
$ git branch --track linux-4.17.y origin/linux-4.17.y<br />
<br />
最后一行不是必须的,但你应该需要执行它。<br />
(要获取你需要的那个分支的具体名称,没有什么通用的方法,或许可以靠 web 页面的 "ref" 链接来猜测)<br />
<br />
如果需要 linux-4.17.y 的快照,这样做:<br />
<br />
$ git checkout -b linux-4.17.y<br />
<br />
或者这样做,将它解压到其他目录里:<br />
<br />
$ mkdir /foo/bar/src-4.17; cd /foo/bar/src-4.17<br />
$ git clone --no-local --depth 1 -b linux-4.17.y ../linux-stable<br />
<br />
然后像平常一样,执行 <code>git pull</code> 来更新你的快照。<br />
<br />
==== 未来可能出现的其他方案 ====<br />
Git 虚拟文件系统 (Git Virtual Filesystem, GVFS) 由微软开发,允许在不克隆仓库至本地的情况下使用 git 仓库。(参阅 [https://blogs.msdn.microsoft.com/bharry/2017/05/24/the-largest-git-repo-on-the-planet/ this Microsoft blog] 或 [[wikipedia:Git_Virtual_File_System|Wikipedia artcile]]。)这个功能在 Linux 暂不可用。<br />
<br />
无论如何这个功能暂不适用于上述示例中的 Linux 内核仓库。<br />
<br />
== Git 服务器 ==<br />
<br />
这一节讲述如何配置使用不同的协议连接到存储库。<br />
<br />
=== SSH 协议 ===<br />
<br />
要使用 SSH 协议,首先要准备一个 SSH 公钥,可以按照 [[SSH keys (简体中文)]] 的指导来完成。要配置一个 SSH 服务器,请遵循 [[Secure Shell (简体中文)]] 的指导。<br />
<br />
当 SSH 生成了密钥之后,将 {{ic|~/.ssh/id_rsa.pub}} 文件的内容粘贴至服务器上的 {{ic|~/.ssh/authorized_keys}} 文件里(一行一个,同一个公钥确保在同一行)。现在 Git 仓库可以通过 SSH 来访问:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
现在,如果你的 SSH 客户端的 {{ic|StrictHostKeyChecking}} 选项设为了 {{ic|ask}}(默认),你应该会收到来自 SSH 的问题,要你回答 yes/no。输入 {{ic|yes}} 然后回车,你的仓库就能被取出。同时,由于通过 SSH 协议访问,你现在应该有提交权限。<br />
<br />
要把一个已存在的仓库改成使用 SSH 访问,需要重新定义一下远程地址:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
要从非 22 端口连接,可以在每台主机的 {{ic|/etc/ssh/ssh_config}} 或 {{ic|~/.ssh/config}} 里配置。要为某个本地仓库设置端口(示例中用的 443 端口):<br />
<br />
{{hc|.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
你可以通过只允许用户执行 push 和 pull 操作来进一步提高 SSH 账户的安全性。这是通过将该账户的默认登录 shell 换成 git-shell 来实现的。在 [https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8 配置服务器] 中对此有所描述。<br />
<br />
=== Smart HTTP 协议 ===<br />
<br />
通过使用 git-http 后端,Git 可以像使用 SSH 协议或 Git 协议一样高效地使用 HTTP(S) 协议。此外,它不仅可以从仓库中克隆或拉取更改,还可以通过 HTTP(S) 推送更改。<br />
<br />
这个设置相当简单,因为你只需要安装 Apache Web 服务器({{pkg|apache}},启用 {{ic|mod_cgi}}、{{ic|mod_alias}} 和 {{ic|mod_env}}),当然还要安装 {{pkg|git}}。<br />
<br />
当你正在进行基本设置时,请将以下内容添加到 Apache 配置文件中,该配置文件通常位于:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
这里假设你的 Git 仓库位于 {{ic|/srv/git}},并且你想用类似 {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}} 的方式来访问它们。<br />
<br />
{{注意|请确保 Apache 对你的仓库有读写权限。}}<br />
<br />
如果需要更多详细文档,请访问:<br />
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP<br />
* https://git-scm.com/docs/git-http-backend<br />
<br />
=== Git 协议 ===<br />
<br />
{{注意|Git 协议没有加密或认证机制,且只允许读取。}}<br />
<br />
[[start|Start 并且 enable]] {{ic|git-daemon.socket}} 这个 systemd 单元。<br />
<br />
守护程序会带有以下选项启动:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
位于 {{ic|/srv/git/}} 目录下的仓库会被守护程序识别。客户端能以类似这样的方式连接:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== 设置访问权限 ===<br />
<br />
要限制读取和/或写入权限,可以使用常规 Unix 权限控制。更多信息请参考 [https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill]。<br />
<br />
如果需要更加精细的访问控制,请参考 [[gitolite]] 和 [[gitosis]]。<br />
<br />
== 参考资料 ==<br />
<br />
* Git 手册页:{{man|1|git}}<br />
* [https://git-scm.com/book/en/ Pro Git book]<br />
* 来自 GitHub 的 [https://git.github.io/git-reference/ Git Reference] <br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]<br />
* [https://wiki.videolan.org/Git VideoLAN wiki article]<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Transmission_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539059
Transmission (简体中文)
2018-08-31T17:24:01Z
<p>Arisaka: Sync with English page.(add non git version of tremc)</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:BitTorrent clients (简体中文)]]<br />
[[de:Transmission]]<br />
[[en:Transmission]]<br />
[[fr:Transmission]]<br />
[[it:Transmission]]<br />
[[ja:Transmission]]<br />
{{TranslationStatus (简体中文)|Transmission|2018-08-31|532639}}<br />
[http://www.transmissionbt.com/ Transmission] 是一个轻量级、跨平台的 BitTorrent 客户端。<br />
<br />
== 安装 ==<br />
<br />
有多种可选的软件包:<br />
* {{Pkg|transmission-cli}} - 包括命令行工具、守护程序和 [[#Web 界面]]。<br />
* {{Pkg|transmission-gtk}} - GTK+ 3 图形界面.<br />
* {{Pkg|transmission-qt}} - Qt5 图形界面.<br />
* {{AUR|tremc}} 或 {{AUR|tremc-git}} - 用于守护程序的 Curses 界面。<br />
<br />
{{注意| GTK+ 客户端无法连接至守护程序,想用守护程序的用户可以考虑带图形界面的 Qt 包,或是带 Curses 界面的 tremc 包。}}<br />
<br />
== 图形界面的配置 ==<br />
<br />
两种带 GUI 的版本 ''transmission-gtk'' 和 ''transmission-qt'' 都可以在没有后端守护程序的情况下独立运行。<br />
<br />
GUI 版本都被配置为开箱即用,但用户可能仍需要更改一些设置。GUI 配置文件的默认路径是 {{ic|~/.config/transmission}}。<br />
<br />
在 Transmission 的网站上,有一份各种选项如何配置的教程:<br />
https://github.com/transmission/transmission/wiki/Editing-Configuration-Files.<br />
<br />
== Transmission 守护程序和命令行 ==<br />
<br />
''transmission-cli'' 支持的命令包括:<br />
:''transmission-daemon'': 启动守护程序。<br />
:''transmission-remote'': 调用本地或远程守护程序的 [[Wikipedia:Command-line interface|命令行界面]],后面跟着希望守护程序运行的命令。<br />
:''transmission-show'': 返回指定种子文件的信息。<br />
:''transmission-create'': 创建一个新的种子文件。<br />
:''transmission-edit'': 新增、删除或替换一个 tracker 服务器的 announce URL。<br />
:''transmission-cli'': ([https://github.com/transmission/transmission/commit/950387ab5a443629598f93c057f41150707866ab 已弃用]) 启动一个非守护程序的本地 ''transmission'' 实例,用于手动下载一个种子。<br />
:''tremc'': (需要 {{AUR|tremc-git}}) 为本地或远程守护程序启动一个 [[Wikipedia:curses (programming library)|curses]] 界面。<br />
<br />
=== 守护程序的启动与停止 ===<br />
<br />
就像 [[#选择一个用户]] 里面的说明那样,transmission 的守护程序可以按以下方式运行:<br />
<br />
* 作为 ''transmission'' 用户运行,只要 [[systemd (简体中文)#使用单元|用 systemd]] start/enable {{ic|transmission.service}} 服务即可。<br />
: 你可以按照 [[#选择一个用户]] 里的说明更改默认用户。<br />
<br />
* 用你自己的账户,只要在账户下运行:{{bc|$ transmission-daemon}} 守护程序可以这样来停止:{{bc|$ killall transmission-daemon}}<br />
<br />
启动守护程序将会创建一个初始的 ''transmission'' 配置文件。详情参阅 [[#配置守护程序]]。<br />
<br />
另一种停止 transmission 的方法是使用 ''transmission-remote'' 命令:<br />
$ transmission-remote --exit<br />
<br />
<br />
=== 减少多余的日志 ===<br />
<br />
运行 transmission-daemon 可能会产生许多不需要的日志条目。只要用一个小脚本包装一下再启动就可以过滤日志输出。以下示例可以提供一些启发:<br />
{{hc|transwrap.sh|<nowiki><br />
#!/bin/zsh<br />
killall transmission-daemon 2> /dev/null<br />
transmission-daemon --foreground --log-info 2>&1 | while read line; do<br />
echo $line |<br />
grep -v "announcer.c:\|platform.c:\|announce done (tr-dht.c:" |<br />
grep -v "Saved.*variant.c:" |<br />
while read line; do<br />
echo $line | grep -q "Queued for verification (verify.c:" &&<br />
notify-send --app-name="Transmission Started" "${line#* * }"<br />
echo $line | grep -q "changed from .Incomplete. to .Complete." &&<br />
notify-send --app-name="Transmission Complete" "${line#* * }"<br />
echo $line | systemd-cat --identifier="TransWrap" --priority=5<br />
done 2>&1 > /dev/null<br />
done&disown<br />
</nowiki><br />
}}<br />
<br />
=== 仅当连接到网络时运行 ===<br />
<br />
==== Netctl ====<br />
<br />
你可能只想在连接某些网络时运行 transmission。下面的脚本会先检查连接是否在授权的网络列表中,是的话再继续启动 transmission-daemon。<br />
<br />
{{hc|/etc/netctl/hooks/90-transmission.sh|<nowiki><br />
#!/bin/bash<br />
<br />
# The SSIDs for which we enable this.<br />
declare -A ssids=(<br />
["network_1"]=y<br />
["network_2"]=y<br />
)<br />
<br />
if [[ ${ssids[$SSID]} ]]; then<br />
case $ACTION in<br />
CONNECT|REESTABLISHED)<br />
# Need to wait, otherwise doesn't seem to bind to 9091.<br />
sleep 30<br />
systemctl start transmission<br />
;;<br />
*)<br />
systemctl stop transmission<br />
;;<br />
esac<br />
fi<br />
</nowiki><br />
}}<br />
<br />
==== Wicd ====<br />
<br />
在文件夹 {{ic|/etc/wicd/scripts/postconnect}} 里创建一个 [[#守护程序的启动与停止|启动脚本]],并且在文件夹 {{ic|/etc/wicd/scripts/predisconnect}} 里创建一个 [[#守护程序的启动与停止|停止脚本]]。记得给它们运行权限,例如:<br />
<br />
{{hc|/etc/wicd/scripts/postconnect/transmission|2=<br />
#!/bin/bash<br />
<br />
systemctl start transmission<br />
}}<br />
{{hc|/etc/wicd/scripts/predisconnect/transmission|2=<br />
#!/bin/bash<br />
<br />
systemctl stop transmission<br />
}}<br />
<br />
=== 选择一个用户 ===<br />
<br />
选择你想如何运行 {{ic|transmission}}:<br />
<br />
* 作为独立用户运行,默认用户是 {{ic|transmission}}(推荐,因为安全性更高)。<br />
默认情况下,''transmission'' 会创建名为 {{ic|transmission}} 的用户和组(它的主目录的文件位于 {{ic|/var/lib/transmission/}}),并且用这个“账户”运行。这是一种安全措施,因为这样 ''transmission'' 及其下载的文件将无法访问 {{ic|/var/lib/transmission/}} 目录之外的文件。配置、操作和访问下载的文件需要使用 “root” 权限完成(比如用 [[sudo]])。<br />
<br />
* 在你自己的账户下运行。<br />
设置这种方式需要 [[systemd (简体中文)#修改现存单元文件|重写]] 已提供的服务文件并在其中指定你的用户名:<br />
<br />
{{hc|/etc/systemd/system/transmission.service.d/username.conf|2=<br />
[Service]<br />
User=''your_username''<br />
}}<br />
<br />
=== 配置守护程序 ===<br />
<br />
[[#守护程序的启动与停止|启动守护程序]] 来创建缺省的配置文件。<br />
<br />
* 如果用 {{ic|transmission}} 这个用户来运行 Transmission,配置文件会存放在 {{ic|/var/lib/transmission/.config/transmission-daemon/settings.json}}。<br />
<br />
* 如果用你自己的账户运行 Transmission,配置文件会存放在 {{ic|~/.config/transmission-daemon/settings.json}}。<br />
<br />
使用一个 Transmission 客户端或者用自带的 web 界面(在支持的浏览器中用 http://localhost:9091 来访问)可以自定义守护程序。<br />
<br />
在 Transmission 的网站上,有一份各种选项如何配置的教程:https://github.com/transmission/transmission/wiki/Editing-Configuration-Files<br />
<br />
{{注意|如果你想用一个文本编辑器手动编辑配置文件,请先 [[#守护程序的启动与停止|停止守护程序]];否则当它停止时将会覆盖配置文件。}}<br />
{{注意|另一种方式是,可以用 SIGHUP 信号指示守护程序重新加载其配置,运行 {{ic|kill -s SIGHUP `pidof transmission-daemon`}} 即可。}}<br />
<br />
一个给那些用 {{ic|transmission}} 账户运行的用户的建议是,用适当的权限创建一个共享的下载目录,这样就能同时允许 {{ic|transmission}} 账户和其他账户访问下载文件,也能相应地更新配置文件。例如:<br />
# mkdir /mnt/data/torrents<br />
# chown -R facade:transmission /mnt/data/torrents<br />
# chmod -R 775 /mnt/data/torrents<br />
<br />
现在 {{ic|/mnt/data/torrents}} 目录可供系统账户 {{ic|facade}} 和 {{ic|transmission}} 用户所属的 {{ic|transmission}} 组访问。非常不鼓励使这个目录可读写(即不要将目录 ''chmod'' 到 ''777''),而是应该将个别用户/组的部分权限授予部分目录。<br />
<br />
{{注意|如果 {{ic|/mnt/data/torrents}} 位于一个可移除的设备上,比如这是一个 {{ic|/etc/fstab}} 条目且带有 {{ic|nofail}} 选项,那么 Transmission 会报告说没有找到文件。要解决这个问题,可以在 {{ic|/etc/systemd/system/transmission.service.d/transmission.conf}} 文件的 {{ic|[Unit]}} 一节中加入 {{ic|1=RequiresMountsFor=/mnt/data/torrents}}。}}<br />
<br />
另一种方法是把你的账户加入 {{ic|transmission}} 用户组 ({{ic|#usermod -a -G transmission yourusername}}),然后修改 {{ic|/var/lib/transmission}} 和 {{ic|/var/lib/transmission/Downloads}} 目录的权限设置,以允许 {{ic|transmission}} 组成员对这两个目录的 {{ic|rwx}} 访问权。<br />
<br />
==== Host 白名单 ====<br />
<br />
如果你想用远程主机的主机名来访问位于该主机上的 Transmission 守护程序,你需要把主机名加入 {{ic|settings.json}} 文件中的 {{ic|rpc-host-whitelist}} 字段中。<br />
否则你会在连接主机时收到一条 "421 Misdirected Request" 错误。<br />
<br />
如果你用该服务器的 IP 地址来访问守护程序,这一步可以省略。<br />
<br />
==== 监视目录 ====<br />
<br />
如果你想 ''自动添加某个文件夹中的 .torrent 文件'',但是配置文件中的 {{ic|watch-dir}} 和 {{ic|watch-dir-enabled}} 选项都不起作用,可以带 {{ic|-c /path/to/watch/dir}} 参数启动 transmission 守护程序。<br />
<br />
如果你在用 systemd,按照 [[systemd (简体中文)#修改现存单元文件]] 里面的描述编辑 {{ic|transmission.service}} 单元文件。<br />
<br />
==== 启用 IPv6 ====<br />
<br />
默认情况下,守护程序仅监听 IPv4 连接。要同时监听 IPv6 连接,安装 {{AUR|transmission-cli-ipv6}} (或者 {{AUR|transmission-cli-git}},或者等 Transmission 3.0 发布),然后把 {{ic|settings.json}} 里的 {{ic|rpc-bind-address}} 选项改为 {{ic|"::"}}。<br />
<br />
==== CLI 使用示范 ====<br />
<br />
如果你想删除所有已完成的种子,可以用下面的命令(用你自己的用户名和密码):<br />
# transmission-remote -n 'username:password' -l | grep 100% | awk '{print $1}'| paste -d, -s | xargs -i transmission-remote -t {} -r<br />
<br />
== Web 界面 ==<br />
<br />
=== GUI 方式 ===<br />
<br />
当 Transmission 安装完毕后就可以轻易架起 web 界面。你只需要单击 '''edit''' 菜单,选择 '''preferences'''。单击 '''Remote''' 选项卡并启用 '''Allow remote access'''。<br />
<br />
此处你可以修改默认的监听端口 9091。<br />
<br />
单击 '''Use authentication''' 并填写用户名和密码就可以启用身份认证。<br />
<br />
要提高安全性,可以启用 '''Only allow these IP addresses''' 限制来自任意 IP 的访问。<br />
<br />
现在你可以单击 '''Open web client''' (用你的默认浏览器打开)或手动访问 {{ic|http://''TARGET_IP_ADDRESS'':''PORT''}} 来启动 web 界面。<br />
<br />
如果没有修改监听端口,默认是 9091。在这种情况下访问链接是 {{Ic|http://localhost:9091}}。<br />
<br />
{{注意|记住,必须安装 {{Pkg|transmission-cli}}。}}<br />
<br />
=== CLI 方式 ===<br />
<br />
设置 web 界面甚至不需要借助图形界面,因为守护程序提供了类似的选项。你无需指定任何参数即可访问 web 界面,可参阅 [[#守护程序的启动与停止]]。<br />
<br />
不过,你仍然可以指定在前一节中看到的所有选项:<br />
<br />
{{bc|$ transmission-daemon --auth --username arch --password linux --port 9091 --allowed "127.0.0.1"}} <br />
等同于<br />
{{bc|$ transmission-daemon -t -u arch -v linux -p 9091 -a "127.0.0.1"}}<br />
<br />
== 故障排除 ==<br />
<br />
==== 无法使用网络连接至守护程序 ====<br />
<br />
在 {{ic|network.service}} 初始化后守护程序就会开始运行。但是,如果启用了 {{ic|dhcpcd}} 服务而不是特定设备的服务(比如 {{ic|dhcpcd@enp1s0.service}}),可能 Transmission 会因为启动过早而无法绑定到相应的网络接口。于是 web 界面无法访问。一种可能的解决方案是在 systemd 单元的 [[systemd (简体中文)#修改现存单元文件|配置文件]] 里增加 {{ic|Requires}} 行。<br />
<br />
{{hc|/etc/systemd/system/transmission.service.d/fixdep.conf|2=<br />
[Unit]<br />
Requires=network.target<br />
}}<br />
<br />
==== 无法显示 Web 界面 ====<br />
<br />
{{bc|404: Not Found<br />
<br />
Couldn't find Transmission's web interface files!<br />
<br />
Users: to tell Transmission where to look, set the TRANSMISSION_WEB_HOME environment variable to the folder where the web interface's index.html is located.<br />
<br />
Package Builders: to set a custom default at compile time, #define PACKAGE_DATA_DIR in libtransmission/platform.c or tweak tr_getClutchDir () by hand.}}<br />
<br />
即使你用图形界面,也需要安装 {{Pkg|transmission-cli}} 来支持 web 界面。<br />
<br />
== 更多信息 ==<br />
*[https://trac.transmissionbt.com/wiki Transmission 维基]<br />
*[https://trac.transmissionbt.com/wiki/HeadlessUsage/General HeadlessUsage]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Core_utilities_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=539036
Core utilities (简体中文)
2018-08-31T16:19:29Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:Command-line (简体中文)]]<br />
[[en:Core utilities]]<br />
[[es:Core utilities]]<br />
[[fa:Core utilities]]<br />
[[it:Core utilities]]<br />
[[ja:Core Utilities]]<br />
[[ko:Core utilities]]<br />
[[pt:Core utilities]]<br />
[[ru:Core utilities]]<br />
[[zh-hant:Core utilities]]<br />
{{TranslationStatus (简体中文)|Core_Utilities|2018-08-31|538932}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Command-line shell}}<br />
{{Related|General recommendations (简体中文)}}<br />
{{Related|GNU}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related|cron (简体中文)}}<br />
{{Related|man page (简体中文)}}<br />
{{Related|Securely wipe disk#shred}}<br />
{{Related|File permissions and attributes (简体中文)}}<br />
{{Related|Color output in console (简体中文)}}<br />
{{Related|Archiving and compression}}<br />
{{Related|chmod}}<br />
{{Related|chown}}<br />
{{Related articles end}}<br />
<br />
本文涉及 GNU/Linux 系统的所谓的 "核心" 工具,比如 '''less''', '''ls''', 和 '''grep''',包括但不限于以上集成于 GNU {{Pkg|coreutils}} 中的工具。下文提供了关于这些实用工具颇为丰富的技巧和有帮助的其他信息。<br />
<br />
大多数命令行工具的文档都存放在 [[man page]] 里面,来自 [[GNU Project]] 的工具放在 [[Info manual]] 里面,一些 [[shell]] 为它的内置命令提供了 {{ic|help}} 命令。另外,大多数命令加上 {{ic|--help}} 参数时会显示自身的使用说明。<br />
<br />
== 文件管理 ==<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| cd<br />
| 变更目录(shell 内置命令)<br />
| {{man|1p|cd}}<br />
| cd /etc/pacman.d<br />
|-<br />
| mkdir<br />
| 创建目录<br />
| {{man|1|mkdir}}<br />
| mkdir ~/newfolder<br />
|-<br />
| rmdir<br />
| 删除空目录<br />
| {{man|1|rmdir}}<br />
| rmdir ~/emptyfolder<br />
|-<br />
| rm<br />
| 删除文件<br />
| {{man|1|rm}}<br />
| rm ~/file.txt<br />
|-<br />
| rm -r<br />
| 删除目录和目录内文件<br />
|<br />
| rm -r ~/.cache<br />
|-<br />
| ls<br />
| 列出文件名称<br />
| {{man|1|ls}}<br />
| ls *.mkv<br />
|-<br />
| ls -a<br />
| 列出隐藏文件<br />
|<br />
| ls -a /home/archie<br />
|-<br />
| ls -al<br />
| 显示隐藏文件和文件属性<br />
|<br />
|<br />
|-<br />
| mv<br />
| 移动文件<br />
| {{man|1|mv}}<br />
| mv ~/compressed.zip ~/archive/compressed2.zip<br />
|-<br />
| cp<br />
| 复制文件<br />
| {{man|1|cp}}<br />
| cp ~/.bashrc ~/.bashrc.bak<br />
|-<br />
| chmod +x<br />
| 设置文件为[[Help:Reading (简体中文)#添加可执行权限|可执行文件]]<br />
| {{man|1|chmod}}<br />
| chmod +x ~/.local/bin/myscript.sh<br />
|-<br />
| cat<br />
| 显示文件内容<br />
| {{man|1|cat}}<br />
| cat /etc/hostname<br />
|-<br />
| find<br />
| 查找文件<br />
| {{man|1|find}}<br />
| find ~ -name myfile<br />
|}<br />
<br />
=== ls ===<br />
<br />
[[Wikipedia:ls|ls]] 可以列出目录中的文件名称。<br />
<br />
请参考 {{ic|ls}} [[Info manual]]([https://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html#ls-invocation 在线版本])获取更多信息。<br />
<br />
[https://the.exa.website exa] 相较于 {{ic|ls}} 和 {{ic|tree}} 是一个更加现代的、人性化的选择。它有更多的特性,例如将 [[Git]] 修改和文件名一同显示,在 {{ic|--long}} 模式中对每列进行不同的着色,或者在 {{ic|tree}} 视图中显示 {{ic|--long}} 模式元数据。''exa'' 可以在软件包 {{Pkg|exa}} 中找到。<br />
<br />
{{ic|-l}} 选项(“长格式”)用于显示文件类型、[[File permissions and attributes (简体中文)|权限]]、所有者的[[Users and groups (简体中文)|用户名]]和[[Users and groups (简体中文)#用户组管理|用户组]]、大小、修改时间等等,具体参阅 [https://www.gnu.org/software/coreutils/manual/html_node/What-information-is-listed.html#index-long-ls-format info document]。<br />
<br />
默认情况下,包含空格的文件名和目录名会被单引号引起。要改变这一特性,请使用 {{ic|-N}} 或 {{ic|1=--quoting-style=literal}} 选项。另外,将 {{ic|QUOTING_STYLE}} [[Environment variables (简体中文)|环境变量]] 设置为 {{ic|literal}} 也可以。[https://unix.stackexchange.com/questions/258679/why-is-ls-suddenly-surrounding-items-with-spaces-in-single-quotes]<br />
<br />
=== cat ===<br />
<br />
[[Wikipedia:cat_(Unix)|cat]] 是一个将文件内容发送到标准输出的标准 Unix 工具。<br />
<br />
如果您希望能以倒读顺序显示文件内容,有个位于 coreutils 包中的工具叫 [[Wikipedia:tac (Unix)|tac]] (''cat'' 倒着写)。<br />
<br />
=== less ===<br />
<br />
{{Expansion|less 是一个复杂的家伙,这一章应该介绍一些基本的 less 命令。}}<br />
<br />
[[Wikipedia:less (Unix)|less]] 是一个对文本文件内容进行分页显示的终端程序,它与其他的分页显示程序如 [[Wikipedia:more (command)|more]] 和 [https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/Documentation/deprecated.txt 已废弃] 的 [[Wikipedia:pg (Unix)|pg]] 相似,但 ''less'' 提供了更高级的界面和更复杂的 [http://www.greenwoodsoftware.com/less/faq.html 功能]。<br />
<br />
参阅 [[List of applications#Terminal pagers]] 查找更多可选方案。<br />
<br />
=== mkdir ===<br />
<br />
[[Wikipedia:mkdir|mkdir]] (''make directory'') 可以创建目录。<br />
<br />
若需递归地创建一系列目录,就要用到 {{ic|-p}} 参数,否则会出错。<br />
<br />
用 {{ic|-m}} 选项可直接指定新建目录的访问权限,因此不必使用 ''chmod'' 更改权限。<br />
<br />
{{提示|如果您仅仅只是想建个临时目录,也许用 [[Wikipedia:Temporary file|mktemp]]: {{ic|mktemp -d}} 更好。}}<br />
<br />
=== mv ===<br />
<br />
[[Wikipedia:mv|mv]] (''move'') 可以移动或重命名文件和目录。<br />
<br />
{{注意|一旦你习惯了“安全别名”,那它就是危险的,因为当你使用另一个没有这些别名的系统或用户时,可能会导致数据丢失。}}<br />
<br />
为了降低使用这个命令带来的风险,请为它添加一个别名:<br />
<br />
alias mv='mv -iv'<br />
<br />
这个别名可以在覆盖已存在的文件前要求确认,并会显示出正在进行的操作。<br />
<br />
=== rm ===<br />
<br />
[[Wikipedia:rm_(Unix)|rm]] (''remove'') 用于删除文件或目录。<br />
<br />
{{注意|一旦你习惯了“安全别名”,那它就是危险的,因为当你使用另一个没有这些别名的系统或用户时,可能会导致数据丢失。}}<br />
<br />
为了降低使用这个命令带来的风险,请为它添加一个别名:<br />
<br />
alias rm='rm -Iv --one-file-system'<br />
<br />
这个别名可以在删除三个以上的文件时要求确认、显示出正在进行的操作、不跨越多个文件系统。如果想在删除一个文件时也获得确认,用 {{ic|-i}} 代替 {{ic|-I}} 即可。<br />
<br />
Zsh 用户可在命令前加上 {{ic|noglob}},避免隐式扩展。<br />
<br />
若要移除空目录,使用 ''rmdir'',若内含文件则命令失败。<br />
<br />
=== find ===<br />
<br />
''find'' 是 {{Pkg|findutils}} 软件包的一部分, 它属于 {{Grp|base}} 软件包组。<br />
<br />
{{提示|{{Pkg|fd}} 是 {{ic|find}} 的一个更加简单、快速、友好的替代方案,它有着更合理的默认值(比如忽略隐藏文件、文件夹和 {{ic|.gitignore}} 等文件,可用 {{ic|fd PATTERN}} 代替 {{ic|find -iname '*PATTERN*'}})。它具有彩色输出(类似 {{ic|ls}}),unicode 支持,正则表达式支持等等。}}<br />
<br />
你可能希望 ''find'' 命令将一个文件名称作为参数,并在文件系统中搜索与该名称匹配的文件。下面的 [[#locate]] 程序可以专门做这件事。<br />
<br />
相反,find 需要一组目录,并将它们下面的每个文件与一组表达式进行匹配。这种设计为实现一些强大的“单行小程序” ("one-liners") 提供了支持,而这是上述“直观”设计无法实现的。参阅 [[GregsWiki:UsingFind]] 来获取使用说明。<br />
<br />
=== locate ===<br />
<br />
[[安装]] 软件包 {{Pkg|mlocate}}。包里包括了一个 {{ic|updatedb.timer}} 单元,用于每天更新数据库。这个 systemd 定时器在安装后就会 enable,如果不想重启系统就开始使用它,请手动 [[start]]。以 root 身份手动运行 ''updatedb'' 也可以更新数据库。默认会忽略 {{ic|/media}} 和 {{ic|/mnt}} 等路径,所以 ''locate'' 无法找到外置设备里的文件。详情请参考 {{man|8|updatedb}}。<br />
<br />
''locate'' 命令是一个靠文件名快速查找文件的常用 Unix 工具。因为是从数据库查找而不是直接访问文件系统,所以速度比 [[wikipedia:Find|find]] 快很多。而缺点是在数据库更新后创建的新文件不会被搜索到。<br />
<br />
使用 ''locate'' 前需建立数据库,请先以 root 权限执行 {{ic|updatedb}}。<br />
<br />
详情参考 [http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ How locate works and rewrite it in one minute]。<br />
<br />
=== diff ===<br />
<br />
''diff'' 用于逐行比较文件,它的输出内容可以放到一种被称为 patch 的文件里,而这种文件可以被 {{man|1|patch}} 工具所使用。Arch Linux 默认的 ''diff'' 来自 GNU {{Pkg|diffutils}},而这个软件包也包含了 ''cmp'',可以逐字节比较文件。<br />
<br />
另一个可以逐行比对两份已排序的文件的命令叫 ''comm'',参阅 {{man|1|comm}}。<br />
<br />
比较文本文件时,逐个单词地比对通常更加合理:<br />
<br />
* [[git]] 内置的 {{ic|git diff}} 可以使用 {{ic|--color-words}} 参数来实现逐词比较,使用 {{ic|--no-index}} 参数来比较 Git 工作树外的文件。<br />
* {{App|dwdiff|一个用于 diff 程序的逐词 diff 前端,支持彩色输出。|https://os.ghalkes.nl/dwdiff.html|{{Pkg|dwdiff}}}}<br />
* {{App|GNU wdiff|GNU 实现的逐词比较的 diff,不支持彩色输出。|https://www.gnu.org/software/wdiff/|{{Pkg|wdiff}}}}<br />
* {{App|cwdiff|对 GNU wdiff 的包装,使它支持彩色输出。|https://github.com/junghans/cwdiff|{{AUR|cwdiff}}, {{AUR|cwdiff-git}}}}<br />
<br />
== 文本流处理 ==<br />
<br />
=== grep ===<br />
<br />
[[Wikipedia:grep|grep]] (''global/regular expression/print'') 是最初给 Unix 写的命令行文字搜索工具,"grep" 命令在文件或标准输入里搜索符合指定正则表达式的行,并把结果打印到标准输出。<br />
<br />
* 要在输出结果中显示行数,加上 {{ic|-n}} 选项。<br />
* ''grep'' 可以在二进制文件中查找十六进制数值,例如要查找文件中的 {{ic|A1 F2}},应该这样写命令:{{bc|1=$ LANG=C grep --text --perl-regexp "\xA1\xF2" ''/path/to/file''}}<br />
<br />
参阅 [[Color output in console#grep]] 来启用彩色输出支持。<br />
<br />
更多信息请参阅 {{man|1|grep}}。<br />
<br />
{{提示|有专门用于检索版本控制系统(VCS)源代码的 ''grep'' 工具,例如 {{Pkg|ripgrep}}、{{Pkg|the_silver_searcher}} 和 {{Pkg|ack}},再加上 {{AUR|mgrep}}(一个多行查找工具)。}}<br />
<br />
=== sed ===<br />
<br />
[[Wikipedia:sed|sed]] (''stream editor'') 是一条专门过滤或替换文本的命令。<br />
<br />
[http://sed.sourceforge.net/sed1line.txt 这个列表]里有一系列现成的 ''sed'' 单行命令示范。<br />
<br />
{{提示|[[#awk|awk]] 和 [[Perl]] 语言在这方面更为强大。}}<br />
<br />
=== awk ===<br />
<br />
[[Wikipedia:AWK|AWK]] 是一种模式扫描和处理语言,存在多个实现:<br />
<br />
* {{App|gawk|GNU 版本的 awk, 参考 {{man|1|gawk}}.|https://www.gnu.org/software/gawk/|{{Pkg|gawk}} (已经包含在{{Grp|base}}中)}}<br />
* {{App|nawk|真正的 AWK 实现,参考 {{man|1|nawk}}.|https://www.cs.princeton.edu/~bwk/btl.mirror/|{{Pkg|nawk}}}}<br />
* {{App|mawk|一个非常快速的 AWK 实现。|http://invisible-island.net/mawk/|{{AUR|mawk}}}}<br />
* [[BusyBox]] 也包含了一个 AWK 实现。<br />
<br />
== 系统管理 ==<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| mount<br />
| 挂载分区<br />
| {{man|8|mount}}<br />
| mount /dev/sdc1 /media/usb<br />
|-<br />
| df -h<br />
| 显示各个分区上的剩余空间<br />
| {{man|1|df}}<br />
|<br />
|-<br />
| ps -A<br />
| 列出所有正在运行的进程<br />
| {{man|1|ps}}<br />
|<br />
|-<br />
| killall<br />
| 杀死所有运行中的进程实例<br />
| {{man|1|killall}}<br />
|<br />
|-<br />
| ss -at<br />
| 列出所有已打开的 TCP 套接字<br />
| {{man|8|ss}}<br />
|<br />
|}<br />
<br />
=== sudo ===<br />
<br />
参阅 [[Sudo (简体中文)|Sudo]]。<br />
<br />
=== which ===<br />
<br />
[[wikipedia:Which_(Unix)|which]] 显示 shell 命令的完整路径。在下面的例子中 {{ic|ssh}} 的完整路径作为一个参数传递给了 {{ic|journalctl}}:<br />
<br />
# journalctl $(which sshd)<br />
<br />
=== lsblk ===<br />
<br />
{{Move|File systems|放在此处更好。|section=Rewrite}}<br />
<br />
{{man|8|lsblk}} 命令会显示所有连接到系统的 [[Wikipedia:Device file#Block devices|块设备]] 和分区状况,例如:<br />
<br />
{{hc|$ lsblk -f|<br />
NAME FSTYPE LABEL UUID MOUNTPOINT<br />
sda<br />
├─sda1 vfat C4DA-2C4D /boot<br />
├─sda2 swap 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 [SWAP]<br />
└─sda3 ext4 56adc99b-a61e-46af-aab7-a6d07e504652 /<br />
}}<br />
<br />
设备名称的开头定义块设备的类型,大部分现代存储设备(如硬盘、[[SSD]] 和 USB 闪存设备)都被识别为 SCSI disks ({{ic|sd}})。类型后面跟着给设备编号的小写字母,第一个设备从 {{ic|a}} 开始 ({{ic|sda}}),第二个设备就是 {{ic|b}} ({{ic|sdb}}),以此类推。每个设备上的 ''现有'' 分区将用数字编号,从 {{ic|1}} 开始 ({{ic|sda1}}),第二个分区就是 {{ic|2}} ({{ic|sda2}}),以此类推。在上面的示例中,只有一个设备可用 ({{ic|sda}}),该设备有三个分区 ({{ic|sda1}} 到 {{ic|sda3}}),每个分区具有不同的 [[file system|文件系统]]。<br />
<br />
其它常见的块设备有 {{ic|mmcblk}}(内存卡)或 {{ic|nvme}}([[NVMe]] 设备)。不清楚的设备类型可以在这里搜索到:[https://www.kernel.org/doc/html/latest/admin-guide/devices.html kernel documentation]。<br />
<br />
=== ip ===<br />
<br />
{{Remove|与 [[Network configuration#Network management]] 和 {{man|8|ip}} 重复。表格没有价值,文档链接失效。|section=Rewrite}}<br />
<br />
[[Wikipedia:Iproute2|ip]] 显示关于网络设备,IP 地址,路由表和其他 Linux [[Wikipedia:Internet Protocol|IP]] 软件栈的对象信息。通过附加各种命令,你可以操纵或配置大多数对象。<br />
<br />
{{注意| ''ip'' 命令在 {{Pkg|iproute2}} 包中提供,这个包已经包含在 {{Grp|base}} 组。}}<br />
<br />
{| class="wikitable"<br />
! 子命令 !! 作用 !! 手册页名称<br />
|-<br />
| ip addr || 协议地址管理 || {{man|8|ip-address}} <br />
|-<br />
| ip addrlabel || 协议地址标签管理 || {{man|8|ip-addrlabel}}<br />
|-<br />
| ip l2tp || tunnel Ethernet over IP (L2TPv3) || {{man|8|ip-l2tp}}<br />
|-<br />
| ip link || 网络设备配置 || {{man|8|ip-link}}<br />
|-<br />
| ip maddr || 多播地址管理 || {{man|8|ip-maddress}}<br />
|-<br />
| ip monitor || 监测 netlink 信息 || {{man|8|ip-monitor}}<br />
|-<br />
| ip mroute || 多播路由缓存管理 || {{man|8|ip-mroute}}<br />
|-<br />
| ip mrule || 多播路由策略数据库的规则 ||<br />
|-<br />
| ip neigh || 邻居表/ARP 表管理|| {{man|8|ip-neighbour}}<br />
|-<br />
| ip netns || process network namespace management || {{man|8|ip-netns}}<br />
|-<br />
| ip ntable || 邻居表配置 || {{man|8|ip-ntable}}<br />
|-<br />
| ip route || 路由表管理 || {{man|8|ip-route}}<br />
|-<br />
| ip rule || 路由策略数据库管理 || {{man|8|ip-rule}}<br />
|-<br />
| ip tcp_metrics || 管理 TCP Metrics || {{man|8|ip-tcp_metrics}}<br />
|-<br />
| ip tunnel || 隧道配置 || {{man|8|ip-tunnel}}<br />
|-<br />
| ip tuntap || 管理 TUN/TAP 设备 ||<br />
|-<br />
| ip xfrm || 管理 IPsec 策略 || {{man|8|ip-xfrm}}<br />
|}<br />
<br />
{{ic|help}} 帮助命令可用于所有子命令。例如,输入 {{ic|ip addr help}} 将显示地址对象相关的命令语法。高级用法参见 [http://www.policyrouting.org/iproute2.doc.html iproute2 documentation]。<br />
<br />
[[Network configuration (简体中文)]] 中提到了 ''ip'' 命令在多种实际任务中的使用方法。<br />
<br />
{{注意|你也许很熟悉旧版 Linux 中的 [[Wikipedia:ifconfig|ifconfig]] 命令。在 Arch Linux 中现已不再使用;应当用 ''ip'' 替代之。}}<br />
<br />
=== ss ===<br />
<br />
参阅 [[Network configuration#Investigate sockets]]。<br />
<br />
== 杂项 ==<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| strings<br />
| 显示二进制文件中可打印的字符<br />
| {{man|1|strings}}<br />
| strings /usr/bin/free<br />
|}<br />
<br />
=== dd ===<br />
<br />
[[dd]] 是在 unix 和 类 unix 系统中主要用于转换和拷贝文件的命令。<br />
<br />
=== iconv ===<br />
<br />
''iconv'' 可以转换文本的字符编码。<br />
<br />
下列命令将文件 {{ic|''foo''}} 从 ISO-8859-15 转换至 UTF-8,然后保存到 {{ic|''foo''.utf}}:<br />
<br />
$ iconv -f ISO-8859-15 -t UTF-8 ''foo'' > ''foo''.utf<br />
<br />
查阅 {{man|1|iconv}} 获取更多细节。<br />
<br />
{{提示|如果你不想改变文件的修改时间,可以用 {{pkg|recode}} 代替 iconv。}}<br />
<br />
=== od ===<br />
<br />
[[Wikipedia:od (Unix)|od]] (''o''ctal ''d''ump) 命令在显示非人类可读格式时非常有用,比如程序的可执行文件,或者未格式化的设备的内容。参阅 [https://www.gnu.org/software/coreutils/manual/html_node/od-invocation.html#od-invocation manual] 了解详情。<br />
<br />
=== seq ===<br />
<br />
''seq'' (''sequence'') 可以打印一列数字。Shell 内置了该命令的其他替代方案,可以按照 [[Wikipedia:Seq (Unix)|Wikipedia]] 的说明进行练习。<br />
<br />
=== tar ===<br />
<br />
{{Remove|与 [[Archiving and compression#Archiving only]] 重复,表格没有价值,因为 tar 可以自动检测文件格式。|section=Rewrite}}<br />
<br />
作为早期的 Unix 存档格式,.tar 文件(称为“tarballs”)广泛用于类 Unix 操作系统中的打包操作。[[pacman]] 和 [[AUR]] 软件包都是压缩的 tarball,Arch 默认使用 [[GNU Project|GNU 的]] ''tar'' 程序。<br />
<br />
对于 ''.tar'' 文件,''tar'' 默认根据扩展名来解压文件:<br />
<br />
$ tar xvf ''file.EXTENSION''<br />
<br />
强制指定格式:<br />
<br />
{| class="wikitable"<br />
!文件类型 !! 解压命令<br />
|-<br />
|{{ic|''file''.tar}} || {{Ic|tar xvf ''file''.tar}}<br />
|-<br />
|{{ic|''file''.tgz}} || {{Ic|tar xvzf ''file''.tgz}}<br />
|-<br />
|{{ic|''file''.tar.gz}} || {{Ic|tar xvzf ''file''.tar.gz}}<br />
|-<br />
|{{ic|''file''.tar.bz}} || {{Ic|bzip -cd ''file''.bz <nowiki>|</nowiki> tar xvf -}}<br />
|-<br />
|{{ic|''file''.tar.bz2}} || {{Ic|tar xvjf ''file''.tar.bz2}}<br> {{Ic|bzip2 -cd ''file''.bz2 <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.xz}} || {{Ic|tar xvJf ''file''.tar.xz}}<br> {{Ic|xz -cd ''file''.xz <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.zst}} || {{Ic|tar -I zstd xvf ''file''.tar.zst}}<br />
|}<br />
<br />
这其中有部分 ''tar'' 的参数可以认为是历史遗留问题,但在执行某些特定的操作时仍然有用。更多细节请参阅 {{man|1|tar}}。<br />
<br />
{{注意|虽然 GNU 的 ''tar'' 是默认的 ''tar'' 程序,但是官方 Arch Linux 项目(如 [[pacman]] 和 [[mkinitcpio]])使用的是 {{Pkg|libarchive}} 包中的 ''bsdtar''。}}<br />
<br />
另请参考 [[Archiving and compression]]。<br />
<br />
=== wipefs ===<br />
<br />
{{Move|Partitioning|放在此处更好。|section=Rewrite}}<br />
<br />
{{Expansion|在什么情况下需要擦除 magic strings?}}<br />
<br />
''wipefs'' 可以列出或擦除指定设备的 [[File systems (简体中文)|文件系统]]、[[RAID (简体中文)|RAID]] 或 [[Partitioning (简体中文)|分区表]] 标志 (magic strings)。它不会擦除文件系统本身,也不会擦除设备中的任何其他数据。<br />
<br />
更多信息请参阅 {{man|8|wipefs}}。<br />
<br />
例如,擦除 {{ic|/dev/sdb}} 设备中的所有标志并为每个标志在 {{ic|~/wipefs-sdb-''offset''.bak}} 创建一个备份文件:<br />
<br />
# wipefs --all --backup /dev/sdb<br />
<br />
== 参考资料 ==<br />
<br />
* [http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html POSIX Utilities]<br />
* [https://www.gnu.org/software/coreutils/manual/coreutils.html GNU Coreutils online documentation]<br />
* [http://www.reddit.com/r/commandline/comments/19garq/a_sampling_of_coreutils_120/ A sampling of coreutils on Reddit] [http://www.reddit.com/r/commandline/comments/19ge6v/a_sampling_of_coreutils_2040/ , part 2] [http://www.reddit.com/r/commandline/comments/19j1w3/a_sampling_of_coreutils_4060/ , part 3] - Overview of commands in coreutils<br />
* [https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/ Learn the DD command]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Git_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=534924
Git (简体中文)
2018-08-14T16:05:16Z
<p>Arisaka: Sync with English page.</p>
<hr />
<div>[[Category:Version Control System (简体中文)]]<br />
[[en:Git]]<br />
[[es:Git]]<br />
[[ja:Git]]<br />
{{TranslationStatus (简体中文)|Git|2018-08-14|534795}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion (简体中文)}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}<br />
<br />
[[wikipedia:Git (software)|Git]] 是一个由 Linux 内核作者 Linus Torvalds 编写的版本控制系统(VCS),现在被用来维护 [[AUR]] 软件包以及数以千计的其他项目,其中包括 Linux 内核。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|git}} 软件包。要使用开发版本,请安装 {{AUR|git-git}} 软件包。当使用 ''git svn''、''git gui'' 和 ''gitk'' 等工具时请检查可选依赖项是否安装。<br />
<br />
=== 图形化前端 ===<br />
<br />
参考 [https://git-scm.com/download/gui/linux git GUI Clients]。<br />
<br />
* {{App|Giggle|用于 git 的 GTK+ 前端。|https://wiki.gnome.org/Apps/giggle/|{{Pkg|giggle}}}}<br />
* {{App|Git Cola|用 Python 编写的丝滑而强大的 git 图形前端。|https://git-cola.github.io/|{{AUR|git-cola}}}}<br />
* {{App|Git Extensions|允许用户不使用命令行就可以完成 git 各项操作的图形前端。|https://gitextensions.github.io/|{{AUR|gitextensions}}}}<br />
* {{App|gitg|用于查看 git 仓库的 GNOME GUI 客户端。|https://wiki.gnome.org/Apps/Gitg|{{Pkg|gitg}}}}<br />
* {{App|git-gui|Tcl/Tk 库编写的可移植 git 图形前端。|https://git-scm.com/docs/git-gui|{{Pkg|git}} + {{Pkg|tk}}}}<br />
:{{注意|要打开 ''git-gui'' 的拼写检查功能,请安装 {{Pkg|aspell}},同时还需要与 {{ic|LC_MESSAGES}} [[Environment variables (简体中文)|环境变量]] 相对应的字典文件。参阅 {{Bug|28181}} 和 [[aspell (简体中文)]]。}}<br />
* {{App|gitk|Tcl/Tk 库编写的 Git 仓库查看器。|https://git-scm.com/docs/gitk|{{Pkg|git}} + {{Pkg|tk}}}}<br />
* {{App|QGit|可图形化地按照不同开发分支显示修订历史记录、查阅补丁内容、查看被修改文件的 Git GUI 查看器。|https://github.com/tibirna/qgit|{{Pkg|qgit}}}}<br />
* {{App|[[Wikipedia:RabbitVCS|RabbitVCS]]|一组图形化工具,用于轻松、直接地访问您使用的版本控制系统。|http://rabbitvcs.org/|{{AUR|rabbitvcs}}}}<br />
* {{App|Tig|基于 ncurses 的 git 字符模式前端。|https://jonas.github.io/tig/|{{Pkg|tig}}}}<br />
* {{App|ungit|在不牺牲 git 各种功能的情况下使其变得更加友好。|https://github.com/FredrikNoren/ungit|{{AUR|nodejs-ungit}}}}<br />
<br />
<br />
<br />
== 配置 ==<br />
<br />
你至少需要设置好姓名和邮箱之后才能开始使用 Git:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@example.com''"<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE 起步 - 初次运行 Git 前的配置]。<br />
<br />
更多设置选项可参阅 [[#提示与技巧]]。<br />
<br />
== 基本用法 ==<br />
<br />
一个 Git 版本库包含在一个名为 {{ic|.git}} 的目录内,该目录包含了修订历史以及其他元数据。版本库所跟踪的目录(默认为父目录)称为工作目录。在工作树进行的更改在被提交 (commit) 前需要先暂存 (stage) 起来。Git 还可以让你恢复以前提交的工作树文件。<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E5%9F%BA%E7%A1%80 起步 - Git 基础]。<br />
<br />
=== 获取一个 Git 仓库 ===<br />
<br />
* 初始化一个版本库<br />
:{{ic|git init}},参阅 {{man|1|git-init}}<br />
* 克隆 (clone) 一个现有的版本库<br />
:{{ic|git clone ''repository''}},参阅 {{man|1|git-clone}}<br />
<br />
=== 记录更改 ===<br />
<br />
Git 管理的项目存在一个暂存区 (staging area),即 git 目录中的 {{ic|index}} 文件,其中保存了即将包含在你下一次提交中的文件更改。要将某个修改过的文件记录下来,首先需要将修改后的文件添加到 index(暂存它),然后用 {{ic|git commit}} 命令将当前的 index 保存为一次新的提交。<br />
<br />
==== 暂存 (stage) 更改 ====<br />
<br />
* 将工作树中的文件更改添加至 index<br />
:{{ic|git add ''pathspec''}},参阅 {{man|1|git-add}}<br />
* 移除 index 中记录的文件更改<br />
:{{ic|git reset ''pathspec''}},参阅 {{man|1|git-reset}}<br />
* 显示即将提交的更改、未暂存的更改以及未被 git 跟踪的文件<br />
:{{ic|git status}},参阅 {{man|1|git-status}}<br />
<br />
可以用 {{ic|.gitignore}} 文件来让 git 忽略某些未跟踪的文件,请参阅 {{man|5|gitignore}}。<br />
<br />
Git 不会跟踪文件移动。合并时的文件移动检测仅基于内容的相似性。{{ic|git mv}} 命令仅仅是为了方便,它相当于:<br />
<br />
$ mv -i foo bar<br />
$ git reset -- foo<br />
$ git add bar<br />
<br />
==== 提交 (commit) 更改 ====<br />
<br />
{{ic|git commit}} 命令将暂存区的更改保存至版本库,参阅 {{man|1|git-commit}}。<br />
<br />
* {{ic|-m}} – 后面跟上提交消息作为参数直接提交,而不是打开默认的文本编辑器来写提交信息后再提交<br />
* {{ic|-a}} – 自动暂存已更改或已删除的文件(不会添加未跟踪的文件)<br />
* {{ic|--amend}} – 重做上次提交,用于修改提交消息或修改提交的文件<br />
<br />
{{提示|建议经常性的提交小更改,并附上有意义的提交信息。}}<br />
<br />
==== 选择修订版本 ====<br />
<br />
Git 提供了多种方式来指定修订版本,参阅 {{man|7|gitrevisions}} 和 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC 选择修订版本]。<br />
<br />
许多 Git 命令需要用修订版本作为参数。一次提交记录可以用下列任何一种方式表示:<br />
<br />
* 某次提交的 SHA-1 哈希值(前7位通常足以唯一标识它)<br />
* 任意提交时的标签,如分支名称或 tag 名称<br />
* 标签 {{ic|HEAD}} 总是指向当前 check out 的提交(通常是分支的头部,除非你使用 ''git checkout'' 跳回到历史记录中的旧提交)<br />
* 以上任意一种表示方式加上 {{ic|~}} 都可以表示之前的提交。例如,{{ic|HEAD~}} 指向 {{ic|HEAD}} 的前一次提交,{{ic|HEAD~5}} 指向 {{ic|HEAD}} 5 次前的提交。<br />
<br />
==== 查看更改 ====<br />
<br />
查看不同提交间的修改处:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
或者查看暂存区和工作树之间的不同:<br />
<br />
$ git diff<br />
<br />
查看修改历史(其中 "''-N''" 指定最近的 n 次修改):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
=== 撤销修改 ===<br />
<br />
* {{ic|git reset}} - 重置当前 HEAD 指针到指定状态,参阅 {{man|1|git-reset}}<br />
<br />
* {{ic|git checkout}} - 恢复工作树中的文件,参阅 {{man|1|git-checkout}}<br />
<br />
=== 分支 (branch) ===<br />
<br />
Bug 修复和新功能通常在不同分支里测试。当一切就绪时它们就可以合并至默认(主)分支。<br />
<br />
创建一个分支,其名称准确地反映了其目的:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
列出已存在的分支:<br />
<br />
$ git branch<br />
<br />
切换分支:<br />
<br />
$ git checkout ''branch''<br />
<br />
新建分支并切换至该分支:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
将一个分支合并回主分支:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
如果不存在冲突的话,所有更改将被合并。否则 Git 将显示一条错误信息,并通过给工作树中的文件加注释来记录冲突。添加的注释可以用 {{ic|git diff}} 显示。要解决冲突,必须编辑文件,删除注释,并提交最终版本。请参阅下面的 [[#处理合并 (merge)]]。<br />
<br />
当一个分支使用完毕,可以这样删除:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== 多人合作 ===<br />
<br />
一个典型的 Git 工作流像这样:<br />
<br />
# 创建一个新仓库或克隆一个远程仓库。<br />
# 新建一个分支用于修改文件,然后提交这些修改。<br />
# 将多次提交合并在一起,这样更便于组织项目或更好地理解。<br />
# 把提交的分支合并回主分支。<br />
# (可选)将更改推送至远程服务器。<br />
<br />
==== 合并请求 (pull requests) ====<br />
<br />
在做出并提交更改后,贡献者可以请求原作者合并更改。这被称为 ''合并请求 (pull request)''。<br />
<br />
如果用 pull:<br />
<br />
$ git pull ''location'' master<br />
<br />
''pull'' 命令相当于 ''fetch'' 和 ''merge'' 命令的结合。如果存在冲突(比如原作者在同一时间段内在相同位置做了更改),那就有必要手动解决冲突。<br />
<br />
另一种方式是,原作者可以选择想要合并的更改。通过使用 ''fetch'' 命令(以及带有特殊 {{ic|FETCH_HEAD}} 标记的 ''log'' 命令),可以在决定如何处理合并请求 (pull request) 前查看该请求的内容:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== 使用远程仓库 (remote) ====<br />
<br />
远程 (remote) 是和本地相关联的远程仓库的别名。其实就是创建一个 ''label'' 来定义一个位置。这些 label 用于标识经常访问的仓库。<br />
<br />
添加一个远程仓库:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
获取远程库里的内容:<br />
<br />
$ git fetch ''label''<br />
<br />
显示本地主分支与远程主分支之间的差异:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
查看当前仓库相关联的远程仓库:<br />
<br />
$ git remote -v<br />
<br />
当设置的远程仓库是本仓库的 fork 来源(项目的领导者),这个远程仓库会被定义为 ''upstream''(上游)。<br />
<br />
==== 向某个仓库推送 (push) 修改 ====<br />
<br />
从原作者处获得推送修改的权限之后,使用以下命令推送修改:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
当使用 ''git clone'' 获得这个仓库后,git 会把仓库的原始地址记录在名为 {{ic|origin}} 的变量中。<br />
<br />
所以一次 ''典型的'' 推送可以这样做: <br />
<br />
$ git push origin master<br />
<br />
如果使用了 {{ic|-u}} ({{ic|--set-upstream-to}}) 选项,地址将会被记录下来,下次只要使用 {{ic|git push}} 就可以了。<br />
<br />
==== 处理合并 (merge) ====<br />
<br />
可以查看 Git Book 的 [https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6#遇到冲突时的分支合并 遇到冲突时的分支合并] 部分了解如何处理合并冲突。合并操作通常是可逆的,如果想返回合并前,可以使用 {{ic|--abort}} 命令(比如 {{ic|git merge --abort}} 或 {{ic|git pull --abort}})。<br />
<br />
=== 历史记录和版本记录 ===<br />
<br />
==== 在历史记录中搜索 ====<br />
<br />
{{ic|git log}} 命令可以显示历史记录信息,其中包含每次提交的校验和、作者、日期,以及简略信息。''校验和'' 就是一次提交对象的 "对象名称",通常是一个 40 位的 SHA-1 哈希值。<br />
<br />
对于具有较长信息的历史记录(其中 "''checksum''" 可以截取前几位,只要它是唯一的):<br />
<br />
$ git show (''checksum'')<br />
<br />
在被跟踪的文件中搜索 ''pattern'':<br />
<br />
$ git grep ''pattern''<br />
<br />
在 {{ic|.c}} 和 {{ic|.h}} 文件中搜索:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== 使用标签 (tag) ====<br />
<br />
给某次提交打标签来标记这个版本:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tag'' 通常是用于 [https://www.drupal.org/node/1066342 发布/标记版本] 的,但它可以是任何字符串。通常使用带注释的标签,因为它们会被添加到 Git 数据库中。<br />
<br />
标记当前的提交:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
列出标签:<br />
<br />
$ git tag -l<br />
<br />
删除某个标签:<br />
<br />
$ git tag -d 2.08<br />
<br />
更新远程库中的标签:<br />
<br />
$ git push --tags<br />
<br />
==== 重新组织 commit ====<br />
<br />
在提交合并请求之前,可能需要合并/重新组织 commit。这是通过 ''git rebase''(变基){{ic|--interactive}}完成的:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
然后会打开文本编辑器,其中包含指定范围内所有提交的摘要;这种情况下会包括最新提交 ({{ic|HEAD}}),但不包括 {{ic|''checksum''}} 表示的那次 commit。也可以使用数字来标记,例如用 {{ic|HEAD~3}},这会把最后三次提交变基:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
修改第一栏中的动作可以决定如何执行变基操作。可选的动作有:<br />
<br />
* {{ic|pick}} — 原样保留每次提交(默认)。<br />
* {{ic|edit}} — 编辑文件和/或 commit 信息。<br />
* {{ic|reword}} — 编辑 commit 信息。<br />
* {{ic|squash}} — 合并/折叠到先前的提交中。<br />
* {{ic|fixup}} — 合并/折叠到先前的提交中并丢弃它们的信息。<br />
<br />
提交会被重新排序或从历史记录中擦除(所以要非常小心)。编辑文件后,Git 将执行指定的操作;如果提示有合并问题待解决,请解决它们并使用 {{ic|git rebase --continue}} 来继续,或使用 {{ic|git rebase --abort}} 命令来取消操作。<br />
<br />
{{注意|合并多次提交的操作只能应用于本地提交,它会导致其他人共享的存储库出现问题。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
=== 使用 git-config ===<br />
<br />
Git 从 4 个 ini 类型的配置文件里读取配置:<br />
<br />
* {{ic|/etc/gitconfig}} 是应用于整个系统的默认配置文件<br />
* {{ic|~/.gitconfig}} 和 {{ic|~/.config/git/config}} (自 1.7.12 起)是应用于特定用户的配置文件<br />
* {{ic|.git/config}} 是应用于特定仓库的配置文件<br />
<br />
这些文件可以直接编辑,但是更常用的方法是使用 ''git config'',下面是一些示范。<br />
<br />
列出当前已配置的变量:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
将默认文本编辑器从 [[vim]] 改成 [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
设置默认的推送 (push) 行为:<br />
<br />
$ git config --global push.default simple<br />
<br />
设置不同的 ''git difftool'' 工具(默认是 ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
更多信息请参阅 {{man|1|git-config}} 和 [https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git 配置 Git]。<br />
<br />
=== 保持良好的礼仪 ===<br />
<br />
* 当你想为一个现有的项目贡献时,请先阅读并理解这个项目的许可,因为它可能会过度限制你更改代码的权力。有些许可会在代码的所有权方面引起争议。<br />
* 理解这个项目的社区,以及你可以融入其中的程度。要了解项目的主要方向,可以阅读所有文档甚至是代码库的 [[#历史记录和版本记录|log]]。<br />
* 当发起一个合并请求,或者提交一个补丁时,保证它是小改动并且有完善的文档;这将有助于项目维护者理解你的改动,并决定是否合并这些改动或是让你再改一下。<br />
* 如果贡献被拒绝,不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清楚和耐心地讨论这次贡献的理由,最终可能通过这种方法解决问题。<br />
<br />
=== 加快身份验证 ===<br />
<br />
每次向 Git 服务器推送时都要认证身份,你可能会想要避免这种麻烦。<br />
<br />
* 如果你是用 SSH 密钥来认证的,请使用 [[SSH keys (简体中文)#SSH agents|SSH agents]]。参阅 [[Secure Shell (简体中文)#加速 SSH]] 和 [[Secure Shell (简体中文)#保持在线]]。<br />
* 如果你是用账号和密码来认证的,在服务器支持 SSH 的情况下请切换至 [[SSH keys (简体中文)|SSH keys]], 否则请尝试 [https://git-scm.com/docs/git-credential-cache git-credential-cache] 或 [https://git-scm.com/docs/git-credential-store git-credential-store]。<br />
<br />
=== 默认通讯协议 ===<br />
<br />
如果你正在使用一个上述那种复用的 SSH 连接,让 Git 使用 SSH 可能比使用 HTTPS 更快。同时,一些服务器(比如 AUR)只允许通过 SSH 推送更改。例如,像下面这样配置可以使得 Git 通过 SSH 访问 AUR 上的任何仓库。<br />
<br />
{{hc|~/.gitconfig|<nowiki><br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
</nowiki>}}<br />
<br />
=== Bash 自动补全 ===<br />
<br />
要启用 Bash 的自动补全,请在 [[Bash#Configuration_files|Bash 启动文件]] 里用 source 加载 {{ic|/usr/share/git/completion/git-completion.bash}} 文件。或者也可以安装 {{pkg|bash-completion}}。<br />
<br />
=== Git 提示符 ===<br />
<br />
Git 包带有一个提示符脚本。要启用它,请用 source 加载 {{ic|/usr/share/git/completion/git-prompt.sh}} 脚本,然后使用 {{ic|%s}} 参数设置一个自定义 shell 提示符:<br />
<br />
* [[Bash]] 用户: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* [[zsh]] 用户: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
要自动完成这项工作,请参阅 [[Command-line shell#Configuration files]]。<br />
<br />
当切换至一个 Git 仓库所在目录时,shell 提示符会变成所在分支名称。也可以配置提示符来显示其他信息:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || 已暂存 (staged) 显示 '''+''',未暂存 (unstaged) 显示 '''*'''。<br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || 已储藏 (stashed) 显示 '''$'''。<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || 有未跟踪文件时显示 '''%'''。<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' 分别表示落后于上游、领先于上游、偏离上游。<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} 需要设置为 {{ic|auto}} 才能使更改生效。<br />
<br />
{{注意|如果发生了 {{ic|$(__git_ps1)}} 返回 {{ic|((unknown))}} 的情况,是因为有一个 {{ic|.git}} 文件夹在你当前的文件夹里面,但却不包含任何存储库,因此 Git 不认识它。这有可能发生在你把 {{ic|~/.git/config}} 误认为是 Git 的配置文件而不是 {{ic|~/.gitconfig}}。}}<br />
<br />
你也可以使用来自 [[AUR]] 的自定义 git shell 提示符软件包,例如 {{AUR|bash-git-prompt}} 或 {{AUR|gittify}}。<br />
<br />
=== 可视化显示 ===<br />
<br />
要了解已经完成了多少工作:<br />
<br />
$ git diff --stat<br />
<br />
带有 fork 显示的 ''git log'':<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
给图形化的 ''git log'' 做一个别名(使用 ''git graph'' 即可显示经过修饰的 log):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
=== 关于提交 (commit) 的小提示 ===<br />
<br />
重置为以前的提交(非常危险,这将会擦除所有内容并改写为特定提交):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
如果远程仓库的地址发生变化,可以这样更新它的位置:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
自动附加签名行到提交(将某个 姓名-电邮 签名添加到提交中,某些项目会要求这样做):<br />
<br />
$ git commit -s<br />
<br />
自动附加签名到补丁(使用 {{ic|git format-patch ''commit''}} 时生效):<br />
<br />
$ git config --local format.signoff true<br />
<br />
提交已更改文件的特定部分。如果有大量更改时,最好拆分成多个提交,这种情况下这个命令通常很有用:<br />
<br />
$ git add -p<br />
<br />
=== 对提交 (commit) 签名 ===<br />
<br />
Git 允许使用 [[GnuPG (简体中文)|GnuPG]] 对提交和标签进行签名,请参见 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C 签署工作]。<br />
<br />
{{注意|<br />
如果是借助 {{Pkg|pinentry}} 来进行 GPG 签名,请确保 {{ic|1=export GPG_TTY=$(tty)}}(或者使用 pinentry-tty),否则当 GPG 处于锁定状态时签名这一步会失败(因为它无法在 shell 提示符里询问 pin 码)。}}<br />
<br />
配置 Git 使它自动对提交进行签名:<br />
<br />
$ git config --global commit.gpgSign true<br />
<br />
=== 在非主分支上工作 ===<br />
<br />
偶尔项目维护人员会要求你在其他分支上完成工作。这些分支通常被称为 {{ic|devel}} 或 {{ic|testing}}。首先要克隆存储库。<br />
<br />
要进入不是主分支的分支(''git clone'' 只会显示主分支,但其他分支其实也是存在的,用 {{ic|git branch -a}} 可以显示出来):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
然后就可以像平常一样编辑文件,但是要使得整个仓库都保持同步,下面这两个命令都要用:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
=== 直接将补丁发送至邮件列表 ===<br />
<br />
如果你想直接将补丁发送至一个邮件列表,需要安装以下软件包:{{Pkg|perl-authen-sasl}},{{Pkg|perl-net-smtp-ssl}} 和 {{Pkg|perl-mime-tools}}。<br />
<br />
确保你已经配置了用户名和邮件地址,可参阅 [[#配置]]。<br />
<br />
配置你的邮箱设置:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.example.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@example.com''<br />
<br />
现在你应该可以将补丁发送至某个邮件列表了(可参阅[http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
=== 远程库很大时的注意事项 ===<br />
<br />
{{Style|<br />
此处使用了非正式的表达、缩写、HTML 标签(而不是代码模板),且没有使用 wiki 内链接。}}<br />
<br />
当远程库很大时该怎么办?请参考这一节。其中的示例来自于 linux kernel。<br />
<br />
==== 最简单的方式:接收整个仓库 ====<br />
<br />
你可以这样接收整个仓库:<br />
<br />
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git<br />
<br />
下载时间会很长,而且 "git clone" 无法断点续传(截止至 2018 年 8 月),还会占用很多硬盘空间。<br />
<br />
可以用这个命令更新仓库<br />
$ git pull<br />
<br />
==== 部分接收 ====<br />
也许你想把本地仓库的大小限制得小一点,比如只保留 v4.14 以后的代码来分离出一个 bug,那么可以这么做:<br />
<br />
$ git clone --shallow-exclude v4.13 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # 这样就只会下载 v4.14 及以后的文件,v4.13 以前的不会下载。<br />
<br />
也许你只需要最新的仓库快照,忽略所有的历史记录。(如果有压缩包提供且足够使用,那就下载压缩包,获取 git 仓库快照开销要大一点。)可以这样做:<br />
<br />
$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git<br />
<br />
之后也可以这样获取历史提交记录:<br />
<br />
$ git fetch --tags --shallow-exclude v4.1 # 获取 v4.1 之后的提交记录<br />
$ git fetch --tags --shallow-since 2016-01-01<br />
<br />
如果没有 <code>--tags</code>,那么就接收不到 tags。<br />
<br />
==== 获取其他分支 ====<br />
在上面的示例中,你本地的仓库仅跟踪主线内核,即“最近开发完成”的内核。假设你想获取最近的 “LTS” 版内核,比如最新的 4.14 分支,可以这么做:<br />
<br />
$ git remote set-branches --add origin linux-4.17.y<br />
$ git fetch<br />
$ git branch --track linux-4.17.y origin/linux-4.17.y<br />
<br />
最后一行不是必须的,但你应该需要执行它。<br />
(要获取你需要的那个分支的具体名称,没有什么通用的方法,或许可以靠 web 页面的 "ref" 链接来猜测)<br />
<br />
如果需要 linux-4.17.y 的快照,这样做:<br />
<br />
$ git checkout -b linux-4.17.y<br />
<br />
或者这样做,将它解压到其他目录里:<br />
<br />
$ mkdir /foo/bar/src-4.17; cd /foo/bar/src-4.17<br />
$ git clone --no-local --depth 1 -b linux-4.17.y ../linux-stable<br />
<br />
然后像平常一样,执行 <code>git pull</code> 来更新你的快照。<br />
<br />
==== 未来可能出现的其他方案 ====<br />
Git 虚拟文件系统 (Git Virtual Filesystem, GVFS) 由微软开发,允许在不克隆仓库至本地的情况下使用 git 仓库。(参阅 [https://blogs.msdn.microsoft.com/bharry/2017/05/24/the-largest-git-repo-on-the-planet/ this Microsoft blog] 或 [[wikipedia:Git_Virtual_File_System|Wikipedia artcile]]。)这个功能在 Linux 暂不可用。<br />
<br />
无论如何这个功能暂不适用于上述示例中的 Linux 内核仓库。<br />
<br />
== Git 服务器 ==<br />
<br />
这一节讲述如何配置使用不同的协议连接到存储库。<br />
<br />
=== SSH 协议 ===<br />
<br />
要使用 SSH 协议,首先要准备一个 SSH 公钥,可以按照 [[SSH keys (简体中文)]] 的指导来完成。要配置一个 SSH 服务器,请遵循 [[Secure Shell (简体中文)]] 的指导。<br />
<br />
当 SSH 生成了密钥之后,将 {{ic|~/.ssh/id_rsa.pub}} 文件的内容粘贴至服务器上的 {{ic|~/.ssh/authorized_keys}} 文件里(一行一个,同一个公钥确保在同一行)。现在 Git 仓库可以通过 SSH 来访问:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
现在,如果你的 SSH 客户端的 {{ic|StrictHostKeyChecking}} 选项设为了 {{ic|ask}}(默认),你应该会收到来自 SSH 的问题,要你回答 yes/no。输入 {{ic|yes}} 然后回车,你的仓库就能被取出。同时,由于通过 SSH 协议访问,你现在应该有提交权限。<br />
<br />
要把一个已存在的仓库改成使用 SSH 访问,需要重新定义一下远程地址:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
要从非 22 端口连接,可以在每台主机的 {{ic|/etc/ssh/ssh_config}} 或 {{ic|~/.ssh/config}} 里配置。要为某个本地仓库设置端口(示例中用的 443 端口):<br />
<br />
{{hc|.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
你可以通过只允许用户执行 push 和 pull 操作来进一步提高 SSH 账户的安全性。这是通过将该账户的默认登录 shell 换成 git-shell 来实现的。在 [https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8 配置服务器] 中对此有所描述。<br />
<br />
=== Smart HTTP 协议 ===<br />
<br />
通过使用 git-http 后端,Git 可以像使用 SSH 协议或 Git 协议一样高效地使用 HTTP(S) 协议。此外,它不仅可以从仓库中克隆或拉取更改,还可以通过 HTTP(S) 推送更改。<br />
<br />
这个设置相当简单,因为你只需要安装 Apache Web 服务器({{pkg|apache}},启用 {{ic|mod_cgi}}、{{ic|mod_alias}} 和 {{ic|mod_env}}),当然还要安装 {{pkg|git}}。<br />
<br />
当你正在进行基本设置时,请将以下内容添加到 Apache 配置文件中,该配置文件通常位于:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
这里假设你的 Git 仓库位于 {{ic|/srv/git}},并且你想用类似 {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}} 的方式来访问它们。<br />
<br />
{{注意|请确保 Apache 对你的仓库有读写权限。}}<br />
<br />
如果需要更多详细文档,请访问:<br />
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP<br />
* https://git-scm.com/docs/git-http-backend<br />
<br />
=== Git 协议 ===<br />
<br />
{{注意|Git 协议没有加密或认证机制,且只允许读取。}}<br />
<br />
[[start|Start 并且 enable]] {{ic|git-daemon.socket}} 这个 systemd 单元。<br />
<br />
守护程序会带有以下选项启动:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
位于 {{ic|/srv/git/}} 目录下的仓库会被守护程序识别。客户端能以类似这样的方式连接:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== 设置访问权限 ===<br />
<br />
要限制读取和/或写入权限,可以使用常规 Unix 权限控制。更多信息请参考 [https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill]。<br />
<br />
如果需要更加精细的访问控制,请参考 [[gitolite]] 和 [[gitosis]]。<br />
<br />
== 参考资料 ==<br />
<br />
* Git 手册页:{{man|1|git}}<br />
* [https://git-scm.com/book/en/ Pro Git book]<br />
* 来自 GitHub 的 [https://git.github.io/git-reference/ Git Reference] <br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]<br />
* [https://wiki.videolan.org/Git VideoLAN wiki article]<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=XFS_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)&diff=521928
XFS (Русский)
2018-05-19T14:19:20Z
<p>Arisaka: Add zh-hans link.</p>
<hr />
<div>[[Category:Русский]]<br />
[[Category:File systems (Русский)]]<br />
[[en:XFS]]<br />
[[it:XFS]]<br />
[[ja:XFS]]<br />
[[zh-hans:XFS]]<br />
{{Related articles start (Русский)}}<br />
{{Related|Файловые системы}}<br />
{{Related articles end}}<br />
{{TranslationStatus (Русский)|XFS|24 июля 2017|482825}}<br />
{{Unmaintained (Русский)}}<br />
<br />
XFS is a high-performance journaling file system created by Silicon Graphics, Inc. XFS is particularly proficient at parallel IO due to its allocation group based design. This enables extreme scalability of IO threads, filesystem bandwidth, file and filesystem size when spanning multiple storage devices.<br />
<br />
== Installation ==<br />
<br />
The tools to manage XFS partions are in the {{Pkg|xfsprogs}} package from the [[official repositories]], which is included in the default base installation.<br />
<br />
== Data corruption ==<br />
<br />
If for whatever reason you experience data corruption, you will need to repair the filesystem manually.<br />
<br />
=== Repair XFS Filesystem ===<br />
<br />
First unmount the XFS filesystem.<br />
# umount /dev/sda3<br />
<br />
Once unmounted, run the {{man|8|xfs_repair}} tool.<br />
# xfs_repair -v /dev/sda3<br />
<br />
== Integrity ==<br />
<br />
xfsprogs 3.2.0 has introduced a new on-disk format (v5) that includes a metadata checksum scheme called [https://www.kernel.org/doc/Documentation/filesystems/xfs-self-describing-metadata.txt Self-Describing Metadata]. <br />
Based upon CRC32 it provides for example additional protection against metadata corruption during unexpected power losses. Checksum is enabled by default when using xfsprogs 3.2.3 or later. If you need read-write mountable xfs for older kernel, It can be easily disable using the {{ic|1=-m crc=0}} switch when calling {{man|8|mkfs.xfs}}.<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
The XFS v5 on-disk format is considered stable for production workloads starting Linux Kernel 3.15.<br />
<br />
{{Note|Unlike [[Btrfs]] and [[ZFS]], the CRC32 checksum only applies to the metadata and not actual data.}}<br />
<br />
== Performance ==<br />
<br />
For optimal speed, just create an XFS file system with:<br />
<br />
# mkfs.xfs /dev/''target_partition''<br />
<br />
Yep, so simple - since all of the [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E "boost knobs" are already "on" by default].<br />
<br />
{{Warning|Disabling barriers, disabling atime, and other performance enhancements make data corruption and failure much more likely.}}<br />
<br />
As per [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E XFS wiki], consider changing the default CFQ [[Improving performance#Tuning I/O scheduler|I/O scheduler]] (for example to [[wikipedia:Deadline_scheduler|Deadline]], [[wikipedia:NOOP_scheduler|Noop]] or [[Linux-ck#How_to_enable_the_BFQ_I.2FO_Scheduler|BFQ]]) to enjoy all of the benefits of XFS, especially on [[SSD]]s.<br />
<br />
=== Stripe size and width ===<br />
<br />
If this filesystem will be on a striped RAID you can gain significant speed improvements by specifying the stripe size to the {{man|8|mkfs.xfs}} command.<br />
<br />
See [http://xfs.org/index.php/XFS_FAQ#Q:_How_to_calculate_the_correct_sunit.2Cswidth_values_for_optimal_performance How to calculate the correct sunit,swidth values for optimal performance]<br />
<br />
=== Disable barrier ===<br />
<br />
You can increase performance by disabling barrier usage for the filesystem by adding the ''nobarrier'' mount option to the {{ic|/etc/fstab}} file.<br />
<br />
=== Access time ===<br />
<br />
On some filesystems you can increase performance by adding the {{ic|noatime}} mount option to the {{ic|/etc/fstab}} file. For XFS filesystems the default atime behaviour is {{ic|relatime}}, which has almost no overhead compared to noatime but still maintains sane atime values. All Linux filesystems use this as the default now (since around 2.6.30), but XFS has used relatime-like behaviour since 2006, so no-one should really need to ever use noatime on XFS for performance reasons.<br />
<br />
Also, {{ic|noatime}} implies {{ic|nodiratime}}, so there is never a need to specify '''nodiratime''' when '''noatime''' is also specified.<br />
<br />
=== Defragmentation ===<br />
<br />
Although the extent-based nature of XFS and the delayed allocation strategy it uses significantly improves the file system's resistance to fragmentation problems, XFS provides a filesystem defragmentation utility (''xfs_fsr'', short for XFS filesystem reorganizer) that can defragment the files on a mounted and active XFS filesystem. It can be useful to view XFS fragmentation periodically.<br />
<br />
{{man|8|xfs_fsr}} improves the organization of mounted filesystems. The reorganization algorithm operates on one file at a time, compacting or otherwise improving the layout of the file extents (contiguous blocks of file data).<br />
<br />
==== Inspect fragmentation levels ====<br />
<br />
To see how much fragmentation your file system currently has:<br />
# xfs_db -c frag -r /dev/sda3<br />
<br />
==== Perform defragmentation ====<br />
<br />
To begin defragmentation, use the {{man|8|xfs_fsr}} command:<br />
# xfs_fsr /dev/sda3<br />
<br />
=== Free inode btree ===<br />
<br />
Starting Linux 3.16, XFS has added a btree that tracks free inodes. It is equivalent to the existing inode allocation btree with the exception that the free inode btree tracks inode chunks with at least one free inode. The purpose is to improve lookups for free inode clusters for inode allocation. It improves performance on aged filesystems i.e. months or years down the track when you have added and removed millions of files to/from the filesystem. Using this feature doesn't impact overall filesystem reliability level or recovery capabilities.<br />
<br />
This feature relies on the new v5 on-disk format that has been considered stable for production workloads starting Linux Kernel 3.15. It does not change existing on-disk structures, but adds a new one that must remain consistent with the inode allocation btree; for this reason older kernels will only be able to mount read-only filesystems with the free inode btree feature.<br />
<br />
The feature enabled by default when using xfsprogs 3.2.3 or later. If you need writable filesystem for older kernel, it can be disable with {{ic|1=finobt=0}} switch when formatting a XFS partition. You will need {{ic|1=crc=0}} together.<br />
# mkfs.xfs -m crc=0,finobt=0 /dev/''target_partition''<br />
or shortly ({{ic|finobt}} depends {{ic|crc}})<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
== See also ==<br />
<br />
* [http://xfs.org/index.php/XFS_FAQ XFS FAQ]<br />
* [http://xfs.org/index.php/Improving_Metadata_Performance_By_Reducing_Journal_Overhead Improving Metadata Performance By Reducing Journal Overhead]<br />
* [[wikipedia:XFS|XFS Wikipedia Entry]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=XFS_(Italiano)&diff=521927
XFS (Italiano)
2018-05-19T14:18:28Z
<p>Arisaka: Add zh-hans link.</p>
<hr />
<div>[[Category:File systems (Italiano)]]<br />
[[en:XFS]]<br />
[[ja:XFS]]<br />
[[ru:XFS]]<br />
[[zh-hans:XFS]]<br />
==Manutenzione del FileSystem==<br />
===Controllare il grado di frammentazione===<br />
Per visualizzare su terminale il grado di frammentazione di una partizione XFS si usa il comando '''xfs_db'''<br />
xfs_db -r <device><br />
<br />
xfs_db> frag<br />
actual 269349, ideal 268587, fragmentation factor 0.28%<br />
xfs_db> <br />
L'opzione '''-r''' apre il device, o anche solo un file, in modalità '''read-only'''. Per uscire dal programma poi è sufficiente<br />
xfs_db> quit<br />
<br />
===Deframmentazione del FileSystem===<br />
La deframmentazione viene effettuata dal programma '''xfs_fsr''', che si occupa di ricollocare i file presenti (o solamente un file) nel device selezionato. Invocandolo senza parametri avviamo il processo che legge le partizione XFS presenti in '''/etc/mtab''' e per 7200 secondi (2 ore) riorganizza i file uno alla volta. Se non termina la procedura, verrà salvato un file '''/var/tmp/.xfslast''' con la situazione corrente, in modo da continuare la deframmentazione al prossimo avvio dell'applicazione conoscendo i file già riallocati.<br />
Se vogliamo effettuare l'operazione per un periodo di tempo diverso<br />
xfs_fsr -t <secondi><br />
Questa opzione è utile per configurare un job da far eseguire durante i tempi morti, è sconsigliato infatti effettuare questa operazione durante il normale utilizzo del computer<br />
<br />
===Attenzioni particolari===<br />
'''xfs_fsr''' non lavora sui file mappati in memoria, per cui potrebbero essere esposti a video degli errori se si usa l'opzione '''-v'''. Inoltre non è necessario solitamente effettuare questa operazione su '''/''', '''/boot''', '''/usr'''. L'operazione può risultare nell'impossibilità di avviare il computer se si effettua la deframmentazione di ''/boot'' in presenza del bootloader '''LILO''': in questo caso è necessario lanciare il comando <br />
lilo <br />
dopo aver deframmentato.</div>
Arisaka
https://wiki.archlinux.org/index.php?title=XFS_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=521926
XFS (简体中文)
2018-05-19T14:17:08Z
<p>Arisaka: Create page & sync with English version.</p>
<hr />
<div>[[Category:File systems (简体中文)]]<br />
[[en:XFS]]<br />
[[it:XFS]]<br />
[[ja:XFS]]<br />
[[ru:XFS]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|File systems (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|XFS|2018-05-19|521924}}<br />
<br />
XFS 是由硅谷图形公司 (Silicon Graphics, Inc.) 开发的高性能日志式文件系统。XFS 因其基于分配组 (allocation group) 的设计而特别擅长并行 IO。当该文件系统跨越多个存储设备时,这种设计使得 IO 线程数、文件系统带宽、文件和文件系统大小都具有极大的可伸缩性。<br />
<br />
== 安装 ==<br />
<br />
用于管理 XFS 分区的工具位于 {{Pkg|xfsprogs}} 软件包中,该包默认已经安装在基本系统中。<br />
<br />
== 数据损坏 ==<br />
<br />
如果遇到了任何原因的引起的数据损坏,就需要手动修复文件系统。<br />
<br />
=== 修复 XFS 文件系统 ===<br />
<br />
先卸载 XFS 文件系统:<br />
# umount /dev/sda3<br />
<br />
卸载后,运行 {{man|8|xfs_repair}} 工具来修复:<br />
# xfs_repair -v /dev/sda3<br />
<br />
== 数据完整性 ==<br />
<br />
xfsprogs 3.2.0 引入了一种新型磁盘格式 (v5),其包含了称为 [https://www.kernel.org/doc/Documentation/filesystems/xfs-self-describing-metadata.txt 自描述元数据 (Self-Describing Metadata)] 的元数据校验方案。<br />
基于 CRC32,它提供的额外保护措施可以在意外断电时防止元数据损坏。当使用 xfsprogs 3.2.3 或更高版本时,这种校验默认是打开的。如果需要在旧版内核中挂载 XFS 为可读写,可以在调用 {{man|8|mkfs.xfs}} 时加上 {{ic|1=-m crc=0}} 来关闭校验特性。<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
自 Linux Kernel 3.15 起,XFS v5 磁盘格式被视作稳定特性,可用于生产环境。<br />
<br />
{{注意|与 [[Btrfs (简体中文)|Btrfs]] 和 [[ZFS (简体中文)|ZFS]] 不同,XFS 中的 CRC32 校验仅用于元数据而非实际数据。}}<br />
<br />
== 性能 ==<br />
<br />
要获得最佳速度,只要这样创建 XFS 文件系统:<br />
<br />
# mkfs.xfs /dev/''target_partition''<br />
<br />
对,就是这么简单 - 因为所有 [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E 新特性默认都是开启的]。<br />
<br />
{{警告|关闭写入屏障 (barrier)、关闭访问时间记录 (atime) 以及其他性能增强功能会导致数据损坏和丢失的可能性更大。}}<br />
<br />
根据 [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E XFS wiki],可以考虑更改默认的 CFQ [[Improving performance#Input/output schedulers|I/O 调度器]](比如改成 [[wikipedia:Deadline_scheduler|Deadline]]、[[wikipedia:NOOP_scheduler|Noop]] 或 [[Linux-ck#How to enable the BFQ I/O Scheduler|BFQ]])来发挥 XFS 的所有优势,特别是在 [[Solid State Drives (简体中文)|SSD]] 上。<br />
<br />
=== 带区大小和宽度 ===<br />
<br />
如果这个文件系统位于条带化的 RAID 上,可以在 {{man|8|mkfs.xfs}} 命令中指定带区大小来获得显著的性能提升。<br />
<br />
参考 [http://xfs.org/index.php/XFS_FAQ#Q:_How_to_calculate_the_correct_sunit.2Cswidth_values_for_optimal_performance How to calculate the correct sunit,swidth values for optimal performance]<br />
<br />
=== 关闭写入屏障 (Barrier) ===<br />
<br />
可以通过关闭文件系统的写入屏障来提高性能,方法是向 [[fstab (简体中文)|fstab]] 中添加 {{ic|nobarrier}} 挂载选项。<br />
<br />
=== 访问时间记录 ===<br />
<br />
某些文件系统可以通过在 {{ic|/etc/fstab}} 文件中添加 {{ic|noatime}} 挂载选项来增强性能。对于 XFS 文件系统来说,默认的访问时间记录行为是 {{ic|relatime}},与 noatime 相比这几乎没有额外开销,且仍然可以记录正确的访问时间。所有 Linux 文件系统现在都以这个选项为默认值(从大约 2.6.30 版本开始),但是 XFS 从 2006 年开始就采用了类似 relatime 的特性,因此不需要出于性能考虑而在 XFS 上使用 noatime。<br />
<br />
另外,{{ic|noatime}} 包含了 {{ic|nodiratime}},所以指定了 '''noatime''' 时就不需要指定 '''nodiratime'''。<br />
<br />
=== 磁盘碎片整理 ===<br />
<br />
尽管 XFS 本质上基于区段 (Extent) 并且延迟分配策略很大程度上增强了它对磁盘碎片的抗性,XFS 仍然提供了磁盘碎片整理程序(''xfs_fsr'',XFS filesystem reorganizer 的缩写),它可以在已挂载且活动的 XFS 文件系统上整理碎片。定期查看 XFS 碎片也很有用。<br />
<br />
{{man|8|xfs_fsr}} 改进了已挂载文件系统的文件组织。该重组织算法一次操作一份文件,对文件进行压缩或改进文件区段布局(改成连续数据块)。<br />
<br />
==== 检查碎片程度 ====<br />
<br />
查看当前文件系统中有多少磁盘碎片:<br />
# xfs_db -c frag -r /dev/sda3<br />
<br />
==== 进行碎片整理 ====<br />
<br />
要启动碎片整理,使用 {{man|8|xfs_fsr}} 命令:<br />
# xfs_fsr /dev/sda3<br />
<br />
=== B+树(用于索引未用 inode) ===<br />
<br />
自 Linux 3.16 起,XFS 增加了 B+树用于索引未被使用的 inode。它等同于索引已使用 inode 的 B+树,不同之处在于索引未用 inode 的 B+树至少包含一个未用 inode。这一设计的目的是改进分配 inode 时寻找未用 inode 簇的性能。它可以提高长期使用后的文件系统性能,比如你在数月或数年之间已经向文件系统写入或删除了数百万的文件。使用这个功能不会影响整个文件系统的可靠性程度或恢复能力。<br />
<br />
这个功能依赖于新的 v5 磁盘格式,自 Linux Kernel 3.15 起它被视作可用于生产环境的稳定特性。它没有改变磁盘上原本的数据结构,但会添加一个新的结构来使它与 B+树(用于分配 inode)保持兼容;因此,旧版本的内核只能将带有 B+树功能的文件系统挂载为只读模式。<br />
<br />
当使用 xfsprogs 3.2.3 或更高版本时这个功能默认是开启的。如果你需要一个旧版本内核可写入的文件系统,这个功能可以在格式化 XFS 分区时用 {{ic|1=finobt=0}} 开关来关闭。你还需要把它和 {{ic|1=crc=0}} 一起用。<br />
# mkfs.xfs -m crc=0,finobt=0 /dev/''target_partition''<br />
也可以简写({{ic|crc}} 包含了 {{ic|finobt}})<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
== 故障排除 ==<br />
<br />
=== 根文件系统配额 ===<br />
<br />
XFS 配额挂载选项({{ic|uquota}}、{{ic|gquota}}、{{ic|prjquota}} 等)会在重新挂载文件系统时失效。要对根文件系统启用配额功能,这个挂载选项需要作为 [[Kernel parameters (简体中文)|内核参数]] {{ic|1=rootflags=}} 传递给初始化内存盘 (initramfs)。在随后的启动过程中,这个选项不需要在 {{ic|/etc/fstab}} 中挂载根 ({{ic|/}}) 文件系统的选项里再次列出。<br />
<br />
{{注意|XFS 配额相较于标准 Linux [[Disk quota|磁盘配额]] 有一些区别,这篇文章 http://inai.de/linux/adm_quota 或许值得一读。}}<br />
<br />
== 参考资料 ==<br />
<br />
* [http://xfs.org/index.php/XFS_FAQ XFS FAQ]<br />
* [http://xfs.org/index.php/Improving_Metadata_Performance_By_Reducing_Journal_Overhead Improving Metadata Performance By Reducing Journal Overhead]<br />
* [[wikipedia:XFS|XFS Wikipedia Entry]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=XFS&diff=521924
XFS
2018-05-19T13:47:18Z
<p>Arisaka: Update interlanguage links</p>
<hr />
<div>[[Category:File systems]]<br />
[[it:XFS]]<br />
[[ja:XFS]]<br />
[[ru:XFS]]<br />
[[zh-hans:XFS]]<br />
{{Related articles start}}<br />
{{Related|File systems}}<br />
{{Related articles end}}<br />
<br />
XFS is a high-performance journaling file system created by Silicon Graphics, Inc. XFS is particularly proficient at parallel IO due to its allocation group based design. This enables extreme scalability of IO threads, filesystem bandwidth, file and filesystem size when spanning multiple storage devices.<br />
<br />
== Installation ==<br />
<br />
The tools to manage XFS partions are in the {{Pkg|xfsprogs}} package, which is included in the default base installation.<br />
<br />
== Data corruption ==<br />
<br />
If for whatever reason you experience data corruption, you will need to repair the filesystem manually.<br />
<br />
=== Repair XFS Filesystem ===<br />
<br />
First unmount the XFS filesystem.<br />
# umount /dev/sda3<br />
<br />
Once unmounted, run the {{man|8|xfs_repair}} tool.<br />
# xfs_repair -v /dev/sda3<br />
<br />
== Integrity ==<br />
<br />
xfsprogs 3.2.0 has introduced a new on-disk format (v5) that includes a metadata checksum scheme called [https://www.kernel.org/doc/Documentation/filesystems/xfs-self-describing-metadata.txt Self-Describing Metadata]. <br />
Based upon CRC32 it provides for example additional protection against metadata corruption during unexpected power losses. Checksum is enabled by default when using xfsprogs 3.2.3 or later. If you need read-write mountable xfs for older kernel, It can be easily disable using the {{ic|1=-m crc=0}} switch when calling {{man|8|mkfs.xfs}}.<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
The XFS v5 on-disk format is considered stable for production workloads starting Linux Kernel 3.15.<br />
<br />
{{Note|Unlike [[Btrfs]] and [[ZFS]], the CRC32 checksum only applies to the metadata and not actual data.}}<br />
<br />
== Performance ==<br />
<br />
For optimal speed, just create an XFS file system with:<br />
<br />
# mkfs.xfs /dev/''target_partition''<br />
<br />
Yep, so simple - since all of the [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E "boost knobs" are already "on" by default].<br />
<br />
{{Warning|Disabling barriers, disabling atime, and other performance enhancements make data corruption and failure much more likely.}}<br />
<br />
As per [http://xfs.org/index.php/XFS_FAQ#Q:_I_want_to_tune_my_XFS_filesystems_for_.3Csomething.3E XFS wiki], consider changing the default CFQ [[Improving performance#Input/output schedulers|I/O scheduler]] (for example to [[wikipedia:Deadline_scheduler|Deadline]], [[wikipedia:NOOP_scheduler|Noop]] or [[Linux-ck#How to enable the BFQ I/O Scheduler|BFQ]]) to enjoy all of the benefits of XFS, especially on [[SSD]]s.<br />
<br />
=== Stripe size and width ===<br />
<br />
If this filesystem will be on a striped RAID you can gain significant speed improvements by specifying the stripe size to the {{man|8|mkfs.xfs}} command.<br />
<br />
See [http://xfs.org/index.php/XFS_FAQ#Q:_How_to_calculate_the_correct_sunit.2Cswidth_values_for_optimal_performance How to calculate the correct sunit,swidth values for optimal performance]<br />
<br />
=== Disable barrier ===<br />
<br />
You can increase performance by disabling barrier usage for the filesystem by adding the {{ic|nobarrier}} mount option to [[fstab]].<br />
<br />
=== Access time ===<br />
<br />
On some filesystems you can increase performance by adding the {{ic|noatime}} mount option to the {{ic|/etc/fstab}} file. For XFS filesystems the default atime behaviour is {{ic|relatime}}, which has almost no overhead compared to noatime but still maintains sane atime values. All Linux filesystems use this as the default now (since around 2.6.30), but XFS has used relatime-like behaviour since 2006, so no-one should really need to ever use noatime on XFS for performance reasons.<br />
<br />
Also, {{ic|noatime}} implies {{ic|nodiratime}}, so there is never a need to specify '''nodiratime''' when '''noatime''' is also specified.<br />
<br />
=== Defragmentation ===<br />
<br />
Although the extent-based nature of XFS and the delayed allocation strategy it uses significantly improves the file system's resistance to fragmentation problems, XFS provides a filesystem defragmentation utility (''xfs_fsr'', short for XFS filesystem reorganizer) that can defragment the files on a mounted and active XFS filesystem. It can be useful to view XFS fragmentation periodically.<br />
<br />
{{man|8|xfs_fsr}} improves the organization of mounted filesystems. The reorganization algorithm operates on one file at a time, compacting or otherwise improving the layout of the file extents (contiguous blocks of file data).<br />
<br />
==== Inspect fragmentation levels ====<br />
<br />
To see how much fragmentation your file system currently has:<br />
# xfs_db -c frag -r /dev/sda3<br />
<br />
==== Perform defragmentation ====<br />
<br />
To begin defragmentation, use the {{man|8|xfs_fsr}} command:<br />
# xfs_fsr /dev/sda3<br />
<br />
=== Free inode btree ===<br />
<br />
Starting Linux 3.16, XFS has added a btree that tracks free inodes. It is equivalent to the existing inode allocation btree with the exception that the free inode btree tracks inode chunks with at least one free inode. The purpose is to improve lookups for free inode clusters for inode allocation. It improves performance on aged filesystems i.e. months or years down the track when you have added and removed millions of files to/from the filesystem. Using this feature does not impact overall filesystem reliability level or recovery capabilities.<br />
<br />
This feature relies on the new v5 on-disk format that has been considered stable for production workloads starting Linux Kernel 3.15. It does not change existing on-disk structures, but adds a new one that must remain consistent with the inode allocation btree; for this reason older kernels will only be able to mount read-only filesystems with the free inode btree feature.<br />
<br />
The feature enabled by default when using xfsprogs 3.2.3 or later. If you need writable filesystem for older kernel, it can be disable with {{ic|1=finobt=0}} switch when formatting a XFS partition. You will need {{ic|1=crc=0}} together.<br />
# mkfs.xfs -m crc=0,finobt=0 /dev/''target_partition''<br />
or shortly ({{ic|finobt}} depends {{ic|crc}})<br />
# mkfs.xfs -m crc=0 /dev/''target_partition''<br />
<br />
== Troubleshooting ==<br />
<br />
=== Root file system quota ===<br />
<br />
XFS quota mount options ({{ic|uquota}}, {{ic|gquota}}, {{ic|prjquota}}, etc.) fail during re-mount of the file system. To enable quota for root file system, the mount option must be passed to initramfs as a [[kernel parameter]] {{ic|1=rootflags=}}. Subsequently, it should not be listed among mount options in {{ic|/etc/fstab}} for the root ({{ic|/}}) filesystem.<br />
<br />
{{Note|There are some differences of XFS Quota compared to standard Linux [[Disk quota]], this article http://inai.de/linux/adm_quota may be worth reading.}}<br />
<br />
== See also ==<br />
<br />
* [http://xfs.org/index.php/XFS_FAQ XFS FAQ]<br />
* [http://xfs.org/index.php/Improving_Metadata_Performance_By_Reducing_Journal_Overhead Improving Metadata Performance By Reducing Journal Overhead]<br />
* [[wikipedia:XFS|XFS Wikipedia Entry]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=RAID_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=521325
RAID (简体中文)
2018-05-16T07:03:23Z
<p>Arisaka: Full sync with English Version.</p>
<hr />
<div>[[Category:Storage virtualization (简体中文)]]<br />
[[en:RAID]]<br />
[[es:RAID]]<br />
[[it:RAID]]<br />
[[ja:RAID]]<br />
[[ru:RAID]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Software RAID and LVM}}<br />
{{Related|LVM#RAID}}<br />
{{Related|Installing with Fake RAID}}<br />
{{Related|Convert a single drive system to RAID}}<br />
{{Related|ZFS}}<br />
{{Related|ZFS/Virtual disks}}<br />
{{Related|Swap#Striping}}<br />
{{Related|Btrfs (简体中文)#RAID}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|RAID|2018-05-16|518803}}<br />
{{Style|Non-standard headers, other [[Help:Style]] issues}}<br />
<br />
独立磁盘冗余阵列 (Redundant Array of Independent Disks, [[Wikipedia:RAID|RAID]]) 是一种将多个磁盘驱动器组件(通常是多块硬盘或多个分区)组合为一个逻辑单元的存储技术。根据 RAID 的部署情况,这个逻辑单元可以是单个的文件系统,也可以是一个能在其上建立多个分区的透明中间层。根据所需的冗余量和性能要求,数据按照 [[#RAID 级别]] 中的某一种方式分布在驱动器中。所选的 RAID 级别决定了是否可以防止数据丢失(硬盘故障时)、是否提高性能或结合两者优势。<br />
<br />
本文介绍如何使用 mdadm 创建并管理一个软件磁盘阵列。<br />
<br />
{{警告|确保在操作前 [[Backup programs|备份]] 所有数据。}}<br />
<br />
== RAID 级别 ==<br />
<br />
尽管大部分 RAID 级别都或多或少地包含了数据冗余,RAID 并不能完全保证数据安全。如果遇到火灾、计算机被盗或者多块硬盘同时损坏,RAID 将无法保护数据。此外,配置一个带有 RAID 的系统是一个复杂的过程,可能会破坏现有数据。<br />
<br />
=== 基本 RAID 级别 ===<br />
<br />
有多种不同的 [[Wikipedia:Standard RAID levels|基本 RAID 级别]],下面列出了最常用的几种。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 0|RAID 0]]<br />
: 将多块硬盘组合为一个带区卷,尽管它 ''并不提供数据冗余'',它仍可以被当做是 RAID,而且它确实提供了 ''巨幅的速度提升''。如果提高速度比数据安全更重要(比如作为 [[swap]] 分区),可以选择这种 RAID 级别。在服务器上,RAID 1 和 RAID 5 阵列更加合适。在 RAID 0 阵列中,块设备的大小是最小组成分区的大小乘以组成分区的数量。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 1|RAID 1]]<br />
: 这是最直接的 RAID 级别:完全镜像。与其他 RAID 级别一样,它只在分区位于不同物理硬盘上才有效。如果某一块硬盘损坏,由 RAID 阵列提供的块设备将不受影响。可以使用 RAID 1 的情境包括了除 [[swap]] 和临时文件外的其他所有情境。请注意,如果使用由软件实现的 RAID,引导分区只能选择 RAID 1,因为读取引导分区的引导器通常无法辨识 RAID,但一个 RAID 1 的组成分区可以像常规分区一样读取。RAID 1 阵列块设备的大小是最小组成分区的大小。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 5|RAID 5]]<br />
: 需要至少 3 块物理硬盘,并结合了 RAID 1 的数据冗余和 RAID 0 的速度与可用空间上的优势。RAID 5 使用了类似 RAID 0 的条带化技术,同时也将奇偶校验块''分布式地存储在每一块磁盘上''。如果遭遇硬盘损坏,这些奇偶校验块就可以用来在替代的新磁盘上重建损坏的数据。RAID 5 仅可弥补一个组成磁盘损坏带来的损失。<br />
: {{注意|RAID 5 是结合了速度与数据冗余优势的常用选择。但值得注意的是,当一块硬盘损坏而没有及时更换,此时若再有硬盘损坏,则所有数据都将丢失。此外,考虑到现代磁盘的超大容量和消费级硬盘无法恢复的读取错误率 (Unrecoverable read error, URE),超过 4TiB 的阵列在重建数据时出现至少一处读取错误 (URE) 的概率几乎在'''预料之中'''(概率大于 50%)。因此,存储行业不再推荐使用 RAID 5。}}<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 6|RAID 6]]<br />
: 需要至少 4 块物理硬盘,提供了和 RAID 5 一样的优势并且在两块硬盘损坏时仍能保证数据安全。RAID 6 使用了和 RAID 5 类似的条带化技术,但是把两个不同的奇偶校验块 ''分布式地存储在每一块磁盘上''。如果磁盘发生故障,这些奇偶校验块将用于重建替换磁盘上的数据。RAID 6 可以承担两个组成磁盘的损失。在抵御无法恢复的读取错误 (Unrecoverable read error, URE) 时也某种程度上更加可靠,因为磁盘阵列在重建某一块损坏硬盘的数据时仍然有奇偶校验块可以校验数据。但是,总体而言,RAID 6 开销较大,大多数时候 far2 布局的 RAID 10(参见下文)提供了更快的速度和更强的可靠性,因此更倾向于采用 RAID 10。<br />
<br />
=== 嵌套 RAID 级别 ===<br />
<br />
; [[Wikipedia:Nested RAID levels#RAID 10 (RAID 1+0)|RAID 1+0]]<br />
: RAID1+0 是一种结合了两种基本 RAID 级别的嵌套级别,它相对基本级别提高了性能且增加了冗余量。它通常被称为 ''RAID10'',但是,Linux MD(内核自带的 RAID 实现)支持的 RAID10 不是简单的两层 RAID 重叠,请看下文。<br />
<br />
; [[Wikipedia:Non-standard RAID levels#Linux MD RAID 10|RAID 10]]<br />
: Linux 下的 RAID10 建立在 RAID1+0 的概念上,但它将其实现为单一的一层,这一层可以有多种不同的布局。可参考 [https://www.suse.com/zh-cn/documentation/sles11/stor_admin/data/raidmdadmr10cpx.html 创建复杂 RAID 10]。<br />
: 在 Y 块硬盘上的 ''近 X 布局'' 在不同硬盘上重复储存每个数据块 X 次,但不需要 Y 可以被 X 整除。数据块放在所镜像的磁盘上几乎相同的位置,这就是 ''近布局'' 名字的来源。它可以工作在任意数量的磁盘上,最少是 2 块。在 2 块硬盘上的近 2 布局相当于 RAID1,4 块硬盘上的近 2 布局相当于 RAID1+0。<br />
: 在 Y 块硬盘上的 ''远 X 布局'' 设计用于在镜像阵列中提供与条带化技术一样快的读取速度。它通过把每块硬盘分成前后两部分来实现这一点,写入第一块硬盘前半部分数据也会写入第二块硬盘的后半部分,反之亦然。这样可以达到一个效果,那就是把对连续数据的读取条带化,而这正是 RAID0 和 RAID5 读取性能高的原因。它的缺点在于写入连续数据时有轻微性能损失,因为硬盘磁头要运动到另一片区域来写入镜像。当数据读取性能和可用性/冗余性一样重要时,比起 RAID1+0 '''和''' RAID5,更应该优先考虑远 2 布局的 RAID10。需注意这种方式仍无法代替备份。详情请阅读维基百科相关页面。<br />
<br />
=== RAID 级别对比 ===<br />
<br />
{| class="wikitable"<br />
! RAID 级别!!数据冗余!!物理设备利用率!!读取性能!!写入性能!!最少磁盘数量<br />
|-<br />
| '''0'''||{{No}}||100%||n 倍<br />
<br />
'''最优'''<br />
||n 倍<br />
<br />
'''最优'''<br />
||2<br />
|-<br />
| '''1'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍<br />
||1 倍||2<br />
|-<br />
| '''5'''||{{Yes}}||67% - 94%||(n−1) 倍<br />
<br />
'''较优'''<br />
||(n−1) 倍<br />
<br />
'''较优'''<br />
||3<br />
|-<br />
| '''6'''||{{Yes}}||50% - 88%||(n−2) 倍||(n−2) 倍||4<br />
|-<br />
| '''10,far2'''||{{Yes}}||50%||n 倍<br />
'''最优;''' 与 RAID0 相当但加入了数据冗余<br />
||(n/2) 倍||2<br />
|-<br />
| '''10,near2'''||{{Yes}}||50%||如果有多个进程同时读取,最多 n 倍,否则 1 倍||(n/2) 倍||2<br />
|}<br />
<br />
<nowiki>*</nowiki> 其中 ''n'' 表示用于组成阵列的磁盘数量。<br />
<br />
== 实现方式 ==<br />
<br />
RAID 设备可以用不同方式来管理:<br />
<br />
; 软件 RAID<br />
: 这是最简单的实现方式,因为它不依赖于专用固件或专有软件。这种阵列由操作系统通过以下方式进行管理:<br />
:* 通过抽象层管理(比如 [[#安装|mdadm]]); {{注意|这是在本指南下文将要使用的方法。}}<br />
:* 通过逻辑卷管理器来管理(比如 [[LVM#RAID|LVM]]);<br />
:* 通过文件系统的某个组件来管理(比如 [[ZFS (简体中文)|ZFS]],[[Btrfs#RAID|Btrfs]])。<br />
<br />
; 硬件 RAID<br />
: 这种阵列由安装在计算机上的专用硬件卡直接管理,硬盘直接连接在该计算机上。RAID 的处理逻辑由板载的处理器完成,它独立于 [[Wikipedia:Central processing unit|主处理器 (CPU)]]。尽管这种方案独立于任何操作系统,但却需要驱动程序来使硬件 RAID 控制器正常工作。取决于不同的制造商,硬件 RAID 阵列可以在 option ROM 里设置或者操作系统安装完成后另行安装配套软件来设置。这种设置是独立于 Linux 内核的:内核并不能看到单独的每块硬盘。<br />
<br />
; [[Fakeraid|FakeRAID]]<br />
: 这种类型的 RAID 应当称为 BIOS 或板载 RAID,却常被错误地当做硬件 RAID 来宣传。这种阵列由伪 RAID 控制器来管理,RAID 逻辑由 option ROM 或[http://www.win-raid.com/t19f13-Intel-EFI-RAID-quot-SataDriver-quot-BIOS-Modules.html 安装了 EFI Sata 驱动程序的] 固件本身([[Unified Extensible Firmware Interface (简体中文)|UEFI]] 情况下)来完成,但并不是实现了 ''所有'' RAID 功能的完整硬件 RAID 控制器。因此,这种 RAID 有时被称为 FakeRAID。来自 [[official repositories (简体中文)|官方仓库]] 的 {{Pkg|dmraid}} 用于处理这种控制器。这里列出一些 FakeRAID 控制器:[[Wikipedia:Intel Rapid Storage Technology|Intel Rapid Storage]],JMicron JMB36x RAID ROM,AMD RAID,ASMedia 106x 和 NVIDIA MediaShield。<br />
<br />
=== 我正在使用哪一种 RAID? ===<br />
<br />
由于软件 RAID 是由用户部署的,因此用户很容易就知道 RAID 的类型。<br />
<br />
但是,辨别 FakeRAID 和真正的硬件 RAID 是很困难的。如上所述,制造商经常错误地混淆这两种类型的 RAID,还可能进行虚假宣传。这种情况下应该采取的最好方式是运行 {{ic|lspci}} 命令并在输出信息中找到你的 RAID 控制器,然后根据这些信息进行更进一步的搜索。硬件 RAID 控制器会在这一列表中出现,但 FakeRAID 不会。同时,真正的硬件 RAID 控制器通常价格很高,如果这个系统是自行组装的,那么很可能安装一个硬件 RAID 会使电脑的价格显著提高。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|mdadm}}。''mdadm'' 用于管理在纯块设备上建立起来的纯软件 RAID:底层硬件不提供任何 RAID 逻辑,只是一些磁盘而已。''mdadm'' 可以在任何块设备集合上工作,甚至是那些非常规的设备。比如,你可以用一堆 U 盘来建立 RAID 阵列。<br />
<br />
=== 准备设备 ===<br />
<br />
{{警告|这些步骤会擦除指定设备上的所有数据,输入命令请小心!}}<br />
<br />
如果设备是旧设备重用或刚从一个现有的阵列上拆下来,请擦除所有旧的 RAID 配置信息:<br />
<br />
# mdadm --misc --zero-superblock /dev/<drive><br />
<br />
或者是删除设备上的某个特定的分区:<br />
<br />
# mdadm --misc --zero-superblock /dev/<partition><br />
<br />
{{注意|<br />
* 清除一个分区的 superblock 不会影响到磁盘上的其他分区。<br />
* 考虑到 RAID 本身的功能特点,在运行中的磁盘阵列中完全地 [[securely wipe disk|安全擦除磁盘]] 是很困难的。请在创建阵列前考虑要不要安全擦除磁盘。<br />
}}<br />
<br />
=== 对磁盘进行分区 ===<br />
<br />
强烈推荐对用于阵列的硬盘进行分区。考虑到大多数 RAID 用户会用到超过 2 TiB 的硬盘,因此推荐并要求使用 GPT。参阅 [[Partitioning (简体中文)]] 获取关于磁盘分区的更多信息以及可供使用的 [[Partitioning (简体中文)#分区工具|分区工具]]。<br />
<br />
{{注意|也可以在裸磁盘(没有分区的磁盘)上直接创建 RAID,但不推荐这么做,因为这样可能会导致更换损坏硬盘时出现问题}}<br />
<br />
{{注意|当更换 RAID 中的某块损坏的硬盘时,新硬盘的大小必须恰好等于或大于损坏的硬盘,否则无法完成阵列重建过程。即使是同一厂商相同型号的硬盘也可能有容量上的细微差别。通过在磁盘末尾保留一些未分配的空间可以消除磁盘容量上的细微差异,这样可以使替代磁盘的型号选择更加容易。因此,最好在磁盘末尾留出大约 100 MiB 的未分配空间。}}<br />
<br />
==== GUID 分区表 ====<br />
<br />
* 创建分区以后,这些分区的 [[Wikipedia:GUID Partition Table#Partition type GUIDs|类型标识符 (GUID)]] 应该是 {{ic|A19D880F-05FC-4D3B-A006-743F0F84911E}}(在 ''fdisk'' 里将分区类型改为 {{ic|Linux RAID}} 或在 ''gdisk'' 里改为 {{ic|FD00}} 可以给所选分区分配这个标识符)。<br />
* 如果使用了一个更大的磁盘阵列,可以考虑分配 [[Persistent block device naming (简体中文)#by-label|文件系统标签]] 或 [[Persistent block device naming (简体中文)#by-partlabel|分区标签]] 用于以后区分每块单独的硬盘。<br />
* 建议在每个设备上创建大小相同的分区。<br />
<br />
==== 主引导记录 (MBR) ====<br />
<br />
对于在使用 MBR 的硬盘上创建分区的用户,可用的 [[Wikipedia:Partition type|分区类型 ID]] 包括:<br />
<br />
* {{ic|0xFD}}: 自动检测的 RAID(''fdisk'' 中称为 {{ic|Linux raid autodetect}})<br />
* {{ic|0xDA}}: 无文件系统(''fdisk'' 中称为 {{ic|Non-FS data}})<br />
<br />
更多信息请参阅 [https://raid.wiki.kernel.org/index.php/Partition_Types Linux Raid Wiki:Partition Types]。<br />
<br />
=== 创建阵列 ===<br />
<br />
使用 {{ic|mdadm}} 来创建阵列。参阅 {{man|8|mdadm}} 获取支持的选项。下面列出部分使用范例。<br />
<br />
{{警告|不要简单地复制/粘贴下面的示例,确保你已经使用正确的选项和设备名称替代了示例中相应的内容。}}<br />
<br />
{{注意|<br />
* 如果有一个从 [[Syslinux (简体中文)|Syslinux]] 启动的 RAID1 阵列,在 syslinux v4.07 中要求元数据值为 1.0,而不是默认的 1.2。<br />
* 当用 [[Archiso (简体中文)|Arch 安装镜像]] 创建磁盘阵列时,请使用 {{ic|1=--homehost=''myhostname''}} 选项设置 [[hostname|主机名]](或者 {{ic|1=--homehost=any}} 选项无论在什么主机上都用相同的主机名),否则主机名称 {{ic|archiso}} 会被写入阵列的元数据中。<br />
}}<br />
<br />
{{提示|要为 RAID 设备指定一个自定义的名称,可以使用 {{ic|1=--name=''MyRAIDName''}} 选项或将 RAID 设备路径改为 {{ic|/dev/md/''MyRAIDName''}}。Udev 会使用该名称创建指向 {{ic|/dev/md/}} 内 RAID 阵列的符号链接。如果 {{ic|homehost}} 与当前 [[hostname|主机名]] 匹配(或者 homehost 设为了 {{ic|any}})则链接将会是 {{ic|/dev/md/''name''}},如果 homehost 不匹配那么链接将会是 {{ic|/dev/md/''homehost'':''name''}}。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立 RAID1 阵列:<br />
<br />
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1<br />
<br />
下面这个例子展示了使用 4 块磁盘作为工作 (active) 磁盘,1 块作为备用 (spare) 磁盘建立 RAID5 阵列:<br />
<br />
# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1<br />
<br />
{{提示|{{ic|--chunk}} 可用于修改默认的区块大小。更多关于优化区块大小的内容请参阅 [http://www.zdnet.com/article/chunks-the-hidden-key-to-raid-performance/ Chunks: the hidden key to RAID performance]。}}<br />
<br />
下面这个例子展示了在 2 个设备上建立远 2 布局的 RAID10 阵列 (RAID10, far2):<br />
<br />
# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1<br />
<br />
这样,阵列就会在虚拟设备 {{ic|/dev/mdX}} 下建立起来,容量已经合并且可以使用(但处于降级模式)。mdadm 在后台同步数据时你已经可以直接开始使用这个阵列了。储存奇偶校验位可能要花很长时间,可以用这个命令查看进度:<br />
<br />
$ cat /proc/mdstat<br />
<br />
=== 更新配置文件 ===<br />
<br />
默认情况下,{{ic|mdadm.conf}} 中的大部分内容都被注释掉了,它应该只包含如下内容:<br />
<br />
{{hc|/etc/mdadm.conf|<br />
...<br />
DEVICE partitions<br />
...<br />
}}<br />
<br />
这一指令告诉 mdadm 检查由 {{ic|/proc/partitions}} 引用的所有设备并尽可能将其中的阵列组合起来。如果你确实想启动所有可用的阵列并且确信不存在意料之外的超级块(比如安装了新的存储设备),那么这样的配置就很好。当然有一种更精准的控制方法,就是显式地将阵列添加到 {{ic|/etc/mdadm.conf}}:<br />
<br />
# mdadm --detail --scan >> /etc/mdadm.conf<br />
<br />
这将会在配置中添加类似这样的内容:<br />
<br />
{{hc|/etc/mdadm.conf|2=<br />
...<br />
DEVICE partitions<br />
...<br />
ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe<br />
}}<br />
<br />
这也会使 mdadm 检查由 {{ic|/proc/partitions}} 引用的设备。但是,只有超级块的 UUID 是 {{ic|27664…}} 的设备才会被组合成激活的阵列。<br />
<br />
更多信息请参阅 {{man|5|mdadm.conf}}。<br />
<br />
=== 组合成磁盘阵列 ===<br />
<br />
更新配置文件后即可用 mdadm 组合磁盘阵列:<br />
<br />
# mdadm --assemble --scan<br />
<br />
=== 格式化 RAID 上的文件系统 ===<br />
<br />
现在磁盘阵列已经可以像普通分区一样被格式化成某个 [[File systems (简体中文)|文件系统]],但要记住:<br />
<br />
* 不是所有文件系统都支持超大分区(参阅 [[Wikipedia:Comparison of file systems#Limits]])。<br />
* 文件系统需要支持在线增大和收缩(参阅 [[Wikipedia:Comparison of file systems#Features]])。<br />
* 应合理计算跨度大小和带区宽度来获得最佳性能。<br />
<br />
==== 计算 stride(跨度大小)和 stripe width(带区宽度) ====<br />
<br />
优化文件系统结构以适应底层 RAID 结构需要 2 个参数:''stride'' 和 ''stripe width''。它们对应于 RAID 的 ''chunk size(区块大小)'' 、文件系统的 ''block size(块大小)'' 以及 ''"data disks"(数据盘)的数量''。<br />
<br />
Chunk size(RAID 区块大小)是 RAID 阵列的一个属性,在阵列创建时就已经定好了。目前 {{ic|mdadm}} 默认该值为 512 KiB。这个参数可以用 {{ic|mdadm}} 读取:<br />
<br />
# mdadm --detail /dev/mdX | grep 'Chunk Size'<br />
<br />
Block size(块大小)是文件系统的一个属性,在文件系统创建时就已经定好了。在大部分文件系统上(包括 ext4)默认是 4 KiB。更多关于当前系统 ext4 的信息可以查看 {{ic|/etc/mke2fs.conf}} 文件。<br />
<br />
"Data disks"(数据盘)的数量指的是阵列能够完全重建数据所要求的最少可用设备。例如,对于 N 个设备的 raid0 来说这个数量是 N,对于 raid5 来说是 N-1。<br />
<br />
当你获得了这三个参数时,stride 和 stripe width 可以用下列公式来计算:<br />
<br />
stride = chunk size / block size<br />
stripe width = number of data disks * stride<br />
<br />
===== 范例 1. RAID0 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID0 阵列是由 2 块物理硬盘组成的。<br />
* Chunk size(RAID 区块大小)是 64 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 64/4 = 16。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 2*16 = 32。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.5 -b 4096 -E stride=16,stripe-width=32 /dev/md0<br />
<br />
===== 范例 2. RAID5 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID5 阵列由 4 块物理硬盘组成,3 块是数据盘,1 块是奇偶校验盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。在这个例子中,stripe width 的大小是 3*128 = 384.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=384 /dev/md0<br />
<br />
关于 stride 和 stripe width 的更多信息,请参阅:[http://wiki.centos.org/HowTos/Disk_Optimization RAID Math]。<br />
<br />
===== 范例 3. RAID10,far2 =====<br />
<br />
本范例使用了正确的 stride 和 stripe width 将合并后的分区格式化成了 ext4:<br />
<br />
* 假设这一 RAID10 阵列由 2 块物理硬盘组成。考虑到远 2 布局的 RAID10 的自身特性,两块硬盘都是数据盘。<br />
* Chunk size(RAID 区块大小)是 512 KiB。<br />
<br />
{{hc|# mdadm --detail /dev/md0 {{!}} grep 'Chunk Size'|<br />
Chunk Size : 512K<br />
}}<br />
<br />
* Block size(文件系统块大小)是 4 KiB。<br />
<br />
因为 stride = chunk size / block size。<br />
在这个例子中,stride 大小是 512/4 = 128。<br />
<br />
因为 stripe width = # of physical '''data''' disks * stride。<br />
在这个例子中,stripe width 的大小是 2*128 = 256。<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/md0<br />
<br />
== 在 Live CD 中挂载 RAID ==<br />
<br />
如果你需要在 Live CD 中挂载 RAID 分区,用这个命令:<br />
<br />
# mdadm --assemble /dev/<disk1> /dev/<disk2> /dev/<disk3> /dev/<disk4><br />
<br />
如果缺一块盘的 RAID 1 被错误地识别为了 RAID 1(参照 {{ic|mdadm --detail /dev/md<number>}})并报告为非活动状态(参照 {{ic|cat /proc/mdstat}}),需要先停止磁盘阵列:<br />
<br />
# mdadm --stop /dev/md<number><br />
<br />
== 在 RAID 上安装 Arch Linux ==<br />
<br />
{{注意|本节仅适用于根文件系统在磁盘阵列上的情况。如果你的磁盘阵列上只是一个数据分区,那么可以跳过本节。}}<br />
<br />
你应该在安装过程中的 [[Partitioning (简体中文)|分区]] 和 [[File systems (简体中文)#创建文件系统|格式化]] 步骤之间创建 RAID 阵列。这将会把一个位于 RAID 阵列上的分区格式化成根文件系统,而不是直接格式化一个分区。<br />
按照 [[#安装]] 一节的步骤创建 RAID 阵列。,然后继续安装过程,直到 pacstrap 步骤完成。<br />
当使用 [[Unified Extensible Firmware Interface (简体中文)|UEFI 启动]] 时,还需要阅读 [[EFI System Partition (简体中文)#RAID 上的 ESP]]。<br />
<br />
=== 更新配置文件 ===<br />
<br />
{{注意|这些操作应该在 chroot 以外完成,因此要在文件路径前加上 {{ic|/mnt}}。}}<br />
<br />
在基本系统安装完成以后,RAID 的默认配置文件 {{ic|mdadm.conf}} 需要这样来更新:<br />
<br />
# mdadm --detail --scan >> /mnt/etc/mdadm.conf<br />
<br />
在运行这个命令以后一定要用文本编辑器检查 {{ic|mdadm.conf}} 配置文件来确保它的内容看起来是合理的。<br />
<br />
{{注意|为防止系统启动时 {{ic|mdmonitor.service}} 启动失败(默认设为自动启动),你需要取消 {{ic|MAILADDR}} 的注释,并且在 {{ic|mdadm.conf}} 结尾留下可处理磁盘阵列出错通知的邮件地址和/或应用程序。参阅 [[#启用事件邮件通知]]。}}<br />
<br />
现在继续安装过程直到 [[Installation guide (简体中文)#Initramfs]] 步骤之前为止,然后按照下一节的步骤做。<br />
<br />
=== 配置 mkinitcpio ===<br />
<br />
{{注意|这些操作应该在 chroot 时完成。}}<br />
<br />
向 {{ic|mkinitcpio.conf}} 中的 [[mkinitcpio (简体中文)#钩子(HOOKS)|HOOKS]] 部分添加 {{ic|mdadm_udev}} 来为初始化内存盘添加 mdadm 支持:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
HOOKS=(base udev autodetect keyboard modconf block '''mdadm_udev''' filesystems fsck)<br />
...<br />
}}<br />
<br />
如果在一个 FakeRAID 阵列上使用 {{ic|mdadm_udev}} 钩子,建议在 [[mkinitcpio (简体中文)#附加文件(BINARIES、FILES)|BINARIES]] 列表中添加 ''mdmon'':<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=<br />
...<br />
BINARIES=('''mdmon''')<br />
...<br />
}}<br />
<br />
然后 [[mkinitcpio (简体中文)#创建和启用镜像|重新生成初始化内存盘]]。<br />
<br />
参考 [[mkinitcpio (简体中文)#使用 RAID 磁盘阵列]]。<br />
<br />
=== 配置 boot loader ===<br />
<br />
将 {{ic|root}} 参数指向映射的磁盘,例如:<br />
<br />
root=/dev/md/''MyRAIDArray''<br />
<br />
如果按上述用内核设备节点来指定映射磁盘的方法之后,从软件 RAID 分区启动失败了,那就用 [[Persistent block device naming (简体中文)|持久化命名块设备]] 中的某种方法来指定映射的磁盘,例如:<br />
<br />
root=LABEL=Root_Label<br />
<br />
参考 [[GRUB#RAID]]。<br />
<br />
== 维护 RAID ==<br />
<br />
=== 数据清扫 (Scrubbing) ===<br />
<br />
定期运行数据 [[wikipedia:Data_scrubbing|清扫 (Scrubbing)]] 来检查并修复错误是一种很好的做法。一次完整数据清扫可能会花费数个小时,具体取决于磁盘阵列的大小和配置。<br />
<br />
启动数据清扫:<br />
<br />
# echo check > /sys/block/md0/md/sync_action<br />
<br />
数据检查操作会扫描驱动器来检查坏扇区并自动修复它们。如果找到了包含损坏数据的好扇区(本扇区中的数据与另一块硬盘中记录本扇区应有的数据不符,例如奇偶校验块和另一块数据块相结合可以证明本数据块是错误的),那就不动作,但记录下这一事件(见下文)。这种“不动作”允许管理员自行检查坏扇区中原本的数据和从冗余数据中重建的数据,然后决定保留哪个。<br />
<br />
与许多 mdadm 相关的任务/事项一样,数据清扫的进度也可以通过查看 {{ic|/proc/mdstat}} 文件来查询。<br />
<br />
例如:<br />
<br />
{{hc|$ cat /proc/mdstat|<nowiki><br />
Personalities : [raid6] [raid5] [raid4] [raid1]<br />
md0 : active raid1 sdb1[0] sdc1[1]<br />
3906778112 blocks super 1.2 [2/2] [UU]<br />
[>....................] check = 4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec<br />
bitmap: 0/30 pages [0KB], 65536KB chunk<br />
</nowiki>}}<br />
<br />
安全地停止当前的数据清扫操作:<br />
<br />
# echo idle > /sys/block/md0/md/sync_action<br />
<br />
{{注意|如果在数据清扫暂停时重启了系统,将继续进行清扫。}}<br />
<br />
数据清扫完成后,管理员可以检查有多少数据块(如果有的话)被标记为坏块:<br />
<br />
# cat /sys/block/md0/md/mismatch_cnt<br />
<br />
==== 关于数据清扫的一般说明 ====<br />
<br />
{{注意|用户也可以 echo '''repair''' 到 {{ic|/sys/block/md0/md/sync_action}} 里面,但是这是不明智的,因为一旦遇到数据不一致就被自动改写为一致。危险之处在于我们实际并不知道奇偶校验块和数据块哪个是对的(在 RAID1 中是不知道哪个数据块是对的)。因此自动清扫操作能不能用正确数据替换错误数据取决于运气。}}<br />
<br />
以 root 身份设定一个 cron 任务来定期执行清扫是很好的。{{AUR|raid-check}} 会对此有所帮助。如果要用 systemd 定时器而不是 cron 来执行定期清扫,{{AUR|raid-check-systemd}} 中包含了相同的脚本和配套的 systemd 定时器单元文件。<br />
<br />
{{注意|对于常规的大容量驱动器,清扫工作耗时大约 '''6 秒每 GB'''(即每 TB 大约需要 1 小时 45 分钟),因此应合理确定 cron 任务或定时器的开始时间。}}<br />
<br />
==== 对清扫 RAID1 和 RAID10 的说明 ====<br />
<br />
由于 RAID1 和 RAID10 本质上就是没有数据缓冲的,所以即使阵列工作正常,它的不匹配计数仍然可能是个非零值。这些不匹配计数只存在于正在写入数据的区域,且它们不反映任何问题。但是,我们无法区分非零的不匹配计数到底代表正在写入数据还是确实存在问题。这是造成 RAID1 和 RAID10 阵列误报错误的根源。即使如此,仍然建议定期清扫以发现并纠正驱动器上可能出现的坏扇区。<br />
<br />
=== 从阵列中移除设备 ===<br />
<br />
要从阵列中移除一个设备,先将这个设备标记为 faulty(故障):<br />
<br />
# mdadm --fail /dev/md0 /dev/sdxx<br />
<br />
现在从阵列中移除这个设备:<br />
<br />
# mdadm --remove /dev/md0 /dev/sdxx<br />
<br />
永久移除设备(比如想把一个设备拿出来单独使用):<br />
先使用上述两个命令,然后:<br />
<br />
# mdadm --zero-superblock /dev/sdxx<br />
<br />
{{警告|<br />
* 不要在 RAID0 阵列或者其他线性存放数据的阵列中进行这个操作!否则数据会丢失!<br />
* 重新使用已经移除的硬盘却不清除它的超级块将会导致下次启动时丢失所有数据。(因为 mdadm 将会把它当做磁盘阵列的一部分来使用)。<br />
}}<br />
<br />
停止使用某个阵列:<br />
<br />
# 卸载 (umount) 目标阵列<br />
# 用这个命令停止磁盘阵列运行:{{ic|mdadm --stop /dev/md0}}<br />
# 将本节开头的三个命令在每块硬盘上都运行一遍。<br />
# 将 {{ic|/etc/mdadm.conf}} 中的相关行移除。<br />
<br />
=== 向阵列中添加设备 ===<br />
<br />
可以在系统正在运行且设备已经挂载的情况下使用 mdadm 添加新设备。<br />
按照前文所述的方法,使用现有阵列中相同的布局对新设备进行分区。<br />
<br />
如果 RAID 阵列尚未组合,先组合它们:<br />
<br />
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1<br />
<br />
向阵列中添加新设备:<br />
<br />
# mdadm --add /dev/md0 /dev/sdc1<br />
<br />
这一步 mdadm 不会花费很长时间。再次说明,可以这样检查进度:<br />
<br />
# cat /proc/mdstat<br />
<br />
用这个命令检查已经添加的设备:<br />
<br />
# mdadm --misc --detail /dev/md0<br />
<br />
{{注意|对于 RAID0 设备可能会收到以下错误信息:<br />
<br />
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument<br />
<br />
这是由于上述命令会将新磁盘添加为 "spare"(备用)盘,但是 RAID0 中不存在备用盘。如果想往 RAID0 阵列中添加磁盘,你需要同时使用 "grow" 和 "add" 参数。如下所示:<br />
<br />
# mdadm --grow /dev/md0 --raid-devices<nowiki>=</nowiki>3 --add /dev/sdc1<br />
<br />
}}<br />
<br />
=== 增大 RAID 卷的大小 ===<br />
<br />
如果给阵列安装了更大的磁盘,或者增大了分区大小,可能就需要增大 RAID 卷的大小以适应更大的可用空间。这一过程可用首先按照上文中关于更换磁盘的步骤来做。当 RAID 卷在更大的磁盘上重建完成后,这个卷需要 "grow" 来填充多出来的空间。<br />
<br />
# mdadm --grow /dev/md0 --size=max<br />
<br />
接着,在 RAID 卷 {{ic|/dev/md0}} 上的现有分区可能需要调整大小。参阅 [[Partitioning (简体中文)]] 获取更多信息。最后,上述分区上的文件系统也需要重新调整大小。如果用 {{ic|gparted}} 来完成分区操作,这些都会自动完成。如果用的是其他工具,请手动卸载 (unmount) 文件系统并调整其大小。<br />
<br />
# umount /storage<br />
# fsck.ext4 -f /dev/md0p1<br />
# resize2fs /dev/md0p1<br />
<br />
=== 修改同步速度限制 ===<br />
<br />
同步工作需要一定的时间。如果本机不需要完成其他任务,可以提高速度限制值。<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 0.0% (77696/155042219) finish=265.8min speed=9712K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
查看当前速度限制:<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_min|<br />
1000<br />
}}<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_max|<br />
200000<br />
}}<br />
<br />
提高限制值:<br />
<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_min<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_max<br />
<br />
然后查看同步速度和预计完成时间:<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1]<br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 1.3% (2136640/155042219) finish=158.2min speed=16102K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
更多信息可参阅 [[sysctl#MDADM]]。<br />
<br />
== 监视运行情况 ==<br />
<br />
可以显示当前 RAID 设备状态的一行简单命令:<br />
<br />
{{hc|# awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat<br />
|md1: [UU]<br />
md0: [UU]<br />
}}<br />
<br />
=== 用 watch 监视 mdstat ===<br />
<br />
# watch -t 'cat /proc/mdstat'<br />
<br />
或者最好用 {{pkg|tmux}}<br />
<br />
# tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"<br />
<br />
=== 用 iotop 追踪 IO ===<br />
<br />
{{pkg|iotop}} 可以显示各个进程的输入输出状态。请用这个命令来查看 RAID 线程的输入输出。<br />
<br />
# iotop -a -p $(sed 's, , -p ,g' <<<`pgrep "_raid|_resync|jbd2"`)<br />
<br />
=== 用 iostat 追踪 IO ===<br />
<br />
{{Pkg|sysstat}} 包中的 ''iostat'' 实用程序可以显示各个设备和分区的输入输出统计。<br />
<br />
# iostat -dmy 1 /dev/md0<br />
# iostat -dmy 1 # all<br />
<br />
=== 启用事件邮件通知 ===<br />
<br />
要完成发送邮件的任务需要一个 smtp 邮件服务器或至少需要一个 ssmtp/msmtp 邮件转发器。大概最简单的解决方案是使用 {{AUR|dma}},它非常小巧(安装完只占用 0.08 MiB)且不需要设置。<br />
<br />
编辑 {{ic|/etc/mdadm.conf}} 来添加用于接收通知的邮件地址。<br />
<br />
{{注意|如果用的是上文提到的 dma,用户可以直接将邮件发送到本机 (localhost) 的某个用户名 (username) 中,不一定非要发到外部邮件地址。}}<br />
<br />
测试配置是否正确:<br />
<br />
# mdadm --monitor --scan --oneshot --test<br />
<br />
mdadm 使用 {{ic|mdmonitor.service}} 来完成监控任务,所以现在你无需进行更多设置了。如果你没有在 {{ic|/etc/mdadm.conf}} 设置邮件地址,那么这个 service 就会出错。如果你不想接收 mdadm 一般事件通知,可以忽略这个错误;如果不想接收一般事件通知但是需要接收故障信息,可以 [[Systemd (简体中文)#使用单元|mask(屏蔽)]] 这个 unit。<br />
<br />
==== 其他实现方式 ====<br />
<br />
为避免安装 smtp 邮件服务器或邮件转发器的麻烦,可以使用系统上已经安装的 [[S-nail]] 工具(不要忘了设置它)。<br />
<br />
创建 {{ic|/etc/mdadm_warning.sh}} 文件:<br />
<br />
{{hc|/etc/mdadm_warning.sh|2=<br />
#!/bin/bash<br />
event=$1<br />
device=$2<br />
<br />
echo " " | /usr/bin/mailx -s "$event on $device" '''destination@email.com'''<br />
}}<br />
<br />
然后给它执行权限:{{ic|chmod +x /etc/mdadm_warning.sh}}<br />
<br />
然后在 mdadm.conf 中添加这一行:<br />
<br />
PROGRAM /etc/mdadm_warning.sh<br />
<br />
用前述的方法测试并启用它。<br />
<br />
== 故障排除 ==<br />
<br />
如果你在重启计算机时遇到类似 "invalid raid superblock magic" 的错误,并且除了已经配置好的硬盘外又接了其他硬盘,请检查硬盘顺序是不是正确的。在安装 RAID 时,硬盘编号可能是 hdd、hde 和 hdf,但是重启后它们的编号可能变成了 hda、hdb 和 hdc。请相应地调整你的内核参数。这种情况经常发生。<br />
<br />
=== Error: "kernel: ataX.00: revalidation failed" ===<br />
<br />
如果你突然(在重启、修改 BIOS 设置后)遇到类似错误信息:<br />
<br />
Feb 9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)<br />
<br />
这并不意味着设备已经损坏。尽管你可能会在网上看到一些讲内核崩溃的链接指向最坏的结果,但总而言之,并不是内核崩溃。可能你不知怎么的在 BIOS 里或内核参数里修改了 APIC 或 ACPI 设置。把它改回来就好了。通常关闭 APIC 和/或 ACPI 就好了。<br />
<br />
=== 磁盘阵列以只读模式启动 ===<br />
<br />
当由 md 启动磁盘阵列时,超级块将被改写,数据同步可能已经开始了。要以只读模式启动,可以向内核模块 {{ic|md_mod}} 传递参数 {{ic|start_ro}}。设置了这个参数以后,新的磁盘阵列进入 'auto-ro' 模式,该模式停止了所有内部读写操作(更新超级块、再同步、数据恢复),并且会在第一个写入请求到来时自动切换至 'rw' (读写)模式。<br />
<br />
{{注意|在第一个写入请求到来前使用 {{ic|mdadm --readonly}} 命令可以将阵列设置为真正的 'ro' (只读)模式,还可以用 {{ic|mdadm --readwrite}} 命令直接开始再同步而不用等待写入请求。}}<br />
<br />
要在启动时设置该参数,在内核启动参数中添加 {{ic|1=md_mod.start_ro=1}}。<br />
<br />
也可以在模块加载时传递该参数,可以从 {{ic|/etc/modprobe.d/}} 下的文件中传递,也可以直接从 {{ic|/sys/}} 传递:<br />
<br />
# echo 1 > /sys/module/md_mod/parameters/start_ro<br />
<br />
=== 在损坏或缺失磁盘的情况下恢复 RAID ===<br />
<br />
当磁盘阵列中的一个驱动器由于任何原因损坏时,也可能会发生上述错误。如果在缺失一块硬盘的情况下你仍需要强制启动磁盘阵列,输入以下命令(根据实际修改):<br />
<br />
# mdadm --manage /dev/md0 --run<br />
<br />
现在你应该可以用类似下面的命令来挂载它(如果在 fstab 里有它的话):<br />
<br />
# mount /dev/md0<br />
<br />
现在磁盘阵列应该已经工作并且可以使用,但仍旧是缺一块盘的状态。因此需要按照上文 [[#准备设备]] 所述再添加一个磁盘分区,然后就可以将新磁盘分区加入到磁盘阵列中:<br />
<br />
# mdadm --manage --add /dev/md0 /dev/sdd1<br />
<br />
如果输入:<br />
<br />
# cat /proc/mdstat<br />
<br />
你就能看到磁盘阵列已经激活并正在重建。<br />
<br />
你可能还需要更新你的配置文件(参阅:[[#更新配置文件]])。<br />
<br />
== 基准测试 ==<br />
<br />
用于 RAID 基准测试的工具有很多种。不同 RAID 最显著的不同是多个线程在读取 RAID 卷时的速度提升程度。<br />
<br />
{{AUR|tiobench}} 通过测量磁盘的全线程读写 (fully-threaded I/O) 来专门测试多线程性能提升程度。<br />
<br />
{{Pkg|bonnie++}} 测试对一个或多个数据库类型文件的读写,以及对小文件的创建、读取、删除,这样可以模拟 Squid、INN 和 Maildir format e-mail 等程序的文件读写。其附带的 [http://www.coker.com.au/bonnie++/zcav/ ZCAV] 程序可以测试硬盘不同区域的性能,且不用向硬盘写入任何数据。<br />
<br />
'''不应该''' 使用 {{ic|hdparm}} 来对 RAID 进行基准测试,因为它多次返回的结果会非常不一致。<br />
<br />
== 参考资料 ==<br />
<br />
{{Out of date|许多链接太旧且无效。}}<br />
<br />
* [http://www.gentoo.org/doc/en/articles/software-raid-p1.xml Software RAID in the new Linux 2.4 kernel, Part 1]{{Dead link|2018|03|10}} and [http://www.gentoo.org/doc/en/articles/software-raid-p2.xml Part 2]{{Dead link|2018|03|10}} in the Gentoo Linux Docs<br />
* [http://raid.wiki.kernel.org/index.php/Linux_Raid Linux RAID wiki entry] on The Linux Kernel Archives<br />
* [https://raid.wiki.kernel.org/index.php/Write-intent_bitmap How Bitmaps Work]<br />
* [http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-raid.html Chapter 15: Redundant Array of Independent Disks (RAID)] of Red Hat Enterprise Linux 6 Documentation<br />
* [http://tldp.org/FAQ/Linux-RAID-FAQ/x37.html Linux-RAID FAQ] on the Linux Documentation Project<br />
* [http://support.dell.com/support/topics/global.aspx/support/entvideos/raid?c=us&l=en&s=gen Dell.com Raid Tutorial]{{Dead link|2018|03|10}} - Interactive Walkthrough of Raid<br />
* [http://www.miracleas.com/BAARF/ BAARF]{{Dead link|2018|03|10}} including ''[http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt Why should I not use RAID 5?]''{{Dead link|2018|03|10}} by Art S. Kagel<br />
* [http://www.linux-mag.com/id/7924/ Introduction to RAID], [http://www.linux-mag.com/id/7931/ Nested-RAID: RAID-5 and RAID-6 Based Configurations], [http://www.linux-mag.com/id/7928/ Intro to Nested-RAID: RAID-01 and RAID-10], and [http://www.linux-mag.com/id/7932/ Nested-RAID: The Triple Lindy] in Linux Magazine<br />
* [http://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html HowTo: Speed Up Linux Software Raid Building And Re-syncing]<br />
* [http://fomori.org/blog/?p=94 RAID5-Server to hold all your data]<br />
* [[Wikipedia:Non-RAID drive architectures]]<br />
<br />
'''mdadm'''<br />
* [http://anonscm.debian.org/gitweb/?p=pkg-mdadm/mdadm.git;a=blob_plain;f=debian/FAQ;hb=HEAD Debian mdadm FAQ]<br />
* [http://www.kernel.org/pub/linux/utils/raid/mdadm/ mdadm source code]<br />
* [http://www.linux-mag.com/id/7939/ Software RAID on Linux with mdadm] in Linux Magazine<br />
* [[Wikipedia:mdadm|Wikipedia - mdadm]]<br />
<br />
'''Forum threads'''<br />
* [http://forums.overclockers.com.au/showthread.php?t=865333 Raid Performance Improvements with bitmaps]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=125445 GRUB and GRUB2]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=123698 Can't install grub2 on software RAID]<br />
* [http://forums.gentoo.org/viewtopic-t-888624-start-0.html Use RAID metadata 1.2 in boot and root partition]<br />
<br />
'''RAID with encryption'''<br />
* [http://www.shimari.com/dm-crypt-on-raid/ Linux/Fedora: Encrypt /home and swap over RAID with dm-crypt] by Justin Wells</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Git_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=520120
Git (简体中文)
2018-05-04T07:33:16Z
<p>Arisaka: Sync with English version.</p>
<hr />
<div>[[Category:Version Control System (简体中文)]]<br />
[[en:Git]]<br />
[[es:Git]]<br />
[[ja:Git]]<br />
{{TranslationStatus (简体中文)|Git|2018-05-04|520101}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion (简体中文)}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}<br />
<br />
[[wikipedia:Git (software)|Git]] 是一个由 Linux 内核作者 Linus Torvalds 编写的版本控制系统(VCS),现在被用来维护 [[AUR]] 软件包以及数以千计的其他项目,其中包括 Linux 内核。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|git}} 软件包。要使用开发版本,请安装 {{AUR|git-git}} 软件包。当使用 ''git svn''、''git gui'' 和 ''gitk'' 等工具时请检查可选依赖项是否安装。<br />
<br />
{{注意|要打开 ''git-gui'' 的拼写检查功能,请安装 {{Pkg|aspell}},同时还需要与 {{ic|LC_MESSAGES}} [[Environment variables (简体中文)|环境变量]] 相对应的字典文件。参阅 {{Bug|28181}} 和 [[aspell (简体中文)]]。}}<br />
<br />
== 配置 ==<br />
<br />
你至少需要设置好姓名和邮箱之后才能开始使用 Git:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@example.com''"<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE 起步 - 初次运行 Git 前的配置]。<br />
<br />
更多设置选项可参阅 [[#提示与技巧]]。<br />
<br />
== 基本用法 ==<br />
<br />
一个 Git 版本库包含在一个名为 {{ic|.git}} 的目录内,该目录包含了修订历史以及其他元数据。版本库所跟踪的目录(默认为父目录)称为工作目录。在工作树进行的更改在被提交 (commit) 前需要先暂存 (stage) 起来。Git 还可以让你恢复以前提交的工作树文件。<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E5%9F%BA%E7%A1%80 起步 - Git 基础]。<br />
<br />
=== 获取一个 Git 仓库 ===<br />
<br />
* 初始化一个版本库<br />
:{{ic|git init}},参阅 {{man|1|git-init}}<br />
* 克隆 (clone) 一个现有的版本库<br />
:{{ic|git clone ''repository''}},参阅 {{man|1|git-clone}}<br />
<br />
=== 记录更改 ===<br />
<br />
Git 管理的项目存在一个暂存区 (staging area),即 git 目录中的 {{ic|index}} 文件,其中保存了即将包含在你下一次提交中的文件更改。要将某个修改过的文件记录下来,首先需要将修改后的文件添加到 index(暂存它),然后用 {{ic|git commit}} 命令将当前的 index 保存为一次新的提交。<br />
<br />
==== 暂存 (stage) 更改 ====<br />
<br />
* 将工作树中的文件更改添加至 index<br />
:{{ic|git add ''pathspec''}},参阅 {{man|1|git-add}}<br />
* 移除 index 中记录的文件更改<br />
:{{ic|git reset ''pathspec''}},参阅 {{man|1|git-reset}}<br />
* 显示即将提交的更改、未暂存的更改以及未被 git 跟踪的文件<br />
:{{ic|git status}},参阅 {{man|1|git-status}}<br />
<br />
可以用 {{ic|.gitignore}} 文件来让 git 忽略某些未跟踪的文件,请参阅 {{man|5|gitignore}}。<br />
<br />
Git 不会跟踪文件移动。合并时的文件移动检测仅基于内容的相似性。{{ic|git mv}} 命令仅仅是为了方便,它相当于:<br />
<br />
$ mv -i foo bar<br />
$ git reset -- foo<br />
$ git add bar<br />
<br />
==== 提交 (commit) 更改 ====<br />
<br />
{{ic|git commit}} 命令将暂存区的更改保存至版本库,参阅 {{man|1|git-commit}}。<br />
<br />
* {{ic|-m}} – 后面跟上提交消息作为参数直接提交,而不是打开默认的文本编辑器来写提交信息后再提交<br />
* {{ic|-a}} – 自动暂存已更改或已删除的文件(不会添加未跟踪的文件)<br />
* {{ic|--amend}} – 重做上次提交,用于修改提交消息或修改提交的文件<br />
<br />
{{提示|建议经常性的提交小更改,并附上有意义的提交信息。}}<br />
<br />
==== 选择修订版本 ====<br />
<br />
Git 提供了多种方式来指定修订版本,参阅 {{man|7|gitrevisions}} 和 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC 选择修订版本]。<br />
<br />
许多 Git 命令需要用修订版本作为参数。一次提交记录可以用下列任何一种方式表示:<br />
<br />
* 某次提交的 SHA-1 哈希值(前7位通常足以唯一标识它)<br />
* 任意提交时的标签,如分支名称或 tag 名称<br />
* 标签 {{ic|HEAD}} 总是指向当前 check out 的提交(通常是分支的头部,除非你使用 ''git checkout'' 跳回到历史记录中的旧提交)<br />
* 以上任意一种表示方式加上 {{ic|~}} 都可以表示之前的提交。例如,{{ic|HEAD~}} 指向 {{ic|HEAD}} 的前一次提交,{{ic|HEAD~5}} 指向 {{ic|HEAD}} 5 次前的提交。<br />
<br />
==== 查看更改 ====<br />
<br />
查看不同提交间的修改处:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
或者查看暂存区和工作树之间的不同:<br />
<br />
$ git diff<br />
<br />
查看修改历史(其中 "''-N''" 指定最近的 n 次修改):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
=== 撤销修改 ===<br />
<br />
* {{ic|git reset}} - 重置当前 HEAD 指针到指定状态,参阅 {{man|1|git-reset}}<br />
<br />
* {{ic|git checkout}} - 恢复工作树中的文件,参阅 {{man|1|git-checkout}}<br />
<br />
=== 分支 (branch) ===<br />
<br />
Bug 修复和新功能通常在不同分支里测试。当一切就绪时它们就可以合并至默认(主)分支。<br />
<br />
创建一个分支,其名称准确地反映了其目的:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
列出已存在的分支:<br />
<br />
$ git branch<br />
<br />
切换分支:<br />
<br />
$ git checkout ''branch''<br />
<br />
新建分支并切换至该分支:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
将一个分支合并回主分支:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
如果不存在冲突的话,所有更改将被合并。否则 Git 将显示一条错误信息,并通过给工作树中的文件加注释来记录冲突。添加的注释可以用 {{ic|git diff}} 显示。要解决冲突,必须编辑文件,删除注释,并提交最终版本。请参阅下面的 [[#处理合并 (merge)]]。<br />
<br />
当一个分支使用完毕,可以这样删除:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== 多人合作 ===<br />
<br />
一个典型的 Git 工作流像这样:<br />
<br />
# 创建一个新仓库或克隆一个远程仓库。<br />
# 新建一个分支用于修改文件,然后提交这些修改。<br />
# 将多次提交合并在一起,这样更便于组织项目或更好地理解。<br />
# 把提交的分支合并回主分支。<br />
# (可选)将更改推送至远程服务器。<br />
<br />
==== 合并请求 (pull requests) ====<br />
<br />
在做出并提交更改后,贡献者可以请求原作者合并更改。这被称为 ''合并请求 (pull request)''。<br />
<br />
如果用 pull:<br />
<br />
$ git pull ''location'' master<br />
<br />
''pull'' 命令相当于 ''fetch'' 和 ''merge'' 命令的结合。如果存在冲突(比如原作者在同一时间段内在相同位置做了更改),那就有必要手动解决冲突。<br />
<br />
另一种方式是,原作者可以选择想要合并的更改。通过使用 ''fetch'' 命令(以及带有特殊 {{ic|FETCH_HEAD}} 标记的 ''log'' 命令),可以在决定如何处理合并请求 (pull request) 前查看该请求的内容:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== 使用远程仓库 (remote) ====<br />
<br />
远程 (remote) 是和本地相关联的远程仓库的别名。其实就是创建一个 ''label'' 来定义一个位置。这些 label 用于标识经常访问的仓库。<br />
<br />
添加一个远程仓库:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
获取远程库里的内容:<br />
<br />
$ git fetch ''label''<br />
<br />
显示本地主分支与远程主分支之间的差异:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
查看当前仓库相关联的远程仓库:<br />
<br />
$ git remote -v<br />
<br />
当设置的远程仓库是本仓库的 fork 来源(项目的领导者),这个远程仓库会被定义为 ''upstream''(上游)。<br />
<br />
==== 向某个仓库推送 (push) 修改 ====<br />
<br />
从原作者处获得推送修改的权限之后,使用以下命令推送修改:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
当使用 ''git clone'' 获得这个仓库后,git 会把仓库的原始地址记录在名为 {{ic|origin}} 的变量中。<br />
<br />
所以一次 ''典型的'' 推送可以这样做: <br />
<br />
$ git push origin master<br />
<br />
如果使用了 {{ic|-u}} ({{ic|--set-upstream-to}}) 选项,地址将会被记录下来,下次只要使用 {{ic|git push}} 就可以了。<br />
<br />
==== 处理合并 (merge) ====<br />
<br />
可以查看 Git Book 的 [https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6#遇到冲突时的分支合并 遇到冲突时的分支合并] 部分了解如何处理合并冲突。合并操作通常是可逆的,如果想返回合并前,可以使用 {{ic|--abort}} 命令(比如 {{ic|git merge --abort}} 或 {{ic|git pull --abort}})。<br />
<br />
=== 历史记录和版本记录 ===<br />
<br />
==== 在历史记录中搜索 ====<br />
<br />
{{ic|git log}} 命令可以显示历史记录信息,其中包含每次提交的校验和、作者、日期,以及简略信息。''校验和'' 就是一次提交对象的 "对象名称",通常是一个 40 位的 SHA-1 哈希值。<br />
<br />
对于具有较长信息的历史记录(其中 "''checksum''" 可以截取前几位,只要它是唯一的):<br />
<br />
$ git show (''checksum'')<br />
<br />
在被跟踪的文件中搜索 ''pattern'':<br />
<br />
$ git grep ''pattern''<br />
<br />
在 {{ic|.c}} 和 {{ic|.h}} 文件中搜索:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== 使用标签 (tag) ====<br />
<br />
给某次提交打标签来标记这个版本:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tag'' 通常是用于 [https://www.drupal.org/node/1066342 发布/标记版本] 的,但它可以是任何字符串。通常使用带注释的标签,因为它们会被添加到 Git 数据库中。<br />
<br />
标记当前的提交:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
列出标签:<br />
<br />
$ git tag -l<br />
<br />
删除某个标签:<br />
<br />
$ git tag -d 2.08<br />
<br />
更新远程库中的标签:<br />
<br />
$ git push --tags<br />
<br />
==== 重新组织 commit ====<br />
<br />
在提交合并请求之前,可能需要合并/重新组织 commit。这是通过 ''git rebase''(变基){{ic|--interactive}}完成的:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
然后会打开文本编辑器,其中包含指定范围内所有提交的摘要;这种情况下会包括最新提交 ({{ic|HEAD}}),但不包括 {{ic|''checksum''}} 表示的那次 commit。也可以使用数字来标记,例如用 {{ic|HEAD~3}},这会把最后三次提交变基:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
修改第一栏中的动作可以决定如何执行变基操作。可选的动作有:<br />
<br />
* {{ic|pick}} — 原样保留每次提交(默认)。<br />
* {{ic|edit}} — 编辑文件和/或 commit 信息。<br />
* {{ic|reword}} — 编辑 commit 信息。<br />
* {{ic|squash}} — 合并/折叠到先前的提交中。<br />
* {{ic|fixup}} — 合并/折叠到先前的提交中并丢弃它们的信息。<br />
<br />
提交会被重新排序或从历史记录中擦除(所以要非常小心)。编辑文件后,Git 将执行指定的操作;如果提示有合并问题待解决,请解决它们并使用 {{ic|git rebase --continue}} 来继续,或使用 {{ic|git rebase --abort}} 命令来取消操作。<br />
<br />
{{注意|合并多次提交的操作只能应用于本地提交,它会导致其他人共享的存储库出现问题。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
=== 使用 git-config ===<br />
<br />
Git 从三个 ini 类型的配置文件里读取配置:<br />
<br />
* {{ic|/etc/gitconfig}} 是应用于整个系统的默认配置文件<br />
* {{ic|~/.gitconfig}} 是应用于特定用户的配置文件<br />
* {{ic|.git/config}} 是应用于特定仓库的配置文件<br />
<br />
这些文件可以直接编辑,但是更常用的方法是使用 ''git config'',下面是一些示范。<br />
<br />
列出当前已配置的变量:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
将默认文本编辑器从 [[vim]] 改成 [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
设置默认的推送 (push) 行为:<br />
<br />
$ git config --global push.default simple<br />
<br />
设置不同的 ''git difftool'' 工具(默认是 ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
更多信息请参阅 {{man|1|git-config}} 和 [https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git 配置 Git]。<br />
<br />
=== 保持良好的礼仪 ===<br />
<br />
* 当你想为一个现有的项目贡献时,请先阅读并理解这个项目的许可,因为它可能会过度限制你更改代码的权力。有些许可会在代码的所有权方面引起争议。<br />
* 理解这个项目的社区,以及你可以融入其中的程度。要了解项目的主要方向,可以阅读所有文档甚至是代码库的 [[#历史记录和版本记录|log]]。<br />
* 当发起一个合并请求,或者提交一个补丁时,保证它是小改动并且有完善的文档;这将有助于项目维护者理解你的改动,并决定是否合并这些改动或是让你再改一下。<br />
* 如果贡献被拒绝,不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清楚和耐心地讨论这次贡献的理由,最终可能通过这种方法解决问题。<br />
<br />
=== 加快身份验证 ===<br />
<br />
每次向 Git 服务器推送时都要认证身份,你可能会想要避免这种麻烦。<br />
<br />
* 如果你是用 SSH 密钥来认证的,请使用 [[SSH keys (简体中文)#SSH agents|SSH agents]]。参阅 [[Secure Shell (简体中文)#加速 SSH]] 和 [[Secure Shell (简体中文)#保持在线]]。<br />
* 如果你是用账号和密码来认证的,在服务器支持 SSH 的情况下请切换至 [[SSH keys (简体中文)|SSH keys]], 否则请尝试 [https://git-scm.com/docs/git-credential-cache git-credential-cache] 或 [https://git-scm.com/docs/git-credential-store git-credential-store]。<br />
<br />
=== 默认通讯协议 ===<br />
<br />
如果你正在使用一个上述那种复用的 SSH 连接,让 Git 使用 SSH 可能比使用 HTTPS 更快。同时,一些服务器(比如 AUR)只允许通过 SSH 推送更改。例如,像下面这样配置可以使得 Git 通过 SSH 访问 AUR 上的任何仓库。<br />
<br />
{{hc|~/.gitconfig|<nowiki><br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
</nowiki>}}<br />
<br />
=== Bash 自动补全 ===<br />
<br />
要启用 Bash 的自动补全,请在 [[Bash#Configuration_files|Bash 启动文件]] 里用 source 加载 {{ic|/usr/share/git/completion/git-completion.bash}} 文件。或者也可以安装 {{pkg|bash-completion}}。<br />
<br />
=== Git 提示符 ===<br />
<br />
Git 包带有一个提示符脚本。要启用它,请用 source 加载 {{ic|/usr/share/git/completion/git-prompt.sh}} 脚本,然后使用 {{ic|%s}} 参数设置一个自定义 shell 提示符:<br />
<br />
* [[Bash]] 用户: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* [[zsh]] 用户: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
要自动完成这项工作,请参阅 [[Command-line shell#Configuration files]]。<br />
<br />
当切换至一个 Git 仓库所在目录时,shell 提示符会变成所在分支名称。也可以配置提示符来显示其他信息:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || 已暂存 (staged) 显示 '''+''',未暂存 (unstaged) 显示 '''*'''。<br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || 已储藏 (stashed) 显示 '''$'''。<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || 有未跟踪文件时显示 '''%'''。<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' 分别表示落后于上游、领先于上游、偏离上游。<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} 需要设置为 {{ic|auto}} 才能使更改生效。<br />
<br />
{{注意|如果发生了 {{ic|$(__git_ps1)}} 返回 {{ic|((unknown))}} 的情况,是因为有一个 {{ic|.git}} 文件夹在你当前的文件夹里面,但却不包含任何存储库,因此 Git 不认识它。这有可能发生在你把 {{ic|~/.git/config}} 误认为是 Git 的配置文件而不是 {{ic|~/.gitconfig}}。}}<br />
<br />
你也可以使用来自 [[AUR]] 的自定义 git shell 提示符软件包,例如 {{AUR|bash-git-prompt}} 或 {{AUR|gittify}}。<br />
<br />
=== 可视化显示 ===<br />
<br />
要了解已经完成了多少工作:<br />
<br />
$ git diff --stat<br />
<br />
带有 fork 显示的 ''git log'':<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
给图形化的 ''git log'' 做一个别名(使用 ''git graph'' 即可显示经过修饰的 log):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
=== 关于提交 (commit) 的小提示 ===<br />
<br />
重置为以前的提交(非常危险,这将会擦除所有内容并改写为特定提交):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
如果远程仓库的地址发生变化,可以这样更新它的位置:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
自动附加签名行到提交(将某个 姓名-电邮 签名添加到提交中,某些项目会要求这样做):<br />
<br />
$ git commit -s<br />
<br />
自动附加签名到补丁(使用 {{ic|git format-patch ''commit''}} 时生效):<br />
<br />
$ git config --local format.signoff true<br />
<br />
提交已更改文件的特定部分。如果有大量更改时,最好拆分成多个提交,这种情况下这个命令通常很有用:<br />
<br />
$ git add -p<br />
<br />
=== 对提交 (commit) 签名 ===<br />
<br />
Git 允许使用 [[GnuPG (简体中文)|GnuPG]] 对提交和标签进行签名,请参见 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C 签署工作]。<br />
<br />
{{注意|<br />
如果是借助 {{Pkg|pinentry}} 来进行 GPG 签名,请确保 {{ic|1=export GPG_TTY=$(tty)}}(或者使用 pinentry-tty),否则当 GPG 处于锁定状态时签名这一步会失败(因为它无法在 shell 提示符里询问 pin 码)。}}<br />
<br />
配置 Git 使它自动对提交进行签名:<br />
<br />
$ git config --global commit.gpgSign true<br />
<br />
=== 在非主分支上工作 ===<br />
<br />
偶尔项目维护人员会要求你在其他分支上完成工作。这些分支通常被称为 {{ic|devel}} 或 {{ic|testing}}。首先要克隆存储库。<br />
<br />
要进入不是主分支的分支(''git clone'' 只会显示主分支,但其他分支其实也是存在的,用 {{ic|git branch -a}} 可以显示出来):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
然后就可以像平常一样编辑文件,但是要使得整个仓库都保持同步,下面这两个命令都要用:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
=== 直接将补丁发送至邮件列表 ===<br />
<br />
如果你想直接将补丁发送至一个邮件列表,需要安装以下软件包:{{Pkg|perl-authen-sasl}},{{Pkg|perl-net-smtp-ssl}} 和 {{Pkg|perl-mime-tools}}。<br />
<br />
确保你已经配置了用户名和邮件地址,可参阅 [[#配置]]。<br />
<br />
配置你的邮箱设置:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.example.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@example.com''<br />
<br />
现在你应该可以将补丁发送至某个邮件列表了(可参阅[http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
== Git 服务器 ==<br />
<br />
这一节讲述如何配置使用不同的协议连接到存储库。<br />
<br />
=== SSH 协议 ===<br />
<br />
要使用 SSH 协议,首先要准备一个 SSH 公钥,可以按照 [[SSH keys (简体中文)]] 的指导来完成。要配置一个 SSH 服务器,请遵循 [[Secure Shell (简体中文)]] 的指导。<br />
<br />
当 SSH 生成了密钥之后,将 {{ic|~/.ssh/id_rsa.pub}} 文件的内容粘贴至服务器上的 {{ic|~/.ssh/authorized_keys}} 文件里(一行一个,同一个公钥确保在同一行)。现在 Git 仓库可以通过 SSH 来访问:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
现在,如果你的 SSH 客户端的 {{ic|StrictHostKeyChecking}} 选项设为了 {{ic|ask}}(默认),你应该会收到来自 SSH 的问题,要你回答 yes/no。输入 {{ic|yes}} 然后回车,你的仓库就能被取出。同时,由于通过 SSH 协议访问,你现在应该有提交权限。<br />
<br />
要把一个已存在的仓库改成使用 SSH 访问,需要重新定义一下远程地址:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
要从非 22 端口连接,可以在每台主机的 {{ic|/etc/ssh/ssh_config}} 或 {{ic|~/.ssh/config}} 里配置。要为某个本地仓库设置端口(示例中用的 443 端口):<br />
<br />
{{hc|.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
你可以通过只允许用户执行 push 和 pull 操作来进一步提高 SSH 账户的安全性。这是通过将该账户的默认登录 shell 换成 git-shell 来实现的。在 [https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8 配置服务器] 中对此有所描述。<br />
<br />
=== Smart HTTP 协议 ===<br />
<br />
通过使用 git-http 后端,Git 可以像使用 SSH 协议或 Git 协议一样高效地使用 HTTP(S) 协议。此外,它不仅可以从仓库中克隆或拉取更改,还可以通过 HTTP(S) 推送更改。<br />
<br />
这个设置相当简单,因为你只需要安装 Apache Web 服务器({{pkg|apache}},启用 {{ic|mod_cgi}}、{{ic|mod_alias}} 和 {{ic|mod_env}}),当然还要安装 {{pkg|git}}。<br />
<br />
当你正在进行基本设置时,请将以下内容添加到 Apache 配置文件中,该配置文件通常位于:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
这里假设你的 Git 仓库位于 {{ic|/srv/git}},并且你想用类似 {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}} 的方式来访问它们。<br />
<br />
{{注意|请确保 Apache 对你的仓库有读写权限。}}<br />
<br />
如果需要更多详细文档,请访问:<br />
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP<br />
* https://git-scm.com/docs/git-http-backend<br />
<br />
=== Git 协议 ===<br />
<br />
{{注意|Git 协议没有加密或认证机制,且只允许读取。}}<br />
<br />
[[start|Start 并且 enable]] {{ic|git-daemon.socket}} 这个 systemd 单元。<br />
<br />
守护程序会带有以下选项启动:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
位于 {{ic|/srv/git/}} 目录下的仓库会被守护程序识别。客户端能以类似这样的方式连接:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== 设置访问权限 ===<br />
<br />
要限制读取和/或写入权限,可以使用常规 Unix 权限控制。更多信息请参考 [https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill]。<br />
<br />
如果需要更加精细的访问控制,请参考 [[gitolite]] 和 [[gitosis]]。<br />
<br />
== 参考资料 ==<br />
<br />
* Git 手册页:{{man|1|git}}<br />
* [https://git-scm.com/book/en/ Pro Git book]<br />
* 来自 GitHub 的 [https://git.github.io/git-reference/ Git Reference] <br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]<br />
* [https://wiki.videolan.org/Git VideoLAN wiki article]<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=520119
OpenSSH (简体中文)
2018-05-04T07:22:57Z
<p>Arisaka: Sync with English version.</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:Secure Shell (简体中文)]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fa:SSH]]<br />
[[fr:ssh]]<br />
[[ja:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys (简体中文)}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|SSHFS (简体中文)}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related|SCP and SFTP}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Secure Shell|2018-05-04|518925}}<br />
<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器默认情况下,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专有软件、自由软件以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(来源:[[Wikipedia:Secure Shell|维基百科 Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH 是由 Theo de Raadt 领导的 OpenBSD 项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{pkg|openssh}}.<br />
<br />
<br />
===SSH 客户端===<br />
<br />
连接SSH服务器,运行命令<br />
<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
<br />
如果服务器仅允许使用密钥登录,请参考 [[SSH keys (简体中文)|SSH Keys]] 。<br />
<br />
====配置====<br />
<br />
客户端可以在配置文件中存储常用选项和常用主机,下列选项都可以应用至全局或应用至特定主机。 例如:<br />
<br />
{{hc|~/.ssh/config|# global options<br />
User ''user''<br />
<br />
# host-specific options<br />
Host myserver<br />
HostName ''server-address''<br />
Port ''port''}}<br />
<br />
进行了如上的配置后,以下命令是等效的<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
$ ssh myserver<br />
<br />
查看 {{man|5|ssh_config}} 获取更多信息。<br />
<br />
某些选项没有命令行参数,但是可以使用 {{ic|-o}} 在命令行中配置指定选项的参数。<br />
例如 {{ic|1=-oKexAlgorithms=+diffie-hellman-group1-sha1}}.<br />
<br />
===SSH 服务端===<br />
<br />
====配置====<br />
<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers ''user1 user2''<br />
<br />
只允许一些组访问:<br />
AllowGroups ''group1 group2''<br />
<br />
你也可以运行以下命令关联文件(如{{ic|/etc/issue}}文件)到登录欢迎信息:<br />
Banner /etc/issue<br />
<br />
公钥和私钥在 ''sshd'' [[#管理 sshd 守护进程|service 文件]] 安装的时候就自动生成在 {{ic|/etc/ssh}} 里面了,四个秘钥对分别由四种算法生成: [[SSH_keys#Choosing_the_authentication_key_type|dsa、rsa、ecdsa 和 ed25519]]。要让 sshd 使用一组特定的密钥,请指定以下选项:<br />
<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
如果此服务器在公网中,建议运行以下命令以更改sshd服务监听端口:<br />
Port 39901<br />
<br />
{{Tip|<br />
* 参考 [[Wikipedia:List of TCP and UDP port numbers|TCP 和 UDP 端口号列表]] 和本地的 {{ic|/etc/services}} 文件来选择一个未被常用服务占用的端口。把端口从默认的 22 改成别的可以减少由于端口扫描器尝试自动登录造成的登录日志条目,更多信息请参考 [[Port knocking]]。<br />
* 完全取消密码登录方式可以极大的增强安全性,请查看[[#强制公钥验证]]。查看[[#安全防护]]了解更多增强安全性的手段。<br />
* OpenSSH 可以监听多个端口,只需在配置文件中加入多行{{ic|Port ''port_number''}}即可。}}<br />
<br />
==== 管理 sshd 守护进程 ====<br />
<br />
{{Pkg|openssh}} 包括了两种 [[systemd]] 服务:<br />
#{{ic|sshd.service}},使 SSH 守护进程始终运行,并为每个入站连接创建子进程。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh#n16] 适用于有大量 SSH 流量的系统。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n15] <br />
#{{ic|sshd.socket}} + {{ic|sshd@.service}}, 为每个连接生成 SSH 守护进程的实例。它意味着让 ''systemd'' 监听 SSH socket,并且只有在有连接传入时启动守护进程。几乎所有情况下都推荐使用{{ic|sshd}}。 [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n18][http://lists.freedesktop.org/archives/systemd-devel/2011-January/001107.html][http://0pointer.de/blog/projects/inetd.html]<br />
<br />
[[start]] 并 [[enable]] {{ic|sshd.service}} '''或''' {{ic|sshd.socket}} 中的任何一个都可以启动守护进程。<br />
<br />
如果选择了 sshd.socket,并且不在默认的 22 端口监听,你需要[[edit|编辑]] ststemd 单元文件:<br />
<br />
{{hc|# systemctl edit sshd.socket|<nowiki><br />
[Socket]<br />
ListenStream=<br />
ListenStream=12345<br />
</nowiki>}}<br />
<br />
{{警告|使用 {{ic|sshd.socket}} 会使 {{ic|ListenAddress}} 设置无效,这将允许来自任何地址的连接。为了达到与 {{ic|ListenAddress}} 一样设置 IP 的效果, 你必须在 {{ic|ListenStream}} 中指定端口''和'' IP (例如:{{ic|1=ListenStream=192.168.1.100:22}})。你还需要在 {{ic|[Socket]}} 下面增加 {{ic|1=FreeBind=true}},否则设置 IP 与设置 {{ic|ListenAddress}} 有着相同的缺陷:如果网络未及时启动,socket 将无法启动。}}<br />
<br />
{{提示|打开 {{ic|sshd.service}} 时将为每个连接启动一个 {{ic|sshd@.service}} 的临时实例(实例名称不同)。因此,{{ic|sshd.socket}} 和常规 {{ic|sshd.service}} 都不允许监视日志中的连接尝试。使用 {{ic|journalctl -u "sshd@*"}} 或 {{ic|journalctl /usr/bin/sshd}} 可以看到 socket 激活的 SSH 实例的日志。}}<br />
<br />
==== 安全防护 ====<br />
<br />
允许通过SSH进行远程登录对管理服务器很有用,但也会对服务器构成安全威胁。SSH 通常是暴力攻击的目标,因此 SSH 访问需要适当限制,以防止第三方访问您的服务器。<br />
<br />
下列是有关该主题的优秀指南:<br />
<br />
*[https://wiki.mozilla.org/Security/Guidelines/OpenSSH Article by Mozilla Infosec Team]<br />
*[https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure sshd]<br />
<br />
===== 强制公钥验证 =====<br />
<br />
如果客户端无法通过公钥进行身份验证,则默认情况下,SSH服务器将使用密码来验证,从而允许恶意用户通过[[#防止暴力破解|暴力破解]]密码获取访问权限。一种防止此类攻击的有效方法是完全禁用密码登录,并强制使用[[SSH keys]]。可以在 {{ic|sshd_config}} 中禁用以下选项:<br />
<br />
PasswordAuthentication no<br />
<br />
{{警告|在将上述选项添加到你的配置之前,请确保所有需要 SSH 访问的帐户都在相应的 {{ic|authorized_keys}} 文件中设置了公钥验证。请参阅 [[SSH keys#Copying the public key to the remote server]] 以获取更多信息。}}<br />
<br />
===== 双因素验证与公钥 =====<br />
<br />
SSH 可以设置为采用多种方式进行身份验证,你可以使用 {{ic|AuthenticationMethods}} 选项来指明在登录时需要哪些身份验证方式。这使你可以用公钥与双因素验证结合来登录。<br />
<br />
参阅 [[Google Authenticator (简体中文)]] 来设置 Google Authenticator。<br />
<br />
为了使 [[PAM (简体中文)]] 与 OpenSSH 协同工作, 编辑下列文件:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey keyboard-interactive:pam<br />
}}<br />
<br />
然后,你可以使用公钥'''或''' PAM 中设置的用户验证信息两者之一登录。<br />
<br />
另外,如果你想登录时同时验证公钥'''和''' PAM,请使用逗号而不是空格来分隔 AuthenticationMethods:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey''','''keyboard-interactive:pam<br />
}}<br />
<br />
通过要求提供公钥'''和''' PAM 认证,你可能希望禁用密码登录:<br />
{{hc|/etc/pam.d/sshd|<br />
auth required pam_securetty.so #disable remote root<br />
#Require google authenticator<br />
auth required pam_google_authenticator.so<br />
#But not password<br />
#auth include system-remote-login<br />
account include system-remote-login<br />
password include system-remote-login<br />
session include system-remote-login<br />
}}<br />
<br />
===== 防止暴力破解 =====<br />
暴力破解的概念很简单,即某人不断尝试用大量随机产生的用户名和密码对来登录网页或服务器的某个服务(比如 SSH)。<br />
<br />
====== 使用 ufw ======<br />
<br />
请参阅 [[ufw#Rate limiting with ufw]].<br />
<br />
====== 使用 iptables ======<br />
<br />
{{Merge|Simple_stateful_firewall#Bruteforce_attacks|Out of scope, same technique as already described in the SSF.}}<br />
<br />
如果你已经在用 iptables,可以配置以下规则来保护 SSH 免受暴破。<br />
<br />
{{注意|此示例中 SSH 所用的 TCP 端口已经改为了 42660。}}<br />
<br />
在应用后面的规则之前,我们先新建一条规则链来记录并拒绝过多的连接请求:<br />
<br />
# iptables -N LOG_AND_DROP<br />
<br />
第一条规则将应用于预示 TCP 42660 端口有新连接的数据包:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --set --name DEFAULT --rsource<br />
<br />
下一条规则告诉 iptables 查找匹配前一条规则的数据包,这些数据包也来自已添加到监视列表中的主机。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --update --seconds 90 --hitcount 4 --name DEFAULT --rsource -j LOG_AND_DROP<br />
<br />
现在,让 iptables 决定如何处理 TCP 42660 端口的通信中不符合上述规则的数据包。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -j ACCEPT<br />
<br />
我们向 LOG_AND_DROP 表增加如下规则,并使用 -j (jump) 参数将数据包的信息传递给日志记录工具。<br />
<br />
# iptables -A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7<br />
<br />
在按照第一条规则进行记录后,所有数据包将被丢弃。<br />
<br />
# iptables -A LOG_AND_DROP -j DROP<br />
<br />
====== 防止暴力破解的工具 ======<br />
<br />
你可以用类似 [[fail2ban]] 或 [[sshguard]] 的自动防暴破的脚本来阻挡攻击者。<br />
<br />
* 仅允许来自受信任位置的 SSH 入站连接。<br />
* 使用 [[fail2ban]] 或 [[sshguard]] 自动阻止多次密码验证失败的 IP 地址。<br />
* 使用 [https://github.com/jtniehof/pam_shield pam_shield] 来阻止在一定时间内执行过多登录尝试的 IP 地址。与 [[fail2ban]] 或 [[sshguard]]不同,该程序不考虑登录成功或失败。<br />
<br />
===== 禁用或限制 root 账户登录 =====<br />
{{Out of date|最新版本默认已禁用 root 账户登录。暂不清楚本节的哪些部分是多余的。}}<br />
<br />
允许 root 账户随意通过 SSH 登录通常是不安全的,有两种方法可以限制 root 账户通过 SSH 登录,从而提高安全性。<br />
<br />
====== 禁用 root 登录 ======<br />
<br />
Sudo 可以有选择地为需要 root 权限的操作提供相应的权限,且不需要登录 root 账户。这样即可关闭 root 登录,并且可以看做一种防范暴力攻击的安全措施,因为现在攻击者除了要猜测密码外还要猜测帐户名称。<br />
<br />
通过编辑 {{ic|/etc/ssh/sshd_config}} 中的 "Authentication" 一节可以使 SSH 屏蔽 root 用户登录,只要将 {{ic|#PermitRootLogin prohibit-password}} 改成 {{ic|no}} 并取消该行注释即可:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
PermitRootLogin no<br />
...<br />
}}<br />
<br />
然后 [[restart|重启]] SSH 守护进程。<br />
<br />
现在你将无法通过 root 账户登录,但仍可以用普通账户登录并使用 [[su]] 或者 [[sudo]] 来完成系统维护工作。<br />
<br />
====== 限制 root 登录 ======<br />
<br />
一些自动化的维护任务(比如远程备份整个系统)需要完整的 root 权限。要以安全的方式允许 root 登录而不是禁用它,可以只允许远程登录的 root 用户执行指定的命令,在 {{ic|~root/.ssh/authorized_keys}} 头部加上指定的密钥即可,例如:<br />
<br />
command="/usr/lib/rsync/rrsync -ro /" ssh-rsa …<br />
<br />
这样,任何用户持有该秘钥即可执行引号之间的命令。<br />
<br />
为了弥补因 root 用户名称暴露而导致受攻击的可能性增加,可以将以下命令加入 {{ic|sshd_config}}:<br />
<br />
PermitRootLogin forced-commands-only<br />
<br />
该设置不仅会限制 root 用户通过 SSH 执行的命令,还会禁用密码登录方式,强制 root 帐户使用公钥登录。<br />
<br />
如果不想限制 root 用户可执行的命令,可以仅关闭密码验证来强制使用公钥验证:<br />
<br />
PermitRootLogin prohibit-password<br />
<br />
===== 保护 authorized_keys 文件 =====<br />
<br />
你可以阻止其他用户向该文件加入新公钥且通过新的公钥连接。<br />
<br />
把 {{ic|authorized_keys}} 文件的权限全部去掉,只保留读权限:<br />
<br />
$ chmod 400 ~/.ssh/authorized_keys<br />
<br />
为防止用户把权限改回来,可以对 {{ic|authorized_keys}} 文件采取 [[File permissions and attributes#chattr and lsattr|set the immutable bit(设为不可变)]] 操作。尽管如此,用户仍然可以重命名 {{ic|~/.ssh}} 并新建一个 {{ic|~/.ssh}} 目录和 {{ic|authorized_keys}} 文件。所以 {{ic|~/.ssh}} 目录也要设置 immutable bit。<br />
<br />
{{注意|如果你自己需要新增一个公钥,你需要先移除 {{ic|authorized_keys}} 文件的 immutable bit,并增加写权限,最后按上述步骤重新加密。}}<br />
<br />
== 其他 SSH 客户端与服务端 ==<br />
除了 OpenSSH,还有很多可用的 SSH [[Wikipedia:Comparison of SSH clients|客户端]] 和 [[Wikipedia:Comparison of SSH servers|服务端]]。<br />
<br />
=== Dropbear ===<br />
[[Wikipedia:Dropbear (software)|Dropbear]] 是一个 SSH-2 客户端与服务端。 {{Pkg|dropbear}} 可以从 [[official repositories|官方仓库]] 下载。<br />
<br />
它的命令行版客户端叫 dbclient。<br />
<br />
=== Mosh ===<br />
来自 Mosh [http://mosh.mit.edu/ 网站]:<br />
<br />
:Remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. Mosh is a replacement for SSH. It is more robust and responsive, especially over slow connections such as Wi-Fi, cellular, and long-distance.<br />
:翻译:允许“漫游”的远程终端,支持间歇性的连接,并提供对于用户按键的智能本地回馈和行编辑回馈。Mosh 是 SSH 的替代品。它更加强大而快速,特别针对诸如 Wi-Fi,移动网络和超远距离等慢速连接环境。<br />
<br />
[[Install|安装]] {{Pkg|mosh}} 这个包, 或安装最新版:{{AUR|mosh-git}}。<br />
<br />
Mosh 有一个未写入文档的命令行选项:{{ic|1=--predict=experimental}},它可以产生更有力的本地按键响应。对降低键盘输入视觉上的延迟确认感兴趣的用户可能更喜欢这个预测模式。<br />
<br />
{{提示|Mosh 从设计上就不允许你访问会话的历史记录,请考虑安装终端复用工具,如 [[tmux]] 或 [[screen]] 。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
{{Accuracy|根据目前本文的布局,这部分看起来应该是通用的,但实际上大部分提供的技巧只能在 ''openssh'' 中使用。比如 ''dropbear'' (在 [[#Other SSH clients and servers]] 列表中) 不支持 SOCKS 协议。[https://en.wikipedia.org/wiki/Comparison_of_SSH_clients#Technical]}}<br />
<br />
=== 加密 Socks 通道 ===<br />
<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的 SSH 服务器,比如在家里或办公室。用动态的 DNS 服务 [http://www.dyndns.org/ DynDNS] 也可能是很有用的,这样你就不必记住你的 IP 了。<br />
<br />
==== 第一步:开始连接 ====<br />
<br />
你只要执行这一个命令就能开始你的连接:<br />
<br />
$ ssh -TND 4711 ''user''@''host''<br />
<br />
这里的 {{Ic|''user''}} 是你在 {{Ic|''host''}} 这台 SSH 服务器上的用户名。它会让你输入密码,然后你就能连上了。 {{Ic|N}} 表示不采用交互提示,而 {{Ic|D}} 表示指定监听的本地端口(你可以使用任何你喜欢的数字),{{Ic|T}} 表示禁用伪 tty 分配。<br />
<br />
加了 {{Ic|-v}} (verbose) 标志以后的输出可以让你能够验证到底连了哪个端口。<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你没有配置你的浏览器(或其他程序)使用这个新创建的 socks 隧道,上述步骤是无效的。由于当前版本的 SSH 支持 SOCKS4 和 SOCKS5,因此您可以使用其中任何一种。<br />
<br />
* 对于 Firefox: ''Edit > Preferences > Advanced > Network > Connection > Setting'': <br> 选中 ''Manual proxy configuration'' 单选框, 然后在 ''SOCKS host'' 里输入 {{ic|localhost}}, 然后在后面那个框中输入你的端口号(本例中为 {{ic|4711}})。<br />
<br />
Firefox 不会自动通过 socks 隧道发送 DNS 请求,这一潜在的隐私问题可以通过以下步骤来解决:<br />
<br />
# 在 Firefox 地址栏中输入:about:config 。<br />
# 搜索:network.proxy.socks_remote_dns<br />
# 将该值设为 true。<br />
# 重启浏览器。<br />
<br />
* 对于 Chromium: 你可以将 SOCKS 设置设置为环境变量或命令行选项。我建议将下列函数之一加入到你的 {{ic|.bashrc}}:<br />
function secure_chromium {<br />
port=4711<br />
export SOCKS_SERVER=localhost:$port<br />
export SOCKS_VERSION=5<br />
chromium &<br />
exit<br />
}<br />
或者<br />
function secure_chromium {<br />
port=4711<br />
chromium --proxy-server="socks://localhost:$port" &<br />
exit<br />
}<br />
<br />
现在打开终端然后输入:<br />
<br />
$ secure_chromium<br />
<br />
享受你的安全隧道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过 SSH 运行图形程序你必须使用 X11 转发 (forwarding)。这不要求对端安装了完整的 X11,但是至少要装好 ''xauth''。''xauth'' 是一个用来管理 {{ic|Xauthority}} 配置的工具,该配置用于服务器与客户端之间的 X11 会话认证([http://xmodulo.com/2012/11/how-to-enable-x11-forwarding-using-ssh.html source])。<br />
<br />
{{警告|X11 转发有着重要的安全问题需要考虑,至少应先阅读 {{man|1|ssh}}、{{man|5|sshd_config}} 和 {{man|5|ssh_config}} 手册页。也可以参考 [https://security.stackexchange.com/questions/14815/security-concerns-with-x11-forwarding 这个 StackExchange 帖]。}}<br />
<br />
==== 配置 ====<br />
<br />
在远程主机上:<br />
<br />
*[[install|安装]] {{Pkg|xorg-xauth}} 和 {{Pkg|xorg-xhost}} 这两个包<br />
*在 {{ic|/etc/ssh/ssh'''d'''_config}} 上:<br />
**确保 {{ic|AllowTcpForwarding}} 和 {{ic|X11UseLocalhost}} 已经设置为 ''yes'',并且 {{ic|X11DisplayOffset}} 设置为 ''10'' (这些是默认设置,参考 {{man|5|sshd_config}})<br />
**将 {{ic|X11Forwarding}} 设置为 ''yes''<br />
* 最后 [[restart|重启]] [[#Daemon management|''sshd'' 守护进程]]{{Broken section link}}.<br />
<br />
在客户端上,通过在命令行设置 {{ic|-X}} 参数启用 {{ic|ForwardX11}},或者在[[#配置|客户端配置文件]]中将 {{ic|ForwardX11}} 设置为 ''yes''。<br />
<br />
{{提示|如果 GUI 绘制不正常或者有错误提示,你可以启用 {{ic|ForwardX11Trusted}} 选项(或在命令行中加上 {{ic|-Y}} 参数),这将使 X11 转发脱离 [http://www.x.org/wiki/Development/Documentation/Security/ X11 SECURITY extension] 的控制,如果你这样做,请确保已经读过本节开头的[[#X11 转发|警告]]。}}<br />
<br />
==== 使用方法 ====<br />
<br />
{{Accuracy|{{ic|xhost}} [http://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-from-ubuntu-machine#comment-17148 通常不是必须的]}}<br />
<br />
正常登录远程主机,如果客户端的配置文件中没有启用 ''ForwardX11'' 那就加上 {{ic|-X}} 参数:<br />
$ ssh -X ''user@host''<br />
<br />
如果在运行图形程序的时候碰到错误,尝试用 ''ForwardX11Trusted'' 代替 ''ForwardX11'' :<br />
$ ssh -Y ''user@host''<br />
<br />
现在你应该可以运行服务器上的任何 X 图形程序,任何输出都会重定向至你当前的会话:<br />
$ xclock<br />
<br />
如果碰到 "Cannot open display" 的错误,请尝试用非管理员账户运行下列命令:<br />
$ xhost +<br />
<br />
上述命令将允许任何人转发 X11 应用程序,这个命令可以限制特定的主机类型:<br />
$ xhost +hostname<br />
<br />
其中 hostname 是要转发到的特定主机的名称。更多信息可以查看 {{man|1|xhost}}。<br />
<br />
请注意某些应用程序,它们会检查本地计算机上正在运行的实例。[[Firefox]] 就是其中之一:你可以关掉本机上的 Firefox 或者使用以下启动参数来启动远程实例:<br />
$ firefox --no-remote<br />
<br />
当你连接时收到 "X11 forwarding request failed on channel 0" 错误(或者服务器上的 {{ic|/var/log/errors.log}} 文件显示 "Failed to allocate internet-domain X11 display socket" 错误),请确保已经安装 {{Pkg|xorg-xauth}},如果装完了仍然不起作用,尝试以下方法之一:<br />
<br />
* 在''服务器''的 {{ic|ssh'''d'''_config}} 中启用 {{ic|AddressFamily any}} 选项,或者<br />
* 将''服务器''的 {{ic|ssh'''d'''_config}} 中的 {{ic|AddressFamily}} 选项设为 inet。<br />
将其设置为 inet 可能会修复 IPv4 上的 Ubuntu 客户端的问题。<br />
<br />
要以其他用户身份运行 SSH 服务器上的 X 应用程序,你需要先用已知用户登录,取出 {{Ic|xauth list}} 中的身份认证行,然后 {{Ic|xauth add}} 它。<br />
<br />
{{提示|[http://unix.stackexchange.com/a/12772/29867 这里] 是 [http://unix.stackexchange.com/a/46748/29867 一些] 用来诊断 {{ic|X11 Forwarding}} 问题有用的 [http://superuser.com/a/805060/185665 链接]。}}<br />
<br />
=== 转发其他端口 ===<br />
<br />
除了 SSH 内建的对 X11 的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一条SSH命令来建立一个安全的VNC连接。本地转发可以通过 {{Ic|-L}} 来设置,后面可以指定一个地址及端口 {{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过 SSH 得到一个在 {{ic|192.168.0.100}} 的 shell,同时也会创建一个从本机 TCP 1000 端口到 mail.google.com 上的 25 端口的隧道。建立之后,通过 {{ic|localhost:1000}} 的连接可以直接连接到 Gmail 的 SMTP 端口。对 Google 而言,任何这样的连接都是来自 {{ic|192.168.0.100}} 的(即使这些连接中没有数据传输),并且,在本机和 192.168.0.100 之间的数据传递是安全的,但 {{ic|192.168.0.100}} 和 Google 之间是不安全的,除非还采取了别的手段保障数据安全。<br />
<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到 {{ic|localhost:2000}} 的连接直接转发到远程主机 192.168.0.100 的 6001 端口。对于使用 VNC 服务器(tightvns包的一部分)建立的 VNC 连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过 SSH 隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过 {{Ic|-R}} 参数,以及 {{Ic|<tunnel port>:<destination address>:<destination port>}} 能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在 {{ic|192.168.0.200}} 上得到一个 shell,同时,来自 {{ic|192.168.0.200}} 的 3000 端口(远程主机的 {{ic|localhost:3000}})的数据将会通过隧道转发至本机,然后转发至 irc.freenode.net 上的 6667 端口。因此,在这个例子中,在远程主机上能够使用 IRC 程序,即使端口 6667 被阻止。<br />
<br />
本地转发和远程转发都可以提供一个安全的“网关”,允许其他计算机无需运行 SSH 或者 SSH daemon 来使用 SSH 隧道,即在隧道起点提供绑定的地址,作为转发规则。例如 {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}。{{Ic|<tunnel address>}} 可以是作为隧道起点的机器上的任何地址,地址 {{Ic|localhost}} 允许来自本地回环的连接,空地址 {{Ic|*}} 允许来自任意网卡的连接。默认情况下,转发仅限于连接至位于隧道“起点”的主机,即 {{Ic|<tunnel address>}} 被设置为 {{Ic|localhost}}。本地转发不需要额外的设置,而远程转发受限于对端的 SSH daemon 设置。更多关于远程转发和本地转发的信息可分别参阅 {{man|5|sshd_config}} 中的 {{Ic|GatewayPorts}} 选项和 {{man|1|ssh}} 中的 {{ic|-L address}} 选项。<br />
<br />
=== 跳板机 ===<br />
<br />
在某些情况下,你与目标主机之间可能无法直接连接,此时就要用到跳板机。因此,我们尝试将两个或更多 SSH 隧道连接在一起,并假设您的本地密钥已针对链中的每个服务器授权。这可以通过使用SSH代理转发 ({{ic|-A}}) 和伪终端分配 ({{ic|-t}}) 来实现,它使用以下语法转发本地密钥:<br />
<br />
$ ssh -A -t -l user1 bastion1 \<br />
ssh -A -t -l user2 intermediate2 \<br />
ssh -A -t -l user3 target<br />
<br />
一个更简单的方法是使用 {{ic|-J}} 选项:<br />
<br />
$ ssh -J user1@bastion1,user2@intermediate2 user3@target<br />
<br />
<br />
{{ic|-J}} 指令中的多个主机可以用逗号隔开,它们将按照列出的顺序连接。{{ic|user...@}} 部分不是必需的,但可以使用。定义 {{ic|-J}} 选项里的不同的主机规格可以使用 ssh 配置文件,因此如果需要,可以在那里设置特定的每个主机选项。<br />
<br />
=== 通过中继反向 SSH 连接 ===<br />
<br />
{{Style|SSH 隧道的设想是很经典的,所以添加一些参考资料的详细解释会更好。比如 [https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work/118650#118650] 涵盖了一些其他情况。}}<br />
<br />
这个想法是客户端通过一个中继连接到服务器,而服务器使用反向 SSH 隧道连接到同一个中继。例如,当服务器位于 NAT 后面时,这是很有用的,而此处的中继是一个可公开访问的 SSH 服务器,用作用户有权访问的代理服务器。前提是客户端的密钥同时对中继和服务器都已经授权,服务器需要授权中继用于反向 SSH 连接。<br />
<br />
以下配置假设 user1 是客户端使用的账户,user2 是中继的,user3 是服务器的。首先服务器要先建立反向隧道:<br />
<br />
ssh -R 2222:localhost:22 -N user2@relay<br />
<br />
这可以利用启动脚本、systemd service 或者 {{Pkg|autossh}} 来自动完成。<br />
<br />
{{Expansion|需要解释为何光有 {{ic|ssh user3@relay -p 2222}} 是不够的。}}<br />
<br />
在客户端使用以下命令建立连接:<br />
<br />
ssh user2@relay ssh user3@localhost -p 2222<br />
<br />
可以在中继的 {{ic|~/.ssh/authorized_keys}} 中定义 {{ic|command}} 字段来建立反向隧道:<br />
<br />
command="ssh user3@localhost -p 2222" ssh-rsa KEY2 user1@client<br />
<br />
在这种情况下用下列命令建立连接:<br />
<br />
ssh user2@relay<br />
<br />
注意,客户端内 scp 的自动完成功能失效,甚至在某些配置下 scp 本身也无法工作。<br />
<br />
=== 端口复用 ===<br />
<br />
SSH 守护进程通常监听 22 端口,但是许多公共热点会屏蔽非常规 HTTP/S 端口(分别是 80 和 443 端口)的流量,这样就屏蔽了 SSH 连接。最快的解决方法是让 {{ic|sshd}} 额外监听白名单上的端口:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
Port 22<br />
Port 443<br />
}}<br />
<br />
但是443端口很有可能已经被 HTTPS 服务占用,在这种情况下可以使用端口复用工具,比如 {{Pkg|sslh}},它可以监听在一个被复用的端口上并转发相应的数据包给对应的服务。<br />
<br />
=== 加速 SSH ===<br />
<br />
此处列出一些可以加速全部连接或针对某台主机加速的 [[#配置|客户端配置]] 选项。要了解这些选项的完整概述,请参阅 {{man|5|ssh_config}}。<br />
<br />
* 使用以下参数来使到某一台主机的所有回话 (sessions) 共享同一个连接: {{bc|<nowiki><br />
ControlMaster auto<br />
ControlPersist yes<br />
ControlPath ~/.ssh/sockets/socket-%r@%h:%p<br />
</nowiki>}}<br />
: 其中 {{ic|~/.ssh/sockets}} 可以是一个其他用户不可写入的任意目录。<br />
<br />
* {{ic|ControlPersist}} 指定在初始客户端连接关闭后,主服务器在后台等待新客户端的时间。可能的值是: <br />
** {{ic|no}} 指定在最后一个客户端断开后立即关闭连接,<br />
** 一个用秒数表示的时间,<br />
** {{ic|yes}} 连接不会自动关闭,而是始终处于等待。<br />
<br />
* 另一种加速的方法是通过 {{ic|Compression yes}} 选项或者 {{ic|-C}} 参数来启用压缩。<br />
: {{注意|{{man|1|ssh}} 指出:“在调制解调器线路或其他慢速线路上启用压缩是可取的,但在网速快的情况下只会降低速度。”这条提示可能会适得其反,具体取决于你的网络配置。}}<br />
<br />
* 通过使用 {{ic|AddressFamily inet}} 选项或者 {{ic|-4}} 参数来跳过 IPv6 查找,可以缩短登录时间。<br />
<br />
* 最后,如果你想用 SFTP 或 SCP,[https://www.psc.edu/index.php/hpn-ssh High Performance SSH/SCP] 可以通过动态提高 SSH 缓冲区大小来显著提高吞吐量。安装 {{AUR|openssh-hpn-git}} 这个包来使用打过这一增强补丁的 OpenSSH 版本。<br />
<br />
=== 用 SSHFS 挂载远程文件系统 ===<br />
<br />
请参阅 [[SSHFS]] 来将一个 SSH 可访问的远程文件系统挂载至一个本地目录,然后你就能在挂载好的文件上执行常规操作(复制,重命名,用 vim 编辑等等)。''sshfs'' 比 ''shfs'' 更好,因为后者自 2004 年起就没再更新。<br />
{{提示|软件包 {{AUR|autosshfs-git}} 可以用于在登录时自动运行 autosshfs。}}<br />
<br />
=== 保持在线 ===<br />
<br />
默认情况下,如果你的会话空闲了某个时间之后,它会自动登出。为了保持会话,在长时间没有数据传输时客户端可以向服务器发送一个激活信号。与之对应,服务器也可以在一段时间没有收到消息时定期发送一个信号。<br />
<br />
* 在 '''服务器''',{{ic|ClientAliveInterval}} 是没有从客户端收到消息后的超时时间,超时后 ''sshd'' 将会发送一个请求来等待回应。默认是 0,指不会发出请求。比如要求每隔 60 秒向客户端发送响应请求,在你的 [[#配置_2|服务器配置]] 里设置 {{ic|ClientAliveInterval 60}} 即可。{{ic|ClientAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
* 在 '''客户端''',{{ic|ServerAliveInterval}} 控制着从客户端发往服务器的响应请求的时间间隔。比如要求服务器每隔 120 秒响应一次,在你的 [[#配置|客户端配置]] 里加入 {{ic|ServerAliveInterval 120}} 即可。{{ic|ServerAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
<br />
{{注意| 为确保会话保持活动状态,客户端或服务器中只有一个需要发送保持活动请求。如果用户同时控制服务器和客户端,那么合理的选择是使用 {{ic|ServerAliveInterval}} 选项配置需要保持会话的客户端,并保留其他客户端和服务器的默认配置。}}<br />
<br />
=== 利用 systemd 自动重启 SSH 隧道 ===<br />
<br />
[[systemd]] 可以在开机/登录时自动启动 SSH,''还可以'' 在 SSH 连接断开时自动重连。这使它成为管理 SSH 隧道的有力工具。<br />
<br />
下面的 service 可以使用 [[#配置|ssh 配置]] 里面的配置在你登录系统的时候自动开启一个 SSH 隧道。如果连接因为某种原因断开,它将会每隔10秒重启一下:<br />
<br />
{{hc|~/.config/systemd/user/tunnel.service|<nowiki><br />
[Unit]<br />
Description=SSH tunnel to myserver<br />
<br />
[Service]<br />
Type=simple<br />
Restart=always<br />
RestartSec=10<br />
ExecStart=/usr/bin/ssh -F %h/.ssh/config -N myserver<br />
</nowiki>}}<br />
<br />
然后 [[enable]] 并且 [[start]] 这个 user service。欲知如何防止连接超时,请参阅 [[#Keep alive]]{{Broken section link}}。如果你想在系统引导后就打开这个连接,你需要将这个 unit 重写为 system service。<br />
<br />
=== Autossh - 自动重启 SSH 会话和隧道连接 ===<br />
<br />
当一个 SSH 会话或隧道无法保持连接(比如网络环境差导致客户端断线),可以使用 {{Pkg|autossh}} 来自动重启它们。<br />
<br />
使用范例:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" username@example.com<br />
<br />
结合 [[SSHFS]]:<br />
$ sshfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=45,ServerAliveCountMax=2,ssh_command='autossh -M 0' username@example.com: /mnt/example <br />
<br />
通过一个由 [[Proxy settings]] 设置好的 SOCKS 代理来连接:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" -NCD 8080 username@example.com <br />
<br />
使用 {{ic|-f}} 选项以后可以使 autossh 作为后台进程运行,然而以这种方式运行意味着不能交互输入密码。<br />
<br />
当你在会话中打出 {{ic|exit}} 即可结束会话,或者 autossh 收到了 SIGTERM, SIGINT of SIGKILL 信号。<br />
<br />
==== 利用 systemd 在引导后自动运行 autossh ====<br />
<br />
如果你想自动启动 autossh,创建一个 systemd unit 文件:<br />
<br />
{{hc|/etc/systemd/system/autossh.service|2=<br />
[Unit]<br />
Description=AutoSSH service for port 2222<br />
After=network.target<br />
<br />
[Service]<br />
Environment="AUTOSSH_GATETIME=0"<br />
ExecStart=/usr/bin/autossh -M 0 -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
}}<br />
<br />
其中 {{ic|1=AUTOSSH_GATETIME=0}} 是一个环境变量,它表示 ssh 需要连上多久,autossh 才判定这个连接是成功的。将它设为 0 后 autossh 也会忽略 ssh 的第一次运行失败。这在开机启动 autossh 时可能是有用的。其他环境变量可以在手册页找到。当然,如果需要的话,你可以使这个单元更加复杂(详情请参阅 systemd 文档),显然你可以使用自己的 autossh 选项,但请注意 {{ic|-f}} 选项意味着 {{ic|1=AUTOSSH_GATETIME=0}} 无法在 systemd 中起效。<br />
<br />
别忘了 [[start]] 且/或 [[enable]] 这个 service。<br />
<br />
你可能还会需要关闭 ControlMaster,像这样:<br />
<br />
ExecStart=/usr/bin/autossh -M 0 -o ControlMaster=no -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
{{提示|同时管理多个 autossh 进程也是很简单的,要保持多个隧道连接,只需要用不同的文件名创建多个 service 文件。}}<br />
<br />
=== 当 SSH 守护进程出错时的其他选择 ===<br />
<br />
对于仅依赖 SSH 的远程或无头服务器,启动 SSH 守护程序失败(例如系统升级后)可能会阻止管理员访问。[[systemd]] 通过 {{ic|OnFailure}} 选项提供了简便的解决方案。<br />
<br />
假设服务器运行 {{ic|sshd}} 并且 [[telnet]] 是所选的故障安全替代方案。按如下所示创建一个文件。'''不要''' [[enable]] telnet.socket!<br />
<br />
{{hc|/etc/systemd/system/sshd.service.d/override.conf|2=<br />
[Unit]<br />
OnFailure=telnet.socket<br />
}}<br />
<br />
这样就行了。当 {{ic|sshd}} 正在运行时,Telnet 是不可用的。如果 {{ic|sshd}} 无法启动,可以打开一个 telnet 会话进行恢复。<br />
<br />
== 疑难解答 ==<br />
<br />
=== 自检清单 ===<br />
<br />
在进一步阅读前,请先仔细检查下面这些常见故障。<br />
<br />
# 配置文件存放目录 {{ic|~/.ssh}} 及目录下的文件应该只有你的账户才有访问权限(在客户端和服务器上都检查这一条): {{bc|<nowiki><br />
$ chmod 700 ~/.ssh<br />
$ chmod 600 ~/.ssh/*<br />
$ chown -R $USER ~/.ssh<br />
</nowiki>}}<br />
# 检查客户端的公钥(比如 {{ic|id_rsa.pub}})在服务器的 {{ic|~/.ssh/authorized_keys}} 文件里面。<br />
# 检查有没有在 [[#配置_2|服务器配置]] 里面设置 {{ic|AllowUsers}} 或 {{ic|AllowGroups}} 来限制 SSH 访问。<br />
# 检查用户是否设置了密码。有时还没有登录过服务器的新用户没有密码。<br />
# 把 {{ic|LogLevel DEBUG}} 加到 {{ic|/etc/ssh/sshd_config}} 文件尾部。<br />
# 使用 {{ic|journalctl -xe}} 查看可能的错误信息。<br />
# 在客户端和服务器上 [[Restart|重启]] {{ic|sshd}} 然后注销/重新登录。<br />
<br />
=== 拒绝连接或者超时问题 ===<br />
<br />
==== 端口转发 ====<br />
<br />
如果您位于 NAT 模式/路由器之后(除非您位于 VPS 或可公开寻址的主机上),请确保您的路由器可以将传入的 ssh 连接转发到您的计算机。使用 {{ic|$ ip addr}} 查找服务器的内网 IP 地址,并将您的路由器设置为将 SSH 端口上的 TCP 数据包转发到该 IP。[http://portforward.com portforward.com] 可以提供帮助。<br />
<br />
==== SSH服务是否开启并且正在监听? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示 SSH 端口是打开的,那么说明 SSH 服务没有启动。查看 {{ic|/var/log/messages}} 来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
<br />
[[Iptables]] 可能会阻止 {{ic|22}} 端口的连接。使用 {{bc|# iptables -nvL}} 来检查可能会在 {{ic|INPUT}} 链上导致丢包的规则。必要情况下可以用以下命令来解锁端口:<br />
{{bc|<br />
# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT<br />
}}<br />
更多配置防火墙的信息,请参阅 [[firewalls]].<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是 NAT 路由的问题)<br />
<br />
==== 你的 ISP 或第三方屏蔽了默认端口? ====<br />
{{注意|只有在你'''确保'''你没有运行任何防火墙,你已经在路由器上配置了 DMZ 主机或已经将端口映射到你的计算机,而这些都没有用的情况下才尝试以下步骤。可以在此找到诊断步骤或可能的解决方案。}}<br />
<br />
某些情况下,你的运营商会屏蔽默认端口(22 端口),无论怎么尝试(尝试开启端口、强化堆栈、防范洪水攻击)都无济于事。要确认确实存在屏蔽,只要创建一个接受任何来源(0.0.0.0)的服务器并远程连接它。<br />
<br />
如果你收到与此类似的错误消息:<br />
ssh: connect to host www.inet.hr port 22: Connection refused<br />
<br />
就表示你的 ISP '''没有'''屏蔽端口,但是服务器没有在该端口上运行 SSH 服务(请参阅 [[wikipedia:Security_through_obscurity|security through obscurity]])。<br />
<br />
但是,如果你收到与这条类似的错误消息:<br />
ssh: connect to host 111.222.333.444 port 22: Operation timed out <br />
<br />
这就表示有人阻止了 22 端口的 TCP 连接,基本上是通过防火墙或第三方干预(如 ISP 阻止和/或拒绝端口 22 上的传入通信),使得端口不可用。如果你的计算机上没有运行任何防火墙,并且在你的路由器和交换机中没有这方面的流量,那么你的 ISP 屏蔽了通讯。<br />
<br />
为了再次检查确认,可以在服务器上运行 Wireshark 并让它监听在 22 端口。由于 Wireshark 是一个二层数据包嗅探工具,而 TCP/UDP 工作在第三层及以上(参阅 [[wikipedia:Internet protocol suite|IP Network stack]]),如果在连接时未收到任何内容,则第三方很可能阻止了该端口上到服务器的流量。<br />
<br />
===== 诊断 =====<br />
<br />
[[Install|安装]] {{Pkg|tcpdump}} 或 Wireshark ({{Pkg|wireshark-cli}})。<br />
<br />
用于 tcpdump:<br />
<br />
# tcpdump -ni ''interface'' "port 22"<br />
<br />
用于 Wireshark:<br />
<br />
$ tshark -f "tcp port 22" -i ''interface''<br />
<br />
其中 {{ic|''interface''}} 是用于连接 WAN 的网络适配器(用 {{ic|ip a}} 来查找)。如果在尝试远程连接时没有收到任何数据包,则可以确信你的 ISP 屏蔽了 22 端口上的传入连接。<br />
<br />
===== 可能的解决方案 =====<br />
此方案是换一个 ISP 没有屏蔽的端口。编辑 {{ic|/etc/ssh/sshd_config}} 文件来使用不同的端口。例如,新增这几行:<br />
<br />
Port 22<br />
Port 1234<br />
<br />
还要确保文件中的其他“Port”配置行被注释掉。只是注释“Port 22”并加上“Port 1234”不会解决问题,因为那样 sshd 将只监听在 1234 端口上。写入这两行可以在两个端口上运行 SSH 服务器。<br />
<br />
[[Restart|重启]] 服务器上的 {{ic|sshd.service}} 就基本完成了。你还需要配置客户端来使用与默认端口不同的端口,这个问题有很多种解决方案,在这里我们只介绍两种。<br />
<br />
==== "Read from socket failed: connection reset by peer" 错误 ====<br />
<br />
使用最近版本的 openssh 连接到较旧的 ssh 服务器时有时会失败,并显示上述错误消息。这可以通过为该主机设置各种 [[#配置|客户端选项]] 来解决。有关下列选项的更多信息,请参阅 {{man|5|ssh_config}}。<br />
<br />
问题可能出在 {{ic|ecdsa-sha2-nistp*-cert-v01@openssh}} 椭圆曲线算法上。这些算法可以通过在 {{ic|HostKeyAlgorithms}} 里设置可用算法来排除那些算法。<br />
<br />
如果这不起作用,可能是秘钥列表太长了。设置 {{ic|Ciphers}} 来减少列表长度(少于 80 个字符应该可以)。同样的,也可以尝试缩短 {{ic|MACs}} 列表。<br />
<br />
参阅 openssh bug forum 上的 [http://www.gossamer-threads.com/lists/openssh/dev/51339 讨论]。<br />
<br />
=== "[your shell]: No such file or directory" / SSH 认证问题 ===<br />
对于这个问题,一个可能的原因是需要 SSH 客户端在 {{Ic|$SHELL}} 中提供绝对路径(例如可以通过 {{Ic|whereis -b [your shell]}} 得到),即使你的 shell 在 {{Ic|$PATH}} 里的某个路径中。<br />
<br />
==="Terminal unknown" 或 "Error opening terminal" 错误 ===<br />
如果你在登录时收到上述错误,这意味着服务器无法识别你的终端。使用 Ncurses 的应用程序(如 nano)可能会失败,并显示“Error opening terminal”。<br />
<br />
正确的解决方案是在服务器上安装客户端终端的 terminfo 文件。这会告诉服务器上的控制台程序如何正确地与终端进行交互。你可以使用 {{ic|$ infocmp}} 获得关于当前 terminfo 的信息,然后找出 [[Pacman#Querying_package_databases|哪个包包括了它们]]。<br />
<br />
如果你不能正常[[install|安装]]它,可以把 terminfo 复制到服务器上你的主目录里面:<br />
<br />
$ ssh myserver mkdir -p ~/.terminfo/${TERM:0:1}<br />
$ scp /usr/share/terminfo/${TERM:0:1}/$TERM myserver:~/.terminfo/${TERM:0:1}/<br />
<br />
重新登录、登出服务器后这个问题应该已经解决。<br />
<br />
==== TERM hack ====<br />
<br />
{{警告|这只能作为最后的手段。}}<br />
<br />
你可以在服务器上的环境(例如 {{ic|.bash_profile}})中简单地设置 {{ic|1=TERM=xterm}} 。这将消除错误并允许 ncurses 应用程序再次运行,但除非你的终端的控制序列与 xterm 完全匹配,否则可能会遇到奇怪的行为和图形界面问题。<br />
<br />
=== "Connection closed by x.x.x.x [preauth]" 错误 ===<br />
如果你在 sshd 的 log 里看到这条错误,请确保你已经设置了可用的 HostKey<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
=== id_dsa 被 OpenSSH 7.0 拒绝 ===<br />
<br />
出于安全原因,OpenSSH 7.0 弃用了 DSA 公钥。如果你必须启用它们,请[[#配置|设置]] {{ic|PubkeyAcceptedKeyTypes +ssh-dss}} 选项(http://www.openssh.com/legacy.html 没有提到这一点)。<br />
<br />
=== OpenSSH 7.0 的 "No matching key exchange method found" 错误 ===<br />
<br />
OpenSSH 7.0 弃用了 diffie-hellman-group1-sha1 密钥算法,因为它很弱并且在所谓 Logjam 攻击的理论范围内(参阅http://www.openssh.com/legacy.html)。如果特定主机需要这个密钥算法,ssh 会产生如下错误消息:<br />
<br />
Unable to negotiate with 127.0.0.1: no matching key exchange method found.<br />
Their offer: diffie-hellman-group1-sha1<br />
<br />
这个问题的最佳解决方案是将服务器升级/配置为不使用不推荐的算法。如果做不到这一点,可以配置[[#配置|客户端选项]] {{ic|KexAlgorithms +diffie-hellman-group1-sha1}} 强制客户端使用这个算法。<br />
<br />
=== 断开 SSH 连接时 tmux/screen 会话被关闭 ===<br />
<br />
如果进程在会话结束时被终止,那么你可能是用 ssh.socket 激活的,{{Pkg|systemd}} 注意到 SSH 会话进程退出,然后杀掉了 tmux/screen 进程。这种情况有两种解决方案。一种是通过使用 {{ic|ssh.service}} 来代替 {{ic|ssh.socket}} 来避免使用 socket 激活。另一个是在 {{ic|ssh@.service}} 的 Service 部分设置 {{ic|1=KillMode=process}}。<br />
<br />
在常规的 {{ic|ssh.service}} 里面 {{ic|1=KillMode=process}} 这个选项也是有用的,它可以在 service 停止或重启时防止 SSH 会话进程或 {{Pkg|screen}} 或 {{Pkg|tmux}} 进程被 kill 掉。<br />
<br />
=== SSH 会话无响应 ===<br />
<br />
SSH 响应 [[Wikipedia:Software_flow_control|流控制命令]] 中的 {{ic|XON}} 和 {{ic|XOFF}} 命令。 当你按 {{ic|Ctrl+s}} 时,它会冻结/挂起/停止响应。按 {{ic|Ctrl+q}} 恢复会话。<br />
<br />
== 参阅 ==<br />
<br />
* [[Wikipedia:Secure Shell]]<br />
* [http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
* [http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks<br />
* [https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure Secure Shell]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=General_troubleshooting_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=519247
General troubleshooting (简体中文)
2018-04-30T02:38:00Z
<p>Arisaka: 修改 Getty 页面的链接为简体中文链接。</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:System administration (简体中文)]]<br />
[[Category:System recovery (简体中文)]]<br />
[[Category:Getting and installing Arch (简体中文)]]<br />
[[en:General troubleshooting]]<br />
[[es:General troubleshooting]]<br />
[[ja:一般的なトラブルシューティング]]<br />
[[ru:General troubleshooting]]<br />
{{Related articles start}}<br />
{{Related|Reporting bug guidelines (简体中文)}}<br />
{{Related|Step-by-step debugging guide}}<br />
{{Related|Debug - Getting Traces (简体中文)}}<br />
{{Related|IRC Collaborative Debugging}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|General troubleshooting|2018-04-02|515594}}<br />
<br />
本文介绍了一些常规的故障排除方法。有关特定应用程序的问题,请参阅该特定程序的 wiki 页面。<br />
<br />
== 常用手段 ==<br />
<br />
=== 注意细节 ===<br />
<br />
为了解决遇到的问题,对当前使用的这个程序,你应该有一个基本的了解,这是 ''至关重要'' 的。它是如何工作的,它依赖什么才能正常运行?如果不能很好地回答这些问题,最好阅读一下这些出错程序的 [[Table of contents (简体中文)|Archwiki]] 文章。一旦你觉得你已经理解了它,你将更容易找出问题的原因。<br />
<br />
=== 常见问题 / 检查项 ===<br />
<br />
下面列出了许多常见问题,用于排查故障。在每个问题下都有注释,说明你该如何回答这个问题,紧接着的是一些如何收集数据的简单示例,还有查看各种日志的工具。<br />
<br />
# 出现了什么故障?<br />
#: 请尽可能精确地描述问题,这将帮助你在查找特定信息的时候不至感到困惑或扯到别的方面去。<br />
# 是否显示了错误信息?(如果有的话)<br />
#: 将包含相关 '''错误信息''' 的 ''完整输出'' 复制并粘贴到类似 {{ic|$HOME/issue.log}} 这样单独的文件中。例如,可以将以下 [[mkinitcpio (简体中文)|mkinitcpio]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ mkinitcpio -p linux >> $HOME/issue.log}}<br />
# 可以复现这个故障码?<br />
#: 如果是这样,请 '''按步骤''' 给出 ''确切的'' 指示/命令来做到这一点。<br />
# 第一次遇到这些故障的时间,以及从没有故障到故障发生之间你修改了什么内容?<br />
#:如果这种情况发生在某次升级之后,可以列出 '''所有已升级的包'''。包括 ''版本号'',同时粘贴 [[pacman]].log ({{ic|/var/log/pacman.log}}) 的升级日志。使用 [[Systemd (简体中文)|systemd]] 的 systemctl 工具检查故障程序依赖的 ''所有'' 服务的运行状态。例如,可以将 [[Systemd (简体中文)#systemd 基本工具|systemd]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ systemctl status dhcpcd@eth0.service >> $HOME/issue.log}}<br />
#: {{注意|使用 {{ic|'''>>'''}} 可以保证 {{ic|$HOME/issue.log}} 中之前保存的内容不会被覆盖。}}<br />
<br />
=== 寻求解决 ===<br />
<br />
不要通过这样的表述来寻求问题的解决:<br />
<br />
''程序 X 不工作了。''<br />
<br />
描述整个系统的环境更有助于解决问题,比如:<br />
<br />
''应用程序 X 在执行 Z 任务时,会报出 Y 错误,条件是 A 和 B。''<br />
<br />
=== 额外支援 ===<br />
<br />
利用你眼前的所有信息,你应该对系统里发生了什么有一个较好的认识,并且可以开始着手修复了。<br />
<br />
如果需要额外支援,[https://bbs.archlinux.org 官方论坛] 或 IRC (irc.freenode.net 上的 #archlinux 频道) 都可以提供帮助。更多频道可参考 [[IRC channels]]。<br />
<br />
{{注意|[[Code of conduct (简体中文)#仅支持 Arch Linux|技术支持 ''仅限于'' Arch Linux]] 而非 [[Arch-based distributions (简体中文)|基于 Arch 的发行版]]。}}<br />
<br />
当要求贴出 '''完整''' 的 输出 / 日志 时,不能仅仅贴出你认为的重要部分。信息来源应该包括:<br />
<br />
* 所有涉及到的命令的完整输出,不要只选择你认为相关的东西。<br />
* 来自 systemd 的 {{ic|journalctl}} 的输出。要获取更多的输出,请使用 {{ic|1=systemd.log_level=debug}} 引导参数。<br />
* 日志文件(看一下 {{ic|/var/log}} 目录)<br />
* 相关的配置文件<br />
* 相关的驱动程序<br />
* 相关软件包的版本<br />
* 内核相关:{{ic|dmesg}}。对于启动问题,至少贴出最后 10 行,多贴一些当然更好。<br />
* 网络相关:相关命令的完整输出,再加上所有相关配置文件。<br />
* Xorg 相关: {{ic|/var/log/Xorg.0.log}},如果你已经覆盖了出问题的日志,就贴在这之前的日志。<br />
* Pacman 相关:如果最近的更新弄坏了什么东西,请到 {{ic|/var/log/pacman.log}} 找它。<br />
<br />
贴出这些信息有一个更好的方式,就是使用在线剪贴板 (pastebin)。你可以 [[install|安装]] {{pkg|pbpst}} 或 {{pkg|gist}} 来自动上传信息。例如,要上传这次启动以来的 systemd 日志,可以这么做:<br />
<br />
# journalctl -xb | pbpst -S<br />
<br />
这将返回一个链接,你可以把它贴到论坛或 IRC。<br />
<br />
另外,在提问之前,请先阅读 [http://www.catb.org/esr/faqs/smart-questions.html 提问的智慧] 和 [[Code of conduct (简体中文)|行为准则]]。<br />
<br />
== 系统启动问题 ==<br />
<br />
诊断 [[boot process (简体中文)|启动过程]] 中的问题主要是修改 [[kernel parameters (简体中文)|内核参数]],然后重启系统。<br />
<br />
如果系统无法启动,可以从 [https://www.archlinux.org/download/ live 镜像] 启动并 [[change root (简体中文)|chroot]] 到现有系统。<br />
<br />
=== 控制台的输出信息 ===<br />
<br />
在启动过程完成以后,屏幕会被清空并显示登录提示符,这使得用户无法看到初始化过程中的输出和其中的错误信息。这一默认特性可以使用接下来几节中的方法进行修改。<br />
<br />
请注意,无论选择下面哪个方法,在启动后通过使用 {{ic|dmesg}} 或 {{ic|journalctl -b}} 都可以显示内核消息,用于检查错误。<br />
<br />
==== 输出流控制 ====<br />
<br />
以下是适用于大多数终端模拟器的基本操作,包括虚拟终端 (vc):<br />
<br />
* 按 {{ic|Ctrl+S}} 暂停输出<br />
* 按 {{ic|Ctrl+Q}} 继续输出<br />
<br />
这样不仅会暂停输出,而且会暂停尝试打印到终端的程序,即暂停输出时会阻塞 {{ic|write()}} 调用。 如果你的 ''init'' 进程出现冻结,请确保系统控制台没有暂停。<br />
<br />
要查看已经显示过的错误信息,参见 [[Getty (简体中文)#将引导消息保留在 tty1 上]]。<br />
<br />
==== 回滚显示 ====<br />
<br />
回滚显示允许用户查看已经从控制台滚动过去并消失的文字内容。这通常是在视频适配器和显示设备之间创建缓冲(称为回滚缓冲区)实现的。默认情况下,将缓冲的内容上下滚动的快捷键是 {{ic|Shift+PageUp}} 和 {{ic|Shift+PageDown}}。<br />
<br />
如果回滚内容没有完全包含足够的信息,可能需要扩大回滚缓冲区的大小来容纳更多输出。这可以通过配置内核的 framebuffer console(fbcon,帧缓冲控制台)来实现,修改 [[kernel parameter|内核参数]] {{ic|1=fbcon=scrollback:Nk}} 即可,其中 {{ic|N}} 是缓冲区大小,单位是 kB,默认是 32k。<br />
<br />
如果这不奏效,你的 framebuffer console 可能没有正确地启用。参阅 [https://www.kernel.org/doc/Documentation/fb/fbcon.txt Framebuffer Console documentation] 来查找其他影响参数,比如修改帧缓冲驱动。<br />
<br />
==== Debug 输出 ====<br />
<br />
在启动时,大部分来自内核的消息都是隐藏的,可以加入不同的内核参数来输出更多信息。最简单的是这些:<br />
<br />
* {{ic|debug}} 可以同时启用来自内核和 [[Systemd (简体中文)|systemd]] 的调试信息<br />
* {{ic|ignore_loglevel}} 强制显示 ''所有'' 内核消息<br />
<br />
在特定情况下有用的其他参数如下:<br />
* {{ic|1=earlyprintk=vga,keep}} 在早期启动过程中就输出内核消息,用于内核在有输出前就崩溃的情况下。在 [[Unified Extensible Firmware Interface (简体中文)|EFI]] 系统上要把 {{ic|vga}} 改成 {{ic|efi}}。<br />
* {{ic|1=log_buf_len=16M}} 用于分配一个更大 (16MB) 的内核消息缓冲区,用来保证 debug 输出不被覆盖。<br />
<br />
还有很多独立的调试参数,用于在特定的子系统中启用调试,例如 {{ic|bootmem_debug}} 和 {{ic|sched_debug}}。更多详细信息请参考 [https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt kernel parameter documentation]。<br />
<br />
{{注意|如果无法回滚的足够远以查看所需的启动输出,你需要扩大 [[#回滚显示|回滚缓冲区]] 的大小。}}<br />
<br />
=== 故障恢复控制台 ===<br />
<br />
在启动过程中的某个阶段获取一个交互式 shell 可以帮助你准确找出问题出在哪里,以及为何失败。有几个内核参数可以做到这一点,但它们都启动了一个正常的shell,可以随时 {{ic|exit}} 让内核恢复正在执行的操作:<br />
* {{ic|rescue}} 在根文件系统刚刚被挂载为读写模式的时候启动一个 shell<br />
* {{ic|emergency}} 可以在更早的时候启动 shell,早于大部分文件系统挂载之前<br />
* {{ic|1=init=/bin/sh}}(作为最后的选择)把 init 程序改成 root shell。因为 {{ic|rescue}} 和 {{ic|emergency}} 都依赖于 [[Systemd (简体中文)|systemd]],而这可以在 ''systemd'' 坏掉的时候工作<br />
<br />
还有一个选择,那就是 systemd 的 debug-shell,它在 {{ic|tty9}} 上新增了一个 root shell,可以按 Ctrl+Alt+F9 来使用。这个功能可以通过在 [[kernel parameters|内核参数]] 中添加 {{ic|systemd.debug-shell}},或者是 [[enabling|启用]] {{ic|debug-shell.service}} 来打开。注意在使用完后禁用该服务,避免在每次启动时都打开 root shell 而带来安全风险。<br />
<br />
=== Intel 显卡造成的黑屏 ===<br />
<br />
这很可能是 [[kernel mode setting]] 的问题造成的。尝试 [[Kernel mode setting#Disabling modesetting|disabling modesetting]] 或者修改 [[Intel#KMS Issue: console is limited to small area|video port]]。<br />
<br />
=== 加载内核时卡住 ===<br />
<br />
尝试添加 {{ic|1=acpi=off}} 内核参数来关闭 ACPI。<br />
<br />
=== 调试内核模块 ===<br />
<br />
参见 [[Kernel modules#Obtaining information]]。<br />
<br />
=== 调试硬件 ===<br />
<br />
* 按照 [[udev#Debug output]] 的说明可以显示额外硬件调试信息。<br />
* 确保你的系统已经安装了 [[Microcode (简体中文)|Microcode]] 更新。<br />
* 使用 [http://www.memtest.org/ Memtest86+] 来测试设备的 RAM,不可靠的 RAM 可能会导致一些非常奇怪的问题,从随机崩溃到数据损坏都有可能。<br />
<br />
== 内核崩溃 (Kernel panics) ==<br />
<br />
Linux 内核进入不可恢复的故障状态时,即发生了“内核崩溃” (''kernel panic'')。这种状态通常来源于错误的硬件驱动程序,导致内核死锁,无响应并需要重新启动。在死锁之前,会生成一条诊断消息,其中包括:发生崩溃时的''机器状态'',导致崩溃的内核函数的''调用栈'',以及当前加载的模块的列表。庆幸的是,使用 ''mainline(主线)'' 版本的内核(比如官方仓库提供的内核)不会经常发生内核崩溃,但是当它们发生时,你需要知道如何处理它们。<br />
<br />
{{注意|Kernel panics 有时被称为 ''oops'' 或 ''Kernel oops'',虽然 panics 和 oops 都是在出错的状态下才会发生,但是 ''oops'' 更为通用,因为它并不一定会导致内核死锁,有时内核可以通过结束出错的任务来恢复并继续运行。}}<br />
<br />
{{提示|在启动时传递参数 {{ic|1=oops=panic}} 或者在 {{ic|/proc/sys/kernel/panic_on_oops}} 中写入 {{ic|1}} 来强制用 panic 代替可恢复的 oops。如果你认为自动恢复 oops 导致了小概率的系统不稳定,进而导致了后来的错误难以被诊断,那么建议你这样做。}}<br />
<br />
=== 查看 panic 信息 ===<br />
<br />
如果在早期启动过程中发生了 kernel panic,你或许会在控制台上看到包含 "Kernel panic - not syncing:" 的消息,一旦 [[Systemd (简体中文)|Systemd]] 开始运行,内核消息就会被捕捉到并写入系统日志。但是,当 Kernel panic 发生时,内核发出的诊断信息 ''几乎不会'' 被写入硬盘上的日志文件,因为在 {{ic|system-journald}} 运作前内核就死锁了。因此,检查内核崩溃消息的唯一方法是在崩溃时从控制台看错误信息(如果没有设置 ''kdump crashkernel'' 的话)。可以用以下内核参数来启动,这样就能重现 tty1 上的错误信息:<br />
<br />
{{bc|1=systemd.journald.forward_to_console=1 console=tty1}}<br />
<br />
{{提示|如果崩溃信息滚动得太快导致无法阅读,可以在启动时尝试添加 {{ic|1=pause_on_oops=''seconds''}} 内核参数。}}<br />
<br />
==== 示例场景:模块损坏 ====<br />
<br />
根据诊断信息,我们可以大致推断出是哪个子系统或者模块导致了崩溃。在这个示例中,我们假设机器在启动时发生了 panic。注意那些用 '''粗体''' 标记的行:<br />
<br />
{{bc|'''kernel: BUG: unable to handle kernel NULL pointer dereference at (null)''' [1]<br />
'''kernel: IP: fw_core_init+0x18/0x1000 [firewire_core]''' [2]<br />
kernel: PGD 718d00067 <br />
kernel: P4D 718d00067 <br />
kernel: PUD 7b3611067 <br />
kernel: PMD 0 <br />
kernel: <br />
kernel: Oops: 0002 [#1] PREEMPT SMP<br />
'''kernel: Modules linked in: firewire_core(+) crc_itu_t cfg80211 rfkill ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG nf_conntrack_ipv4 ...''' [3] <br />
kernel: CPU: 6 PID: 1438 Comm: modprobe Tainted: P O 4.13.3-1-ARCH #1<br />
kernel: Hardware name: Gigabyte Technology Co., Ltd. H97-D3H/H97-D3H-CF, BIOS F5 06/26/2014<br />
kernel: task: ffff9c667abd9e00 task.stack: ffffb53b8db34000<br />
kernel: RIP: 0010:fw_core_init+0x18/0x1000 [firewire_core]<br />
kernel: RSP: 0018:ffffb53b8db37c68 EFLAGS: 00010246<br />
kernel: RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000<br />
kernel: RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffffc16d3af4<br />
kernel: RBP: ffffb53b8db37c70 R08: 0000000000000000 R09: ffffffffae113e95<br />
kernel: R10: ffffe93edfdb9680 R11: 0000000000000000 R12: ffffffffc16d9000<br />
kernel: R13: ffff9c6729bf8f60 R14: ffffffffc16d5710 R15: ffff9c6736e55840<br />
kernel: FS: 00007f301fc80b80(0000) GS:ffff9c675dd80000(0000) knlGS:0000000000000000<br />
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
kernel: CR2: 0000000000000000 CR3: 00000007c6456000 CR4: 00000000001406e0<br />
kernel: Call Trace:<br />
'''kernel: do_one_initcall+0x50/0x190''' [4]<br />
kernel: ? do_init_module+0x27/0x1f2<br />
kernel: do_init_module+0x5f/0x1f2<br />
kernel: load_module+0x23f3/0x2be0<br />
kernel: SYSC_init_module+0x16b/0x1a0<br />
kernel: ? SYSC_init_module+0x16b/0x1a0<br />
kernel: SyS_init_module+0xe/0x10<br />
kernel: entry_SYSCALL_64_fastpath+0x1a/0xa5<br />
kernel: RIP: 0033:0x7f301f3a2a0a<br />
kernel: RSP: 002b:00007ffcabbd1998 EFLAGS: 00000246 ORIG_RAX: 00000000000000af<br />
kernel: RAX: ffffffffffffffda RBX: 0000000000c85a48 RCX: 00007f301f3a2a0a<br />
kernel: RDX: 000000000041aada RSI: 000000000001a738 RDI: 00007f301e7eb010<br />
kernel: RBP: 0000000000c8a520 R08: 0000000000000001 R09: 0000000000000085<br />
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000c79208<br />
kernel: R13: 0000000000c8b4d8 R14: 00007f301e7fffff R15: 0000000000000030<br />
kernel: Code: <c7> 04 25 00 00 00 00 01 00 00 00 bb f4 ff ff ff e8 73 43 9c ec 48 <br />
kernel: RIP: fw_core_init+0x18/0x1000 [firewire_core] RSP: ffffb53b8db37c68<br />
kernel: CR2: 0000000000000000<br />
kernel: ---[ end trace 71f4306ea1238f17 ]---<br />
'''kernel: Kernel panic - not syncing: Fatal exception''' [5]<br />
kernel: Kernel Offset: 0x80000000 from 0xffffffff810000000 (relocation range: 0xffffffff800000000-0xfffffffffbffffffff<br />
kernel: ---[ end Kernel panic - not syncing: Fatal exception}}<br />
<br />
* [1] 表明了导致 panic 的错误类型。此处表示一个程序 bug。<br />
* [2] 表明 panic 发生在 ''firewire_core'' 模块中的 ''fw_core_init'' 函数中。<br />
* [3] 表明 ''firewire_core'' 模块是最后一个要加载的模块。<br />
* [4] 表明调用 ''fw_core_init'' 的函数是 ''do_one_initcall''。<br />
* [5] 表明这个 ''oops'' 消息事实上是一次 kernel panic 并且系统已经死锁。<br />
<br />
我们可以猜测,panic 发生在模块 ''firewire_core'' 加载后的初始化例程中。(我们或许可以认为,由于程序错误,这台机器的火线 (IEEE 1394) 相关硬件与这一版本的驱动模块不兼容,并且需要等待下一个版本的驱动发布)与此同时,让机器运行起来的最简单方法,就是不要加载这个模块。我们可以通过以下两种方式之一来完成这个操作:<br />
<br />
* 如果这个模块在加载 ''initramfs'' 时就会被加载,那就在重启时加上内核参数 {{ic|1=rd.blacklist=firewire_core}}。<br />
* 否则就用这个内核参数重启 {{ic|1=module_blacklist=firewire_core}}。<br />
<br />
=== 重启至 root shell 并修复故障 ===<br />
<br />
为了更改系统设置使得 panic 不再发生,你需要一个 root shell。如果 panic 发生在启动时,有几种方法可以在内核死锁前获得一个 root shell:<br />
<br />
* 使用内核参数 {{ic|emergency}}、{{ic|rd.emergency}} 或 {{ic|-b}} 重启电脑,这样可以在根文件系统挂载且 {{ic|systemd}} 启动后就收到登录提示符。<br />
: {{注意|此时,根文件系统将会以'''只读'''方式挂载。执行 {{ic|# mount -o remount,rw /}} 来改变这一设置。}}<br />
* 使用内核参数 {{ic|rescue}}、{{ic|rd.rescue}}、{{ic|single}}、{{ic|s}}、{{ic|S}} 或 {{ic|1}} 在本地文件系统挂载完成后就得到登录提示符。<br />
* 使用内核参数 {{ic|1=systemd.debug-shell=1}} 在 tty9 上获得一个早期 root shell,然后按 {{ic|Ctrl-Alt-F9}} 切换到它。<br />
* 通过使用不同的内核参数重新引导来尝试禁用导致 panic 的内核功能。尝试“备用参数” {{ic|1=acpi=off}} 和 {{ic|nolapic}}。<br />
: {{提示|参阅 Linux 内核源码树中的 {{ic|Documentation/admin-guide/kernel-parameters.txt}} 文件来查找所有内核参数。}}<br />
* 作为最后的手段,你还可以使用 '''Arch Linux Installation CD''' 启动电脑,把根文件系统挂载到 {{ic|/mnt}},然后运行 {{ic|# arch-chroot /mnt}}。<br />
<br />
禁用导致 panic 的服务或程序,回滚有故障的更新或修复配置问题。<br />
<br />
== 软件包管理 ==<br />
<br />
参阅适用于一般主题的 [[Pacman#Troubleshooting]],以及适用于 PGP 密钥问题的 [[pacman/Package signing#Troubleshooting]]。<br />
<br />
== fuser ==<br />
<br />
{{Expansion|需要更多关于其用法的信息}}<br />
<br />
''fuser'' 是一个用于识别进程占用的资源(如打开的文件、文件系统和 TCP/UDP 端口)的命令行工具。<br />
<br />
''fuser'' 由软件包 {{Pkg|psmisc}} 提供,已经由 {{Grp|base}} 组安装。更多信息请查看 {{man|1|fuser}}。<br />
<br />
== 会话权限 ==<br />
<br />
{{注意|你必须使用 [[Systemd (简体中文)|systemd]] 作为你的 init 进程,本地会话才能正常工作。[https://www.archlinux.org/news/d-bus-now-launches-user-buses/] 它是各种设备的 polkit 权限和 ACL 所必需的 (参见 {{ic|/usr/lib/udev/rules.d/70-uaccess.rules}} 和 [http://enotty.pipebreaker.pl/2012/05/23/linux-automatic-user-acl-management/])}}<br />
<br />
首先,确保你有一个带 X 的可用本地会话:<br />
<br />
$ loginctl show-session $XDG_SESSION_ID<br />
<br />
在输出中需要带有 {{ic|1=Remote=no}} and {{ic|1=Active=yes}} 字样。如果没有,确保 X 运行在和登录时一样的 tty 里面。这是保留登录会话所必须的。<br />
<br />
D-Bus 会话也必须随 X 一起启动。关于这个的更多信息参见 [[D-Bus#Starting the user session]]。<br />
<br />
基本 [[polkit]] 操作不需要额外的配置。但有一些 polkit 操作需要请求额外的身份认证,即使是本地会话也是如此。为了达成这项工作,必须运行一个 polkit 身份认证组件。更多信息可参见 [[polkit (简体中文)#身份认证组件]]。<br />
<br />
== 错误信息: "error while loading shared libraries" ==<br />
<br />
{{Accuracy|在 [[System_maintenance#Partial_upgrades_are_unsupported|soname bump]] 之后相关程序可能需要重新编译。}}<br />
<br />
如果在运行程序时遇到类似于这样的错误:<br />
<br />
error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory<br />
<br />
使用 [[pacman]] 或 [[pkgfile]] 来查找包含丢失共享库的软件包:<br />
<br />
{{hc|$ pacman -Fs libusb-0.1.so.4|<br />
extra/libusb-compat 0.1.5-1<br />
usr/lib/libusb-0.1.so.4<br />
}}<br />
<br />
在上述例子中,需要 [[installed|安装]] 软件包 {{Pkg|libusb-compat}}。<br />
<br />
这个错误也有可能意味着你用来安装这个软件的 [[PKGBUILD]] 里没有将这个共享库作为它的依赖库:如果来自官方源,请 [[Reporting bug guidelines (简体中文)|报告一个 bug]];如果来自 [[AUR]],请在 AUR 网站相关页面上把它报告给维护者。<br />
<br />
== 错误信息: "file: could not find any magic files!" ==<br />
<br />
如果看到这条消息,则可能表示软件包更新破坏了动态链接程序的运行时依赖文件,并且系统现在已经基本瘫痪。在修复之前,你将无法重新编译或重新安装软件包或重建 [[mkinitcpio (简体中文)|initramfs]]。<br />
<br />
=== 错误原因 ===<br />
<br />
某次软件更新可能在 {{ic|/etc/ld.so.conf.d}} 目录中添加了非法的 {{ic|''filename''.conf}} 文件,或是错误地编辑了 {{ic|/etc/ld.so.conf}} 文件。其后果就是动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}} 使用了错误的数据重新生成了。这可能导致系统中所有依赖共享库的程序都出错(即几乎所有程序出错)。<br />
<br />
=== 解决方法 ===<br />
<br />
# 使用 '''''Arch Linux Installation CD''''' 启动。<br />
# 挂载根文件系统 {{ic|/}} 到 {{ic|/mnt}},挂载 {{ic|/boot}} 文件系统到 {{ic|/mnt/boot}},然后用命令 {{ic|# arch-chroot /mnt}} 切换到受损的系统中。<br />
# 检查 {{ic|/etc/ld.so.conf}} 文件,删除所有不正确的内容。<br />
# 检查放在 {{ic|/etc/ld.so.conf.d/}} 目录里的文件,删除所有不正确的文件。<br />
# 使用命令 {{ic|# ldconfig}} 重新生成动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}}。<br />
# 使用命令 {{ic|# mkinitcpio -p linux}} 重新生成 [[mkinitcpio (简体中文)|Initramfs]]。<br />
# 退出 chroot 环境,卸载文件系统,然后重启到原来的系统中。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.tuxradar.com/content/how-fix-most-common-linux-problems Fix the Most Common Problems]{{Dead link|2018|02|05}}<br />
* [https://www.reddit.com/r/archlinux/comments/tjjwr/archlinux_a_howto_in_troubleshooting_for_newcomers/ A how-to in troubleshooting for newcomers]<br />
* [http://wiki.ultimatebootcd.com/index.php?title=Tools List of Tools for UBCD] - Memtest-like tools to add to grub.cfg on UltimateBootCD.com<br />
* [[Wikipedia:BIOS Boot partition]]<br />
* [[REISUB]]<br />
* [http://freedesktop.org/wiki/Software/systemd/Debugging#Debug_Logging_to_a_Serial_Console Debug Logging to a Serial Console] on Freedesktop.org<br />
* [https://web.archive.org/web/20120217124742/http://www.lesswatts.org/projects/acpi/debug.php How to Isolate Linux ACPI Issues] on Archive.org</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Getty_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=519246
Getty (简体中文)
2018-04-30T02:32:28Z
<p>Arisaka: Full sync with English Version.</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Boot process (简体中文)]]<br />
[[en:Getty]]<br />
[[ja:Getty]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Display manager (简体中文)}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|Getty|2018-04-30|512521}}<br />
<br />
[[w:getty (Unix)|getty]] 是管理终端线路及其所连终端的程序的通用名称。其目的是保护系统,防止未经授权的访问。通常,每个 getty 进程由 [[systemd (简体中文)|systemd]] 启动,一个进程管理一条终端线路。<br />
<br />
== 安装 ==<br />
<br />
{{Style|TTY 设置和“台阶效应”在这里没有涉及到。TTY 的默认数量可以移到 [[#添加额外的虚拟控制台]] 一节,因为它不依赖于 agetty。}}<br />
<br />
''agetty'' 是 Arch Linux 中默认的 getty 程序,它是 {{Pkg|util-linux}} 包的一部分。它在等待登录时修改 TTY 设置,使得换行符不会转换为 CR-LF,否则会使打印到控制台的消息产生“阶梯效应”。Agetty 管理着虚拟控制台,Arch Linux 中默认提供六个虚拟控制台。一般按 {{ic|Ctrl+Alt+F1}} 到 {{ic|Ctrl+Alt+F6}} 来访问它们。<br />
<br />
其他可选替代包括:<br />
<br />
* {{App|mingetty|一个允许自动登录的最小化 getty。|{{AUR|mingetty}}|{{AUR|mingetty}}}}<br />
* {{App|fbgetty|类似于 mingetty,支持帧缓冲。|http://projects.meuh.org/fbgetty/|{{AUR|fbgetty}}}}<br />
* {{App|mgetty|在 Unix 下处理调制解调器各个方面功能的程序。|http://mgetty.greenie.net/|{{AUR|mgetty}}}}<br />
<br />
== 添加额外的虚拟控制台 ==<br />
<br />
打开 {{ic|/etc/systemd/logind.conf}} 文件并将 '''NAutoVTs=6''' 设置为你想要在启动时得到的虚拟控制台数量。<br />
<br />
如果你想临时获取一个控制台,可以为所需的 TTY 启动一个 getty 服务,执行:<br />
<br />
$ systemctl start getty@ttyN.service<br />
<br />
== 自动登录到虚拟控制台 ==<br />
<br />
配置自动登录要使用 systemd 的 [[Systemd (简体中文)#修改现存单元文件|附加代码片段 (drop-in snippet)]] 功能来重写传递给 ''agetty'' 的默认参数。<br />
<br />
虚拟控制台和串口控制台的配置是不同的。大多数情况下,你应该是想在虚拟控制台下设置自动登录(这种控制台的设备名称为 {{ic|tty''N''}},其中 {{ic|''N''}} 是一个数字)。串口控制台的自动登录配置稍有不同,它们的设备名称类似于 {{ic|ttyS''N''}},其中 {{ic|''N''}} 是一个数字。<br />
<br />
=== 虚拟控制台 ===<br />
<br />
要 [[Systemd (简体中文)#修改现存单元文件|修改现存单元文件]],可以手动创建下列附加文件,或执行 {{ic|systemctl edit getty@tty1}} 并输入附加代码片段 (drop-in snippet) 的内容:<br />
<br />
{{hc|/etc/systemd/system/getty@tty1.service.d/override.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/usr/bin/agetty --autologin ''username'' --noclear %I $TERM<br />
}}<br />
<br />
{{提示|默认 {{ic|getty@.service}} 中的 {{ic|1=Type=idle}} 选项将会推迟该服务的启动时间,直到所有任务(该单元的前置任务)已经完成,防止启动信息淹没了登录提示符。当 [[Start X at login|自动启动 X]] 时,可以通过添加 {{ic|1=Type=simple}} 到 [[Systemd (简体中文)#修改现存单元文件|附加代码片段 (drop-in snippet)]] 来立即启动 {{ic|getty@tty1.service}},因为此时 init 进程和 ''startx'' 都被 [[Silent boot|屏蔽]] 了输出,避免残留启动时的信息。}}<br />
<br />
如果你想用 ''tty'' 而不是 ''tty1'',请参阅 [[Systemd FAQ (简体中文)#如何修改默认的 tty 控制台(getty)数量?|Systemd 常见问题]]。<br />
<br />
=== 串口控制台 ===<br />
<br />
创建以下文件(及目录):<br />
<br />
{{hc|/etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/usr/bin/agetty --autologin ''username'' -s %I 115200,38400,9600 vt102<br />
}}<br />
<br />
=== Nspawn 控制台 ===<br />
<br />
要为 [[systemd-nspawn]] 容器配置自动登录,需要重写 ''console-getty'' 服务:<br />
<br />
{{hc|/etc/systemd/system/console-getty.service.d/override.conf|2=<br />
[Service]<br />
ExecStart=<br />
ExecStart=-/sbin/agetty --noclear --autologin ''username'' --keep-baud console 115200,38400,9600 $TERM<br />
}}<br />
<br />
== 将引导消息保留在 tty1 上 ==<br />
<br />
默认情况下,Arch 会启动 {{ic|getty@tty1}} 服务。该服务单元文件已经写入了 {{ic|--noclear}} 参数,它可以阻止 agetty 清空屏幕。但是 [[systemd (简体中文)|systemd]] 会在启动该服务之前清空屏幕。要关闭这项特性,请创建 {{ic|/etc/systemd/system/getty@tty1.service.d/noclear.conf}} 文件:<br />
<br />
{{hc|1=/etc/systemd/system/getty@tty1.service.d/noclear.conf|2=<br />
[Service]<br />
TTYVTDisallocate=no<br />
}}<br />
<br />
这将仅改写 TTY1 上的 ''agetty'' 的 {{ic|TTYVTDisallocate}} 参数,并保持全局服务文件 {{ic|/usr/lib/systemd/system/getty@.service}} 不变。可参阅 [[Systemd (简体中文)#修改现存单元文件]]。<br />
<br />
{{注意|<br />
* 确保从 [[Kernel parameters (简体中文)|内核参数]] 中移除了 {{ic|quiet}}。<br />
* KMS 晚启动可能会造成部分早期启动信息丢失。请参阅 [[Kernel mode setting (简体中文)#KMS 早启动]] 或 [[Kernel mode setting (简体中文)#禁用 KMS]]。<br />
}}<br />
<br />
== 参考资料 ==<br />
<br />
* [[Systemd (简体中文)#修改默认运行级别/目标]]<br />
* [http://www.linusakesson.net/programming/tty/ The TTY demystified]<br />
* [[Wikipedia:Tty (unix)]]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Git_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=517726
Git (简体中文)
2018-04-17T11:40:09Z
<p>Arisaka: Full sync with English Version.</p>
<hr />
<div>[[Category:Version Control System (简体中文)]]<br />
[[en:Git]]<br />
[[es:Git]]<br />
[[ja:Git]]<br />
{{TranslationStatus (简体中文)|Git|2018-04-17|516679}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion (简体中文)}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}<br />
<br />
[[wikipedia:Git (software)|Git]] 是一个由 Linux 内核作者 Linus Torvalds 编写的版本控制系统(VCS),现在被用来维护 [[AUR]] 软件包以及数以千计的其他项目,其中包括 Linux 内核。<br />
<br />
== 安装 ==<br />
<br />
[[Install|安装]] {{Pkg|git}} 软件包。要使用开发版本,请安装 {{AUR|git-git}} 软件包。当使用 ''git svn''、''git gui'' 和 ''gitk'' 等工具时请检查可选依赖项是否安装。<br />
<br />
{{注意|要打开 ''git-gui'' 的拼写检查功能,请安装 {{Pkg|aspell}},同时还需要与 {{ic|LC_MESSAGES}} [[Environment variables (简体中文)|环境变量]] 相对应的字典文件。参阅 {{Bug|28181}} 和 [[aspell (简体中文)]]。}}<br />
<br />
== 配置 ==<br />
<br />
你至少需要设置好姓名和邮箱之后才能开始使用 Git:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@example.com''"<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE 起步 - 初次运行 Git 前的配置]。<br />
<br />
更多设置选项可参阅 [[#提示与技巧]]。<br />
<br />
== 基本用法 ==<br />
<br />
一个 Git 版本库包含在一个名为 {{ic|.git}} 的目录内,该目录包含了修订历史以及其他元数据。版本库所跟踪的目录(默认为父目录)称为工作目录。在工作树进行的更改在被提交 (commit) 前需要先暂存 (stage) 起来。Git 还可以让你恢复以前提交的工作树文件。<br />
<br />
参阅 [https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E5%9F%BA%E7%A1%80 起步 - Git 基础]。<br />
<br />
=== 获取一个 Git 仓库 ===<br />
<br />
* 初始化一个版本库<br />
:{{ic|git init}},参阅 {{man|1|git-init}}<br />
* 克隆 (clone) 一个现有的版本库<br />
:{{ic|git clone ''repository''}},参阅 {{man|1|git-clone}}<br />
<br />
=== 记录更改 ===<br />
<br />
Git 管理的项目存在一个暂存区 (staging area),即 git 目录中的 {{ic|index}} 文件,其中保存了即将包含在你下一次提交中的文件更改。要将某个修改过的文件记录下来,首先需要将修改后的文件添加到 index(暂存它),然后用 {{ic|git commit}} 命令将当前的 index 保存为一次新的提交。<br />
<br />
==== 暂存 (stage) 更改 ====<br />
<br />
* 将工作树中的文件更改添加至 index<br />
:{{ic|git add ''pathspec''}},参阅 {{man|1|git-add}}<br />
* 移除 index 中记录的文件更改<br />
:{{ic|git reset ''pathspec''}},参阅 {{man|1|git-reset}}<br />
* 显示即将提交的更改、未暂存的更改以及未被 git 跟踪的文件<br />
:{{ic|git status}},参阅 {{man|1|git-status}}<br />
<br />
可以用 {{ic|.gitignore}} 文件来让 git 忽略某些未跟踪的文件,请参阅 {{man|5|gitignore}}。<br />
<br />
Git 不会跟踪文件移动。合并时的文件移动检测仅基于内容的相似性。{{ic|git mv}} 命令仅仅是为了方便,它相当于:<br />
<br />
$ mv -i foo bar<br />
$ git reset -- foo<br />
$ git add bar<br />
<br />
==== 提交 (commit) 更改 ====<br />
<br />
{{ic|git commit}} 命令将暂存区的更改保存至版本库,参阅 {{man|1|git-commit}}。<br />
<br />
* {{ic|-m}} – 后面跟上提交消息作为参数直接提交,而不是打开默认的文本编辑器来写提交信息后再提交<br />
* {{ic|-a}} – 自动暂存已更改或已删除的文件(不会添加未跟踪的文件)<br />
* {{ic|--amend}} – 重做上次提交,用于修改提交消息或修改提交的文件<br />
<br />
{{提示|建议经常性的提交小更改,并附上有意义的提交信息。}}<br />
<br />
==== 选择修订版本 ====<br />
<br />
Git 提供了多种方式来指定修订版本,参阅 {{man|7|gitrevisions}} 和 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC 选择修订版本]。<br />
<br />
许多 Git 命令需要用修订版本作为参数。一次提交记录可以用下列任何一种方式表示:<br />
<br />
* 某次提交的 SHA-1 哈希值(前7位通常足以唯一标识它)<br />
* 任意提交时的标签,如分支名称或 tag 名称<br />
* 标签 {{ic|HEAD}} 总是指向当前 check out 的提交(通常是分支的头部,除非你使用 ''git checkout'' 跳回到历史记录中的旧提交)<br />
* 以上任意一种表示方式加上 {{ic|~}} 都可以表示之前的提交。例如,{{ic|HEAD~}} 指向 {{ic|HEAD}} 的前一次提交,{{ic|HEAD~5}} 指向 {{ic|HEAD}} 5 次前的提交。<br />
<br />
==== 查看更改 ====<br />
<br />
查看不同提交间的修改处:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
或者查看暂存区和工作树之间的不同:<br />
<br />
$ git diff<br />
<br />
查看修改历史(其中 "''-N''" 指定最近的 n 次修改):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
=== 撤销修改 ===<br />
<br />
* {{ic|git reset}} - 重置当前 HEAD 指针到指定状态,参阅 {{man|1|git-reset}}<br />
<br />
* {{ic|git checkout}} - 恢复工作树中的文件,参阅 {{man|1|git-checkout}}<br />
<br />
=== 分支 (branch) ===<br />
<br />
Bug 修复和新功能通常在不同分支里测试。当一切就绪时它们就可以合并至默认(主)分支。<br />
<br />
创建一个分支,其名称准确地反映了其目的:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
列出已存在的分支:<br />
<br />
$ git branch<br />
<br />
切换分支:<br />
<br />
$ git checkout ''branch''<br />
<br />
新建分支并切换至该分支:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
将一个分支合并回主分支:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
如果不存在冲突的话,所有更改将被合并。否则 Git 将显示一条错误信息,并通过给工作树中的文件加注释来记录冲突。添加的注释可以用 {{ic|git diff}} 显示。要解决冲突,必须编辑文件,删除注释,并提交最终版本。请参阅下面的 [[#处理合并 (merge)]]。<br />
<br />
当一个分支使用完毕,可以这样删除:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== 多人合作 ===<br />
<br />
一个典型的 Git 工作流像这样:<br />
<br />
# 创建一个新仓库或克隆一个远程仓库。<br />
# 新建一个分支用于修改文件,然后提交这些修改。<br />
# 将多次提交合并在一起,这样更便于组织项目或更好地理解。<br />
# 把提交的分支合并回主分支。<br />
# (可选)将更改推送至远程服务器。<br />
<br />
==== 合并请求 (pull requests) ====<br />
<br />
在做出并提交更改后,贡献者可以请求原作者合并更改。这被称为 ''合并请求 (pull request)''。<br />
<br />
如果用 pull:<br />
<br />
$ git pull ''location'' master<br />
<br />
''pull'' 命令相当于 ''fetch'' 和 ''merge'' 命令的结合。如果存在冲突(比如原作者在同一时间段内在相同位置做了更改),那就有必要手动解决冲突。<br />
<br />
另一种方式是,原作者可以选择想要合并的更改。通过使用 ''fetch'' 命令(以及带有特殊 {{ic|FETCH_HEAD}} 标记的 ''log'' 命令),可以在决定如何处理合并请求 (pull request) 前查看该请求的内容:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== 使用远程仓库 (remote) ====<br />
<br />
远程 (remote) 是和本地相关联的远程仓库的别名。其实就是创建一个 ''label'' 来定义一个位置。这些 label 用于标识经常访问的仓库。<br />
<br />
添加一个远程仓库:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
获取远程库里的内容:<br />
<br />
$ git fetch ''label''<br />
<br />
显示本地主分支与远程主分支之间的差异:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
查看当前仓库相关联的远程仓库:<br />
<br />
$ git remote -v<br />
<br />
当设置的远程仓库是本仓库的 fork 来源(项目的领导者),这个远程仓库会被定义为 ''upstream''(上游)。<br />
<br />
==== 向某个仓库推送 (push) 修改 ====<br />
<br />
从原作者处获得推送修改的权限之后,使用以下命令推送修改:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
当使用 ''git clone'' 获得这个仓库后,git 会把仓库的原始地址记录在名为 {{ic|origin}} 的变量中。<br />
<br />
所以一次 ''典型的'' 推送可以这样做: <br />
<br />
$ git push origin master<br />
<br />
如果使用了 {{ic|-u}} ({{ic|--set-upstream-to}}) 选项,地址将会被记录下来,下次只要使用 {{ic|git push}} 就可以了。<br />
<br />
==== 处理合并 (merge) ====<br />
<br />
可以查看 Git Book 的 [https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6#遇到冲突时的分支合并 遇到冲突时的分支合并] 部分了解如何处理合并冲突。合并操作通常是可逆的,如果想返回合并前,可以使用 {{ic|--abort}} 命令(比如 {{ic|git merge --abort}} 或 {{ic|git pull --abort}})。<br />
<br />
=== 历史记录和版本记录 ===<br />
<br />
==== 在历史记录中搜索 ====<br />
<br />
{{ic|git log}} 命令可以显示历史记录信息,其中包含每次提交的校验和、作者、日期,以及简略信息。''校验和'' 就是一次提交对象的 "对象名称",通常是一个 40 位的 SHA-1 哈希值。<br />
<br />
对于具有较长信息的历史记录(其中 "''checksum''" 可以截取前几位,只要它是唯一的):<br />
<br />
$ git show (''checksum'')<br />
<br />
在被跟踪的文件中搜索 ''pattern'':<br />
<br />
$ git grep ''pattern''<br />
<br />
在 {{ic|.c}} 和 {{ic|.h}} 文件中搜索:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== 使用标签 (tag) ====<br />
<br />
给某次提交打标签来标记这个版本:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tag'' 通常是用于 [https://www.drupal.org/node/1066342 发布/标记版本] 的,但它可以是任何字符串。通常使用带注释的标签,因为它们会被添加到 Git 数据库中。<br />
<br />
标记当前的提交:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
列出标签:<br />
<br />
$ git tag -l<br />
<br />
删除某个标签:<br />
<br />
$ git tag -d 2.08<br />
<br />
更新远程库中的标签:<br />
<br />
$ git push --tags<br />
<br />
==== 重新组织 commit ====<br />
<br />
在提交合并请求之前,可能需要合并/重新组织 commit。这是通过 ''git rebase''(变基){{ic|--interactive}}完成的:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
然后会打开文本编辑器,其中包含指定范围内所有提交的摘要;这种情况下会包括最新提交 ({{ic|HEAD}}),但不包括 {{ic|''checksum''}} 表示的那次 commit。也可以使用数字来标记,例如用 {{ic|HEAD~3}},这会把最后三次提交变基:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
修改第一栏中的动作可以决定如何执行变基操作。可选的动作有:<br />
<br />
* {{ic|pick}} — 原样保留每次提交(默认)。<br />
* {{ic|edit}} — 编辑文件和/或 commit 信息。<br />
* {{ic|reword}} — 编辑 commit 信息。<br />
* {{ic|squash}} — 合并/折叠到先前的提交中。<br />
* {{ic|fixup}} — 合并/折叠到先前的提交中并丢弃它们的信息。<br />
<br />
提交会被重新排序或从历史记录中擦除(所以要非常小心)。编辑文件后,Git 将执行指定的操作;如果提示有合并问题待解决,请解决它们并使用 {{ic|git rebase --continue}} 来继续,或使用 {{ic|git rebase --abort}} 命令来取消操作。<br />
<br />
{{注意|合并多次提交的操作只能应用于本地提交,它会导致其他人共享的存储库出现问题。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
=== 使用 git-config ===<br />
<br />
Git 从三个 ini 类型的配置文件里读取配置:<br />
<br />
* {{ic|/etc/gitconfig}} 是应用于整个系统的默认配置文件<br />
* {{ic|~/.gitconfig}} 是应用于特定用户的配置文件<br />
* {{ic|.git/config}} 是应用于特定仓库的配置文件<br />
<br />
这些文件可以直接编辑,但是更常用的方法是使用 ''git config'',下面是一些示范。<br />
<br />
列出当前已配置的变量:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
将默认文本编辑器从 [[vim]] 改成 [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
设置默认的推送 (push) 行为:<br />
<br />
$ git config --global push.default simple<br />
<br />
设置不同的 ''git difftool'' 工具(默认是 ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
更多信息请参阅 {{man|1|git-config}} 和 [https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git 配置 Git]。<br />
<br />
=== 保持良好的礼仪 ===<br />
<br />
* 当你想为一个现有的项目贡献时,请先阅读并理解这个项目的许可,因为它可能会过度限制你更改代码的权力。有些许可会在代码的所有权方面引起争议。<br />
* 理解这个项目的社区,以及你可以融入其中的程度。要了解项目的主要方向,可以阅读所有文档甚至是代码库的 [[#历史记录和版本记录|log]]。<br />
* 当发起一个合并请求,或者提交一个补丁时,保证它是小改动并且有完善的文档;这将有助于项目维护者理解你的改动,并决定是否合并这些改动或是让你再改一下。<br />
* 如果贡献被拒绝,不要气馁,毕竟这是他们的项目。如果它很重要,请尽可能清楚和耐心地讨论这次贡献的理由,最终可能通过这种方法解决问题。<br />
<br />
=== 加快身份验证 ===<br />
<br />
每次向 Git 服务器推送时都要认证身份,你可能会想要避免这种麻烦。<br />
<br />
* 如果你是用 SSH 密钥来认证的,请使用 [[SSH keys (简体中文)#SSH agents|SSH agents]]。参阅 [[Secure Shell (简体中文)#加速 SSH]] 和 [[Secure Shell (简体中文)#保持在线]]。<br />
* 如果你是用账号和密码来认证的,在服务器支持 SSH 的情况下请切换至 [[SSH keys (简体中文)|SSH keys]], 否则请尝试 [https://git-scm.com/docs/git-credential-cache git-credential-cache] 或 [https://git-scm.com/docs/git-credential-store git-credential-store]。<br />
<br />
=== 默认通讯协议 ===<br />
<br />
如果你正在使用一个上述那种复用的 SSH 连接,让 Git 使用 SSH 可能比使用 HTTPS 更快。同时,一些服务器(比如 AUR)只允许通过 SSH 推送更改。例如,像下面这样配置可以使得 Git 通过 SSH 访问 AUR 上的任何仓库。<br />
<br />
{{hc|~/.gitconfig|<nowiki><br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
</nowiki>}}<br />
<br />
=== Bash 自动补全 ===<br />
<br />
要启用 Bash 的自动补全,请在 [[Bash#Configuration_files|Bash 启动文件]] 里用 source 加载 {{ic|/usr/share/git/completion/git-completion.bash}} 文件。或者也可以安装 {{pkg|bash-completion}}。<br />
<br />
=== Git 提示符 ===<br />
<br />
Git 包带有一个提示符脚本。要启用它,请在 [[Autostarting (简体中文)#Shells|shell 启动文件]] 里用 source 加载 {{ic|/usr/share/git/completion/git-prompt.sh}} 脚本,然后使用 {{ic|%s}} 参数设置一个自定义 shell 提示符:<br />
<br />
* [[Bash]] 用户: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* [[zsh]] 用户: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
当切换至一个 Git 仓库所在目录时,shell 提示符会变成所在分支名称。也可以配置提示符来显示其他信息:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || 已暂存 (staged) 显示 '''+''',未暂存 (unstaged) 显示 '''*'''。<br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || 已储藏 (stashed) 显示 '''$'''。<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || 有未跟踪文件时显示 '''%'''。<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' 分别表示落后于上游、领先于上游、偏离上游。<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} 需要设置为 {{ic|auto}} 才能使更改生效。<br />
<br />
{{注意|如果发生了 {{ic|$(__git_ps1)}} 返回 {{ic|((unknown))}} 的情况,是因为有一个 {{ic|.git}} 文件夹在你当前的文件夹里面,但却不包含任何存储库,因此 Git 不认识它。这有可能发生在你把 {{ic|~/.git/config}} 误认为是 Git 的配置文件而不是 {{ic|~/.gitconfig}}。}}<br />
<br />
你也可以使用来自 [[AUR]] 的自定义 git shell 提示符软件包,例如 {{AUR|bash-git-prompt}} 或 {{AUR|gittify}}。<br />
<br />
=== 可视化显示 ===<br />
<br />
要了解已经完成了多少工作:<br />
<br />
$ git diff --stat<br />
<br />
带有 fork 显示的 ''git log'':<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
给图形化的 ''git log'' 做一个别名(使用 ''git graph'' 即可显示经过修饰的 log):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
=== 关于提交 (commit) 的小提示 ===<br />
<br />
重置为以前的提交(非常危险,这将会擦除所有内容并改写为特定提交):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
如果远程仓库的地址发生变化,可以这样更新它的位置:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
自动附加签名行到提交(将某个 姓名-电邮 签名添加到提交中,某些项目会要求这样做):<br />
<br />
$ git commit -s<br />
<br />
自动附加签名到补丁(使用 {{ic|git format-patch ''commit''}} 时生效):<br />
<br />
$ git config --local format.signoff true<br />
<br />
提交已更改文件的特定部分。如果有大量更改时,最好拆分成多个提交,这种情况下这个命令通常很有用:<br />
<br />
$ git add -p<br />
<br />
=== 对提交 (commit) 签名 ===<br />
<br />
Git 允许使用 [[GnuPG (简体中文)|GnuPG]] 对提交和标签进行签名,请参见 [https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C 签署工作]。<br />
<br />
{{注意|<br />
如果是借助 {{Pkg|pinentry}} 来进行 GPG 签名,请确保 {{ic|1=export GPG_TTY=$(tty)}}(或者使用 pinentry-tty),否则当 GPG 处于锁定状态时签名这一步会失败(因为它无法在 shell 提示符里询问 pin 码)。}}<br />
<br />
配置 Git 使它自动对提交进行签名:<br />
<br />
$ git config --global commit.gpgSign true<br />
<br />
=== 在非主分支上工作 ===<br />
<br />
偶尔项目维护人员会要求你在其他分支上完成工作。这些分支通常被称为 {{ic|devel}} 或 {{ic|testing}}。首先要克隆存储库。<br />
<br />
要进入不是主分支的分支(''git clone'' 只会显示主分支,但其他分支其实也是存在的,用 {{ic|git branch -a}} 可以显示出来):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
然后就可以像平常一样编辑文件,但是要使得整个仓库都保持同步,下面这两个命令都要用:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
=== 直接将补丁发送至邮件列表 ===<br />
<br />
如果你想直接将补丁发送至一个邮件列表,需要安装以下软件包:{{Pkg|perl-authen-sasl}},{{Pkg|perl-net-smtp-ssl}} 和 {{Pkg|perl-mime-tools}}。<br />
<br />
确保你已经配置了用户名和邮件地址,可参阅 [[#配置]]。<br />
<br />
配置你的邮箱设置:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.example.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@example.com''<br />
<br />
现在你应该可以将补丁发送至某个邮件列表了(可参阅[http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
== Git 服务器 ==<br />
<br />
这一节讲述如何配置使用不同的协议连接到存储库。<br />
<br />
=== SSH 协议 ===<br />
<br />
要使用 SSH 协议,首先要准备一个 SSH 公钥,可以按照 [[SSH keys (简体中文)]] 的指导来完成。要配置一个 SSH 服务器,请遵循 [[Secure Shell (简体中文)]] 的指导。<br />
<br />
当 SSH 生成了密钥之后,将 {{ic|~/.ssh/id_rsa.pub}} 文件的内容粘贴至服务器上的 {{ic|~/.ssh/authorized_keys}} 文件里(一行一个,同一个公钥确保在同一行)。现在 Git 仓库可以通过 SSH 来访问:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
现在,如果你的 SSH 客户端的 {{ic|StrictHostKeyChecking}} 选项设为了 {{ic|ask}}(默认),你应该会收到来自 SSH 的问题,要你回答 yes/no。输入 {{ic|yes}} 然后回车,你的仓库就能被取出。同时,由于通过 SSH 协议访问,你现在应该有提交权限。<br />
<br />
要把一个已存在的仓库改成使用 SSH 访问,需要重新定义一下远程地址:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
要从非 22 端口连接,可以在每台主机的 {{ic|/etc/ssh/ssh_config}} 或 {{ic|~/.ssh/config}} 里配置。要为某个本地仓库设置端口(示例中用的 443 端口):<br />
<br />
{{hc|.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
你可以通过只允许用户执行 push 和 pull 操作来进一步提高 SSH 账户的安全性。这是通过将该账户的默认登录 shell 换成 git-shell 来实现的。在 [https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8 配置服务器] 中对此有所描述。<br />
<br />
=== Smart HTTP 协议 ===<br />
<br />
通过使用 git-http 后端,Git 可以像使用 SSH 协议或 Git 协议一样高效地使用 HTTP(S) 协议。此外,它不仅可以从仓库中克隆或拉取更改,还可以通过 HTTP(S) 推送更改。<br />
<br />
这个设置相当简单,因为你只需要安装 Apache Web 服务器({{pkg|apache}},启用 {{ic|mod_cgi}}、{{ic|mod_alias}} 和 {{ic|mod_env}}),当然还要安装 {{pkg|git}}。<br />
<br />
当你正在进行基本设置时,请将以下内容添加到 Apache 配置文件中,该配置文件通常位于:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
这里假设你的 Git 仓库位于 {{ic|/srv/git}},并且你想用类似 {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}} 的方式来访问它们。<br />
<br />
{{注意|请确保 Apache 对你的仓库有读写权限。}}<br />
<br />
如果需要更多详细文档,请访问:<br />
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP<br />
* https://git-scm.com/docs/git-http-backend<br />
<br />
=== Git 协议 ===<br />
<br />
{{注意|Git 协议没有加密或认证机制,且只允许读取。}}<br />
<br />
[[start|Start 并且 enable]] {{ic|git-daemon.socket}} 这个 systemd 单元。<br />
<br />
守护程序会带有以下选项启动:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
位于 {{ic|/srv/git/}} 目录下的仓库会被守护程序识别。客户端能以类似这样的方式连接:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== 设置访问权限 ===<br />
<br />
要限制读取和/或写入权限,可以使用常规 Unix 权限控制。更多信息请参考 [https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill]。<br />
<br />
如果需要更加精细的访问控制,请参考 [[gitolite]] 和 [[gitosis]]。<br />
<br />
== 参考资料 ==<br />
<br />
* Git 手册页:{{man|1|git}}<br />
* [https://git-scm.com/book/en/ Pro Git book]<br />
* 来自 GitHub 的 [https://git.github.io/git-reference/ Git Reference] <br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]<br />
* [https://wiki.videolan.org/Git VideoLAN wiki article]<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Core_utilities_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=517554
Core utilities (简体中文)
2018-04-15T05:11:08Z
<p>Arisaka: Fixed a translation error in the "cat" chapter.</p>
<hr />
<div>[[Category:Command-line (简体中文)]]<br />
[[en:Core utilities]]<br />
[[es:Core utilities]]<br />
[[fa:Core utilities]]<br />
[[it:Core utilities]]<br />
[[ja:Core Utilities]]<br />
[[ko:Core utilities]]<br />
[[pt:Core utilities]]<br />
[[ru:Core utilities]]<br />
[[zh-hant:Core utilities]]<br />
{{TranslationStatus (简体中文)|Core_Utilities|2018-04-15|516773}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Bash (简体中文)}}<br />
{{Related|Zsh (简体中文)}}<br />
{{Related2|General Recommendations (简体中文)|常用建议}}<br />
{{Related|GNU Project}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related|cron (简体中文)}}<br />
{{Related|man page (简体中文)}}<br />
{{Related|Securely wipe disk#shred}}<br />
{{Related|File permissions and attributes}}<br />
{{Related|Color output in console (简体中文)}}<br />
{{Related articles end}}<br />
<br />
本文涉及 GNU/Linux 系统的所谓的 "核心" 工具,比如 '''less''', '''ls''', 和 '''grep''',包括但不限于以上集成于 GNU {{Pkg|coreutils}} 中的工具。下文提供了关于这些实用工具颇为丰富的技巧和有帮助的其他信息。<br />
<br />
== 基本命令 ==<br />
<br />
下面表格列出了每个 Linux 用户都应该熟悉的命令,黑体命令是 shell 的一部分,其它的是 shell 调用的程序。命令的细节请阅读接下来的几节和''相关文章''。<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| man<br />
| 显示命令的手册页<br />
| {{man|7|man}}<br />
| man ed<br />
|-<br />
| '''cd'''<br />
| 变更目录<br />
| {{man|1p|cd}}<br />
| cd /etc/pacman.d<br />
|-<br />
| mkdir<br />
| 创建目录<br />
| {{man|1|mkdir}}<br />
| mkdir ~/newfolder<br />
|-<br />
| rmdir<br />
| 删除空目录<br />
| {{man|1|rmdir}}<br />
| rmdir ~/emptyfolder<br />
|-<br />
| rm<br />
| 删除文件<br />
| {{man|1|rm}}<br />
| rm ~/file.txt<br />
|-<br />
| rm -r<br />
| 删除目录和内容<br />
|<br />
| rm -r ~/.cache<br />
|-<br />
| ls<br />
| 显示文件<br />
| {{man|1|ls}}<br />
| ls *.mkv<br />
|-<br />
| ls -a<br />
| 显示隐藏文件<br />
|<br />
| ls -a /home/archie<br />
|-<br />
| ls -al<br />
| 显示隐藏文件和文件属性<br />
|<br />
|<br />
|-<br />
| mv<br />
| 移动文件<br />
| {{man|1|mv}}<br />
| mv ~/compressed.zip ~/archive/compressed2.zip<br />
|-<br />
| cp<br />
| 复制文件<br />
| {{man|1|cp}}<br />
| cp ~/.bashrc ~/.bashrc.bak<br />
|-<br />
| chmod +x<br />
| 设置文件为可执行文件<br />
| {{man|1|chmod}}<br />
| chmod +x ~/.local/bin/myscript.sh<br />
|-<br />
| cat<br />
| 显示文件内容<br />
| {{man|1|cat}}<br />
| cat /etc/hostname<br />
|-<br />
| strings<br />
| 显示文件中可打印的内容<br />
| {{man|1|strings}}<br />
| strings /usr/bin/free<br />
|-<br />
| find<br />
| 查找文件<br />
| {{man|1|find}}<br />
| find ~ -name myfile<br />
|-<br />
| mount<br />
| 挂载分区<br />
| {{man|8|mount}}<br />
| mount /dev/sdc1 /media/usb<br />
|-<br />
| df -h<br />
| 显示分区上的剩余空间<br />
| {{man|1|df}}<br />
|<br />
|-<br />
| ps -A<br />
| 显示所有正在运行的进程<br />
| {{man|1|ps}}<br />
|<br />
|-<br />
| killall<br />
| 杀死所有运行中的进程<br />
| {{man|1|killall}}<br />
|<br />
|-<br />
| ss -at<br />
| 显示开放的 TCP 连接列表<br />
| {{man|8|ss}}<br />
|<br />
|}<br />
<br />
== cat ==<br />
<br />
[[Wikipedia:cat_(Unix)|cat]] 是一个将文件内容发送到标准输出的标准 Unix 工具。<br />
<br />
* '''cat''' 并不内置于 shell ,不过若追求高性能,你会发现在很多情况下改用[[wikipedia:Redirection (computing)|重定向]]就很方便得许多,例如编写脚本。事实上,{{ic|$ < ''file''}} 的效果就如同 {{ic|$ cat ''file''}} 一样。<br />
<br />
* 按照以下结构可直接在某文件添加多行文字:<br />
<br />
{{bc|<br />
$ cat << EOF >> ''path/file''<br />
''first line''<br />
...<br />
''last line''<br />
EOF<br />
}}<br />
<br />
或者使用 {{ic|printf}}:<br />
<br />
{{bc|<br />
$ printf '%s\n' 'first line' ... 'last line'<br />
}}<br />
<br />
* 如果您希望能以倒读顺序显示文件内容,有个位于 coreutils 包中的工具叫 [[Wikipedia:tac (Unix)|tac]] (''cat'' 倒着写)。<br />
<br />
== chmod ==<br />
<br />
参阅 [[File permissions and attributes#Changing permissions]]。<br />
<br />
== chown ==<br />
<br />
参阅 [[File permissions and attributes#Changing ownership]]。<br />
<br />
== dd ==<br />
<br />
[[Wikipedia:dd (Unix)|dd]] 是在 unix 和 类 unix 系统中主要用于转换和拷贝文件的命令。<br />
<br />
与 ''cp'' 类似,默认情况下 ''dd'' 以块为单位拷贝文件,具有较低级别的 I/O流 控制功能。<br />
<br />
{{提示|默认情况下在任务完成前 dd 都没有输出,要监控操作的进度,可以添加 {{ic|1=status=progress}} 选项。}}<br />
<br />
更多信息参考 {{man|1|dd}} 或 [https://www.gnu.org/software/coreutils/dd 完整文档]。<br />
<br />
== find ==<br />
<br />
''find'' 是 {{Pkg|findutils}} 软件包的一部分, 它属于 {{Grp|base}} 软件包组。<br />
<br />
{{提示|{{Pkg|fd}} 是 {{ic|find}} 的一个更加简单、快速、友好的替代方案,它有着更合理的默认值(比如忽略隐藏文件、文件夹和 {{ic|.gitignore}} 等文件,可用 {{ic|fd PATTERN}} 代替 {{ic|find -iname '*PATTERN*'}})。它具有彩色输出(类似 {{ic|ls}}),unicode 支持,正则表达式等等。}}<br />
<br />
你可能希望 ''find'' 命令将一个文件名称作为参数,并在文件系统中搜索与该名称匹配的文件。下面的 [[#locate]] 程序可以专门做这件事。<br />
<br />
相反,find 需要一组目录,并将它们下面的每个文件与一组表达式进行匹配。这种设计为实现一些“能干的单行小程序”提供了强大的支持,而这是上述“直观”设计无法实现的。参阅 [http://mywiki.wooledge.org/UsingFind UsingFind] 来获取使用说明。<br />
<br />
==grep==<br />
<br />
[[Wikipedia:grep|grep]] (来自 [[Wikipedia:ed|ed]] 的 ''g/re/p'',''global/regular expression/print'')是最初给 Unix 写的命令行文字搜索工具,{{ic|grep}} 命令在文件或标准输入里搜索符合指定正则表达式模式的行,并把结果打印到标准输出。<br />
<br />
* 记住,''grep'' 能直接处理文件,所以用 {{ic|grep ''pattern'' ''file''}} 代替 {{ic|cat ''file'' {{!}} grep ''pattern''}} 即可。<br />
* 若要 grep 版本控制系统(VCS)的源代码,请使用专门的工具 {{Pkg|ripgrep}}、{{Pkg|the_silver_searcher}} 和 {{Pkg|ack}}。<br />
* 要在输出结果中显示行数,加上 {{ic|-n}} 选项。 <br />
<br />
{{注意|一些命令把错误输出到 {{man|3|stderr}},grep 就无法处理。这时,用 {{ic|''command'' 2>&1 {{!}} grep ''args''}} 或 (对于 Bash 4) {{ic|''command'' {{!}}& grep ''args''}} 将 ''stderr'' 重定向到 ''stdout''。参阅 [http://www.tldp.org/LDP/abs/html/io-redirection.html I/O 重定向]。}}<br />
<br />
参阅 [[Color output in console#grep]] 来启用彩色输出支持。<br />
<br />
== iconv ==<br />
<br />
''iconv'' 将转换一个文本的字符编码。<br />
<br />
下列命令将文件 {{ic|''foo''}} 从 ISO-8859-15 转换至 UTF-8,然后保存到 {{ic|''foo''.utf}}:<br />
<br />
$ iconv -f ISO-8859-15 -t UTF-8 ''foo'' > ''foo''.utf<br />
<br />
查阅 {{man|1|iconv}} 获取更多细节。<br />
<br />
=== 在原文件上转换 ===<br />
<br />
{{提示|如果你不想改变文件的修改时间,可以用 {{pkg|recode}} 代替 iconv。}}<br />
与 [[#sed|sed]] 不同,''iconv'' 没有提供直接转换文件的选项,但是 {{pkg|moreutils}} 包里面的 {{ic|sponge}} 可以帮忙:<br />
<br />
$ iconv -f WINDOWS-1251 -t UTF-8 ''foobar''.txt | sponge ''foobar''.txt<br />
<br />
更多细节请参阅 {{man|1|sponge}}。<br />
<br />
== ip ==<br />
<br />
[[Wikipedia:Iproute2|ip]] 显示关于网络设备,IP 地址,路由表和其他 Linux [[Wikipedia:Internet Protocol|IP]] 软件栈的对象信息。通过附加各种命令,你可以操纵或配置大多数对象。<br />
<br />
{{注意| ''ip'' 命令在 {{Pkg|iproute2}} 包中提供,这个包已经包含在 {{Grp|base}} 组。}}<br />
<br />
{| class="wikitable"<br />
! 对象 !! 作用 !! 手册页名称<br />
|-<br />
| ip addr || 协议地址管理 || {{man|8|ip-address}} <br />
|-<br />
| ip addrlabel || 协议地址标签管理 || {{man|8|ip-addrlabel}}<br />
|-<br />
| ip l2tp || tunnel Ethernet over IP (L2TPv3) || {{man|8|ip-l2tp}}<br />
|-<br />
| ip link || 网络设备配置 || {{man|8|ip-link}}<br />
|-<br />
| ip maddr || 多播地址管理 || {{man|8|ip-maddress}}<br />
|-<br />
| ip monitor || 监测 netlink 信息 || {{man|8|ip-monitor}}<br />
|-<br />
| ip mroute || 多播路由缓存管理 || {{man|8|ip-mroute}}<br />
|-<br />
| ip mrule || 多播路由策略数据库的规则 ||<br />
|-<br />
| ip neigh || 邻居/ARP 表管理|| {{man|8|ip-neighbour}}<br />
|-<br />
| ip netns || process network namespace management || {{man|8|ip-netns}}<br />
|-<br />
| ip ntable || 邻居表配置 || {{man|8|ip-ntable}}<br />
|-<br />
| ip route || 路由表管理 || {{man|8|ip-route}}<br />
|-<br />
| ip rule || 路由策略数据库管理 || {{man|8|ip-rule}}<br />
|-<br />
| ip tcp_metrics || 管理 TCP Metrics || {{man|8|ip-tcp_metrics}}<br />
|-<br />
| ip tunnel || 隧道配置 || {{man|8|ip-tunnel}}<br />
|-<br />
| ip tuntap || 管理 TUN/TAP 设备 ||<br />
|-<br />
| ip xfrm || 管理 IPsec 策略 || {{man|8|ip-xfrm}}<br />
|}<br />
<br />
{{ic|help}} 帮助命令可用于所有对象。例如,输入 {{ic|ip addr help}} 将显示地址的命令语法。高级用法参见 [http://www.policyrouting.org/iproute2.doc.html iproute2 documentation]。<br />
<br />
[[Network configuration]] 显示 ''ip'' 命令的多种常见任务中的使用方式。<br />
<br />
{{注意|你也许很熟悉 [[Wikipedia:ifconfig|ifconfig]] 命令,它用于旧版linux的接口配置。在 Arch Linux 中现已不赞成使用;应当用 ''ip'' 替代之。}}<br />
<br />
== less ==<br />
<br />
{{Expansion|less 是一个复杂的家伙,这一章应该介绍一些基本的 less 命令。}}<br />
<br />
[[Wikipedia:less (Unix)|less]] 是一个对文本文件内容进行分页显示的终端程序,它和其他的分页显示程序如 [[Wikipedia:more (command)|more]] 和 [[Wikipedia:pg (Unix)|pg]] 相似,但 ''less'' 提供了更高级的界面和更多的 [http://www.greenwoodsoftware.com/less/faq.html 功能]。<br />
<br />
参阅 [[List of applications#Terminal pagers]] 查找更多替代方案。<br />
<br />
== locate ==<br />
<br />
[[安装]] 软件包 {{Pkg|mlocate}}。包里包括了一个 {{ic|updatedb.timer}} 单元,用于每天更新数据库。这个 systemd 定时器在安装后就会 enable,如果不想重启系统,请手动 [[start]]。以 root 手动运行 ''updatedb'' 也可以更新数据库。默认会忽略 {{ic|/media}} 和 {{ic|/mnt}} 等路径,所以 ''locate'' 不会查找外置设备里的文件。详情请参考 {{man|8|updatedb}}。<br />
<br />
''locate'' 命令是一个快速查找文件系统的常用 Unix 工具。因为是从数据库查找而不是直接访问文件系统,所以速度比 [[wikipedia:Find|find]] 快很多。而缺点是在数据库更新后创建的新文件不会被搜索到。<br />
<br />
使用 ''locate'' 前需建立数据库,请先以 root 权限执行 {{ic|updatedb}}。<br />
<br />
详情参考 [http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ How locate works and rewrite it in one minute]。<br />
<br />
=== 用 Vim 代替 less 来分页 ===<br />
<br />
[[Vim]] 内置了脚本,可直接查看文本文件、压缩包或目录的内容。在你的 shell 配置文件添加以下内容:<br />
{{hc|~/.bashrc|2=alias less='/usr/share/vim/vim80/macros/less.sh'}}<br />
<br />
除了 ''less.sh'' 宏外还有另外一种用法,依赖于 {{ic|PAGER}} 环境变量。安装 {{Pkg|vimpager}} 并添加以下内容至shell配置文件:<br />
{{hc|~/.bashrc|2=<br />
export PAGER='vimpager'<br />
alias less=$PAGER<br />
}}<br />
<br />
这样,所有使用 {{ic|PAGER}} 环境变量的程序, 如 [[git]], 将使用 ''vim'' 作为分页程序。<br />
<br />
== ls ==<br />
<br />
[[Wikipedia:ls|ls]] 是一个Unix和类Unix系统中列出目录里的文件的一个命令。<br />
<br />
请参考 {{ic|info ls}} 或 [http://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html#ls-invocation 在线文档]。<br />
<br />
[https://the.exa.website exa] 相较于 {{ic|ls}} 和 {{ic|tree}} 是一个更加现代的、人性化的选择。它有更多的特性,例如将 [[Git]] 修改和文件名一同显示,在 {{ic|--long}} 模式中对每列进行不同的着色,或者在 {{ic|tree}} 视图中显示 {{ic|--long}} 模式元数据。 {{Pkg|exa}}<br />
<br />
=== “长格式”输出 ===<br />
<br />
{{ic|-l}} 选项显示一些元数据,例如:<br />
<br />
{{hc|$ ls -l ''/path/to/directory''|<br />
total 128<br />
drwxr-xr-x 2 archie users 4096 Jul 5 21:03 Desktop<br />
drwxr-xr-x 6 archie users 4096 Jul 5 17:37 Documents<br />
drwxr-xr-x 2 archie users 4096 Jul 5 13:45 Downloads<br />
-rw-rw-r-- 1 archie users 5120 Jun 27 08:28 customers.ods<br />
-rw-r--r-- 1 archie users 3339 Jun 27 08:28 todo<br />
-rwxr-xr-x 1 archie users 2048 Jul 6 12:56 myscript.sh<br />
}}<br />
<br />
{{ic|total}} 值表示目录中文件的总磁盘分配,默认情况下为块的数量。<br />
<br />
每个文件和子目录由一行表示,每行划分为 7 个字段,按以下顺序表示:<br />
<br />
* 类型与权限:<br />
** 首字母表示内部类型,参阅 {{ic|info ls -n "What information is listed"}} 来查看所有可能类型的介绍;例如:<br />
*** {{ic|-}} 表示一个普通文件;<br />
*** {{ic|d}} 表示一个目录,比如一个包括了其他文件和文件夹的文件夹;<br />
*** {{ic|p}} 表示一个命名的管道(又名 FIFO);<br />
*** {{ic|l}} 表示这是一个软链接;<br />
** 其他字母表示这个条目的 [[permissions|权限]];<br />
* 这个条目 [[Wikipedia:Hard link|硬链接]] 的数量;对文件而言这个数字至少是 1,即当前显示的文件引用本身;对文件夹而言这个数字至少是 2,当前显示的引用、对自己的引用({{ic|.}} 条目)以及这个文件夹中的子文件夹对父文件夹的引用({{ic|..}} 条目);<br />
* [[user|用户]] 名;<br />
* [[group|组]] 名;<br />
* 大小;<br />
* 修改时间;<br />
* 名称。<br />
<br />
=== 带空格的文件名被引号引起 ===<br />
<br />
默认情况下,包含空格的文件名和目录名会被单引号引起。要改变这一特性,请使用 {{ic|-N}} 或 {{ic|1=--quoting-style=literal}} 选项。另外,将 {{ic|QUOTING_STYLE}} [[environment variable|环境变量]] 设置为 {{ic|literal}} 也可以。[https://unix.stackexchange.com/questions/258679/why-is-ls-suddenly-surrounding-items-with-spaces-in-single-quotes]<br />
<br />
== lsblk ==<br />
<br />
{{man|8|lsblk}} 命令会显示所有连接到系统的 [[w:Device_file#Block_devices|块设备]] 和分区状况:<br />
<br />
{{hc|$ lsblk -f|<br />
NAME FSTYPE LABEL UUID MOUNTPOINT<br />
sda<br />
├─sda1 vfat C4DA-2C4D /boot<br />
├─sda2 swap 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 [SWAP]<br />
└─sda3 ext4 56adc99b-a61e-46af-aab7-a6d07e504652 /<br />
}}<br />
<br />
设备名开头定义块设备的类型,大部分现代的硬盘、[[SSD]] 和 USB 闪存设备都被识别为 SCSI disks ({{ic|sd}})。类型后面跟着给设备编号的小写字母,第一个设备从 {{ic|a}} 开始 ({{ic|sda}}),第二个设备就是 {{ic|b}} ({{ic|sdb}}),以此类推。每个设备上的 ''现有'' 分区将用数字编号,从 {{ic|1}} 开始 ({{ic|sda1}}),第二个分区就是 {{ic|2}} ({{ic|sda2}}),以此类推。在上面的示例中,只有一个设备可用 ({{ic|sda}}),该设备有三个分区 ({{ic|sda1}} 到 {{ic|sda3}}),每个分区具有不同的 [[file system|文件系统]]。<br />
<br />
其它块设备比如 {{ic|mmcblk}}(内存卡)或 {{ic|nvme}}([[NVMe]] 设备)。不清楚的设备类型可以在这里搜索到:[https://www.kernel.org/doc/Documentation/devices.txt kernel documentation]{{Dead link|2017|11|11}}。<br />
<br />
== mkdir ==<br />
<br />
[[Wikipedia:mkdir|mkdir]] (''make directory'') 可以创建目录。<br />
<br />
若需递归地创建一系列目录,就要用到 {{ic|-p}} 参数了,否则会出错。已经十分熟悉这原理的高级用户也可直接设为内置参数:<br />
<br />
alias mkdir='mkdir -p -v'<br />
<br />
{{ic|-v}} 参数可以使创建目录过程中的信息更为详细。<br />
<br />
不必使用 ''chmod'' 更改权限模式, 用 {{ic|-m}} 选项可直接定义新建目录的访问权限。<br />
<br />
{{提示|如果您仅仅只是想建个临时目录,也许用 [[Wikipedia:Temporary file|mktemp]]: {{ic|mktemp -d}} 更好。}}<br />
<br />
== mv ==<br />
<br />
[[Wikipedia:mv|mv]] (''move'') 可以移动或重命名文件和目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias mv='timeout 8 mv -iv'<br />
<br />
这个别名可以延迟 ''mv'' 到 8 秒后才生效,在覆盖已存在的文件时要求确认,列出正在进行的操作并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。<br />
<br />
== od ==<br />
<br />
[[Wikipedia:od (Unix)|od]] (''o''ctal ''d''ump) 命令在显示非人类可读格式时非常有用,比如程序的可执行文件,或者未格式化的设备的内容。参阅[https://www.gnu.org/software/coreutils/manual/html_node/od-invocation.html#od-invocation manual] 了解详情。<br />
<br />
== pv ==<br />
<br />
可以用 {{Pkg|pv}} (''pipe viewer'') 来监视管道中传递的数据,例如:<br />
<br />
# dd if=''/source/filestream'' | pv -''monitor_options'' -s ''size_of_file'' | dd of=''/destination/filestream''<br />
<br />
大多数情况下 {{ic|pv}} 可直接替代 {{ic|cat}}。<br />
<br />
== rm ==<br />
<br />
[[Wikipedia:rm_(Unix)|rm]] (''remove'') 用于删除文件或目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias rm='timeout 3 rm -Iv --one-file-system'<br />
<br />
这个别名可延迟 ''rm'' 到 3 秒后才生效,在删除三个以上的文件时要求确认,列出正在进行的操作,限于只在同一个文件系统生效并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。若你想在删除多文件时一一确认,用 {{ic|-I}} 代替 {{ic|-i}} 即可。<br />
<br />
Zsh 的使用者可在 {{ic|timeout}} 前加上 {{ic|noglob}},避免隐式扩展。<br />
<br />
若要移除空目录,使用 ''rmdir'',若内含文件则命令失败。<br />
<br />
== sed ==<br />
<br />
[[Wikipedia:sed|sed]] (''stream editor'') 是一条专门解析或替换文本的命令。<br />
<br />
这里有一系列现成的 ''sed'' [http://sed.sourceforge.net/sed1line.txt 示范]。<br />
<br />
{{提示|[[Wikipedia:AWK|AWK]] 和 [[Wikipedia:Perl|Perl]] 语言在这方面更为强大。}}<br />
<br />
== seq ==<br />
<br />
''seq'' (''sequence'') 是一条专门排列数字的命令。Shell 内置了该命令的其他替代方案,可以按照 [[Wikipedia:Seq (Unix)|Wikipedia]] 的说明进行练习。<br />
<br />
== ss ==<br />
<br />
''ss'' 是一个检查网络端口的实用程序,并且是 {{Grp|base}} 组中的 {{Pkg|iproute2}} 包的一部分。它具有与 [https://www.archlinux.org/news/deprecation-of-net-tools/ 弃用的] netstat 实用程序类似的功能。<br />
<br />
常用用法包括:<br />
<br />
显示所有 TCP Sockets,连同 service 名称:<br />
$ ss -at<br />
<br />
显示所有 TCP Sockets,连同端口号:<br />
$ ss -atn<br />
<br />
显示所有 UDP Sockets:<br />
$ ss -au<br />
<br />
更多信息请参考 {{Pkg|iproute2}} 包里的 {{man|8|ss}} 或 {{ic|ss.html}}。<br />
<br />
== tar ==<br />
<br />
作为早期的 Unix 存档格式,.tar 文件(称为“tarballs”)广泛用于类 Unix 操作系统中的打包操作。[[pacman]] 和 [[AUR]] 软件包都是压缩的 tarball,Arch 默认使用 [[GNU Project|GNU 的]] ''tar'' 程序。<br />
<br />
对于 ''.tar'' 文件,''tar'' 默认根据扩展名来解压文件:<br />
<br />
$ tar xvf ''file.EXTENSION''<br />
<br />
强制给定格式:<br />
<br />
{| class="wikitable"<br />
!文件类型 !! 解压命令<br />
|-<br />
|{{ic|''file''.tar}} || {{Ic|tar xvf ''file''.tar}}<br />
|-<br />
|{{ic|''file''.tgz}} || {{Ic|tar xvzf ''file''.tgz}}<br />
|-<br />
|{{ic|''file''.tar.gz}} || {{Ic|tar xvzf ''file''.tar.gz}}<br />
|-<br />
|{{ic|''file''.tar.bz}} || {{Ic|bzip -cd ''file''.bz <nowiki>|</nowiki> tar xvf -}}<br />
|-<br />
|{{ic|''file''.tar.bz2}} || {{Ic|tar xvjf ''file''.tar.bz2}}<br> {{Ic|bzip2 -cd ''file''.bz2 <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.xz}} || {{Ic|tar xvJf ''file''.tar.xz}}<br> {{Ic|xz -cd ''file''.xz <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.zst}} || {{Ic|tar -I zstd xvf ''file''.tar.zst}}<br />
|}<br />
<br />
这其中有部分 ''tar'' 的参数可以认为是历史遗留问题,但在执行某些特定的操作时仍然有用。更多细节请参阅 {{man|1|tar}}。<br />
<br />
== which ==<br />
<br />
[[wikipedia:Which_(Unix)|which]] 显示 shell 命令的完整路径。在下面的例子中 {{ic|ssh}} 的完整路径作为一个参数传递给了 {{ic|journalctl}}:<br />
<br />
# journalctl $(which sshd)<br />
<br />
== wipefs ==<br />
<br />
''wipefs'' 可以列出或擦除指定设备的 [[file system|文件系统]]、[[RAID]] 或 [[partition|分区表]] 标志 (magic strings)。它不会擦除文件系统本身,也不会擦除设备中的任何其他数据。<br />
<br />
更多信息请参阅 {{man|8|wipefs}}。<br />
<br />
例如,擦除 {{ic|/dev/sdb}} 设备中的所有标志并为每个标志在 {{ic|~/wipefs-sdb-''offset''.bak}} 创建一个备份文件:<br />
<br />
# wipefs --all --backup /dev/sdb<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.reddit.com/r/commandline/comments/19garq/a_sampling_of_coreutils_120/ A sampling of coreutils] [http://www.reddit.com/r/commandline/comments/19ge6v/a_sampling_of_coreutils_2040/ , part 2] [http://www.reddit.com/r/commandline/comments/19j1w3/a_sampling_of_coreutils_4060/ , part 3] - Overview of commands in coreutils<br />
* [https://www.gnu.org/software/coreutils/manual/coreutils.html GNU Coreutils online documentation]<br />
* [https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/ Learn the DD command]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Core_utilities_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=517552
Core utilities (简体中文)
2018-04-15T05:02:35Z
<p>Arisaka: Sync with English version.</p>
<hr />
<div>[[Category:Command-line (简体中文)]]<br />
[[en:Core utilities]]<br />
[[es:Core utilities]]<br />
[[fa:Core utilities]]<br />
[[it:Core utilities]]<br />
[[ja:Core Utilities]]<br />
[[ko:Core utilities]]<br />
[[pt:Core utilities]]<br />
[[ru:Core utilities]]<br />
[[zh-hant:Core utilities]]<br />
{{TranslationStatus (简体中文)|Core_Utilities|2018-04-15|516773}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Bash (简体中文)}}<br />
{{Related|Zsh (简体中文)}}<br />
{{Related2|General Recommendations (简体中文)|常用建议}}<br />
{{Related|GNU Project}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related|cron (简体中文)}}<br />
{{Related|man page (简体中文)}}<br />
{{Related|Securely wipe disk#shred}}<br />
{{Related|File permissions and attributes}}<br />
{{Related|Color output in console (简体中文)}}<br />
{{Related articles end}}<br />
<br />
本文涉及 GNU/Linux 系统的所谓的 "核心" 工具,比如 '''less''', '''ls''', 和 '''grep''',包括但不限于以上集成于 GNU {{Pkg|coreutils}} 中的工具。下文提供了关于这些实用工具颇为丰富的技巧和有帮助的其他信息。<br />
<br />
== 基本命令 ==<br />
<br />
下面表格列出了每个 Linux 用户都应该熟悉的命令,黑体命令是 shell 的一部分,其它的是 shell 调用的程序。命令的细节请阅读接下来的几节和''相关文章''。<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| man<br />
| 显示命令的手册页<br />
| {{man|7|man}}<br />
| man ed<br />
|-<br />
| '''cd'''<br />
| 变更目录<br />
| {{man|1p|cd}}<br />
| cd /etc/pacman.d<br />
|-<br />
| mkdir<br />
| 创建目录<br />
| {{man|1|mkdir}}<br />
| mkdir ~/newfolder<br />
|-<br />
| rmdir<br />
| 删除空目录<br />
| {{man|1|rmdir}}<br />
| rmdir ~/emptyfolder<br />
|-<br />
| rm<br />
| 删除文件<br />
| {{man|1|rm}}<br />
| rm ~/file.txt<br />
|-<br />
| rm -r<br />
| 删除目录和内容<br />
|<br />
| rm -r ~/.cache<br />
|-<br />
| ls<br />
| 显示文件<br />
| {{man|1|ls}}<br />
| ls *.mkv<br />
|-<br />
| ls -a<br />
| 显示隐藏文件<br />
|<br />
| ls -a /home/archie<br />
|-<br />
| ls -al<br />
| 显示隐藏文件和文件属性<br />
|<br />
|<br />
|-<br />
| mv<br />
| 移动文件<br />
| {{man|1|mv}}<br />
| mv ~/compressed.zip ~/archive/compressed2.zip<br />
|-<br />
| cp<br />
| 复制文件<br />
| {{man|1|cp}}<br />
| cp ~/.bashrc ~/.bashrc.bak<br />
|-<br />
| chmod +x<br />
| 设置文件为可执行文件<br />
| {{man|1|chmod}}<br />
| chmod +x ~/.local/bin/myscript.sh<br />
|-<br />
| cat<br />
| 显示文件内容<br />
| {{man|1|cat}}<br />
| cat /etc/hostname<br />
|-<br />
| strings<br />
| 显示文件中可打印的内容<br />
| {{man|1|strings}}<br />
| strings /usr/bin/free<br />
|-<br />
| find<br />
| 查找文件<br />
| {{man|1|find}}<br />
| find ~ -name myfile<br />
|-<br />
| mount<br />
| 挂载分区<br />
| {{man|8|mount}}<br />
| mount /dev/sdc1 /media/usb<br />
|-<br />
| df -h<br />
| 显示分区上的剩余空间<br />
| {{man|1|df}}<br />
|<br />
|-<br />
| ps -A<br />
| 显示所有正在运行的进程<br />
| {{man|1|ps}}<br />
|<br />
|-<br />
| killall<br />
| 杀死所有运行中的进程<br />
| {{man|1|killall}}<br />
|<br />
|-<br />
| ss -at<br />
| 显示开放的 TCP 连接列表<br />
| {{man|8|ss}}<br />
|<br />
|}<br />
<br />
== cat ==<br />
<br />
[[Wikipedia:cat_(Unix)|cat]] 是一个将文件内容发送到标准输出的标准 Unix 工具。<br />
<br />
* '''cat''' 并不内置于 shell ,不过若追求高性能,你会发现在很多情况下改用[[wikipedia:Redirection (computing)|重定向]]就很方便得许多,例如编写脚本。事实上,{{ic|$ < ''file''}} 的效果就如同 {{ic|$ cat ''file''}} 一样。<br />
<br />
* 按照以下结构可直接在某文件添加多行文字:<br />
<br />
{{bc|<br />
$ cat << EOF >> ''path/file''<br />
''first line''<br />
...<br />
''last line''<br />
EOF<br />
}}<br />
<br />
或者使用 {{ic|printf}}:<br />
<br />
{{bc|<br />
$ printf '%s\n' 'first line' ... 'last line'<br />
}}<br />
<br />
* 如果您希望能以倒读顺序显示文件内容,有个位于核心库中的工具叫 [[Wikipedia:tac (Unix)|tac]] (''cat'' 倒着写).<br />
<br />
== chmod ==<br />
<br />
参阅 [[File permissions and attributes#Changing permissions]]。<br />
<br />
== chown ==<br />
<br />
参阅 [[File permissions and attributes#Changing ownership]]。<br />
<br />
== dd ==<br />
<br />
[[Wikipedia:dd (Unix)|dd]] 是在 unix 和 类 unix 系统中主要用于转换和拷贝文件的命令。<br />
<br />
与 ''cp'' 类似,默认情况下 ''dd'' 以块为单位拷贝文件,具有较低级别的 I/O流 控制功能。<br />
<br />
{{提示|默认情况下在任务完成前 dd 都没有输出,要监控操作的进度,可以添加 {{ic|1=status=progress}} 选项。}}<br />
<br />
更多信息参考 {{man|1|dd}} 或 [https://www.gnu.org/software/coreutils/dd 完整文档]。<br />
<br />
== find ==<br />
<br />
''find'' 是 {{Pkg|findutils}} 软件包的一部分, 它属于 {{Grp|base}} 软件包组。<br />
<br />
{{提示|{{Pkg|fd}} 是 {{ic|find}} 的一个更加简单、快速、友好的替代方案,它有着更合理的默认值(比如忽略隐藏文件、文件夹和 {{ic|.gitignore}} 等文件,可用 {{ic|fd PATTERN}} 代替 {{ic|find -iname '*PATTERN*'}})。它具有彩色输出(类似 {{ic|ls}}),unicode 支持,正则表达式等等。}}<br />
<br />
你可能希望 ''find'' 命令将一个文件名称作为参数,并在文件系统中搜索与该名称匹配的文件。下面的 [[#locate]] 程序可以专门做这件事。<br />
<br />
相反,find 需要一组目录,并将它们下面的每个文件与一组表达式进行匹配。这种设计为实现一些“能干的单行小程序”提供了强大的支持,而这是上述“直观”设计无法实现的。参阅 [http://mywiki.wooledge.org/UsingFind UsingFind] 来获取使用说明。<br />
<br />
==grep==<br />
<br />
[[Wikipedia:grep|grep]] (来自 [[Wikipedia:ed|ed]] 的 ''g/re/p'',''global/regular expression/print'')是最初给 Unix 写的命令行文字搜索工具,{{ic|grep}} 命令在文件或标准输入里搜索符合指定正则表达式模式的行,并把结果打印到标准输出。<br />
<br />
* 记住,''grep'' 能直接处理文件,所以用 {{ic|grep ''pattern'' ''file''}} 代替 {{ic|cat ''file'' {{!}} grep ''pattern''}} 即可。<br />
* 若要 grep 版本控制系统(VCS)的源代码,请使用专门的工具 {{Pkg|ripgrep}}、{{Pkg|the_silver_searcher}} 和 {{Pkg|ack}}。<br />
* 要在输出结果中显示行数,加上 {{ic|-n}} 选项。 <br />
<br />
{{注意|一些命令把错误输出到 {{man|3|stderr}},grep 就无法处理。这时,用 {{ic|''command'' 2>&1 {{!}} grep ''args''}} 或 (对于 Bash 4) {{ic|''command'' {{!}}& grep ''args''}} 将 ''stderr'' 重定向到 ''stdout''。参阅 [http://www.tldp.org/LDP/abs/html/io-redirection.html I/O 重定向]。}}<br />
<br />
参阅 [[Color output in console#grep]] 来启用彩色输出支持。<br />
<br />
== iconv ==<br />
<br />
''iconv'' 将转换一个文本的字符编码。<br />
<br />
下列命令将文件 {{ic|''foo''}} 从 ISO-8859-15 转换至 UTF-8,然后保存到 {{ic|''foo''.utf}}:<br />
<br />
$ iconv -f ISO-8859-15 -t UTF-8 ''foo'' > ''foo''.utf<br />
<br />
查阅 {{man|1|iconv}} 获取更多细节。<br />
<br />
=== 在原文件上转换 ===<br />
<br />
{{提示|如果你不想改变文件的修改时间,可以用 {{pkg|recode}} 代替 iconv。}}<br />
与 [[#sed|sed]] 不同,''iconv'' 没有提供直接转换文件的选项,但是 {{pkg|moreutils}} 包里面的 {{ic|sponge}} 可以帮忙:<br />
<br />
$ iconv -f WINDOWS-1251 -t UTF-8 ''foobar''.txt | sponge ''foobar''.txt<br />
<br />
更多细节请参阅 {{man|1|sponge}}。<br />
<br />
== ip ==<br />
<br />
[[Wikipedia:Iproute2|ip]] 显示关于网络设备,IP 地址,路由表和其他 Linux [[Wikipedia:Internet Protocol|IP]] 软件栈的对象信息。通过附加各种命令,你可以操纵或配置大多数对象。<br />
<br />
{{注意| ''ip'' 命令在 {{Pkg|iproute2}} 包中提供,这个包已经包含在 {{Grp|base}} 组。}}<br />
<br />
{| class="wikitable"<br />
! 对象 !! 作用 !! 手册页名称<br />
|-<br />
| ip addr || 协议地址管理 || {{man|8|ip-address}} <br />
|-<br />
| ip addrlabel || 协议地址标签管理 || {{man|8|ip-addrlabel}}<br />
|-<br />
| ip l2tp || tunnel Ethernet over IP (L2TPv3) || {{man|8|ip-l2tp}}<br />
|-<br />
| ip link || 网络设备配置 || {{man|8|ip-link}}<br />
|-<br />
| ip maddr || 多播地址管理 || {{man|8|ip-maddress}}<br />
|-<br />
| ip monitor || 监测 netlink 信息 || {{man|8|ip-monitor}}<br />
|-<br />
| ip mroute || 多播路由缓存管理 || {{man|8|ip-mroute}}<br />
|-<br />
| ip mrule || 多播路由策略数据库的规则 ||<br />
|-<br />
| ip neigh || 邻居/ARP 表管理|| {{man|8|ip-neighbour}}<br />
|-<br />
| ip netns || process network namespace management || {{man|8|ip-netns}}<br />
|-<br />
| ip ntable || 邻居表配置 || {{man|8|ip-ntable}}<br />
|-<br />
| ip route || 路由表管理 || {{man|8|ip-route}}<br />
|-<br />
| ip rule || 路由策略数据库管理 || {{man|8|ip-rule}}<br />
|-<br />
| ip tcp_metrics || 管理 TCP Metrics || {{man|8|ip-tcp_metrics}}<br />
|-<br />
| ip tunnel || 隧道配置 || {{man|8|ip-tunnel}}<br />
|-<br />
| ip tuntap || 管理 TUN/TAP 设备 ||<br />
|-<br />
| ip xfrm || 管理 IPsec 策略 || {{man|8|ip-xfrm}}<br />
|}<br />
<br />
{{ic|help}} 帮助命令可用于所有对象。例如,输入 {{ic|ip addr help}} 将显示地址的命令语法。高级用法参见 [http://www.policyrouting.org/iproute2.doc.html iproute2 documentation]。<br />
<br />
[[Network configuration]] 显示 ''ip'' 命令的多种常见任务中的使用方式。<br />
<br />
{{注意|你也许很熟悉 [[Wikipedia:ifconfig|ifconfig]] 命令,它用于旧版linux的接口配置。在 Arch Linux 中现已不赞成使用;应当用 ''ip'' 替代之。}}<br />
<br />
== less ==<br />
<br />
{{Expansion|less 是一个复杂的家伙,这一章应该介绍一些基本的 less 命令。}}<br />
<br />
[[Wikipedia:less (Unix)|less]] 是一个对文本文件内容进行分页显示的终端程序,它和其他的分页显示程序如 [[Wikipedia:more (command)|more]] 和 [[Wikipedia:pg (Unix)|pg]] 相似,但 ''less'' 提供了更高级的界面和更多的 [http://www.greenwoodsoftware.com/less/faq.html 功能]。<br />
<br />
参阅 [[List of applications#Terminal pagers]] 查找更多替代方案。<br />
<br />
== locate ==<br />
<br />
[[安装]] 软件包 {{Pkg|mlocate}}。包里包括了一个 {{ic|updatedb.timer}} 单元,用于每天更新数据库。这个 systemd 定时器在安装后就会 enable,如果不想重启系统,请手动 [[start]]。以 root 手动运行 ''updatedb'' 也可以更新数据库。默认会忽略 {{ic|/media}} 和 {{ic|/mnt}} 等路径,所以 ''locate'' 不会查找外置设备里的文件。详情请参考 {{man|8|updatedb}}。<br />
<br />
''locate'' 命令是一个快速查找文件系统的常用 Unix 工具。因为是从数据库查找而不是直接访问文件系统,所以速度比 [[wikipedia:Find|find]] 快很多。而缺点是在数据库更新后创建的新文件不会被搜索到。<br />
<br />
使用 ''locate'' 前需建立数据库,请先以 root 权限执行 {{ic|updatedb}}。<br />
<br />
详情参考 [http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ How locate works and rewrite it in one minute]。<br />
<br />
=== 用 Vim 代替 less 来分页 ===<br />
<br />
[[Vim]] 内置了脚本,可直接查看文本文件、压缩包或目录的内容。在你的 shell 配置文件添加以下内容:<br />
{{hc|~/.bashrc|2=alias less='/usr/share/vim/vim80/macros/less.sh'}}<br />
<br />
除了 ''less.sh'' 宏外还有另外一种用法,依赖于 {{ic|PAGER}} 环境变量。安装 {{Pkg|vimpager}} 并添加以下内容至shell配置文件:<br />
{{hc|~/.bashrc|2=<br />
export PAGER='vimpager'<br />
alias less=$PAGER<br />
}}<br />
<br />
这样,所有使用 {{ic|PAGER}} 环境变量的程序, 如 [[git]], 将使用 ''vim'' 作为分页程序。<br />
<br />
== ls ==<br />
<br />
[[Wikipedia:ls|ls]] 是一个Unix和类Unix系统中列出目录里的文件的一个命令。<br />
<br />
请参考 {{ic|info ls}} 或 [http://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html#ls-invocation 在线文档]。<br />
<br />
[https://the.exa.website exa] 相较于 {{ic|ls}} 和 {{ic|tree}} 是一个更加现代的、人性化的选择。它有更多的特性,例如将 [[Git]] 修改和文件名一同显示,在 {{ic|--long}} 模式中对每列进行不同的着色,或者在 {{ic|tree}} 视图中显示 {{ic|--long}} 模式元数据。 {{Pkg|exa}}<br />
<br />
=== “长格式”输出 ===<br />
<br />
{{ic|-l}} 选项显示一些元数据,例如:<br />
<br />
{{hc|$ ls -l ''/path/to/directory''|<br />
total 128<br />
drwxr-xr-x 2 archie users 4096 Jul 5 21:03 Desktop<br />
drwxr-xr-x 6 archie users 4096 Jul 5 17:37 Documents<br />
drwxr-xr-x 2 archie users 4096 Jul 5 13:45 Downloads<br />
-rw-rw-r-- 1 archie users 5120 Jun 27 08:28 customers.ods<br />
-rw-r--r-- 1 archie users 3339 Jun 27 08:28 todo<br />
-rwxr-xr-x 1 archie users 2048 Jul 6 12:56 myscript.sh<br />
}}<br />
<br />
{{ic|total}} 值表示目录中文件的总磁盘分配,默认情况下为块的数量。<br />
<br />
每个文件和子目录由一行表示,每行划分为 7 个字段,按以下顺序表示:<br />
<br />
* 类型与权限:<br />
** 首字母表示内部类型,参阅 {{ic|info ls -n "What information is listed"}} 来查看所有可能类型的介绍;例如:<br />
*** {{ic|-}} 表示一个普通文件;<br />
*** {{ic|d}} 表示一个目录,比如一个包括了其他文件和文件夹的文件夹;<br />
*** {{ic|p}} 表示一个命名的管道(又名 FIFO);<br />
*** {{ic|l}} 表示这是一个软链接;<br />
** 其他字母表示这个条目的 [[permissions|权限]];<br />
* 这个条目 [[Wikipedia:Hard link|硬链接]] 的数量;对文件而言这个数字至少是 1,即当前显示的文件引用本身;对文件夹而言这个数字至少是 2,当前显示的引用、对自己的引用({{ic|.}} 条目)以及这个文件夹中的子文件夹对父文件夹的引用({{ic|..}} 条目);<br />
* [[user|用户]] 名;<br />
* [[group|组]] 名;<br />
* 大小;<br />
* 修改时间;<br />
* 名称。<br />
<br />
=== 带空格的文件名被引号引起 ===<br />
<br />
默认情况下,包含空格的文件名和目录名会被单引号引起。要改变这一特性,请使用 {{ic|-N}} 或 {{ic|1=--quoting-style=literal}} 选项。另外,将 {{ic|QUOTING_STYLE}} [[environment variable|环境变量]] 设置为 {{ic|literal}} 也可以。[https://unix.stackexchange.com/questions/258679/why-is-ls-suddenly-surrounding-items-with-spaces-in-single-quotes]<br />
<br />
== lsblk ==<br />
<br />
{{man|8|lsblk}} 命令会显示所有连接到系统的 [[w:Device_file#Block_devices|块设备]] 和分区状况:<br />
<br />
{{hc|$ lsblk -f|<br />
NAME FSTYPE LABEL UUID MOUNTPOINT<br />
sda<br />
├─sda1 vfat C4DA-2C4D /boot<br />
├─sda2 swap 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 [SWAP]<br />
└─sda3 ext4 56adc99b-a61e-46af-aab7-a6d07e504652 /<br />
}}<br />
<br />
设备名开头定义块设备的类型,大部分现代的硬盘、[[SSD]] 和 USB 闪存设备都被识别为 SCSI disks ({{ic|sd}})。类型后面跟着给设备编号的小写字母,第一个设备从 {{ic|a}} 开始 ({{ic|sda}}),第二个设备就是 {{ic|b}} ({{ic|sdb}}),以此类推。每个设备上的 ''现有'' 分区将用数字编号,从 {{ic|1}} 开始 ({{ic|sda1}}),第二个分区就是 {{ic|2}} ({{ic|sda2}}),以此类推。在上面的示例中,只有一个设备可用 ({{ic|sda}}),该设备有三个分区 ({{ic|sda1}} 到 {{ic|sda3}}),每个分区具有不同的 [[file system|文件系统]]。<br />
<br />
其它块设备比如 {{ic|mmcblk}}(内存卡)或 {{ic|nvme}}([[NVMe]] 设备)。不清楚的设备类型可以在这里搜索到:[https://www.kernel.org/doc/Documentation/devices.txt kernel documentation]{{Dead link|2017|11|11}}。<br />
<br />
== mkdir ==<br />
<br />
[[Wikipedia:mkdir|mkdir]] (''make directory'') 可以创建目录。<br />
<br />
若需递归地创建一系列目录,就要用到 {{ic|-p}} 参数了,否则会出错。已经十分熟悉这原理的高级用户也可直接设为内置参数:<br />
<br />
alias mkdir='mkdir -p -v'<br />
<br />
{{ic|-v}} 参数可以使创建目录过程中的信息更为详细。<br />
<br />
不必使用 ''chmod'' 更改权限模式, 用 {{ic|-m}} 选项可直接定义新建目录的访问权限。<br />
<br />
{{提示|如果您仅仅只是想建个临时目录,也许用 [[Wikipedia:Temporary file|mktemp]]: {{ic|mktemp -d}} 更好。}}<br />
<br />
== mv ==<br />
<br />
[[Wikipedia:mv|mv]] (''move'') 可以移动或重命名文件和目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias mv='timeout 8 mv -iv'<br />
<br />
这个别名可以延迟 ''mv'' 到 8 秒后才生效,在覆盖已存在的文件时要求确认,列出正在进行的操作并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。<br />
<br />
== od ==<br />
<br />
[[Wikipedia:od (Unix)|od]] (''o''ctal ''d''ump) 命令在显示非人类可读格式时非常有用,比如程序的可执行文件,或者未格式化的设备的内容。参阅[https://www.gnu.org/software/coreutils/manual/html_node/od-invocation.html#od-invocation manual] 了解详情。<br />
<br />
== pv ==<br />
<br />
可以用 {{Pkg|pv}} (''pipe viewer'') 来监视管道中传递的数据,例如:<br />
<br />
# dd if=''/source/filestream'' | pv -''monitor_options'' -s ''size_of_file'' | dd of=''/destination/filestream''<br />
<br />
大多数情况下 {{ic|pv}} 可直接替代 {{ic|cat}}。<br />
<br />
== rm ==<br />
<br />
[[Wikipedia:rm_(Unix)|rm]] (''remove'') 用于删除文件或目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias rm='timeout 3 rm -Iv --one-file-system'<br />
<br />
这个别名可延迟 ''rm'' 到 3 秒后才生效,在删除三个以上的文件时要求确认,列出正在进行的操作,限于只在同一个文件系统生效并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。若你想在删除多文件时一一确认,用 {{ic|-I}} 代替 {{ic|-i}} 即可。<br />
<br />
Zsh 的使用者可在 {{ic|timeout}} 前加上 {{ic|noglob}},避免隐式扩展。<br />
<br />
若要移除空目录,使用 ''rmdir'',若内含文件则命令失败。<br />
<br />
== sed ==<br />
<br />
[[Wikipedia:sed|sed]] (''stream editor'') 是一条专门解析或替换文本的命令。<br />
<br />
这里有一系列现成的 ''sed'' [http://sed.sourceforge.net/sed1line.txt 示范]。<br />
<br />
{{提示|[[Wikipedia:AWK|AWK]] 和 [[Wikipedia:Perl|Perl]] 语言在这方面更为强大。}}<br />
<br />
== seq ==<br />
<br />
''seq'' (''sequence'') 是一条专门排列数字的命令。Shell 内置了该命令的其他替代方案,可以按照 [[Wikipedia:Seq (Unix)|Wikipedia]] 的说明进行练习。<br />
<br />
== ss ==<br />
<br />
''ss'' 是一个检查网络端口的实用程序,并且是 {{Grp|base}} 组中的 {{Pkg|iproute2}} 包的一部分。它具有与 [https://www.archlinux.org/news/deprecation-of-net-tools/ 弃用的] netstat 实用程序类似的功能。<br />
<br />
常用用法包括:<br />
<br />
显示所有 TCP Sockets,连同 service 名称:<br />
$ ss -at<br />
<br />
显示所有 TCP Sockets,连同端口号:<br />
$ ss -atn<br />
<br />
显示所有 UDP Sockets:<br />
$ ss -au<br />
<br />
更多信息请参考 {{Pkg|iproute2}} 包里的 {{man|8|ss}} 或 {{ic|ss.html}}。<br />
<br />
== tar ==<br />
<br />
作为早期的 Unix 存档格式,.tar 文件(称为“tarballs”)广泛用于类 Unix 操作系统中的打包操作。[[pacman]] 和 [[AUR]] 软件包都是压缩的 tarball,Arch 默认使用 [[GNU Project|GNU 的]] ''tar'' 程序。<br />
<br />
对于 ''.tar'' 文件,''tar'' 默认根据扩展名来解压文件:<br />
<br />
$ tar xvf ''file.EXTENSION''<br />
<br />
强制给定格式:<br />
<br />
{| class="wikitable"<br />
!文件类型 !! 解压命令<br />
|-<br />
|{{ic|''file''.tar}} || {{Ic|tar xvf ''file''.tar}}<br />
|-<br />
|{{ic|''file''.tgz}} || {{Ic|tar xvzf ''file''.tgz}}<br />
|-<br />
|{{ic|''file''.tar.gz}} || {{Ic|tar xvzf ''file''.tar.gz}}<br />
|-<br />
|{{ic|''file''.tar.bz}} || {{Ic|bzip -cd ''file''.bz <nowiki>|</nowiki> tar xvf -}}<br />
|-<br />
|{{ic|''file''.tar.bz2}} || {{Ic|tar xvjf ''file''.tar.bz2}}<br> {{Ic|bzip2 -cd ''file''.bz2 <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.xz}} || {{Ic|tar xvJf ''file''.tar.xz}}<br> {{Ic|xz -cd ''file''.xz <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.zst}} || {{Ic|tar -I zstd xvf ''file''.tar.zst}}<br />
|}<br />
<br />
这其中有部分 ''tar'' 的参数可以认为是历史遗留问题,但在执行某些特定的操作时仍然有用。更多细节请参阅 {{man|1|tar}}。<br />
<br />
== which ==<br />
<br />
[[wikipedia:Which_(Unix)|which]] 显示 shell 命令的完整路径。在下面的例子中 {{ic|ssh}} 的完整路径作为一个参数传递给了 {{ic|journalctl}}:<br />
<br />
# journalctl $(which sshd)<br />
<br />
== wipefs ==<br />
<br />
''wipefs'' 可以列出或擦除指定设备的 [[file system|文件系统]]、[[RAID]] 或 [[partition|分区表]] 标志 (magic strings)。它不会擦除文件系统本身,也不会擦除设备中的任何其他数据。<br />
<br />
更多信息请参阅 {{man|8|wipefs}}。<br />
<br />
例如,擦除 {{ic|/dev/sdb}} 设备中的所有标志并为每个标志在 {{ic|~/wipefs-sdb-''offset''.bak}} 创建一个备份文件:<br />
<br />
# wipefs --all --backup /dev/sdb<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.reddit.com/r/commandline/comments/19garq/a_sampling_of_coreutils_120/ A sampling of coreutils] [http://www.reddit.com/r/commandline/comments/19ge6v/a_sampling_of_coreutils_2040/ , part 2] [http://www.reddit.com/r/commandline/comments/19j1w3/a_sampling_of_coreutils_4060/ , part 3] - Overview of commands in coreutils<br />
* [https://www.gnu.org/software/coreutils/manual/coreutils.html GNU Coreutils online documentation]<br />
* [https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/ Learn the DD command]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Git&diff=516679
Git
2018-04-10T12:35:16Z
<p>Arisaka: Repair link to "Git Tools - Revision Selection".</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[es:Git]]<br />
[[ja:Git]]<br />
[[zh-hans:Git]]<br />
{{Related articles start}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}<br />
<br />
[[wikipedia:Git (software)|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain [[AUR]] packages, as well as many other projects, including sources for the Linux kernel. <br />
<br />
== Installation ==<br />
<br />
[[Install]] the {{Pkg|git}} package. For the development version, install the {{AUR|git-git}} package. Check the optional dependencies when using tools such as ''git svn'', ''git gui'' and ''gitk''.<br />
<br />
{{Note|To enable spell checking in ''git-gui'', {{Pkg|aspell}} is required, along with the dictionary corresponding to the {{ic|LC_MESSAGES}} [[environment variable]]. See {{Bug|28181}} and the [[aspell]] article.}}<br />
<br />
== Configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@example.com''"<br />
<br />
See [https://git-scm.com/book/en/Getting-Started-First-Time-Git-Setup Getting Started - First-Time Git Setup].<br />
<br />
See [[#Tips and tricks]] for more settings.<br />
<br />
== Usage ==<br />
<br />
A Git repository is contained in a {{ic|.git}} directory, which holds the revision history and other metadata. The directory tracked by the repository, by default the parent directory, is called the working directory. Changes in the working tree need to be staged before they can be recorded (committed) to the repository. Git also lets you restore, previously committed, working tree files.<br />
<br />
See [https://git-scm.com/book/en/Getting-Started-Git-Basics Getting Started - Git Basics].<br />
<br />
=== Getting a Git repository ===<br />
<br />
* Initialize a repository<br />
:{{ic|git init}}, see {{man|1|git-init}}<br />
* Clone an existing repository<br />
:{{ic|git clone ''repository''}}, see {{man|1|git-clone}}<br />
<br />
=== Recording changes ===<br />
<br />
Git projects have a staging area, which is an {{ic|index}} file in your Git directory, that stores the changes that will go into your next commit. To record a modified file you therefore firstly need to add it to the index (stage it). The {{ic|git commit}} command then stores the current index in a new commit.<br />
<br />
==== Staging changes ====<br />
<br />
* Add working tree changes to the index<br />
:{{ic|git add ''pathspec''}}, see {{man|1|git-add}}<br />
* Remove changes from the index<br />
:{{ic|git reset ''pathspec''}}, see {{man|1|git-reset}}<br />
* Show changes to be committed, unstaged changes and untracked files<br />
:{{ic|git status}}, see {{man|1|git-status}}<br />
<br />
You can tell Git to ignore certain untracked files using {{ic|.gitignore}} files, see {{man|5|gitignore}}.<br />
<br />
Git does not track file movement. Move detection during merges is based only on content similarity. The {{ic|git mv}} command is just there for convenience and is equivalent to:<br />
<br />
$ mv -i foo bar<br />
$ git reset -- foo<br />
$ git add bar<br />
<br />
==== Committing changes ====<br />
<br />
The {{ic|git commit}} command records the staged changes to the repository, see {{man|1|git-commit}}.<br />
<br />
* {{ic|-m}} – supply the commit message as an argument, instead of composing it in your default text editor<br />
* {{ic|-a}} – automatically stage files that have been modified or deleted (does not add untracked files)<br />
* {{ic|--amend}} – redo the last commit, amending the commit message or the committed files<br />
<br />
{{Tip|Always commit small changes frequently and with meaningful messages.}}<br />
<br />
==== Revision selection ====<br />
<br />
Git offers multiple ways to specify revisions, see {{man|7|gitrevisions}} and [https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection Revision Selection].<br />
<br />
Many Git commands take revisions as arguments. A commit can be identified by any of the following:<br />
<br />
* SHA-1 hash of the commit (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used ''git checkout'' to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== Viewing changes ====<br />
<br />
Show differences between commits:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
or between staging area and working tree:<br />
<br />
$ git diff<br />
<br />
View history of changes (where "''-N''" is the number of latest commits):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
=== Undoing things ===<br />
<br />
* {{ic|git reset}} - reset current HEAD to the specified state, see {{man|1|git-reset}}<br />
<br />
* {{ic|git checkout}} - to restore working tree files, see {{man|1|git-checkout}}<br />
<br />
=== Branching ===<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch.<br />
<br />
Create a branch, whose name accurately reflects its purpose:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
List branches:<br />
<br />
$ git branch<br />
<br />
Switch branches:<br />
<br />
$ git checkout ''branch''<br />
<br />
Create and switch:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
Merge a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with {{ic|git diff}}. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See [[#Dealing with merges]] below.<br />
<br />
When done with a branch, delete it with:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
A typical Git work-flow is:<br />
<br />
# Create a new repository or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to merge them. This is called a ''pull request''.<br />
<br />
To pull:<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command combines both ''fetching'' and ''merging''. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can pick the changes wanting to be incorporated. Using the ''fetch'' option (and ''log'' option with a special {{ic|FETCH_HEAD}} symbol), the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are aliases for tracked remote repositories. A ''label'' is created defining a location. These labels are used to identify frequently accessed repositories.<br />
<br />
Create a remote:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
Fetch a remote:<br />
<br />
$ git fetch ''label''<br />
<br />
Show differences between master and a remote master:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
View remotes for the current repository:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
After being given rights from the original authors, push changes with:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When ''git clone'' is performed, it records the original location and gives it a remote name of {{ic|origin}}.<br />
<br />
So what ''typically'' is done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|-u}} ({{ic|--set-upstream-to}}) option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. The ''checksum'' is the "object name" of a commit object, typically a 40-character SHA-1 hash.<br />
<br />
For history with a long message (where the "''checksum''" can be truncated, as long as it is unique):<br />
<br />
$ git show (''checksum'')<br />
<br />
Search for ''pattern'' in tracked files:<br />
<br />
$ git grep ''pattern''<br />
<br />
Search in {{ic|.c}} and {{ic|.h}} files:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== Tagging ====<br />
<br />
Tag commits for versioning:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tagging'' is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used, because they get added to the Git database.<br />
<br />
Tag the current commit with:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
List tags:<br />
<br />
$ git tag -l<br />
<br />
Delete a tag:<br />
<br />
$ git tag -d 2.08<br />
<br />
Update remote tags:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the ''git rebase'' {{ic|--interactive}} option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) back to, but excluding, commit {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Tips and tricks ==<br />
<br />
=== Using git-config ===<br />
<br />
Git reads its configuration from three INI-type configuration files:<br />
<br />
* {{ic|/etc/gitconfig}} for system-wide defaults<br />
* {{ic|~/.gitconfig}} for user-specific configuration<br />
* {{ic|.git/config}} for repository-specific configuration<br />
<br />
These files can be edited directly, but the usual method is to use ''git config'', as shown in the examples below.<br />
<br />
List the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
Set the default editor from [[vim]] to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
Set the default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
Set a different tool for ''git difftool'' (''meld'' by default):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See {{man|1|git-config}} and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Adopting a good etiquette ===<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
=== Speeding up authentication ===<br />
<br />
You may wish to avoid the hassle of authenticating interactively at every push to the Git server.<br />
<br />
* If you are authenticating with SSH keys, use an [[SSH agent]]. See also [[SSH#Speeding up SSH]] and [[SSH#Keep alive]].<br />
* If you are authenticating with username and password, switch to [[SSH keys]] if the server supports SSH, otherwise try [https://git-scm.com/docs/git-credential-cache git-credential-cache] or [https://git-scm.com/docs/git-credential-store git-credential-store].<br />
<br />
=== Protocol Defaults ===<br />
<br />
If you are running a multiplexed SSH connection as shown above, Git over SSH might be faster than HTTPS. Also, some servers (like the AUR) only allow pushing via SSH. For example, the following config will set Git over SSH for any repository hosted on the AUR.<br />
<br />
{{hc|~/.gitconfig|<nowiki><br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
</nowiki>}}<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there is a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
Alternatively, you can use one of git shell prompt customization packages from [[AUR]] such as {{AUR|bash-git-prompt}} or {{AUR|gittify}}.<br />
<br />
=== Visual representation ===<br />
<br />
To get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
''git log'' with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
''git log'' graph alias (i.e. ''git graph'' will show a decorated version):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
=== Commit tips ===<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Signing commits ===<br />
<br />
Git allows commits and tags to be signed using [[GnuPG]], see [https://git-scm.com/book/en/Git-Tools-Signing-Your-Work Signing Your Work].<br />
<br />
{{Note|To use {{Pkg|pinentry}} curses for GPG signing make sure to {{ic|1=export GPG_TTY=$(tty)}} (alternatively use pinentry-tty) otherwise the signing step will fail if GPG is currently in a locked state (since it cannot prompt for pin).}}<br />
<br />
To configure Git to automatically sign commits:<br />
<br />
$ git config --global commit.gpgSign true<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master (''git clone'' only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
=== Directly sending patches to a mailing list ===<br />
<br />
If you want to send patches directly to a mailing list, you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.<br />
<br />
Make sure you have configured your username and e-mail address, see [[#Configuration]].<br />
<br />
Configure your e-mail settings:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.example.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@example.com''<br />
<br />
Now you should be able to send the patch to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository (here 443 as example):<br />
<br />
{{hc|.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
You are able to secure the SSH user account even more allowing only push and pull commands on this user account. This is done by replacing the default login shell by git-shell. Described in [https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server Setting Up the Server].<br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
This assumes your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like: {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}}.<br />
<br />
{{Note|Make sure that Apache can read and write to your repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP<br />
* https://git-scm.com/docs/git-http-backend<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol is not encrypted or authenticated, and only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to<br />
[https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill] for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* Git man pages, see {{man|1|git}}<br />
* [https://git-scm.com/book/en/ Pro Git book]<br />
* [https://git.github.io/git-reference/ Git Reference] by GitHub<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]<br />
* [https://wiki.videolan.org/Git VideoLAN wiki article]<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Core_utilities_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516657
Core utilities (简体中文)
2018-04-10T08:36:27Z
<p>Arisaka: Change category like English version.</p>
<hr />
<div>[[Category:Command-line (简体中文)]]<br />
[[en:Core utilities]]<br />
[[es:Core utilities]]<br />
[[fa:Core utilities]]<br />
[[it:Core utilities]]<br />
[[ja:Core Utilities]]<br />
[[ko:Core utilities]]<br />
[[pt:Core utilities]]<br />
[[ru:Core utilities]]<br />
[[zh-hant:Core utilities]]<br />
{{TranslationStatus (简体中文)|Core_Utilities|2018-04-10|516600}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Bash (简体中文)}}<br />
{{Related|Zsh (简体中文)}}<br />
{{Related2|General Recommendations (简体中文)|常用建议}}<br />
{{Related|GNU Project}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related|cron (简体中文)}}<br />
{{Related|man page (简体中文)}}<br />
{{Related|Securely wipe disk#shred}}<br />
{{Related|File permissions and attributes}}<br />
{{Related|Color output in console (简体中文)}}<br />
{{Related articles end}}<br />
<br />
本文涉及 GNU/Linux 系统的所谓的 "核心" 工具,比如 '''less''', '''ls''', 和 '''grep''',包括但不限于以上集成于 GNU {{Pkg|coreutils}} 中的工具。下文提供了关于这些实用工具颇为丰富的技巧和有帮助的其他信息。<br />
<br />
== 基本命令 ==<br />
<br />
下面表格列出了每个 Linux 用户都应该熟悉的命令,黑体命令是 shell 的一部分,其它的是 shell 调用的程序。命令的细节请阅读接下来的几节和''相关文章''。<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| man<br />
| 显示命令的手册页<br />
| {{man|7|man}}<br />
| man ed<br />
|-<br />
| '''cd'''<br />
| 变更目录<br />
| {{man|1p|cd}}<br />
| cd /etc/pacman.d<br />
|-<br />
| mkdir<br />
| 创建目录<br />
| {{man|1|mkdir}}<br />
| mkdir ~/newfolder<br />
|-<br />
| rmdir<br />
| 删除空目录<br />
| {{man|1|rmdir}}<br />
| rmdir ~/emptyfolder<br />
|-<br />
| rm<br />
| 删除文件<br />
| {{man|1|rm}}<br />
| rm ~/file.txt<br />
|-<br />
| rm -r<br />
| 删除目录和内容<br />
|<br />
| rm -r ~/.cache<br />
|-<br />
| ls<br />
| 显示文件<br />
| {{man|1|ls}}<br />
| ls *.mkv<br />
|-<br />
| ls -a<br />
| 显示隐藏文件<br />
|<br />
| ls -a /home/archie<br />
|-<br />
| ls -al<br />
| 显示隐藏文件和文件属性<br />
|<br />
|<br />
|-<br />
| mv<br />
| 移动文件<br />
| {{man|1|mv}}<br />
| mv ~/compressed.zip ~/archive/compressed2.zip<br />
|-<br />
| cp<br />
| 复制文件<br />
| {{man|1|cp}}<br />
| cp ~/.bashrc ~/.bashrc.bak<br />
|-<br />
| chmod +x<br />
| 设置文件为可执行文件<br />
| {{man|1|chmod}}<br />
| chmod +x ~/.local/bin/myscript.sh<br />
|-<br />
| cat<br />
| 显示文件内容<br />
| {{man|1|cat}}<br />
| cat /etc/hostname<br />
|-<br />
| strings<br />
| 显示文件中可打印的内容<br />
| {{man|1|strings}}<br />
| strings /usr/bin/free<br />
|-<br />
| find<br />
| 查找文件<br />
| {{man|1|find}}<br />
| find ~ -name myfile<br />
|-<br />
| mount<br />
| 挂载分区<br />
| {{man|8|mount}}<br />
| mount /dev/sdc1 /media/usb<br />
|-<br />
| df -h<br />
| 显示分区上的剩余空间<br />
| {{man|1|df}}<br />
|<br />
|-<br />
| ps -A<br />
| 显示所有正在运行的进程<br />
| {{man|1|ps}}<br />
|<br />
|-<br />
| killall<br />
| 杀死所有运行中的进程<br />
| {{man|1|killall}}<br />
|<br />
|-<br />
| ss -at<br />
| 显示开放的 TCP 连接列表<br />
| {{man|8|ss}}<br />
|<br />
|}<br />
<br />
== cat ==<br />
<br />
[[Wikipedia:cat_(Unix)|cat]] 是一个能够连接并显示多文件的标准 Unix 工具。<br />
<br />
* '''cat''' 并不内置于 shell ,不过若追求高性能,你会发现在很多情况下改用[[wikipedia:Redirection (computing)|重定向]]就很方便得许多,例如编写脚本。事实上,{{ic|$ < ''file''}} 的效果就如同 {{ic|$ cat ''file''}} 一样。<br />
<br />
* 按照以下结构可直接在某文件添加多行文字:<br />
<br />
{{bc|<br />
$ cat << EOF >> ''path/file''<br />
''first line''<br />
...<br />
''last line''<br />
EOF<br />
}}<br />
<br />
或者使用 {{ic|printf}}:<br />
<br />
{{bc|<br />
$ printf '%s\n' 'first line' ... 'last line'<br />
}}<br />
<br />
* 如果您希望能以倒读顺序显示文件内容,有个工具叫 [[Wikipedia:tac (Unix)|tac]] (''cat'' 倒着写).<br />
<br />
== dd ==<br />
<br />
[[Wikipedia:dd (Unix)|dd]] 是在 unix 和 类 unix 系统中主要用于转换和拷贝文件的命令。<br />
<br />
与 ''cp'' 类似,默认情况下 ''dd'' 以块为单位拷贝文件,具有较低级别的 I/O流 控制功能。<br />
<br />
{{提示|默认情况下在任务完成前 dd 都没有输出,要监控操作的进度,可以添加 {{ic|1=status=progress}} 选项。}}<br />
<br />
更多信息参考 {{man|1|dd}} 或 [https://www.gnu.org/software/coreutils/dd 完整文档]。<br />
<br />
==grep==<br />
<br />
[[Wikipedia:grep|grep]] (来自 [[Wikipedia:ed|ed]] 的 ''g/re/p'',''global/regular expression/print'')是最初给 Unix 写的命令行文字搜索工具,{{ic|grep}} 命令在文件或标准输入里搜索符合指定正则表达式模式的行,并把结果打印到标准输出。<br />
<br />
* 记住,''grep'' 能直接处理文件,所以用 {{ic|grep ''pattern'' ''file''}} 代替 {{ic|cat ''file'' <nowiki>|</nowiki> grep ''pattern''}} 即可。<br />
* 若要 grep 版本控制系统(VCS)的源代码,请使用专门的工具 {{Pkg|ripgrep}}、{{Pkg|the_silver_searcher}} 和 {{Pkg|ack}}。<br />
* 要在输出结果中显示行数,加上 {{ic|-n}} 选项。 <br />
<br />
{{注意|一些命令把错误输出到 {{man|3|stderr}},grep 就无法处理。这时,用 {{ic|''command'' 2>&1 {{!}} grep ''args''}} 或 (对于 Bash 4) {{ic|''command'' {{!}}& grep ''args''}} 将 ''stderr'' 重定向到 ''stdout''。参阅 [http://www.tldp.org/LDP/abs/html/io-redirection.html I/O 重定向]。}}<br />
<br />
参阅 [[Color output in console#grep]] 来启用彩色输出支持。<br />
<br />
== find ==<br />
<br />
''find'' 是 {{Pkg|findutils}} 软件包的一部分, 它属于 {{Grp|base}} 软件包组。<br />
<br />
{{提示|{{Pkg|fd}} 是 {{ic|find}} 的一个更加简单、快速、友好的替代方案,它有着更合理的默认值(比如忽略隐藏文件、文件夹和 {{ic|.gitignore}} 等文件,可用 {{ic|fd PATTERN}} 代替 {{ic|find -iname '*PATTERN*'}})。它具有彩色输出(类似 {{ic|ls}}),unicode 支持,正则表达式等等。}}<br />
<br />
你可能希望 ''find'' 命令将一个文件名称作为参数,并在文件系统中搜索与该名称匹配的文件。下面的 [[#locate]] 程序可以专门做这件事。<br />
<br />
相反,find 需要一组目录,并将它们下面的每个文件与一组表达式进行匹配。这种设计为实现一些“能干的单行小程序”提供了强大的支持,而这是上述“直观”设计无法实现的。参阅 [http://mywiki.wooledge.org/UsingFind UsingFind] 来获取使用说明。<br />
<br />
== iconv ==<br />
<br />
''iconv'' 将转换一个文本的字符编码。<br />
<br />
下列命令将文件 {{ic|''foo''}} 从 ISO-8859-15 转换至 UTF-8,然后保存到 {{ic|''foo''.utf}}:<br />
<br />
$ iconv -f ISO-8859-15 -t UTF-8 ''foo'' > ''foo''.utf<br />
<br />
查阅 {{man|1|iconv}} 获取更多细节。<br />
<br />
=== 在原文件上转换 ===<br />
<br />
{{提示|如果你不想改变文件的修改时间,可以用 {{pkg|recode}} 代替 iconv。}}<br />
与 [[#sed|sed]] 不同,''iconv'' 没有提供直接转换文件的选项,但是 {{pkg|moreutils}} 包里面的 {{ic|sponge}} 可以帮忙:<br />
<br />
$ iconv -f WINDOWS-1251 -t UTF-8 ''foobar''.txt | sponge ''foobar''.txt<br />
<br />
更多细节请参阅 {{man|1|sponge}}。<br />
<br />
== ip ==<br />
<br />
[[Wikipedia:Iproute2|ip]] 显示关于网络设备,IP 地址,路由表和其他 Linux [[Wikipedia:Internet Protocol|IP]] 软件栈的对象信息。通过附加各种命令,你可以操纵或配置大多数对象。<br />
<br />
{{注意| ''ip'' 命令在 {{Pkg|iproute2}} 包中提供,这个包已经包含在 {{Grp|base}} 组。}}<br />
<br />
{| class="wikitable"<br />
! 对象 !! 作用 !! 手册页名称<br />
|-<br />
| ip addr || 协议地址管理 || {{man|8|ip-address}} <br />
|-<br />
| ip addrlabel || 协议地址标签管理 || {{man|8|ip-addrlabel}}<br />
|-<br />
| ip l2tp || tunnel Ethernet over IP (L2TPv3) || {{man|8|ip-l2tp}}<br />
|-<br />
| ip link || 网络设备配置 || {{man|8|ip-link}}<br />
|-<br />
| ip maddr || 多播地址管理 || {{man|8|ip-maddress}}<br />
|-<br />
| ip monitor || 监测 netlink 信息 || {{man|8|ip-monitor}}<br />
|-<br />
| ip mroute || 多播路由缓存管理 || {{man|8|ip-mroute}}<br />
|-<br />
| ip mrule || 多播路由策略数据库的规则 ||<br />
|-<br />
| ip neigh || 邻居/ARP 表管理|| {{man|8|ip-neighbour}}<br />
|-<br />
| ip netns || process network namespace management || {{man|8|ip-netns}}<br />
|-<br />
| ip ntable || 邻居表配置 || {{man|8|ip-ntable}}<br />
|-<br />
| ip route || 路由表管理 || {{man|8|ip-route}}<br />
|-<br />
| ip rule || 路由策略数据库管理 || {{man|8|ip-rule}}<br />
|-<br />
| ip tcp_metrics || 管理 TCP Metrics || {{man|8|ip-tcp_metrics}}<br />
|-<br />
| ip tunnel || 隧道配置 || {{man|8|ip-tunnel}}<br />
|-<br />
| ip tuntap || 管理 TUN/TAP 设备 ||<br />
|-<br />
| ip xfrm || 管理 IPsec 策略 || {{man|8|ip-xfrm}}<br />
|}<br />
<br />
{{ic|help}} 帮助命令可用于所有对象。例如,输入 {{ic|ip addr help}} 将显示地址的命令语法。高级用法参见 [http://www.policyrouting.org/iproute2.doc.html iproute2 documentation]。<br />
<br />
[[Network configuration]] 显示 ''ip'' 命令的多种常见任务中的使用方式。<br />
<br />
{{注意|你也许很熟悉 [[Wikipedia:ifconfig|ifconfig]] 命令,它用于旧版linux的接口配置。在 Arch Linux 中现已不赞成使用;应当用 ''ip'' 替代之。}}<br />
<br />
== locate ==<br />
<br />
[[安装]] 软件包 {{Pkg|mlocate}}。包里包括了一个 {{ic|updatedb.timer}} 单元,用于每天更新数据库。这个 systemd 定时器在安装后就会 enable,如果不想重启系统,请手动 [[start]]。以 root 手动运行 ''updatedb'' 也可以更新数据库。默认会忽略 {{ic|/media}} 和 {{ic|/mnt}} 等路径,所以 ''locate'' 不会查找外置设备里的文件。详情请参考 {{man|8|updatedb}}。<br />
<br />
''locate'' 命令是一个快速查找文件系统的常用 Unix 工具。因为是从数据库查找而不是直接访问文件系统,所以速度比 [[wikipedia:Find|find]] 快很多。而缺点是在数据库更新后创建的新文件不会被搜索到。<br />
<br />
使用 ''locate'' 前需建立数据库,请先以 root 权限执行 {{ic|updatedb}}。<br />
<br />
详情参考 [http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ How locate works and rewrite it in one minute]。<br />
<br />
== less ==<br />
<br />
{{Expansion|less 是一个复杂的家伙,这一章应该介绍一些基本的 less 命令。}}<br />
<br />
[[Wikipedia:less (Unix)|less]] 是一个对文本文件内容进行分页显示的终端程序,它和其他的分页显示程序如 [[Wikipedia:more (command)|more]] 和 [[Wikipedia:pg (Unix)|pg]] 相似,但 ''less'' 提供了更高级的界面和更多的 [http://www.greenwoodsoftware.com/less/faq.html 功能]。<br />
<br />
参阅 [[List of applications#Terminal pagers]] 查找更多替代方案。<br />
<br />
=== 用 Vim 代替 less 来分页 ===<br />
<br />
[[Vim]] 内置了脚本,可直接查看文本文件、压缩包或目录的内容。在你的 shell 配置文件添加以下内容:<br />
{{hc|~/.bashrc|2=alias less='/usr/share/vim/vim80/macros/less.sh'}}<br />
<br />
除了 ''less.sh'' 宏外还有另外一种用法,依赖于 {{ic|PAGER}} 环境变量。安装 {{Pkg|vimpager}} 并添加以下内容至shell配置文件:<br />
{{hc|~/.bashrc|2=<br />
export PAGER='vimpager'<br />
alias less=$PAGER<br />
}}<br />
<br />
这样,所有使用 {{ic|PAGER}} 环境变量的程序, 如 [[git]], 将使用 ''vim'' 作为分页程序。<br />
<br />
== ls ==<br />
<br />
[[Wikipedia:ls|ls]] 是一个Unix和类Unix系统中列出目录里的文件的一个命令。<br />
<br />
请参考 {{ic|info ls}} 或 [http://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html#ls-invocation 在线文档]。<br />
<br />
[https://the.exa.website exa] 相较于 {{ic|ls}} 和 {{ic|tree}} 是一个更加现代的、人性化的选择。它有更多的特性,例如将 [[Git]] 修改和文件名一同显示,在 {{ic|--long}} 模式中对每列进行不同的着色,或者在 {{ic|tree}} 视图中显示 {{ic|--long}} 模式元数据。 {{Pkg|exa}}<br />
<br />
=== “长格式”输出 ===<br />
<br />
{{ic|-l}} 选项显示一些元数据,例如:<br />
<br />
{{hc|$ ls -l ''/path/to/directory''|<br />
total 128<br />
drwxr-xr-x 2 archie users 4096 Jul 5 21:03 Desktop<br />
drwxr-xr-x 6 archie users 4096 Jul 5 17:37 Documents<br />
drwxr-xr-x 2 archie users 4096 Jul 5 13:45 Downloads<br />
-rw-rw-r-- 1 archie users 5120 Jun 27 08:28 customers.ods<br />
-rw-r--r-- 1 archie users 3339 Jun 27 08:28 todo<br />
-rwxr-xr-x 1 archie users 2048 Jul 6 12:56 myscript.sh<br />
}}<br />
<br />
{{ic|total}} 值表示目录中文件的总磁盘分配,默认情况下为块的数量。<br />
<br />
每个文件和子目录由一行表示,每行划分为 7 个字段,按以下顺序表示:<br />
<br />
* 类型与权限:<br />
** 首字母表示内部类型,参阅 {{ic|info ls -n "What information is listed"}} 来查看所有可能类型的介绍;例如:<br />
*** {{ic|-}} 表示一个普通文件;<br />
*** {{ic|d}} 表示一个目录,比如一个包括了其他文件和文件夹的文件夹;<br />
*** {{ic|p}} 表示一个命名的管道(又名 FIFO);<br />
*** {{ic|l}} 表示这是一个软链接;<br />
** 其他字母表示这个条目的 [[permissions|权限]];<br />
* 这个条目 [[Wikipedia:Hard link|硬链接]] 的数量;对文件而言这个数字至少是 1,即当前显示的文件引用本身;对文件夹而言这个数字至少是 2,当前显示的引用、对自己的引用({{ic|.}} 条目)以及这个文件夹中的子文件夹对父文件夹的引用({{ic|..}} 条目);<br />
* [[user|用户]] 名;<br />
* [[group|组]] 名;<br />
* 大小;<br />
* 修改时间;<br />
* 名称。<br />
<br />
=== 带空格的文件名被引号引起 ===<br />
<br />
默认情况下,包含空格的文件名和目录名会被单引号引起。要改变这一特性,请使用 {{ic|-N}} 或 {{ic|1=--quoting-style=literal}} 选项。另外,将 {{ic|QUOTING_STYLE}} [[environment variable|环境变量]] 设置为 {{ic|literal}} 也可以。[https://unix.stackexchange.com/questions/258679/why-is-ls-suddenly-surrounding-items-with-spaces-in-single-quotes]<br />
<br />
== lsblk ==<br />
<br />
{{man|8|lsblk}} 命令会显示所有连接到系统的 [[w:Device_file#Block_devices|块设备]] 和分区状况:<br />
<br />
{{hc|$ lsblk -f|<br />
NAME FSTYPE LABEL UUID MOUNTPOINT<br />
sda<br />
├─sda1 vfat C4DA-2C4D /boot<br />
├─sda2 swap 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 [SWAP]<br />
└─sda3 ext4 56adc99b-a61e-46af-aab7-a6d07e504652 /<br />
}}<br />
<br />
设备名开头定义块设备的类型,大部分现代的硬盘、[[SSD]] 和 USB 闪存设备都被识别为 SCSI disks ({{ic|sd}})。类型后面跟着给设备编号的小写字母,第一个设备从 {{ic|a}} 开始 ({{ic|sda}}),第二个设备就是 {{ic|b}} ({{ic|sdb}}),以此类推。每个设备上的 ''现有'' 分区将用数字编号,从 {{ic|1}} 开始 ({{ic|sda1}}),第二个分区就是 {{ic|2}} ({{ic|sda2}}),以此类推。在上面的示例中,只有一个设备可用 ({{ic|sda}}),该设备有三个分区 ({{ic|sda1}} 到 {{ic|sda3}}),每个分区具有不同的 [[file system|文件系统]]。<br />
<br />
其它块设备比如 {{ic|mmcblk}}(内存卡)或 {{ic|nvme}}([[NVMe]] 设备)。不清楚的设备类型可以在这里搜索到:[https://www.kernel.org/doc/Documentation/devices.txt kernel documentation]{{Dead link|2017|11|11}}。<br />
<br />
== mkdir ==<br />
<br />
[[Wikipedia:mkdir|mkdir]] (''make directory'') 可以创建目录。<br />
<br />
若需递归地创建一系列目录,就要用到 {{ic|-p}} 参数了,否则会出错。已经十分熟悉这原理的高级用户也可直接设为内置参数:<br />
<br />
alias mkdir='mkdir -p -v'<br />
<br />
{{ic|-v}} 参数可以使创建目录过程中的信息更为详细。<br />
<br />
不必使用 ''chmod'' 更改权限模式, 用 {{ic|-m}} 选项可直接定义新建目录的访问权限。<br />
<br />
{{提示|如果您仅仅只是想建个临时目录,也许用 [[Wikipedia:Temporary file|mktemp]]: {{ic|mktemp -d}} 更好。}}<br />
<br />
== mv ==<br />
<br />
[[Wikipedia:mv|mv]] (''move'') 可以移动或重命名文件和目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias mv='timeout 8 mv -iv'<br />
<br />
这个别名可以延迟 ''mv'' 到 8 秒后才生效,在覆盖已存在的文件时要求确认,列出正在进行的操作并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。<br />
<br />
== od ==<br />
<br />
[[Wikipedia:od (Unix)|od]] (''o''ctal ''d''ump) 命令在显示非人类可读格式时非常有用,比如程序的可执行文件,或者未格式化的设备的内容。参阅[https://www.gnu.org/software/coreutils/manual/html_node/od-invocation.html#od-invocation manual] 了解详情。<br />
<br />
== pv ==<br />
<br />
可以用 {{Pkg|pv}} (''pipe viewer'') 来监视管道中传递的数据,例如:<br />
<br />
# dd if=''/source/filestream'' | pv -''monitor_options'' -s ''size_of_file'' | dd of=''/destination/filestream''<br />
<br />
大多数情况下 {{ic|pv}} 可直接替代 {{ic|cat}}。<br />
<br />
== rm ==<br />
<br />
[[Wikipedia:rm_(Unix)|rm]] (''remove'') 用于删除文件或目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias rm='timeout 3 rm -Iv --one-file-system'<br />
<br />
这个别名可延迟 ''rm'' 到 3 秒后才生效,在删除三个以上的文件时要求确认,列出正在进行的操作,限于只在同一个文件系统生效并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。若你想在删除多文件时一一确认,用 {{ic|-I}} 代替 {{ic|-i}} 即可。<br />
<br />
Zsh 的使用者可在 {{ic|timeout}} 前加上 {{ic|noglob}},避免隐式扩展。<br />
<br />
若要移除空目录,使用 ''rmdir'',若内含文件则命令失败。<br />
<br />
== sed ==<br />
<br />
[[Wikipedia:sed|sed]] (''stream editor'') 是一条专门解析或替换文本的命令。<br />
<br />
这里有一系列现成的 ''sed'' [http://sed.sourceforge.net/sed1line.txt 示范]。<br />
<br />
{{提示|[[Wikipedia:AWK|AWK]] 和 [[Wikipedia:Perl|Perl]] 语言在这方面更为强大。}}<br />
<br />
== seq ==<br />
<br />
''seq'' (''sequence'') 是一条专门排列数字的命令。Shell 内置了该命令的其他替代方案,可以按照 [[Wikipedia:Seq (Unix)|Wikipedia]] 的说明进行练习。<br />
<br />
== ss ==<br />
<br />
''ss'' 是一个检查网络端口的实用程序,并且是 {{Grp|base}} 组中的 {{Pkg|iproute2}} 包的一部分。它具有与 [https://www.archlinux.org/news/deprecation-of-net-tools/ 弃用的] netstat 实用程序类似的功能。<br />
<br />
常用用法包括:<br />
<br />
显示所有 TCP Sockets,连同 service 名称:<br />
$ ss -at<br />
<br />
显示所有 TCP Sockets,连同端口号:<br />
$ ss -atn<br />
<br />
显示所有 UDP Sockets:<br />
$ ss -au<br />
<br />
更多信息请参考 {{Pkg|iproute2}} 包里的 {{man|8|ss}} 或 {{ic|ss.html}}。<br />
<br />
== tar ==<br />
<br />
作为早期的 Unix 存档格式,.tar 文件(称为“tarballs”)广泛用于类 Unix 操作系统中的打包操作。[[pacman]] 和 [[AUR]] 软件包都是压缩的 tarball,Arch 默认使用 [[GNU Project|GNU 的]] ''tar'' 程序。<br />
<br />
对于 ''.tar'' 文件,''tar'' 默认根据扩展名来解压文件:<br />
<br />
$ tar xvf ''file.EXTENSION''<br />
<br />
强制给定格式:<br />
<br />
{| class="wikitable"<br />
!文件类型 !! 解压命令<br />
|-<br />
|{{ic|''file''.tar}} || {{Ic|tar xvf ''file''.tar}}<br />
|-<br />
|{{ic|''file''.tgz}} || {{Ic|tar xvzf ''file''.tgz}}<br />
|-<br />
|{{ic|''file''.tar.gz}} || {{Ic|tar xvzf ''file''.tar.gz}}<br />
|-<br />
|{{ic|''file''.tar.bz}} || {{Ic|bzip -cd ''file''.bz <nowiki>|</nowiki> tar xvf -}}<br />
|-<br />
|{{ic|''file''.tar.bz2}} || {{Ic|tar xvjf ''file''.tar.bz2}}<br> {{Ic|bzip2 -cd ''file''.bz2 <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.xz}} || {{Ic|tar xvJf ''file''.tar.xz}}<br> {{Ic|xz -cd ''file''.xz <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.zst}} || {{Ic|tar -I zstd xvf ''file''.tar.zst}}<br />
|}<br />
<br />
这其中有部分 ''tar'' 的参数可以认为是历史遗留问题,但在执行某些特定的操作时仍然有用。更多细节请参阅 {{man|1|tar}}。<br />
<br />
== which ==<br />
<br />
[[wikipedia:Which_(Unix)|which]] 显示 shell 命令的完整路径。在下面的例子中 {{ic|ssh}} 的完整路径作为一个参数传递给了 {{ic|journalctl}}:<br />
<br />
# journalctl $(which sshd)<br />
<br />
== wipefs ==<br />
<br />
''wipefs'' 可以列出或擦除指定设备的 [[file system|文件系统]]、[[RAID]] 或 [[partition|分区表]] 标志 (magic strings)。它不会擦除文件系统本身,也不会擦除设备中的任何其他数据。<br />
<br />
更多信息请参阅 {{man|8|wipefs}}。<br />
<br />
例如,擦除 {{ic|/dev/sdb}} 设备中的所有标志并为每个标志在 {{ic|~/wipefs-sdb-''offset''.bak}} 创建一个备份文件:<br />
<br />
# wipefs --all --backup /dev/sdb<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.reddit.com/r/commandline/comments/19garq/a_sampling_of_coreutils_120/ A sampling of coreutils] [http://www.reddit.com/r/commandline/comments/19ge6v/a_sampling_of_coreutils_2040/ , part 2] [http://www.reddit.com/r/commandline/comments/19j1w3/a_sampling_of_coreutils_4060/ , part 3] - Overview of commands in coreutils<br />
* [https://www.gnu.org/software/coreutils/manual/coreutils.html GNU Coreutils online documentation]<br />
* [https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/ Learn the DD command]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Category:Command-line_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516655
Category:Command-line (简体中文)
2018-04-10T08:28:15Z
<p>Arisaka: Create category.</p>
<hr />
<div>[[Category:Applications (简体中文)]]<br />
[[Category:System administration (简体中文)]]<br />
此类别包含基本的命令行实用程序。</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Su_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516654
Su (简体中文)
2018-04-10T08:25:49Z
<p>Arisaka: </p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:简体中文]]<br />
[[Category:Security (简体中文)]]<br />
[[Category:Command-line (简体中文)]]<br />
[[en:Su]]<br />
[[es:Su]]<br />
[[fa:su]]<br />
[[fr:su]]<br />
[[ja:su]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Users and groups (简体中文)}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|su|2018-04-10|516603}}<br />
<br />
'''su''' 命令 ('''s'''ubstitute '''u'''ser) 用来切换当前用户身份到其他用户身份,默认切换成 root。<br />
<br />
参阅 [[PAM]] 可以找到配置 '''su''' 其他特性的方法。<br />
<br />
== 安装 ==<br />
su 是 {{Pkg|util-linux}} 包的一部分,默认已经作为 {{Grp|base}} 组的一部分安装到 Arch 中了。<br />
<br />
== 用法 ==<br />
要切换到其他用户身份,将要切换的用户名传递给 su,像这样:<br />
<br />
# su ''username''<br />
<br />
然后就能看到提示符,要求输入所要切换用户的密码。<br />
<br />
如果没有传入用户名,su 默认切换为 root 用户,要求输入的密码也应该是 root 用户的密码。<br />
<br />
== 另一个选择:Sudo ==<br />
<br />
{{Merge|sudo|这些文档应该在 [[sudo]] 页面上显示。}}<br />
{{Merge|Security#Use_sudo_instead_of_su|在 [[Security]] 页面上论述了相同的主题。}}<br />
<br />
[[sudo]] 可以提供和 su 类似的功能,且更加可定制化,根据具体要求和威胁模型分析,可以作为 su 的一个替代。sudo 系统会提示你输入你自己的密码,或者根本没有密码(如果以这种方式配置的话),而不是目标用户(你正试图使用的帐户)的密码。这样就不必在用户之间共享密码,并且如果需要阻止一个用户获得 root 权限(或获得其他用户权限),则无需更改 root 密码(更改密码将给其他人造成不便),你只需要撤销该用户的 sudo 访问权。<br />
<br />
如果 sudo 被配置为允许用户以 root 身份运行 shell,那么用户只要用 {{ic|sudo -s}} 或 {{ic|sudo -i}} 命令就可以分别模拟出 {{ic|su}} 或 {{ic|su -l}} 命令的效果,而且是用他自己的密码(或没有密码),而不是 root 的密码。同样,如果允许以 john 身份运行 shell,{{ic|sudo -u john -i}} 和 {{ic|su -l john}} 效果一样。<br />
<br />
== 提示和技巧 ==<br />
=== “登录至”其他用户 ===<br />
su 的默认行为是保持在当前目录中并保持原始用户的环境变量(而不是切换到新用户的环境变量)。<br />
<br />
这一特性的优劣需要注意以下重要的对比因素:<br />
<br />
* 系统管理员可以使用普通用户的 shell 而不是自己的。特别是在有些时候,解决用户问题的最有效的方法,就是登录到该用户的帐户以重现问题或进行调试。<br />
<br />
* 但是通常情况下,root 用户不能登录普通用户的 shell 并使用该用户的环境变量进行操作,而是用自己的环境变量操作,这在很多情况下是不可取的,甚至是危险的。在无意中使用普通用户的 shell 时,root 可能会安装程序,或对系统进行其他更改,而这些更改与使用 root 帐户时所做的结果不同。例如,可能会安装某个程序,使得普通用户能够意外地损坏系统或未经授权访问某些数据。<br />
<br />
因此,建议系统管理员以及被授权使用 su 的任何其他用户(建议只有极少数用户),始终保持用 {{ic|-l}} 或 {{ic|--login}} 选项运行 su 命令的习惯。它有两个作用:<br />
# 通过 ''登录至'' 目标用户,从当前工作目录切换到目标用户的主目录(比如切换到 root 用户就是 {{ic|/root}})。<br />
# 根据目标用户的 {{ic|~/.bashrc}} 切换到目标用户的环境变量。也就是说,当前工作目录和环境将会切换到和目标用户登录新会话时一样的目录和环境(而不是仅接管现有用户的会话)。<br />
<br />
因此,管理员通常应该这样使用 su:<br />
$ su -l<br />
<br />
添加用户名 root 结果一样:<br />
$ su -l root<br />
<br />
对于任何其他用户(如名为 archie 的用户),同样可以做到:<br />
# su -l archie<br />
<br />
你可能希望在 {{ic|~/.bashrc}} 里为这个规则添加一个 alias:<br />
<br />
alias su="su -l"<br />
<br />
=== su 和 wheel 用户组 ===<br />
BSD su 默认仅允许 "wheel" [[Users and groups (简体中文)#用户组管理|用户组]] 成员切换至 root 身份。而 GNU su 默认没有这一特性,可以使用 [[PAM (简体中文)|PAM]] 来模拟这一特性。将 {{ic|/etc/pam.d/su}} 和 {{ic|/etc/pam.d/su-l}} 中相应的行取消注释:<br />
<br />
auth required pam_wheel.so use_uid</div>
Arisaka
https://wiki.archlinux.org/index.php?title=RAID_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516536
RAID (简体中文)
2018-04-09T14:46:18Z
<p>Arisaka: Add Translateme</p>
<hr />
<div>[[Category:File systems (简体中文)]]<br />
[[en:RAID]]<br />
[[es:RAID]]<br />
[[it:RAID]]<br />
[[ja:RAID]]<br />
[[ru:RAID]]<br />
{{Related articles start}}<br />
{{Related|Software RAID and LVM}}<br />
{{Related|Installing with Fake RAID}}<br />
{{Related|Convert a single drive system to RAID}}<br />
{{Related|ZFS}}<br />
{{Related|Experimenting with ZFS}}<br />
{{Related|Swap#Striping}}<br />
{{Related|Btrfs#RAID}}<br />
{{Related articles end}}<br />
{{Translateme (简体中文)|这篇文章后半部分没有翻译。}}<br />
{{TranslationStatus (简体中文)|RAID|2017-02-07|466889}}<br />
本文主要叙述了RAID的意义与基本形式,以及如何配置软/硬RAID。<br />
<br />
== 简介 ==<br />
<br />
参见 [[Wikipedia:RAID]].<br />
<br />
磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意。<br />
磁盘阵列是由很多价格较便宜的磁盘,以硬件(RAID卡)或软件(例如[[ZFS (简体中文)]] )形式组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能。利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。<br />
磁盘阵列还能利用同位检查(Parity Check)的观念,在数组中任意一个硬盘故障时,仍可读出数据,在数据重构时,将数据经计算后重新置入新硬盘中。<br />
<br />
{{Warning|尽管RAID可以预防数据丢失,但并不完全保证数据不会丢失,请在使用RAID的同时注意备份重要数据}}}<br />
<br />
===基本RAID级别===<br />
这里有许多不同的 [[Wikipedia:Standard RAID levels|RAID级别]],请你选择最合适于您的。<br />
<br />
; [[Wikipedia:Standard RAID levels#RAID 0|RAID 0]]<br />
: RAID 0 并不是真正的RAID结构,没有数据冗余,没有数据校验的磁盘陈列。实现RAID 0至少需要两块以上的硬盘,它将两块以上的硬盘合并成一块,数据连续地分割在每块盘上。 因为带宽加倍,所以读/写速度加倍, 但RAID 0在提高性能的同时,并没有提供数据保护功能,只要任何一块硬盘损坏就会丢失所有数据。因此RAID 0 不可应用于需要数据高可用性的关键领域。<br />
; [[Wikipedia:Standard RAID levels#RAID 1|RAID 1]]<br />
: RAID1是将一个两块硬盘所构成RAID磁盘阵列,其容量仅等于一块硬盘的容量,因为另一块只是当作数据“镜像”。RAID 1磁盘阵列显然是最可靠的一种阵列,因为它总是保持一份完整的数据备份。它的性能自然没有RAID 0磁盘阵列那样好,但其数据读取确实较单一硬盘来的快,因为数据会从两块硬盘中较快的一块中读出。RAID 1磁盘阵列的写入速度通常较慢,因为数据得分别写入两块硬盘中并做比较。RAID 1磁盘阵列一般支持“热交换”,就是说阵列中硬盘的移除或替换可以在系统运行时进行,无须中断退出系统。RAID 1磁盘阵列是十分安全的,不过也是较贵一种RAID磁盘阵列解决方案,因为两块硬盘仅能提供一块硬盘的容量。RAID 1磁盘阵列主要用在数据安全性很高,而且要求能够快速恢复被破坏的数据的场合。<br />
; [[Wikipedia:Standard RAID levels#RAID 5|RAID 5]]<br />
: RAID 5 是一种存储性能、数据安全和存储成本兼顾的存储解决方案。 RAID 5可以理解为是RAID 0和RAID 1的折中方案。RAID 5可以为系统提供数据安全保障,但保障程度要比Mirror低而磁盘空间利用率要比Mirror高。RAID 5具有和RAID 0相近似的数据读取速度,只是多了一个奇偶校验信息,写入数据的速度比对单个磁盘进行写入操作稍慢。同时由于多个数据对应一个奇偶校验信息,RAID 5的磁盘空间利用率要比RAID 1高,存储成本相对较低,是目前运用较多的一种解决方案。<br />
: {{Note|尽管RAID 5是数据安全与I/O速度的权衡,但是由于其工作方式,在大于4Tb的场合下,磁盘故障发生后,数据重建的难度将大大增加。所以存储行业并不建议使用RAID5 }}<br />
; [[Wikipedia:Standard RAID levels#RAID 6|RAID 6]]<br />
: RAID6技术是在RAID 5基础上,为了进一步加强数据保护而设计的一种RAID方式,实际上是一种扩展RAID 5等级。与RAID 5的不同之处于除了每个硬盘上都有同级数据XOR校验区外,还有一个针对每个数据块的XOR校验区。当然,当前盘数据块的校验数据不可能存在当前盘而是交错存储的,具体形式见图。这样一来,等于每个数据块有了两个校验保护屏障(一个分层校验,一个是总体校验),因此RAID 6的数据冗余性能相当好。但是,由于增加了一个校验,所以写入的效率较RAID 5还差,而且控制系统的设计也更为复杂,第二块的校验区也减少了有效存储空间。<br />
: {{Note|组成RAID 6阵列需要至少四块磁盘。 }}<br />
===嵌套 RAID 级别===<br />
: RAID 10/01<br />
; RAID 10是先镜射再分区数据,再将所有硬盘分为两组,视为是RAID 0的最低组合,然后将这两组各自视为RAID 1运作。RAID 01则是跟RAID 10的程序相反,是先分区再将数据镜射到两组硬盘。它将所有的硬盘分为两组,变成RAID 1的最低组合,而将两组硬盘各自视为RAID 0运作。<br />
当RAID 10有一个硬盘受损,其余硬盘会继续运作。RAID 01只要有一个硬盘受损,同组RAID 0的所有硬盘都会停止运作,只剩下其他组的硬盘运作,可靠性较低。如果以六个硬盘建RAID 01,镜射再用三个建RAID 0,那么坏一个硬盘便会有三个硬盘离线。因此,RAID 10远较RAID 01常用,零售主板绝大部分支持RAID 0/1/5/10,但不支持RAID 01。<br />
<br />
=== RAID 级别对比 ===<br />
{| class="wikitable sortable"<br />
|-<br />
! RAID等級 !! 最少磁盘 !! 最大容错 !! 可用容量 !! 读取效能 !! 写入效能 !! 安全性 !! 目的 !! 应用场合<br />
|- <br />
| 单一硬盘 || (參考) || 0 || 1 || 1 || 1 || 无 || || <br />
|- <br />
| JBOD || 1 || 0 || n || 1 || 1 || 无(同RAID 0) || 增加容量 || 个人(暂时)存储备份<br />
|- <br />
| 0 || 2 || 0 || n || n || n || 一块硬盘故障,整个阵列损坏 || 追求最大容量、速度 || 影片剪接快取用途<br />
|-<br />
| 1 || 2 ||n-1 ||1 || n ||1 || 最高,一个正常即可 || 追求最大安全性 || 个人,企业备份<br />
|-<br />
| 5 || 3 || 1 || n-1 || n-1 || n-1 || 高 || 追求最大容量、最小预算 || 个人,企业备份<br />
|-<br />
| 6 || 4 || 2 || n-2 || n-2|| n-2|| 安全性較RAID 5高 || 同RAID 5,但较安全 || 個人、企業備份<br />
|- <br />
| 10 || 4 || n/2 || n/2|| n || n/2 || 安全性高 || 綜合RAID 0/1优点,理论速度較快 || 大型服务器 <br />
|-<br />
|}<br />
<br />
== 实施方法 ==<br />
RAID可由以下方法实施:<br />
<br />
; 软RAID<br />
: 对于软RAID阵列,有以下途径可以实施阵列:<br />
:* 抽象层实现 (例如 [[#Installation|mdadm]]); {{Note|我们会在接下来引导你安装}}<br />
:* 逻辑卷实现 (例如 [[LVM (简体中文)]]);<br />
:* 文件系统实现 (例如 [[ZFS (简体中文)]], [[Btrfs (简体中文)]]).<br />
<br />
; 硬RAID<br />
: 硬RAID由硬件(可以使芯片组內建也可以是单独设备)直接连接磁盘实现。RAID 逻辑一般由一块板载I/O芯片实现。RAID 的配置可以由直接更改RAID卡的设置实现,也可以由其他厂商指定的方法。操作系统不直接与硬盘联系。在一些情况下可能需要安装厂商专有驱动。<br />
<br />
; [[Fakeraid|FakeRAID]]<br />
: This type of RAID is properly called BIOS or Onboard RAID, but is falsely advertised as hardware RAID. The array is managed by pseudo-RAID controllers where the RAID logic is implemented in an option rom or in the firmware itself [http://www.win-raid.com/t19f13-Intel-EFI-RAID-quot-SataDriver-quot-BIOS-Modules.html with a EFI SataDriver] (in case of [[UEFI]]), but are not full hardware RAID controllers with ''all'' RAID features implemented. Therefore, this type of RAID is sometimes called FakeRAID. {{Pkg|dmraid}} from the [[official repositories]], will be used to deal with these controllers. Here are some examples of FakeRAID controllers: [[Wikipedia:Intel Rapid Storage Technology|Intel Rapid Storage]], JMicron JMB36x RAID ROM, AMD RAID, ASMedia 106x, and NVIDIA MediaShield.<br />
<br />
===Which type of RAID do I have?===<br />
<br />
Since software RAID is implemented by the user, the type of RAID is easily known to the user.<br />
<br />
However, discerning between FakeRAID and true hardware RAID can be more difficult. As stated, manufacturers often incorrectly distinguish these two types of RAID and false advertising is always possible. The best solution in this instance is to run the {{ic|lspci}} command and looking through the output to find the RAID controller. Then do a search to see what information can be located about the RAID controller. Hardware RAID controllers appear in this list, but FakeRAID implementations do not. Also, true hardware RAID controller are often rather expensive (~$400+), so if someone customized the system, then it is very likely that choosing a hardware RAID setup made a very noticeable change in the computer's price.<br />
<br />
== Installation ==<br />
<br />
Install {{Pkg|mdadm}} from the [[official repositories]]. ''mdadm'' is used for administering pure software RAID using plain block devices: the underlying hardware does not provide any RAID logic, just a supply of disks. ''mdadm'' will work with any collection of block devices. Even if unusual. For example, one can thus make a RAID array from a collection of thumb drives.<br />
<br />
===Prepare the Devices===<br />
<br />
{{Warning|These steps erase everything on a device, so type carefully!}}<br />
<br />
If the device is being reused or re-purposed from an existing array, erase any old RAID configuration information:<br />
# mdadm --zero-superblock /dev/<drive><br />
<br />
or if a particular partition on a drive is to be deleted:<br />
# mdadm --zero-superblock /dev/<partition><br />
<br />
{{Note|<br />
* Zapping a partition's superblock should not affect the other partitions on the disk.<br />
* Due to the nature of RAID functionality it is very difficult to [[Securely wipe disk]]s fully on a running array. Consider whether it is useful to do so before creating it.}}<br />
<br />
===Create the Partition Table (GPT)===<br />
<br />
It is highly recommended to pre-partition the disks to be used in the array. Since most RAID users are selecting HDDs >2 TB, GPT partition tables are required and recommended. Disks are easily partitioned using {{Pkg|gptfdisk}}.<br />
<br />
* After created, the partition type should be assigned hex code FD00.<br />
* If a larger disk array is employed, consider assigning [[Persistent_block_device_naming#by-label|disk labels]] or [[Persistent_block_device_naming#by-partlabel|partition labels]] to make it easier to identify an individual disk later. <br />
* Creating partitions that are of the same size on each of the devices is preferred.<br />
* A good tip is to leave approx 100 MB at the end of the device when partitioning. See below for rationale.<br />
<br />
====Partitions Types for MBR====<br />
<br />
For those creating partitions on HDDs with a MBR partition table, the partition types available for use are:<br />
<br />
* 0xDA (for non-fs data -- current recommendation by [https://raid.wiki.kernel.org/index.php/Partition_Types kernel.org])<br />
* 0xFD (for raid autodetect arrays -- was useful before booting an initrd to load kernel modules)<br />
<br />
{{Note|It is also possible to create a RAID directly on the raw disks (without partitions), but not recommended because it can cause problems when swapping a failed disk.}}<br />
<br />
When replacing a failed disk of a RAID, the new disk has to be exactly the same size as the failed disk or bigger — otherwise the array recreation process will not work. Even hard drives of the same manufacturer and model can have small size differences. By leaving a little space at the end of the disk unallocated one can compensate for the size differences between drives, which makes choosing a replacement drive model easier. Therefore, '''it is good practice to leave about 100 MB of unallocated space at the end of the disk.'''<br />
<br />
=== Build the Array ===<br />
<br />
{{Warning|Kernel versions 4.2.x and 4.3.x currently have an active bug that prevents them from assembling a RAID10 array; users needing this layout are encouraged to use kernel version 4.1.x series provided by {{pkg|linux-lts}} until this bug is fixed. References are provided in the [[#See also]] section.}}<br />
<br />
Use {{ic|mdadm}} to build the array. Several examples are given below.<br />
<br />
{{Warning|Do not simply copy/paste the examples below; use your brain and substitute the correct options/drive letters!}}<br />
<br />
{{Note|If this is a RAID1 array which is intended to boot from [[Syslinux]] a limitation in syslinux v4.07 requires the metadata value to be 1.0 rather than the default of 1.2.}}<br />
<br />
The following example shows building a 2-device RAID1 array:<br />
<br />
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md0 /dev/sdb1 /dev/sdc1<br />
<br />
The following example shows building a RAID5 array with 4 active devices and 1 spare device:<br />
<br />
# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md0 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1<br />
<br />
:{{Tip|{{ic|--chunk}} was used in the previous example to change the chunk size from the default value. See [http://www.zdnet.com/article/chunks-the-hidden-key-to-raid-performance/ Chunks: the hidden key to RAID performance] for more on chunk size optimisation.}}<br />
<br />
The following example shows building a RAID10,far2 array with 2 devices:<br />
<br />
# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md0 /dev/sdb1 /dev/sdc1<br />
<br />
{{Tip| The {{ic|--homehost}} and {{ic|--name}} options can be used for a custom raid device name. They are delimited by a colon in the resulting name.}}<br />
<br />
The array is created under the virtual device {{ic|/dev/mdX}}, assembled and ready to use (in degraded mode). One can directly start using it while mdadm resyncs the array in the background. It can take a long time to restore parity. Check the progress with:<br />
<br />
$ cat /proc/mdstat<br />
<br />
=== Update configuration file ===<br />
<br />
By default, most of {{ic|mdadm.conf}} is commented out, and it contains just the following:<br />
<br />
{{hc|/etc/mdadm.conf|DEVICE partitions}}<br />
<br />
This directive tells mdadm to examine the devices referenced by {{ic|/proc/partitions}} and assemble as many arrays as possible. This is fine if you really do want to start all available arrays and are confident that no unexpected superblocks will be found (such as after installing a new storage device). A more precise approach is as follows:<br />
# echo 'DEVICE partitions' > /etc/mdadm.conf<br />
# mdadm --detail --scan >> /etc/mdadm.conf<br />
<br />
This results in something like the following:<br />
{{hc|/etc/mdadm.conf|2=<br />
DEVICE partitions<br />
ARRAY /dev/md/0 metadata=1.2 name=pine:0 UUID=27664f0d:111e493d:4d810213:9f291abe<br />
}}<br />
<br />
This also causes mdadm to examine the devices referenced by {{ic|/proc/partitions}}. However, only devices that have superblocks with a UUID of {{ic|27664…}} are assembled in to active arrays.<br />
<br />
See {{ic|mdadm.conf(5)}} for more information.<br />
<br />
===Assemble the Array===<br />
<br />
Once the configuration file has been updated the array can be assembled using mdadm:<br />
<br />
# mdadm --assemble --scan<br />
<br />
===Format the RAID Filesystem===<br />
<br />
The array can now be formatted like any other disk, just keep in mind that:<br />
* Due to the large volume size not all filesystems are suited (see: [[Wikipedia:Comparison of file systems#Limits|File system limits]]).<br />
* The filesystem should support growing and shrinking while online (see: [[Wikipedia:Comparison of file systems#Features|File system features]]).<br />
* One should calculate the correct stride and stripe-width for optimal performance.<br />
<br />
==== Calculating the Stride and Stripe Width ====<br />
<br />
Two parameters are required to optimise the filesystem structure to fit optimally within the underlying RAID structure: the ''stride'' and ''stripe width''. These are derived from the RAID ''chunk size'', the filesystem ''block size'', and the ''number of "data disks"''.<br />
<br />
The chunk size is a property of the RAID array, decided at the time of its creation. {{ic|mdadm}}'s current default is 512 KiB. It can be found with {{ic|mdadm}}:<br />
<br />
# mdadm --detail /dev/mdX | grep 'Chunk Size'<br />
<br />
The block size is a property of the filesystem, decided at ''its'' creation. The default for many filesystems, including ext4, is 4 KiB. See {{ic|/etc/mke2fs.conf}} for details on ext4.<br />
<br />
The number of "data disks" is the minimum number of devices in the array required to completely rebuild it without data loss. For example, this is N for a raid0 array of N devices and N-1 for raid5.<br />
<br />
Once you have these three quantities, the stride and the stripe width can be calculated using the following formulas:<br />
<br />
stride = chunk size / block size<br />
stripe width = number of data disks * stride<br />
<br />
<br />
===== Example 1. RAID0 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
* Hypothetical RAID0 array is composed of 2 physical disks.<br />
* Chunk size is 64 KiB.<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size.<br />
In this example, the math is 64/4 so the stride = 16.<br />
<br />
stripe width = # of physical '''data''' disks * stride.<br />
In this example, the math is 2*16 so the stripe width = 32.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.5 -b 4096 -E stride=16,stripe-width=32 /dev/md0<br />
<br />
===== Example 2. RAID5 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
* Hypothetical RAID5 array is composed of 4 physical disks; 3 data discs and 1 parity disc.<br />
* Chunk size is 512 KiB.<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size.<br />
In this example, the math is 512/4 so the stride = 128.<br />
<br />
stripe width = # of physical '''data''' disks * stride.<br />
In this example, the math is 3*128 so the stripe width = 384.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=384 /dev/md0<br />
<br />
For more on stride and stripe width, see: [http://wiki.centos.org/HowTos/Disk_Optimization RAID Math].<br />
<br />
===== Example 3. RAID10,far2 =====<br />
<br />
Example formatting to ext4 with the correct stripe width and stride:<br />
* Hypothetical RAID10 array is composed of 2 physical disks. Because of the properties of RAID10 in far2 layout, both count as data disks.<br />
* Chunk size is 512 KiB.<br />
# mdadm --detail /dev/md0 | grep 'Chunk Size'<br />
Chunk Size : 512K<br />
* Block size is 4 KiB.<br />
<br />
stride = chunk size / block size.<br />
In this example, the math is 512/4 so the stride = 128.<br />
<br />
stripe width = # of physical '''data''' disks * stride.<br />
In this example, the math is 2*128 so the stripe width = 256.<br />
<br />
# mkfs.ext4 -v -L myarray -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/md0<br />
<br />
== Mounting from a Live CD ==<br />
<br />
Users wanting to mount the RAID partition from a Live CD, use:<br />
<br />
# mdadm --assemble /dev/<disk1> /dev/<disk2> /dev/<disk3> /dev/<disk4><br />
<br />
If your RAID 1 that's missing a disk array was wrongly auto-detected as RAID 1 (as per {{ic|mdadm --detail /dev/md<number>}}) and reported as inactive (as per {{ic|cat /proc/mdstat}}), stop the array first:<br />
<br />
# mdadm --stop /dev/md<number><br />
<br />
== Installing Arch Linux on RAID ==<br />
{{Note|The following section is applicable only if the root filesystem resides on the array. Users may skip this section if the array holds a data partition(s).}}<br />
You should create the RAID array between the [[Partitioning]] and [[File systems#Format a device|formatting]]{{Broken section link}} steps of the Installation Procedure. Instead of directly formatting a partition to be your root file system, it will be created on a RAID array.<br />
Follow the section [[#Setup]]{{Broken section link}} to create the RAID array. Then continue with the installation procedure until the pacstrap step is completed.<br />
When using [[Unified Extensible Firmware Interface|UEFI boot]], also read [[EFI System Partition#ESP on RAID|ESP on RAID]].<br />
<br />
=== Update configuration file ===<br />
{{Note|This should be done outside of the chroot, hence the prefix /mnt to the filepath.}}<br />
After the base system is installed the default configuration file, {{ic|mdadm.conf}}, must be updated like so:<br />
# mdadm --detail --scan >> /mnt/etc/mdadm.conf<br />
<br />
Always check the mdadm.conf configuration file using a text editor after running this command to ensure that its contents look reasonable.<br />
{{Note|To prevent failure of '''mdmonitor''' at boot (enabled by default), you will need to uncomment '''MAILADDR''' and provide an e-mail address and/or application to handle notification of problems with your array at the bottom of mdadm.conf.}}<br />
Continue with the installation procedure until you reach the step “Create initial ramdisk environment”, then follow the next section.<br />
<br />
=== Add mdadm hook to mkinitcpio.conf ===<br />
<br />
{{Accuracy|1=[[Mkinitcpio#Common hooks]] also suggests adding {{ic|mdmon}} to the {{ic|BINARIES}} section. See also [https://bbs.archlinux.org/viewtopic.php?id=148947] and [http://unix.stackexchange.com/questions/57440/cant-remount-local-file-systems-for-read-write-raid1].}}<br />
<br />
{{Note|This should be done whilst chrooted.}}<br />
<br />
Add {{ic|mdadm_udev}} to the [[Mkinitcpio#HOOKS|HOOKS]] section of the {{ic|mkinitcpio.conf}} to add support for mdadm directly into the init image:<br />
<br />
HOOKS="base udev autodetect block '''mdadm_udev''' filesystems usbinput fsck"<br />
<br />
Then [[Mkinitcpio#Image creation and activation|Regenerate the initramfs image]].<br />
<br />
=== Configure the boot loader ===<br />
<br />
Add an {{ic|md}} [[kernel parameter]] for each RAID array; also point the {{ic|root}} parameter to the correct mapped device. The following example accommodates three RAID 1 arrays and sets the second one as root:<br />
<br />
root=/dev/md1 md=0,/dev/sda2,/dev/sdb2 md=1,/dev/sda3,/dev/sdb3 md=2,/dev/sda4,/dev/sdb4<br />
<br />
If booting from a software raid partition fails using the kernel device node method above, an alternative and more reliable way is to use [[Persistent block device naming]], for example:<br />
<br />
root=LABEL=Root_Label<br />
<br />
See also [[GRUB#RAID]].<br />
<br />
== RAID Maintenance ==<br />
=== Scrubbing ===<br />
It is good practice to regularly run data [[wikipedia:Data_scrubbing|scrubbing]] to check for and fix errors. Depending on the size/configuration of the array, a scrub may take multiple hours to complete.<br />
<br />
To initiate a data scrub:<br />
# echo check > /sys/block/md0/md/sync_action<br />
<br />
The check operation scans the drives for bad sectors and automatically repairs them. If it finds good sectors that contain bad data (the data in a sector does not agree with what the data from another disk indicates that it should be, for example the parity block + the other data blocks would cause us to think that this data block is incorrect), then no action is taken, but the event is logged (see below). This "do nothing" allows admins to inspect the data in the sector and the data that would be produced by rebuilding the sectors from redundant information and pick the correct data to keep.<br />
<br />
As with many tasks/items relating to mdadm, the status of the scrub can be queried by reading {{ic|/proc/mdstat}}.<br />
<br />
Example:<br />
{{hc|$ cat /proc/mdstat|<nowiki><br />
Personalities : [raid6] [raid5] [raid4] [raid1] <br />
md0 : active raid1 sdb1[0] sdc1[1]<br />
3906778112 blocks super 1.2 [2/2] [UU]<br />
[>....................] check = 4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec<br />
bitmap: 0/30 pages [0KB], 65536KB chunk<br />
</nowiki>}}<br />
<br />
To stop a currently running data scrub safely:<br />
# echo idle > /sys/block/md0/md/sync_action<br />
<br />
{{Note|If the system is rebooted after a partial scrub has been suspended, the scrub will start over.}}<br />
<br />
When the scrub is complete, admins may check how many blocks (if any) have been flagged as bad:<br />
# cat /sys/block/md0/md/mismatch_cnt<br />
<br />
==== General Notes on Scrubbing ====<br />
{{Note|Users may alternatively echo '''repair''' to /sys/block/md0/md/sync_action but this is ill-advised since if a mismatch in the data is encountered, it would be automatically updated to be consistent. The danger is that we really don't know whether it's the parity or the data block that's correct (or which data block in case of RAID1). It's luck-of-the-draw whether or not the operation gets the right data instead of the bad data.}}<br />
<br />
It is a good idea to set up a cron job as root to schedule a periodic scrub. See {{AUR|raid-check}} which can assist with this. To perform a periodic scrub using systemd timers instead of cron, See {{AUR|raid-check-systemd}} which contains the same script along with associated systemd timer unit files. (note: for typical platter drives, scrubbing can take approximately '''six seconds per gigabyte''' [that's one hour forty-five minutes per terabyte] so plan the start of your cron job or timer appropriately)<br />
<br />
==== RAID1 and RAID10 Notes on Scrubbing ====<br />
Due to the fact that RAID1 and RAID10 writes in the kernel are unbuffered, an array can have non-0 mismatch counts even when the array is healthy. These non-0 counts will only exist in transient data areas where they don't pose a problem. However, we can't tell the difference between a non-0 count that is just in transient data or a non-0 count that signifies a real problem. This fact is a source of false positives for RAID1 and RAID10 arrays. It is however still recommended to scrub regularly in order to catch and correct any bad sectors that might be present in the devices.<br />
<br />
===Removing Devices from an Array===<br />
One can remove a device from the array after marking it as faulty:<br />
# mdadm --fail /dev/md0 /dev/sdxx<br />
<br />
Now remove it from the array:<br />
# mdadm --remove /dev/md0 /dev/sdxx<br />
<br />
Remove device permanently (for example, to use it individually from now on):<br />
Issue the two commands described above then:<br />
<br />
# mdadm --zero-superblock /dev/sdxx<br />
<br />
{{Warning | '''DO NOT''' issue this command on linear or RAID0 arrays or data '''LOSS''' will occur!}}<br />
{{Warning | Reusing the removed disk without zeroing the superblock '''WILL CAUSE LOSS OF ALL DATA''' on the next boot. (After mdadm will try to use it as the part of the raid array).}}<br />
<br />
Stop using an array:<br />
# Umount target array<br />
# Stop the array with: {{ic|mdadm --stop /dev/md0}}<br />
# Repeat the three command described in the beginning of this section on each device.<br />
# Remove the corresponding line from /etc/mdadm.conf<br />
<br />
=== Adding a New Device to an Array ===<br />
Adding new devices with mdadm can be done on a running system with the devices mounted.<br />
Partition the new device using the same layout as one of those already in the arrays as discussed above.<br />
<br />
Assemble the RAID array if it is not already assembled:<br />
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1<br />
<br />
Add the new device the array:<br />
# mdadm --add /dev/md0 /dev/sdc1<br />
<br />
This should not take long for mdadm to do. Again, check the progress with:<br />
# cat /proc/mdstat<br />
<br />
Check that the device has been added with the command:<br />
# mdadm --misc --detail /dev/md0<br />
<br />
{{Note|For RAID0 arrays you may get the following error message:<br />
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument<br />
This is because the above commands will add the new disk as a "spare" but RAID0 doesn't have spares. If you want to add a device to a RAID0 array, you need to "grow" and "add" in the same command. This is demonstrated below:<br />
# mdadm --grow /dev/md0 --raid-devices<nowiki>=</nowiki>3 --add /dev/sdc1<br />
}}<br />
<br />
=== Increasing Size of a RAID Volume ===<br />
<br />
If larger disks are installed in a RAID array or partition size has been increased, it may be desirable to increase the size of the RAID volume to fill the larger available space. This process may be begun by first following the above sections pertaining to replacing disks. Once the RAID volume has been rebuilt onto the larger disks it must be "grown" to fill the space.<br />
# mdadm --grow /dev/md0 --size=max<br />
Next, partitions present on the RAID volume {{ic|/dev/md0}} may need to be resized. See [[Partitioning]] for details. Finally, the filesystem on the above mentioned partition will need to be resized. If partitioning was performed with {{ic|gparted}} this will be done automatically. If other tools were used, unmount and then resize the filesystem manually.<br />
{{bc|<br />
# umount /storage<br />
# fsck.ext4 -f /dev/md0p1<br />
# resize2fs /dev/md0p1<br />
}}<br />
<br />
=== Change sync speed limits ===<br />
<br />
Syncing can take a while. If the machine is not needed for other tasks the speed limit can be increased.<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1] <br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 0.0% (77696/155042219) finish=265.8min speed=9712K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
Check the current speed limit.<br />
<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_min|<br />
1000<br />
}}<br />
{{hc|# cat /proc/sys/dev/raid/speed_limit_max|<br />
200000<br />
}}<br />
<br />
Increase the limits.<br />
<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_min<br />
# echo 400000 >/proc/sys/dev/raid/speed_limit_max<br />
<br />
Then check out the syncing speed and estimated finish time.<br />
<br />
{{hc|# cat /proc/mdstat|<nowiki><br />
Personalities : [raid1] <br />
md0 : active raid1 sda3[2] sdb3[1]<br />
155042219 blocks super 1.2 [2/1] [_U]<br />
[>....................] recovery = 1.3% (2136640/155042219) finish=158.2min speed=16102K/sec<br />
<br />
unused devices: <none><br />
</nowiki>}}<br />
<br />
<br />
See also [[sysctl#MDADM]].<br />
<br />
== Monitoring ==<br />
A simple one-liner that prints out the status of the RAID devices:<br />
{{hc|awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat<br />
|md1: [UU]<br />
md0: [UU]<br />
}}<br />
<br />
===Watch mdstat===<br />
{{bc|watch -t 'cat /proc/mdstat'}}<br />
Or preferably using {{pkg|tmux}}<br />
{{bc|tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"}}<br />
<br />
===Track IO with iotop===<br />
The {{pkg|iotop}} package displays the input/output stats for processes. Use this command to view the IO for raid threads.<br />
<br />
{{bc|<nowiki>iotop -a -p $(sed 's, , -p ,g' <<<`pgrep "_raid|_resync|jbd2"`)</nowiki>}}<br />
<br />
===Track IO with iostat===<br />
<br />
The ''iostat'' utility from {{Pkg|sysstat}} package displays the input/output statistics for devices and partitions.<br />
<br />
iostat -dmy 1 /dev/md0<br />
iostat -dmy 1 # all<br />
<br />
===Mailing on events===<br />
A smtp mail server (sendmail) or at least an email forwarder (ssmtp/msmtp) is required to accomplish this. Perhaps the most simplistic solution is to use {{AUR|dma}} which is very tiny (installs to 0.08 MiB) and requires no setup.<br />
<br />
Edit {{ic|/etc/mdadm.conf}} defining the email address to which notifications will be received. <br />
{{Note|If using dma as mentioned above, users may simply mail directly to the username on the localhost rather than to an external email address.}}<br />
<br />
To test the configuration:<br />
# mdadm --monitor --scan --oneshot --test<br />
<br />
[[mdadm]] includes a systemd service (mdmonitor.service) to perform the monitoring task, so at this point, you have nothing left to do. If you do not set a mail address in {{ic|/etc/mdadm.conf}}, that service will fail. If you do not want to receive mail on mdadm events, the failure can be ignored; if you don't want notifications and are sensitive about failure messages, you can mask the unit.<br />
<br />
==== Alternative method ====<br />
<br />
To avoid the installation of a smtp mail server or an email forwarder you can use the [[S-nail]] tool (don't forget to setup) already on your system.<br />
<br />
Create a file named {{ic|/etc/mdadm_warning.sh}} with:<br />
<br />
#!/bin/bash<br />
event=$1<br />
device=$2<br />
<br />
echo " " | /usr/bin/mailx -s "$event on $device" '''destination@email.com'''<br />
<br />
And give it execution permissions {{ic|chmod +x /etc/mdadm_warning.sh}}<br />
<br />
Then add this to the mdadm.conf<br />
<br />
PROGRAM /etc/mdadm_warning.sh<br />
<br />
To test and enable use the same as in the previous method.<br />
<br />
==Troubleshooting==<br />
If you are getting error when you reboot about "invalid raid superblock magic" and you have additional hard drives other than the ones you installed to, check that your hard drive order is correct. During installation, your RAID devices may be hdd, hde and hdf, but during boot they may be hda, hdb and hdc. Adjust your kernel line accordingly. This is what happened to me anyway.<br />
<br />
===Error: "kernel: ataX.00: revalidation failed"===<br />
If you suddenly (after reboot, changed BIOS settings) experience Error messages like:<br />
<br />
Feb 9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)<br />
<br />
Is doesn't necessarily mean that a drive is broken. You often find panic links on the web which go for the worst. In a word, No Panic. Maybe you just changed APIC or ACPI settings within your BIOS or Kernel parameters somehow. Change them back and you should be fine. Ordinarily, turning ACPI and/orACPI off should help.<br />
<br />
===Start arrays read-only===<br />
When an md array is started, the superblock will be written, and resync may begin. To start read-only set the kernel module {{ic|md_mod}} parameter {{ic|start_ro}}. When this is set, new arrays get an 'auto-ro' mode, which disables all internal io (superblock updates, resync, recovery) and is automatically switched to 'rw' when the first write request arrives.<br />
<br />
{{Note|The array can be set to true 'ro' mode using {{ic|mdadm --readonly}} before the first write request, or resync can be started without a write using {{ic|mdadm --readwrite}}.}}<br />
<br />
To set the parameter at boot, add {{ic|<nowiki>md_mod.start_ro=1</nowiki>}} to your kernel line.<br />
<br />
Or set it at module load time from {{ic|/etc/modprobe.d/}} file or from directly from {{ic|/sys/}}.<br />
{{bc|echo 1 > /sys/module/md_mod/parameters/start_ro}}<br />
<br />
===Recovering from a broken or missing drive in the raid===<br />
You might get the above mentioned error also when one of the drives breaks for whatever reason. In that case you will have to force the raid to still turn on even with one disk short. Type this (change where needed):<br />
# mdadm --manage /dev/md0 --run<br />
<br />
Now you should be able to mount it again with something like this (if you had it in fstab):<br />
# mount /dev/md0<br />
<br />
Now the raid should be working again and available to use, however with one disk short! So, to add that one disc partition it the way like described above in [[#Prepare the Devices|Prepare the device]]. Once that is done you can add the new disk to the raid by doing:<br />
# mdadm --manage --add /dev/md0 /dev/sdd1<br />
<br />
If you type:<br />
# cat /proc/mdstat<br />
you probably see that the raid is now active and rebuilding.<br />
<br />
You also might want to update your configuration (see: [[#Update configuration file]]).<br />
<br />
== Benchmarking ==<br />
There are several tools for benchmarking a RAID. The most notable improvement is the speed increase when multiple threads are reading from the same RAID volume.<br />
<br />
{{AUR|tiobench}} specifically benchmarks these performance improvements by measuring fully-threaded I/O on the disk.<br />
<br />
{{Pkg|bonnie++}} tests database type access to one or more files, and creation, reading, and deleting of small files which can simulate the usage of programs such as Squid, INN, or Maildir format e-mail. The enclosed [http://www.coker.com.au/bonnie++/zcav/ ZCAV] program tests the performance of different zones of a hard drive without writing any data to the disk.<br />
<br />
{{ic|hdparm}} should '''NOT''' be used to benchmark a RAID, because it provides very inconsistent results.<br />
<br />
== See also ==<br />
* [http://www.gentoo.org/doc/en/articles/software-raid-p1.xml Software RAID in the new Linux 2.4 kernel, Part 1] and [http://www.gentoo.org/doc/en/articles/software-raid-p2.xml Part 2] in the Gentoo Linux Docs<br />
* [http://raid.wiki.kernel.org/index.php/Linux_Raid Linux RAID wiki entry] on The Linux Kernel Archives<br />
* [https://raid.wiki.kernel.org/index.php/Write-intent_bitmap How Bitmaps Work]<br />
* [http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-raid.html Chapter 15: Redundant Array of Independent Disks (RAID)] of Red Hat Enterprise Linux 6 Documentation<br />
* [http://tldp.org/FAQ/Linux-RAID-FAQ/x37.html Linux-RAID FAQ] on the Linux Documentation Project<br />
* [http://support.dell.com/support/topics/global.aspx/support/entvideos/raid?c=us&l=en&s=gen Dell.com Raid Tutorial] - Interactive Walkthrough of Raid<br />
* [http://www.miracleas.com/BAARF/ BAARF] including ''[http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt Why should I not use RAID 5?]'' by Art S. Kagel<br />
* [http://www.linux-mag.com/id/7924/ Introduction to RAID], [http://www.linux-mag.com/id/7931/ Nested-RAID: RAID-5 and RAID-6 Based Configurations], [http://www.linux-mag.com/id/7928/ Intro to Nested-RAID: RAID-01 and RAID-10], and [http://www.linux-mag.com/id/7932/ Nested-RAID: The Triple Lindy] in Linux Magazine<br />
* [http://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html HowTo: Speed Up Linux Software Raid Building And Re-syncing]<br />
* [http://fomori.org/blog/?p=94 RAID5-Server to hold all your data]<br />
<br />
'''Active bugs'''<br />
* [http://marc.info/?l=linux-raid&m=144960710718870&w=2 linux-raid ML #1]<br />
* [http://marc.info/?l=linux-raid&m=144830809503689&w=2 linux-raid ML #2]<br />
<br />
'''mdadm'''<br />
* [http://anonscm.debian.org/gitweb/?p=pkg-mdadm/mdadm.git;a=blob_plain;f=debian/FAQ;hb=HEAD Debian mdadm FAQ]<br />
* [http://www.kernel.org/pub/linux/utils/raid/mdadm/ mdadm source code]<br />
* [http://www.linux-mag.com/id/7939/ Software RAID on Linux with mdadm] in Linux Magazine<br />
<br />
'''Forum threads'''<br />
* [http://forums.overclockers.com.au/showthread.php?t=865333 Raid Performance Improvements with bitmaps]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=125445 GRUB and GRUB2]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=123698 Can't install grub2 on software RAID]<br />
* [http://forums.gentoo.org/viewtopic-t-888624-start-0.html Use RAID metadata 1.2 in boot and root partition]<br />
<br />
'''RAID with encryption'''<br />
* [http://www.shimari.com/dm-crypt-on-raid/ Linux/Fedora: Encrypt /home and swap over RAID with dm-crypt] by Justin Wells</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Transmission_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516535
Transmission (简体中文)
2018-04-09T14:26:10Z
<p>Arisaka: Full sync with English Version.</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:BitTorrent clients]]<br />
[[de:Transmission]]<br />
[[en:Transmission]]<br />
[[fr:Transmission]]<br />
[[it:Transmission]]<br />
[[ja:Transmission]]<br />
{{TranslationStatus (简体中文)|Transmission|2018-04-09|507716}}<br />
[http://www.transmissionbt.com/ Transmission] 是一个轻量级、跨平台的 BitTorrent 客户端。<br />
<br />
== 安装 ==<br />
<br />
有多种可选的软件包:<br />
* {{Pkg|transmission-cli}} - 包括命令行工具、守护程序和 [[#Web 界面]]。<br />
* {{Pkg|transmission-gtk}} - GTK+ 3 图形界面.<br />
* {{Pkg|transmission-qt}} - Qt5 图形界面.<br />
* {{AUR|tremc-git}} - 用于守护程序的 Curses 界面。<br />
<br />
{{注意| GTK+ 客户端无法连接至守护程序,想用守护程序的用户可以考虑带图形界面的 Qt 包,或是带 Curses 界面的 tremc 包。}}<br />
<br />
== 图形界面的配置 ==<br />
<br />
两种带 GUI 的版本 ''transmission-gtk'' 和 ''transmission-qt'' 都可以在没有后端守护程序的情况下独立运行。<br />
<br />
GUI 版本都被配置为开箱即用,但用户可能仍需要更改一些设置。GUI 配置文件的默认路径是 {{ic|~/.config/transmission}}。<br />
<br />
在 Transmission 的网站上,有一份各种选项如何配置的教程:<br />
https://github.com/transmission/transmission/wiki/Editing-Configuration-Files.<br />
<br />
== Transmission 守护程序和命令行 ==<br />
<br />
''transmission-cli'' 支持的命令包括:<br />
:''transmission-daemon'': 启动守护程序。<br />
:''transmission-remote'': 调用本地或远程守护程序的 [[Wikipedia:Command-line interface|命令行界面]],后面跟着希望守护程序运行的命令。<br />
:''transmission-show'': 返回指定种子文件的信息。<br />
:''transmission-create'': 创建一个新的种子文件。<br />
:''transmission-edit'': 新增、删除或替换一个 tracker 服务器的 announce URL。<br />
:''transmission-cli'': ([https://github.com/transmission/transmission/commit/950387ab5a443629598f93c057f41150707866ab 已弃用]) 启动一个非守护程序的本地 ''transmission'' 实例,用于手动下载一个种子。<br />
:''tremc'': (需要 {{AUR|tremc-git}}) 为本地或远程守护程序启动一个 [[Wikipedia:curses (programming library)|curses]] 界面。<br />
<br />
=== 守护程序的启动与停止 ===<br />
<br />
就像 [[#选择一个用户]] 里面的说明那样,transmission 的守护程序可以按以下方式运行:<br />
<br />
* 作为 ''transmission'' 用户运行,只要 [[systemd (简体中文)#使用单元|用 systemd]] start/enable {{ic|transmission.service}} 服务即可。<br />
: 你可以按照 [[#选择一个用户]] 里的说明更改默认用户。<br />
<br />
* 用你自己的账户,只要在账户下运行:{{bc|$ transmission-daemon}} 守护程序可以这样来停止:{{bc|$ killall transmission-daemon}}<br />
<br />
启动守护程序将会创建一个初始的 ''transmission'' 配置文件。详情参阅 [[#配置守护程序]]。<br />
<br />
另一种停止 transmission 的方法是使用 ''transmission-remote'' 命令:<br />
$ transmission-remote --exit<br />
<br />
<br />
=== 减少多余的日志 ===<br />
<br />
运行 transmission-daemon 可能会产生许多不需要的日志条目。只要用一个小脚本包装一下再启动就可以过滤日志输出。以下示例可以提供一些启发:<br />
{{hc|transwrap.sh|<nowiki><br />
#!/bin/zsh<br />
killall transmission-daemon 2> /dev/null<br />
transmission-daemon --foreground --log-info 2>&1 | while read line; do<br />
echo $line |<br />
grep -v "announcer.c:\|platform.c:\|announce done (tr-dht.c:" |<br />
grep -v "Saved.*variant.c:" |<br />
while read line; do<br />
echo $line | grep -q "Queued for verification (verify.c:" &&<br />
notify-send --app-name="Transmission Started" "${line#* * }"<br />
echo $line | grep -q "changed from .Incomplete. to .Complete." &&<br />
notify-send --app-name="Transmission Complete" "${line#* * }"<br />
echo $line | systemd-cat --identifier="TransWrap" --priority=5<br />
done 2>&1 > /dev/null<br />
done&disown<br />
</nowiki><br />
}}<br />
<br />
=== 仅当连接到网络时运行 ===<br />
<br />
==== Netctl ====<br />
<br />
你可能只想在连接某些网络时运行 transmission。下面的脚本会先检查连接是否在授权的网络列表中,是的话再继续启动 transmission-daemon。<br />
<br />
{{hc|/etc/netctl/hooks/90-transmission.sh|<nowiki><br />
#!/bin/bash<br />
<br />
# The SSIDs for which we enable this.<br />
declare -A ssids=(<br />
["network_1"]=y<br />
["network_2"]=y<br />
)<br />
<br />
if [[ ${ssids[$SSID]} ]]; then<br />
case $ACTION in<br />
CONNECT|REESTABLISHED)<br />
# Need to wait, otherwise doesn't seem to bind to 9091.<br />
sleep 30<br />
systemctl start transmission<br />
;;<br />
*)<br />
systemctl stop transmission<br />
;;<br />
esac<br />
fi<br />
</nowiki><br />
}}<br />
<br />
==== Wicd ====<br />
<br />
在文件夹 {{ic|/etc/wicd/scripts/postconnect}} 里创建一个 [[#守护程序的启动与停止|启动脚本]],并且在文件夹 {{ic|/etc/wicd/scripts/predisconnect}} 里创建一个 [[#守护程序的启动与停止|停止脚本]]。记得给它们运行权限,例如:<br />
<br />
{{hc|/etc/wicd/scripts/postconnect/transmission|2=<br />
#!/bin/bash<br />
<br />
systemctl start transmission<br />
}}<br />
{{hc|/etc/wicd/scripts/predisconnect/transmission|2=<br />
#!/bin/bash<br />
<br />
systemctl stop transmission<br />
}}<br />
<br />
=== 选择一个用户 ===<br />
<br />
选择你想如何运行 {{ic|transmission}}:<br />
<br />
* 作为独立用户运行,默认用户是 {{ic|transmission}}(推荐,因为安全性更高)。<br />
默认情况下,''transmission'' 会创建名为 {{ic|transmission}} 的用户和组(它的主目录的文件位于 {{ic|/var/lib/transmission/}}),并且用这个“账户”运行。这是一种安全措施,因为这样 ''transmission'' 及其下载的文件将无法访问 {{ic|/var/lib/transmission/}} 目录之外的文件。配置、操作和访问下载的文件需要使用 “root” 权限完成(比如用 [[sudo]])。<br />
<br />
* 在你自己的账户下运行。<br />
设置这种方式需要 [[systemd (简体中文)#修改现存单元文件|重写]] 已提供的服务文件并在其中指定你的用户名:<br />
<br />
{{hc|/etc/systemd/system/transmission.service.d/username.conf|2=<br />
[Service]<br />
User=''your_username''<br />
}}<br />
<br />
=== 配置守护程序 ===<br />
<br />
[[#守护程序的启动与停止|启动守护程序]] 来创建缺省的配置文件。<br />
<br />
* 如果用 {{ic|transmission}} 这个用户来运行 Transmission,配置文件会存放在 {{ic|/var/lib/transmission/.config/transmission-daemon/settings.json}}。<br />
<br />
* 如果用你自己的账户运行 Transmission,配置文件会存放在 {{ic|~/.config/transmission-daemon/settings.json}}。<br />
<br />
使用一个 Transmission 客户端或者用自带的 web 界面(在支持的浏览器中用 http://localhost:9091 来访问)可以自定义守护程序。<br />
<br />
在 Transmission 的网站上,有一份各种选项如何配置的教程:https://github.com/transmission/transmission/wiki/Editing-Configuration-Files<br />
<br />
{{注意|如果你想用一个文本编辑器手动编辑配置文件,请先 [[#守护程序的启动与停止|停止守护程序]];否则当它停止时将会覆盖配置文件。}}<br />
{{注意|另一种方式是,可以用 SIGHUP 信号指示守护程序重新加载其配置,运行 {{ic|kill -s SIGHUP `pidof transmission-daemon`}} 即可。}}<br />
<br />
一个给那些用 {{ic|transmission}} 账户运行的用户的建议是,用适当的权限创建一个共享的下载目录,这样就能同时允许 {{ic|transmission}} 账户和其他账户访问下载文件,也能相应地更新配置文件。例如:<br />
# mkdir /mnt/data/torrents<br />
# chown -R facade:transmission /mnt/data/torrents<br />
# chmod -R 775 /mnt/data/torrents<br />
<br />
现在 {{ic|/mnt/data/torrents}} 目录可供系统账户 {{ic|facade}} 和 {{ic|transmission}} 用户所属的 {{ic|transmission}} 组访问。非常不鼓励使这个目录可读写(即不要将目录 ''chmod'' 到 ''777''),而是应该将个别用户/组的部分权限授予部分目录。<br />
<br />
{{注意|如果 {{ic|/mnt/data/torrents}} 位于一个可移除的设备上,比如这是一个 {{ic|/etc/fstab}} 条目且带有 {{ic|nofail}} 选项,那么 Transmission 会报告说没有找到文件。要解决这个问题,可以在 {{ic|/etc/systemd/system/transmission.service.d/transmission.conf}} 文件的 {{ic|[Unit]}} 一节中加入 {{ic|1=RequiresMountsFor=/mnt/data/torrents}}。}}<br />
<br />
另一种方法是把你的账户加入 {{ic|transmission}} 用户组 ({{ic|#usermod -a -G transmission yourusername}}),然后修改 {{ic|/var/lib/transmission}} 和 {{ic|/var/lib/transmission/Downloads}} 目录的权限设置,以允许 {{ic|transmission}} 组成员对这两个目录的 {{ic|rwx}} 访问权。<br />
<br />
==== Host 白名单 ====<br />
<br />
如果你想用远程主机的主机名来访问位于该主机上的 Transmission 守护程序,你需要把主机名加入 {{ic|settings.json}} 文件中的 {{ic|rpc-host-whitelist}} 字段中。<br />
否则你会在连接主机时收到一条 "421 Misdirected Request" 错误。<br />
<br />
如果你用该服务器的 IP 地址来访问守护程序,这一步可以省略。<br />
<br />
==== 监视目录 ====<br />
<br />
如果你想 ''自动添加某个文件夹中的 .torrent 文件'',但是配置文件中的 {{ic|watch-dir}} 和 {{ic|watch-dir-enabled}} 选项都不起作用,可以带 {{ic|-c /path/to/watch/dir}} 参数启动 transmission 守护程序。<br />
<br />
如果你在用 systemd,按照 [[systemd (简体中文)#修改现存单元文件]] 里面的描述编辑 {{ic|transmission.service}} 单元文件。<br />
<br />
==== 启用 IPv6 ====<br />
<br />
默认情况下,守护程序仅监听 IPv4 连接。要同时监听 IPv6 连接,安装 {{AUR|transmission-cli-ipv6}} (或者 {{AUR|transmission-cli-git}},或者等 Transmission 3.0 发布),然后把 {{ic|settings.json}} 里的 {{ic|rpc-bind-address}} 选项改为 {{ic|"::"}}。<br />
<br />
==== CLI 使用示范 ====<br />
<br />
如果你想删除所有已完成的种子,可以用下面的命令(用你自己的用户名和密码):<br />
# transmission-remote -n 'username:password' -l | grep 100% | awk '{print $1}'| paste -d, -s | xargs -i transmission-remote -t {} -r<br />
<br />
== Web 界面 ==<br />
<br />
=== GUI 方式 ===<br />
<br />
当 Transmission 安装完毕后就可以轻易架起 web 界面。你只需要单击 '''edit''' 菜单,选择 '''preferences'''。单击 '''Remote''' 选项卡并启用 '''Allow remote access'''。<br />
<br />
此处你可以修改默认的监听端口 9091。<br />
<br />
单击 '''Use authentication''' 并填写用户名和密码就可以启用身份认证。<br />
<br />
要提高安全性,可以启用 '''Only allow these IP addresses''' 限制来自任意 IP 的访问。<br />
<br />
现在你可以单击 '''Open web client''' (用你的默认浏览器打开)或手动访问 {{ic|http://''TARGET_IP_ADDRESS'':''PORT''}} 来启动 web 界面。<br />
<br />
如果没有修改监听端口,默认是 9091。在这种情况下访问链接是 {{Ic|http://localhost:9091}}。<br />
<br />
{{注意|记住,必须安装 {{Pkg|transmission-cli}}。}}<br />
<br />
=== CLI 方式 ===<br />
<br />
设置 web 界面甚至不需要借助图形界面,因为守护程序提供了类似的选项。你无需指定任何参数即可访问 web 界面,可参阅 [[#守护程序的启动与停止]]。<br />
<br />
不过,你仍然可以指定在前一节中看到的所有选项:<br />
<br />
{{bc|$ transmission-daemon --auth --username arch --password linux --port 9091 --allowed "127.0.0.1"}} <br />
等同于<br />
{{bc|$ transmission-daemon -t -u arch -v linux -p 9091 -a "127.0.0.1"}}<br />
<br />
== 故障排除 ==<br />
<br />
==== 无法使用网络连接至守护程序 ====<br />
<br />
在 {{ic|network.service}} 初始化后守护程序就会开始运行。但是,如果启用了 {{ic|dhcpcd}} 服务而不是特定设备的服务(比如 {{ic|dhcpcd@enp1s0.service}}),可能 Transmission 会因为启动过早而无法绑定到相应的网络接口。于是 web 界面无法访问。一种可能的解决方案是在 systemd 单元的 [[systemd (简体中文)#修改现存单元文件|配置文件]] 里增加 {{ic|Requires}} 行。<br />
<br />
{{hc|/etc/systemd/system/transmission.service.d/fixdep.conf|2=<br />
[Unit]<br />
Requires=network.target<br />
}}<br />
<br />
==== 无法显示 Web 界面 ====<br />
<br />
{{bc|404: Not Found<br />
<br />
Couldn't find Transmission's web interface files!<br />
<br />
Users: to tell Transmission where to look, set the TRANSMISSION_WEB_HOME environment variable to the folder where the web interface's index.html is located.<br />
<br />
Package Builders: to set a custom default at compile time, #define PACKAGE_DATA_DIR in libtransmission/platform.c or tweak tr_getClutchDir () by hand.}}<br />
<br />
即使你用图形界面,也需要安装 {{Pkg|transmission-cli}} 来支持 web 界面。<br />
<br />
== 更多信息 ==<br />
*[https://trac.transmissionbt.com/wiki Transmission 维基]<br />
*[https://trac.transmissionbt.com/wiki/HeadlessUsage/General HeadlessUsage]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=516417
Mathematica (简体中文)
2018-04-07T12:40:42Z
<p>Arisaka: </p>
<hr />
<div>[[Category:Mathematics and science (简体中文)]]<br />
[[en:Mathematica]]<br />
[[it:Mathematica]]<br />
[[ja:Mathematica]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Scientific Applications (简体中文)}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Mathematica|2018-04-07|516199}}<br />
<br />
[http://www.wolfram.com/mathematica/ Mathematica] 是用于科学,工程和数学领域的商业软件。在这里我们说明如何安装它。<br />
<br />
== 安装 ==<br />
<br />
由于 Mathematica 是专有软件,升级可能会产生成本,因此本节列出了不同可用版本的说明。<br />
<br />
=== Mathematica 6 ===<br />
<br />
==== 挂载 iso 文件 ====<br />
<br />
挂载 Mathematica {{ic|.iso}} 的一种方式是创建 {{ic|/media/iso}} 目录用于挂载,并在 [[fstab]] 中增加这几行:<br />
/''location/of/mathematica.iso'' /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
然后就可以这样挂载它:<br />
# mount /media/iso<br />
<br />
==== 运行安装程序 ====<br />
<br />
进入这个目录来启动安装程序:<br />
/Unix/Installer<br />
运行 ''MathInstaller'':<br />
sh ./MathInstaller<br />
{{注意|如果没有把 "sh" 放在前面,那么会得到一个关于解释器出错 (bad interpreter) 的错误信息。}}<br />
<br />
==== 字体 ====<br />
<br />
向 FontPath 里添加包含 Type1 和 BDF 字体的目录。<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 安装起来非常方便。<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
按照指示完成即可。<br />
<br />
KDE 用户注意,Mathematica 的图标可能会出现在 ''Lost & Found'' 分类里面。解决方法是以 root 用户身份运行下列命令:<br />
<br />
# ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
=== Mathematica 8 ===<br />
<br />
Mathematica 8 的一个问题是执行 WolframAlpha[ ] 函数时会出现崩溃,这个崩溃可以重现。Mathematica 的默认配置为,在设置如何连接到互联网以获取数据时,检测系统的代理设置。但是在调用库函数时存在一个 bug,最终会使 Mathematica 崩溃。解决方法是通过将 Mathematica 配置为“直接连接”到互联网来完全避免此库调用 (''Edit > Preferences > Internet Connectivity > Proxy Settings'')。这个错误已经报告给 Wolfram。<br />
<br />
=== Mathematica 10 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}} (需要旧版本)。需要 {{ic|Mathematica_10.XX.YY_LINUX.sh}} 安装脚本,从 Wolfram.com 或某大学的站点上下载。同时你还需要一个激活密钥。<br />
<br />
=== Mathematica 11 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}}。从 Wolfram Research 获取 {{ic|Mathematica_11.XX.YY_LINUX.sh}} 和激活密钥。成功的安装可能也会抛出一些不严重的错误:xdg-icon-resource, mkdir, xdg-desktop-menu 等。<br />
<br />
Mathematica 11 在 [https://reference.wolfram.com/language/ref/$UserDocumentsDirectory.html $UserDocumentsDirectory] 自动创建 'Wolfram Mathematica' 文件夹,Mathematica 根据 [[XDG user directories]] 自动设置了这个变量。<br />
<br />
== 故障排除 == <br />
<br />
=== "Missing symbols" 错误 ===<br />
<br />
如果出现字体渲染问题,某些符号无法显示(比如 {{ic|/}} 显示为正方形),请尝试卸载 {{Pkg|font-mathematica}}。<br />
<br />
同时,尝试 [http://mathematica.stackexchange.com/questions/1158/invisible-conjugate-glyph-in-the-linux-frontend 这种] 方案。其中还说明了 Mathematica 版本 9 修复了这个问题。<br />
<br />
尝试让应用程序使用抗锯齿。<br />
对于 KDE 用户: ''System Settings > Application Appearance > Fonts > Use anti-aliasing (Enabled)''<br />
<br />
=== HiDPI / Retina 屏幕 ===<br />
<br />
如果你有一块 [[HiDPI]] 屏幕,比如 Apple Retina 屏幕,而且 Mathematica 里面的文字非常小,这样就能解决:<br />
<br />
* 打开 ''Edit → Preferences''<br />
* 在 ''Advanced'' 选项卡里单击 ''Open Option Inspector''<br />
* 在右侧的树状列表中找到 ''Formatting Options → Font Options → Font Properties''<br />
* 改变 ''"ScreenResolution"'' 的值到它原来的两倍大小,比如 72 → 144。你也可以用 <code>xdpyinfo | grep resolution</code> 来获得一个更精确的数字(也要变成原来的两倍大小)。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Official site]<br />
* [http://www.wolfram.com/support/ Official Support]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=User_talk:Arisaka&diff=515911
User talk:Arisaka
2018-04-04T10:01:57Z
<p>Arisaka: </p>
<hr />
<div>== 欢迎加入中文翻译组 ==<br />
看到你刚翻译了 [[General troubleshooting (简体中文)]],这个是我之前一直想翻译但是没找到时间的。大致浏览了一下,翻译质量非常高,感谢。最近花在 Arch wiki 上的时间不多,有什么问题可以发邮件或者在我的讨论页面留言。--[[User:Fengchao|Fengchao]] ([[User talk:Fengchao|talk]]) 01:46, 4 April 2018 (UTC)<br />
: 感谢前辈关注,初来参与,翻译出的页面上要是有什么问题或者不完善的还请指出。我从现在起到今年(18年)7月底都有时间可以在 Arch wiki 上持续翻译,8月份工作之后要视情况而定(加班应该不会太多)。若有你认为迫切需要翻译的页面也请告诉我,我觉得 wiki 上还有很多页面需要同步,目前是尽量挑常用的页面和我自己常用软件的说明页面来翻译。 --[[User:Arisaka|Arisaka]] ([[User talk:Arisaka|talk]]) 10:01, 4 April 2018 (UTC)</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Su_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515656
Su (简体中文)
2018-04-03T03:06:10Z
<p>Arisaka: Sync with English version.</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:简体中文]]<br />
[[Category:Security (简体中文)]]<br />
[[en:Su]]<br />
[[es:Su]]<br />
[[fa:su]]<br />
[[fr:su]]<br />
[[ja:su]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Users and groups (简体中文)}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related articles end}}<br />
{{TranslationStatus (简体中文)|su|2018-04-03|502924}}<br />
<br />
'''su''' 命令 ('''s'''ubstitute '''u'''ser) 用来切换当前用户身份到其他用户身份,默认切换成 root。<br />
<br />
参阅 [[PAM]] 可以找到配置 '''su''' 其他特性的方法。<br />
<br />
== 安装 ==<br />
su 是 {{Pkg|util-linux}} 包的一部分,默认已经作为 {{Grp|base}} 组的一部分安装到 Arch 中了。<br />
<br />
== 用法 ==<br />
要切换到其他用户身份,将要切换的用户名传递给 su,像这样:<br />
<br />
# su ''username''<br />
<br />
然后就能看到提示符,要求输入所要切换用户的密码。<br />
<br />
如果没有传入用户名,su 默认切换为 root 用户,要求输入的密码也应该是 root 用户的密码。<br />
<br />
== 另一个选择:Sudo ==<br />
<br />
{{Merge|sudo|这些文档应该在 [[sudo]] 页面上显示。}}<br />
{{Merge|Security#Use_sudo_instead_of_su|在 [[Security]] 页面上论述了相同的主题。}}<br />
<br />
[[sudo]] 可以提供和 su 类似的功能,且更加可定制化,根据具体要求和威胁模型分析,可以作为 su 的一个替代。sudo 系统会提示你输入你自己的密码,或者根本没有密码(如果以这种方式配置的话),而不是目标用户(你正试图使用的帐户)的密码。这样就不必在用户之间共享密码,并且如果需要阻止一个用户获得 root 权限(或获得其他用户权限),则无需更改 root 密码(更改密码将给其他人造成不便),你只需要撤销该用户的 sudo 访问权。<br />
<br />
如果 sudo 被配置为允许用户以 root 身份运行 shell,那么用户只要用 {{ic|sudo -s}} 或 {{ic|sudo -i}} 命令就可以分别模拟出 {{ic|su}} 或 {{ic|su -l}} 命令的效果,而且是用他自己的密码(或没有密码),而不是 root 的密码。同样,如果允许以 john 身份运行 shell,{{ic|sudo -u john -i}} 和 {{ic|su -l john}} 效果一样。<br />
<br />
== 提示和技巧 ==<br />
=== “登录至”其他用户 ===<br />
su 的默认行为是保持在当前目录中并保持原始用户的环境变量(而不是切换到新用户的环境变量)。<br />
<br />
这一特性的优劣需要注意以下重要的对比因素:<br />
<br />
* 系统管理员可以使用普通用户的 shell 而不是自己的。特别是在有些时候,解决用户问题的最有效的方法,就是登录到该用户的帐户以重现问题或进行调试。<br />
<br />
* 但是通常情况下,root 用户不能登录普通用户的 shell 并使用该用户的环境变量进行操作,而是用自己的环境变量操作,这在很多情况下是不可取的,甚至是危险的。在无意中使用普通用户的 shell 时,root 可能会安装程序,或对系统进行其他更改,而这些更改与使用 root 帐户时所做的结果不同。例如,可能会安装某个程序,使得普通用户能够意外地损坏系统或未经授权访问某些数据。<br />
<br />
因此,建议系统管理员以及被授权使用 su 的任何其他用户(建议只有极少数用户),始终保持用 {{ic|-l}} 或 {{ic|--login}} 选项运行 su 命令的习惯。它有两个作用:<br />
# 通过 ''登录至'' 目标用户,从当前工作目录切换到目标用户的主目录(比如切换到 root 用户就是 {{ic|/root}})。<br />
# 根据目标用户的 {{ic|~/.bashrc}} 切换到目标用户的环境变量。也就是说,当前工作目录和环境将会切换到和目标用户登录新会话时一样的目录和环境(而不是仅接管现有用户的会话)。<br />
<br />
因此,管理员通常应该这样使用 su:<br />
$ su -l<br />
<br />
添加用户名 root 结果一样:<br />
$ su -l root<br />
<br />
对于任何其他用户(如名为 archie 的用户),同样可以做到:<br />
# su -l archie<br />
<br />
你可能希望在 {{ic|~/.bashrc}} 里为这个规则添加一个 alias:<br />
<br />
alias su="su -l"<br />
<br />
=== su 和 wheel 用户组 ===<br />
BSD su 默认仅允许 "wheel" [[Users and groups (简体中文)#用户组管理|用户组]] 成员切换至 root 身份。而 GNU su 默认没有这一特性,可以使用 [[PAM (简体中文)|PAM]] 来模拟这一特性。将 {{ic|/etc/pam.d/su}} 和 {{ic|/etc/pam.d/su-l}} 中相应的行取消注释:<br />
<br />
auth required pam_wheel.so use_uid</div>
Arisaka
https://wiki.archlinux.org/index.php?title=General_troubleshooting_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515601
General troubleshooting (简体中文)
2018-04-02T15:36:35Z
<p>Arisaka: </p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:System administration (简体中文)]]<br />
[[Category:System recovery (简体中文)]]<br />
[[Category:Getting and installing Arch (简体中文)]]<br />
[[en:General troubleshooting]]<br />
[[es:General troubleshooting]]<br />
[[ja:一般的なトラブルシューティング]]<br />
[[ru:General troubleshooting]]<br />
{{Related articles start}}<br />
{{Related|Reporting bug guidelines (简体中文)}}<br />
{{Related|Step-by-step debugging guide}}<br />
{{Related|Debug - Getting Traces (简体中文)}}<br />
{{Related|IRC Collaborative Debugging}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|General troubleshooting|2018-04-02|515594}}<br />
<br />
本文介绍了一些常规的故障排除方法。有关特定应用程序的问题,请参阅该特定程序的 wiki 页面。<br />
<br />
== 常用手段 ==<br />
<br />
=== 注意细节 ===<br />
<br />
为了解决遇到的问题,对当前使用的这个程序,你应该有一个基本的了解,这是 ''至关重要'' 的。它是如何工作的,它依赖什么才能正常运行?如果不能很好地回答这些问题,最好阅读一下这些出错程序的 [[Table of contents (简体中文)|Archwiki]] 文章。一旦你觉得你已经理解了它,你将更容易找出问题的原因。<br />
<br />
=== 常见问题 / 检查项 ===<br />
<br />
下面列出了许多常见问题,用于排查故障。在每个问题下都有注释,说明你该如何回答这个问题,紧接着的是一些如何收集数据的简单示例,还有查看各种日志的工具。<br />
<br />
# 出现了什么故障?<br />
#: 请尽可能精确地描述问题,这将帮助你在查找特定信息的时候不至感到困惑或扯到别的方面去。<br />
# 是否显示了错误信息?(如果有的话)<br />
#: 将包含相关 '''错误信息''' 的 ''完整输出'' 复制并粘贴到类似 {{ic|$HOME/issue.log}} 这样单独的文件中。例如,可以将以下 [[mkinitcpio (简体中文)|mkinitcpio]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ mkinitcpio -p linux >> $HOME/issue.log}}<br />
# 可以复现这个故障码?<br />
#: 如果是这样,请 '''按步骤''' 给出 ''确切的'' 指示/命令来做到这一点。<br />
# 第一次遇到这些故障的时间,以及从没有故障到故障发生之间你修改了什么内容?<br />
#:如果这种情况发生在某次升级之后,可以列出 '''所有已升级的包'''。包括 ''版本号'',同时粘贴 [[pacman]].log ({{ic|/var/log/pacman.log}}) 的升级日志。使用 [[Systemd (简体中文)|systemd]] 的 systemctl 工具检查故障程序依赖的 ''所有'' 服务的运行状态。例如,可以将 [[Systemd (简体中文)#systemd 基本工具|systemd]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ systemctl status dhcpcd@eth0.service >> $HOME/issue.log}}<br />
#: {{注意|使用 {{ic|'''>>'''}} 可以保证 {{ic|$HOME/issue.log}} 中之前保存的内容不会被覆盖。}}<br />
<br />
=== 寻求解决 ===<br />
<br />
不要通过这样的表述来寻求问题的解决:<br />
<br />
''程序 X 不工作了。''<br />
<br />
描述整个系统的环境更有助于解决问题,比如:<br />
<br />
''应用程序 X 在执行 Z 任务时,会报出 Y 错误,条件是 A 和 B。''<br />
<br />
=== 额外支援 ===<br />
<br />
利用你眼前的所有信息,你应该对系统里发生了什么有一个较好的认识,并且可以开始着手修复了。<br />
<br />
如果需要额外支援,[https://bbs.archlinux.org 官方论坛] 或 IRC (irc.freenode.net 上的 #archlinux 频道) 都可以提供帮助。更多频道可参考 [[IRC channels]]。<br />
<br />
{{注意|[[Code of conduct (简体中文)#仅支持 Arch Linux|技术支持 ''仅限于'' Arch Linux]] 而非 [[Arch-based distributions (简体中文)|基于 Arch 的发行版]]。}}<br />
<br />
当要求贴出 '''完整''' 的 输出 / 日志 时,不能仅仅贴出你认为的重要部分。信息来源应该包括:<br />
<br />
* 所有涉及到的命令的完整输出,不要只选择你认为相关的东西。<br />
* 来自 systemd 的 {{ic|journalctl}} 的输出。要获取更多的输出,请使用 {{ic|1=systemd.log_level=debug}} 引导参数。<br />
* 日志文件(看一下 {{ic|/var/log}} 目录)<br />
* 相关的配置文件<br />
* 相关的驱动程序<br />
* 相关软件包的版本<br />
* 内核相关:{{ic|dmesg}}。对于启动问题,至少贴出最后 10 行,多贴一些当然更好。<br />
* 网络相关:相关命令的完整输出,再加上所有相关配置文件。<br />
* Xorg 相关: {{ic|/var/log/Xorg.0.log}},如果你已经覆盖了出问题的日志,就贴在这之前的日志。<br />
* Pacman 相关:如果最近的更新弄坏了什么东西,请到 {{ic|/var/log/pacman.log}} 找它。<br />
<br />
贴出这些信息有一个更好的方式,就是使用在线剪贴板 (pastebin)。你可以 [[install|安装]] {{pkg|pbpst}} 或 {{pkg|gist}} 来自动上传信息。例如,要上传这次启动以来的 systemd 日志,可以这么做:<br />
<br />
# journalctl -xb | pbpst -S<br />
<br />
这将返回一个链接,你可以把它贴到论坛或 IRC。<br />
<br />
另外,在提问之前,请先阅读 [http://www.catb.org/esr/faqs/smart-questions.html 提问的智慧] 和 [[Code of conduct (简体中文)|行为准则]]。<br />
<br />
== 系统启动问题 ==<br />
<br />
诊断 [[boot process (简体中文)|启动过程]] 中的问题主要是修改 [[kernel parameters (简体中文)|内核参数]],然后重启系统。<br />
<br />
如果系统无法启动,可以从 [https://www.archlinux.org/download/ live 镜像] 启动并 [[change root (简体中文)|chroot]] 到现有系统。<br />
<br />
=== 控制台的输出信息 ===<br />
<br />
在启动过程完成以后,屏幕会被清空并显示登录提示符,这使得用户无法看到初始化过程中的输出和其中的错误信息。这一默认特性可以使用接下来几节中的方法进行修改。<br />
<br />
请注意,无论选择下面哪个方法,在启动后通过使用 {{ic|dmesg}} 或 {{ic|journalctl -b}} 都可以显示内核消息,用于检查错误。<br />
<br />
==== 输出流控制 ====<br />
<br />
以下是适用于大多数终端模拟器的基本操作,包括虚拟终端 (vc):<br />
<br />
* 按 {{ic|Ctrl+S}} 暂停输出<br />
* 按 {{ic|Ctrl+Q}} 继续输出<br />
<br />
这样不仅会暂停输出,而且会暂停尝试打印到终端的程序,即暂停输出时会阻塞 {{ic|write()}} 调用。 如果你的 ''init'' 进程出现冻结,请确保系统控制台没有暂停。<br />
<br />
要查看已经显示过的错误信息,参见 [[Getty#Have boot messages stay on tty1]]。<br />
<br />
==== 回滚显示 ====<br />
<br />
回滚显示允许用户查看已经从控制台滚动过去并消失的文字内容。这通常是在视频适配器和显示设备之间创建缓冲(称为回滚缓冲区)实现的。默认情况下,将缓冲的内容上下滚动的快捷键是 {{ic|Shift+PageUp}} 和 {{ic|Shift+PageDown}}。<br />
<br />
如果回滚内容没有完全包含足够的信息,可能需要扩大回滚缓冲区的大小来容纳更多输出。这可以通过配置内核的 framebuffer console(fbcon,帧缓冲控制台)来实现,修改 [[kernel parameter|内核参数]] {{ic|1=fbcon=scrollback:Nk}} 即可,其中 {{ic|N}} 是缓冲区大小,单位是 kB,默认是 32k。<br />
<br />
如果这不奏效,你的 framebuffer console 可能没有正确地启用。参阅 [https://www.kernel.org/doc/Documentation/fb/fbcon.txt Framebuffer Console documentation] 来查找其他影响参数,比如修改帧缓冲驱动。<br />
<br />
==== Debug 输出 ====<br />
<br />
在启动时,大部分来自内核的消息都是隐藏的,可以加入不同的内核参数来输出更多信息。最简单的是这些:<br />
<br />
* {{ic|debug}} 可以同时启用来自内核和 [[Systemd (简体中文)|systemd]] 的调试信息<br />
* {{ic|ignore_loglevel}} 强制显示 ''所有'' 内核消息<br />
<br />
在特定情况下有用的其他参数如下:<br />
* {{ic|1=earlyprintk=vga,keep}} 在早期启动过程中就输出内核消息,用于内核在有输出前就崩溃的情况下。在 [[Unified Extensible Firmware Interface (简体中文)|EFI]] 系统上要把 {{ic|vga}} 改成 {{ic|efi}}。<br />
* {{ic|1=log_buf_len=16M}} 用于分配一个更大 (16MB) 的内核消息缓冲区,用来保证 debug 输出不被覆盖。<br />
<br />
还有很多独立的调试参数,用于在特定的子系统中启用调试,例如 {{ic|bootmem_debug}} 和 {{ic|sched_debug}}。更多详细信息请参考 [https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt kernel parameter documentation]。<br />
<br />
{{注意|如果无法回滚的足够远以查看所需的启动输出,你需要扩大 [[#回滚显示|回滚缓冲区]] 的大小。}}<br />
<br />
=== 故障恢复控制台 ===<br />
<br />
在启动过程中的某个阶段获取一个交互式 shell 可以帮助你准确找出问题出在哪里,以及为何失败。有几个内核参数可以做到这一点,但它们都启动了一个正常的shell,可以随时 {{ic|exit}} 让内核恢复正在执行的操作:<br />
* {{ic|rescue}} 在根文件系统刚刚被挂载为读写模式的时候启动一个 shell<br />
* {{ic|emergency}} 可以在更早的时候启动 shell,早于大部分文件系统挂载之前<br />
* {{ic|1=init=/bin/sh}}(作为最后的选择)把 init 程序改成 root shell。因为 {{ic|rescue}} 和 {{ic|emergency}} 都依赖于 [[Systemd (简体中文)|systemd]],而这可以在 ''systemd'' 坏掉的时候工作<br />
<br />
还有一个选择,那就是 systemd 的 debug-shell,它在 {{ic|tty9}} 上新增了一个 root shell,可以按 Ctrl+Alt+F9 来使用。这个功能可以通过在 [[kernel parameters|内核参数]] 中添加 {{ic|systemd.debug-shell}},或者是 [[enabling|启用]] {{ic|debug-shell.service}} 来打开。注意在使用完后禁用该服务,避免在每次启动时都打开 root shell 而带来安全风险。<br />
<br />
=== Intel 显卡造成的黑屏 ===<br />
<br />
这很可能是 [[kernel mode setting]] 的问题造成的。尝试 [[Kernel mode setting#Disabling modesetting|disabling modesetting]] 或者修改 [[Intel#KMS Issue: console is limited to small area|video port]]。<br />
<br />
=== 加载内核时卡住 ===<br />
<br />
尝试添加 {{ic|1=acpi=off}} 内核参数来关闭 ACPI。<br />
<br />
=== 调试内核模块 ===<br />
<br />
参见 [[Kernel modules#Obtaining information]]。<br />
<br />
=== 调试硬件 ===<br />
<br />
* 按照 [[udev#Debug output]] 的说明可以显示额外硬件调试信息。<br />
* 确保你的系统已经安装了 [[Microcode (简体中文)|Microcode]] 更新。<br />
* 使用 [http://www.memtest.org/ Memtest86+] 来测试设备的 RAM,不可靠的 RAM 可能会导致一些非常奇怪的问题,从随机崩溃到数据损坏都有可能。<br />
<br />
== 内核崩溃 (Kernel panics) ==<br />
<br />
Linux 内核进入不可恢复的故障状态时,即发生了“内核崩溃” (''kernel panic'')。这种状态通常来源于错误的硬件驱动程序,导致内核死锁,无响应并需要重新启动。在死锁之前,会生成一条诊断消息,其中包括:发生崩溃时的''机器状态'',导致崩溃的内核函数的''调用栈'',以及当前加载的模块的列表。庆幸的是,使用 ''mainline(主线)'' 版本的内核(比如官方仓库提供的内核)不会经常发生内核崩溃,但是当它们发生时,你需要知道如何处理它们。<br />
<br />
{{注意|Kernel panics 有时被称为 ''oops'' 或 ''Kernel oops'',虽然 panics 和 oops 都是在出错的状态下才会发生,但是 ''oops'' 更为通用,因为它并不一定会导致内核死锁,有时内核可以通过结束出错的任务来恢复并继续运行。}}<br />
<br />
{{提示|在启动时传递参数 {{ic|1=oops=panic}} 或者在 {{ic|/proc/sys/kernel/panic_on_oops}} 中写入 {{ic|1}} 来强制用 panic 代替可恢复的 oops。如果你认为自动恢复 oops 导致了小概率的系统不稳定,进而导致了后来的错误难以被诊断,那么建议你这样做。}}<br />
<br />
=== 查看 panic 信息 ===<br />
<br />
如果在早期启动过程中发生了 kernel panic,你或许会在控制台上看到包含 "Kernel panic - not syncing:" 的消息,一旦 [[Systemd (简体中文)|Systemd]] 开始运行,内核消息就会被捕捉到并写入系统日志。但是,当 Kernel panic 发生时,内核发出的诊断信息 ''几乎不会'' 被写入硬盘上的日志文件,因为在 {{ic|system-journald}} 运作前内核就死锁了。因此,检查内核崩溃消息的唯一方法是在崩溃时从控制台看错误信息(如果没有设置 ''kdump crashkernel'' 的话)。可以用以下内核参数来启动,这样就能重现 tty1 上的错误信息:<br />
<br />
{{bc|1=systemd.journald.forward_to_console=1 console=tty1}}<br />
<br />
{{提示|如果崩溃信息滚动得太快导致无法阅读,可以在启动时尝试添加 {{ic|1=pause_on_oops=''seconds''}} 内核参数。}}<br />
<br />
==== 示例场景:模块损坏 ====<br />
<br />
根据诊断信息,我们可以大致推断出是哪个子系统或者模块导致了崩溃。在这个示例中,我们假设机器在启动时发生了 panic。注意那些用 '''粗体''' 标记的行:<br />
<br />
{{bc|'''kernel: BUG: unable to handle kernel NULL pointer dereference at (null)''' [1]<br />
'''kernel: IP: fw_core_init+0x18/0x1000 [firewire_core]''' [2]<br />
kernel: PGD 718d00067 <br />
kernel: P4D 718d00067 <br />
kernel: PUD 7b3611067 <br />
kernel: PMD 0 <br />
kernel: <br />
kernel: Oops: 0002 [#1] PREEMPT SMP<br />
'''kernel: Modules linked in: firewire_core(+) crc_itu_t cfg80211 rfkill ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG nf_conntrack_ipv4 ...''' [3] <br />
kernel: CPU: 6 PID: 1438 Comm: modprobe Tainted: P O 4.13.3-1-ARCH #1<br />
kernel: Hardware name: Gigabyte Technology Co., Ltd. H97-D3H/H97-D3H-CF, BIOS F5 06/26/2014<br />
kernel: task: ffff9c667abd9e00 task.stack: ffffb53b8db34000<br />
kernel: RIP: 0010:fw_core_init+0x18/0x1000 [firewire_core]<br />
kernel: RSP: 0018:ffffb53b8db37c68 EFLAGS: 00010246<br />
kernel: RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000<br />
kernel: RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffffc16d3af4<br />
kernel: RBP: ffffb53b8db37c70 R08: 0000000000000000 R09: ffffffffae113e95<br />
kernel: R10: ffffe93edfdb9680 R11: 0000000000000000 R12: ffffffffc16d9000<br />
kernel: R13: ffff9c6729bf8f60 R14: ffffffffc16d5710 R15: ffff9c6736e55840<br />
kernel: FS: 00007f301fc80b80(0000) GS:ffff9c675dd80000(0000) knlGS:0000000000000000<br />
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
kernel: CR2: 0000000000000000 CR3: 00000007c6456000 CR4: 00000000001406e0<br />
kernel: Call Trace:<br />
'''kernel: do_one_initcall+0x50/0x190''' [4]<br />
kernel: ? do_init_module+0x27/0x1f2<br />
kernel: do_init_module+0x5f/0x1f2<br />
kernel: load_module+0x23f3/0x2be0<br />
kernel: SYSC_init_module+0x16b/0x1a0<br />
kernel: ? SYSC_init_module+0x16b/0x1a0<br />
kernel: SyS_init_module+0xe/0x10<br />
kernel: entry_SYSCALL_64_fastpath+0x1a/0xa5<br />
kernel: RIP: 0033:0x7f301f3a2a0a<br />
kernel: RSP: 002b:00007ffcabbd1998 EFLAGS: 00000246 ORIG_RAX: 00000000000000af<br />
kernel: RAX: ffffffffffffffda RBX: 0000000000c85a48 RCX: 00007f301f3a2a0a<br />
kernel: RDX: 000000000041aada RSI: 000000000001a738 RDI: 00007f301e7eb010<br />
kernel: RBP: 0000000000c8a520 R08: 0000000000000001 R09: 0000000000000085<br />
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000c79208<br />
kernel: R13: 0000000000c8b4d8 R14: 00007f301e7fffff R15: 0000000000000030<br />
kernel: Code: <c7> 04 25 00 00 00 00 01 00 00 00 bb f4 ff ff ff e8 73 43 9c ec 48 <br />
kernel: RIP: fw_core_init+0x18/0x1000 [firewire_core] RSP: ffffb53b8db37c68<br />
kernel: CR2: 0000000000000000<br />
kernel: ---[ end trace 71f4306ea1238f17 ]---<br />
'''kernel: Kernel panic - not syncing: Fatal exception''' [5]<br />
kernel: Kernel Offset: 0x80000000 from 0xffffffff810000000 (relocation range: 0xffffffff800000000-0xfffffffffbffffffff<br />
kernel: ---[ end Kernel panic - not syncing: Fatal exception}}<br />
<br />
* [1] 表明了导致 panic 的错误类型。此处表示一个程序 bug。<br />
* [2] 表明 panic 发生在 ''firewire_core'' 模块中的 ''fw_core_init'' 函数中。<br />
* [3] 表明 ''firewire_core'' 模块是最后一个要加载的模块。<br />
* [4] 表明调用 ''fw_core_init'' 的函数是 ''do_one_initcall''。<br />
* [5] 表明这个 ''oops'' 消息事实上是一次 kernel panic 并且系统已经死锁。<br />
<br />
我们可以猜测,panic 发生在模块 ''firewire_core'' 加载后的初始化例程中。(我们或许可以认为,由于程序错误,这台机器的火线 (IEEE 1394) 相关硬件与这一版本的驱动模块不兼容,并且需要等待下一个版本的驱动发布)与此同时,让机器运行起来的最简单方法,就是不要加载这个模块。我们可以通过以下两种方式之一来完成这个操作:<br />
<br />
* 如果这个模块在加载 ''initramfs'' 时就会被加载,那就在重启时加上内核参数 {{ic|1=rd.blacklist=firewire_core}}。<br />
* 否则就用这个内核参数重启 {{ic|1=module_blacklist=firewire_core}}。<br />
<br />
=== 重启至 root shell 并修复故障 ===<br />
<br />
为了更改系统设置使得 panic 不再发生,你需要一个 root shell。如果 panic 发生在启动时,有几种方法可以在内核死锁前获得一个 root shell:<br />
<br />
* 使用内核参数 {{ic|emergency}}、{{ic|rd.emergency}} 或 {{ic|-b}} 重启电脑,这样可以在根文件系统挂载且 {{ic|systemd}} 启动后就收到登录提示符。<br />
: {{注意|此时,根文件系统将会以'''只读'''方式挂载。执行 {{ic|# mount -o remount,rw /}} 来改变这一设置。}}<br />
* 使用内核参数 {{ic|rescue}}、{{ic|rd.rescue}}、{{ic|single}}、{{ic|s}}、{{ic|S}} 或 {{ic|1}} 在本地文件系统挂载完成后就得到登录提示符。<br />
* 使用内核参数 {{ic|1=systemd.debug-shell=1}} 在 tty9 上获得一个早期 root shell,然后按 {{ic|Ctrl-Alt-F9}} 切换到它。<br />
* 通过使用不同的内核参数重新引导来尝试禁用导致 panic 的内核功能。尝试“备用参数” {{ic|1=acpi=off}} 和 {{ic|nolapic}}。<br />
: {{提示|参阅 Linux 内核源码树中的 {{ic|Documentation/admin-guide/kernel-parameters.txt}} 文件来查找所有内核参数。}}<br />
* 作为最后的手段,你还可以使用 '''Arch Linux Installation CD''' 启动电脑,把根文件系统挂载到 {{ic|/mnt}},然后运行 {{ic|# arch-chroot /mnt}}。<br />
<br />
禁用导致 panic 的服务或程序,回滚有故障的更新或修复配置问题。<br />
<br />
== 软件包管理 ==<br />
<br />
参阅适用于一般主题的 [[Pacman#Troubleshooting]],以及适用于 PGP 密钥问题的 [[pacman/Package signing#Troubleshooting]]。<br />
<br />
== fuser ==<br />
<br />
{{Expansion|需要更多关于其用法的信息}}<br />
<br />
''fuser'' 是一个用于识别进程占用的资源(如打开的文件、文件系统和 TCP/UDP 端口)的命令行工具。<br />
<br />
''fuser'' 由软件包 {{Pkg|psmisc}} 提供,已经由 {{Grp|base}} 组安装。更多信息请查看 {{man|1|fuser}}。<br />
<br />
== 会话权限 ==<br />
<br />
{{注意|你必须使用 [[Systemd (简体中文)|systemd]] 作为你的 init 进程,本地会话才能正常工作。[https://www.archlinux.org/news/d-bus-now-launches-user-buses/] 它是各种设备的 polkit 权限和 ACL 所必需的 (参见 {{ic|/usr/lib/udev/rules.d/70-uaccess.rules}} 和 [http://enotty.pipebreaker.pl/2012/05/23/linux-automatic-user-acl-management/])}}<br />
<br />
首先,确保你有一个带 X 的可用本地会话:<br />
<br />
$ loginctl show-session $XDG_SESSION_ID<br />
<br />
在输出中需要带有 {{ic|1=Remote=no}} and {{ic|1=Active=yes}} 字样。如果没有,确保 X 运行在和登录时一样的 tty 里面。这是保留登录会话所必须的。<br />
<br />
D-Bus 会话也必须随 X 一起启动。关于这个的更多信息参见 [[D-Bus#Starting the user session]]。<br />
<br />
基本 [[polkit]] 操作不需要额外的配置。但有一些 polkit 操作需要请求额外的身份认证,即使是本地会话也是如此。为了达成这项工作,必须运行一个 polkit 身份认证组件。更多信息可参见 [[polkit (简体中文)#身份认证组件]]。<br />
<br />
== 错误信息: "error while loading shared libraries" ==<br />
<br />
{{Accuracy|在 [[System_maintenance#Partial_upgrades_are_unsupported|soname bump]] 之后相关程序可能需要重新编译。}}<br />
<br />
如果在运行程序时遇到类似于这样的错误:<br />
<br />
error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory<br />
<br />
使用 [[pacman]] 或 [[pkgfile]] 来查找包含丢失共享库的软件包:<br />
<br />
{{hc|$ pacman -Fs libusb-0.1.so.4|<br />
extra/libusb-compat 0.1.5-1<br />
usr/lib/libusb-0.1.so.4<br />
}}<br />
<br />
在上述例子中,需要 [[installed|安装]] 软件包 {{Pkg|libusb-compat}}。<br />
<br />
这个错误也有可能意味着你用来安装这个软件的 [[PKGBUILD]] 里没有将这个共享库作为它的依赖库:如果来自官方源,请 [[Reporting bug guidelines (简体中文)|报告一个 bug]];如果来自 [[AUR]],请在 AUR 网站相关页面上把它报告给维护者。<br />
<br />
== 错误信息: "file: could not find any magic files!" ==<br />
<br />
如果看到这条消息,则可能表示软件包更新破坏了动态链接程序的运行时依赖文件,并且系统现在已经基本瘫痪。在修复之前,你将无法重新编译或重新安装软件包或重建 [[mkinitcpio (简体中文)|initramfs]]。<br />
<br />
=== 错误原因 ===<br />
<br />
某次软件更新可能在 {{ic|/etc/ld.so.conf.d}} 目录中添加了非法的 {{ic|''filename''.conf}} 文件,或是错误地编辑了 {{ic|/etc/ld.so.conf}} 文件。其后果就是动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}} 使用了错误的数据重新生成了。这可能导致系统中所有依赖共享库的程序都出错(即几乎所有程序出错)。<br />
<br />
=== 解决方法 ===<br />
<br />
# 使用 '''''Arch Linux Installation CD''''' 启动。<br />
# 挂载根文件系统 {{ic|/}} 到 {{ic|/mnt}},挂载 {{ic|/boot}} 文件系统到 {{ic|/mnt/boot}},然后用命令 {{ic|# arch-chroot /mnt}} 切换到受损的系统中。<br />
# 检查 {{ic|/etc/ld.so.conf}} 文件,删除所有不正确的内容。<br />
# 检查放在 {{ic|/etc/ld.so.conf.d/}} 目录里的文件,删除所有不正确的文件。<br />
# 使用命令 {{ic|# ldconfig}} 重新生成动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}}。<br />
# 使用命令 {{ic|# mkinitcpio -p linux}} 重新生成 [[mkinitcpio (简体中文)|Initramfs]]。<br />
# 退出 chroot 环境,卸载文件系统,然后重启到原来的系统中。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.tuxradar.com/content/how-fix-most-common-linux-problems Fix the Most Common Problems]{{Dead link|2018|02|05}}<br />
* [https://www.reddit.com/r/archlinux/comments/tjjwr/archlinux_a_howto_in_troubleshooting_for_newcomers/ A how-to in troubleshooting for newcomers]<br />
* [http://wiki.ultimatebootcd.com/index.php?title=Tools List of Tools for UBCD] - Memtest-like tools to add to grub.cfg on UltimateBootCD.com<br />
* [[Wikipedia:BIOS Boot partition]]<br />
* [[REISUB]]<br />
* [http://freedesktop.org/wiki/Software/systemd/Debugging#Debug_Logging_to_a_Serial_Console Debug Logging to a Serial Console] on Freedesktop.org<br />
* [https://web.archive.org/web/20120217124742/http://www.lesswatts.org/projects/acpi/debug.php How to Isolate Linux ACPI Issues] on Archive.org</div>
Arisaka
https://wiki.archlinux.org/index.php?title=General_troubleshooting_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515600
General troubleshooting (简体中文)
2018-04-02T15:35:10Z
<p>Arisaka: Create page & sync with English version.</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:System administration (简体中文)]]<br />
[[Category:System recovery (简体中文)]]<br />
[[Category:Getting and installing Arch (简体中文)]]<br />
[[en:General troubleshooting]]<br />
[[es:General troubleshooting]]<br />
[[ja:一般的なトラブルシューティング]]<br />
[[ru:General troubleshooting]]<br />
{{Related articles start}}<br />
{{Related|Reporting bug guidelines (简体中文)}}<br />
{{Related|Step-by-step debugging guide}}<br />
{{Related|Debug - Getting Traces (简体中文)}}<br />
{{Related|IRC Collaborative Debugging}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|General troubleshooting|2018-03-30|513025}}<br />
<br />
本文介绍了一些常规的故障排除方法。有关特定应用程序的问题,请参阅该特定程序的 wiki 页面。<br />
<br />
== 常用手段 ==<br />
<br />
=== 注意细节 ===<br />
<br />
为了解决遇到的问题,对当前使用的这个程序,你应该有一个基本的了解,这是 ''至关重要'' 的。它是如何工作的,它依赖什么才能正常运行?如果不能很好地回答这些问题,最好阅读一下这些出错程序的 [[Table of contents (简体中文)|Archwiki]] 文章。一旦你觉得你已经理解了它,你将更容易找出问题的原因。<br />
<br />
=== 常见问题 / 检查项 ===<br />
<br />
下面列出了许多常见问题,用于排查故障。在每个问题下都有注释,说明你该如何回答这个问题,紧接着的是一些如何收集数据的简单示例,还有查看各种日志的工具。<br />
<br />
# 出现了什么故障?<br />
#: 请尽可能精确地描述问题,这将帮助你在查找特定信息的时候不至感到困惑或扯到别的方面去。<br />
# 是否显示了错误信息?(如果有的话)<br />
#: 将包含相关 '''错误信息''' 的 ''完整输出'' 复制并粘贴到类似 {{ic|$HOME/issue.log}} 这样单独的文件中。例如,可以将以下 [[mkinitcpio (简体中文)|mkinitcpio]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ mkinitcpio -p linux >> $HOME/issue.log}}<br />
# 可以复现这个故障码?<br />
#: 如果是这样,请 '''按步骤''' 给出 ''确切的'' 指示/命令来做到这一点。<br />
# 第一次遇到这些故障的时间,以及从没有故障到故障发生之间你修改了什么内容?<br />
#:如果这种情况发生在某次升级之后,可以列出 '''所有已升级的包'''。包括 ''版本号'',同时粘贴 [[pacman]].log ({{ic|/var/log/pacman.log}}) 的升级日志。使用 [[Systemd (简体中文)|systemd]] 的 systemctl 工具检查故障程序依赖的 ''所有'' 服务的运行状态。例如,可以将 [[Systemd (简体中文)#systemd 基本工具|systemd]] 命令的输出转发到 {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ systemctl status dhcpcd@eth0.service >> $HOME/issue.log}}<br />
#: {{注意|使用 {{ic|'''>>'''}} 可以保证 {{ic|$HOME/issue.log}} 中之前保存的内容不会被覆盖。}}<br />
<br />
=== 寻求解决 ===<br />
<br />
不要通过这样的表述来寻求问题的解决:<br />
<br />
''程序 X 不工作了。''<br />
<br />
描述整个系统的环境更有助于解决问题,比如:<br />
<br />
''应用程序 X 在执行 Z 任务时,会报出 Y 错误,条件是 A 和 B。''<br />
<br />
=== 额外支援 ===<br />
<br />
利用你眼前的所有信息,你应该对系统里发生了什么有一个较好的认识,并且可以开始着手修复了。<br />
<br />
如果需要额外支援,[https://bbs.archlinux.org 官方论坛] 或 IRC (irc.freenode.net 上的 #archlinux 频道) 都可以提供帮助。更多频道可参考 [[IRC channels]]。<br />
<br />
{{注意|[[Code of conduct (简体中文)#仅支持 Arch Linux|技术支持 ''仅限于'' Arch Linux]] 而非 [[Arch-based distributions (简体中文)|基于 Arch 的发行版]]。}}<br />
<br />
当要求贴出 '''完整''' 的 输出 / 日志 时,不能仅仅贴出你认为的重要部分。信息来源应该包括:<br />
<br />
* 所有涉及到的命令的完整输出,不要只选择你认为相关的东西。<br />
* 来自 systemd 的 {{ic|journalctl}} 的输出。要获取更多的输出,请使用 {{ic|1=systemd.log_level=debug}} 引导参数。<br />
* 日志文件(看一下 {{ic|/var/log}} 目录)<br />
* 相关的配置文件<br />
* 相关的驱动程序<br />
* 相关软件包的版本<br />
* 内核相关:{{ic|dmesg}}。对于启动问题,至少贴出最后 10 行,多贴一些当然更好。<br />
* 网络相关:相关命令的完整输出,再加上所有相关配置文件。<br />
* Xorg 相关: {{ic|/var/log/Xorg.0.log}},如果你已经覆盖了出问题的日志,就贴在这之前的日志。<br />
* Pacman 相关:如果最近的更新弄坏了什么东西,请到 {{ic|/var/log/pacman.log}} 找它。<br />
<br />
贴出这些信息有一个更好的方式,就是使用在线剪贴板 (pastebin)。你可以 [[install|安装]] {{pkg|pbpst}} 或 {{pkg|gist}} 来自动上传信息。例如,要上传这次启动以来的 systemd 日志,可以这么做:<br />
<br />
# journalctl -xb | pbpst -S<br />
<br />
这将返回一个链接,你可以把它贴到论坛或 IRC。<br />
<br />
另外,在提问之前,请先阅读 [http://www.catb.org/esr/faqs/smart-questions.html 提问的智慧] 和 [[Code of conduct (简体中文)|行为准则]]。<br />
<br />
== 系统启动问题 ==<br />
<br />
诊断 [[boot process (简体中文)|启动过程]] 中的问题主要是修改 [[kernel parameters (简体中文)|内核参数]],然后重启系统。<br />
<br />
如果系统无法启动,可以从 [https://www.archlinux.org/download/ live 镜像] 启动并 [[change root (简体中文)|chroot]] 到现有系统。<br />
<br />
=== 控制台的输出信息 ===<br />
<br />
在启动过程完成以后,屏幕会被清空并显示登录提示符,这使得用户无法看到初始化过程中的输出和其中的错误信息。这一默认特性可以使用接下来几节中的方法进行修改。<br />
<br />
请注意,无论选择下面哪个方法,在启动后通过使用 {{ic|dmesg}} 或 {{ic|journalctl -b}} 都可以显示内核消息,用于检查错误。<br />
<br />
==== 输出流控制 ====<br />
<br />
以下是适用于大多数终端模拟器的基本操作,包括虚拟终端 (vc):<br />
<br />
* 按 {{ic|Ctrl+S}} 暂停输出<br />
* 按 {{ic|Ctrl+Q}} 继续输出<br />
<br />
这样不仅会暂停输出,而且会暂停尝试打印到终端的程序,即暂停输出时会阻塞 {{ic|write()}} 调用。 如果你的 ''init'' 进程出现冻结,请确保系统控制台没有暂停。<br />
<br />
要查看已经显示过的错误信息,参见 [[Getty#Have boot messages stay on tty1]]。<br />
<br />
==== 回滚显示 ====<br />
<br />
回滚显示允许用户查看已经从控制台滚动过去并消失的文字内容。这通常是在视频适配器和显示设备之间创建缓冲(称为回滚缓冲区)实现的。默认情况下,将缓冲的内容上下滚动的快捷键是 {{ic|Shift+PageUp}} 和 {{ic|Shift+PageDown}}。<br />
<br />
如果回滚内容没有完全包含足够的信息,可能需要扩大回滚缓冲区的大小来容纳更多输出。这可以通过配置内核的 framebuffer console(fbcon,帧缓冲控制台)来实现,修改 [[kernel parameter|内核参数]] {{ic|1=fbcon=scrollback:Nk}} 即可,其中 {{ic|N}} 是缓冲区大小,单位是 kB,默认是 32k。<br />
<br />
如果这不奏效,你的 framebuffer console 可能没有正确地启用。参阅 [https://www.kernel.org/doc/Documentation/fb/fbcon.txt Framebuffer Console documentation] 来查找其他影响参数,比如修改帧缓冲驱动。<br />
<br />
==== Debug 输出 ====<br />
<br />
在启动时,大部分来自内核的消息都是隐藏的,可以加入不同的内核参数来输出更多信息。最简单的是这些:<br />
<br />
* {{ic|debug}} 可以同时启用来自内核和 [[Systemd (简体中文)|systemd]] 的调试信息<br />
* {{ic|ignore_loglevel}} 强制显示 ''所有'' 内核消息<br />
<br />
在特定情况下有用的其他参数如下:<br />
* {{ic|1=earlyprintk=vga,keep}} 在早期启动过程中就输出内核消息,用于内核在有输出前就崩溃的情况下。在 [[Unified Extensible Firmware Interface (简体中文)|EFI]] 系统上要把 {{ic|vga}} 改成 {{ic|efi}}。<br />
* {{ic|1=log_buf_len=16M}} 用于分配一个更大 (16MB) 的内核消息缓冲区,用来保证 debug 输出不被覆盖。<br />
<br />
还有很多独立的调试参数,用于在特定的子系统中启用调试,例如 {{ic|bootmem_debug}} 和 {{ic|sched_debug}}。更多详细信息请参考 [https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt kernel parameter documentation]。<br />
<br />
{{注意|如果无法回滚的足够远以查看所需的启动输出,你需要扩大 [[#回滚显示|回滚缓冲区]] 的大小。}}<br />
<br />
=== 故障恢复控制台 ===<br />
<br />
在启动过程中的某个阶段获取一个交互式 shell 可以帮助你准确找出问题出在哪里,以及为何失败。有几个内核参数可以做到这一点,但它们都启动了一个正常的shell,可以随时 {{ic|exit}} 让内核恢复正在执行的操作:<br />
* {{ic|rescue}} 在根文件系统刚刚被挂载为读写模式的时候启动一个 shell<br />
* {{ic|emergency}} 可以在更早的时候启动 shell,早于大部分文件系统挂载之前<br />
* {{ic|1=init=/bin/sh}}(作为最后的选择)把 init 程序改成 root shell。因为 {{ic|rescue}} 和 {{ic|emergency}} 都依赖于 [[Systemd (简体中文)|systemd]],而这可以在 ''systemd'' 坏掉的时候工作<br />
<br />
还有一个选择,那就是 systemd 的 debug-shell,它在 {{ic|tty9}} 上新增了一个 root shell,可以按 Ctrl+Alt+F9 来使用。这个功能可以通过在 [[kernel parameters|内核参数]] 中添加 {{ic|systemd.debug-shell}},或者是 [[enabling|启用]] {{ic|debug-shell.service}} 来打开。注意在使用完后禁用该服务,避免在每次启动时都打开 root shell 而带来安全风险。<br />
<br />
=== Intel 显卡造成的黑屏 ===<br />
<br />
这很可能是 [[kernel mode setting]] 的问题造成的。尝试 [[Kernel mode setting#Disabling modesetting|disabling modesetting]] 或者修改 [[Intel#KMS Issue: console is limited to small area|video port]]。<br />
<br />
=== 加载内核时卡住 ===<br />
<br />
尝试添加 {{ic|1=acpi=off}} 内核参数来关闭 ACPI。<br />
<br />
=== 调试内核模块 ===<br />
<br />
参见 [[Kernel modules#Obtaining information]]。<br />
<br />
=== 调试硬件 ===<br />
<br />
* 按照 [[udev#Debug output]] 的说明可以显示额外硬件调试信息。<br />
* 确保你的系统已经安装了 [[Microcode (简体中文)|Microcode]] 更新。<br />
* 使用 [http://www.memtest.org/ Memtest86+] 来测试设备的 RAM,不可靠的 RAM 可能会导致一些非常奇怪的问题,从随机崩溃到数据损坏都有可能。<br />
<br />
== 内核崩溃 (Kernel panics) ==<br />
<br />
Linux 内核进入不可恢复的故障状态时,即发生了“内核崩溃” (''kernel panic'')。这种状态通常来源于错误的硬件驱动程序,导致内核死锁,无响应并需要重新启动。在死锁之前,会生成一条诊断消息,其中包括:发生崩溃时的''机器状态'',导致崩溃的内核函数的''调用栈'',以及当前加载的模块的列表。庆幸的是,使用 ''mainline(主线)'' 版本的内核(比如官方仓库提供的内核)不会经常发生内核崩溃,但是当它们发生时,你需要知道如何处理它们。<br />
<br />
{{注意|Kernel panics 有时被称为 ''oops'' 或 ''Kernel oops'',虽然 panics 和 oops 都是在出错的状态下才会发生,但是 ''oops'' 更为通用,因为它并不一定会导致内核死锁,有时内核可以通过结束出错的任务来恢复并继续运行。}}<br />
<br />
{{提示|在启动时传递参数 {{ic|1=oops=panic}} 或者在 {{ic|/proc/sys/kernel/panic_on_oops}} 中写入 {{ic|1}} 来强制用 panic 代替可恢复的 oops。如果你认为自动恢复 oops 导致了小概率的系统不稳定,进而导致了后来的错误难以被诊断,那么建议你这样做。}}<br />
<br />
=== 查看 panic 信息 ===<br />
<br />
如果在早期启动过程中发生了 kernel panic,你或许会在控制台上看到包含 "Kernel panic - not syncing:" 的消息,一旦 [[Systemd (简体中文)|Systemd]] 开始运行,内核消息就会被捕捉到并写入系统日志。但是,当 Kernel panic 发生时,内核发出的诊断信息 ''几乎不会'' 被写入硬盘上的日志文件,因为在 {{ic|system-journald}} 运作前内核就死锁了。因此,检查内核崩溃消息的唯一方法是在崩溃时从控制台看错误信息(如果没有设置 ''kdump crashkernel'' 的话)。可以用以下内核参数来启动,这样就能重现 tty1 上的错误信息:<br />
<br />
{{bc|1=systemd.journald.forward_to_console=1 console=tty1}}<br />
<br />
{{提示|如果崩溃信息滚动得太快导致无法阅读,可以在启动时尝试添加 {{ic|1=pause_on_oops=''seconds''}} 内核参数。}}<br />
<br />
==== 示例场景:模块损坏 ====<br />
<br />
根据诊断信息,我们可以大致推断出是哪个子系统或者模块导致了崩溃。在这个示例中,我们假设机器在启动时发生了 panic。注意那些用 '''粗体''' 标记的行:<br />
<br />
{{bc|'''kernel: BUG: unable to handle kernel NULL pointer dereference at (null)''' [1]<br />
'''kernel: IP: fw_core_init+0x18/0x1000 [firewire_core]''' [2]<br />
kernel: PGD 718d00067 <br />
kernel: P4D 718d00067 <br />
kernel: PUD 7b3611067 <br />
kernel: PMD 0 <br />
kernel: <br />
kernel: Oops: 0002 [#1] PREEMPT SMP<br />
'''kernel: Modules linked in: firewire_core(+) crc_itu_t cfg80211 rfkill ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG nf_conntrack_ipv4 ...''' [3] <br />
kernel: CPU: 6 PID: 1438 Comm: modprobe Tainted: P O 4.13.3-1-ARCH #1<br />
kernel: Hardware name: Gigabyte Technology Co., Ltd. H97-D3H/H97-D3H-CF, BIOS F5 06/26/2014<br />
kernel: task: ffff9c667abd9e00 task.stack: ffffb53b8db34000<br />
kernel: RIP: 0010:fw_core_init+0x18/0x1000 [firewire_core]<br />
kernel: RSP: 0018:ffffb53b8db37c68 EFLAGS: 00010246<br />
kernel: RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000<br />
kernel: RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffffc16d3af4<br />
kernel: RBP: ffffb53b8db37c70 R08: 0000000000000000 R09: ffffffffae113e95<br />
kernel: R10: ffffe93edfdb9680 R11: 0000000000000000 R12: ffffffffc16d9000<br />
kernel: R13: ffff9c6729bf8f60 R14: ffffffffc16d5710 R15: ffff9c6736e55840<br />
kernel: FS: 00007f301fc80b80(0000) GS:ffff9c675dd80000(0000) knlGS:0000000000000000<br />
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
kernel: CR2: 0000000000000000 CR3: 00000007c6456000 CR4: 00000000001406e0<br />
kernel: Call Trace:<br />
'''kernel: do_one_initcall+0x50/0x190''' [4]<br />
kernel: ? do_init_module+0x27/0x1f2<br />
kernel: do_init_module+0x5f/0x1f2<br />
kernel: load_module+0x23f3/0x2be0<br />
kernel: SYSC_init_module+0x16b/0x1a0<br />
kernel: ? SYSC_init_module+0x16b/0x1a0<br />
kernel: SyS_init_module+0xe/0x10<br />
kernel: entry_SYSCALL_64_fastpath+0x1a/0xa5<br />
kernel: RIP: 0033:0x7f301f3a2a0a<br />
kernel: RSP: 002b:00007ffcabbd1998 EFLAGS: 00000246 ORIG_RAX: 00000000000000af<br />
kernel: RAX: ffffffffffffffda RBX: 0000000000c85a48 RCX: 00007f301f3a2a0a<br />
kernel: RDX: 000000000041aada RSI: 000000000001a738 RDI: 00007f301e7eb010<br />
kernel: RBP: 0000000000c8a520 R08: 0000000000000001 R09: 0000000000000085<br />
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000c79208<br />
kernel: R13: 0000000000c8b4d8 R14: 00007f301e7fffff R15: 0000000000000030<br />
kernel: Code: <c7> 04 25 00 00 00 00 01 00 00 00 bb f4 ff ff ff e8 73 43 9c ec 48 <br />
kernel: RIP: fw_core_init+0x18/0x1000 [firewire_core] RSP: ffffb53b8db37c68<br />
kernel: CR2: 0000000000000000<br />
kernel: ---[ end trace 71f4306ea1238f17 ]---<br />
'''kernel: Kernel panic - not syncing: Fatal exception''' [5]<br />
kernel: Kernel Offset: 0x80000000 from 0xffffffff810000000 (relocation range: 0xffffffff800000000-0xfffffffffbffffffff<br />
kernel: ---[ end Kernel panic - not syncing: Fatal exception}}<br />
<br />
* [1] 表明了导致 panic 的错误类型。此处表示一个程序 bug。<br />
* [2] 表明 panic 发生在 ''firewire_core'' 模块中的 ''fw_core_init'' 函数中。<br />
* [3] 表明 ''firewire_core'' 模块是最后一个要加载的模块。<br />
* [4] 表明调用 ''fw_core_init'' 的函数是 ''do_one_initcall''。<br />
* [5] 表明这个 ''oops'' 消息事实上是一次 kernel panic 并且系统已经死锁。<br />
<br />
我们可以猜测,panic 发生在模块 ''firewire_core'' 加载后的初始化例程中。(我们或许可以认为,由于程序错误,这台机器的火线 (IEEE 1394) 相关硬件与这一版本的驱动模块不兼容,并且需要等待下一个版本的驱动发布)与此同时,让机器运行起来的最简单方法,就是不要加载这个模块。我们可以通过以下两种方式之一来完成这个操作:<br />
<br />
* 如果这个模块在加载 ''initramfs'' 时就会被加载,那就在重启时加上内核参数 {{ic|1=rd.blacklist=firewire_core}}。<br />
* 否则就用这个内核参数重启 {{ic|1=module_blacklist=firewire_core}}。<br />
<br />
=== 重启至 root shell 并修复故障 ===<br />
<br />
为了更改系统设置使得 panic 不再发生,你需要一个 root shell。如果 panic 发生在启动时,有几种方法可以在内核死锁前获得一个 root shell:<br />
<br />
* 使用内核参数 {{ic|emergency}}、{{ic|rd.emergency}} 或 {{ic|-b}} 重启电脑,这样可以在根文件系统挂载且 {{ic|systemd}} 启动后就收到登录提示符。<br />
: {{注意|此时,根文件系统将会以'''只读'''方式挂载。执行 {{ic|# mount -o remount,rw /}} 来改变这一设置。}}<br />
* 使用内核参数 {{ic|rescue}}、{{ic|rd.rescue}}、{{ic|single}}、{{ic|s}}、{{ic|S}} 或 {{ic|1}} 在本地文件系统挂载完成后就得到登录提示符。<br />
* 使用内核参数 {{ic|1=systemd.debug-shell=1}} 在 tty9 上获得一个早期 root shell,然后按 {{ic|Ctrl-Alt-F9}} 切换到它。<br />
* 通过使用不同的内核参数重新引导来尝试禁用导致 panic 的内核功能。尝试“备用参数” {{ic|1=acpi=off}} 和 {{ic|nolapic}}。<br />
: {{提示|参阅 Linux 内核源码树中的 {{ic|Documentation/admin-guide/kernel-parameters.txt}} 文件来查找所有内核参数。}}<br />
* 作为最后的手段,你还可以使用 '''Arch Linux Installation CD''' 启动电脑,把根文件系统挂载到 {{ic|/mnt}},然后运行 {{ic|# arch-chroot /mnt}}。<br />
<br />
禁用导致 panic 的服务或程序,回滚有故障的更新或修复配置问题。<br />
<br />
== 软件包管理 ==<br />
<br />
参阅适用于一般主题的 [[Pacman#Troubleshooting]],以及适用于 PGP 密钥问题的 [[pacman/Package signing#Troubleshooting]]。<br />
<br />
== fuser ==<br />
<br />
{{Expansion|需要更多关于其用法的信息}}<br />
<br />
''fuser'' 是一个用于识别进程占用的资源(如打开的文件、文件系统和 TCP/UDP 端口)的命令行工具。<br />
<br />
''fuser'' 由软件包 {{Pkg|psmisc}} 提供,已经由 {{Grp|base}} 组安装。更多信息请查看 {{man|1|fuser}}。<br />
<br />
== 会话权限 ==<br />
<br />
{{注意|你必须使用 [[Systemd (简体中文)|systemd]] 作为你的 init 进程,本地会话才能正常工作。[https://www.archlinux.org/news/d-bus-now-launches-user-buses/] 它是各种设备的 polkit 权限和 ACL 所必需的 (参见 {{ic|/usr/lib/udev/rules.d/70-uaccess.rules}} 和 [http://enotty.pipebreaker.pl/2012/05/23/linux-automatic-user-acl-management/])}}<br />
<br />
首先,确保你有一个带 X 的可用本地会话:<br />
<br />
$ loginctl show-session $XDG_SESSION_ID<br />
<br />
在输出中需要带有 {{ic|1=Remote=no}} and {{ic|1=Active=yes}} 字样。如果没有,确保 X 运行在和登录时一样的 tty 里面。这是保留登录会话所必须的。<br />
<br />
D-Bus 会话也必须随 X 一起启动。关于这个的更多信息参见 [[D-Bus#Starting the user session]]。<br />
<br />
基本 [[polkit]] 操作不需要额外的配置。但有一些 polkit 操作需要请求额外的身份认证,即使是本地会话也是如此。为了达成这项工作,必须运行一个 polkit 身份认证组件。更多信息可参见 [[polkit (简体中文)#身份认证组件]]。<br />
<br />
== 错误信息: "error while loading shared libraries" ==<br />
<br />
{{Accuracy|在 [[System_maintenance#Partial_upgrades_are_unsupported|soname bump]] 之后相关程序可能需要重新编译。}}<br />
<br />
如果在运行程序时遇到类似于这样的错误:<br />
<br />
error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory<br />
<br />
使用 [[pacman]] 或 [[pkgfile]] 来查找包含丢失共享库的软件包:<br />
<br />
{{hc|$ pacman -Fs libusb-0.1.so.4|<br />
extra/libusb-compat 0.1.5-1<br />
usr/lib/libusb-0.1.so.4<br />
}}<br />
<br />
在上述例子中,需要 [[installed|安装]] 软件包 {{Pkg|libusb-compat}}。<br />
<br />
这个错误也有可能意味着你用来安装这个软件的 [[PKGBUILD]] 里没有将这个共享库作为它的依赖库:如果来自官方源,请 [[Reporting bug guidelines (简体中文)|报告一个 bug]];如果来自 [[AUR]],请在 AUR 网站相关页面上把它报告给维护者。<br />
<br />
== 错误信息: "file: could not find any magic files!" ==<br />
<br />
如果看到这条消息,则可能表示软件包更新破坏了动态链接程序的运行时依赖文件,并且系统现在已经基本瘫痪。在修复之前,你将无法重新编译或重新安装软件包或重建 [[mkinitcpio (简体中文)|initramfs]]。<br />
<br />
=== 错误原因 ===<br />
<br />
某次软件更新可能在 {{ic|/etc/ld.so.conf.d}} 目录中添加了非法的 {{ic|''filename''.conf}} 文件,或是错误地编辑了 {{ic|/etc/ld.so.conf}} 文件。其后果就是动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}} 使用了错误的数据重新生成了。这可能导致系统中所有依赖共享库的程序都出错(即几乎所有程序出错)。<br />
<br />
=== 解决方法 ===<br />
<br />
# 使用 '''''Arch Linux Installation CD''''' 启动。<br />
# 挂载根文件系统 {{ic|/}} 到 {{ic|/mnt}},挂载 {{ic|/boot}} 文件系统到 {{ic|/mnt/boot}},然后用命令 {{ic|# arch-chroot /mnt}} 切换到受损的系统中。<br />
# 检查 {{ic|/etc/ld.so.conf}} 文件,删除所有不正确的内容。<br />
# 检查放在 {{ic|/etc/ld.so.conf.d/}} 目录里的文件,删除所有不正确的文件。<br />
# 使用命令 {{ic|# ldconfig}} 重新生成动态链接程序的运行时依赖文件 {{ic|/etc/ld.so.cache}}。<br />
# 使用命令 {{ic|# mkinitcpio -p linux}} 重新生成 [[mkinitcpio (简体中文)|Initramfs]]。<br />
# 退出 chroot 环境,卸载文件系统,然后重启到原来的系统中。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.tuxradar.com/content/how-fix-most-common-linux-problems Fix the Most Common Problems]{{Dead link|2018|02|05}}<br />
* [https://www.reddit.com/r/archlinux/comments/tjjwr/archlinux_a_howto_in_troubleshooting_for_newcomers/ A how-to in troubleshooting for newcomers]<br />
* [http://wiki.ultimatebootcd.com/index.php?title=Tools List of Tools for UBCD] - Memtest-like tools to add to grub.cfg on UltimateBootCD.com<br />
* [[Wikipedia:BIOS Boot partition]]<br />
* [[REISUB]]<br />
* [http://freedesktop.org/wiki/Software/systemd/Debugging#Debug_Logging_to_a_Serial_Console Debug Logging to a Serial Console] on Freedesktop.org<br />
* [https://web.archive.org/web/20120217124742/http://www.lesswatts.org/projects/acpi/debug.php How to Isolate Linux ACPI Issues] on Archive.org</div>
Arisaka
https://wiki.archlinux.org/index.php?title=General_troubleshooting&diff=515594
General troubleshooting
2018-04-02T14:20:00Z
<p>Arisaka: Add zh-hans link.</p>
<hr />
<div>[[Category:System administration]]<br />
[[Category:System recovery]]<br />
[[Category:Getting and installing Arch]]<br />
[[es:General troubleshooting]]<br />
[[ja:一般的なトラブルシューティング]]<br />
[[ru:General troubleshooting]]<br />
[[zh-hans:General troubleshooting]]<br />
{{Related articles start}}<br />
{{Related|Reporting bug guidelines}}<br />
{{Related|Step-by-step debugging guide}}<br />
{{Related|Debug - Getting Traces}}<br />
{{Related|IRC Collaborative Debugging}}<br />
{{Related articles end}}<br />
<br />
This article explains some methods for general troubleshooting. For application specific issues, please reference the particular wiki page for that program.<br />
<br />
== General procedures ==<br />
<br />
=== Attention to detail ===<br />
<br />
In order to resolve an issue that you are having, it is ''absolutely crucial'' to have a firm basic understanding of how that specific subsystem functions. How does it work, and what does it need to run without error? If you cannot comfortably answer these question then you would best review the [[Table of contents|Archwiki]] article for the subsystem that you are having trouble with. Once you feel like you have understood it, it will be easier for you to pinpoint the cause of the problem.<br />
<br />
=== Questions/checklist ===<br />
<br />
The following gives a number of questions for you whenever dealing with a malfunctioning system. Under each question there are notes explaining how you should be answering each question, followed by some light examples on how to easily gather data output and what tools can be used to review logs and the journal.<br />
<br />
# What is the issue(s)?<br />
#: Be ''as precise as possible''. This will help you not get confused and/or side-tracked when looking up specific information.<br />
# Are there error messages? (if any)<br />
#: Copy and paste ''full outputs'' that contain '''error messages''' related to your issue into a separate file, such as {{ic|$HOME/issue.log}}. For example, to forward the output of the following [[mkinitcpio]] command to {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ mkinitcpio -p linux >> $HOME/issue.log}}<br />
# Can you reproduce the issue?<br />
#: If so, give ''exact'' '''step-by-step''' instructions/commands needed to do so.<br />
# When did you first encounter these issues and what was changed between then and when the system was operating without error?<br />
#:If it occurred right after an update then, list '''all packages that were updated'''. Include ''version numbers'', also, paste the entire update from [[pacman]].log ({{ic|/var/log/pacman.log}}). Also take note of the statuses of ''any'' service(s) needed to support the malfunctioning application(s) using [[systemd]]'s systemctl tools. For example, to forward the output of the following [[Systemd#Basic_systemctl_usage|systemd]] command to {{ic|$HOME/issue.log}}:<br />
#: {{bc|$ systemctl status dhcpcd@eth0.service >> $HOME/issue.log}}<br />
#: {{Note|Using {{ic|'''>>'''}} will ensure any previous text in {{ic|$HOME/issue.log}} will not be overwritten.}}<br />
<br />
=== Approach ===<br />
<br />
Rather than approaching an issue by stating,<br />
<br />
''Application X does not work.''<br />
<br />
you will find it more helpful to formulate your issue in the context of the system as a whole, as:<br />
<br />
''Application X produces Y error(s) when performing Z tasks under conditions A and B.''<br />
<br />
=== Additional support ===<br />
<br />
With all the information in front of you you should have a good idea as to what is going on with the system and you can now start working on a proper fix.<br />
<br />
If you require any additional support, it can be found on [https://bbs.archlinux.org the forums] or IRC at irc.freenode.net #archlinux. See [[IRC channels]] for other options.<br />
<br />
{{Note|[[Code of conduct#Arch Linux distribution support .2Aonly.2A|Support is provided for Arch Linux ''only'']] and not [[Arch-based distributions]].}}<br />
<br />
When asking for support post the '''complete''' output/logs, not just what you think are the significant sections. Sources of information include:<br />
<br />
* Full output of any command involved - do not just select what you think is relevant.<br />
* Output from systemd's {{ic|journalctl}}. For more extensive output, use the {{ic|1=systemd.log_level=debug}} boot parameter.<br />
* Log files (have a look in {{ic|/var/log}})<br />
* Relevant configuration files<br />
* Drivers involved<br />
* Versions of packages involved<br />
* Kernel: {{ic|dmesg}}. For a boot problem, at least the last 10 lines displayed, preferably more<br />
* Networking: Exact output of commands involved, and any configuration files<br />
* Xorg: {{ic|/var/log/Xorg.0.log}}, and prior logs if you have overwritten the problematic one<br />
* Pacman: If a recent upgrade broke something, look in {{ic|/var/log/pacman.log}}<br />
<br />
One of the better ways to post this information is to use an online pastebin. You can [[install]] the {{pkg|pbpst}} or {{pkg|gist}} package to automatically upload information. For example, to upload the content of your systemd journal from this boot you would do:<br />
<br />
# journalctl -xb | pbpst -S<br />
<br />
A link will then be output that you can paste to the forum or IRC.<br />
<br />
Additionally, before posting your question, you may wish to review [http://www.catb.org/esr/faqs/smart-questions.html how to ask smart questions]. See also [[Code of conduct]].<br />
<br />
== Boot problems ==<br />
<br />
Diagnosing errors during the [[boot process]] involves changing the [[kernel parameters]], and rebooting the system.<br />
<br />
If booting the system is not possible, boot from a [https://www.archlinux.org/download/ live image] and [[change root]] to the existing system.<br />
<br />
=== Console messages ===<br />
<br />
After the boot process, the screen is cleared and the login prompt appears, leaving users unable to read init output and error messages. This default behavior may be modified using methods outlined in the sections below.<br />
<br />
Note that regardless of the chosen option, kernel messages can be displayed for inspection after booting by using {{ic|dmesg}} or all logs from the current boot with {{ic|journalctl -b}}.<br />
<br />
==== Flow control ====<br />
<br />
This is basic management that applies to most terminal emulators, including virtual consoles (vc):<br />
<br />
* Press {{ic|Ctrl+S}} to pause the output<br />
* And {{ic|Ctrl+Q}} to resume it<br />
<br />
This pauses not only the output, but also programs which try to print to the terminal, as they will block on the {{ic|write()}} calls for as long as the output is paused. If your ''init'' appears frozen, make sure the system console is not paused.<br />
<br />
To see error messages which are already displayed, see [[Getty#Have boot messages stay on tty1]].<br />
<br />
==== Scrollback ====<br />
<br />
Scrollback allows the user to go back and view text which has scrolled off the screen of a text console. This is made possible by a buffer created between the video adapter and the display device called the scrollback buffer. By default, the key combinations of {{ic|Shift+PageUp}} and {{ic|Shift+PageDown}} scroll the buffer up and down.<br />
<br />
If scrolling up all the way does not show you enough information, you need to expand your scrollback buffer to hold more output. This is done by tweaking the kernel's framebuffer console (fbcon) with the [[kernel parameter]] {{ic|1=fbcon=scrollback:Nk}} where {{ic|N}} is the desired buffer size is kilobytes. The default size is 32k.<br />
<br />
If this does not work, your framebuffer console may not be properly enabled. Check the [https://www.kernel.org/doc/Documentation/fb/fbcon.txt Framebuffer Console documentation] for other parameters, e.g. for changing the framebuffer driver.<br />
<br />
==== Debug output ====<br />
<br />
Most kernel messages are hidden during boot. You can see more of these messages by adding different kernel parameters. The simplest ones are:<br />
<br />
* {{ic|debug}} enables debug messages for both the kernel and [[systemd]]<br />
* {{ic|ignore_loglevel}} forces ''all'' kernel messages to be printed<br />
<br />
Other parameters you can add that might be useful in certain situations are:<br />
* {{ic|1=earlyprintk=vga,keep}} prints kernel messages very early in the boot process, in case the kernel would crash before output is shown. You must change {{ic|vga}} to {{ic|efi}} for [[EFI]] systems<br />
* {{ic|1=log_buf_len=16M}} allocates a larger (16MB) kernel message buffer, to ensure that debug output is not overwritten<br />
<br />
There are also a number of separate debug parameters for enabling debugging in specific subsystems e.g. {{ic|bootmem_debug}}, {{ic|sched_debug}}. Check the [https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt kernel parameter documentation] for specific information.<br />
<br />
{{Note|If you cannot scroll back far enough to view the desired boot output, you should increase the size of the [[#Scrollback|scrollback buffer]].}}<br />
<br />
=== Recovery shells ===<br />
<br />
Getting an interactive shell at some stage in the boot process can help you pinpoint exactly where and why something is failing. There are several kernel parameters for doing so, but they all launch a normal shell which you can {{ic|exit}} to let the kernel resume what it was doing:<br />
* {{ic|rescue}} launches a shell shortly after the root filesystem is remounted read/write<br />
* {{ic|emergency}} launches a shell even earlier, before most filesystems are mounted<br />
* {{ic|1=init=/bin/sh}} (as a last resort) changes the init program to a root shell. {{ic|rescue}} and {{ic|emergency}} both rely on [[systemd]], but this should work even if ''systemd'' is broken<br />
<br />
Another option is systemd's debug-shell which adds a root shell on {{ic|tty9}} (accessible with Ctrl+Alt+F9). It can be enabled by either adding {{ic|systemd.debug-shell}} to the [[kernel parameters]], or by [[enabling]] {{ic|debug-shell.service}}. Take care to disable the service when done to avoid the security risk of leaving a root shell open on every boot.<br />
<br />
=== Blank screen with Intel video ===<br />
<br />
This is most likely due to a problem with [[kernel mode setting]]. Try [[Kernel mode setting#Disabling modesetting|disabling modesetting]] or changing the [[Intel#KMS Issue: console is limited to small area|video port]].<br />
<br />
=== Stuck while loading the kernel ===<br />
<br />
Try disabling ACPI by adding the {{ic|1=acpi=off}} kernel parameter.<br />
<br />
=== Debugging kernel modules ===<br />
<br />
See [[Kernel modules#Obtaining information]].<br />
<br />
=== Debugging hardware ===<br />
<br />
* You can display extra debugging information about your hardware by following [[udev#Debug output]].<br />
* Ensure that [[Microcode]] updates are applied on your system.<br />
* Test your device's RAM with [http://www.memtest.org/ Memtest86+]. Unstable RAM may lead to some extremely odd issues, ranging from random crashes to data corruption.<br />
<br />
== Kernel panics ==<br />
<br />
A ''kernel panic'' occurs when the Linux kernel enters an unrecoverable failure state. The state typically originates from buggy hardware drivers resulting in the machine being deadlocked, non-responsive, and requiring a reboot. Just prior to deadlock, a diagnostic message is generated, consisting of: the ''machine state'' when the failure ocurred, a ''call trace'' leading to the kernel function that recognized the failure, and a listing of currently loaded modules. Thankfully, kernel panics do not happen very often using ''mainline'' versions of the kernel--such as those supplied by the official repositories--but when they do happen, you need to know how to deal with them.<br />
<br />
{{Note|Kernel panics are sometimes referred to as ''oops'' or ''kernel oops''. While both panics and oops occur as the result of a failure state, an ''oops'' is more general in that it does not ''necessarily'' result in a deadlocked machine--sometimes the kernel can recover from an oops by killing the offending task and carrying on.}}<br />
<br />
{{Tip|Pass the kernel parameter {{ic|1=oops=panic}} at boot or write {{ic|1}} to {{ic|/proc/sys/kernel/panic_on_oops}} to force a recoverable oops to issue a panic instead. This is advisable if you are concerned about the small chance of system instability resulting from an oops recovery which may make future errors difficult to diagnose.}}<br />
<br />
=== Examine panic message ===<br />
<br />
If a kernel panic occurs very early in the boot process, you may see a message on the console containing "Kernel panic - not syncing:", but once [[Systemd]] is running, kernel messages will typically be captured and written to the system log. However, when a panic occurs, the diagnostic message output by the kernel is ''almost never'' written to the log file on disk because the machine deadlocks before {{ic|system-journald}} gets the chance. Therefore, the only way to examine the panic message is to view it on the console as it happens (without resorting to setting up a ''kdump crashkernel''). You can do this by booting with the following kernel parameters and attempting to reproduce the panic on tty1:<br />
<br />
{{bc|1=systemd.journald.forward_to_console=1 console=tty1}}<br />
<br />
{{Tip|In the event that the panic message scrolls away too quickly to examine, try passing the kernel parameter {{ic|1=pause_on_oops=''seconds''}} at boot.}}<br />
<br />
==== Example scenario: bad module ====<br />
<br />
It is possible to make a best guess as to what subsystem or module is causing the panic using the information in the diagnostic message. In this scenario, we have a panic on some imaginary machine during boot. Pay attention to the lines highlighted in '''bold''':<br />
<br />
{{bc|'''kernel: BUG: unable to handle kernel NULL pointer dereference at (null)''' [1]<br />
'''kernel: IP: fw_core_init+0x18/0x1000 [firewire_core]''' [2]<br />
kernel: PGD 718d00067 <br />
kernel: P4D 718d00067 <br />
kernel: PUD 7b3611067 <br />
kernel: PMD 0 <br />
kernel: <br />
kernel: Oops: 0002 [#1] PREEMPT SMP<br />
'''kernel: Modules linked in: firewire_core(+) crc_itu_t cfg80211 rfkill ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG nf_conntrack_ipv4 ...''' [3] <br />
kernel: CPU: 6 PID: 1438 Comm: modprobe Tainted: P O 4.13.3-1-ARCH #1<br />
kernel: Hardware name: Gigabyte Technology Co., Ltd. H97-D3H/H97-D3H-CF, BIOS F5 06/26/2014<br />
kernel: task: ffff9c667abd9e00 task.stack: ffffb53b8db34000<br />
kernel: RIP: 0010:fw_core_init+0x18/0x1000 [firewire_core]<br />
kernel: RSP: 0018:ffffb53b8db37c68 EFLAGS: 00010246<br />
kernel: RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000<br />
kernel: RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffffc16d3af4<br />
kernel: RBP: ffffb53b8db37c70 R08: 0000000000000000 R09: ffffffffae113e95<br />
kernel: R10: ffffe93edfdb9680 R11: 0000000000000000 R12: ffffffffc16d9000<br />
kernel: R13: ffff9c6729bf8f60 R14: ffffffffc16d5710 R15: ffff9c6736e55840<br />
kernel: FS: 00007f301fc80b80(0000) GS:ffff9c675dd80000(0000) knlGS:0000000000000000<br />
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
kernel: CR2: 0000000000000000 CR3: 00000007c6456000 CR4: 00000000001406e0<br />
kernel: Call Trace:<br />
'''kernel: do_one_initcall+0x50/0x190''' [4]<br />
kernel: ? do_init_module+0x27/0x1f2<br />
kernel: do_init_module+0x5f/0x1f2<br />
kernel: load_module+0x23f3/0x2be0<br />
kernel: SYSC_init_module+0x16b/0x1a0<br />
kernel: ? SYSC_init_module+0x16b/0x1a0<br />
kernel: SyS_init_module+0xe/0x10<br />
kernel: entry_SYSCALL_64_fastpath+0x1a/0xa5<br />
kernel: RIP: 0033:0x7f301f3a2a0a<br />
kernel: RSP: 002b:00007ffcabbd1998 EFLAGS: 00000246 ORIG_RAX: 00000000000000af<br />
kernel: RAX: ffffffffffffffda RBX: 0000000000c85a48 RCX: 00007f301f3a2a0a<br />
kernel: RDX: 000000000041aada RSI: 000000000001a738 RDI: 00007f301e7eb010<br />
kernel: RBP: 0000000000c8a520 R08: 0000000000000001 R09: 0000000000000085<br />
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000c79208<br />
kernel: R13: 0000000000c8b4d8 R14: 00007f301e7fffff R15: 0000000000000030<br />
kernel: Code: <c7> 04 25 00 00 00 00 01 00 00 00 bb f4 ff ff ff e8 73 43 9c ec 48 <br />
kernel: RIP: fw_core_init+0x18/0x1000 [firewire_core] RSP: ffffb53b8db37c68<br />
kernel: CR2: 0000000000000000<br />
kernel: ---[ end trace 71f4306ea1238f17 ]---<br />
'''kernel: Kernel panic - not syncing: Fatal exception''' [5]<br />
kernel: Kernel Offset: 0x80000000 from 0xffffffff810000000 (relocation range: 0xffffffff800000000-0xfffffffffbffffffff<br />
kernel: ---[ end Kernel panic - not syncing: Fatal exception}}<br />
<br />
* [1] Indicates the type of error that caused the panic. In this case it was a programmer bug.<br />
* [2] Indicates that the panic happened in a function called ''fw_core_init'' in module ''firewire_core''.<br />
* [3] Indicates that ''firewire_core'' was the latest module to be loaded.<br />
* [4] Indicates that the function that called function ''fw_core_init'' was ''do_one_initcall''.<br />
* [5] Indicates that this ''oops'' message is, in fact, a kernel panic and the system is now deadlocked.<br />
<br />
We can surmise then, that the panic occurred during the initialization routine of module ''firewire_core'' as it was loaded. (We might assume then, that the machine's firewire hardware is incompatible with this version of the firewire driver module due to a programmer error, and will have to wait for a new release.) In the meantime, the easiest way to get the machine running again is to prevent the module from being loaded. We can do this in one of two ways:<br />
<br />
* If the module is being loaded during the execution of the ''initramfs'', reboot with the kernel parameter {{ic|1=rd.blacklist=firewire_core}}.<br />
* Otherwise reboot with the kernel parameter {{ic|1=module_blacklist=firewire_core}}.<br />
<br />
=== Reboot into root shell and fix problem ===<br />
<br />
You will need a root shell to make changes to the system so the panic no longer occurs. If the panic occurs on boot, there are several strategies to obtain a root shell before the machine deadlocks:<br />
<br />
* Reboot with the kernel parameter {{ic|emergency}}, {{ic|rd.emergency}}, or {{ic|-b}} to receive a prompt to login just after the root filesystem is mounted and {{ic|systemd}} is started.<br />
: {{Note|At this point, the root filesystem will be mounted '''read-only'''. Execute {{ic|# mount -o remount,rw /}} to make changes.}}<br />
* Reboot with the kernel parameter {{ic|rescue}}, {{ic|rd.rescue}}, {{ic|single}}, {{ic|s}}, {{ic|S}}, or {{ic|1}} to receive a prompt to login just after local filesystems are mounted.<br />
* Reboot with the kernel parameter {{ic|1=systemd.debug-shell=1}} to obtain a very early root shell on tty9. Switch to it with by pressing {{ic|Ctrl-Alt-F9}}.<br />
* Experiment by rebooting with different sets of kernel parameters to possibly disable the kernel feature that is causing the panic. Try the "old standbys" {{ic|1=acpi=off}} and {{ic|nolapic}}.<br />
: {{Tip|See {{ic|Documentation/admin-guide/kernel-parameters.txt}} in the Linux kernel source tree for all parameters.}}<br />
* As a last resort, boot with the '''Arch Linux Installation CD''' and mount the root filesystem on {{ic|/mnt}} then execute {{ic|# arch-chroot /mnt}}.<br />
<br />
Disable the service or program that is causing the panic, roll-back a faulty update, or fix a configuration problem.<br />
<br />
== Package management ==<br />
<br />
See [[Pacman#Troubleshooting]] for general topics, and [[pacman/Package signing#Troubleshooting]] for issues with PGP keys.<br />
<br />
== fuser ==<br />
<br />
{{Expansion|Needs more information about its usage}}<br />
<br />
''fuser'' is a command-line utility for identifying processes using resources such as files, filesystems and TCP/UDP ports.<br />
<br />
''fuser'' is provided by the {{Pkg|psmisc}} package, which should be already installed as part of the {{Grp|base}} group. See {{man|1|fuser}} for detail.<br />
<br />
== Session permissions ==<br />
<br />
{{Note|You must be using [[systemd]] as your init system for local sessions to work.[https://www.archlinux.org/news/d-bus-now-launches-user-buses/] It is required for polkit permissions and ACLs for various devices (see {{ic|/usr/lib/udev/rules.d/70-uaccess.rules}} and [http://enotty.pipebreaker.pl/2012/05/23/linux-automatic-user-acl-management/])}}<br />
<br />
First, make sure you have a valid local session within X:<br />
<br />
$ loginctl show-session $XDG_SESSION_ID<br />
<br />
This should contain {{ic|1=Remote=no}} and {{ic|1=Active=yes}} in the output. If it does not, make sure that X runs on the same tty where the login occurred. This is required in order to preserve the logind session.<br />
<br />
A D-Bus session should also be started along with X. See [[D-Bus#Starting the user session]] for more information on this.<br />
<br />
Basic [[polkit]] actions do not require further set-up. Some polkit actions require further authentication, even with a local session. A polkit authentication agent needs to be running for this to work. See [[polkit#Authentication agents]] for more information on this.<br />
<br />
== Message: "error while loading shared libraries" ==<br />
<br />
{{Accuracy|Or the program needs to be rebuilt after a [[System_maintenance#Partial_upgrades_are_unsupported|soname bump]].}}<br />
<br />
If, while using a program, you get an error similar to: <br />
<br />
error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory<br />
<br />
Use [[pacman]] or [[pkgfile]] to search for the package that owns the missing library:<br />
<br />
{{hc|$ pacman -Fs libusb-0.1.so.4|<br />
extra/libusb-compat 0.1.5-1<br />
usr/lib/libusb-0.1.so.4<br />
}}<br />
<br />
In this case, the {{Pkg|libusb-compat}} package needs to be [[installed]].<br />
<br />
The error could also mean that the package that you used to install your program does not list the library as a dependency in its [[PKGBUILD]]: if it is an official package, [[report a bug]]; if it is an [[AUR]] package, report it to the maintainer using its page in the AUR website.<br />
<br />
== Message: "file: could not find any magic files!" ==<br />
<br />
If you see this message, it likely indicates that a package update has corrupted the dynamic linker run-time bindings file and your system is now essentially crippled. You will not be able to recompile or reinstall the package responsible or rebuild the [[initramfs]] until you fix it.<br />
<br />
=== Problem ===<br />
<br />
A package update likely added an invalid {{ic|''filename''.conf}} to the directory {{ic|/etc/ld.so.conf.d}} or edited {{ic|/etc/ld.so.conf}} incorrectly. The result is that the dynamic linker run-time bindings file {{ic|/etc/ld.so.cache}} is being re-generated with invalid data. This can potentially cause all programs on the system that depend on shared libraries to fail (ie. almost all of them).<br />
<br />
=== Solution ===<br />
<br />
# Boot with the '''''Arch Linux Installation CD'''''.<br />
# Mount your root {{ic|/}} filesystem on {{ic|/mnt}} and your {{ic|/boot}} filesystem on {{ic|/mnt/boot}} and chroot into the broken system by executing {{ic|# arch-chroot /mnt}}.<br />
# Examine the file {{ic|/etc/ld.so.conf}} and remove any invalid lines found.<br />
# Examine the files located in the directory {{ic|/etc/ld.so.conf.d/}} and remove any invalid files.<br />
# Rebuild the dynamic linker run-time bindings file {{ic|/etc/ld.so.cache}} by executing {{ic|# ldconfig}}.<br />
# Rebuild the [[Initramfs]] by executing {{ic|# mkinitcpio -p linux}}.<br />
# Exit the chroot, unmount filesystems, and reboot back into your installed system.<br />
<br />
== See also ==<br />
<br />
* [http://www.tuxradar.com/content/how-fix-most-common-linux-problems Fix the Most Common Problems]{{Dead link|2018|02|05}}<br />
* [https://www.reddit.com/r/archlinux/comments/tjjwr/archlinux_a_howto_in_troubleshooting_for_newcomers/ A how-to in troubleshooting for newcomers]<br />
* [http://wiki.ultimatebootcd.com/index.php?title=Tools List of Tools for UBCD] - Memtest-like tools to add to grub.cfg on UltimateBootCD.com<br />
* [[Wikipedia:BIOS Boot partition]]<br />
* [[REISUB]]<br />
* [http://freedesktop.org/wiki/Software/systemd/Debugging#Debug_Logging_to_a_Serial_Console Debug Logging to a Serial Console] on Freedesktop.org<br />
* [https://web.archive.org/web/20120217124742/http://www.lesswatts.org/projects/acpi/debug.php How to Isolate Linux ACPI Issues] on Archive.org</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515264
Mathematica (简体中文)
2018-03-30T06:20:54Z
<p>Arisaka: </p>
<hr />
<div>[[Category:Mathematics and science (简体中文)]]<br />
[[en:Mathematica]]<br />
[[it:Mathematica]]<br />
[[ja:Mathematica]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Scientific Applications (简体中文)}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Mathematica|2018-03-30|515047}}<br />
<br />
[http://www.wolfram.com/mathematica/ Mathematica] 是用于科学,工程和数学领域的商业软件。在这里我们说明如何安装它。<br />
<br />
== 安装 ==<br />
<br />
由于 Mathematica 是专有软件,升级可能会产生成本,因此本节列出了不同可用版本的说明。<br />
<br />
=== Mathematica 6 ===<br />
<br />
==== 挂载 iso 文件 ====<br />
<br />
挂载 Mathematica {{ic|.iso}} 的一种方式是创建 {{ic|/media/iso}} 目录用于挂载,并在 [[fstab]] 中增加这几行:<br />
/''location/of/mathematica.iso'' /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
然后就可以这样挂载它:<br />
# mount /media/iso<br />
<br />
==== 运行安装程序 ====<br />
<br />
进入这个目录来启动安装程序:<br />
/Unix/Installer<br />
运行 ''MathInstaller'':<br />
sh ./MathInstaller<br />
{{注意|如果没有把 "sh" 放在前面,那么会得到一个关于解释器出错 (bad interpreter) 的错误信息。}}<br />
<br />
==== 字体 ====<br />
<br />
向 FontPath 里添加包含 Type1 和 BDF 字体的目录。<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 安装起来非常方便。<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
按照指示完成即可。<br />
<br />
KDE 用户注意,Mathematica 的图标可能会出现在 ''Lost & Found'' 分类里面。解决方法是以 root 用户身份运行下列命令:<br />
<br />
# ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
=== Mathematica 8 ===<br />
<br />
Mathematica 8 的一个问题是执行 WolframAlpha[ ] 函数时会出现崩溃,这个崩溃可以重现。Mathematica 的默认配置为,在设置如何连接到互联网以获取数据时,检测系统的代理设置。但是在调用库函数时存在一个 bug,最终会使 Mathematica 崩溃。解决方法是通过将 Mathematica 配置为“直接连接”到互联网来完全避免此库调用 (''Edit > Preferences > Internet Connectivity > Proxy Settings'')。这个错误已经报告给 Wolfram。<br />
<br />
=== Mathematica 10 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}} (需要旧版本)。需要 {{ic|Mathematica_10.XX.YY_LINUX.sh}} 安装脚本,从 Wolfram.com 或某大学的站点上下载。同时你还需要一个激活密钥。<br />
<br />
=== Mathematica 11 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}}。从 Wolfram Research 获取 {{ic|Mathematica_11.XX.YY_LINUX.sh}} 和激活密钥。成功的安装可能也会抛出一些不严重的错误:xdg-icon-resource, mkdir, xdg-desktop-menu 等。<br />
<br />
Mathematica 11 在 [https://reference.wolfram.com/language/ref/$UserDocumentsDirectory.html $UserDocumentsDirectory] 自动创建 'Wolfram Mathematica' 文件夹,Mathematica 根据 [[XDG user directories]] 自动设置了这个变量。<br />
<br />
== 故障排除 == <br />
<br />
==== "Missing symbols" 错误 ====<br />
<br />
如果出现字体渲染问题,某些符号无法显示(比如 {{ic|/}} 显示为正方形),请尝试卸载 {{Pkg|font-mathematica}}。<br />
<br />
同时,尝试 [http://mathematica.stackexchange.com/questions/1158/invisible-conjugate-glyph-in-the-linux-frontend 这种] 方案。其中还说明了 Mathematica 版本 9 修复了这个问题。<br />
<br />
尝试让应用程序使用抗锯齿。<br />
对于 KDE 用户: ''System Settings > Application Appearance > Fonts > Use anti-aliasing (Enabled)''<br />
<br />
==== HiDPI / Retina 屏幕 ====<br />
<br />
如果你有一块 [[HiDPI]] 屏幕,比如 Apple Retina 屏幕,而且 Mathematica 里面的文字非常小,这样就能解决:<br />
<br />
* 打开 ''Edit → Preferences''<br />
* 在 ''Advanced'' 选项卡里单击 ''Open Option Inspector''<br />
* 在右侧的树状列表中找到 ''Formatting Options → Font Options → Font Properties''<br />
* 改变 ''"ScreenResolution"'' 的值到它原来的两倍大小,比如 72 → 144。你也可以用 <code>xdpyinfo | grep resolution</code> 来获得一个更精确的数字(也要变成原来的两倍大小)。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Official site]<br />
* [http://www.wolfram.com/support/ Official Support]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=ArchWiki:Translation_Team_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515222
ArchWiki:Translation Team (简体中文)
2018-03-29T06:51:43Z
<p>Arisaka: Update translate status info about “Core utilities”</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:ArchWiki (简体中文)]]<br />
[[ar:ArchWiki Translation Team]]<br />
[[cs:ArchWiki Translation Team]]<br />
[[el:ArchWiki Translation Team]]<br />
[[en:ArchWiki Translation Team]]<br />
[[es:ArchWiki Translation Team]]<br />
[[fr:ArchWiki Translation Team]]<br />
[[hr:ArchWiki Translation Team]]<br />
[[it:ArchWiki Translation Team]]<br />
[[ja:ArchWiki 翻訳チーム]]<br />
[[ko:ArchWiki Translation Team]]<br />
[[nl:ArchWiki Translation Team]]<br />
[[pl:ArchWiki Translation Team]]<br />
[[pt:ArchWiki Translation Team]]<br />
[[ru:ArchWiki Translation Team]]<br />
[[sk:ArchWiki Translation Team]]<br />
Arch Wiki 上有许多中文页面,这其中大部分是从外文翻译过来的,这些页面是无数中文志愿者劳动的结晶。随着时间推移,有些页面因为没有及时维护,内容严重过时。而目前的翻译工作缺少组织,效率偏低。所以参照西班牙和意大利翻译组的做法,添加这个页面。<br />
<br />
如果你希望对Arch Wiki做贡献,参与Wiki建设,比如翻译英文页面和对已翻译过的中文页面进行维护,只需要编辑下面的[[#页面维护列表]],添加相应的条目,并将自己加为相关页面的维护者。如果你在列表中还没有找到想要翻译的页面,可以自行添加。另外,如果因为时间原因无法再维护页面,请及时将自己从维护者列表中删除。<br />
<br />
== 创建翻译 ==<br />
{{注意|如果不准备翻译页面的大部分内容,请尽量不要新建简体中文页面。检查英文页面的更新需要花费不少精力,没有翻译的页面会增加维护负担。}}<br />
# 如果还不知道如何编辑 wiki,请阅读 [[Help:Editing (简体中文)|编辑帮助]]。<br />
# 阅读 [[Help:i18n (简体中文)|i18n帮助]],文章给出了 ArchWiki 国际化和本地化的指南。<br />
# [[Special:UserLogin|登录]] 以进行编辑。<br />
# 选择要翻译的页面,例如从 [[Special:Random|随机页面]] 或[[#页面维护列表|页面维护列表]] 中选择一个未翻译完成的页面。假设要翻译 [[Some Page]].<br />
# 进入选择的英文页面,点击页面顶部的 '''编辑'''。<br />
# 添加要翻译文件的语言间链接, 简体中文的话加入<nowiki>[[zh-hans:Some Page]]</nowiki>,其它语言参见[[Help:i18n#Interlanguage links]])。<br />
# 复制所有页面代码。<br />
# 保存页面 (新加了语言链接)<br />
# 访问页面左边新添加的语言链接,应该会进到 [[Some Page (简体中文)]] : {{ic|<nowiki>https://wiki.archlinux.org/index.php/Some_Page_(</nowiki>''简体中文'')}}<br />
# 因为页面不存在,点击 '''创建'''。<br />
# 将显示一个编辑器 - 粘贴复制的英文页面。<br />
# 将文章分类修改为本地化版本,例如将 {{ic|<nowiki>[[Category:Internationalization]]</nowiki>}} 修改为 {{ic|<nowiki>[[Category:Internationalization (简体中文)]]</nowiki>}},参阅[[Help:Category (简体中文)]].<br />
# 修改语言间链接,指向英文页面(将 {{ic|zh-hans}} 修改为 {{ic|en}},并将英文页面移到文章顶部。<br />
# 翻译页面,进行保存。<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
# 更新所有其它语言页面,加入刚翻译文章的语言间链接。<br />
# (可选)创建一个简体中文名称的页面,指向新创建的页面:访问 {{ic|<nowiki>https://wiki.archlinux.org/index.php/</nowiki>''页面的中文名称''}}.<br />
# (可选)建立新页面,并加入:{{bc|<nowiki>#REDIRECT [[Some Page (简体中文)</nowiki>]]}}<br />
<br />
== 完善翻译 ==<br />
[https://wiki.archlinux.org/index.php?title=Special:WhatLinksHere/Template:Translateme_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&limit=100 这个页面] 包含了需要完善翻译的简体中文页面。完善翻译的基本步骤:<br />
# 选择自己比较熟悉的文章进行翻译<br />
# 先检查英文页面的对应段落,更新成最新的英文后再翻译,避免翻译过时的内容,减少信息遗漏。<br />
# 翻译完成后删除页面中的 <nowiki>{{translateme (简体中文)}}</nowiki> 标记<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
<br />
== 更新过期页面 == <br />
如果发现有 Wiki 页面过期或错误:<br />
* 小的改动,有时间可以立即进行修改同步,维护者并不控制页面的编辑权限,越多的人参与维护越好。如果改动较大,请先联系维护者,避免重复劳动。<br />
* 没有时间查看更改,请给页面加上 {{ic|<nowiki>{{out of date}}</nowiki>}} 模版,这样其他贡献者更容易发现需要更新的页面,而读者看到过期标记就可以直接查看英文页面,以免被错误内容误导,白白耽误时间。<br />
* 没有时间翻译,请将过期的中文部分删去,从英文页面中复制更改的部分到中文页面的相应部分,去掉{{ic|<nowiki>{{out of date}}</nowiki>}}模板(如果页面上有的话)并加上{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他贡献者就更容易发现需要翻译的页面,而读者也不会被过期的内容误导。<br />
如果发现有页面未翻译:<br />
* 有时间的话,请将页面中的英文部分翻译为中文,并去掉{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板。<br />
* 没有时间翻译,请为页面添加{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他的贡献者就能更容易发现需要翻译的页面。<br />
{{注意|在修改页面上的模板时,请同时更新页面维护列表的翻译状态。}}<br />
<br />
== 翻译任务 ==<br />
=== 模板 Article summary 变更为 Related ===<br />
因为 Summary 中的简介基本上和正文的介绍一样,所以页面左边的介绍栏进行了简化,只保留相关文章功能。英文页面正在进行大规模修改,相应的中文页面也需要同步更新。<br />
<br />
需要注意的地方:<br />
* 将第一行改成<br />
: <nowiki>{{Related articles start (简体中文)}}</nowiki><br />
* 如果英文的相关文章存在中文翻译,则替换为简体中文页面。示例:<br />
: <nowiki>{{Related2|Display Manager (简体中文)|显示管理器}}</nowiki><br />
* 示例:[https://wiki.archlinux.org/index.php?title=Start_X_at_Login&diff=0&oldid=270155 英文变更], [https://wiki.archlinux.org/index.php?title=Start_X_at_Login_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=285643&oldid=242662 对应的翻译]<br />
<br />
== 维护翻译 ==<br />
完成页面的翻译只是初步完成任务,及时同步英文页面改动、更新翻译是一个持续性的工作,可能会耗费更多的时间。<br />
<br />
=== 页面认领 ===<br />
所有人都可以认领页面。认领后的责任包括进行翻译,关注英文页面的改动,及时同步翻译。<br />
<br />
为了更好的跟踪英文页面的修改,请务必在设置中启用监视列表邮件通知,并监视对应的英文页面(从设置中找到监视列表,加入英文页面。或者直接到英文页面点击页面顶端的监视标签。这样只要有改动,就会收到邮件通知)。<br />
<br />
{{小贴士|如果收到邮件通知后没有访问页面或者访问了页面却没有登录用户,下次页面改动时就不会再发邮件通知。可以点击监视列表中的'''标记所有页面为已读'''再次获取更新。}}<br />
<br />
如果页面有维护者但长期得不到更新,将会在维护列表中删除维护者。<br />
<br />
=== 翻译状态模板 ===<br />
Arch 作为滚动发行版,软件变化比较快,对应的文档变化也比较快。许多翻译的文章由于缺乏更新,会产生命令运行出错或不起作用等问题。而由于这些过期页面没有及时标记出来,所以用户无法及时获得更新。[[Template:TranslationStatus (简体中文)|翻译状态模板]]就是为了解决这个问题而创建。<br />
<br />
此模板可以起到如下作用:<br />
* 为用户提供翻译状况,包括翻译时间、英文页面的最后版本等<br />
* 用户可以点击查看翻译后,英文页面的改动,这样英文不是很好的用户可以只查看很小一部分英文内容,并判断出是否影响操作。<br />
* 翻译人员可以跟踪页面状况,通过[[Special:WhatLinksHere/Template:TranslationStatus_(简体中文)|模板的反向链接]]可以查找到所有标记页面,查看需要更新翻译的部分。<br />
<br />
[[Template:TranslationStatus (简体中文)|模板页面]]有详细的使用方法。<br />
<br />
=== 页面维护列表 ===<br />
{{注意|请按照拉丁字母顺序添加页面。}}<br />
<br />
翻译状态说明:<br />
;过期:页面内容未与英文页面同步,对应{{ic|<nowiki>{{out of date}}</nowiki>}} 模版<br />
;未翻译:页面中含有英文内容,对应{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板<br />
;完成:页面已与英文页面同步<br />
<br />
{| class="wikitable sortable collapsible" border="1"<br />
|-<br />
! 页面<br />
! 翻译状态<br />
! 维护者<br />
! class="unsortable" width="30%" | 备注<br />
|-<br />
| [[AMD Catalyst (简体中文)]]<br />
| 过期<br />
| Shibao Zhao<br />
| 无<br />
|-<br />
| [[acpid (简体中文)]]<br />
| 过期<br />
| Cael<br />
|<br />
|-<br />
| [[Advanced Linux Sound Architecture (简体中文)]]<br />
| 翻译中<br />
| ihonliu<br />
| 无<br />
|-<br />
| [[Arch based distributions (active) (简体中文)]]<br />
| 完成<br />
| Joshua<br />
| 勘误中<br />
|-<br />
| [[ATI (简体中文)]]<br />
| 完成<br />
| skysailing<br />
| 无<br />
|-<br />
| [[AUR helpers (简体中文)]]<br />
| 进行中<br />
| Stonex<br />
| 无<br />
|-<br />
| [[awesome (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无<br />
|-<br />
| [[BIND (简体中文)]]<br />
| 完成<br />
| Dargasia<br />
|<br />
|-<br />
| [[Bumblebee (简体中文)]]<br />
| 完成<br />
| Peter<br />
| 无<br />
|-<br />
| [[Chromium (简体中文)]]<br />
| 完成<br />
| Bobby<br />
| 无<br />
|-<br />
| [[Ceph (简体中文)]]<br />
| 翻译中<br />
| Aaron Chen<br />
| 部分未翻译 <br />
|-<br />
| [[Cinnamon (简体中文)]]<br />
| 部分翻译 <br />
| Bobby<br />
| 部分未翻译 <br />
|- <br />
| [[Common Applications (简体中文)]]<br />
| 部分翻译 <br />
| DavidChen<br />
| 翻译中<br />
|-<br />
| [[Common Applications/Science (简体中文)]]<br />
| drop maintain<br />
| 更新,翻译中<br />
|<br />
|-<br />
| [[Compiz (简体中文)]]<br />
| 翻译中<br />
| xiii_1991<br />
| 20140813开始<br />
|-<br />
| [[Core utilities (简体中文)]]<br />
| 完成<br />
| rentaro, Arisaka<br />
| 无<br />
|-<br />
|-<br />
| [[Clover (简体中文)]]<br />
| 完成<br />
| Yume Kankawa<br />
| 无<br />
|-<br />
| [[Disk cloning (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Dynamic Kernel Module Support (简体中文)]]<br />
| 完成<br />
| Mithrandir<br />
| 完善中<br />
|-<br />
| [[Emacs (简体中文)]]<br />
| 翻译中<br />
| Jaurung yuanhang<br />
| 未完成<br />
|-<br />
| [[File recovery (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Font configuration (简体中文)]]<br />
| 翻译中<br />
| Jaurung<br />
| 完善中<br />
|-<br />
| [[Fonts (简体中文)]]<br />
| 翻译中<br />
| qqbzg<br />
| 无<br />
|-<br />
| [[GNOME (简体中文)]]<br />
| 过期<br />
| <br />
| <br />
|-<br />
| [[KDE (简体中文)]]<br />
| 过期<br />
| <br />
| <br />
|-<br />
| [[LAMP (简体中文)]]<br />
| 完成<br />
| Liuzhengyi<br />
| 勘误中<br />
|-<br />
| [[LibreOffice (简体中文)]]<br />
| 完成<br />
| qqbzg<br />
| 勘误中<br />
|-<br />
| [[Local Mirror (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|- <br />
| [[Matlab (简体中文)]]<br />
| 部分翻译 <br />
| Liu Qinyang<br />
|<br />
|-<br />
| [[NetworkManager (简体中文)]]<br />
| 翻译中 <br />
| Jack-lijing, leeking <br />
| 请优先翻译<br />
|-<br />
| [[Network Time Protocol daemon (简体中文)]]<br />
| 完成<br />
| sid<br />
| 完善中<br />
|-<br />
| [[OpenOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Opera (简体中文)]]<br />
| 未翻译<br />
| Bobby<br />
| 请优先翻译此文 <br />
|-<br />
| [[Pacman GUI Frontends (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Pidgin (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无 <br />
|- <br />
| [[ranger (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[Raspberry Pi (简体中文)]]<br />
| 翻译中<br />
| Mithrandir<br />
| <br />
|-<br />
| [[Reporting bug guidelines (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[Secure Shell (简体中文)]]<br />
| 完成<br />
| Arisaka<br />
| 无<br />
|-<br />
| [[Smart Common Input Method platform (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Systemd-timesyncd (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[Tomcat (简体中文)]]<br />
| 完成<br />
| Starwing117<br />
| 持续更新中 <br />
|-<br />
| [[Vim (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[VirtualBox (简体中文)]]<br />
| 翻译至 2017-10-15<br />
| [[User:5long]]<br />
|<br />
|-<br />
| [[VMware (简体中文)]]<br />
| 完成<br />
| ThomasWFan<br />
| 页面已经与英文版同步,长期维护中<br />
|- <br />
| [[Xfce (简体中文)]]<br />
| 完成 <br />
| 无<br />
| 无<br />
|-<br />
| [[Xmonad (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Xrandr (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Python打包指引 (简体中文)]]<br />
| 翻译中<br />
| SherlockHolo<br />
| 无</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Core_utilities_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515220
Core utilities (简体中文)
2018-03-29T06:48:57Z
<p>Arisaka: Full sync with English Version.</p>
<hr />
<div>[[Category:System administration (简体中文)]]<br />
[[Category:Command shells (简体中文)]]<br />
[[en:Core utilities]]<br />
[[es:Core utilities]]<br />
[[fa:Core utilities]]<br />
[[it:Core utilities]]<br />
[[ja:Core Utilities]]<br />
[[ko:Core utilities]]<br />
[[pt:Core utilities]]<br />
[[ru:Core utilities]]<br />
[[zh-hant:Core utilities]]<br />
{{TranslationStatus (简体中文)|Core_Utilities|2018-03-29|513811}}<br />
{{Related articles start (简体中文)}}<br />
{{Related|Bash (简体中文)}}<br />
{{Related|Zsh (简体中文)}}<br />
{{Related2|General Recommendations (简体中文)|常用建议}}<br />
{{Related|GNU Project}}<br />
{{Related|sudo (简体中文)}}<br />
{{Related|cron (简体中文)}}<br />
{{Related|man page (简体中文)}}<br />
{{Related|Securely wipe disk#shred}}<br />
{{Related|File permissions and attributes}}<br />
{{Related|Color output in console (简体中文)}}<br />
{{Related articles end}}<br />
<br />
本文涉及 GNU/Linux 系统的所谓的 "核心" 工具,比如 '''less''', '''ls''', 和 '''grep''',包括但不限于以上集成于 GNU {{Pkg|coreutils}} 中的工具。下文提供了关于这些实用工具颇为丰富的技巧和有帮助的其他信息。<br />
<br />
== 基本命令 ==<br />
<br />
下面表格列出了每个 Linux 用户都应该熟悉的命令,黑体命令是 shell 的一部分,其它的是 shell 调用的程序。命令的细节请阅读接下来的几节和''相关文章''。<br />
<br />
{| class="wikitable"<br />
! 命令<br />
! 描述<br />
! 手册页名称<br />
! 示例<br />
|-<br />
| man<br />
| 显示命令的手册页<br />
| {{man|7|man}}<br />
| man ed<br />
|-<br />
| '''cd'''<br />
| 变更目录<br />
| {{man|1p|cd}}<br />
| cd /etc/pacman.d<br />
|-<br />
| mkdir<br />
| 创建目录<br />
| {{man|1|mkdir}}<br />
| mkdir ~/newfolder<br />
|-<br />
| rmdir<br />
| 删除空目录<br />
| {{man|1|rmdir}}<br />
| rmdir ~/emptyfolder<br />
|-<br />
| rm<br />
| 删除文件<br />
| {{man|1|rm}}<br />
| rm ~/file.txt<br />
|-<br />
| rm -r<br />
| 删除目录和内容<br />
|<br />
| rm -r ~/.cache<br />
|-<br />
| ls<br />
| 显示文件<br />
| {{man|1|ls}}<br />
| ls *.mkv<br />
|-<br />
| ls -a<br />
| 显示隐藏文件<br />
|<br />
| ls -a /home/archie<br />
|-<br />
| ls -al<br />
| 显示隐藏文件和文件属性<br />
|<br />
|<br />
|-<br />
| mv<br />
| 移动文件<br />
| {{man|1|mv}}<br />
| mv ~/compressed.zip ~/archive/compressed2.zip<br />
|-<br />
| cp<br />
| 复制文件<br />
| {{man|1|cp}}<br />
| cp ~/.bashrc ~/.bashrc.bak<br />
|-<br />
| chmod +x<br />
| 设置文件为可执行文件<br />
| {{man|1|chmod}}<br />
| chmod +x ~/.local/bin/myscript.sh<br />
|-<br />
| cat<br />
| 显示文件内容<br />
| {{man|1|cat}}<br />
| cat /etc/hostname<br />
|-<br />
| strings<br />
| 显示文件中可打印的内容<br />
| {{man|1|strings}}<br />
| strings /usr/bin/free<br />
|-<br />
| find<br />
| 查找文件<br />
| {{man|1|find}}<br />
| find ~ -name myfile<br />
|-<br />
| mount<br />
| 挂载分区<br />
| {{man|8|mount}}<br />
| mount /dev/sdc1 /media/usb<br />
|-<br />
| df -h<br />
| 显示分区上的剩余空间<br />
| {{man|1|df}}<br />
|<br />
|-<br />
| ps -A<br />
| 显示所有正在运行的进程<br />
| {{man|1|ps}}<br />
|<br />
|-<br />
| killall<br />
| 杀死所有运行中的进程<br />
| {{man|1|killall}}<br />
|<br />
|-<br />
| ss -at<br />
| 显示开放的 TCP 连接列表<br />
| {{man|8|ss}}<br />
|<br />
|}<br />
<br />
== cat ==<br />
<br />
[[Wikipedia:cat_(Unix)|cat]] 是一个能够连接并显示多文件的标准 Unix 工具。<br />
<br />
* '''cat''' 并不内置于 shell ,不过若追求高性能,你会发现在很多情况下改用[[wikipedia:Redirection (computing)|重定向]]就很方便得许多,例如编写脚本。事实上,{{ic|$ < ''file''}} 的效果就如同 {{ic|$ cat ''file''}} 一样。<br />
<br />
* 按照以下结构可直接在某文件添加多行文字:<br />
<br />
{{bc|<br />
$ cat << EOF >> ''path/file''<br />
''first line''<br />
...<br />
''last line''<br />
EOF<br />
}}<br />
<br />
或者使用 {{ic|printf}}:<br />
<br />
{{bc|<br />
$ printf '%s\n' 'first line' ... 'last line'<br />
}}<br />
<br />
* 如果您希望能以倒读顺序显示文件内容,有个工具叫 [[Wikipedia:tac (Unix)|tac]] (''cat'' 倒着写).<br />
<br />
== dd ==<br />
<br />
[[Wikipedia:dd (Unix)|dd]] 是在 unix 和 类 unix 系统中主要用于转换和拷贝文件的命令。<br />
<br />
与 ''cp'' 类似,默认情况下 ''dd'' 以块为单位拷贝文件,具有较低级别的 I/O流 控制功能。<br />
<br />
{{提示|默认情况下在任务完成前 dd 都没有输出,要监控操作的进度,可以添加 {{ic|1=status=progress}} 选项。}}<br />
<br />
更多信息参考 {{man|1|dd}} 或 [https://www.gnu.org/software/coreutils/dd 完整文档]。<br />
<br />
==grep==<br />
<br />
[[Wikipedia:grep|grep]] (来自 [[Wikipedia:ed|ed]] 的 ''g/re/p'',''global/regular expression/print'')是最初给 Unix 写的命令行文字搜索工具,{{ic|grep}} 命令在文件或标准输入里搜索符合指定正则表达式模式的行,并把结果打印到标准输出。<br />
<br />
* 记住,''grep'' 能直接处理文件,所以用 {{ic|grep ''pattern'' ''file''}} 代替 {{ic|cat ''file'' <nowiki>|</nowiki> grep ''pattern''}} 即可。<br />
* 若要 grep 版本控制系统(VCS)的源代码,请使用专门的工具 {{Pkg|ripgrep}}、{{Pkg|the_silver_searcher}} 和 {{Pkg|ack}}。<br />
* 要在输出结果中显示行数,加上 {{ic|-n}} 选项。 <br />
<br />
{{注意|一些命令把错误输出到 {{man|3|stderr}},grep 就无法处理。这时,用 {{ic|''command'' 2>&1 {{!}} grep ''args''}} 或 (对于 Bash 4) {{ic|''command'' {{!}}& grep ''args''}} 将 ''stderr'' 重定向到 ''stdout''。参阅 [http://www.tldp.org/LDP/abs/html/io-redirection.html I/O 重定向]。}}<br />
<br />
参阅 [[Color output in console#grep]] 来启用彩色输出支持。<br />
<br />
== find ==<br />
<br />
''find'' 是 {{Pkg|findutils}} 软件包的一部分, 它属于 {{Grp|base}} 软件包组。<br />
<br />
{{提示|{{Pkg|fd}} 是 {{ic|find}} 的一个更加简单、快速、友好的替代方案,它有着更合理的默认值(比如忽略隐藏文件、文件夹和 {{ic|.gitignore}} 等文件,可用 {{ic|fd PATTERN}} 代替 {{ic|find -iname '*PATTERN*'}})。它具有彩色输出(类似 {{ic|ls}}),unicode 支持,正则表达式等等。}}<br />
<br />
你可能希望 ''find'' 命令将一个文件名称作为参数,并在文件系统中搜索与该名称匹配的文件。下面的 [[#locate]] 程序可以专门做这件事。<br />
<br />
相反,find 需要一组目录,并将它们下面的每个文件与一组表达式进行匹配。这种设计为实现一些“能干的单行小程序”提供了强大的支持,而这是上述“直观”设计无法实现的。参阅 [http://mywiki.wooledge.org/UsingFind UsingFind] 来获取使用说明。<br />
<br />
== iconv ==<br />
<br />
''iconv'' 将转换一个文本的字符编码。<br />
<br />
下列命令将文件 {{ic|''foo''}} 从 ISO-8859-15 转换至 UTF-8,然后保存到 {{ic|''foo''.utf}}:<br />
<br />
$ iconv -f ISO-8859-15 -t UTF-8 ''foo'' > ''foo''.utf<br />
<br />
查阅 {{man|1|iconv}} 获取更多细节。<br />
<br />
=== 在原文件上转换 ===<br />
<br />
{{提示|如果你不想改变文件的修改时间,可以用 {{pkg|recode}} 代替 iconv。}}<br />
与 [[#sed|sed]] 不同,''iconv'' 没有提供直接转换文件的选项,但是 {{pkg|moreutils}} 包里面的 {{ic|sponge}} 可以帮忙:<br />
<br />
$ iconv -f WINDOWS-1251 -t UTF-8 ''foobar''.txt | sponge ''foobar''.txt<br />
<br />
更多细节请参阅 {{man|1|sponge}}。<br />
<br />
== ip ==<br />
<br />
[[Wikipedia:Iproute2|ip]] 显示关于网络设备,IP 地址,路由表和其他 Linux [[Wikipedia:Internet Protocol|IP]] 软件栈的对象信息。通过附加各种命令,你可以操纵或配置大多数对象。<br />
<br />
{{注意| ''ip'' 命令在 {{Pkg|iproute2}} 包中提供,这个包已经包含在 {{Grp|base}} 组。}}<br />
<br />
{| class="wikitable"<br />
! 对象 !! 作用 !! 手册页名称<br />
|-<br />
| ip addr || 协议地址管理 || {{man|8|ip-address}} <br />
|-<br />
| ip addrlabel || 协议地址标签管理 || {{man|8|ip-addrlabel}}<br />
|-<br />
| ip l2tp || tunnel Ethernet over IP (L2TPv3) || {{man|8|ip-l2tp}}<br />
|-<br />
| ip link || 网络设备配置 || {{man|8|ip-link}}<br />
|-<br />
| ip maddr || 多播地址管理 || {{man|8|ip-maddress}}<br />
|-<br />
| ip monitor || 监测 netlink 信息 || {{man|8|ip-monitor}}<br />
|-<br />
| ip mroute || 多播路由缓存管理 || {{man|8|ip-mroute}}<br />
|-<br />
| ip mrule || 多播路由策略数据库的规则 ||<br />
|-<br />
| ip neigh || 邻居/ARP 表管理|| {{man|8|ip-neighbour}}<br />
|-<br />
| ip netns || process network namespace management || {{man|8|ip-netns}}<br />
|-<br />
| ip ntable || 邻居表配置 || {{man|8|ip-ntable}}<br />
|-<br />
| ip route || 路由表管理 || {{man|8|ip-route}}<br />
|-<br />
| ip rule || 路由策略数据库管理 || {{man|8|ip-rule}}<br />
|-<br />
| ip tcp_metrics || 管理 TCP Metrics || {{man|8|ip-tcp_metrics}}<br />
|-<br />
| ip tunnel || 隧道配置 || {{man|8|ip-tunnel}}<br />
|-<br />
| ip tuntap || 管理 TUN/TAP 设备 ||<br />
|-<br />
| ip xfrm || 管理 IPsec 策略 || {{man|8|ip-xfrm}}<br />
|}<br />
<br />
{{ic|help}} 帮助命令可用于所有对象。例如,输入 {{ic|ip addr help}} 将显示地址的命令语法。高级用法参见 [http://www.policyrouting.org/iproute2.doc.html iproute2 documentation]。<br />
<br />
[[Network configuration]] 显示 ''ip'' 命令的多种常见任务中的使用方式。<br />
<br />
{{注意|你也许很熟悉 [[Wikipedia:ifconfig|ifconfig]] 命令,它用于旧版linux的接口配置。在 Arch Linux 中现已不赞成使用;应当用 ''ip'' 替代之。}}<br />
<br />
== locate ==<br />
<br />
[[安装]] 软件包 {{Pkg|mlocate}}。包里包括了一个 {{ic|updatedb.timer}} 单元,用于每天更新数据库。这个 systemd 定时器在安装后就会 enable,如果不想重启系统,请手动 [[start]]。以 root 手动运行 ''updatedb'' 也可以更新数据库。默认会忽略 {{ic|/media}} 和 {{ic|/mnt}} 等路径,所以 ''locate'' 不会查找外置设备里的文件。详情请参考 {{man|8|updatedb}}。<br />
<br />
''locate'' 命令是一个快速查找文件系统的常用 Unix 工具。因为是从数据库查找而不是直接访问文件系统,所以速度比 [[wikipedia:Find|find]] 快很多。而缺点是在数据库更新后创建的新文件不会被搜索到。<br />
<br />
使用 ''locate'' 前需建立数据库,请先以 root 权限执行 {{ic|updatedb}}。<br />
<br />
详情参考 [http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ How locate works and rewrite it in one minute]。<br />
<br />
== less ==<br />
<br />
{{Expansion|less 是一个复杂的家伙,这一章应该介绍一些基本的 less 命令。}}<br />
<br />
[[Wikipedia:less (Unix)|less]] 是一个对文本文件内容进行分页显示的终端程序,它和其他的分页显示程序如 [[Wikipedia:more (command)|more]] 和 [[Wikipedia:pg (Unix)|pg]] 相似,但 ''less'' 提供了更高级的界面和更多的 [http://www.greenwoodsoftware.com/less/faq.html 功能]。<br />
<br />
参阅 [[List of applications#Terminal pagers]] 查找更多替代方案。<br />
<br />
=== 用 Vim 代替 less 来分页 ===<br />
<br />
[[Vim]] 内置了脚本,可直接查看文本文件、压缩包或目录的内容。在你的 shell 配置文件添加以下内容:<br />
{{hc|~/.bashrc|2=alias less='/usr/share/vim/vim80/macros/less.sh'}}<br />
<br />
除了 ''less.sh'' 宏外还有另外一种用法,依赖于 {{ic|PAGER}} 环境变量。安装 {{Pkg|vimpager}} 并添加以下内容至shell配置文件:<br />
{{hc|~/.bashrc|2=<br />
export PAGER='vimpager'<br />
alias less=$PAGER<br />
}}<br />
<br />
这样,所有使用 {{ic|PAGER}} 环境变量的程序, 如 [[git]], 将使用 ''vim'' 作为分页程序。<br />
<br />
== ls ==<br />
<br />
[[Wikipedia:ls|ls]] 是一个Unix和类Unix系统中列出目录里的文件的一个命令。<br />
<br />
请参考 {{ic|info ls}} 或 [http://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html#ls-invocation 在线文档]。<br />
<br />
[https://the.exa.website exa] 相较于 {{ic|ls}} 和 {{ic|tree}} 是一个更加现代的、人性化的选择。它有更多的特性,例如将 [[Git]] 修改和文件名一同显示,在 {{ic|--long}} 模式中对每列进行不同的着色,或者在 {{ic|tree}} 视图中显示 {{ic|--long}} 模式元数据。 {{Pkg|exa}}<br />
<br />
=== “长格式”输出 ===<br />
<br />
{{ic|-l}} 选项显示一些元数据,例如:<br />
<br />
{{hc|$ ls -l ''/path/to/directory''|<br />
total 128<br />
drwxr-xr-x 2 archie users 4096 Jul 5 21:03 Desktop<br />
drwxr-xr-x 6 archie users 4096 Jul 5 17:37 Documents<br />
drwxr-xr-x 2 archie users 4096 Jul 5 13:45 Downloads<br />
-rw-rw-r-- 1 archie users 5120 Jun 27 08:28 customers.ods<br />
-rw-r--r-- 1 archie users 3339 Jun 27 08:28 todo<br />
-rwxr-xr-x 1 archie users 2048 Jul 6 12:56 myscript.sh<br />
}}<br />
<br />
{{ic|total}} 值表示目录中文件的总磁盘分配,默认情况下为块的数量。<br />
<br />
每个文件和子目录由一行表示,每行划分为 7 个字段,按以下顺序表示:<br />
<br />
* 类型与权限:<br />
** 首字母表示内部类型,参阅 {{ic|info ls -n "What information is listed"}} 来查看所有可能类型的介绍;例如:<br />
*** {{ic|-}} 表示一个普通文件;<br />
*** {{ic|d}} 表示一个目录,比如一个包括了其他文件和文件夹的文件夹;<br />
*** {{ic|p}} 表示一个命名的管道(又名 FIFO);<br />
*** {{ic|l}} 表示这是一个软链接;<br />
** 其他字母表示这个条目的 [[permissions|权限]];<br />
* 这个条目 [[Wikipedia:Hard link|硬链接]] 的数量;对文件而言这个数字至少是 1,即当前显示的文件引用本身;对文件夹而言这个数字至少是 2,当前显示的引用、对自己的引用({{ic|.}} 条目)以及这个文件夹中的子文件夹对父文件夹的引用({{ic|..}} 条目);<br />
* [[user|用户]] 名;<br />
* [[group|组]] 名;<br />
* 大小;<br />
* 修改时间;<br />
* 名称。<br />
<br />
=== 带空格的文件名被引号引起 ===<br />
<br />
默认情况下,包含空格的文件名和目录名会被单引号引起。要改变这一特性,请使用 {{ic|-N}} 或 {{ic|1=--quoting-style=literal}} 选项。另外,将 {{ic|QUOTING_STYLE}} [[environment variable|环境变量]] 设置为 {{ic|literal}} 也可以。[https://unix.stackexchange.com/questions/258679/why-is-ls-suddenly-surrounding-items-with-spaces-in-single-quotes]<br />
<br />
== lsblk ==<br />
<br />
{{man|8|lsblk}} 命令会显示所有连接到系统的 [[w:Device_file#Block_devices|块设备]] 和分区状况:<br />
<br />
{{hc|$ lsblk -f|<br />
NAME FSTYPE LABEL UUID MOUNTPOINT<br />
sda<br />
├─sda1 vfat C4DA-2C4D /boot<br />
├─sda2 swap 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 [SWAP]<br />
└─sda3 ext4 56adc99b-a61e-46af-aab7-a6d07e504652 /<br />
}}<br />
<br />
设备名开头定义块设备的类型,大部分现代的硬盘、[[SSD]] 和 USB 闪存设备都被识别为 SCSI disks ({{ic|sd}})。类型后面跟着给设备编号的小写字母,第一个设备从 {{ic|a}} 开始 ({{ic|sda}}),第二个设备就是 {{ic|b}} ({{ic|sdb}}),以此类推。每个设备上的 ''现有'' 分区将用数字编号,从 {{ic|1}} 开始 ({{ic|sda1}}),第二个分区就是 {{ic|2}} ({{ic|sda2}}),以此类推。在上面的示例中,只有一个设备可用 ({{ic|sda}}),该设备有三个分区 ({{ic|sda1}} 到 {{ic|sda3}}),每个分区具有不同的 [[file system|文件系统]]。<br />
<br />
其它块设备比如 {{ic|mmcblk}}(内存卡)或 {{ic|nvme}}([[NVMe]] 设备)。不清楚的设备类型可以在这里搜索到:[https://www.kernel.org/doc/Documentation/devices.txt kernel documentation]{{Dead link|2017|11|11}}。<br />
<br />
== mkdir ==<br />
<br />
[[Wikipedia:mkdir|mkdir]] (''make directory'') 可以创建目录。<br />
<br />
若需递归地创建一系列目录,就要用到 {{ic|-p}} 参数了,否则会出错。已经十分熟悉这原理的高级用户也可直接设为内置参数:<br />
<br />
alias mkdir='mkdir -p -v'<br />
<br />
{{ic|-v}} 参数可以使创建目录过程中的信息更为详细。<br />
<br />
不必使用 ''chmod'' 更改权限模式, 用 {{ic|-m}} 选项可直接定义新建目录的访问权限。<br />
<br />
{{提示|如果您仅仅只是想建个临时目录,也许用 [[Wikipedia:Temporary file|mktemp]]: {{ic|mktemp -d}} 更好。}}<br />
<br />
== mv ==<br />
<br />
[[Wikipedia:mv|mv]] (''move'') 可以移动或重命名文件和目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias mv='timeout 8 mv -iv'<br />
<br />
这个别名可以延迟 ''mv'' 到 8 秒后才生效,在覆盖已存在的文件时要求确认,列出正在进行的操作并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。<br />
<br />
== od ==<br />
<br />
[[Wikipedia:od (Unix)|od]] (''o''ctal ''d''ump) 命令在显示非人类可读格式时非常有用,比如程序的可执行文件,或者未格式化的设备的内容。参阅[https://www.gnu.org/software/coreutils/manual/html_node/od-invocation.html#od-invocation manual] 了解详情。<br />
<br />
== pv ==<br />
<br />
可以用 {{Pkg|pv}} (''pipe viewer'') 来监视管道中传递的数据,例如:<br />
<br />
# dd if=''/source/filestream'' | pv -''monitor_options'' -s ''size_of_file'' | dd of=''/destination/filestream''<br />
<br />
大多数情况下 {{ic|pv}} 可直接替代 {{ic|cat}}。<br />
<br />
== rm ==<br />
<br />
[[Wikipedia:rm_(Unix)|rm]] (''remove'') 用于删除文件或目录。<br />
<br />
为了降低使用这个命令带来的风险,请添加一个 alias:<br />
<br />
alias rm='timeout 3 rm -Iv --one-file-system'<br />
<br />
这个别名可延迟 ''rm'' 到 3 秒后才生效,在删除三个以上的文件时要求确认,列出正在进行的操作,限于只在同一个文件系统生效并且在 shell 被配置为忽略空格开头的命令的情况下,不将自身记入 shell 的命令历史记录。若你想在删除多文件时一一确认,用 {{ic|-I}} 代替 {{ic|-i}} 即可。<br />
<br />
Zsh 的使用者可在 {{ic|timeout}} 前加上 {{ic|noglob}},避免隐式扩展。<br />
<br />
若要移除空目录,使用 ''rmdir'',若内含文件则命令失败。<br />
<br />
== sed ==<br />
<br />
[[Wikipedia:sed|sed]] (''stream editor'') 是一条专门解析或替换文本的命令。<br />
<br />
这里有一系列现成的 ''sed'' [http://sed.sourceforge.net/sed1line.txt 示范]。<br />
<br />
{{提示|[[Wikipedia:AWK|AWK]] 和 [[Wikipedia:Perl|Perl]] 语言在这方面更为强大。}}<br />
<br />
== seq ==<br />
<br />
''seq'' (''sequence'') 是一条专门排列数字的命令。Shell 内置了该命令的其他替代方案,可以按照 [[Wikipedia:Seq (Unix)|Wikipedia]] 的说明进行练习。<br />
<br />
== ss ==<br />
<br />
''ss'' 是一个检查网络端口的实用程序,并且是 {{Grp|base}} 组中的 {{Pkg|iproute2}} 包的一部分。它具有与 [https://www.archlinux.org/news/deprecation-of-net-tools/ 弃用的] netstat 实用程序类似的功能。<br />
<br />
常用用法包括:<br />
<br />
显示所有 TCP Sockets,连同 service 名称:<br />
$ ss -at<br />
<br />
显示所有 TCP Sockets,连同端口号:<br />
$ ss -atn<br />
<br />
显示所有 UDP Sockets:<br />
$ ss -au<br />
<br />
更多信息请参考 {{Pkg|iproute2}} 包里的 {{man|8|ss}} 或 {{ic|ss.html}}。<br />
<br />
== tar ==<br />
<br />
作为早期的 Unix 存档格式,.tar 文件(称为“tarballs”)广泛用于类 Unix 操作系统中的打包操作。[[pacman]] 和 [[AUR]] 软件包都是压缩的 tarball,Arch 默认使用 [[GNU Project|GNU 的]] ''tar'' 程序。<br />
<br />
对于 ''.tar'' 文件,''tar'' 默认根据扩展名来解压文件:<br />
<br />
$ tar xvf ''file.EXTENSION''<br />
<br />
强制给定格式:<br />
<br />
{| class="wikitable"<br />
!文件类型 !! 解压命令<br />
|-<br />
|{{ic|''file''.tar}} || {{Ic|tar xvf ''file''.tar}}<br />
|-<br />
|{{ic|''file''.tgz}} || {{Ic|tar xvzf ''file''.tgz}}<br />
|-<br />
|{{ic|''file''.tar.gz}} || {{Ic|tar xvzf ''file''.tar.gz}}<br />
|-<br />
|{{ic|''file''.tar.bz}} || {{Ic|bzip -cd ''file''.bz <nowiki>|</nowiki> tar xvf -}}<br />
|-<br />
|{{ic|''file''.tar.bz2}} || {{Ic|tar xvjf ''file''.tar.bz2}}<br> {{Ic|bzip2 -cd ''file''.bz2 <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.xz}} || {{Ic|tar xvJf ''file''.tar.xz}}<br> {{Ic|xz -cd ''file''.xz <nowiki>| tar xvf -</nowiki>}}<br />
|-<br />
|{{ic|''file''.tar.zst}} || {{Ic|tar -I zstd xvf ''file''.tar.zst}}<br />
|}<br />
<br />
这其中有部分 ''tar'' 的参数可以认为是历史遗留问题,但在执行某些特定的操作时仍然有用。更多细节请参阅 {{man|1|tar}}。<br />
<br />
== which ==<br />
<br />
[[wikipedia:Which_(Unix)|which]] 显示 shell 命令的完整路径。在下面的例子中 {{ic|ssh}} 的完整路径作为一个参数传递给了 {{ic|journalctl}}:<br />
<br />
# journalctl $(which sshd)<br />
<br />
== wipefs ==<br />
<br />
''wipefs'' 可以列出或擦除指定设备的 [[file system|文件系统]]、[[RAID]] 或 [[partition|分区表]] 标志 (magic strings)。它不会擦除文件系统本身,也不会擦除设备中的任何其他数据。<br />
<br />
更多信息请参阅 {{man|8|wipefs}}。<br />
<br />
例如,擦除 {{ic|/dev/sdb}} 设备中的所有标志并为每个标志在 {{ic|~/wipefs-sdb-''offset''.bak}} 创建一个备份文件:<br />
<br />
# wipefs --all --backup /dev/sdb<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.reddit.com/r/commandline/comments/19garq/a_sampling_of_coreutils_120/ A sampling of coreutils] [http://www.reddit.com/r/commandline/comments/19ge6v/a_sampling_of_coreutils_2040/ , part 2] [http://www.reddit.com/r/commandline/comments/19j1w3/a_sampling_of_coreutils_4060/ , part 3] - Overview of commands in coreutils<br />
* [https://www.gnu.org/software/coreutils/manual/coreutils.html GNU Coreutils online documentation]<br />
* [https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/ Learn the DD command]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515183
OpenSSH (简体中文)
2018-03-28T17:19:38Z
<p>Arisaka: Sync</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:Secure Shell (简体中文)]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fa:SSH]]<br />
[[fr:ssh]]<br />
[[ja:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys (简体中文)}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|SSHFS (简体中文)}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related|SCP and SFTP}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Secure Shell|2018-03-29|515156}}<br />
<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器默认情况下,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专有软件、自由软件以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(来源:[[Wikipedia:Secure Shell|维基百科 Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH 是由 Theo de Raadt 领导的 OpenBSD 项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{pkg|openssh}}.<br />
<br />
<br />
===SSH 客户端===<br />
<br />
连接SSH服务器,运行命令<br />
<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
<br />
如果服务器仅允许使用密钥登录,请参考 [[SSH keys (简体中文)|SSH Keys]] 。<br />
<br />
====配置====<br />
<br />
客户端可以在配置文件中存储常用选项和常用主机,下列选项都可以应用至全局或应用至特定主机。 例如:<br />
<br />
{{hc|~/.ssh/config|# global options<br />
User ''user''<br />
<br />
# host-specific options<br />
Host myserver<br />
HostName ''server-address''<br />
Port ''port''}}<br />
<br />
进行了如上的配置后,以下命令是等效的<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
$ ssh myserver<br />
<br />
查看 {{man|5|ssh_config}} 获取更多信息。<br />
<br />
某些选项没有命令行参数,但是可以使用 {{ic|-o}} 在命令行中配置指定选项的参数。<br />
例如 {{ic|1=-oKexAlgorithms=+diffie-hellman-group1-sha1}}.<br />
<br />
===SSH 服务端===<br />
<br />
====配置====<br />
<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers ''user1 user2''<br />
<br />
只允许一些组访问:<br />
AllowGroups ''group1 group2''<br />
<br />
你也可以运行以下命令关联文件(如{{ic|/etc/issue}}文件)到登录欢迎信息:<br />
Banner /etc/issue<br />
<br />
公钥和私钥在 ''sshd'' [[#管理 sshd 守护进程|service 文件]] 安装的时候就自动生成在 {{ic|/etc/ssh}} 里面了,四个秘钥对分别由四种算法生成: [[SSH_keys#Choosing_the_authentication_key_type|dsa、rsa、ecdsa 和 ed25519]]。要让 sshd 使用一组特定的密钥,请指定以下选项:<br />
<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
如果此服务器在公网中,建议运行以下命令以更改sshd服务监听端口:<br />
Port 39901<br />
<br />
{{Tip|<br />
* 参考 [[Wikipedia:List of TCP and UDP port numbers|TCP 和 UDP 端口号列表]] 和本地的 {{ic|/etc/services}} 文件来选择一个未被常用服务占用的端口。把端口从默认的 22 改成别的可以减少由于端口扫描器尝试自动登录造成的登录日志条目,更多信息请参考 [[Port knocking]]。<br />
* 完全取消密码登录方式可以极大的增强安全性,请查看[[#强制公钥验证]]。查看[[#安全防护]]了解更多增强安全性的手段。<br />
* OpenSSH 可以监听多个端口,只需在配置文件中加入多行{{ic|Port ''port_number''}}即可。}}<br />
<br />
==== 管理 sshd 守护进程 ====<br />
<br />
{{Pkg|openssh}} 包括了两种 [[systemd]] 服务:<br />
#{{ic|sshd.service}},使 SSH 守护进程始终运行,并为每个入站连接创建子进程。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh#n16] 适用于有大量 SSH 流量的系统。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n15] <br />
#{{ic|sshd.socket}} + {{ic|sshd@.service}}, 为每个连接生成 SSH 守护进程的实例。它意味着让 ''systemd'' 监听 SSH socket,并且只有在有连接传入时启动守护进程。几乎所有情况下都推荐使用{{ic|sshd}}。 [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n18][http://lists.freedesktop.org/archives/systemd-devel/2011-January/001107.html][http://0pointer.de/blog/projects/inetd.html]<br />
<br />
[[start]] 并 [[enable]] {{ic|sshd.service}} '''或''' {{ic|sshd.socket}} 中的任何一个都可以启动守护进程。<br />
<br />
如果选择了 sshd.socket,并且不在默认的 22 端口监听,你需要[[edit|编辑]] ststemd 单元文件:<br />
<br />
{{hc|# systemctl edit sshd.socket|<nowiki><br />
[Socket]<br />
ListenStream=<br />
ListenStream=12345<br />
</nowiki>}}<br />
<br />
{{警告|使用 {{ic|sshd.socket}} 会使 {{ic|ListenAddress}} 设置无效,这将允许来自任何地址的连接。为了达到与 {{ic|ListenAddress}} 一样设置 IP 的效果, 你必须在 {{ic|ListenStream}} 中指定端口''和'' IP (例如:{{ic|1=ListenStream=192.168.1.100:22}})。你还需要在 {{ic|[Socket]}} 下面增加 {{ic|1=FreeBind=true}},否则设置 IP 与设置 {{ic|ListenAddress}} 有着相同的缺陷:如果网络未及时启动,socket 将无法启动。}}<br />
<br />
{{提示|打开 {{ic|sshd.service}} 时将为每个连接启动一个 {{ic|sshd@.service}} 的临时实例(实例名称不同)。因此,{{ic|sshd.socket}} 和常规 {{ic|sshd.service}} 都不允许监视日志中的连接尝试。使用 {{ic|journalctl -u "sshd@*"}} 或 {{ic|journalctl /usr/bin/sshd}} 可以看到 socket 激活的 SSH 实例的日志。}}<br />
<br />
==== 安全防护 ====<br />
<br />
允许通过SSH进行远程登录对管理服务器很有用,但也会对服务器构成安全威胁。SSH 通常是暴力攻击的目标,因此 SSH 访问需要适当限制,以防止第三方访问您的服务器。<br />
<br />
下列是有关该主题的优秀指南:<br />
<br />
*[https://wiki.mozilla.org/Security/Guidelines/OpenSSH Article by Mozilla Infosec Team]<br />
*[https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure sshd]<br />
<br />
===== 强制公钥验证 =====<br />
<br />
如果客户端无法通过公钥进行身份验证,则默认情况下,SSH服务器将使用密码来验证,从而允许恶意用户通过[[#防止暴力破解|暴力破解]]密码获取访问权限。一种防止此类攻击的有效方法是完全禁用密码登录,并强制使用[[SSH keys]]。可以在 {{ic|sshd_config}} 中禁用以下选项:<br />
<br />
PasswordAuthentication no<br />
<br />
{{警告|在将上述选项添加到你的配置之前,请确保所有需要 SSH 访问的帐户都在相应的 {{ic|authorized_keys}} 文件中设置了公钥验证。请参阅 [[SSH keys#Copying the public key to the remote server]] 以获取更多信息。}}<br />
<br />
===== 双因素验证与公钥 =====<br />
<br />
自 OpenSSH 6.2 起,你可以使用 {{ic|AuthenticationMethods}} 选项添加自己的钥匙串进行身份验证。这使你可以用公钥与双因素验证结合来登录。<br />
<br />
参阅 [[Google Authenticator (简体中文)]] 来设置 Google Authenticator。<br />
<br />
为了使 [[PAM (简体中文)]] 与 OpenSSH 协同工作, 编辑下列文件:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey keyboard-interactive:pam<br />
}}<br />
<br />
然后,你可以使用公钥'''或''' PAM 中设置的用户验证信息两者之一登录。<br />
<br />
另外,如果你想登录时同时验证公钥'''和''' PAM,请使用逗号而不是空格来分隔 AuthenticationMethods:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey,keyboard-interactive:pam<br />
}}<br />
<br />
通过要求提供公钥'''和''' PAM 认证,你可能希望禁用密码登录:<br />
{{hc|/etc/pam.d/sshd|<br />
auth required pam_securetty.so #disable remote root<br />
#Require google authenticator<br />
auth required pam_google_authenticator.so<br />
#But not password<br />
#auth include system-remote-login<br />
account include system-remote-login<br />
password include system-remote-login<br />
session include system-remote-login<br />
}}<br />
<br />
===== 防止暴力破解 =====<br />
暴力破解的概念很简单,即某人不断尝试用大量随机产生的用户名和密码对来登录网页或服务器的某个服务(比如 SSH)。<br />
<br />
====== 使用 ufw ======<br />
<br />
请参阅 [[ufw#Rate limiting with ufw]].<br />
<br />
====== 使用 iptables ======<br />
<br />
{{Merge|Simple_stateful_firewall#Bruteforce_attacks|Out of scope, same technique as already described in the SSF.}}<br />
<br />
如果你已经在用 iptables,可以配置以下规则来保护 SSH 免受暴破。<br />
<br />
{{注意|此示例中 SSH 所用的 TCP 端口已经改为了 42660。}}<br />
<br />
在应用后面的规则之前,我们先新建一条规则链来记录并拒绝过多的连接请求:<br />
<br />
# iptables -N LOG_AND_DROP<br />
<br />
第一条规则将应用于预示 TCP 42660 端口有新连接的数据包:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --set --name DEFAULT --rsource<br />
<br />
下一条规则告诉 iptables 查找匹配前一条规则的数据包,这些数据包也来自已添加到监视列表中的主机。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --update --seconds 90 --hitcount 4 --name DEFAULT --rsource -j LOG_AND_DROP<br />
<br />
现在,让 iptables 决定如何处理 TCP 42660 端口的通信中不符合上述规则的数据包。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -j ACCEPT<br />
<br />
我们向 LOG_AND_DROP 表增加如下规则,并使用 -j (jump) 参数将数据包的信息传递给日志记录工具。<br />
<br />
# iptables -A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7<br />
<br />
在按照第一条规则进行记录后,所有数据包将被丢弃。<br />
<br />
# iptables -A LOG_AND_DROP -j DROP<br />
<br />
====== 防止暴力破解的工具 ======<br />
<br />
你可以用类似 [[fail2ban]] 或 [[sshguard]] 的自动防暴破的脚本来阻挡攻击者。<br />
<br />
* 仅允许来自受信任位置的 SSH 入站连接。<br />
* 使用 [[fail2ban]] 或 [[sshguard]] 自动阻止多次密码验证失败的 IP 地址。<br />
* 使用 [https://github.com/jtniehof/pam_shield pam_shield] 来阻止在一定时间内执行过多登录尝试的 IP 地址。与 [[fail2ban]] 或 [[sshguard]]不同,该程序不考虑登录成功或失败。<br />
<br />
===== 禁用或限制 root 账户登录 =====<br />
{{Out of date|最新版本默认已禁用 root 账户登录。暂不清楚本节的哪些部分是多余的。}}<br />
<br />
允许 root 账户随意通过 SSH 登录通常是不安全的,有两种方法可以限制 root 账户通过 SSH 登录,从而提高安全性。<br />
<br />
====== 禁用 root 登录 ======<br />
<br />
Sudo 可以有选择地为需要 root 权限的操作提供相应的权限,且不需要登录 root 账户。这样即可关闭 root 登录,并且可以看做一种防范暴力攻击的安全措施,因为现在攻击者除了要猜测密码外还要猜测帐户名称。<br />
<br />
通过编辑 {{ic|/etc/ssh/sshd_config}} 中的 "Authentication" 一节可以使 SSH 屏蔽 root 用户登录,只要将 {{ic|#PermitRootLogin prohibit-password}} 改成 {{ic|no}} 并取消该行注释即可:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
PermitRootLogin no<br />
...<br />
}}<br />
<br />
然后 [[restart|重启]] SSH 守护进程。<br />
<br />
现在你将无法通过 root 账户登录,但仍可以用普通账户登录并使用 [[su]] 或者 [[sudo]] 来完成系统维护工作。<br />
<br />
====== 限制 root 登录 ======<br />
<br />
一些自动化的维护任务(比如远程备份整个系统)需要完整的 root 权限。要以安全的方式允许 root 登录而不是禁用它,可以只允许远程登录的 root 用户执行指定的命令,在 {{ic|~root/.ssh/authorized_keys}} 头部加上指定的密钥即可,例如:<br />
<br />
command="/usr/lib/rsync/rrsync -ro /" ssh-rsa …<br />
<br />
这样,任何用户持有该秘钥即可执行引号之间的命令。<br />
<br />
为了弥补因 root 用户名称暴露而导致受攻击的可能性增加,可以将以下命令加入 {{ic|sshd_config}}:<br />
<br />
PermitRootLogin forced-commands-only<br />
<br />
该设置不仅会限制 root 用户通过 SSH 执行的命令,还会禁用密码登录方式,强制 root 帐户使用公钥登录。<br />
<br />
如果不想限制 root 用户可执行的命令,可以仅关闭密码验证来强制使用公钥验证:<br />
<br />
PermitRootLogin without-password<br />
<br />
===== 保护 authorized_keys 文件 =====<br />
<br />
你可以阻止其他用户向该文件加入新公钥且通过新的公钥连接。<br />
<br />
把 {{ic|authorized_keys}} 文件的权限全部去掉,只保留读权限:<br />
<br />
$ chmod 400 ~/.ssh/authorized_keys<br />
<br />
为防止用户把权限改回来,可以对 {{ic|authorized_keys}} 文件采取 [[File permissions and attributes#chattr and lsattr|set the immutable bit(设为不可变)]] 操作。尽管如此,用户仍然可以重命名 {{ic|~/.ssh}} 并新建一个 {{ic|~/.ssh}} 目录和 {{ic|authorized_keys}} 文件。所以 {{ic|~/.ssh}} 目录也要设置 immutable bit。<br />
<br />
{{注意|如果你自己需要新增一个公钥,你需要先移除 {{ic|authorized_keys}} 文件的 immutable bit,并增加写权限,最后按上述步骤重新加密。}}<br />
<br />
== 其他 SSH 客户端与服务端 ==<br />
除了 OpenSSH,还有很多可用的 SSH [[Wikipedia:Comparison of SSH clients|客户端]] 和 [[Wikipedia:Comparison of SSH servers|服务端]]。<br />
<br />
=== Dropbear ===<br />
[[Wikipedia:Dropbear (software)|Dropbear]] 是一个 SSH-2 客户端与服务端。 {{Pkg|dropbear}} 可以从 [[official repositories|官方仓库]] 下载。<br />
<br />
它的命令行版客户端叫 dbclient。<br />
<br />
=== Mosh ===<br />
来自 Mosh [http://mosh.mit.edu/ 网站]:<br />
<br />
:Remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. Mosh is a replacement for SSH. It is more robust and responsive, especially over slow connections such as Wi-Fi, cellular, and long-distance.<br />
:翻译:允许“漫游”的远程终端,支持间歇性的连接,并提供对于用户按键的智能本地回馈和行编辑回馈。Mosh 是 SSH 的替代品。它更加强大而快速,特别针对诸如 Wi-Fi,移动网络和超远距离等慢速连接环境。<br />
<br />
[[Install|安装]] {{Pkg|mosh}} 这个包, 或安装最新版:{{AUR|mosh-git}}。<br />
<br />
Mosh 有一个未写入文档的命令行选项:{{ic|1=--predict=experimental}},它可以产生更有力的本地按键响应。对降低键盘输入视觉上的延迟确认感兴趣的用户可能更喜欢这个预测模式。<br />
<br />
{{提示|Mosh 从设计上就不允许你访问会话的历史记录,请考虑安装终端复用工具,如 [[tmux]] 或 [[screen]] 。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
{{Accuracy|根据目前本文的布局,这部分看起来应该是通用的,但实际上大部分提供的技巧只能在 ''openssh'' 中使用。比如 ''dropbear'' (在 [[#Other SSH clients and servers]] 列表中) 不支持 SOCKS 协议。[https://en.wikipedia.org/wiki/Comparison_of_SSH_clients#Technical]}}<br />
<br />
=== 加密 Socks 通道 ===<br />
<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的 SSH 服务器,比如在家里或办公室。用动态的 DNS 服务 [http://www.dyndns.org/ DynDNS] 也可能是很有用的,这样你就不必记住你的 IP 了。<br />
<br />
==== 第一步:开始连接 ====<br />
<br />
你只要执行这一个命令就能开始你的连接:<br />
<br />
$ ssh -TND 4711 ''user''@''host''<br />
<br />
这里的 {{Ic|''user''}} 是你在 {{Ic|''host''}} 这台 SSH 服务器上的用户名。它会让你输入密码,然后你就能连上了。 {{Ic|N}} 表示不采用交互提示,而 {{Ic|D}} 表示指定监听的本地端口(你可以使用任何你喜欢的数字),{{Ic|T}} 表示禁用伪 tty 分配。<br />
<br />
加了 {{Ic|-v}} (verbose) 标志以后的输出可以让你能够验证到底连了哪个端口。<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你没有配置你的浏览器(或其他程序)使用这个新创建的 socks 隧道,上述步骤是无效的。由于当前版本的 SSH 支持 SOCKS4 和 SOCKS5,因此您可以使用其中任何一种。<br />
<br />
* 对于 Firefox: ''Edit > Preferences > Advanced > Network > Connection > Setting'': <br> 选中 ''Manual proxy configuration'' 单选框, 然后在 ''SOCKS host'' 里输入 {{ic|localhost}}, 然后在后面那个框中输入你的端口号(本例中为 {{ic|4711}})。<br />
<br />
Firefox 不会自动通过 socks 隧道发送 DNS 请求,这一潜在的隐私问题可以通过以下步骤来解决:<br />
<br />
# 在 Firefox 地址栏中输入:about:config 。<br />
# 搜索:network.proxy.socks_remote_dns<br />
# 将该值设为 true。<br />
# 重启浏览器。<br />
<br />
* 对于 Chromium: 你可以将 SOCKS 设置设置为环境变量或命令行选项。我建议将下列函数之一加入到你的 {{ic|.bashrc}}:<br />
function secure_chromium {<br />
port=4711<br />
export SOCKS_SERVER=localhost:$port<br />
export SOCKS_VERSION=5<br />
chromium &<br />
exit<br />
}<br />
或者<br />
function secure_chromium {<br />
port=4711<br />
chromium --proxy-server="socks://localhost:$port" &<br />
exit<br />
}<br />
<br />
现在打开终端然后输入:<br />
<br />
$ secure_chromium<br />
<br />
享受你的安全隧道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过 SSH 运行图形程序你必须使用 X11 转发 (forwarding)。这不要求对端安装了完整的 X11,但是至少要装好 ''xauth''。''xauth'' 是一个用来管理 {{ic|Xauthority}} 配置的工具,该配置用于服务器与客户端之间的 X11 会话认证([http://xmodulo.com/2012/11/how-to-enable-x11-forwarding-using-ssh.html source])。<br />
<br />
{{警告|X11 转发有着重要的安全问题需要考虑,至少应先阅读 {{man|1|ssh}}、{{man|5|sshd_config}} 和 {{man|5|ssh_config}} 手册页。也可以参考 [https://security.stackexchange.com/questions/14815/security-concerns-with-x11-forwarding 这个 StackExchange 帖]。}}<br />
<br />
==== 配置 ====<br />
<br />
在远程主机上:<br />
<br />
*[[install|安装]] {{Pkg|xorg-xauth}} 和 {{Pkg|xorg-xhost}} 这两个包<br />
*在 {{ic|/etc/ssh/ssh'''d'''_config}} 上:<br />
**确保 {{ic|AllowTcpForwarding}} 和 {{ic|X11UseLocalhost}} 已经设置为 ''yes'',并且 {{ic|X11DisplayOffset}} 设置为 ''10'' (这些是默认设置,参考 {{man|5|sshd_config}})<br />
**将 {{ic|X11Forwarding}} 设置为 ''yes''<br />
* 最后 [[restart|重启]] [[#Daemon management|''sshd'' 守护进程]].<br />
<br />
在客户端上,通过在命令行设置 {{ic|-X}} 参数启用 {{ic|ForwardX11}},或者在[[#配置|客户端配置文件]]中将 {{ic|ForwardX11}} 设置为 ''yes''。<br />
<br />
{{提示|如果 GUI 绘制不正常或者有错误提示,你可以启用 {{ic|ForwardX11Trusted}} 选项(或在命令行中加上 {{ic|-Y}} 参数),这将使 X11 转发脱离 [http://www.x.org/wiki/Development/Documentation/Security/ X11 SECURITY extension] 的控制,如果你这样做,请确保已经读过本节开头的[[#X11 转发|警告]]。}}<br />
<br />
==== 使用方法 ====<br />
<br />
{{Accuracy|{{ic|xhost}} [http://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-from-ubuntu-machine#comment-17148 通常不是必须的]}}<br />
<br />
正常登录远程主机,如果客户端的配置文件中没有启用 ''ForwardX11'' 那就加上 {{ic|-X}} 参数:<br />
$ ssh -X ''user@host''<br />
<br />
如果在运行图形程序的时候碰到错误,尝试用 ''ForwardX11Trusted'' 代替 ''ForwardX11'' :<br />
$ ssh -Y ''user@host''<br />
<br />
现在你应该可以运行服务器上的任何 X 图形程序,任何输出都会重定向至你当前的会话:<br />
$ xclock<br />
<br />
如果碰到 "Cannot open display" 的错误,请尝试用非管理员账户运行下列命令:<br />
$ xhost +<br />
<br />
上述命令将允许任何人转发 X11 应用程序,这个命令可以限制特定的主机类型:<br />
$ xhost +hostname<br />
<br />
其中 hostname 是要转发到的特定主机的名称。更多信息可以查看 {{man|1|xhost}}。<br />
<br />
请注意某些应用程序,它们会检查本地计算机上正在运行的实例。[[Firefox]] 就是其中之一:你可以关掉本机上的 Firefox 或者使用以下启动参数来启动远程实例:<br />
$ firefox --no-remote<br />
<br />
当你连接时收到 "X11 forwarding request failed on channel 0" 错误(或者服务器上的 {{ic|/var/log/errors.log}} 文件显示 "Failed to allocate internet-domain X11 display socket" 错误),请确保已经安装 {{Pkg|xorg-xauth}},如果装完了仍然不起作用,尝试以下方法之一:<br />
<br />
* 在''服务器''的 {{ic|ssh'''d'''_config}} 中启用 {{ic|AddressFamily any}} 选项,或者<br />
* 将''服务器''的 {{ic|ssh'''d'''_config}} 中的 {{ic|AddressFamily}} 选项设为 inet。<br />
将其设置为 inet 可能会修复 IPv4 上的 Ubuntu 客户端的问题。<br />
<br />
要以其他用户身份运行 SSH 服务器上的 X 应用程序,你需要先用已知用户登录,取出 {{Ic|xauth list}} 中的身份认证行,然后 {{Ic|xauth add}} 它。<br />
<br />
{{提示|[http://unix.stackexchange.com/a/12772/29867 这里] 是 [http://unix.stackexchange.com/a/46748/29867 一些] 用来诊断 {{ic|X11 Forwarding}} 问题有用的 [http://superuser.com/a/805060/185665 链接]。}}<br />
<br />
=== 转发其他端口 ===<br />
<br />
除了 SSH 内建的对 X11 的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一条SSH命令来建立一个安全的VNC连接。本地转发可以通过 {{Ic|-L}} 来设置,后面可以指定一个地址及端口 {{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在 192.168.0.100 的 shell,同时也会创建一个从本机 1000 端口到 mai.google.com 上的 25 端口的隧道。建立之后,localhost:1000 会通过 192.168.0.100 连接到 Gmail 的 SMTP 端口。任何从 192.168.0.100 到 mail.google.com:25 的连接(即使不必要)都会以这样的方式建立,并且,在本机和 192.168.0.100 之间的数据传递都是安全的,除非你采取了别的手段。<br />
<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到 localhost:2000 的连接直接转发到远程主机 192.168.0.100 的 6001 端口。对于使用 VNC 服务器(tightvns包的一部分)建立的 VNC 连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过 SSH 隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过 {{Ic|-R}} 参数,以及 {{Ic|<tunnel port>:<destination address>:<destination port>}} 能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在 192.168.0.200 上得到一个 shell,同时也会创建一个从 192.168.0.200 上的 3000 端口到 irc.freenode.net 上的 6667 端口的隧道。建立之后,192.168.0.200:3000 会通过本机连接到 freenode 的 IRC 端口。到 192.168.0.200 的 3000 端口的连接将会通过隧道发送到本机然后转发到 irc.freenode.net 的 6667 端口。因此,在这个例子中,在远程主机上 IRC 程序能够被使用,即使端口 6667 被阻止。<br />
<br />
本地转发和远程转发都可以提供一个安全的"网关",允许其他计算机无需使用 SSH 或者 SSH daemon 来使用 ssh 隧道,即在隧道起点提供绑定的地址,作为转发规则。例如 {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}。{{Ic|<tunnel address>}} 可以是作为网关的机器上的任何地址,例如 {{Ic|localhost}}(仅允许本地访问),{{Ic|192.168.0.100}}(仅允许通过192.168.0.100访问), {{Ic|*}}(允许所有地址访问)。它们可以是通过本地环回端口,或是通过其他任何端口的连接。默认情况下,转发受到隧道“起点”的主机限制,即 {{Ic|<tunnel address>}} 被设置为 {{Ic|localhost}}。本地转发不需要额外的设置,而远程转发受限于对端的 SSH daemon 设置。请参阅 {{Ic|sshd_config(5)}} 中的 {{Ic|GatewayPorts}} 选项。<br />
<br />
=== 跳板机 ===<br />
<br />
在某些情况下,你与目标主机之间可能无法直接连接,此时就要用到跳板机。因此,我们尝试将两个或更多 SSH 隧道连接在一起,并假设您的本地密钥已针对链中的每个服务器授权。这可以通过使用SSH代理转发 ({{ic|-A}}) 和伪终端分配 ({{ic|-t}}) 来实现,它使用以下语法转发本地密钥:<br />
<br />
$ ssh -A -t -l user1 bastion1 \<br />
ssh -A -t -l user2 intermediate2 \<br />
ssh -A -t -l user3 target<br />
<br />
一个更简单的方法是使用 {{ic|-J}} 选项:<br />
<br />
$ ssh -J user1@bastion1,user2@intermediate2 user3@target<br />
<br />
<br />
{{ic|-J}} 指令中的多个主机可以用逗号隔开,它们将按照列出的顺序连接。{{ic|user...@}} 部分不是必需的,但可以使用。定义 {{ic|-J}} 选项里的不同的主机规格可以使用 ssh 配置文件,因此如果需要,可以在那里设置特定的每个主机选项。<br />
<br />
=== 通过中继反向 SSH 连接 ===<br />
<br />
{{Style|SSH 隧道的设想是很经典的,所以添加一些参考资料的详细解释会更好。比如 [https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work/118650#118650] 涵盖了一些其他情况。}}<br />
<br />
这个想法是客户端通过一个中继连接到服务器,而服务器使用反向 SSH 隧道连接到同一个中继。例如,当服务器位于 NAT 后面时,这是很有用的,而此处的中继是一个可公开访问的 SSH 服务器,用作用户有权访问的代理服务器。前提是客户端的密钥同时对中继和服务器都已经授权,服务器需要授权中继用于反向 SSH 连接。<br />
<br />
以下配置假设 user1 是客户端使用的账户,user2 是中继的,user3 是服务器的。首先服务器要先建立反向隧道:<br />
<br />
ssh -R 2222:localhost:22 -N user2@relay<br />
<br />
这可以利用启动脚本、systemd service 或者 {{Pkg|autossh}} 来自动完成。<br />
<br />
{{Expansion|需要解释为何光有 {{ic|ssh user3@relay -p 2222}} 是不够的。}}<br />
<br />
在客户端使用以下命令建立连接:<br />
<br />
ssh user2@relay ssh user3@localhost -p 2222<br />
<br />
可以在中继的 {{ic|~/.ssh/authorized_keys}} 中定义 {{ic|command}} 字段来建立反向隧道:<br />
<br />
command="ssh user3@localhost -p 2222" ssh-rsa KEY2 user1@client<br />
<br />
在这种情况下用下列命令建立连接:<br />
<br />
ssh user2@relay<br />
<br />
注意,客户端内 scp 的自动完成功能失效,甚至在某些配置下 scp 本身也无法工作。<br />
<br />
=== 端口复用 ===<br />
<br />
SSH 守护进程通常监听 22 端口,但是许多公共热点会屏蔽非常规 HTTP/S 端口(分别是 80 和 443 端口)的流量,这样就屏蔽了 SSH 连接。最快的解决方法是让 {{ic|sshd}} 额外监听白名单上的端口:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
Port 22<br />
Port 443<br />
}}<br />
<br />
但是443端口很有可能已经被 HTTPS 服务占用,在这种情况下可以使用端口复用工具,比如 {{Pkg|sslh}},它可以监听在一个被复用的端口上并转发相应的数据包给对应的服务。<br />
<br />
=== 加速 SSH ===<br />
<br />
此处列出一些可以加速全部连接或针对某台主机加速的 [[#配置|客户端配置]] 选项。要了解这些选项的完整概述,请参阅 {{man|5|ssh_config}}。<br />
<br />
* 使用以下参数来使到某一台主机的所有回话 (sessions) 共享同一个连接: {{bc|<nowiki><br />
ControlMaster auto<br />
ControlPersist yes<br />
ControlPath ~/.ssh/sockets/socket-%r@%h:%p<br />
</nowiki>}}<br />
: 其中 {{ic|~/.ssh/sockets}} 可以是一个其他用户不可写入的任意目录。<br />
<br />
* {{ic|ControlPersist}} 指定在初始客户端连接关闭后,主服务器在后台等待新客户端的时间。可能的值是: <br />
** {{ic|no}} 指定在最后一个客户端断开后立即关闭连接,<br />
** 一个用秒数表示的时间,<br />
** {{ic|yes}} 连接不会自动关闭,而是始终处于等待。<br />
<br />
* 另一种加速的方法是通过 {{ic|Compression yes}} 选项或者 {{ic|-C}} 参数来启用压缩。<br />
: {{注意|{{man|1|ssh}} 指出:“在调制解调器线路或其他慢速线路上启用压缩是可取的,但在网速快的情况下只会降低速度。”这条提示可能会适得其反,具体取决于你的网络配置。}}<br />
<br />
* 通过使用 {{ic|AddressFamily inet}} 选项或者 {{ic|-4}} 参数来跳过 IPv6 查找,可以缩短登录时间。<br />
<br />
* 最后,如果你想用 SFTP 或 SCP,[https://www.psc.edu/index.php/hpn-ssh High Performance SSH/SCP] 可以通过动态提高 SSH 缓冲区大小来显著提高吞吐量。安装 {{AUR|openssh-hpn-git}} 这个包来使用打过这一增强补丁的 OpenSSH 版本。<br />
<br />
=== 用 SSHFS 挂载远程文件系统 ===<br />
<br />
请参阅 [[SSHFS]] 来将一个 SSH 可访问的远程文件系统挂载至一个本地目录,然后你就能在挂载好的文件上执行常规操作(复制,重命名,用 vim 编辑等等)。''sshfs'' 比 ''shfs'' 更好,因为后者自 2004 年起就没再更新。<br />
{{提示|软件包 {{AUR|autosshfs-git}} 可以用于在登录时自动运行 autosshfs。}}<br />
<br />
=== 保持在线 ===<br />
<br />
默认情况下,如果你的会话空闲了某个时间之后,它会自动登出。为了保持会话,在长时间没有数据传输时客户端可以向服务器发送一个激活信号。与之对应,服务器也可以在一段时间没有收到消息时定期发送一个信号。<br />
<br />
* 在 '''服务器''',{{ic|ClientAliveInterval}} 是没有从客户端收到消息后的超时时间,超时后 ''sshd'' 将会发送一个请求来等待回应。默认是 0,指不会发出请求。比如要求每隔 60 秒向客户端发送响应请求,在你的 [[#配置_2|服务器配置]] 里设置 {{ic|ClientAliveInterval 60}} 即可。{{ic|ClientAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
* 在 '''客户端''',{{ic|ServerAliveInterval}} 控制着从客户端发往服务器的响应请求的时间间隔。比如要求服务器每隔 120 秒响应一次,在你的 [[#配置|客户端配置]] 里加入 {{ic|ServerAliveInterval 120}} 即可。{{ic|ServerAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
<br />
{{注意| 为确保会话保持活动状态,客户端或服务器中只有一个需要发送保持活动请求。如果用户同时控制服务器和客户端,那么合理的选择是使用 {{ic|ServerAliveInterval}} 选项配置需要保持会话的客户端,并保留其他客户端和服务器的默认配置。}}<br />
<br />
=== 利用 systemd 自动重启 SSH 隧道 ===<br />
<br />
[[systemd]] 可以在开机/登录时自动启动 SSH,''还可以'' 在 SSH 连接断开时自动重连。这使它成为管理 SSH 隧道的有力工具。<br />
<br />
下面的 service 可以使用 [[#配置|ssh 配置]] 里面的配置在你登录系统的时候自动开启一个 SSH 隧道。如果连接因为某种原因断开,它将会每隔10秒重启一下:<br />
<br />
{{hc|~/.config/systemd/user/tunnel.service|<nowiki><br />
[Unit]<br />
Description=SSH tunnel to myserver<br />
<br />
[Service]<br />
Type=simple<br />
Restart=always<br />
RestartSec=10<br />
ExecStart=/usr/bin/ssh -F %h/.ssh/config -N myserver<br />
</nowiki>}}<br />
<br />
然后 [[enable]] 并且 [[start]] 这个 user service。欲知如何防止连接超时,请参阅 [[#Keep alive]]。如果你想在系统引导后就打开这个连接,你需要将这个 unit 重写为 system service。<br />
<br />
=== Autossh - 自动重启 SSH 会话和隧道连接 ===<br />
<br />
当一个 SSH 会话或隧道无法保持连接(比如网络环境差导致客户端断线),可以使用 {{Pkg|autossh}} 来自动重启它们。<br />
<br />
使用范例:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" username@example.com<br />
<br />
结合 [[SSHFS]]:<br />
$ sshfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=45,ServerAliveCountMax=2,ssh_command='autossh -M 0' username@example.com: /mnt/example <br />
<br />
通过一个由 [[Proxy settings]] 设置好的 SOCKS 代理来连接:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" -NCD 8080 username@example.com <br />
<br />
使用 {{ic|-f}} 选项以后可以使 autossh 作为后台进程运行,然而以这种方式运行意味着不能交互输入密码。<br />
<br />
当你在会话中打出 {{ic|exit}} 即可结束会话,或者 autossh 收到了 SIGTERM, SIGINT of SIGKILL 信号。<br />
<br />
==== 利用 systemd 在引导后自动运行 autossh ====<br />
<br />
如果你想自动启动 autossh,创建一个 systemd unit 文件:<br />
<br />
{{hc|/etc/systemd/system/autossh.service|2=<br />
[Unit]<br />
Description=AutoSSH service for port 2222<br />
After=network.target<br />
<br />
[Service]<br />
Environment="AUTOSSH_GATETIME=0"<br />
ExecStart=/usr/bin/autossh -M 0 -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
}}<br />
<br />
其中 {{ic|1=AUTOSSH_GATETIME=0}} 是一个环境变量,它表示 ssh 需要连上多久,autossh 才判定这个连接是成功的。将它设为 0 后 autossh 也会忽略 ssh 的第一次运行失败。这在开机启动 autossh 时可能是有用的。其他环境变量可以在手册页找到。当然,如果需要的话,你可以使这个单元更加复杂(详情请参阅 systemd 文档),显然你可以使用自己的 autossh 选项,但请注意 {{ic|-f}} 选项意味着 {{ic|1=AUTOSSH_GATETIME=0}} 无法在 systemd 中起效。<br />
<br />
别忘了 [[start]] 且/或 [[enable]] 这个 service。<br />
<br />
你可能还会需要关闭 ControlMaster,像这样:<br />
<br />
ExecStart=/usr/bin/autossh -M 0 -o ControlMaster=no -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
{{提示|同时管理多个 autossh 进程也是很简单的,要保持多个隧道连接,只需要用不同的文件名创建多个 service 文件。}}<br />
<br />
=== 当 SSH 守护进程出错时的其他选择 ===<br />
<br />
对于仅依赖 SSH 的远程或无头服务器,启动 SSH 守护程序失败(例如系统升级后)可能会阻止管理员访问。[[systemd]] 通过 {{ic|OnFailure}} 选项提供了简便的解决方案。<br />
<br />
假设服务器运行 {{ic|sshd}} 并且 [[telnet]] 是所选的故障安全替代方案。按如下所示创建一个文件。'''不要''' [[enable]] telnet.socket!<br />
<br />
{{hc|/etc/systemd/system/sshd.service.d/override.conf|2=<br />
[Unit]<br />
OnFailure=telnet.socket<br />
}}<br />
<br />
这样就行了。当 {{ic|sshd}} 正在运行时,Telnet 是不可用的。如果 {{ic|sshd}} 无法启动,可以打开一个 telnet 会话进行恢复。<br />
<br />
== 疑难解答 ==<br />
<br />
=== 自检清单 ===<br />
<br />
在进一步阅读前,请先仔细检查下面这些常见故障。<br />
<br />
# 配置文件存放目录 {{ic|~/.ssh}} 及目录下的文件应该只有你的账户才有访问权限(在客户端和服务器上都检查这一条): {{bc|<nowiki><br />
$ chmod 700 ~/.ssh<br />
$ chmod 600 ~/.ssh/*<br />
$ chown -R $USER ~/.ssh<br />
</nowiki>}}<br />
# 检查客户端的公钥(比如 {{ic|id_rsa.pub}})在服务器的 {{ic|~/.ssh/authorized_keys}} 文件里面。<br />
# 检查有没有在 [[#配置_2|服务器配置]] 里面设置 {{ic|AllowUsers}} 或 {{ic|AllowGroups}} 来限制 SSH 访问。<br />
# 检查用户是否设置了密码。有时还没有登录过服务器的新用户没有密码。<br />
# 把 {{ic|LogLevel DEBUG}} 加到 {{ic|/etc/ssh/sshd_config}} 文件尾部。<br />
# 使用 {{ic|journalctl -xe}} 查看可能的错误信息。<br />
# 在客户端和服务器上 [[Restart|重启]] {{ic|sshd}} 然后注销/重新登录。<br />
<br />
=== 拒绝连接或者超时问题 ===<br />
<br />
==== 端口转发 ====<br />
<br />
如果您位于 NAT 模式/路由器之后(除非您位于 VPS 或可公开寻址的主机上),请确保您的路由器可以将传入的 ssh 连接转发到您的计算机。使用 {{ic|$ ip addr}} 查找服务器的内网 IP 地址,并将您的路由器设置为将 SSH 端口上的 TCP 数据包转发到该 IP。[http://portforward.com portforward.com] 可以提供帮助。<br />
<br />
==== SSH服务是否开启并且正在监听? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示 SSH 端口是打开的,那么说明 SSH 服务没有启动。查看 {{ic|/var/log/messages}} 来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
<br />
[[Iptables]] 可能会阻止 {{ic|22}} 端口的连接。使用 {{bc|# iptables -nvL}} 来检查可能会在 {{ic|INPUT}} 链上导致丢包的规则。必要情况下可以用以下命令来解锁端口:<br />
{{bc|<br />
# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT<br />
}}<br />
更多配置防火墙的信息,请参阅 [[firewalls]].<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是 NAT 路由的问题)<br />
<br />
==== 你的 ISP 或第三方屏蔽了默认端口? ====<br />
{{注意|只有在你'''确保'''你没有运行任何防火墙,你已经在路由器上配置了 DMZ 主机或已经将端口映射到你的计算机,而这些都没有用的情况下才尝试以下步骤。可以在此找到诊断步骤或可能的解决方案。}}<br />
<br />
某些情况下,你的运营商会屏蔽默认端口(22 端口),无论怎么尝试(尝试开启端口、强化堆栈、防范洪水攻击)都无济于事。要确认确实存在屏蔽,只要创建一个接受任何来源(0.0.0.0)的服务器并远程连接它。<br />
<br />
如果你收到与此类似的错误消息:<br />
ssh: connect to host www.inet.hr port 22: Connection refused<br />
<br />
就表示你的 ISP '''没有'''屏蔽端口,但是服务器没有在该端口上运行 SSH 服务(请参阅 [[wikipedia:Security_through_obscurity|security through obscurity]])。<br />
<br />
但是,如果你收到与这条类似的错误消息:<br />
ssh: connect to host 111.222.333.444 port 22: Operation timed out <br />
<br />
这就表示有人阻止了 22 端口的 TCP 连接,基本上是通过防火墙或第三方干预(如 ISP 阻止和/或拒绝端口 22 上的传入通信),使得端口不可用。如果你的计算机上没有运行任何防火墙,并且在你的路由器和交换机中没有这方面的流量,那么你的 ISP 屏蔽了通讯。<br />
<br />
为了再次检查确认,可以在服务器上运行 Wireshark 并让它监听在 22 端口。由于 Wireshark 是一个二层数据包嗅探工具,而 TCP/UDP 工作在第三层及以上(参阅 [[wikipedia:Internet protocol suite|IP Network stack]]),如果在连接时未收到任何内容,则第三方很可能阻止了该端口上到服务器的流量。<br />
<br />
===== 诊断 =====<br />
<br />
[[Install|安装]] {{Pkg|tcpdump}} 或 Wireshark ({{Pkg|wireshark-cli}})。<br />
<br />
用于 tcpdump:<br />
<br />
# tcpdump -ni ''interface'' "port 22"<br />
<br />
用于 Wireshark:<br />
<br />
$ tshark -f "tcp port 22" -i ''interface''<br />
<br />
其中 {{ic|''interface''}} 是用于连接 WAN 的网络适配器(用 {{ic|ip a}} 来查找)。如果在尝试远程连接时没有收到任何数据包,则可以确信你的 ISP 屏蔽了 22 端口上的传入连接。<br />
<br />
===== 可能的解决方案 =====<br />
此方案是换一个 ISP 没有屏蔽的端口。编辑 {{ic|/etc/ssh/sshd_config}} 文件来使用不同的端口。例如,新增这几行:<br />
<br />
Port 22<br />
Port 1234<br />
<br />
还要确保文件中的其他“Port”配置行被注释掉。只是注释“Port 22”并加上“Port 1234”不会解决问题,因为那样 sshd 将只监听在 1234 端口上。写入这两行可以在两个端口上运行 SSH 服务器。<br />
<br />
[[Restart|重启]] 服务器上的 {{ic|sshd.service}} 就基本完成了。你还需要配置客户端来使用与默认端口不同的端口,这个问题有很多种解决方案,在这里我们只介绍两种。<br />
<br />
==== "Read from socket failed: connection reset by peer" 错误 ====<br />
<br />
使用最近版本的 openssh 连接到较旧的 ssh 服务器时有时会失败,并显示上述错误消息。这可以通过为该主机设置各种 [[#配置|客户端选项]] 来解决。有关下列选项的更多信息,请参阅 {{man|5|ssh_config}}。<br />
<br />
问题可能出在 {{ic|ecdsa-sha2-nistp*-cert-v01@openssh}} 椭圆曲线算法上。这些算法可以通过在 {{ic|HostKeyAlgorithms}} 里设置可用算法来排除那些算法。<br />
<br />
如果这不起作用,可能是秘钥列表太长了。设置 {{ic|Ciphers}} 来减少列表长度(少于 80 个字符应该可以)。同样的,也可以尝试缩短 {{ic|MACs}} 列表。<br />
<br />
参阅 openssh bug forum 上的 [http://www.gossamer-threads.com/lists/openssh/dev/51339 讨论]。<br />
<br />
=== "[your shell]: No such file or directory" / SSH 认证问题 ===<br />
对于这个问题,一个可能的原因是需要 SSH 客户端在 {{Ic|$SHELL}} 中提供绝对路径(例如可以通过 {{Ic|whereis -b [your shell]}} 得到),即使你的 shell 在 {{Ic|$PATH}} 里的某个路径中。<br />
<br />
==="Terminal unknown" 或 "Error opening terminal" 错误 ===<br />
如果你在登录时收到上述错误,这意味着服务器无法识别你的终端。使用 Ncurses 的应用程序(如 nano)可能会失败,并显示“Error opening terminal”。<br />
<br />
正确的解决方案是在服务器上安装客户端终端的 terminfo 文件。这会告诉服务器上的控制台程序如何正确地与终端进行交互。你可以使用 {{ic|$ infocmp}} 获得关于当前 terminfo 的信息,然后找出 [[Pacman#Querying_package_databases|哪个包包括了它们]]。<br />
<br />
如果你不能正常[[install|安装]]它,可以把 terminfo 复制到服务器上你的主目录里面:<br />
<br />
$ ssh myserver mkdir -p ~/.terminfo/${TERM:0:1}<br />
$ scp /usr/share/terminfo/${TERM:0:1}/$TERM myserver:~/.terminfo/${TERM:0:1}/<br />
<br />
重新登录、登出服务器后这个问题应该已经解决。<br />
<br />
==== TERM hack ====<br />
<br />
{{警告|这只能作为最后的手段。}}<br />
<br />
你可以在服务器上的环境(例如 {{ic|.bash_profile}})中简单地设置 {{ic|1=TERM=xterm}} 。这将消除错误并允许 ncurses 应用程序再次运行,但除非你的终端的控制序列与 xterm 完全匹配,否则可能会遇到奇怪的行为和图形界面问题。<br />
<br />
=== "Connection closed by x.x.x.x [preauth]" 错误 ===<br />
如果你在 sshd 的 log 里看到这条错误,请确保你已经设置了可用的 HostKey<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
=== id_dsa 被 OpenSSH 7.0 拒绝 ===<br />
<br />
出于安全原因,OpenSSH 7.0 弃用了 DSA 公钥。如果你必须启用它们,请[[#配置|设置]] {{ic|PubkeyAcceptedKeyTypes +ssh-dss}} 选项(http://www.openssh.com/legacy.html 没有提到这一点)。<br />
<br />
=== OpenSSH 7.0 的 "No matching key exchange method found" 错误 ===<br />
<br />
OpenSSH 7.0 弃用了 diffie-hellman-group1-sha1 密钥算法,因为它很弱并且在所谓 Logjam 攻击的理论范围内(参阅http://www.openssh.com/legacy.html)。如果特定主机需要这个密钥算法,ssh 会产生如下错误消息:<br />
<br />
Unable to negotiate with 127.0.0.1: no matching key exchange method found.<br />
Their offer: diffie-hellman-group1-sha1<br />
<br />
这个问题的最佳解决方案是将服务器升级/配置为不使用不推荐的算法。如果做不到这一点,可以配置[[#配置|客户端选项]] {{ic|KexAlgorithms +diffie-hellman-group1-sha1}} 强制客户端使用这个算法。<br />
<br />
=== 断开 SSH 连接时 tmux/screen 会话被关闭 ===<br />
<br />
如果进程在会话结束时被终止,那么你可能是用 ssh.socket 激活的,{{Pkg|systemd}} 注意到 SSH 会话进程退出,然后杀掉了 tmux/screen 进程。这种情况有两种解决方案。一种是通过使用 {{ic|ssh.service}} 来代替 {{ic|ssh.socket}} 来避免使用 socket 激活。另一个是在 {{ic|ssh@.service}} 的 Service 部分设置 {{ic|1=KillMode=process}}。<br />
<br />
在常规的 {{ic|ssh.service}} 里面 {{ic|1=KillMode=process}} 这个选项也是有用的,它可以在 service 停止或重启时防止 SSH 会话进程或 {{Pkg|screen}} 或 {{Pkg|tmux}} 进程被 kill 掉。<br />
<br />
=== SSH 会话无响应 ===<br />
<br />
SSH 响应 [[Wikipedia:Software_flow_control|流控制命令]] 中的 {{ic|XON}} 和 {{ic|XOFF}} 命令。 当你按 {{ic|Ctrl+s}} 时,它会冻结/挂起/停止响应。按 {{ic|Ctrl+q}} 恢复会话。<br />
<br />
== 参阅 ==<br />
<br />
* [[Wikipedia:Secure Shell]]<br />
* [http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
* [http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks<br />
* [https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure Secure Shell]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515148
OpenSSH (简体中文)
2018-03-28T02:17:28Z
<p>Arisaka: Sync with English version.</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:Secure Shell (简体中文)]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fa:SSH]]<br />
[[fr:ssh]]<br />
[[ja:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys (简体中文)}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|SSHFS (简体中文)}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related|SCP and SFTP}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Secure Shell|2018-03-28|515054}}<br />
<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器默认情况下,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专有软件、自由软件以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(来源:[[Wikipedia:Secure Shell|维基百科 Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH 是由 Theo de Raadt 领导的 OpenBSD 项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{pkg|openssh}}.<br />
<br />
<br />
===SSH 客户端===<br />
<br />
连接SSH服务器,运行命令<br />
<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
<br />
如果服务器仅允许使用密钥登录,请参考 [[SSH keys (简体中文)|SSH Keys]] 。<br />
<br />
====配置====<br />
<br />
客户端可以在配置文件中存储常用选项和常用主机,下列选项都可以应用至全局或应用至特定主机。 例如:<br />
<br />
{{hc|~/.ssh/config|# global options<br />
User ''user''<br />
<br />
# host-specific options<br />
Host myserver<br />
HostName ''server-address''<br />
Port ''port''}}<br />
<br />
进行了如上的配置后,以下命令是等效的<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
$ ssh myserver<br />
<br />
查看 {{man|5|ssh_config}} 获取更多信息。<br />
<br />
某些选项没有命令行参数,但是可以使用 {{ic|-o}} 在命令行中配置指定选项的参数。<br />
例如 {{ic|1=-oKexAlgorithms=+diffie-hellman-group1-sha1}}.<br />
<br />
===SSH 服务端===<br />
<br />
====配置====<br />
<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers ''user1 user2''<br />
<br />
只允许一些组访问:<br />
AllowGroups ''group1 group2''<br />
<br />
你也可以运行以下命令关联文件(如{{ic|/etc/issue}}文件)到登录欢迎信息:<br />
Banner /etc/issue<br />
<br />
公钥和私钥在 ''sshd'' [[#管理 sshd 守护进程|service 文件]] 安装的时候就已经生成在 {{ic|/etc/ssh}} 里面了,秘钥对由四种算法生成: [[SSH_keys#Choosing_the_authentication_key_type|dsa、rsa、ecdsa 和 ed25519]]。要让 sshd 使用一组特定的密钥,请指定以下选项:<br />
<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
如果此服务器在公网中,建议运行以下命令以更改sshd服务监听端口:<br />
Port 39901<br />
<br />
{{Tip|<br />
* 参考 [[Wikipedia:List of TCP and UDP port numbers|TCP 和 UDP 端口号列表]] 和本地的 {{ic|/etc/services}} 文件来选择一个未被常用服务占用的端口。把端口从默认的 22 改成别的可以减少由于端口扫描器尝试自动登录造成的登录日志条目,更多信息请参考 [[Port knocking]]。<br />
* 完全取消密码登录方式可以极大的增强安全性,请查看[[#强制公钥验证]]。查看[[#安全防护]]了解更多增强安全性的手段。<br />
* OpenSSH 可以监听多个端口,只需在配置文件中加入多行{{ic|Port ''port_number''}}即可。}}<br />
<br />
==== 管理 sshd 守护进程 ====<br />
<br />
{{Pkg|openssh}} 包括了两种 [[systemd]] 服务:<br />
#{{ic|sshd.service}},使 SSH 守护进程始终运行,并为每个入站连接创建子进程。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh#n16] 适用于有大量 SSH 流量的系统。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n15] <br />
#{{ic|sshd.socket}} + {{ic|sshd@.service}}, 为每个连接生成 SSH 守护进程的实例。它意味着让 ''systemd'' 监听 SSH socket,并且只有在有连接传入时启动守护进程。几乎所有情况下都推荐使用{{ic|sshd}}。 [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n18][http://lists.freedesktop.org/archives/systemd-devel/2011-January/001107.html][http://0pointer.de/blog/projects/inetd.html]<br />
<br />
[[start]] 并 [[enable]] {{ic|sshd.service}} '''或''' {{ic|sshd.socket}} 中的任何一个都可以启动守护进程。<br />
<br />
如果选择了 sshd.socket,并且不在默认的 22 端口监听,你需要[[edit|编辑]] ststemd 单元文件:<br />
<br />
{{hc|# systemctl edit sshd.socket|<nowiki><br />
[Socket]<br />
ListenStream=<br />
ListenStream=12345<br />
</nowiki>}}<br />
<br />
{{警告|使用 {{ic|sshd.socket}} 会使 {{ic|ListenAddress}} 设置无效,这将允许来自任何地址的连接。为了达到与 {{ic|ListenAddress}} 一样设置 IP 的效果, 你必须在 {{ic|ListenStream}} 中指定端口''和'' IP (例如:{{ic|1=ListenStream=192.168.1.100:22}})。你还需要在 {{ic|[Socket]}} 下面增加 {{ic|1=FreeBind=true}},否则设置 IP 与设置 {{ic|ListenAddress}} 有着相同的缺陷:如果网络未及时启动,socket 将无法启动。}}<br />
<br />
{{提示|打开 {{ic|sshd.service}} 时将为每个连接启动一个 {{ic|sshd@.service}} 的临时实例(实例名称不同)。因此,{{ic|sshd.socket}} 和常规 {{ic|sshd.service}} 都不允许监视日志中的连接尝试。使用 {{ic|journalctl -u "sshd@*"}} 或 {{ic|journalctl /usr/bin/sshd}} 可以看到 socket 激活的 SSH 实例的日志。}}<br />
<br />
==== 安全防护 ====<br />
<br />
允许通过SSH进行远程登录对管理服务器很有用,但也会对服务器构成安全威胁。SSH 通常是暴力攻击的目标,因此 SSH 访问需要适当限制,以防止第三方访问您的服务器。<br />
<br />
下列是有关该主题的优秀指南:<br />
<br />
*[https://wiki.mozilla.org/Security/Guidelines/OpenSSH Article by Mozilla Infosec Team]<br />
*[https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure sshd]<br />
<br />
===== 强制公钥验证 =====<br />
<br />
如果客户端无法通过公钥进行身份验证,则默认情况下,SSH服务器将使用密码来验证,从而允许恶意用户通过[[#防止暴力破解|暴力破解]]密码获取访问权限。一种防止此类攻击的有效方法是完全禁用密码登录,并强制使用[[SSH keys]]。可以在 {{ic|sshd_config}} 中禁用以下选项:<br />
<br />
PasswordAuthentication no<br />
<br />
{{警告|在将上述选项添加到你的配置之前,请确保所有需要 SSH 访问的帐户都在相应的 {{ic|authorized_keys}} 文件中设置了公钥验证。请参阅 [[SSH keys#Copying the public key to the remote server]] 以获取更多信息。}}<br />
<br />
===== 双因素验证与公钥 =====<br />
<br />
自 OpenSSH 6.2 起,你可以使用 {{ic|AuthenticationMethods}} 选项添加自己的钥匙串进行身份验证。这使你可以用公钥与双因素验证结合来登录。<br />
<br />
参阅 [[Google Authenticator (简体中文)]] 来设置 Google Authenticator。<br />
<br />
为了使 [[PAM (简体中文)]] 与 OpenSSH 协同工作, 编辑下列文件:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey keyboard-interactive:pam<br />
}}<br />
<br />
然后,你可以使用公钥'''或''' PAM 中设置的用户验证信息两者之一登录。<br />
<br />
另外,如果你想登录时同时验证公钥'''和''' PAM,请使用逗号而不是空格来分隔 AuthenticationMethods:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey,keyboard-interactive:pam<br />
}}<br />
<br />
通过要求提供公钥'''和''' PAM 认证,你可能希望禁用密码登录:<br />
{{hc|/etc/pam.d/sshd|<br />
auth required pam_securetty.so #disable remote root<br />
#Require google authenticator<br />
auth required pam_google_authenticator.so<br />
#But not password<br />
#auth include system-remote-login<br />
account include system-remote-login<br />
password include system-remote-login<br />
session include system-remote-login<br />
}}<br />
<br />
===== 防止暴力破解 =====<br />
暴力破解的概念很简单,即某人不断尝试用大量随机产生的用户名和密码对来登录网页或服务器的某个服务(比如 SSH)。<br />
<br />
====== 使用 ufw ======<br />
<br />
请参阅 [[ufw#Rate limiting with ufw]].<br />
<br />
====== 使用 iptables ======<br />
<br />
{{Merge|Simple_stateful_firewall#Bruteforce_attacks|Out of scope, same technique as already described in the SSF.}}<br />
<br />
如果你已经在用 iptables,可以配置以下规则来保护 SSH 免受暴破。<br />
<br />
{{注意|此示例中 SSH 所用的 TCP 端口已经改为了 42660。}}<br />
<br />
在应用后面的规则之前,我们先新建一条规则链来记录并拒绝过多的连接请求:<br />
<br />
# iptables -N LOG_AND_DROP<br />
<br />
第一条规则将应用于预示 TCP 42660 端口有新连接的数据包:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --set --name DEFAULT --rsource<br />
<br />
下一条规则告诉 iptables 查找匹配前一条规则的数据包,这些数据包也来自已添加到监视列表中的主机。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --update --seconds 90 --hitcount 4 --name DEFAULT --rsource -j LOG_AND_DROP<br />
<br />
现在,让 iptables 决定如何处理 TCP 42660 端口的通信中不符合上述规则的数据包。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -j ACCEPT<br />
<br />
我们向 LOG_AND_DROP 表增加如下规则,并使用 -j (jump) 参数将数据包的信息传递给日志记录工具。<br />
<br />
# iptables -A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7<br />
<br />
在按照第一条规则进行记录后,所有数据包将被丢弃。<br />
<br />
# iptables -A LOG_AND_DROP -j DROP<br />
<br />
====== 防止暴力破解的工具 ======<br />
<br />
你可以用类似 [[fail2ban]] 或 [[sshguard]] 的自动防暴破的脚本来阻挡攻击者。<br />
<br />
* 仅允许来自受信任位置的 SSH 入站连接。<br />
* 使用 [[fail2ban]] 或 [[sshguard]] 自动阻止多次密码验证失败的 IP 地址。<br />
* 使用 [https://github.com/jtniehof/pam_shield pam_shield] 来阻止在一定时间内执行过多登录尝试的 IP 地址。与 [[fail2ban]] 或 [[sshguard]]不同,该程序不考虑登录成功或失败。<br />
<br />
===== 禁用或限制 root 账户登录 =====<br />
{{Out of date|最新版本默认已禁用 root 账户登录。暂不清楚本节的哪些部分是多余的。}}<br />
<br />
允许 root 账户随意通过 SSH 登录通常是不安全的,有两种方法可以限制 root 账户通过 SSH 登录,从而提高安全性。<br />
<br />
====== 禁用 root 登录 ======<br />
<br />
Sudo 可以有选择地为需要 root 权限的操作提供相应的权限,且不需要登录 root 账户。这样即可关闭 root 登录,并且可以看做一种防范暴力攻击的安全措施,因为现在攻击者除了要猜测密码外还要猜测帐户名称。<br />
<br />
通过编辑 {{ic|/etc/ssh/sshd_config}} 中的 "Authentication" 一节可以使 SSH 屏蔽 root 用户登录,只要将 {{ic|#PermitRootLogin prohibit-password}} 改成 {{ic|no}} 并取消该行注释即可:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
PermitRootLogin no<br />
...<br />
}}<br />
<br />
然后 [[restart|重启]] SSH 守护进程。<br />
<br />
现在你将无法通过 root 账户登录,但仍可以用普通账户登录并使用 [[su]] 或者 [[sudo]] 来完成系统维护工作。<br />
<br />
====== 限制 root 登录 ======<br />
<br />
一些自动化的维护任务(比如远程备份整个系统)需要完整的 root 权限。要以安全的方式允许 root 登录而不是禁用它,可以只允许远程登录的 root 用户执行指定的命令,在 {{ic|~root/.ssh/authorized_keys}} 头部加上指定的密钥即可,例如:<br />
<br />
command="/usr/lib/rsync/rrsync -ro /" ssh-rsa …<br />
<br />
这样,任何用户持有该秘钥即可执行引号之间的命令。<br />
<br />
为了弥补因 root 用户名称暴露而导致受攻击的可能性增加,可以将以下命令加入 {{ic|sshd_config}}:<br />
<br />
PermitRootLogin forced-commands-only<br />
<br />
该设置不仅会限制 root 用户通过 SSH 执行的命令,还会禁用密码登录方式,强制 root 帐户使用公钥登录。<br />
<br />
如果不想限制 root 用户可执行的命令,可以仅关闭密码验证来强制使用公钥验证:<br />
<br />
PermitRootLogin without-password<br />
<br />
===== 保护 authorized_keys 文件 =====<br />
<br />
你可以阻止其他用户向该文件加入新公钥且通过新的公钥连接。<br />
<br />
把 {{ic|authorized_keys}} 文件的权限全部去掉,只保留读权限:<br />
<br />
$ chmod 400 ~/.ssh/authorized_keys<br />
<br />
为防止用户把权限改回来,可以对 {{ic|authorized_keys}} 文件采取 [[File permissions and attributes#chattr and lsattr|set the immutable bit(设为不可变)]] 操作。尽管如此,用户仍然可以重命名 {{ic|~/.ssh}} 并新建一个 {{ic|~/.ssh}} 目录和 {{ic|authorized_keys}} 文件。所以 {{ic|~/.ssh}} 目录也要设置 immutable bit。<br />
<br />
{{注意|如果你自己需要新增一个公钥,你需要先移除 {{ic|authorized_keys}} 文件的 immutable bit,并增加写权限,最后按上述步骤重新加密。}}<br />
<br />
== 其他 SSH 客户端与服务端 ==<br />
除了 OpenSSH,还有很多可用的 SSH [[Wikipedia:Comparison of SSH clients|客户端]] 和 [[Wikipedia:Comparison of SSH servers|服务端]]。<br />
<br />
=== Dropbear ===<br />
[[Wikipedia:Dropbear (software)|Dropbear]] 是一个 SSH-2 客户端与服务端。 {{Pkg|dropbear}} 可以从 [[official repositories|官方仓库]] 下载。<br />
<br />
它的命令行版客户端叫 dbclient。<br />
<br />
=== Mosh ===<br />
来自 Mosh [http://mosh.mit.edu/ 网站]:<br />
<br />
:Remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. Mosh is a replacement for SSH. It is more robust and responsive, especially over slow connections such as Wi-Fi, cellular, and long-distance.<br />
:翻译:允许“漫游”的远程终端,支持间歇性的连接,并提供对于用户按键的智能本地回馈和行编辑回馈。Mosh 是 SSH 的替代品。它更加强大而快速,特别针对诸如 Wi-Fi,移动网络和超远距离等慢速连接环境。<br />
<br />
[[Install|安装]] {{Pkg|mosh}} 这个包, 或安装最新版:{{AUR|mosh-git}}。<br />
<br />
Mosh 有一个未写入文档的命令行选项:{{ic|1=--predict=experimental}},它可以产生更有力的本地按键响应。对降低键盘输入视觉上的延迟确认感兴趣的用户可能更喜欢这个预测模式。<br />
<br />
{{提示|Mosh 从设计上就不允许你访问会话的历史记录,请考虑安装终端复用工具,如 [[tmux]] 或 [[screen]] 。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
{{Accuracy|根据目前本文的布局,这部分看起来应该是通用的,但实际上大部分提供的技巧只能在 ''openssh'' 中使用。比如 ''dropbear'' (在 [[#Other SSH clients and servers]] 列表中) 不支持 SOCKS 协议。[https://en.wikipedia.org/wiki/Comparison_of_SSH_clients#Technical]}}<br />
<br />
=== 加密 Socks 通道 ===<br />
<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的 SSH 服务器,比如在家里或办公室。用动态的 DNS 服务 [http://www.dyndns.org/ DynDNS] 也可能是很有用的,这样你就不必记住你的 IP 了。<br />
<br />
==== 第一步:开始连接 ====<br />
<br />
你只要执行这一个命令就能开始你的连接:<br />
<br />
$ ssh -TND 4711 ''user''@''host''<br />
<br />
这里的 {{Ic|''user''}} 是你在 {{Ic|''host''}} 这台 SSH 服务器上的用户名。它会让你输入密码,然后你就能连上了。 {{Ic|N}} 表示不采用交互提示,而 {{Ic|D}} 表示指定监听的本地端口(你可以使用任何你喜欢的数字),{{Ic|T}} 表示禁用伪 tty 分配。<br />
<br />
加了 {{Ic|-v}} (verbose) 标志以后的输出可以让你能够验证到底连了哪个端口。<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你没有配置你的浏览器(或其他程序)使用这个新创建的 socks 隧道,上述步骤是无效的。由于当前版本的 SSH 支持 SOCKS4 和 SOCKS5,因此您可以使用其中任何一种。<br />
<br />
* 对于 Firefox: ''Edit > Preferences > Advanced > Network > Connection > Setting'': <br> 选中 ''Manual proxy configuration'' 单选框, 然后在 ''SOCKS host'' 里输入 {{ic|localhost}}, 然后在后面那个框中输入你的端口号(本例中为 {{ic|4711}})。<br />
<br />
Firefox 不会自动通过 socks 隧道发送 DNS 请求,这一潜在的隐私问题可以通过以下步骤来解决:<br />
<br />
# 在 Firefox 地址栏中输入:about:config 。<br />
# 搜索:network.proxy.socks_remote_dns<br />
# 将该值设为 true。<br />
# 重启浏览器。<br />
<br />
* 对于 Chromium: 你可以将 SOCKS 设置设置为环境变量或命令行选项。我建议将下列函数之一加入到你的 {{ic|.bashrc}}:<br />
function secure_chromium {<br />
port=4711<br />
export SOCKS_SERVER=localhost:$port<br />
export SOCKS_VERSION=5<br />
chromium &<br />
exit<br />
}<br />
或者<br />
function secure_chromium {<br />
port=4711<br />
chromium --proxy-server="socks://localhost:$port" &<br />
exit<br />
}<br />
<br />
现在打开终端然后输入:<br />
<br />
$ secure_chromium<br />
<br />
享受你的安全隧道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过 SSH 运行图形程序你必须使用 X11 转发 (forwarding)。这不要求对端安装了完整的 X11,但是至少要装好 ''xauth''。''xauth'' 是一个用来管理 {{ic|Xauthority}} 配置的工具,该配置用于服务器与客户端之间的 X11 会话认证([http://xmodulo.com/2012/11/how-to-enable-x11-forwarding-using-ssh.html source])。<br />
<br />
{{警告|X11 转发有着重要的安全问题需要考虑,至少应先阅读 {{man|1|ssh}}、{{man|5|sshd_config}} 和 {{man|5|ssh_config}} 手册页。也可以参考 [https://security.stackexchange.com/questions/14815/security-concerns-with-x11-forwarding 这个 StackExchange 帖]。}}<br />
<br />
==== 配置 ====<br />
<br />
在远程主机上:<br />
<br />
*[[install|安装]] {{Pkg|xorg-xauth}} 和 {{Pkg|xorg-xhost}} 这两个包<br />
*在 {{ic|/etc/ssh/ssh'''d'''_config}} 上:<br />
**确保 {{ic|AllowTcpForwarding}} 和 {{ic|X11UseLocalhost}} 已经设置为 ''yes'',并且 {{ic|X11DisplayOffset}} 设置为 ''10'' (这些是默认设置,参考 {{man|5|sshd_config}})<br />
**将 {{ic|X11Forwarding}} 设置为 ''yes''<br />
* 最后 [[restart|重启]] [[#Daemon management|''sshd'' 守护进程]].<br />
<br />
在客户端上,通过在命令行设置 {{ic|-X}} 参数启用 {{ic|ForwardX11}},或者在[[#配置|客户端配置文件]]中将 {{ic|ForwardX11}} 设置为 ''yes''。<br />
<br />
{{提示|如果 GUI 绘制不正常或者有错误提示,你可以启用 {{ic|ForwardX11Trusted}} 选项(或在命令行中加上 {{ic|-Y}} 参数),这将使 X11 转发脱离 [http://www.x.org/wiki/Development/Documentation/Security/ X11 SECURITY extension] 的控制,如果你这样做,请确保已经读过本节开头的[[#X11 转发|警告]]。}}<br />
<br />
==== 使用方法 ====<br />
<br />
{{Accuracy|{{ic|xhost}} [http://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-from-ubuntu-machine#comment-17148 通常不是必须的]}}<br />
<br />
正常登录远程主机,如果客户端的配置文件中没有启用 ''ForwardX11'' 那就加上 {{ic|-X}} 参数:<br />
$ ssh -X ''user@host''<br />
<br />
如果在运行图形程序的时候碰到错误,尝试用 ''ForwardX11Trusted'' 代替 ''ForwardX11'' :<br />
$ ssh -Y ''user@host''<br />
<br />
现在你应该可以运行服务器上的任何 X 图形程序,任何输出都会重定向至你当前的会话:<br />
$ xclock<br />
<br />
如果碰到 "Cannot open display" 的错误,请尝试用非管理员账户运行下列命令:<br />
$ xhost +<br />
<br />
上述命令将允许任何人转发 X11 应用程序,这个命令可以限制特定的主机类型:<br />
$ xhost +hostname<br />
<br />
其中 hostname 是要转发到的特定主机的名称。更多信息可以查看 {{man|1|xhost}}。<br />
<br />
请注意某些应用程序,它们会检查本地计算机上正在运行的实例。[[Firefox]] 就是其中之一:你可以关掉本机上的 Firefox 或者使用以下启动参数来启动远程实例:<br />
$ firefox --no-remote<br />
<br />
当你连接时收到 "X11 forwarding request failed on channel 0" 错误(或者服务器上的 {{ic|/var/log/errors.log}} 文件显示 "Failed to allocate internet-domain X11 display socket" 错误),请确保已经安装 {{Pkg|xorg-xauth}},如果装完了仍然不起作用,尝试以下方法之一:<br />
<br />
* 在''服务器''的 {{ic|ssh'''d'''_config}} 中启用 {{ic|AddressFamily any}} 选项,或者<br />
* 将''服务器''的 {{ic|ssh'''d'''_config}} 中的 {{ic|AddressFamily}} 选项设为 inet。<br />
将其设置为 inet 可能会修复 IPv4 上的 Ubuntu 客户端的问题。<br />
<br />
要以其他用户身份运行 SSH 服务器上的 X 应用程序,你需要先用已知用户登录,取出 {{Ic|xauth list}} 中的身份认证行,然后 {{Ic|xauth add}} 它。<br />
<br />
{{提示|[http://unix.stackexchange.com/a/12772/29867 这里] 是 [http://unix.stackexchange.com/a/46748/29867 一些] 用来诊断 {{ic|X11 Forwarding}} 问题有用的 [http://superuser.com/a/805060/185665 链接]。}}<br />
<br />
=== 转发其他端口 ===<br />
<br />
除了 SSH 内建的对 X11 的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一条SSH命令来建立一个安全的VNC连接。本地转发可以通过 {{Ic|-L}} 来设置,后面可以指定一个地址及端口 {{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在 192.168.0.100 的 shell,同时也会创建一个从本机 1000 端口到 mai.google.com 上的 25 端口的隧道。建立之后,localhost:1000 会通过 192.168.0.100 连接到 Gmail 的 SMTP 端口。任何从 192.168.0.100 到 mail.google.com:25 的连接(即使不必要)都会以这样的方式建立,并且,在本机和 192.168.0.100 之间的数据传递都是安全的,除非你采取了别的手段。<br />
<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到 localhost:2000 的连接直接转发到远程主机 192.168.0.100 的 6001 端口。对于使用 VNC 服务器(tightvns包的一部分)建立的 VNC 连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过 SSH 隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过 {{Ic|-R}} 参数,以及 {{Ic|<tunnel port>:<destination address>:<destination port>}} 能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在 192.168.0.200 上得到一个 shell,同时也会创建一个从 192.168.0.200 上的 3000 端口到 irc.freenode.net 上的 6667 端口的隧道。建立之后,192.168.0.200:3000 会通过本机连接到 freenode 的 IRC 端口。到 192.168.0.200 的 3000 端口的连接将会通过隧道发送到本机然后转发到 irc.freenode.net 的 6667 端口。因此,在这个例子中,在远程主机上 IRC 程序能够被使用,即使端口 6667 被阻止。<br />
<br />
本地转发和远程转发都可以提供一个安全的"网关",允许其他计算机无需使用 SSH 或者 SSH daemon 来使用 ssh 隧道,即在隧道起点提供绑定的地址,作为转发规则。例如 {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}。{{Ic|<tunnel address>}} 可以是作为网关的机器上的任何地址,例如 {{Ic|localhost}}(仅允许本地访问),{{Ic|192.168.0.100}}(仅允许通过192.168.0.100访问), {{Ic|*}}(允许所有地址访问)。它们可以是通过本地环回端口,或是通过其他任何端口的连接。默认情况下,转发受到隧道“起点”的主机限制,即 {{Ic|<tunnel address>}} 被设置为 {{Ic|localhost}}。本地转发不需要额外的设置,而远程转发受限于对端的 SSH daemon 设置。请参阅 {{Ic|sshd_config(5)}} 中的 {{Ic|GatewayPorts}} 选项。<br />
<br />
=== 跳板机 ===<br />
<br />
在某些情况下,你与目标主机之间可能无法直接连接,此时就要用到跳板机。因此,我们尝试将两个或更多 SSH 隧道连接在一起,并假设您的本地密钥已针对链中的每个服务器授权。这可以通过使用SSH代理转发 ({{ic|-A}}) 和伪终端分配 ({{ic|-t}}) 来实现,它使用以下语法转发本地密钥:<br />
<br />
$ ssh -A -t -l user1 bastion1 \<br />
ssh -A -t -l user2 intermediate2 \<br />
ssh -A -t -l user3 target<br />
<br />
一个更简单的方法是使用 {{ic|-J}} 选项:<br />
<br />
$ ssh -J user1@bastion1,user2@intermediate2 user3@target<br />
<br />
<br />
{{ic|-J}} 指令中的多个主机可以用逗号隔开,它们将按照列出的顺序连接。{{ic|user...@}} 部分不是必需的,但可以使用。定义 {{ic|-J}} 选项里的不同的主机规格可以使用 ssh 配置文件,因此如果需要,可以在那里设置特定的每个主机选项。<br />
<br />
=== 通过中继反向 SSH 连接 ===<br />
<br />
{{Style|SSH 隧道的设想是很经典的,所以添加一些参考资料的详细解释会更好。比如 [https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work/118650#118650] 涵盖了一些其他情况。}}<br />
<br />
这个想法是客户端通过一个中继连接到服务器,而服务器使用反向 SSH 隧道连接到同一个中继。例如,当服务器位于 NAT 后面时,这是很有用的,而此处的中继是一个可公开访问的 SSH 服务器,用作用户有权访问的代理服务器。前提是客户端的密钥同时对中继和服务器都已经授权,服务器需要授权中继用于反向 SSH 连接。<br />
<br />
以下配置假设 user1 是客户端使用的账户,user2 是中继的,user3 是服务器的。首先服务器要先建立反向隧道:<br />
<br />
ssh -R 2222:localhost:22 -N user2@relay<br />
<br />
这可以利用启动脚本、systemd service 或者 {{Pkg|autossh}} 来自动完成。<br />
<br />
{{Expansion|需要解释为何光有 {{ic|ssh user3@relay -p 2222}} 是不够的。}}<br />
<br />
在客户端使用以下命令建立连接:<br />
<br />
ssh user2@relay ssh user3@localhost -p 2222<br />
<br />
可以在中继的 {{ic|~/.ssh/authorized_keys}} 中定义 {{ic|command}} 字段来建立反向隧道:<br />
<br />
command="ssh user3@localhost -p 2222" ssh-rsa KEY2 user1@client<br />
<br />
在这种情况下用下列命令建立连接:<br />
<br />
ssh user2@relay<br />
<br />
注意,客户端内 scp 的自动完成功能失效,甚至在某些配置下 scp 本身也无法工作。<br />
<br />
=== 端口复用 ===<br />
<br />
SSH 守护进程通常监听 22 端口,但是许多公共热点会屏蔽非常规 HTTP/S 端口(分别是 80 和 443 端口)的流量,这样就屏蔽了 SSH 连接。最快的解决方法是让 {{ic|sshd}} 额外监听白名单上的端口:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
Port 22<br />
Port 443<br />
}}<br />
<br />
但是443端口很有可能已经被 HTTPS 服务占用,在这种情况下可以使用端口复用工具,比如 {{Pkg|sslh}},它可以监听在一个被复用的端口上并转发相应的数据包给对应的服务。<br />
<br />
=== 加速 SSH ===<br />
<br />
此处列出一些可以加速全部连接或针对某台主机加速的 [[#配置|客户端配置]] 选项。要了解这些选项的完整概述,请参阅 {{man|5|ssh_config}}。<br />
<br />
* 使用以下参数来使到某一台主机的所有回话 (sessions) 共享同一个连接: {{bc|<nowiki><br />
ControlMaster auto<br />
ControlPersist yes<br />
ControlPath ~/.ssh/sockets/socket-%r@%h:%p<br />
</nowiki>}}<br />
: 其中 {{ic|~/.ssh/sockets}} 可以是一个其他用户不可写入的任意目录。<br />
<br />
* {{ic|ControlPersist}} 指定在初始客户端连接关闭后,主服务器在后台等待新客户端的时间。可能的值是: <br />
** {{ic|no}} 指定在最后一个客户端断开后立即关闭连接,<br />
** 一个用秒数表示的时间,<br />
** {{ic|yes}} 连接不会自动关闭,而是始终处于等待。<br />
<br />
* 另一种加速的方法是通过 {{ic|Compression yes}} 选项或者 {{ic|-C}} 参数来启用压缩。<br />
: {{注意|{{man|1|ssh}} 指出:“在调制解调器线路或其他慢速线路上启用压缩是可取的,但在网速快的情况下只会降低速度。”这条提示可能会适得其反,具体取决于你的网络配置。}}<br />
<br />
* 通过使用 {{ic|AddressFamily inet}} 选项或者 {{ic|-4}} 参数来跳过 IPv6 查找,可以缩短登录时间。<br />
<br />
* 最后,如果你想用 SFTP 或 SCP,[https://www.psc.edu/index.php/hpn-ssh High Performance SSH/SCP] 可以通过动态提高 SSH 缓冲区大小来显著提高吞吐量。安装 {{AUR|openssh-hpn-git}} 这个包来使用打过这一增强补丁的 OpenSSH 版本。<br />
<br />
=== 用 SSHFS 挂载远程文件系统 ===<br />
<br />
请参阅 [[SSHFS]] 来将一个 SSH 可访问的远程文件系统挂载至一个本地目录,然后你就能在挂载好的文件上执行常规操作(复制,重命名,用 vim 编辑等等)。''sshfs'' 比 ''shfs'' 更好,因为后者自 2004 年起就没再更新。<br />
{{提示|软件包 {{AUR|autosshfs-git}} 可以用于在登录时自动运行 autosshfs。}}<br />
<br />
=== 保持在线 ===<br />
<br />
默认情况下,如果你的会话空闲了某个时间之后,它会自动登出。为了保持会话,在长时间没有数据传输时客户端可以向服务器发送一个激活信号。与之对应,服务器也可以在一段时间没有收到消息时定期发送一个信号。<br />
<br />
* 在 '''服务器''',{{ic|ClientAliveInterval}} 是没有从客户端收到消息后的超时时间,超时后 ''sshd'' 将会发送一个请求来等待回应。默认是 0,指不会发出请求。比如要求每隔 60 秒向客户端发送响应请求,在你的 [[#配置_2|服务器配置]] 里设置 {{ic|ClientAliveInterval 60}} 即可。{{ic|ClientAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
* 在 '''客户端''',{{ic|ServerAliveInterval}} 控制着从客户端发往服务器的响应请求的时间间隔。比如要求服务器每隔 120 秒响应一次,在你的 [[#配置|客户端配置]] 里加入 {{ic|ServerAliveInterval 120}} 即可。{{ic|ServerAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
<br />
{{注意| 为确保会话保持活动状态,客户端或服务器中只有一个需要发送保持活动请求。如果用户同时控制服务器和客户端,那么合理的选择是使用 {{ic|ServerAliveInterval}} 选项配置需要保持会话的客户端,并保留其他客户端和服务器的默认配置。}}<br />
<br />
=== 利用 systemd 自动重启 SSH 隧道 ===<br />
<br />
[[systemd]] 可以在开机/登录时自动启动 SSH,''还可以'' 在 SSH 连接断开时自动重连。这使它成为管理 SSH 隧道的有力工具。<br />
<br />
下面的 service 可以使用 [[#配置|ssh 配置]] 里面的配置在你登录系统的时候自动开启一个 SSH 隧道。如果连接因为某种原因断开,它将会每隔10秒重启一下:<br />
<br />
{{hc|~/.config/systemd/user/tunnel.service|<nowiki><br />
[Unit]<br />
Description=SSH tunnel to myserver<br />
<br />
[Service]<br />
Type=simple<br />
Restart=always<br />
RestartSec=10<br />
ExecStart=/usr/bin/ssh -F %h/.ssh/config -N myserver<br />
</nowiki>}}<br />
<br />
然后 [[enable]] 并且 [[start]] 这个 user service。欲知如何防止连接超时,请参阅 [[#Keep alive]]。如果你想在系统引导后就打开这个连接,你需要将这个 unit 重写为 system service。<br />
<br />
=== Autossh - 自动重启 SSH 会话和隧道连接 ===<br />
<br />
当一个 SSH 会话或隧道无法保持连接(比如网络环境差导致客户端断线),可以使用 {{Pkg|autossh}} 来自动重启它们。<br />
<br />
使用范例:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" username@example.com<br />
<br />
结合 [[SSHFS]]:<br />
$ sshfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=45,ServerAliveCountMax=2,ssh_command='autossh -M 0' username@example.com: /mnt/example <br />
<br />
通过一个由 [[Proxy settings]] 设置好的 SOCKS 代理来连接:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" -NCD 8080 username@example.com <br />
<br />
使用 {{ic|-f}} 选项以后可以使 autossh 作为后台进程运行,然而以这种方式运行意味着不能交互输入密码。<br />
<br />
当你在会话中打出 {{ic|exit}} 即可结束会话,或者 autossh 收到了 SIGTERM, SIGINT of SIGKILL 信号。<br />
<br />
==== 利用 systemd 在引导后自动运行 autossh ====<br />
<br />
如果你想自动启动 autossh,创建一个 systemd unit 文件:<br />
<br />
{{hc|/etc/systemd/system/autossh.service|2=<br />
[Unit]<br />
Description=AutoSSH service for port 2222<br />
After=network.target<br />
<br />
[Service]<br />
Environment="AUTOSSH_GATETIME=0"<br />
ExecStart=/usr/bin/autossh -M 0 -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
}}<br />
<br />
其中 {{ic|1=AUTOSSH_GATETIME=0}} 是一个环境变量,它表示 ssh 需要连上多久,autossh 才判定这个连接是成功的。将它设为 0 后 autossh 也会忽略 ssh 的第一次运行失败。这在开机启动 autossh 时可能是有用的。其他环境变量可以在手册页找到。当然,如果需要的话,你可以使这个单元更加复杂(详情请参阅 systemd 文档),显然你可以使用自己的 autossh 选项,但请注意 {{ic|-f}} 选项意味着 {{ic|1=AUTOSSH_GATETIME=0}} 无法在 systemd 中起效。<br />
<br />
别忘了 [[start]] 且/或 [[enable]] 这个 service。<br />
<br />
你可能还会需要关闭 ControlMaster,像这样:<br />
<br />
ExecStart=/usr/bin/autossh -M 0 -o ControlMaster=no -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
{{提示|同时管理多个 autossh 进程也是很简单的,要保持多个隧道连接,只需要用不同的文件名创建多个 service 文件。}}<br />
<br />
=== 当 SSH 守护进程出错时的其他选择 ===<br />
<br />
对于仅依赖 SSH 的远程或无头服务器,启动 SSH 守护程序失败(例如系统升级后)可能会阻止管理员访问。[[systemd]] 通过 {{ic|OnFailure}} 选项提供了简便的解决方案。<br />
<br />
假设服务器运行 {{ic|sshd}} 并且 [[telnet]] 是所选的故障安全替代方案。按如下所示创建一个文件。'''不要''' [[enable]] telnet.socket!<br />
<br />
{{hc|/etc/systemd/system/sshd.service.d/override.conf|2=<br />
[Unit]<br />
OnFailure=telnet.socket<br />
}}<br />
<br />
这样就行了。当 {{ic|sshd}} 正在运行时,Telnet 是不可用的。如果 {{ic|sshd}} 无法启动,可以打开一个 telnet 会话进行恢复。<br />
<br />
== 疑难解答 ==<br />
<br />
=== 自检清单 ===<br />
<br />
在进一步阅读前,请先仔细检查下面这些常见故障。<br />
<br />
# 配置文件存放目录 {{ic|~/.ssh}} 及目录下的文件应该只有你的账户才有访问权限(在客户端和服务器上都检查这一条): {{bc|<nowiki><br />
$ chmod 700 ~/.ssh<br />
$ chmod 600 ~/.ssh/*<br />
$ chown -R $USER ~/.ssh<br />
</nowiki>}}<br />
# 检查客户端的公钥(比如 {{ic|id_rsa.pub}})在服务器的 {{ic|~/.ssh/authorized_keys}} 文件里面。<br />
# 检查有没有在 [[#配置_2|服务器配置]] 里面设置 {{ic|AllowUsers}} 或 {{ic|AllowGroups}} 来限制 SSH 访问。<br />
# 检查用户是否设置了密码。有时还没有登录过服务器的新用户没有密码。<br />
# 把 {{ic|LogLevel DEBUG}} 加到 {{ic|/etc/ssh/sshd_config}} 文件尾部。<br />
# 使用 {{ic|journalctl -xe}} 查看可能的错误信息。<br />
# 在客户端和服务器上 [[Restart|重启]] {{ic|sshd}} 然后注销/重新登录。<br />
<br />
=== 拒绝连接或者超时问题 ===<br />
<br />
==== 端口转发 ====<br />
<br />
如果您位于 NAT 模式/路由器之后(除非您位于 VPS 或可公开寻址的主机上),请确保您的路由器可以将传入的 ssh 连接转发到您的计算机。使用 {{ic|$ ip addr}} 查找服务器的内网 IP 地址,并将您的路由器设置为将 SSH 端口上的 TCP 数据包转发到该 IP。[http://portforward.com portforward.com] 可以提供帮助。<br />
<br />
==== SSH服务是否开启并且正在监听? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示 SSH 端口是打开的,那么说明 SSH 服务没有启动。查看 {{ic|/var/log/messages}} 来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
<br />
[[Iptables]] 可能会阻止 {{ic|22}} 端口的连接。使用 {{bc|# iptables -nvL}} 来检查可能会在 {{ic|INPUT}} 链上导致丢包的规则。必要情况下可以用以下命令来解锁端口:<br />
{{bc|<br />
# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT<br />
}}<br />
更多配置防火墙的信息,请参阅 [[firewalls]].<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是 NAT 路由的问题)<br />
<br />
==== 你的 ISP 或第三方屏蔽了默认端口? ====<br />
{{注意|只有在你'''确保'''你没有运行任何防火墙,你已经在路由器上配置了 DMZ 主机或已经将端口映射到你的计算机,而这些都没有用的情况下才尝试以下步骤。可以在此找到诊断步骤或可能的解决方案。}}<br />
<br />
某些情况下,你的运营商会屏蔽默认端口(22 端口),无论怎么尝试(尝试开启端口、强化堆栈、防范洪水攻击)都无济于事。要确认确实存在屏蔽,只要创建一个接受任何来源(0.0.0.0)的服务器并远程连接它。<br />
<br />
如果你收到与此类似的错误消息:<br />
ssh: connect to host www.inet.hr port 22: Connection refused<br />
<br />
就表示你的 ISP '''没有'''屏蔽端口,但是服务器没有在该端口上运行 SSH 服务(请参阅 [[wikipedia:Security_through_obscurity|security through obscurity]])。<br />
<br />
但是,如果你收到与这条类似的错误消息:<br />
ssh: connect to host 111.222.333.444 port 22: Operation timed out <br />
<br />
这就表示有人阻止了 22 端口的 TCP 连接,基本上是通过防火墙或第三方干预(如 ISP 阻止和/或拒绝端口 22 上的传入通信),使得端口不可用。如果你的计算机上没有运行任何防火墙,并且在你的路由器和交换机中没有这方面的流量,那么你的 ISP 屏蔽了通讯。<br />
<br />
为了再次检查确认,可以在服务器上运行 Wireshark 并让它监听在 22 端口。由于 Wireshark 是一个二层数据包嗅探工具,而 TCP/UDP 工作在第三层及以上(参阅 [[wikipedia:Internet protocol suite|IP Network stack]]),如果在连接时未收到任何内容,则第三方很可能阻止了该端口上到服务器的流量。<br />
<br />
===== 诊断 =====<br />
<br />
[[Install|安装]] {{Pkg|tcpdump}} 或 Wireshark ({{Pkg|wireshark-cli}})。<br />
<br />
用于 tcpdump:<br />
<br />
# tcpdump -ni ''interface'' "port 22"<br />
<br />
用于 Wireshark:<br />
<br />
$ tshark -f "tcp port 22" -i ''interface''<br />
<br />
其中 {{ic|''interface''}} 是用于连接 WAN 的网络适配器(用 {{ic|ip a}} 来查找)。如果在尝试远程连接时没有收到任何数据包,则可以确信你的 ISP 屏蔽了 22 端口上的传入连接。<br />
<br />
===== 可能的解决方案 =====<br />
此方案是换一个 ISP 没有屏蔽的端口。编辑 {{ic|/etc/ssh/sshd_config}} 文件来使用不同的端口。例如,新增这几行:<br />
<br />
Port 22<br />
Port 1234<br />
<br />
还要确保文件中的其他“Port”配置行被注释掉。只是注释“Port 22”并加上“Port 1234”不会解决问题,因为那样 sshd 将只监听在 1234 端口上。写入这两行可以在两个端口上运行 SSH 服务器。<br />
<br />
[[Restart|重启]] 服务器上的 {{ic|sshd.service}} 就基本完成了。你还需要配置客户端来使用与默认端口不同的端口,这个问题有很多种解决方案,在这里我们只介绍两种。<br />
<br />
==== "Read from socket failed: connection reset by peer" 错误 ====<br />
<br />
使用最近版本的 openssh 连接到较旧的 ssh 服务器时有时会失败,并显示上述错误消息。这可以通过为该主机设置各种 [[#配置|客户端选项]] 来解决。有关下列选项的更多信息,请参阅 {{man|5|ssh_config}}。<br />
<br />
问题可能出在 {{ic|ecdsa-sha2-nistp*-cert-v01@openssh}} 椭圆曲线算法上。这些算法可以通过在 {{ic|HostKeyAlgorithms}} 里设置可用算法来排除那些算法。<br />
<br />
如果这不起作用,可能是秘钥列表太长了。设置 {{ic|Ciphers}} 来减少列表长度(少于 80 个字符应该可以)。同样的,也可以尝试缩短 {{ic|MACs}} 列表。<br />
<br />
参阅 openssh bug forum 上的 [http://www.gossamer-threads.com/lists/openssh/dev/51339 讨论]。<br />
<br />
=== "[your shell]: No such file or directory" / SSH 认证问题 ===<br />
对于这个问题,一个可能的原因是需要 SSH 客户端在 {{Ic|$SHELL}} 中提供绝对路径(例如可以通过 {{Ic|whereis -b [your shell]}} 得到),即使你的 shell 在 {{Ic|$PATH}} 里的某个路径中。<br />
<br />
==="Terminal unknown" 或 "Error opening terminal" 错误 ===<br />
如果你在登录时收到上述错误,这意味着服务器无法识别你的终端。使用 Ncurses 的应用程序(如 nano)可能会失败,并显示“Error opening terminal”。<br />
<br />
正确的解决方案是在服务器上安装客户端终端的 terminfo 文件。这会告诉服务器上的控制台程序如何正确地与终端进行交互。你可以使用 {{ic|$ infocmp}} 获得关于当前 terminfo 的信息,然后找出 [[Pacman#Querying_package_databases|哪个包包括了它们]]。<br />
<br />
如果你不能正常[[install|安装]]它,可以把 terminfo 复制到服务器上你的主目录里面:<br />
<br />
$ ssh myserver mkdir -p ~/.terminfo/${TERM:0:1}<br />
$ scp /usr/share/terminfo/${TERM:0:1}/$TERM myserver:~/.terminfo/${TERM:0:1}/<br />
<br />
重新登录、登出服务器后这个问题应该已经解决。<br />
<br />
==== TERM hack ====<br />
<br />
{{警告|这只能作为最后的手段。}}<br />
<br />
你可以在服务器上的环境(例如 {{ic|.bash_profile}})中简单地设置 {{ic|1=TERM=xterm}} 。这将消除错误并允许 ncurses 应用程序再次运行,但除非你的终端的控制序列与 xterm 完全匹配,否则可能会遇到奇怪的行为和图形界面问题。<br />
<br />
=== "Connection closed by x.x.x.x [preauth]" 错误 ===<br />
如果你在 sshd 的 log 里看到这条错误,请确保你已经设置了可用的 HostKey<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
=== id_dsa 被 OpenSSH 7.0 拒绝 ===<br />
<br />
出于安全原因,OpenSSH 7.0 弃用了 DSA 公钥。如果你必须启用它们,请[[#配置|设置]] {{ic|PubkeyAcceptedKeyTypes +ssh-dss}} 选项(http://www.openssh.com/legacy.html 没有提到这一点)。<br />
<br />
=== OpenSSH 7.0 的 "No matching key exchange method found" 错误 ===<br />
<br />
OpenSSH 7.0 弃用了 diffie-hellman-group1-sha1 密钥算法,因为它很弱并且在所谓 Logjam 攻击的理论范围内(参阅http://www.openssh.com/legacy.html)。如果特定主机需要这个密钥算法,ssh 会产生如下错误消息:<br />
<br />
Unable to negotiate with 127.0.0.1: no matching key exchange method found.<br />
Their offer: diffie-hellman-group1-sha1<br />
<br />
这个问题的最佳解决方案是将服务器升级/配置为不使用不推荐的算法。如果做不到这一点,可以配置[[#配置|客户端选项]] {{ic|KexAlgorithms +diffie-hellman-group1-sha1}} 强制客户端使用这个算法。<br />
<br />
=== 断开 SSH 连接时 tmux/screen 会话被关闭 ===<br />
<br />
如果进程在会话结束时被终止,那么你可能是用 ssh.socket 激活的,{{Pkg|systemd}} 注意到 SSH 会话进程退出,然后杀掉了 tmux/screen 进程。这种情况有两种解决方案。一种是通过使用 {{ic|ssh.service}} 来代替 {{ic|ssh.socket}} 来避免使用 socket 激活。另一个是在 {{ic|ssh@.service}} 的 Service 部分设置 {{ic|1=KillMode=process}}。<br />
<br />
在常规的 {{ic|ssh.service}} 里面 {{ic|1=KillMode=process}} 这个选项也是有用的,它可以在 service 停止或重启时防止 SSH 会话进程或 {{Pkg|screen}} 或 {{Pkg|tmux}} 进程被 kill 掉。<br />
<br />
=== SSH 会话无响应 ===<br />
<br />
SSH 响应 [[Wikipedia:Software_flow_control|流控制命令]] 中的 {{ic|XON}} 和 {{ic|XOFF}} 命令。 当你按 {{ic|Ctrl+s}} 时,它会冻结/挂起/停止响应。按 {{ic|Ctrl+q}} 恢复会话。<br />
<br />
== 参阅 ==<br />
<br />
* [[Wikipedia:Secure Shell]]<br />
* [http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
* [http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks<br />
* [https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure Secure Shell]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica_(Italiano)&diff=515049
Mathematica (Italiano)
2018-03-27T10:40:21Z
<p>Arisaka: Add zh-hans link.</p>
<hr />
<div>[[Category:Development (Italiano)]]<br />
[[Category:Mathematics and science (Italiano)]]<br />
[[en:Mathematica]]<br />
[[ja:Mathematica]]<br />
[[zh-hans:Mathematica]]<br />
{{Translateme|traduzione è obsoleta}}<br />
{{Related articles start (Italiano)}}<br />
{{Related|Scientific Applications (Italiano)}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab}}<br />
{{Related articles end}}<br />
<br />
Mathematica è un programma commerciale usato in campo scientifico, matematico e ingegneristico. Qui viene spiegato come installarlo.<br />
<br />
== Installazione ==<br />
=== Mathematica 6 ===<br />
==== Montare l'iso ====<br />
Un modo per montare l'iso di Mathematica è creare '''/media/iso''' e aggiungere la seguente riga a fstab:<br />
/<location/of/mathematica.iso> /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
Ora è pssibile montarla con:<br />
mount /media/iso<br />
==== Eseguire l'installer ====<br />
È possibile avviare l'installer andando in:<br />
/Unix/Installer<br />
Eseguire ./MathInstaller con:<br />
sh ./MathInstaller<br />
{{Nota|Se non si piazza '''sh''' davanti, poi si otterrà un errore riguardo a un cattivo interprete}}<br />
<br />
==== Font ====<br />
Aggiungere le cartelle contenenti i font Type1 e BDF alla propria FontPath. <br />
<br />
==== Risoluzione dei problemi ====<br />
Se si hanno problemi di resa dei font nei quali certi simboli non vengono mostrati (es. "/" appare come un rettangolo), provare a disinstallare il pacchetto "mathematica-fonts".<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 è più facile da installare.<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
Seguire le istruzioni.<br />
<br />
Per gli utenti KDE l'icona di Mathematica può apparire nella categoria Oggetti smarriti. Per risolvere eseguire il seguente comando da amministratore:<br />
<br />
sudo ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
<br />
=== Mathematica 8 ===<br />
<br />
==== Mathematica 8.0.1 ====<br />
<br />
C'è un pacchetto in [[AUR (Italiano)|AUR]] per Mathematica 8.0.1-2 reperibile [https://aur.archlinux.org/packages.php?ID=47077 qui].<br />
Lo script per l'installazione Mathematica_8.0.1_LINUX.sh è richiesto.<br />
<br />
== Altre risorse ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Sito ufficiale (en)]<br />
* [http://www.wolfram.com/support/ Supporto ufficiale (en)]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515048
Mathematica (简体中文)
2018-03-27T10:37:47Z
<p>Arisaka: Fiest commit, translated from English version.</p>
<hr />
<div>[[Category:Mathematics and science]]<br />
[[Category:简体中文]]<br />
[[Category:Mathematica (简体中文)]]<br />
[[en:Mathematica]]<br />
[[it:Mathematica]]<br />
[[ja:Mathematica]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|Scientific Applications (简体中文)}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab (简体中文)}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Mathematica|2018-03-27|495458}}<br />
<br />
[http://www.wolfram.com/mathematica/ Mathematica] 是用于科学,工程和数学领域的商业软件。在这里我们说明如何安装它。<br />
<br />
== 安装 ==<br />
<br />
由于 Mathematica 是专有软件,升级可能会产生成本,因此本节列出了不同可用版本的说明。<br />
<br />
=== Mathematica 6 ===<br />
<br />
==== 挂载 iso 文件 ====<br />
<br />
挂载 Mathematica {{ic|.iso}} 的一种方式是创建 {{ic|/media/iso}} 目录用于挂载,并在 [[fstab]] 中增加这几行:<br />
/''location/of/mathematica.iso'' /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
然后就可以这样挂载它:<br />
# mount /media/iso<br />
<br />
==== 运行安装程序 ====<br />
<br />
进入这个目录来启动安装程序:<br />
/Unix/Installer<br />
运行 ''MathInstaller'':<br />
sh ./MathInstaller<br />
{{注意|如果没有把 "sh" 放在前面,那么会得到一个关于解释器出错 (bad interpreter) 的错误信息。}}<br />
<br />
==== 字体 ====<br />
<br />
向 FontPath 里添加包含 Type1 和 BDF 字体的目录。<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 安装起来非常方便。<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
按照指示完成即可。<br />
<br />
KDE 用户注意,Mathematica 的图标可能会出现在 ''Lost & Found'' 分类里面。解决方法是以 root 用户身份运行下列命令:<br />
<br />
# ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
=== Mathematica 8 ===<br />
<br />
Mathematica 8 的一个问题是执行 WolframAlpha[ ] 函数时会出现崩溃,这个崩溃可以重现。Mathematica 的默认配置为,在设置如何连接到互联网以获取数据时,检测系统的代理设置。但是在调用库函数时存在一个 bug,最终会使 Mathematica 崩溃。解决方法是通过将 Mathematica 配置为“直接连接”到互联网来完全避免此库调用 (''Edit > Preferences > Internet Connectivity > Proxy Settings'')。这个错误已经报告给 Wolfram。<br />
<br />
=== Mathematica 10 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}} (需要旧版本)。需要 {{ic|Mathematica_10.XX.YY_LINUX.sh}} 安装脚本,从 Wolfram.com 或某大学的站点上下载。同时你还需要一个激活密钥。<br />
<br />
=== Mathematica 11 ===<br />
<br />
[[Install|安装]] {{AUR|mathematica}}。从 Wolfram Research 获取 {{ic|Mathematica_11.XX.YY_LINUX.sh}} 和激活密钥。成功的安装可能也会抛出一些不严重的错误:xdg-icon-resource, mkdir, xdg-desktop-menu 等。<br />
<br />
Mathematica 11 在 [https://reference.wolfram.com/language/ref/$UserDocumentsDirectory.html $UserDocumentsDirectory] 自动创建 'Wolfram Mathematica' 文件夹,Mathematica 根据 [[XDG user directories]] 自动设置了这个变量。<br />
<br />
== 疑难解答 == <br />
<br />
==== "Missing symbols" 错误 ====<br />
<br />
如果出现字体渲染问题,某些符号无法显示(比如 {{ic|/}} 显示为正方形),请尝试卸载 {{Pkg|font-mathematica}}。<br />
<br />
同时,尝试 [http://mathematica.stackexchange.com/questions/1158/invisible-conjugate-glyph-in-the-linux-frontend 这种] 方案。其中还说明了 Mathematica 版本 9 修复了这个问题。<br />
<br />
尝试让应用程序使用抗锯齿。<br />
对于 KDE 用户: ''System Settings > Application Appearance > Fonts > Use anti-aliasing (Enabled)''<br />
<br />
==== HiDPI / Retina 屏幕 ====<br />
<br />
如果你有一块 [[HiDPI]] 屏幕,比如 Apple Retina 屏幕,而且 Mathematica 里面的文字非常小,这样就能解决:<br />
<br />
* 打开 ''Edit → Preferences''<br />
* 在 ''Advanced'' 选项卡里单击 ''Open Option Inspector''<br />
* 在右侧的树状列表中找到 ''Formatting Options → Font Options → Font Properties''<br />
* 改变 ''"ScreenResolution"'' 的值到它原来的两倍大小,比如 72 → 144。你也可以用 <code>xdpyinfo | grep resolution</code> 来获得一个更精确的数字(也要变成原来的两倍大小)。<br />
<br />
== 参阅 ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Official site]<br />
* [http://www.wolfram.com/support/ Official Support]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=Mathematica&diff=515047
Mathematica
2018-03-27T10:22:26Z
<p>Arisaka: Add zh-hans link</p>
<hr />
<div>[[Category:Mathematics and science]]<br />
[[it:Mathematica]]<br />
[[ja:Mathematica]]<br />
[[zh-hans:Mathematica]]<br />
{{Related articles start}}<br />
{{Related|Scientific Applications}}<br />
{{Related|Sage-mathematics}}<br />
{{Related|Matlab}}<br />
{{Related articles end}}<br />
<br />
[http://www.wolfram.com/mathematica/ Mathematica] is a commercial program used in scientific, engineering and mathematical fields. Here we explain how to install it.<br />
<br />
== Installation ==<br />
<br />
Since Mathematica is a non-free application and upgrades may incur costs, this section lists instructions for different available versions. <br />
<br />
=== Mathematica 6 ===<br />
<br />
==== Mounting iso ====<br />
<br />
One way to mount the Mathematica {{ic|.iso}} is to create a {{ic|/media/iso}} mount directory and add the following line to the [[fstab]]:<br />
/''location/of/mathematica.iso'' /media/iso iso9660 exec,ro,user,noauto,loop=/dev/loop0 0 0<br />
Now you can mount it with:<br />
# mount /media/iso<br />
<br />
==== Running the Installer ====<br />
<br />
You can start the installer by navigating to:<br />
/Unix/Installer<br />
Run ''MathInstaller'' with:<br />
sh ./MathInstaller<br />
{{Note|If you do not place the "sh" in front, then you will get an error about a bad interpreter.}}<br />
<br />
==== Fonts ====<br />
<br />
Add the directories containing Type1 and BDF fonts to your FontPath.<br />
<br />
=== Mathematica 7 ===<br />
<br />
Mathematica 7 is much easier to install.<br />
<br />
tar xf Mathematica-7.0.1.tar.gz<br />
cd Unix/Installer<br />
./MathInstaller<br />
<br />
Follow instructions.<br />
<br />
For KDE users, the Mathematica icon may appear in the ''Lost & Found'' category. To solve this, execute the following as root:<br />
<br />
# ln -s /etc/xdg/menus/applications-merged /etc/xdg/menus/kde-applications-merged<br />
<br />
=== Mathematica 8 ===<br />
<br />
An issue with Mathematica 8 is a reproducible crash when performing WolframAlpha[] functions. By default, Mathematica is configured to detect the system's proxy settings when configuring how to connect to the internet to fetch data. A "bug" exists that will eventually crash Mathematica when the calling library is used. A workaround is to avoid this library call altogether by configuring Mathematica to "directly connect" to the internet. (''Edit > Preferences > Internet Connectivity > Proxy Settings''). This bug has been reported to Wolfram.<br />
<br />
=== Mathematica 10 ===<br />
<br />
[[Install]] {{AUR|mathematica}} (need historical version). The {{ic|Mathematica_10.XX.YY_LINUX.sh}} installation script is required; you will need to download this separately from Wolfram.com, your university, etc. You will also need an activation key.<br />
<br />
=== Mathematica 11 ===<br />
<br />
[[Install]] {{AUR|mathematica}}. Obtain {{ic|Mathematica_11.XX.YY_LINUX.sh}} from Wolfram Research, along with an activation key. Successful install may throw non-critical errors: xdg-icon-resource, mkdir, xdg-desktop-menu.<br />
<br />
Mathematica 11 automatically creates a document folder 'Wolfram Mathematica' in [https://reference.wolfram.com/language/ref/$UserDocumentsDirectory.html $UserDocumentsDirectory], which is set by Mathematica according to [[XDG user directories]].<br />
<br />
== Troubleshooting == <br />
<br />
==== Missing symbols ====<br />
<br />
If you have font rendering problems where certain symbols do not show up (i.e. {{ic|/}} appears as a square), try uninstalling {{Pkg|font-mathematica}}.<br />
<br />
Also, try [http://mathematica.stackexchange.com/questions/1158/invisible-conjugate-glyph-in-the-linux-frontend this] solution. It also states the issue is fixed with Mathematica version 9.<br />
<br />
Try having applications use anti-aliasing. <br />
For KDE: ''System Settings > Application Appearance > Fonts > Use anti-aliasing (Enabled)''<br />
<br />
==== HiDPI / Retina Screens ====<br />
<br />
If you have a [[HiDPI]] screen, such as an Apple Retina display, and the main text in Mathematica looks small when you open it, this can be fixed:<br />
<br />
* Go to ''Edit → Preferences''<br />
* From the ''Advanced'' tab, click ''Open Option Inspector''<br />
* In the tree on the right, go to ''Formatting Options → Font Options → Font Properties''<br />
* Change the value for ''"ScreenResolution"'' to double its current setting, e.g. 72 → 144. You can also use <code>xdpyinfo | grep resolution</code> to get a more precise number (which will need to be doubled).<br />
<br />
== See also ==<br />
<br />
* [http://www.wolfram.com/mathematica/ Official site]<br />
* [http://www.wolfram.com/support/ Official Support]</div>
Arisaka
https://wiki.archlinux.org/index.php?title=ArchWiki:Translation_Team_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515041
ArchWiki:Translation Team (简体中文)
2018-03-27T06:02:13Z
<p>Arisaka: Update translate status info about “Secure Shell”</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:ArchWiki (简体中文)]]<br />
[[ar:ArchWiki Translation Team]]<br />
[[cs:ArchWiki Translation Team]]<br />
[[el:ArchWiki Translation Team]]<br />
[[en:ArchWiki Translation Team]]<br />
[[es:ArchWiki Translation Team]]<br />
[[fr:ArchWiki Translation Team]]<br />
[[hr:ArchWiki Translation Team]]<br />
[[it:ArchWiki Translation Team]]<br />
[[ja:ArchWiki 翻訳チーム]]<br />
[[ko:ArchWiki Translation Team]]<br />
[[nl:ArchWiki Translation Team]]<br />
[[pl:ArchWiki Translation Team]]<br />
[[pt:ArchWiki Translation Team]]<br />
[[ru:ArchWiki Translation Team]]<br />
[[sk:ArchWiki Translation Team]]<br />
Arch Wiki 上有许多中文页面,这其中大部分是从外文翻译过来的,这些页面是无数中文志愿者劳动的结晶。随着时间推移,有些页面因为没有及时维护,内容严重过时。而目前的翻译工作缺少组织,效率偏低。所以参照西班牙和意大利翻译组的做法,添加这个页面。<br />
<br />
如果你希望对Arch Wiki做贡献,参与Wiki建设,比如翻译英文页面和对已翻译过的中文页面进行维护,只需要编辑下面的[[#页面维护列表]],添加相应的条目,并将自己加为相关页面的维护者。如果你在列表中还没有找到想要翻译的页面,可以自行添加。另外,如果因为时间原因无法再维护页面,请及时将自己从维护者列表中删除。<br />
<br />
== 创建翻译 ==<br />
{{注意|如果不准备翻译页面的大部分内容,请尽量不要新建简体中文页面。检查英文页面的更新需要花费不少精力,没有翻译的页面会增加维护负担。}}<br />
# 如果还不知道如何编辑 wiki,请阅读 [[Help:Editing (简体中文)|编辑帮助]]。<br />
# 阅读 [[Help:i18n (简体中文)|i18n帮助]],文章给出了 ArchWiki 国际化和本地化的指南。<br />
# [[Special:UserLogin|登录]] 以进行编辑。<br />
# 选择要翻译的页面,例如从 [[Special:Random|随机页面]] 或[[#页面维护列表|页面维护列表]] 中选择一个未翻译完成的页面。假设要翻译 [[Some Page]].<br />
# 进入选择的英文页面,点击页面顶部的 '''编辑'''。<br />
# 添加要翻译文件的语言间链接, 简体中文的话加入<nowiki>[[zh-hans:Some Page]]</nowiki>,其它语言参见[[Help:i18n#Interlanguage links]])。<br />
# 复制所有页面代码。<br />
# 保存页面 (新加了语言链接)<br />
# 访问页面左边新添加的语言链接,应该会进到 [[Some Page (简体中文)]] : {{ic|<nowiki>https://wiki.archlinux.org/index.php/Some_Page_(</nowiki>''简体中文'')}}<br />
# 因为页面不存在,点击 '''创建'''。<br />
# 将显示一个编辑器 - 粘贴复制的英文页面。<br />
# 将文章分类修改为本地化版本,例如将 {{ic|<nowiki>[[Category:Internationalization]]</nowiki>}} 修改为 {{ic|<nowiki>[[Category:Internationalization (简体中文)]]</nowiki>}},参阅[[Help:Category (简体中文)]].<br />
# 修改语言间链接,指向英文页面(将 {{ic|zh-hans}} 修改为 {{ic|en}},并将英文页面移到文章顶部。<br />
# 翻译页面,进行保存。<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
# 更新所有其它语言页面,加入刚翻译文章的语言间链接。<br />
# (可选)创建一个简体中文名称的页面,指向新创建的页面:访问 {{ic|<nowiki>https://wiki.archlinux.org/index.php/</nowiki>''页面的中文名称''}}.<br />
# (可选)建立新页面,并加入:{{bc|<nowiki>#REDIRECT [[Some Page (简体中文)</nowiki>]]}}<br />
<br />
== 完善翻译 ==<br />
[https://wiki.archlinux.org/index.php?title=Special:WhatLinksHere/Template:Translateme_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&limit=100 这个页面] 包含了需要完善翻译的简体中文页面。完善翻译的基本步骤:<br />
# 选择自己比较熟悉的文章进行翻译<br />
# 先检查英文页面的对应段落,更新成最新的英文后再翻译,避免翻译过时的内容,减少信息遗漏。<br />
# 翻译完成后删除页面中的 <nowiki>{{translateme (简体中文)}}</nowiki> 标记<br />
# (推荐)给翻译完成的页面加上[[Template:TranslationStatus (简体中文)|翻译状态]],后有详细介绍。<br />
<br />
== 更新过期页面 == <br />
如果发现有 Wiki 页面过期或错误:<br />
* 小的改动,有时间可以立即进行修改同步,维护者并不控制页面的编辑权限,越多的人参与维护越好。如果改动较大,请先联系维护者,避免重复劳动。<br />
* 没有时间查看更改,请给页面加上 {{ic|<nowiki>{{out of date}}</nowiki>}} 模版,这样其他贡献者更容易发现需要更新的页面,而读者看到过期标记就可以直接查看英文页面,以免被错误内容误导,白白耽误时间。<br />
* 没有时间翻译,请将过期的中文部分删去,从英文页面中复制更改的部分到中文页面的相应部分,去掉{{ic|<nowiki>{{out of date}}</nowiki>}}模板(如果页面上有的话)并加上{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他贡献者就更容易发现需要翻译的页面,而读者也不会被过期的内容误导。<br />
如果发现有页面未翻译:<br />
* 有时间的话,请将页面中的英文部分翻译为中文,并去掉{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板。<br />
* 没有时间翻译,请为页面添加{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板,这样其他的贡献者就能更容易发现需要翻译的页面。<br />
{{注意|在修改页面上的模板时,请同时更新页面维护列表的翻译状态。}}<br />
<br />
== 翻译任务 ==<br />
=== 模板 Article summary 变更为 Related ===<br />
因为 Summary 中的简介基本上和正文的介绍一样,所以页面左边的介绍栏进行了简化,只保留相关文章功能。英文页面正在进行大规模修改,相应的中文页面也需要同步更新。<br />
<br />
需要注意的地方:<br />
* 将第一行改成<br />
: <nowiki>{{Related articles start (简体中文)}}</nowiki><br />
* 如果英文的相关文章存在中文翻译,则替换为简体中文页面。示例:<br />
: <nowiki>{{Related2|Display Manager (简体中文)|显示管理器}}</nowiki><br />
* 示例:[https://wiki.archlinux.org/index.php?title=Start_X_at_Login&diff=0&oldid=270155 英文变更], [https://wiki.archlinux.org/index.php?title=Start_X_at_Login_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=285643&oldid=242662 对应的翻译]<br />
<br />
== 维护翻译 ==<br />
完成页面的翻译只是初步完成任务,及时同步英文页面改动、更新翻译是一个持续性的工作,可能会耗费更多的时间。<br />
<br />
=== 页面认领 ===<br />
所有人都可以认领页面。认领后的责任包括进行翻译,关注英文页面的改动,及时同步翻译。<br />
<br />
为了更好的跟踪英文页面的修改,请务必在设置中启用监视列表邮件通知,并监视对应的英文页面(从设置中找到监视列表,加入英文页面。或者直接到英文页面点击页面顶端的监视标签。这样只要有改动,就会收到邮件通知)。<br />
<br />
{{小贴士|如果收到邮件通知后没有访问页面或者访问了页面却没有登录用户,下次页面改动时就不会再发邮件通知。可以点击监视列表中的'''标记所有页面为已读'''再次获取更新。}}<br />
<br />
如果页面有维护者但长期得不到更新,将会在维护列表中删除维护者。<br />
<br />
=== 翻译状态模板 ===<br />
Arch 作为滚动发行版,软件变化比较快,对应的文档变化也比较快。许多翻译的文章由于缺乏更新,会产生命令运行出错或不起作用等问题。而由于这些过期页面没有及时标记出来,所以用户无法及时获得更新。[[Template:TranslationStatus (简体中文)|翻译状态模板]]就是为了解决这个问题而创建。<br />
<br />
此模板可以起到如下作用:<br />
* 为用户提供翻译状况,包括翻译时间、英文页面的最后版本等<br />
* 用户可以点击查看翻译后,英文页面的改动,这样英文不是很好的用户可以只查看很小一部分英文内容,并判断出是否影响操作。<br />
* 翻译人员可以跟踪页面状况,通过[[Special:WhatLinksHere/Template:TranslationStatus_(简体中文)|模板的反向链接]]可以查找到所有标记页面,查看需要更新翻译的部分。<br />
<br />
[[Template:TranslationStatus (简体中文)|模板页面]]有详细的使用方法。<br />
<br />
=== 页面维护列表 ===<br />
{{注意|请按照拉丁字母顺序添加页面。}}<br />
<br />
翻译状态说明:<br />
;过期:页面内容未与英文页面同步,对应{{ic|<nowiki>{{out of date}}</nowiki>}} 模版<br />
;未翻译:页面中含有英文内容,对应{{ic|<nowiki>{{translateme (简体中文)}}</nowiki>}}模板<br />
;完成:页面已与英文页面同步<br />
<br />
{| class="wikitable sortable collapsible" border="1"<br />
|-<br />
! 页面<br />
! 翻译状态<br />
! 维护者<br />
! class="unsortable" width="30%" | 备注<br />
|-<br />
| [[AMD Catalyst (简体中文)]]<br />
| 过期<br />
| Shibao Zhao<br />
| 无<br />
|-<br />
| [[acpid (简体中文)]]<br />
| 过期<br />
| Cael<br />
|<br />
|-<br />
| [[Advanced Linux Sound Architecture (简体中文)]]<br />
| 翻译中<br />
| ihonliu<br />
| 无<br />
|-<br />
| [[Arch based distributions (active) (简体中文)]]<br />
| 完成<br />
| Joshua<br />
| 勘误中<br />
|-<br />
| [[ATI (简体中文)]]<br />
| 完成<br />
| skysailing<br />
| 无<br />
|-<br />
| [[AUR helpers (简体中文)]]<br />
| 进行中<br />
| Stonex<br />
| 无<br />
|-<br />
| [[awesome (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无<br />
|-<br />
| [[BIND (简体中文)]]<br />
| 完成<br />
| Dargasia<br />
|<br />
|-<br />
| [[Bumblebee (简体中文)]]<br />
| 完成<br />
| Peter<br />
| 无<br />
|-<br />
| [[Chromium (简体中文)]]<br />
| 完成<br />
| Bobby<br />
| 无<br />
|-<br />
| [[Ceph (简体中文)]]<br />
| 翻译中<br />
| Aaron Chen<br />
| 部分未翻译 <br />
|-<br />
| [[Cinnamon (简体中文)]]<br />
| 部分翻译 <br />
| Bobby<br />
| 部分未翻译 <br />
|- <br />
| [[Common Applications (简体中文)]]<br />
| 部分翻译 <br />
| DavidChen<br />
| 翻译中<br />
|-<br />
| [[Common Applications/Science (简体中文)]]<br />
| drop maintain<br />
| 更新,翻译中<br />
|<br />
|-<br />
| [[Compiz (简体中文)]]<br />
| 翻译中<br />
| xiii_1991<br />
| 20140813开始<br />
|-<br />
| [[Core utilities (简体中文)]]<br />
| 翻译中<br />
| rentaro<br />
| 同步翻译至2014年7月23日08:13英文页面,完善中<br />
|-<br />
|-<br />
| [[Clover (简体中文)]]<br />
| 完成<br />
| Yume Kankawa<br />
| 无<br />
|-<br />
| [[Disk cloning (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Dynamic Kernel Module Support (简体中文)]]<br />
| 完成<br />
| Mithrandir<br />
| 完善中<br />
|-<br />
| [[Emacs (简体中文)]]<br />
| 翻译中<br />
| Jaurung yuanhang<br />
| 未完成<br />
|-<br />
| [[File recovery (简体中文)]]<br />
| 翻译中<br />
| _spaike97<br />
| 无<br />
|-<br />
| [[Font configuration (简体中文)]]<br />
| 翻译中<br />
| Jaurung<br />
| 完善中<br />
|-<br />
| [[Fonts (简体中文)]]<br />
| 翻译中<br />
| qqbzg<br />
| 无<br />
|-<br />
| [[GNOME (简体中文)]]<br />
| 过期<br />
| <br />
| <br />
|-<br />
| [[KDE (简体中文)]]<br />
| 过期<br />
| <br />
| <br />
|-<br />
| [[LAMP (简体中文)]]<br />
| 完成<br />
| Liuzhengyi<br />
| 勘误中<br />
|-<br />
| [[LibreOffice (简体中文)]]<br />
| 完成<br />
| qqbzg<br />
| 勘误中<br />
|-<br />
| [[Local Mirror (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|- <br />
| [[Matlab (简体中文)]]<br />
| 部分翻译 <br />
| Liu Qinyang<br />
|<br />
|-<br />
| [[NetworkManager (简体中文)]]<br />
| 翻译中 <br />
| Jack-lijing, leeking <br />
| 请优先翻译<br />
|-<br />
| [[Network Time Protocol daemon (简体中文)]]<br />
| 完成<br />
| sid<br />
| 完善中<br />
|-<br />
| [[OpenOffice (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Opera (简体中文)]]<br />
| 未翻译<br />
| Bobby<br />
| 请优先翻译此文 <br />
|-<br />
| [[Pacman GUI Frontends (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Pidgin (简体中文)]]<br />
| 进行中<br />
| Cael<br />
| 无 <br />
|- <br />
| [[ranger (简体中文)]]<br />
| 完成<br />
| Jason Zhang<br />
| 完善中<br />
|-<br />
| [[Raspberry Pi (简体中文)]]<br />
| 翻译中<br />
| Mithrandir<br />
| <br />
|-<br />
| [[Reporting bug guidelines (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[Secure Shell (简体中文)]]<br />
| 完成<br />
| Arisaka<br />
| 等待校对<br />
|-<br />
| [[Smart Common Input Method platform (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Systemd-timesyncd (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[Tomcat (简体中文)]]<br />
| 完成<br />
| Starwing117<br />
| 持续更新中 <br />
|-<br />
| [[Vim (简体中文)]]<br />
| 完成<br />
| 无<br />
| 无<br />
|-<br />
| [[VirtualBox (简体中文)]]<br />
| 翻译至 2017-10-15<br />
| [[User:5long]]<br />
|<br />
|-<br />
| [[VMware (简体中文)]]<br />
| 完成<br />
| ThomasWFan<br />
| 页面已经与英文版同步,长期维护中<br />
|- <br />
| [[Xfce (简体中文)]]<br />
| 完成 <br />
| 无<br />
| 无<br />
|-<br />
| [[Xmonad (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Xrandr (简体中文)]]<br />
| 过期<br />
| 无<br />
| 无<br />
|-<br />
| [[Python打包指引 (简体中文)]]<br />
| 翻译中<br />
| SherlockHolo<br />
| 无</div>
Arisaka
https://wiki.archlinux.org/index.php?title=OpenSSH_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)&diff=515040
OpenSSH (简体中文)
2018-03-27T05:52:19Z
<p>Arisaka: 完全翻译了英文页面 Secure_Shell</p>
<hr />
<div>[[Category:简体中文]]<br />
[[Category:Secure Shell (简体中文)]]<br />
[[de:SSH]]<br />
[[en:Secure Shell]]<br />
[[es:Secure Shell]]<br />
[[fa:SSH]]<br />
[[fr:ssh]]<br />
[[ja:Secure Shell]]<br />
[[ru:Secure Shell]]<br />
{{Related articles start (简体中文)}}<br />
{{Related|SSH keys (简体中文)}}<br />
{{Related|Pam abl}}<br />
{{Related|fail2ban}}<br />
{{Related|sshguard}}<br />
{{Related|SSHFS (简体中文)}}<br />
{{Related|Syslog-ng}}<br />
{{Related|SFTP chroot}}<br />
{{Related|SCP and SFTP}}<br />
{{Related articles end}}<br />
<br />
{{TranslationStatus (简体中文)|Secure Shell|2018-03-27|514713}}<br />
<br />
'''Secure Shell''' ('''SSH''') 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议。加密保证了数据的保密性和完整性。SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用户。<br />
<br />
SSH 通常用于远程访问和执行命令,但是它也支持隧道,转发任意 TCP 端口以及 X11 连接;它还能够用 SFTP 或 SCP 协议来传输文件。<br />
<br />
一个 SSH 服务器默认情况下,在 TCP 端口 22 进行监听。一个 SSH 客户端程序通常被用来建立一个远程连接到 '''sshd''' 守护进程。这两者都被广泛地存在于现代操作系统中,包括 Mac OS X,GNU/Linux,Solaris 和 OpenVMS 等。以专有软件、自由软件以及开源版本的形式和不同的复杂性和完整性存在。<br />
<br />
(来源:[[Wikipedia:Secure Shell|维基百科 Secure Shell]])<br />
<br />
== OpenSSH ==<br />
<br />
OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密通讯会话的计算机程序。它被创建为 SSH Communications Security 公司拥有专利的 Secure Shell 软件套装的一个开源替代。OpenSSH 是由 Theo de Raadt 领导的 OpenBSD 项目的一部分。 <br />
<br />
人们常把 OpenSSH 与相似名字的 OpenSSL 搞混,但是,这两个项目是由不同的团队出于不同的目的开发出来的。相似的名字只是由于相似的目标。<br />
<br />
=== 安装OpenSSH ===<br />
从[[官方源]]中[[安装]] {{pkg|openssh}}.<br />
<br />
<br />
===SSH 客户端===<br />
<br />
连接SSH服务器,运行命令<br />
<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
<br />
如果服务器仅允许使用密钥登录,请参考 [[SSH keys (简体中文)|SSH Keys]] 。<br />
<br />
====配置====<br />
<br />
客户端可以在配置文件中存储常用选项和常用主机,下列选项都可以应用至全局或应用至特定主机。 例如:<br />
<br />
{{hc|~/.ssh/config|# global options<br />
User ''user''<br />
<br />
# host-specific options<br />
Host myserver<br />
HostName ''server-address''<br />
Port ''port''}}<br />
<br />
进行了如上的配置后,以下命令是等效的<br />
$ ssh -p ''port'' ''user''@''server-address''<br />
$ ssh myserver<br />
<br />
查看 {{man|5|ssh_config}} 获取更多信息。<br />
<br />
某些选项没有命令行参数,但是可以使用 {{ic|-o}} 在命令行中配置指定选项的参数。<br />
例如 {{ic|1=-oKexAlgorithms=+diffie-hellman-group1-sha1}}.<br />
<br />
===SSH 服务端===<br />
<br />
====配置====<br />
<br />
SSH 守护进程的配置文件是{{ic|/etc/ssh/ssh'''d'''_config}}。<br />
<br />
只允许某些用户访问的话,加入这一行:<br />
AllowUsers ''user1 user2''<br />
<br />
只允许一些组访问:<br />
AllowGroups ''group1 group2''<br />
<br />
你也可以运行以下命令关联文件(如{{ic|/etc/issue}}文件)到登录欢迎信息:<br />
Banner /etc/issue<br />
<br />
公钥和私钥在 ''sshd'' [[#管理 sshd 守护进程|service 文件]] 安装的时候就已经生成在 {{ic|/etc/ssh}} 里面了,秘钥对由四种算法生成: [[SSH_keys#Choosing_the_authentication_key_type|dsa、rsa、ecdsa 和 ed25519]]。如果你需要使用一组特定的秘钥,可以如下手动配置:<br />
<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
如果此服务器在公网中,建议运行以下命令以更改sshd服务监听端口:<br />
Port 39901<br />
<br />
参考 [[Wikipedia:List of TCP and UDP port numbers|TCP 和 UDP 端口号列表]] 和本地的 {{ic|/etc/services}} 文件来选择一个未被常用服务占用的端口。尽管 ssh 的运行端口可以被像 nmap 这样的端口扫描器侦测到,但改变它可以减少由于自动验证的尝试造成的登录日志条目,更多信息请参考 [[Port knocking]]。<br />
<br />
{{注意|OpenSSH 可以监听多个端口,只需在配置文件中加入多行{{ic|Port ''port_number''}}即可。}}<br />
<br />
完全取消密码登录方式可以极大的增强安全性,请查看[[#强制公钥验证]]。查看[[#安全防护]]了解更多增强安全性的手段。<br />
<br />
==== 管理 sshd 守护进程 ====<br />
<br />
{{Pkg|openssh}} 包括了两种 [[systemd]] 服务:<br />
#{{ic|sshd.service}},使 SSH 守护进程始终运行,并为每个入站连接创建子进程。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh#n16] 适用于有大量 SSH 流量的系统。[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n15] <br />
#{{ic|sshd.socket}} + {{ic|sshd@.service}}, 为每个连接生成 SSH 守护进程的实例。它意味着让 ''systemd'' 监听 SSH socket,并且只有在有连接传入时启动守护进程。几乎所有情况下都推荐使用{{ic|sshd}}。 [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/sshd.service?h=packages/openssh&id=4cadf5dff444e4b7265f8918652f4e6dff733812#n18][http://lists.freedesktop.org/archives/systemd-devel/2011-January/001107.html][http://0pointer.de/blog/projects/inetd.html]<br />
<br />
[[start]] 并 [[enable]] {{ic|sshd.service}} '''或''' {{ic|sshd.socket}} 中的任何一个都可以启动守护进程。<br />
<br />
如果选择了 sshd.socket,并且不在默认的 22 端口监听,你需要[[edit|编辑]] ststemd 单元文件:<br />
<br />
{{hc|# systemctl edit sshd.socket|<nowiki><br />
[Socket]<br />
ListenStream=<br />
ListenStream=12345<br />
</nowiki>}}<br />
<br />
{{警告|使用 {{ic|sshd.socket}} 会使 {{ic|ListenAddress}} 设置无效,这将允许来自任何地址的连接。为了达到与 {{ic|ListenAddress}} 一样设置 IP 的效果, 你必须在 {{ic|ListenStream}} 中指定端口''和'' IP (例如:{{ic|1=ListenStream=192.168.1.100:22}})。你还需要在 {{ic|[Socket]}} 下面增加 {{ic|1=FreeBind=true}},否则设置 IP 与设置 {{ic|ListenAddress}} 有着相同的缺陷:如果网络未及时启动,socket 将无法启动。}}<br />
<br />
{{提示|打开 {{ic|sshd.service}} 时将为每个连接启动一个 {{ic|sshd@.service}} 的临时实例(实例名称不同)。因此,{{ic|sshd.socket}} 和常规 {{ic|sshd.service}} 都不允许监视日志中的连接尝试。使用 {{ic|journalctl -u "sshd@*"}} 或 {{ic|journalctl /usr/bin/sshd}} 可以看到 socket 激活的 SSH 实例的日志。}}<br />
<br />
==== 安全防护 ====<br />
<br />
允许通过SSH进行远程登录对管理服务器很有用,但也会对服务器构成安全威胁。SSH 通常是暴力攻击的目标,因此 SSH 访问需要适当限制,以防止第三方访问您的服务器。<br />
<br />
下列是有关该主题的优秀指南:<br />
<br />
*[https://wiki.mozilla.org/Security/Guidelines/OpenSSH Article by Mozilla Infosec Team]<br />
*[https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure sshd]<br />
<br />
===== 强制公钥验证 =====<br />
<br />
如果客户端无法通过公钥进行身份验证,则默认情况下,SSH服务器将使用密码来验证,从而允许恶意用户通过[[#防止暴力破解|暴力破解]]密码获取访问权限。一种防止此类攻击的有效方法是完全禁用密码登录,并强制使用[[SSH keys]]。可以在 {{ic|sshd_config}} 中禁用以下选项:<br />
<br />
PasswordAuthentication no<br />
<br />
{{警告|在将上述选项添加到你的配置之前,请确保所有需要 SSH 访问的帐户都在相应的 {{ic|authorized_keys}} 文件中设置了公钥验证。请参阅 [[SSH keys#Copying the public key to the remote server]] 以获取更多信息。}}<br />
<br />
===== 双因素验证与公钥 =====<br />
<br />
自 OpenSSH 6.2 起,你可以使用 {{ic|AuthenticationMethods}} 选项添加自己的钥匙串进行身份验证。这使你可以用公钥与双因素验证结合来登录。<br />
<br />
参阅 [[Google Authenticator (简体中文)]] 来设置 Google Authenticator。<br />
<br />
为了使 [[PAM (简体中文)]] 与 OpenSSH 协同工作, 编辑下列文件:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey keyboard-interactive:pam<br />
}}<br />
<br />
然后,你可以使用公钥'''或''' PAM 中设置的用户验证信息两者之一登录。<br />
<br />
另外,如果你想登录时同时验证公钥'''和''' PAM,请使用逗号而不是空格来分隔 AuthenticationMethods:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
ChallengeResponseAuthentication yes<br />
AuthenticationMethods publickey,keyboard-interactive:pam<br />
}}<br />
<br />
通过要求提供公钥'''和''' PAM 认证,你可能希望禁用密码登录:<br />
{{hc|/etc/pam.d/sshd|<br />
auth required pam_securetty.so #disable remote root<br />
#Require google authenticator<br />
auth required pam_google_authenticator.so<br />
#But not password<br />
#auth include system-remote-login<br />
account include system-remote-login<br />
password include system-remote-login<br />
session include system-remote-login<br />
}}<br />
<br />
===== 防止暴力破解 =====<br />
暴力破解的概念很简单,即某人不断尝试用大量随机产生的用户名和密码对来登录网页或服务器的某个服务(比如 SSH)。<br />
<br />
====== 使用 ufw ======<br />
<br />
请参阅 [[ufw#Rate limiting with ufw]].<br />
<br />
====== 使用 iptables ======<br />
<br />
{{Merge|Simple_stateful_firewall#Bruteforce_attacks|Out of scope, same technique as already described in the SSF.}}<br />
<br />
如果你已经在用 iptables,可以配置以下规则来保护 SSH 免受暴破。<br />
<br />
{{注意|此示例中 SSH 所用的 TCP 端口已经改为了 42660。}}<br />
<br />
在应用后面的规则之前,我们先新建一条规则链来记录并拒绝过多的连接请求:<br />
<br />
# iptables -N LOG_AND_DROP<br />
<br />
第一条规则将应用于预示 TCP 42660 端口有新连接的数据包:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --set --name DEFAULT --rsource<br />
<br />
下一条规则告诉 iptables 查找匹配前一条规则的数据包,这些数据包也来自已添加到监视列表中的主机。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -m state --state NEW -m recent --update --seconds 90 --hitcount 4 --name DEFAULT --rsource -j LOG_AND_DROP<br />
<br />
现在,让 iptables 决定如何处理 TCP 42660 端口的通信中不符合上述规则的数据包。<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 42660 -j ACCEPT<br />
<br />
我们向 LOG_AND_DROP 表增加如下规则,并使用 -j (jump) 参数将数据包的信息传递给日志记录工具。<br />
<br />
# iptables -A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7<br />
<br />
在按照第一条规则进行记录后,所有数据包将被丢弃。<br />
<br />
# iptables -A LOG_AND_DROP -j DROP<br />
<br />
====== 防止暴力破解的工具 ======<br />
<br />
你可以用类似 [[fail2ban]] 或 [[sshguard]] 的自动防暴破的脚本来阻挡攻击者。<br />
<br />
* 仅允许来自受信任位置的 SSH 入站连接。<br />
* 使用 [[fail2ban]] 或 [[sshguard]] 自动阻止多次密码验证失败的 IP 地址。<br />
* 使用 [https://github.com/jtniehof/pam_shield pam_shield] 来阻止在一定时间内执行过多登录尝试的 IP 地址。与 [[fail2ban]] 或 [[sshguard]]不同,该程序不考虑登录成功或失败。<br />
<br />
===== 禁用或限制 root 账户登录 =====<br />
{{Out of date|最新版本默认已禁用 root 账户登录。暂不清楚本节的哪些部分是多余的。}}<br />
<br />
允许 root 账户随意通过 SSH 登录通常是不安全的,有两种方法可以限制 root 账户通过 SSH 登录,从而提高安全性。<br />
<br />
====== 禁用 root 登录 ======<br />
<br />
Sudo 可以有选择地为需要 root 权限的操作提供相应的权限,且不需要登录 root 账户。这样即可关闭 root 登录,并且可以看做一种防范暴力攻击的安全措施,因为现在攻击者除了要猜测密码外还要猜测帐户名称。<br />
<br />
通过编辑 {{ic|/etc/ssh/sshd_config}} 中的 "Authentication" 一节可以使 SSH 屏蔽 root 用户登录,只要将 {{ic|#PermitRootLogin prohibit-password}} 改成 {{ic|no}} 并取消该行注释即可:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
PermitRootLogin no<br />
...<br />
}}<br />
<br />
然后 [[restart|重启]] SSH 守护进程。<br />
<br />
现在你将无法通过 root 账户登录,但仍可以用普通账户登录并使用 [[su]] 或者 [[sudo]] 来完成系统维护工作。<br />
<br />
====== 限制 root 登录 ======<br />
<br />
一些自动化的维护任务(比如远程备份整个系统)需要完整的 root 权限。要以安全的方式允许 root 登录而不是禁用它,可以只允许远程登录的 root 用户执行指定的命令,在 {{ic|~root/.ssh/authorized_keys}} 头部加上指定的密钥即可,例如:<br />
<br />
command="/usr/lib/rsync/rrsync -ro /" ssh-rsa …<br />
<br />
这样,任何用户持有该秘钥即可执行引号之间的命令。<br />
<br />
为了弥补因 root 用户名称暴露而导致受攻击的可能性增加,可以将以下命令加入 {{ic|sshd_config}}:<br />
<br />
PermitRootLogin forced-commands-only<br />
<br />
该设置不仅会限制 root 用户通过 SSH 执行的命令,还会禁用密码登录方式,强制 root 帐户使用公钥登录。<br />
<br />
如果不想限制 root 用户可执行的命令,可以仅关闭密码验证来强制使用公钥验证:<br />
<br />
PermitRootLogin without-password<br />
<br />
===== 保护 authorized_keys 文件 =====<br />
<br />
你可以阻止其他用户向该文件加入新公钥且通过新的公钥连接。<br />
<br />
把 {{ic|authorized_keys}} 文件的权限全部去掉,只保留读权限:<br />
<br />
$ chmod 400 ~/.ssh/authorized_keys<br />
<br />
为防止用户把权限改回来,可以对 {{ic|authorized_keys}} 文件采取 [[File permissions and attributes#chattr and lsattr|set the immutable bit(设为不可变)]] 操作。尽管如此,用户仍然可以重命名 {{ic|~/.ssh}} 并新建一个 {{ic|~/.ssh}} 目录和 {{ic|authorized_keys}} 文件。所以 {{ic|~/.ssh}} 目录也要设置 immutable bit。<br />
<br />
{{注意|如果你自己需要新增一个公钥,你需要先移除 {{ic|authorized_keys}} 文件的 immutable bit,并增加写权限,最后按上述步骤重新加密。}}<br />
<br />
== 其他 SSH 客户端与服务端 ==<br />
除了 OpenSSH,还有很多可用的 SSH [[Wikipedia:Comparison of SSH clients|客户端]] 和 [[Wikipedia:Comparison of SSH servers|服务端]]。<br />
<br />
=== Dropbear ===<br />
[[Wikipedia:Dropbear (software)|Dropbear]] 是一个 SSH-2 客户端与服务端。 {{Pkg|dropbear}} 可以从 [[official repositories|官方仓库]] 下载。<br />
<br />
它的命令行版客户端叫 dbclient。<br />
<br />
=== Mosh ===<br />
来自 Mosh [http://mosh.mit.edu/ 网站]:<br />
<br />
:Remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. Mosh is a replacement for SSH. It is more robust and responsive, especially over slow connections such as Wi-Fi, cellular, and long-distance.<br />
:翻译:允许“漫游”的远程终端,支持间歇性的连接,并提供对于用户按键的智能本地回馈和行编辑回馈。Mosh 是 SSH 的替代品。它更加强大而快速,特别针对诸如 Wi-Fi,移动网络和超远距离等慢速连接环境。<br />
<br />
[[Install|安装]] {{Pkg|mosh}} 这个包, 或安装最新版:{{AUR|mosh-git}}。<br />
<br />
Mosh 有一个未写入文档的命令行选项:{{ic|1=--predict=experimental}},它可以产生更有力的本地按键响应。对降低键盘输入视觉上的延迟确认感兴趣的用户可能更喜欢这个预测模式。<br />
<br />
{{提示|Mosh 从设计上就不允许你访问会话的历史记录,请考虑安装终端复用工具,如 [[tmux]] 或 [[screen]] 。}}<br />
<br />
== 提示与技巧 ==<br />
<br />
{{Accuracy|根据目前本文的布局,这部分看起来应该是通用的,但实际上大部分提供的技巧只能在 ''openssh'' 中使用。比如 ''dropbear'' (在 [[#Other SSH clients and servers]] 列表中) 不支持 SOCKS 协议。[https://en.wikipedia.org/wiki/Comparison_of_SSH_clients#Technical]}}<br />
<br />
=== 加密 Socks 通道 ===<br />
<br />
对于连接到各种不安全的无线网络上的笔记本电脑用户来说,这个是特别有用的!唯一所需要的就是一个一定程度上处于安全的地点的 SSH 服务器,比如在家里或办公室。用动态的 DNS 服务 [http://www.dyndns.org/ DynDNS] 也可能是很有用的,这样你就不必记住你的 IP 了。<br />
<br />
==== 第一步:开始连接 ====<br />
<br />
你只要执行这一个命令就能开始你的连接:<br />
<br />
$ ssh -TND 4711 ''user''@''host''<br />
<br />
这里的 {{Ic|''user''}} 是你在 {{Ic|''host''}} 这台 SSH 服务器上的用户名。它会让你输入密码,然后你就能连上了。 {{Ic|N}} 表示不采用交互提示,而 {{Ic|D}} 表示指定监听的本地端口(你可以使用任何你喜欢的数字),{{Ic|T}} 表示禁用伪 tty 分配。<br />
<br />
加了 {{Ic|-v}} (verbose) 标志以后的输出可以让你能够验证到底连了哪个端口。<br />
<br />
==== 第二步:配置你的浏览器(或其它程序) ====<br />
<br />
如果你没有配置你的浏览器(或其他程序)使用这个新创建的 socks 隧道,上述步骤是无效的。由于当前版本的 SSH 支持 SOCKS4 和 SOCKS5,因此您可以使用其中任何一种。<br />
<br />
* 对于 Firefox: ''Edit > Preferences > Advanced > Network > Connection > Setting'': <br> 选中 ''Manual proxy configuration'' 单选框, 然后在 ''SOCKS host'' 里输入 {{ic|localhost}}, 然后在后面那个框中输入你的端口号(本例中为 {{ic|4711}})。<br />
<br />
Firefox 不会自动通过 socks 隧道发送 DNS 请求,这一潜在的隐私问题可以通过以下步骤来解决:<br />
<br />
# 在 Firefox 地址栏中输入:about:config 。<br />
# 搜索:network.proxy.socks_remote_dns<br />
# 将该值设为 true。<br />
# 重启浏览器。<br />
<br />
* 对于 Chromium: 你可以将 SOCKS 设置设置为环境变量或命令行选项。我建议将下列函数之一加入到你的 {{ic|.bashrc}}:<br />
function secure_chromium {<br />
port=4711<br />
export SOCKS_SERVER=localhost:$port<br />
export SOCKS_VERSION=5<br />
chromium &<br />
exit<br />
}<br />
或者<br />
function secure_chromium {<br />
port=4711<br />
chromium --proxy-server="socks://localhost:$port" &<br />
exit<br />
}<br />
<br />
现在打开终端然后输入:<br />
<br />
$ secure_chromium<br />
<br />
享受你的安全隧道吧!<br />
<br />
=== X11 转发 ===<br />
<br />
为了通过 SSH 运行图形程序你必须使用 X11 转发 (forwarding)。这不要求对端安装了完整的 X11,但是至少要装好 ''xauth''。''xauth'' 是一个用来管理 {{ic|Xauthority}} 配置的工具,该配置用于服务器与客户端之间的 X11 会话认证([http://xmodulo.com/2012/11/how-to-enable-x11-forwarding-using-ssh.html source])。<br />
<br />
{{警告|X11 转发有着重要的安全问题需要考虑,至少应先阅读 {{man|1|ssh}}、{{man|5|sshd_config}} 和 {{man|5|ssh_config}} 手册页。也可以参考 [https://security.stackexchange.com/questions/14815/security-concerns-with-x11-forwarding 这个 StackExchange 帖]。}}<br />
<br />
==== 配置 ====<br />
<br />
在远程主机上:<br />
<br />
*[[install|安装]] {{Pkg|xorg-xauth}} 和 {{Pkg|xorg-xhost}} 这两个包<br />
*在 {{ic|/etc/ssh/ssh'''d'''_config}} 上:<br />
**确保 {{ic|AllowTcpForwarding}} 和 {{ic|X11UseLocalhost}} 已经设置为 ''yes'',并且 {{ic|X11DisplayOffset}} 设置为 ''10'' (这些是默认设置,参考 {{man|5|sshd_config}})<br />
**将 {{ic|X11Forwarding}} 设置为 ''yes''<br />
* 最后 [[restart|重启]] [[#Daemon management|''sshd'' 守护进程]].<br />
<br />
在客户端上,通过在命令行设置 {{ic|-X}} 参数启用 {{ic|ForwardX11}},或者在[[#配置|客户端配置文件]]中将 {{ic|ForwardX11}} 设置为 ''yes''。<br />
<br />
{{提示|如果 GUI 绘制不正常或者有错误提示,你可以启用 {{ic|ForwardX11Trusted}} 选项(或在命令行中加上 {{ic|-Y}} 参数),这将使 X11 转发脱离 [http://www.x.org/wiki/Development/Documentation/Security/ X11 SECURITY extension] 的控制,如果你这样做,请确保已经读过本节开头的[[#X11 转发|警告]]。}}<br />
<br />
==== 使用方法 ====<br />
<br />
{{Accuracy|{{ic|xhost}} [http://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-from-ubuntu-machine#comment-17148 通常不是必须的]}}<br />
<br />
正常登录远程主机,如果客户端的配置文件中没有启用 ''ForwardX11'' 那就加上 {{ic|-X}} 参数:<br />
$ ssh -X ''user@host''<br />
<br />
如果在运行图形程序的时候碰到错误,尝试用 ''ForwardX11Trusted'' 代替 ''ForwardX11'' :<br />
$ ssh -Y ''user@host''<br />
<br />
现在你应该可以运行服务器上的任何 X 图形程序,任何输出都会重定向至你当前的会话:<br />
$ xclock<br />
<br />
如果碰到 "Cannot open display" 的错误,请尝试用非管理员账户运行下列命令:<br />
$ xhost +<br />
<br />
上述命令将允许任何人转发 X11 应用程序,这个命令可以限制特定的主机类型:<br />
$ xhost +hostname<br />
<br />
其中 hostname 是要转发到的特定主机的名称。更多信息可以查看 {{man|1|xhost}}。<br />
<br />
请注意某些应用程序,它们会检查本地计算机上正在运行的实例。[[Firefox]] 就是其中之一:你可以关掉本机上的 Firefox 或者使用以下启动参数来启动远程实例:<br />
$ firefox --no-remote<br />
<br />
当你连接时收到 "X11 forwarding request failed on channel 0" 错误(或者服务器上的 {{ic|/var/log/errors.log}} 文件显示 "Failed to allocate internet-domain X11 display socket" 错误),请确保已经安装 {{Pkg|xorg-xauth}},如果装完了仍然不起作用,尝试以下方法之一:<br />
<br />
* 在''服务器''的 {{ic|ssh'''d'''_config}} 中启用 {{ic|AddressFamily any}} 选项,或者<br />
* 将''服务器''的 {{ic|ssh'''d'''_config}} 中的 {{ic|AddressFamily}} 选项设为 inet。<br />
将其设置为 inet 可能会修复 IPv4 上的 Ubuntu 客户端的问题。<br />
<br />
要以其他用户身份运行 SSH 服务器上的 X 应用程序,你需要先用已知用户登录,取出 {{Ic|xauth list}} 中的身份认证行,然后 {{Ic|xauth add}} 它。<br />
<br />
{{提示|[http://unix.stackexchange.com/a/12772/29867 这里] 是 [http://unix.stackexchange.com/a/46748/29867 一些] 用来诊断 {{ic|X11 Forwarding}} 问题有用的 [http://superuser.com/a/805060/185665 链接]。}}<br />
<br />
=== 转发其他端口 ===<br />
<br />
除了 SSH 内建的对 X11 的支持之外,它也能通过本地转发和远程转发,来为任何的TCP连接建立隧道。<br />
<br />
本地转发时,会在本机打开一个端口,连接将被转发到一个远程主机,并给定一个目的地。很多时候,转发目的地和远程主机会相同,因此也提供了一条SSH命令来建立一个安全的VNC连接。本地转发可以通过 {{Ic|-L}} 来设置,后面可以指定一个地址及端口 {{Ic|<tunnel port>:<destination address>:<destination port>}}。<br />
<br />
如下:<br />
<br />
$ ssh -L 1000:mail.google.com:25 192.168.0.100<br />
<br />
以上指令将会通过SSH得到一个在 192.168.0.100 的 shell,同时也会创建一个从本机 1000 端口到 mai.google.com 上的 25 端口的隧道。建立之后,localhost:1000 会通过 192.168.0.100 连接到 Gmail 的 SMTP 端口。任何从 192.168.0.100 到 mail.google.com:25 的连接(即使不必要)都会以这样的方式建立,并且,在本机和 192.168.0.100 之间的数据传递都是安全的,除非你采取了别的手段。<br />
<br />
同样:<br />
<br />
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100<br />
<br />
以上指令会将到 localhost:2000 的连接直接转发到远程主机 192.168.0.100 的 6001 端口。对于使用 VNC 服务器(tightvns包的一部分)建立的 VNC 连接来说,以上的例子尽管很有效,但是安全性有待商榷。<br />
<br />
远程转发允许任何远程主机通过 SSH 隧道连接到本机,提供了和本地转发相反的功能,突破了防火墙的限制。通过 {{Ic|-R}} 参数,以及 {{Ic|<tunnel port>:<destination address>:<destination port>}} 能够实现远程转发。<br />
<br />
如下:<br />
<br />
$ ssh -R 3000:irc.freenode.net:6667 192.168.0.200<br />
<br />
将会在 192.168.0.200 上得到一个 shell,同时也会创建一个从 192.168.0.200 上的 3000 端口到 irc.freenode.net 上的 6667 端口的隧道。建立之后,192.168.0.200:3000 会通过本机连接到 freenode 的 IRC 端口。到 192.168.0.200 的 3000 端口的连接将会通过隧道发送到本机然后转发到 irc.freenode.net 的 6667 端口。因此,在这个例子中,在远程主机上 IRC 程序能够被使用,即使端口 6667 被阻止。<br />
<br />
本地转发和远程转发都可以提供一个安全的"网关",允许其他计算机无需使用 SSH 或者 SSH daemon 来使用 ssh 隧道,即在隧道起点提供绑定的地址,作为转发规则。例如 {{Ic|<tunnel address>:<tunnel port>:<destination address>:<destination port>}}。{{Ic|<tunnel address>}} 可以是作为网关的机器上的任何地址,例如 {{Ic|localhost}}(仅允许本地访问),{{Ic|192.168.0.100}}(仅允许通过192.168.0.100访问), {{Ic|*}}(允许所有地址访问)。它们可以是通过本地环回端口,或是通过其他任何端口的连接。默认情况下,转发受到隧道“起点”的主机限制,即 {{Ic|<tunnel address>}} 被设置为 {{Ic|localhost}}。本地转发不需要额外的设置,而远程转发受限于对端的 SSH daemon 设置。请参阅 {{Ic|sshd_config(5)}} 中的 {{Ic|GatewayPorts}} 选项。<br />
<br />
=== 跳板机 ===<br />
<br />
在某些情况下,你与目标主机之间可能无法直接连接,此时就要用到跳板机。因此,我们尝试将两个或更多 SSH 隧道连接在一起,并假设您的本地密钥已针对链中的每个服务器授权。这可以通过使用SSH代理转发 ({{ic|-A}}) 和伪终端分配 ({{ic|-t}}) 来实现,它使用以下语法转发本地密钥:<br />
<br />
$ ssh -A -t -l user1 bastion1 \<br />
ssh -A -t -l user2 intermediate2 \<br />
ssh -A -t -l user3 target<br />
<br />
一个更简单的方法是使用 {{ic|-J}} 选项:<br />
<br />
$ ssh -J user1@bastion1,user2@intermediate2 user3@target<br />
<br />
<br />
{{ic|-J}} 指令中的多个主机可以用逗号隔开,它们将按照列出的顺序连接。{{ic|user...@}} 部分不是必需的,但可以使用。定义 {{ic|-J}} 选项里的不同的主机规格可以使用 ssh 配置文件,因此如果需要,可以在那里设置特定的每个主机选项。<br />
<br />
=== 通过中继反向 SSH 连接 ===<br />
<br />
{{Style|SSH 隧道的设想是很经典的,所以添加一些参考资料的详细解释会更好。比如 [https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work/118650#118650] 涵盖了一些其他情况。}}<br />
<br />
这个想法是客户端通过一个中继连接到服务器,而服务器使用反向 SSH 隧道连接到同一个中继。例如,当服务器位于 NAT 后面时,这是很有用的,而此处的中继是一个可公开访问的 SSH 服务器,用作用户有权访问的代理服务器。前提是客户端的密钥同时对中继和服务器都已经授权,服务器需要授权中继用于反向 SSH 连接。<br />
<br />
以下配置假设 user1 是客户端使用的账户,user2 是中继的,user3 是服务器的。首先服务器要先建立反向隧道:<br />
<br />
ssh -R 2222:localhost:22 -N user2@relay<br />
<br />
这可以利用启动脚本、systemd service 或者 {{Pkg|autossh}} 来自动完成。<br />
<br />
{{Expansion|需要解释为何光有 {{ic|ssh user3@relay -p 2222}} 是不够的。}}<br />
<br />
在客户端使用以下命令建立连接:<br />
<br />
ssh user2@relay ssh user3@localhost -p 2222<br />
<br />
可以在中继的 {{ic|~/.ssh/authorized_keys}} 中定义 {{ic|command}} 字段来建立反向隧道:<br />
<br />
command="ssh user3@localhost -p 2222" ssh-rsa KEY2 user1@client<br />
<br />
在这种情况下用下列命令建立连接:<br />
<br />
ssh user2@relay<br />
<br />
注意,客户端内 scp 的自动完成功能失效,甚至在某些配置下 scp 本身也无法工作。<br />
<br />
=== 端口复用 ===<br />
<br />
SSH 守护进程通常监听 22 端口,但是许多公共热点会屏蔽非常规 HTTP/S 端口(分别是 80 和 443 端口)的流量,这样就屏蔽了 SSH 连接。最快的解决方法是让 {{ic|sshd}} 额外监听白名单上的端口:<br />
<br />
{{hc|/etc/ssh/sshd_config|<br />
Port 22<br />
Port 443<br />
}}<br />
<br />
但是443端口很有可能已经被 HTTPS 服务占用,在这种情况下可以使用端口复用工具,比如 {{Pkg|sslh}},它可以监听在一个被复用的端口上并转发相应的数据包给对应的服务。<br />
<br />
=== 加速 SSH ===<br />
<br />
此处列出一些可以加速全部连接或针对某台主机加速的 [[#配置|客户端配置]] 选项。要了解这些选项的完整概述,请参阅 {{man|5|ssh_config}}。<br />
<br />
* 使用以下参数来使到某一台主机的所有回话 (sessions) 共享同一个连接: {{bc|<nowiki><br />
ControlMaster auto<br />
ControlPersist yes<br />
ControlPath ~/.ssh/sockets/socket-%r@%h:%p<br />
</nowiki>}}<br />
: 其中 {{ic|~/.ssh/sockets}} 可以是一个其他用户不可写入的任意目录。<br />
<br />
* {{ic|ControlPersist}} 指定在初始客户端连接关闭后,主服务器在后台等待新客户端的时间。可能的值是: <br />
** {{ic|no}} 指定在最后一个客户端断开后立即关闭连接,<br />
** 一个用秒数表示的时间,<br />
** {{ic|yes}} 连接不会自动关闭,而是始终处于等待。<br />
<br />
* 另一种加速的方法是通过 {{ic|Compression yes}} 选项或者 {{ic|-C}} 参数来启用压缩。<br />
: {{注意|{{man|1|ssh}} 指出:“在调制解调器线路或其他慢速线路上启用压缩是可取的,但在网速快的情况下只会降低速度。”这条提示可能会适得其反,具体取决于你的网络配置。}}<br />
<br />
* 通过使用 {{ic|AddressFamily inet}} 选项或者 {{ic|-4}} 参数来跳过 IPv6 查找,可以缩短登录时间。<br />
<br />
* 最后,如果你想用 SFTP 或 SCP,[https://www.psc.edu/index.php/hpn-ssh High Performance SSH/SCP] 可以通过动态提高 SSH 缓冲区大小来显著提高吞吐量。安装 {{AUR|openssh-hpn-git}} 这个包来使用打过这一增强补丁的 OpenSSH 版本。<br />
<br />
=== 用 SSHFS 挂载远程文件系统 ===<br />
<br />
请参阅 [[SSHFS]] 来将一个 SSH 可访问的远程文件系统挂载至一个本地目录,然后你就能在挂载好的文件上执行常规操作(复制,重命名,用 vim 编辑等等)。''sshfs'' 比 ''shfs'' 更好,因为后者自 2004 年起就没再更新。<br />
{{提示|软件包 {{AUR|autosshfs-git}} 可以用于在登录时自动运行 autosshfs。}}<br />
<br />
=== 保持在线 ===<br />
<br />
默认情况下,如果你的会话空闲了某个时间之后,它会自动登出。为了保持会话,在长时间没有数据传输时客户端可以向服务器发送一个激活信号。与之对应,服务器也可以在一段时间没有收到消息时定期发送一个信号。<br />
<br />
* 在 '''服务器''',{{ic|ClientAliveInterval}} 是没有从客户端收到消息后的超时时间,超时后 ''sshd'' 将会发送一个请求来等待回应。默认是 0,指不会发出请求。比如要求每隔 60 秒向客户端发送响应请求,在你的 [[#配置_2|服务器配置]] 里设置 {{ic|ClientAliveInterval 60}} 即可。{{ic|ClientAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
* 在 '''客户端''',{{ic|ServerAliveInterval}} 控制着从客户端发往服务器的响应请求的时间间隔。比如要求服务器每隔 120 秒响应一次,在你的 [[#配置|客户端配置]] 里加入 {{ic|ServerAliveInterval 120}} 即可。{{ic|ServerAliveCountMax}} 和 {{ic|TCPKeepAlive}} 选项也可以参考一下。<br />
<br />
{{注意| 为确保会话保持活动状态,客户端或服务器中只有一个需要发送保持活动请求。如果用户同时控制服务器和客户端,那么合理的选择是使用 {{ic|ServerAliveInterval}} 选项配置需要保持会话的客户端,并保留其他客户端和服务器的默认配置。}}<br />
<br />
=== 利用 systemd 自动重启 SSH 隧道 ===<br />
<br />
[[systemd]] 可以在开机/登录时自动启动 SSH,''还可以'' 在 SSH 连接断开时自动重连。这使它成为管理 SSH 隧道的有力工具。<br />
<br />
下面的 service 可以使用 [[#配置|ssh 配置]] 里面的配置在你登录系统的时候自动开启一个 SSH 隧道。如果连接因为某种原因断开,它将会每隔10秒重启一下:<br />
<br />
{{hc|~/.config/systemd/user/tunnel.service|<nowiki><br />
[Unit]<br />
Description=SSH tunnel to myserver<br />
<br />
[Service]<br />
Type=simple<br />
Restart=always<br />
RestartSec=10<br />
ExecStart=/usr/bin/ssh -F %h/.ssh/config -N myserver<br />
</nowiki>}}<br />
<br />
然后 [[enable]] 并且 [[start]] 这个 user service。欲知如何防止连接超时,请参阅 [[#Keep alive]]。如果你想在系统引导后就打开这个连接,你需要将这个 unit 重写为 system service。<br />
<br />
=== Autossh - 自动重启 SSH 会话和隧道连接 ===<br />
<br />
当一个 SSH 会话或隧道无法保持连接(比如网络环境差导致客户端断线),可以使用 {{Pkg|autossh}} 来自动重启它们。<br />
<br />
使用范例:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" username@example.com<br />
<br />
结合 [[SSHFS]]:<br />
$ sshfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=45,ServerAliveCountMax=2,ssh_command='autossh -M 0' username@example.com: /mnt/example <br />
<br />
通过一个由 [[Proxy settings]] 设置好的 SOCKS 代理来连接:<br />
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" -NCD 8080 username@example.com <br />
<br />
使用 {{ic|-f}} 选项以后可以使 autossh 作为后台进程运行,然而以这种方式运行意味着不能交互输入密码。<br />
<br />
当你在会话中打出 {{ic|exit}} 即可结束会话,或者 autossh 收到了 SIGTERM, SIGINT of SIGKILL 信号。<br />
<br />
==== 利用 systemd 在引导后自动运行 autossh ====<br />
<br />
如果你想自动启动 autossh,创建一个 systemd unit 文件:<br />
<br />
{{hc|/etc/systemd/system/autossh.service|2=<br />
[Unit]<br />
Description=AutoSSH service for port 2222<br />
After=network.target<br />
<br />
[Service]<br />
Environment="AUTOSSH_GATETIME=0"<br />
ExecStart=/usr/bin/autossh -M 0 -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
}}<br />
<br />
其中 {{ic|1=AUTOSSH_GATETIME=0}} 是一个环境变量,它表示 ssh 需要连上多久,autossh 才判定这个连接是成功的。将它设为 0 后 autossh 也会忽略 ssh 的第一次运行失败。这在开机启动 autossh 时可能是有用的。其他环境变量可以在手册页找到。当然,如果需要的话,你可以使这个单元更加复杂(详情请参阅 systemd 文档),显然你可以使用自己的 autossh 选项,但请注意 {{ic|-f}} 选项意味着 {{ic|1=AUTOSSH_GATETIME=0}} 无法在 systemd 中起效。<br />
<br />
别忘了 [[start]] 且/或 [[enable]] 这个 service。<br />
<br />
你可能还会需要关闭 ControlMaster,像这样:<br />
<br />
ExecStart=/usr/bin/autossh -M 0 -o ControlMaster=no -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com<br />
<br />
{{提示|同时管理多个 autossh 进程也是很简单的,要保持多个隧道连接,只需要用不同的文件名创建多个 service 文件。}}<br />
<br />
=== 当 SSH 守护进程出错时的其他选择 ===<br />
<br />
对于仅依赖 SSH 的远程或无头服务器,启动 SSH 守护程序失败(例如系统升级后)可能会阻止管理员访问。[[systemd]] 通过 {{ic|OnFailure}} 选项提供了简便的解决方案。<br />
<br />
假设服务器运行 {{ic|sshd}} 并且 [[telnet]] 是所选的故障安全替代方案。按如下所示创建一个文件。'''不要''' [[enable]] telnet.socket!<br />
<br />
{{hc|/etc/systemd/system/sshd.service.d/override.conf|2=<br />
[Unit]<br />
OnFailure=telnet.socket<br />
}}<br />
<br />
这样就行了。当 {{ic|sshd}} 正在运行时,Telnet 是不可用的。如果 {{ic|sshd}} 无法启动,可以打开一个 telnet 会话进行恢复。<br />
<br />
== 疑难解答 ==<br />
<br />
=== 自检清单 ===<br />
<br />
在进一步阅读前,请先仔细检查下面这些常见故障。<br />
<br />
# 配置文件存放目录 {{ic|~/.ssh}} 及目录下的文件应该只有你的账户才有访问权限(在客户端和服务器上都检查这一条): {{bc|<nowiki><br />
$ chmod 700 ~/.ssh<br />
$ chmod 600 ~/.ssh/*<br />
$ chown -R $USER ~/.ssh<br />
</nowiki>}}<br />
# 检查客户端的公钥(比如 {{ic|id_rsa.pub}})在服务器的 {{ic|~/.ssh/authorized_keys}} 文件里面。<br />
# 检查有没有在 [[#配置_2|服务器配置]] 里面设置 {{ic|AllowUsers}} 或 {{ic|AllowGroups}} 来限制 SSH 访问。<br />
# 检查用户是否设置了密码。有时还没有登录过服务器的新用户没有密码。<br />
# 把 {{ic|LogLevel DEBUG}} 加到 {{ic|/etc/ssh/sshd_config}} 文件尾部。<br />
# 使用 {{ic|journalctl -xe}} 查看可能的错误信息。<br />
# 在客户端和服务器上 [[Restart|重启]] {{ic|sshd}} 然后注销/重新登录。<br />
<br />
=== 拒绝连接或者超时问题 ===<br />
<br />
==== 端口转发 ====<br />
<br />
如果您位于 NAT 模式/路由器之后(除非您位于 VPS 或可公开寻址的主机上),请确保您的路由器可以将传入的 ssh 连接转发到您的计算机。使用 {{ic|$ ip addr}} 查找服务器的内网 IP 地址,并将您的路由器设置为将 SSH 端口上的 TCP 数据包转发到该 IP。[http://portforward.com portforward.com] 可以提供帮助。<br />
<br />
==== SSH服务是否开启并且正在监听? ====<br />
$ ss -tnlp<br />
<br />
如果以上的命令没有显示 SSH 端口是打开的,那么说明 SSH 服务没有启动。查看 {{ic|/var/log/messages}} 来寻找错误信息。<br />
<br />
==== 是否是防火墙阻止了连接? ====<br />
<br />
[[Iptables]] 可能会阻止 {{ic|22}} 端口的连接。使用 {{bc|# iptables -nvL}} 来检查可能会在 {{ic|INPUT}} 链上导致丢包的规则。必要情况下可以用以下命令来解锁端口:<br />
{{bc|<br />
# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT<br />
}}<br />
更多配置防火墙的信息,请参阅 [[firewalls]].<br />
<br />
==== 你的电脑和目的主机之间是否连接? ====<br />
测试你的电脑和目的主机的连接情况:<br />
<br />
# tcpdump -lnn -i any port ssh and tcp-syn<br />
<br />
它会显示一些基本信息,然后等待数据交换。现在尝试你的连接。如果没有输出,就可能是你的电脑网络阻塞了。(也许是防火墙问题,也许是 NAT 路由的问题)<br />
<br />
==== 你的 ISP 或第三方屏蔽了默认端口? ====<br />
{{注意|只有在你'''确保'''你没有运行任何防火墙,你已经在路由器上配置了 DMZ 主机或已经将端口映射到你的计算机,而这些都没有用的情况下才尝试以下步骤。可以在此找到诊断步骤或可能的解决方案。}}<br />
<br />
某些情况下,你的运营商会屏蔽默认端口(22 端口),无论怎么尝试(尝试开启端口、强化堆栈、防范洪水攻击)都无济于事。要确认确实存在屏蔽,只要创建一个接受任何来源(0.0.0.0)的服务器并远程连接它。<br />
<br />
如果你收到与此类似的错误消息:<br />
ssh: connect to host www.inet.hr port 22: Connection refused<br />
<br />
就表示你的 ISP '''没有'''屏蔽端口,但是服务器没有在该端口上运行 SSH 服务(请参阅 [[wikipedia:Security_through_obscurity|security through obscurity]])。<br />
<br />
但是,如果你收到与这条类似的错误消息:<br />
ssh: connect to host 111.222.333.444 port 22: Operation timed out <br />
<br />
这就表示有人阻止了 22 端口的 TCP 连接,基本上是通过防火墙或第三方干预(如 ISP 阻止和/或拒绝端口 22 上的传入通信),使得端口不可用。如果你的计算机上没有运行任何防火墙,并且在你的路由器和交换机中没有这方面的流量,那么你的 ISP 屏蔽了通讯。<br />
<br />
为了再次检查确认,可以在服务器上运行 Wireshark 并让它监听在 22 端口。由于 Wireshark 是一个二层数据包嗅探工具,而 TCP/UDP 工作在第三层及以上(参阅 [[wikipedia:Internet protocol suite|IP Network stack]]),如果在连接时未收到任何内容,则第三方很可能阻止了该端口上到服务器的流量。<br />
<br />
===== 诊断 =====<br />
<br />
[[Install|安装]] {{Pkg|tcpdump}} 或 Wireshark ({{Pkg|wireshark-cli}})。<br />
<br />
用于 tcpdump:<br />
<br />
# tcpdump -ni ''interface'' "port 22"<br />
<br />
用于 Wireshark:<br />
<br />
$ tshark -f "tcp port 22" -i ''interface''<br />
<br />
其中 {{ic|''interface''}} 是用于连接 WAN 的网络适配器(用 {{ic|ip a}} 来查找)。如果在尝试远程连接时没有收到任何数据包,则可以确信你的 ISP 屏蔽了 22 端口上的传入连接。<br />
<br />
===== 可能的解决方案 =====<br />
此方案是换一个 ISP 没有屏蔽的端口。编辑 {{ic|/etc/ssh/sshd_config}} 文件来使用不同的端口。例如,新增这几行:<br />
<br />
Port 22<br />
Port 1234<br />
<br />
还要确保文件中的其他“Port”配置行被注释掉。只是注释“Port 22”并加上“Port 1234”不会解决问题,因为那样 sshd 将只监听在 1234 端口上。写入这两行可以在两个端口上运行 SSH 服务器。<br />
<br />
[[Restart|重启]] 服务器上的 {{ic|sshd.service}} 就基本完成了。你还需要配置客户端来使用与默认端口不同的端口,这个问题有很多种解决方案,在这里我们只介绍两种。<br />
<br />
==== "Read from socket failed: connection reset by peer" 错误 ====<br />
<br />
使用最近版本的 openssh 连接到较旧的 ssh 服务器时有时会失败,并显示上述错误消息。这可以通过为该主机设置各种 [[#配置|客户端选项]] 来解决。有关下列选项的更多信息,请参阅 {{man|5|ssh_config}}。<br />
<br />
问题可能出在 {{ic|ecdsa-sha2-nistp*-cert-v01@openssh}} 椭圆曲线算法上。这些算法可以通过在 {{ic|HostKeyAlgorithms}} 里设置可用算法来排除那些算法。<br />
<br />
如果这不起作用,可能是秘钥列表太长了。设置 {{ic|Ciphers}} 来减少列表长度(少于 80 个字符应该可以)。同样的,也可以尝试缩短 {{ic|MACs}} 列表。<br />
<br />
参阅 openssh bug forum 上的 [http://www.gossamer-threads.com/lists/openssh/dev/51339 讨论]。<br />
<br />
=== "[your shell]: No such file or directory" / SSH 认证问题 ===<br />
对于这个问题,一个可能的原因是需要 SSH 客户端在 {{Ic|$SHELL}} 中提供绝对路径(例如可以通过 {{Ic|whereis -b [your shell]}} 得到),即使你的 shell 在 {{Ic|$PATH}} 里的某个路径中。<br />
<br />
==="Terminal unknown" 或 "Error opening terminal" 错误 ===<br />
如果你在登录时收到上述错误,这意味着服务器无法识别你的终端。使用 Ncurses 的应用程序(如 nano)可能会失败,并显示“Error opening terminal”。<br />
<br />
正确的解决方案是在服务器上安装客户端终端的 terminfo 文件。这会告诉服务器上的控制台程序如何正确地与终端进行交互。你可以使用 {{ic|$ infocmp}} 获得关于当前 terminfo 的信息,然后找出 [[Pacman#Querying_package_databases|哪个包包括了它们]]。<br />
<br />
如果你不能正常[[install|安装]]它,可以把 terminfo 复制到服务器上你的主目录里面:<br />
<br />
$ ssh myserver mkdir -p ~/.terminfo/${TERM:0:1}<br />
$ scp /usr/share/terminfo/${TERM:0:1}/$TERM myserver:~/.terminfo/${TERM:0:1}/<br />
<br />
重新登录、登出服务器后这个问题应该已经解决。<br />
<br />
==== TERM hack ====<br />
<br />
{{警告|这只能作为最后的手段。}}<br />
<br />
你可以在服务器上的环境(例如 {{ic|.bash_profile}})中简单地设置 {{ic|1=TERM=xterm}} 。这将消除错误并允许 ncurses 应用程序再次运行,但除非你的终端的控制序列与 xterm 完全匹配,否则可能会遇到奇怪的行为和图形界面问题。<br />
<br />
=== "Connection closed by x.x.x.x [preauth]" 错误 ===<br />
如果你在 sshd 的 log 里看到这条错误,请确保你已经设置了可用的 HostKey<br />
HostKey /etc/ssh/ssh_host_rsa_key<br />
<br />
=== id_dsa 被 OpenSSH 7.0 拒绝 ===<br />
<br />
出于安全原因,OpenSSH 7.0 弃用了 DSA 公钥。如果你必须启用它们,请[[#配置|设置]] {{ic|PubkeyAcceptedKeyTypes +ssh-dss}} 选项(http://www.openssh.com/legacy.html 没有提到这一点)。<br />
<br />
=== OpenSSH 7.0 的 "No matching key exchange method found" 错误 ===<br />
<br />
OpenSSH 7.0 弃用了 diffie-hellman-group1-sha1 密钥算法,因为它很弱并且在所谓 Logjam 攻击的理论范围内(参阅http://www.openssh.com/legacy.html)。如果特定主机需要这个密钥算法,ssh 会产生如下错误消息:<br />
<br />
Unable to negotiate with 127.0.0.1: no matching key exchange method found.<br />
Their offer: diffie-hellman-group1-sha1<br />
<br />
这个问题的最佳解决方案是将服务器升级/配置为不使用不推荐的算法。如果做不到这一点,可以配置[[#配置|客户端选项]] {{ic|KexAlgorithms +diffie-hellman-group1-sha1}} 强制客户端使用这个算法。<br />
<br />
=== 断开 SSH 连接时 tmux/screen 会话被关闭 ===<br />
<br />
如果进程在会话结束时被终止,那么你可能是用 ssh.socket 激活的,{{Pkg|systemd}} 注意到 SSH 会话进程退出,然后杀掉了 tmux/screen 进程。这种情况有两种解决方案。一种是通过使用 {{ic|ssh.service}} 来代替 {{ic|ssh.socket}} 来避免使用 socket 激活。另一个是在 {{ic|ssh@.service}} 的 Service 部分设置 {{ic|1=KillMode=process}}。<br />
<br />
在常规的 {{ic|ssh.service}} 里面 {{ic|1=KillMode=process}} 这个选项也是有用的,它可以在 service 停止或重启时防止 SSH 会话进程或 {{Pkg|screen}} 或 {{Pkg|tmux}} 进程被 kill 掉。<br />
<br />
=== SSH 会话无响应 ===<br />
<br />
SSH 响应 [[Wikipedia:Software_flow_control|流控制命令]] 中的 {{ic|XON}} 和 {{ic|XOFF}} 命令。 当你按 {{ic|Ctrl+s}} 时,它会冻结/挂起/停止响应。按 {{ic|Ctrl+q}} 恢复会话。<br />
<br />
== 参阅 ==<br />
<br />
* [[Wikipedia:Secure Shell]]<br />
* [http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
* [http://www.ibm.com/developerworks/library/l-keyc/index.html OpenSSH key management, Part 1] and [http://www.ibm.com/developerworks/library/l-keyc2 Part 2] on IBM developerWorks<br />
* [https://stribika.github.io/2015/01/04/secure-secure-shell.html Secure Secure Shell]</div>
Arisaka