SSH
SSH(Secure SHell,安全终端)是用来安全地远程操作计算机的标配工具。所有敏感信息都会被高度加密。除远程终端以外,SSH 还支持文件传输和任意协议的转发,是安全使用远程服务成为可能。SSH 是 Telnet、rlogin 等不安全协议的替代品,更是一个完整的远程操作工具链。
除了用于远程终端访问的 ssh 这个主要指令外,SSH 还包括其他的工具,如安全远程复制 scp、安全文件传输 sftp 和密钥管理工具 ssh-agent。SSH 的标准端口号为 22。
SSH 有多个实现,其中最主流的是使用 BSD 协议的 OpenBSD 的 OpenSSH。Gentoo 默认安装了 OpenSSH。
SSH is multi-platform, and is very widely used: OpenSSH is installed by default on most Unix-like OSs, on Windows10, on MacOS, and can be installed on Android or "jailbroken" iOS (SSH clients are available). This makes SSH a great tool for working with heterogeneous systems.
安装
检查安装
绝大多数的 Gentoo Linux 系统都已经预装了 OpenSSH。可以通过运行 ssh 命令进行检查。如果已经安装,会输出使用说明:
user $
ssh
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q cipher | cipher-auth | mac | kex | key] [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command]
如果没有输出使用说明,那么 ssh 要么损坏了要么没有安装。也有可能是用户添加了新的 USE 配置之后正在重新编译 OpenSSH。无论何种情况,请继续查看可能的 USE 设定。
If this does not try to install OpenSSH, the package may have been masked, or even listed in package.provided, though this would be unusual.
USE 标记
USE flags for net-misc/openssh Port of OpenBSD's free SSH release
+pie
|
Build programs as Position Independent Executables (a security hardening technique) |
+ssl
|
Enable additional crypto algorithms via OpenSSL |
audit
|
Enable support for Linux audit subsystem using sys-process/audit |
debug
|
Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces |
kerberos
|
Add kerberos support |
ldns
|
Use LDNS for DNSSEC/SSHFP validation. |
legacy-ciphers
|
Enable support for deprecated, soon-to-be-dropped DSA keys. See https://marc.info/?l=openssh-unix-dev>m=170494903207436>w=2. |
libedit
|
Use the libedit library (replacement for readline) |
livecd
|
Enable root password logins for live-cd environment. |
pam
|
Add support for PAM (Pluggable Authentication Modules) - DANGEROUS to arbitrarily flip |
security-key
|
Include builtin U2F/FIDO support |
selinux
|
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur |
static
|
!!do not set this during bootstrap!! Causes binaries to be statically linked instead of dynamically |
test
|
Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) |
verify-sig
|
Verify upstream signatures on distfiles |
xmss
|
Enable XMSS post-quantum authentication algorithm |
Emerge
在修改了必要的 USE 标志之后,不要忘记安装(或重装) OpenSSH:
root #
emerge --ask --changed-use net-misc/openssh
After changing any global USE flags in make.conf that affect the OpenSSH package, emerge world to update to the new USE flags:
root #
emerge --ask --verbose --update --deep --newuse @world
配置
创建密钥
为了提供一个安全的 shell,加密的密钥用于管理 SSH 提供的加密、解密和哈希功能。
在第一次启动 SSH 服务的时候,会生成系统密钥。密钥可以使用 ssh-keygen(重新)生成。
root #
/usr/bin/ssh-keygen -t ed25519 -a 100 -f /etc/ssh/ssh_host_ed25519_key -N ""
root #
/usr/bin/ssh-keygen -t rsa -b 4096 -o -a 100 -f /etc/ssh/ssh_host_rsa_key -N ""
服务器端配置
SSH服务器配置文件通常是 /etc/ssh/sshd_config,虽然也有可能通过OpenRC的/etc/conf.d/sshd文件进行进一步的配置,包括修改配置文件的位置。关于如何配置服务器的详细信息请参考sshd_config man page。
服务器提供了使用测试模式验证其配置的方法:
root #
/usr/sbin/sshd -t
始终在重新启动服务之前验证配置更改,以保持远程登录可用。
客户端配置
ssh 客户端与相关的程序(scp,sftp 等)可以通过下面的文件进行配置:
- ~/.ssh/config
- /etc/ssh/ssh_config
更多的信息请阅读 ssh_config 手册:
防御入侵
运行 SSH 服务器
Commands to run the SSH server will depend on active init system.
OpenRC
将OpenSSH服务加入缺省的运行级别:
root #
rc-update add sshd default
启动sshd服务:
root #
rc-service sshd start
OpenSSH服务可以像其它被OpenRC管理的服务一样被控制:
root #
rc-service sshd start
root #
rc-service sshd stop
root #
rc-service sshd restart
rc-service sshd restart 并不会影响到正在运行的到服务器端的SSH连接。
systemd
当系统启动时同时启动OpenSSH:
root #
systemctl enable sshd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/sshd.service to /usr/lib64/systemd/system/sshd.service.
现在启动OpenSSH服务:
root #
systemctl start sshd.service
检查服务是否已经启动:
root #
systemctl status sshd.service
使用
Commands
OpenSSH provides several commands, see each command's man page for usage information:
- scp(1) - secure file copy
- sftp(1) - secure file transfer
- ssh-add(1) - add private key identities to the authentication agent
- ssh-agent(1) - authentication agent
- ssh-copy-id(1) - use locally available keys to authorize logins on a remote machine
- ssh-keygen(1) - authentication key utility
- ssh-keyscan(1) - gather SSH public keys from servers
- sshd(8) - OpenSSH daemon
转义序列
在活动的SSH会话期间,按波形符(~)键可启动转义序列。输入以下内容以获取选项列表:
ssh>
~?
Note that escapes are only recognized immediately after a newline. They may not always work with some shells, such as fish.
连接到远程 SSH 服务器
对于管理 git 服务器非常便利。
For more details see the Security Handbook.
Leaving the passphrase empty implies the private key file will not be encrypted. An attacker having access to the local filesystem will be able to read the private key.
客户端
在客户端应先创建一个密钥对。如果你之前没有创建的话,可以执行下面的命令来完成(当然,请不要输入密码):
user $
ssh-keygen -t rsa
Generating public/private rsa key pair. Enter file in which to save the key (/home/larry/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/larry/.ssh/id_rsa. Your public key has been saved in /home/larry/.ssh/id_rsa.pub. The key fingerprint is: de:ad:be:ef:15:g0:0d:13:37:15:ad:cc:dd:ee:ff:61 larry@client The key's randomart image is: +--[ RSA 2048]----+ | | | . | | . .. n . | | . (: . . | | o . . : . | | . ..: >.> . | | * ?. . | | o.. .. .. | | :. . ! . | +-----------------+
The default file names of the keys must not be changed, or the server may persist in asking for a password even after running ssh-copy-id
as explained below. The file name will be one of:
- id_rsa
- id_ecdsa
- id_ed25519
depending on the key algorithm used.
服务器
确保服务器上存在用户的帐号,然后把客户端的 id_rsa.pub 文件拷贝到服务器端用户 home 目录的 ~/.ssh/authorized_keys 文件。这可以通过在客户端计算机上运行以下命令来实现(这里,需要输入用户在服务器上的密码):
user $
ssh-copy-id <server>
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/larry/.ssh/id_ed25519.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys larry@<server>'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '<server>'" and check to make sure that only the key(s) you wanted were added.
然后就应该可以进行无密码登录了:
user $
ssh <server>
larry@<server>
接着在服务器上,这个文件/etc/ssh/sshd_config 里应该设置PasswordAuthentication no
.
单机测试
上面的步骤可以在本地测试:
user $
ssh-keygen -t rsa
Generating public/private rsa key pair. Enter file in which to save the key (/home/larry/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: ...
user $
mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
user $
ssh localhost
Remote services over ssh
SSH may be used to access remote services, such as HTTP, HTTPS, fileshares, etc., through an encrypted "tunnel". Remote service access is detailed in the SSH tunneling and SSH jump host articles.
Copying files to a remote host
The SFTP command, a part of SSH, uses the SSH File Transfer Protocol to copy files to a remote host. rsync is also an alternative for this.
The OpenSSH 8.0 release notes, from 2019, state "The scp protocol is outdated, inflexible and not readily fixed. We recommend the use of more modern protocols like sftp and rsync for file transfer instead.". The OpenSSH 8.8 release notes, from 2021, state "A near-future release of OpenSSH will switch scp(1) from using the legacy scp/rcp protocol to using SFTP by default.".
ssh-agent
OpenSSH 带有 ssh-agent,这是一个缓存和防止频繁输入 ssh 密码的守护进程。运行时,环境变量 SSH_AUTH_SOCK 是用于指向 ssh-agent 的通信套接字。设置 ssh-agent 的正常方法是将其作为用户会话的最顶层进程运行。否则环境变量在会话中将不可见。
根据图形用户会话被配置为启动的方式,找到一种合适的方式来启动 ssh-agent 可能很棘手。作为 lightdm 显示管理器的示例,你可以编辑和更改 /etc/lightdm/Xsession
user $
exec $command
进入
user $
exec ssh-agent $command
要在每个会话中告诉 ssh-agent 密码一次,请手动运行 ssh-add
或使用 AddKeysToAgent
选项。
最近的 Xfce[1] 将自动启动 ssh-agent(和 gpg-agent)。如果两者都安装,则两者都将启动,这使得身份管理尤其是智能名片更加复杂。要么至少停止 XFCE 自启动的 SSH 代理,要么禁用两者并使用你的 shell、X-session 或类似。
user $
xfconf-query -c xfce4-session -p /startup/ssh-agent/enabled -n -t bool -s false
user $
xfconf-query -c xfce4-session -p /startup/gpg-agent/enabled -n -t bool -s false
Tips
Terminal multiplexers to preserve sessions
It is possible to use a terminal multiplexer to resume a session after a dropped connection. Tmux and Screen are two popular multiplexers that can be used to be able to reconnect to a session, even if a command was running when the connection dropped out.
SSH over intermittent connections
When on unstable Internet connections, or when roaming between networks (such as when moving wifi networks), mosh can help avoid dropping SSH sessions.
Open new tabs for session with Kitty terminal
By using the SSH kitten for the Kitty terminal emulator, it is possible to open new "tabs", or windows, on the current SSH session without having log in again.
Kitty also provides other practical SSH functionality.
Benchmark the optimal rounds for an ed25519 key
It is highly advisable to conduct benchmarking for the ed25519 key generation process, particularly considering the default value of 16 rounds and the potential performance improvements achievable with higher round values.
#!/bin/sh
rounds="16 32 64 100 150"
num_runs=20
for r in $rounds; do
printf "Benchmarking 'ssh-keygen -t ed25519 -a %s' on average:\n" "$r"
total_time=0
i=1
while [ $i -le $num_runs ]; do
start_time=$(date +%s.%N)
ssh-keygen -t ed25519 -a "$r" -f test -N test >/dev/null 2>&1
end_time=$(date +%s.%N)
runtime=$(echo "$end_time - $start_time" | bc)
total_time=$(echo "$total_time + $runtime" | bc)
rm test{,.pub} >/dev/null 2>&1
printf "Run %s: %s seconds\n" "$i" "$runtime"
i=$((i + 1))
done
average_time=$(echo "scale=3; $total_time / $num_runs"| bc)
printf "Average execution time: %s seconds\n\n" "$average_time"
done
It is highly recommended to perform benchmarking for ed25519 key generation, considering both security and performance aspects. While the highest recommended round may offer superior security, it's essential to find the optimal balance based on individual requirements and time constraints. By conducting benchmark tests, one can evaluate the trade-off between security and performance, ensuring the selection of an appropriate round value for ed25519 keys.
Benchmarking is a crucial process to measure the performance and efficiency of a system or a specific component, such as cryptographic algorithms. In the context of SSH (Secure Shell) ciphers, it is important to determine the optimal number of rounds for generating ed25519 keys.
The provided script, ssh-benchmark.sh, conducts benchmarking on the ssh-keygen command with different round values for ed25519 keys. The script executes the ssh-keygen command multiple times with varying round values and measures the execution time for each run. It then calculates the average execution time for each round value.
By benchmarking different round values, system administrators and security professionals can identify the optimal round value that strikes a balance between security and performance. Higher round values generally provide stronger security but can result in increased computational overhead. Finding the right balance ensures that ed25519 keys are generated efficiently without compromising security.
Benchmarking helps identify potential bottlenecks, vulnerabilities, or areas that require improvement in security systems. It assists in selecting the most suitable algorithms and configurations for a particular use case, ensuring that security measures are robust and effective.
故障排除
有三种不同级别的调试模式可以帮助排除故障。配合 -v
参数 SSH 会输出关于其进度的调试信息。这有助于调试连接、验证和配置的问题。多个 -v
参数会增加调试信息的详细程度。最大的详细程度是三级。
user $
ssh example.org -v
user $
ssh example.org -vv
user $
ssh example.org -vvv
Permissions are too open
An ssh connection will only work if the file permissions of the ~/.ssh directory and contents are correct.
- The ~/.ssh directory permissions should be 700 (drwx------), i.e. the owner has full access and no one else has any access.
- Under ~/.ssh:
- public key files' permissions should be 644 (-rw-r--r--), i.e. anyone may read the file, only the owner can write.
- all other files' permissions should be 600 (-rw-------), i.e. only the owner may read or write the file.
These permissions need to be correct on the client and server.
长连接被关闭
许多互联网接入设备进行网络地址转换 (NAT),使在专用网络(典型的例子像家里或者某个营业场所)内的设备可以访问外部网络如互联网,尽管该设备只拥有专用网络上的一个IP地址。不幸的是,不是所有的NAT设备都是一样的,其中一些会错误的关闭那些长时间连接,不经常使用的TCP连接,比如SSH使用的连接。这一问题通常的表现是突然无法和远程的服务器交互,尽管 ssh 客户端程序并未退出。
OpenSSH的客户端和服务器可以被配置为发送一个'keep alive',或不可见的消息,旨在保持并确认连接的实时状态:
- 为了给连接到您的本地服务器的所有客户端使能keep alive,请在/etc/ssh/sshd_config文件中设置
ClientAliveInterval 30
(或者其它值,以秒为单位)。 - 为了给连接到您的本地客户端的所有服务器使能keep alive,请在/etc/ssh/ssh_config文件中设置
ServerAliveInterval 30
(或者其它值,以秒为单位)。
For example, to modify the server's configuration, add following file:
# The following ClientAlive values will keep an inactive session open for 30 minutes
ClientAliveCountMax 60
ClientAliveInterval 30
#
# Deactivate TCPKeepAlive
TCPKeepAlive no
To modify the client's configuration, add following file:
# The following ServerAlive values will keep an inactive session open for 2 hours
ServerAliveInterval 60
ServerAliveCountMax 120
New key does not get used
This scenario covers the case when a key to access a remote system has been created, the public key installed on the remote system, but the remote system is (for some reason) not accessible via ssh. This can happen if the name of the keyfile is not known to ssh.
Confirm which key files ssh is trying by running it with one of the verbose options, as described at the start of the Troubleshooting section. The verbose output will include the names of the keyfiles it is trying, and the one (if any) that actually gets used.
The default key files for the system are listed in the /etc/ssh/ssh_config, see the commented-out lines containing IdentityFile
directives.
There are several ways to use a key with a non-default name.
The key name can be specified on the command line every time:
user $
ssh -i ~/.ssh/my_keyfile user@remotesys
Alternatively, add following ssh configuration file to add a special case for ssh to the remote system:
Host remotesys
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/my_keyfile
If any are specified, it appears to be necessary to specify all the desired keys on a remote host. Read up on the ssh IdentityFile.
X11转发/隧道不工作
问题: 在对配置文件做了必要的修改以允许 X11 转发, 却发现 X 应用程序在服务器端执行却没有转发到客户端。
解决办法: 可能是在SSH登录到远程服务器或者主机的过程中,DISPLAY变量被取消了或者在 SSH session 设置这一变量之后又被重设了。
远程登录后按如下步骤测试这一现象:
user $
echo $DISPLAY
localhost:10.0
如果服务器端设置了 X11UseLocalhost no
,通常应该得到类似于 localhost:10.0
或者 localhost2.local:10.0
这样的结果。如果显示的不是 :0.0
,请检查并确定没有在 $HOME/.bash_profile 中取消了或者重新初始化了 DISPLAY 变量。如果是的话,删除或者注释掉自定义初始化 DISPLAY 变量的语句,以阻止 SSH 登录的时候执行 bash_profile 中的这些代码:
user $
ssh -t larry@localhost2 bash --noprofile
请将上面命令中的larry
替换为适当的用户名。
一个小技巧是在用户的 ~/.bashrc 中将此命令定义为一个 alias。
参考
- Securing the SSH service(安全手册)
- Gentoo Linux 钥匙串指南
- Autossh - 侦测何时SSH连接被断开并自动重新连接。
- SCP - SSH 自带的安全拷贝程序。
- SFTP - SSH 自带的安全文件传输协议客户端。
- SSHFS - 基于 FUSE 和 SSH 的挂载客户端。
- Gentoo手册 — 安装 — 启动SSH服务
- User:Sakaki/Sakaki's_EFI_Install_Guide/Setting_Up_Networking_and_Connecting_via_ssh#Connecting_via_ssh_and_Using_screen