All notes
Ssh

Configs

sshd_config

Use man sshd_config for help.

DenyUsers, AllowUsers

DenyUsers user1 user2 user3
DenyGroups group1 group2

AllowUsers user1 user2
AllowGroups group1 group2

Reload conf

After editing your sshd_config file, you will need to reload your SSH server's configuration - restarting the SSH daemon is not necessary:

sudo service sshd reload

Don't lock yourself out of your SSH server

When experimenting with these access controls, it's a good idea to always have two SSH sessions into the server, and to always make backup of the relevant configuration files. If you log out of one session and get denied access, you still have one active session to fix things.

.ssh/config


Host hawkhost
	HostName www.me.com
	User     me
	IdentityFile /Users/me/.ssh/me.private

KeepAlive

ServerAliveInterval 是SSH层的,数据加密状态传输,不会被简单规则过滤。更多参数说明可以参考 man ssh_config.

ssh_config 里还有个参数 TCPKeepAlive,默认false,可以改为yes。TCPKeepAlive是靠发送空的ACK包来保持连接,由可能在特定情况下无效(被防火墙过滤)。

The following exampl. ServerAliveCountMax 5 (默认是3),解释是:10秒钟发送一次心跳,如果连续5次都没有响应,客户端就断开连接。


Host * 
  SendEnv LANG LC_*
  ServerAliveCountMax 5
  ServerAliveInterval 10

ControlMaster

Anchor. The concept is very simple — rather than each new SSH connection to a particular server opening up a new TCP connection, you instead multiplex all of your SSH connections down one TCP connection. The authentication only happens once, when the TCP connection is opened, and thereafter all your extra SSH sessions are sent down that connection.


Host *
ControlMaster auto
ControlPath ~/.ssh/cm_socket/%[email protected]%h:%p
# Then mkdir ~/.ssh/cm_socket, and you're away.

# Setting up a dedicated master connection
ssh -MNn [email protected]

# If you need to disable control master for a given connection
ssh -S none [email protected]

ssh_config

SuperUser.

For security concern, we usually set ChallengeResponseAuthentication to "no". If you want to fully disable password-based authentication, set BOTH PasswordAuthentication and ChallengeResponseAuthentication to "no".

Usual Commands

ssh

The Amazon AWS allows only the key-pair authentication, so if I log in with ssh -l [email protected], I got the error "permission denied (pulickey)" instead of the password prompt.


ssh -v [email protected] # Output debug info so you could know why you cannot login.
man ssh_config # Check this manual for config options.

# ssh onto remote and execute command.
ssh [email protected] "ls"

The authorized_keys must be 644.

Proxy

haxx.se: ssh proxy.


# HTTP
ssh -L 8080:localhost:80 [email protected] -p 443 

# SOCKS
ssh -ND 8080 [email protected] -p 443

ssh-copy-id

Die.net: ssh-copy-id.


ssh-copy-id [-i [identity_file]] [[email protected]]machine

Functions:

What contents are added to remote?

scp


# -C: Compression enabled.
# -p: Preserves modification times, access times, and modes from the original file.
# -q: Quiet.
scp -Cpqr srcFile destPath

# Copy multiple files from remote to current local directory.
scp [email protected]:~/\{abc.log,cde.txt\} .

ssh-keygen


# -p: requests changing the passphrase.
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]

# -b bits: Specifies the number of bits in the key to create.
ssh-keygen -t rsa -b 2048

# Export pub key from private.
# -y: This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.
# -e: Read a private or public OpenSSH key file and print the key in RFC 4716 SSH Public Key File Format to stdout.
ssh-keygen -y [-f input_keyfile]

Bits. For RSA keys, the minimum size is 768 bits and the default is 2048 bits. Generally, 2048 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2.

ssh-agent, ssh-add

Instead of removing passphrase, consider using ssh-agent, which can cache the passphrase for a time.

ssh-agent

ssh-agent [-c | -s] [-d] [-a bind_address] [-t life] [command [arg ...]]
ssh-agent [-c | -s] -k

Implementation:


ssh-agent bash
ssh-add ~/.ssh/myPrivateKey
# Enter passphrase, then bingo!

