SSH
避免SSH自动断开连接
如果有一段时间在SSH连接上无数据传输,连接就会断开,以下设定可以解决这个问题
方案一:在客户端设置
sudo vim /etc/ssh/ssh_config
开启 ServerAliveInterval 60
开启 TCPKeepAlive yes
此后该系统里的用户连接SSH时,每60秒会发一个KeepAlive请求,避免被踢。
方案二:在服务器端设置
sudo vim /etc/ssh/sshd_config
开启ClientAliveInterval 60
开启 TCPKeepAlive yes
如果您只想让当前的 ssh 保持连接,可以使用以下的命令:
ssh -o ServerAliveInterval=60 user@sshserver
ssh 链接复用
Host *
ForwardAgent yes
ServerAliveInterval 30
ServerAliveCountMax 20
TCPKeepAlive no
ControlMaster auto
ControlPath ~/.ssh/connection-%r@%h:%p
ControlPersist 20m
Compression yes
http://einverne.github.io/post/2017/05/ssh-keep-alive.html
https://www.cyberciti.biz/faq/linux-unix-reuse-openssh-connection/
ssh隧道
CfNg参数
- C表示压缩数据传输
- f表示后台用户验证,这个选项很有用,没有shell的不可登陆账号也能使用.
- N表示不执行脚本或命令
- g表示允许远程主机连接转发端口,往往会没有效果,需要修改
/etc/ssh/sshd_config
添加gatewayports yes
- T禁止分配伪终端,如果ssh使用此选项登录系统时,由于禁用,将无法获得终端;但仍能够获得shell,只不过看起来像在本地,也没有很多应有的环境变量,例如命令提示符,PS1等
- n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background
-L本地转发
-L [本地监听IP:]本地监听端口号:目标主机IP:目标端口号 (其中,“本地监听IP”可以省略,省略的话就认为是“0.0.0.0”,但为了安全性考虑,请务必使用“127.0.0.1”做为本地监听端口, 而不要使用默认的“0.0.0.0”。)
ssh -D 8080 user@host
SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。
ssh -L 2121:host2:21 host3
命令中的L参数一共接受三个值,分别是"本地端口:目标主机:目标主机端口”,它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。
这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。
ssh -CTfNg -L 6300:127.0.0.1:1521 oracle@172.16.1.164
本机的6300端口就是远程主机172.16.1.164的1521端口
socket 转发
OpenSSH 自 6.7 开始支持sock文件转发,将远程sock文件映射到本地.
例如将远程docker的socket映射到本地
ssh -CTfNng -L $(pwd)/docker.sock:/var/run/docker.sock user@someremote
通过跳板机映射socket
ssh -CTfNng -L $(pwd)/docker.sock:/var/run/docker.sock -o "ProxyCommand ssh -q -W %h:%p -p 27897 user@gateway" -p 61177 user@someremote
export DOCKER_HOST=unix://$(pwd)/docker.sock
本机就可以连接docker了
ssh 跳板 (ssh over ssh)
ssh -o 'ProxyCommand ssh -q -W %h:%p root@transferip' root@targetip
ssh over socks5
ssh -o ProxyCommand='nc -x 192.0.2.0:1080 %h %p' user@targetip
测试发现苹果自带的nc
使用-x
会有一些问题,总是还未连上时stdin就输入一些数据,导致链接不成功.
brew install nmap
安装Linux版本的nmap,安装后就会有ncat nmap nping ndiff
等命令
ssh -o 'ProxyCommand ncat --proxy-type socks5 --proxy 172.168.1.3:2388 %h %p' -p port root@hostip
nc 的参数-x
指定了使用sock5代理
有了ssh over socks5
, ssh over ssh
还可以以另一种方式实现
ssh -D 127.0.0.1:1080 user1@ssh-server1
先打通一个本地socks5,然后再使用ssh over socks5
注意 Linux 的 ncat 版本 使用代理的参数并非-x
nc --proxy 192.168.1.85:2388 --proxy-type socks5 targetip targetport
ssh over socks5 proxy + socket 映射
ssh -CTfNng -L /var/run/docker.sock:/var/run/docker.sock -o 'ProxyCommand ncat --proxy-type socks5 --proxy 172.168.1.3:2388 %h %p' -p 61177 root@targetip
https://github.com/ernw/static-toolbox/releases
参考 : https://www.robberphex.com/2015/09/426
-R远程转发
ssh -CTfNg -R 1521:127.0.0.1:6300 oracle@172.16.1.164
在远程主机172.16.1.164上打开1521端口, 来映射本机的6300端口.
在树莓派上映射ssh到外网
ssh -CTfNg -R 2222:127.0.0.1:22 username@yourvps.com
这样就映射vps的2222端口到树莓派上了.但是这样映射的是服务器的127.0.0.1:2222,外网无法连接这个2222端口
如果你自己的服务器连接时需要端口可以在最后加上 -p port
指定ssh的端口
可以在服务器上执行netstat -anltp
查看,这样要先登陆到自己的vps才能通过2222访问树莓派.
可以使用
ssh -CTfNg -R 0.0.0.0:2222:127.0.0.1:22 username@yourvps.com
再在服务器上配置/etc/ssh/sshd_config
#增加下面一句
GatewayPorts yes
#如果有
GatewayPorts no
#则改为
GatewayPorts yes
#然后重启ssh
#centos7: systemctl restart sshd
#centos6: service sshd restart
#ubuntu: service ssh restart
使用netstat -anltp
查看,监听的已经是0.0.0.0
了,不过即使你指定-R参数127.0.0.1:2222
,也不会监听127.0.0.1
而始终是0.0.0.0
若没有netstat
可考虑安装yum install lsof net-tools
使用下面的脚本可以保持断开自动重连,可以作为frp
穿透的简单替代
需事先配置好ssh免密码登陆
先编写一个可执行脚本,例如
/home/osmc/.autossh
#!/bin/bash
while true; do ssh -CTNg -R 2222:127.0.0.1:2222 -p 23 username@yourvps.com; sleep 5;done;
赋予执行权限 chmod +x /home/osmc/.autossh
编写service文件 使用systemd
开机启动
/etc/systemd/system/autossh.service
[Unit]
Description=autossh service
After=network.target network-online.target
[Service]
User=osmc
Restart=on-failure
TimeoutStartSec=0
ExecStart=/home/osmc/.autossh
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable autossh
sudo systemctl start autossh
sudo systemctl status autossh -l
查看状态
此方法存在缺陷,有时候断开无法连接上,最好还是使用frp
使用socks5代理
alias socksproxy="ssh -NT -f -C -D 0.0.0.0:1090 -p 1234 root@host";
-D 绑定地址 -N 不打开远程的shell -T 不分配tty -f 后台运行 -C 使用压缩
执行socksproxy
后就建立了一条ssh socks5 proxy,本地使用127.0.0.1:1090就可以使用服务器中转流量.
ssh 服务
chkconfig --list
可以查看所有服务是否开机启动等.
chkconfig --list sshd
可以单独查看sshd服务的启动状态
/var/empty/sshd
文件夹是sshd所必须的,不能被删除否则ssh服务将无法启动
chkconfig sshd on
将其设置为开机启动
CentOS7 用systemctl
取代了service
旧版本的 chkconfig docker on
改为 systemctl enable docker
https://www.ssh.com/ssh/copy-id
ssh 使用了ssh-copy-id 任然不能免密码登录问题
- 检查权限问题
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
## 如果上面还不行,使用这个
chmod 700 ~/.ssh ; chmod 600 ~/.ssh/authorized_keys ; chmod g-w,o-w ~ ## chmod go-w ~
## 验证文件夹所属权
chown -R root ~
chgrp -R root ~/.ssh/
- 确保sshd配置文件没有禁用密匙验证
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
sshd 配置文件
grep -Ev '''^(#|$)''' sshd_config
可查看有效的配置(排除注释)
/etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding no
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem sftp /usr/libexec/openssh/sftp-server
编译openssh
http://www.openssh.com/ftp.html
在alpine中编译openssh,镜像地址 http://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/
编译完成后得到一些工具,如scp
,sftp-server
,ssh
,sshd
等等
apk update && apk upgrade
apk --update add make curl gcc g++ zlib-dev openssl-dev
cd /tmp
OPENSSH_VERSION=openssh-7.6p1
CPU_NUM=`cat /proc/cpuinfo | grep processor | wc -l`
curl http://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/${OPENSSH_VERSION}.tar.gz | tar xz
cd ${OPENSSH_VERSION}
./configure
make -j$CPU_NUM CFLAGS="-Os" LDFLAGS="-static -L./ -L./openbsd-compat/" && make install
即可静态编译.
我编译好的二进制文件,能直接用于alpine系统
配合Linuxadduser
,可以ssh到docker中
curl -o /usr/local/bin/sshd.xz http://share.suconghou.cn/files/bin/sshd.xz
sshd运行不能直接执行sshd,需要执行/usr/local/bin/sshd
配置文件为/usr/local/etc/sshd_config
,同时还需要几个密匙文件.
curl -o /usr/local/bin/sshd.xz http://share.suconghou.cn/files/bin/sshd.xz
xz -d /usr/local/bin/sshd.xz
chmod +x /usr/local/bin/sshd
mkdir -p /usr/local/etc/
touch /usr/local/etc/sshd_config
ssh-keygen -t dsa -f /usr/local/etc/ssh_host_dsa_key -N ''
ssh-keygen -t rsa -f /usr/local/etc/ssh_host_rsa_key -N ''
ssh-keygen -t ecdsa -f /usr/local/etc/ssh_host_ecdsa_key -N ''
ssh-keygen -t ed25519 -f /usr/local/etc/ssh_host_ed25519_key -N ''
添加一个用户:adduser work
,Alpine里是adduser
,Linux发行版里是useradd
adduser work -M -N
cat /etc/passwd 可以查看所有用户的列表,只输出用户名可以cat /etc/passwd |cut -f 1 -d :
看第三个参数:500以上的,就是后面建的用户了.其它则为系统的用户.
cat /etc/group 查看用户组
非交互式修改密码
在 Linux 中 passwd
echo "1234" | passwd --stdin work
在alpine/buxybox 中 chpasswd
echo "1234" | chpasswd
(默认修改当前用户的密码)
w 可以查看当前活跃的用户列表
删除用户userdel
, 用户userdel -r 用户名
,删除用户账户及用户主目录文件
没有外网IP还可以使用ssh建立一个隧道
ssh -CfNg -R 0.0.0.0:2233:127.0.0.1:22 root@yourvps.com -p 27558
编译dropbear
dropbear 是一个更加小巧的sshd
https://matt.ucc.asn.au/dropbear/dropbear.html
cd /tmp
apk update && apk upgrade && apk add wget make gcc g++ linux-headers
wget --no-check-certificate https://matt.ucc.asn.au/dropbear/releases/dropbear-2017.75.tar.bz2
tar jxvf dropbear-2017.75.tar.bz2 && cd dropbear-2017.75
CFLAGS="-Os -ffunction-sections -fdata-sections" LDFLAGS="-static -Wl,--gc-sections" ./configure --disable-zlib
make -j2
不到一分钟即可编译完成
mkdir /etc/dropbear
后台运行 ./dropbear -E -R -m
不进入后台 ./dropbear -F -E -R -m
-m
意味着用户登陆成功后不显示/etc/motd
文件内的提示.
dbclient
是一个和ssh类似的客户端
然后linux系统的用户即可通过22端口登陆
CentOS7修改ssh端口
注意:修改ssh端口后,可能还是不能使用,主要原因可能是semanage
使用以下命令查看当前SElinux 允许的ssh端口: semanage port -l | grep ssh
添加xxxx端口到 SELinux semanage port -a -t ssh_port_t -p tcp xxxx 然后确认一下是否添加进去 semanage port -l | grep ssh 如果成功会输出 ssh_port_t tcp xxxx, 22
autossh
sudo yum install gcc make
wget http://www.harding.motd.ca/autossh/autossh-1.4e.tgz
tar zxf autossh-1.4e.tgz
cd autossh-1.4e
./configure && make
zsh
Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + r:逆向搜索命令历史 Ctrl + g:从历史搜索模式退出 Ctrl + p:历史中的上一条命令 Ctrl + n:历史中的下一条命令
http://jaywcjlove.github.io/handbook/html/Vim%E7%90%86%E8%A7%A3.html
sudo 记住密码时间
mac 系统 在第一次执行sudo命令后,默认情况下密码将持续15分钟,因此您不需要为每个sudo命令键入密码
可以修改 /etc/sudoers
文件配置该时间 使用 sudo visudo
修改此文件
Defaults env_reset,timestamp_timeout=60
这里设置为1小时
如果要为每个执行的sudo命令输入密码提示,也可以将时间设置为0
ssh 远程执行后台命令
&>/dev/null
>/dev/null 2>/dev/null
>/dev/null 2>&1
三者是等价的。
https://www.gnu.org/software/bash/manual/bash.html#Redirecting-Standard-Output-and-Standard-Error
1.sh
是一个耗时操作
ping -c 10 8.8.8.8
ssh user@host "/1.sh"
客户端会执行等待执行完后退出,客户端显示脚本的输出,中途客户端终止,脚本立即终止执行
ssh user@host "nohup /1.sh"
ssh user@host "nohup /1.sh &"
这两种与第一种结果一样.
如果想要后台运行,需要
ssh user@host "nohup /tmp/1.sh >/dev/null &"
至少需要把标准输出重定向到一个文件才行。
这样做 更保险
ssh user@host "nohup myprogram > foo.out 2> foo.err < /dev/null &"
要做到显示一部分数据,然后后台呢?
修改我们要执行的脚本
1.sh
echo "go to background"
nohup ping -c 20 t.cn &>/dev/null &
echo "ping is in background "
ps aux | grep ping
客户端执行 ssh user@host "/1.sh"
需要注意的是,这里 nohup 加不加都可以,但是最后的&符号必须,否则会造成客户端等待。
即使使用 nohup
和 &
, 重定向标准输出始终是必须的,否则造成客户端等待,并打印这些输出,至少需重定向标准输出。
nohup ping -c 20 t.cn &>/dev/null </dev/null &
ssh直接开启后台任务:
ssh user@host "nohup ping -c 10 t.cn &>/dev/null </dev/null &"
>/dev/null 2>&1
注意 2>&1
必须放在后面
linx rsync
server
rsync --daemon --port 15577
client