最後更新: 2024-01-02
目錄
- 安裝
- 第一次登入
- Debug with SyslogFacility
- 公私匙認證 (authentication key)
- 加強安全性
- ssh login slow
- 重新建立 host key
- Alive
- sshd listen to multiple ports
- Environment Variable
- ForceCommand
- Login 後 show 的 message
- UsePAM
- Login 後 show 的 message(motd)
- Troubleshoot
安裝
Openssh 這工具共分為兩個包:
Server 包: 是指設定檔及daemon(sshd) 本身
Client 包: 主要係 ssh, scp
Server包安裝:
apt-get install openssh-server
主要程式:
/usr/sbin/sshd # daemon 本身
設定檔:
/etc/ssh/sshd_config
Server 的公私匙:
ssh_host_dsa_key.pub
ssh_host_dsa_key
ssh_host_rsa_key.pub <-- 多數
ssh_host_rsa_key
P.S.
當安裝 Server包時, 它們會自動生成的 ~
Config Checking
/usr/sbin/sshd -t
-t Test mode. Only check the validity of the configuration file and sanity of the keys.
echo $?
0
Client包
apt-get install openssh-client
設定檔:
/etc/ssh/ssh_config
主要程式:
/usr/bin/ssh
輔助工具:
/usr/bin/ssh-keygen
/usr/bin/scp
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan
/usr/bin/ssh-argv0
/usr/bin/sftp
/usr/bin/slogin
/usr/bin/ssh-vulnkey
第一次登入
如果係用 Linux 的朋友, client 工具必然是 ssh 了, 不用多說
在 Window 上, ssh 有很多 client 供選擇
而我是用 pietty 的
pietty 它是聞名世界的 putty 中文加強版來,
在中文支援方面尤其出色.
當我們在第一次 login 入 ssh server 時, 我們會見到
注意紅圈部份, 在不同 Server, 就有不用的 fingerprint.
它是 ssh_host_rsa_key.pub 公匙的指紋來,
理論上它是獨一無二的.
我們是用它來分辨是否連上真正的 Server
在第二次連上用一 Server 時, client 就不會再問,
因為 fingerprint 已經保存在 regetry 裡
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
Debug with SyslogFacility
SyslogFacility AUTHPRIV LogLevel Debug
service sshd restart
公私匙認證 (authentication key)
一般情況下 ssh 是用帳戶名及密碼登入的, 而 authentication key 是以公匙及私匙的形式登入
好處是比較安全 (唔怕比人撞密碼)
作法:
在Server 上行 ssh-ssh-keygen 建立密公匙及私匙
它們是建立在 ./ssh 的目錄下, 分別是 id_rsa 及 id_rsa.pub
id_rsa 是私匙 ( 要好好小心保存, 不用放在 Server 上的 ),
id_rsa.pub 是公匙 ( 要放在Server上 )
之後把 id_rsa.pub 改名成 authorized_keys 就可以用它作認證之用
( mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys )
Server Setting
# 相當於 %h/.ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
Variable
- %u by the login name of the use
i.e.
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
sshd為了安全, 對屬主的目錄和文件權限有所要求.
Debug log
Authentication refused: bad ownership or modes for directory
Fix
chmod g-w /home/your_user chmod 700 .ssh chmod 600 .ssh/authorized_keys
OR
StrictModes off
authorized_keys format
# key-comment options keytype base64-encoded_key comment
options: optional. comma-separated option specifications
keytype: ssh-rsa, ssh-dss, ...
The options are supported in authorized_keys files
restrict
Enable all restrictions
i.e. disable port, agent and X11 forwarding, as well as disabling PTY allocation and execution of ~/.ssh/rc
command="cmd"
# Specifies that the command is executed whenever this key is used for authentication.
# The command supplied by the user (if any) is ignored.
# (useful to restrict certain public keys to perform just a specific operation)
# The command is run on a pty if the client requests a pty;
# otherwise it is run without a tty.
environment="NAME=value"
# The patterns may use "*" as wildcard
# CIDR address/masklen notation
# An exclamation mark ! can be used in front of a pattern to negate it.
# Support DNS Name
from="pattern-list"
i.e.
from="*.sales.example.net,!pc.sales.example.net"
no-pty
# Prevents allocation of a pseudo-tty
no-user-rc
# Disables execution of .ssh/rc when using the key.
forwarding
no-agent-forwarding
no-port-forwarding
no-x11-forwarding
permitopen="host:port" # -L option
permitlisten="[host:]port" # -R option
tunnel="n"
認證方式
... sshd[27691]: debug1: KEX done [preauth] ... sshd[27691]: debug1: userauth-request for user MyUserName service ssh-connection method none [preauth] ... sshd[27691]: debug1: attempt 0 failures 0 [preauth] ... sshd[27691]: debug1: PAM: initializing for "MyUserName" ... sshd[27691]: debug1: PAM: setting PAM_RHOST to "IP.ctinets.com" ... sshd[27691]: debug1: PAM: setting PAM_TTY to "ssh" ... sshd[27691]: debug1: userauth_send_banner: sent [preauth] -------------------------------- ... sshd[27691]: debug1: userauth-request for user MyUserName service ssh-connection method publickey [preauth] ... sshd[27691]: debug1: attempt 1 failures 0 [preauth] ... sshd[27691]: debug1: userauth_pubkey: test whether pkalg/pkblob are acceptable for RSA SHA256:?/? [preauth] ... sshd[27691]: debug1: temporarily_use_uid: 1063/1063 (e=0/0) ... sshd[27691]: debug1: trying public key file /root/.ssh/authorized_keys ... sshd[27691]: debug1: Could not open authorized keys '/root/.ssh/authorized_keys': Permission denied ... sshd[27691]: debug1: restore_uid: 0/0 ... sshd[27691]: Failed publickey for MyUserName from R.R.R.R port 57044 ssh2: RSA SHA256:?/? -------------------------------- ... sshd[27691]: debug1: userauth-request for user MyUserName service ssh-connection method keyboard-interactive [preauth] ... sshd[27691]: debug1: attempt 2 failures 1 [preauth] ... sshd[27691]: debug1: keyboard-interactive devs [preauth] ... sshd[27691]: debug1: auth2_challenge: user=MyUserName devs= [preauth] ... sshd[27691]: debug1: kbdint_alloc: devices 'pam' [preauth]
加強安全性
設定安全:
# root 用戶不可經由 ssh login
PermitRootLogin no
Opts:
- yes
- prohibit-password (default)
- without-password
- forced-commands-only (public key authentication + command)
- no
# 一定要用公匙及私匙 login
PasswordAuthentication no
# 只用 Protocol 2
Protocol 2
# 只可以給同時在 AllowUsers 及 AllowGroups 的帳戶登入
# 亦即是說要同時滿足這兩個條規則 !!
# 就算 PermitRootLogin yes 時, root 都不能 login
AllowUsers root sysadmin AllowGroups admin
網絡安全
重新建立 host key
Error msg
Could not load host key: /etc/ssh/ssh_host_key
建立
ssh-keygen -A
ssh-keygen: generating new host keys: RSA1 ECDSA
* "host keys do not exist" 才會建立新的 Key
OR
# ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] [-f output_keyfile]
# -q Silence ssh-keygen
cd /etc/ssh
ssh-keygen -t dsa -f ssh_host_dsa_key
ssh-keygen -t rsa -f ssh_host_rsa_key
ssh-keygen -t ecdsa -f ssh_host_ecdsa_key
查看 server 的 fingerprint
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
Alive
make your OpenSSH server keep alive all connections with clients
# send a null packet to the other side every 30 seconds
# give up if it doesn’t receive any response after 2 tries
ClientAliveInterval 30 ClientAliveCountMax 2
sshd listen to multiple ports
Port 22 Port 2201
Performance
sshd_config
# disable dns lookup the remote host name
UseDNS no
Banner
Banner none | /path/to/file
...
VersionAddendum String....
additional text to append to the SSH protocol banner sent by the server upon connection.
telnet localhost 22
SSH-2.0-OpenSSH_7.4 Private SFTP
sshd per user configuration
e.g.
Match User USERNAME PasswordAuthentication no
不是所有的 Setting 都可以 per user 的, 只有以下 Setting 適用
AllowAgentForwarding, AllowTcpForwarding,
AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, ChrootDirectory,
ForceCommand, GatewayPorts,
GSSAPIAuthentication,
HostbasedAuthentication, HostbasedUsesNameFromPacketOnly,
KbdInteractiveAuthentication, KerberosAuthentication,
MaxAuthTries, MaxSessions, PasswordAuthentication,
PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTunnel,
PubkeyAuthentication,
RhostsRSAAuthentication, RSAAuthentication,
X11DisplayOffset, X11Forwarding and X11UseLocalHost.
Environment Variable
PermitUserEnvironment
# The default is no
Specifies whether "~/.ssh/environment" and "environment=" options in ~/.ssh/authorized_keys are processed by sshd
AcceptEnv
Specifies what environment variables sent by the client will be copied into the session's environ(7).
See SendEnv in ssh_config(5) for how to configure the client.
The TERM environment variable is always sent whenever the client requests a pseudo-terminal as it is required by the protocol.
Variables are specified by name, which may contain the wildcard characters ‘*’and ‘?’.
Multiple environment variables may be separated by whitespace or spread across multiple AcceptEnv directives.
Bewarned that some environment variables could be used to bypass restricted user environments.
For this reason, care should be taken in the use of this directive. The default is not to accept any environment variables.
ForceCommand
The command is invoked by using the user's login shell with the -c option.
This applies to shell, command, or subsystem execution.
Login 後顯示的 message(motd)
/etc/motd
支援中文
"Last login" & Motd message
它們 default 都是 yes
/etc/ssh/sshd_config
PrintLastLog yes PrintMotd yes
~/.hushlogin
Suppress printing the "PrintLastLog" & "PrintMotd"
It does not suppress printing "Banner"
pam_motd
Example
Rocky 8 Login 後會有:
Activate the web console with: systemctl enable --now cockpit.socket
# Stop 它
rm -f /etc/issue.d/cockpit.issue /etc/motd.d/cockpit
UsePAM
UsePAM (Default: no)
yes: this will enable PAM authentication using ChallengeResponseAuthentication and PasswordAuthentication
in addition to PAM account and session module processing for all authentication types.
Because PAM challenge-response authentication usually serves an equivalent role to PasswordAuthentication,
You should disable either PasswordAuthentication or ChallengeResponseAuthentication.
建議
UsePAM yes PasswordAuthentication yes ChallengeResponseAuthentication no
* If UsePAM is enabled, you will not be able to run sshd as a non-root user.
---
ChallengeResponseAuthentication (Default: yes)
Specifies whether challenge-response authentication is allowed.
---
* PAM authentication via ChallengeResponseAuthentication may bypass the setting of
- PasswordAuthentication no
- PermitRootLogin without-password
---
WARNING: 'UsePAM no' is not supported in RHEL and may cause several problems.
History
UseLogin no # /usr/bin/login
UseLogin option is disabled by default in OpenSSH for many years
telnet 年代的事:
init start getty & telnetd getty opened a serial port -> login (prompt for the password) telnetd -> login (prompt for the password)
Troubleshoot
Debug 方式
sshd re-exec requires execution with an absolute path
直接在 cli 行 "sshd" 係 start 唔到 sshd 的
原因:
For every new connection, sshd will re-execute itself,
to ensure that all execute-time randomisations are re-generated for each new connection.
In order for sshd to re-execute itself, it needs to know the full path to itself.
which sshd
/usr/sbin/sshd
sshd foreground debug on another port
# The server also will not fork and will only process one connection
# Multiple -d options increase the debugging level. (Maximum is 3)
/usr/sbin/sshd -d -p 9999
- -d Debug mode
- -p port 9999
[Issue] 某 user login 唔到
debug1: kbdint_alloc: devices 'pam' debug1: auth2_challenge_start: trying authentication method 'pam' Postponed keyboard-interactive for ???? from ::ffff:192.168.168.4 port 39132 ssh2 ... debug1: session_pty_req: session 0 alloc /dev/ttyp0 debug1: server_input_channel_req: channel 0 request shell reply 0 debug1: session_by_channel: session 0 channel 0 debug1: session_input_channel_req: session 0 req shell debug1: PAM: setting PAM_TTY to "/dev/ttyp0" debug1: Setting controlling tty using TIOCSCTTY. debug1: Received SIGCHLD. <-- 問題來了 debug1: session_by_pid: pid 4273 debug1: session_exit_message: session 0 channel 0 pid 4273 debug1: session_exit_message: release channel 0 debug1: session_close: session 0 pid 4273 debug1: session_by_tty: session 0 tty /dev/ttyp0 debug1: session_pty_cleanup: session 0 release /dev/ttyp0 debug1: channel 0: free: server-session, nchannels 1 Connection closed by ::ffff:192.168.168.4 debug1: do_cleanup debug1: PAM: cleanup Closing connection to ::ffff:192.168.168.4 debug1: PAM: cleanup
Fix
cat /etc/shells # 查看系統有什麼 Shell
usermod -s /bin/bash USERNAME
[Issue] ssh login slow
log:
Jul 22 10:44:20 myserver sshd(pam_unix)[25925]: session opened for user root by (uid=0) Jul 22 10:44:20 myserver sshd[25927]: nss_ldap: reconnecting to LDAP server (sleeping 4 seconds)... Jul 22 10:44:20 myserver sshd[25927]: nss_ldap: reconnecting to LDAP server (sleeping 8 seconds)... ...................
[fix] Speed up SSH logon
GSSAPIAuthentication
GSSAPIAuthentication no
Generic Security Services API. In SSH's case its designed to talk to Kerberos.
GSSAPI is a IETF standard for doing strong encrypted authentication in network based applications.
OPENssh uses this API and the underlying kerberos 5 code to provide a alternative means of authentication other than ssh_keys.
# The "-v" maximum is 3
ssh -vvv
debug3: preferred gssapi-keyex,gssapi-with-mic,gssapi,publickey,keyboard-interactive,password
nsswitch
在 nsswitch.conf 內停用 ldap
/etc/nsswitch.conf
passwd: files shadow: files group: files
[Issue]
sshd:Privilege separation user sshd does not exist
解決
UsePrivilegeSeparation no
說明
The default is ''yes''.
sshd separates privileges by creating an unprivileged child process to deal with incoming network traffic.
After successful authentication, another process will be created that has the privilege of the authenticated user.
The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes.
[Issue]
OS: Centos 6
/var/log/secure
sshd[400]: fatal: daemon() failed: No such device
沒有 /dev/null
[Issue]
OS: Centos 7
ssh 時見到它時見到
... Server refused to allocate pty
查看
ls -la /dev/pts/*
lsof /dev/pts/*
/var/log/secure
error openpty read-only file system
mount | grep devpts
mount -t devpts devpts /dev/pts
mount -t devpts -o remount,rw,nosuid,noexec,relatime,uid=0,gid=5,mode=620 devpts /dev/pts