# Set timeout to 4 hours. Default is forever/no expire.
ssh-agent -t 4h
# The timeout of ssh-add overrides that of ssh-agent, per key.
ssh-add -t 4h

# Displays the identities currently held by the agent.
ssh-add -l
# List all identities
ssh-add -L

Security

A unix-domain socket is created and the name of this socket is stored in the SSH_AUTH_SOCK environment variable.
The socket is made accessible only to the current user. This method is easily abused by root or another instance of the same user.
See rabexc.org: pitfalls of ssh-agents for details and good practices, e.g. never ever copy your private keys or run an ssh-agent on a computer somebody else has root on.

EveryBody.org.

Tunneling

Reverse Tunneling

tuicool.com: How to access a Linux server behind NAT via reverse SSH tunnel.

For this, you will need another host (relayServer) outside with a public IP address (e.g. IP 1.1.1.1). Then set up a persistent SSH tunnel from the server (homeServer) in your home network to the public relay host. With that, you can connect back to the home server from the relay host (which is why it’s called a “reverse” tunnel).


# On homeServer, open an SSH connection to relayServer:
# It forwards traffic on port 10022 of relayServer to port 22 of homeServer.
# -f: Requests ssh to go to background just before command execution.
# -N: Do not execute a remote command.
# -T: disables pseudo-tty allocation, which is appropriate because you're not trying to create an interactive shell.
# -vvv: for debugging.
ssh -fNT -R 10022:localhost:22 relayserver_user @ 1.1.1.1

# On relayServer, 127.0.0.1:10022 is bound to sshd.
sudo netstat -nap | grep 10022
# tcp      0    0 127.0.0.1:10022          0.0.0.0:*               LISTEN      8493/sshd

# Log in to relayserver. Then access homeServer as follows.
ssh -p 10022 homeserver_user @ localhost

# The end point of an SSH tunnel on relayserver is binding to loopback address (127.0.0.1). To make it to 0.0.0.0:

vi /etc/ssh/sshd_conf
# Add: GatewayPorts clientspecified
# Restart sshd.

# initiate a reverse SSH tunnel from homeserver:
ssh -fN -R 1.1.1.1:10022 :localhost: 22 relayserver_user @ 1.1.1.1
# Log in to relayServer and confirm with netstat command:
sudo netstat -nap | grep 10022
# tcp      0      0 1.1.1.1:10022     0.0.0.0:*           LISTEN      1538/sshd: dev
# Gain access to NATed homeserver from anywhere.
ssh -p 10022 homeserver_user @ 1.1.1.1

# Use autossh to make persistent connection:
# On homeServer:
# -M: a monitoring port.
autossh -M 10900 -fN -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 1.1.1.1: 10022 :localhost: 22 relayserver_user @ 1.1.1.1

# Kill autossh
pkill -9 autossh

FAQ

Error: no kex algo

SO: ssh prompts no kex alg.

wcfNote: the ssh client is too old. Use bitvise ssh client on Windows instead.

People recommends to edit the sshd_config and add:

KexAlgorithms diffie-hellman-group1-sha1

ssh login by identity file fails

Log in to server and see /var/log/secure. I found:


sshd[25561]: Authentication refused: bad ownership or modes for directory /home/me

chmod 755 /home/me solved the problem.

ssh slow

ssh -vv shows

debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
(wcfNote: This is where ssh -vv holds for long)
debug1: Unspecified GSS failure.  Minor code may provide more information
Cannot determine realm for numeric host address

Solution: in your client host, edit /etc/ssh/ssh_config, and comment out lines begin with "GSSAPIAuthentication yes".

SSH can input username and password, but can't login even with no error info in server log

If the client IP is 192.168.11.1, and the server IP is 192.168.10.1, it is usually network route problem. Try to modify the netmask from 24 to 23:


sudo route add -net 192.168.10.0 netmask 255.255.254.0 dev eth0
sudo route del -net 192.168.10.0 netmask 255.255.255.0 dev eth0

Resume / continue download file with scp

StackOverflow.


rsync --partial --progress --rsh=ssh [email protected]:~/sth.zip .