Linux网络
ssh登录
复制密钥
这个命令组合允许你无密码SSH登录,
ssh-copy-id
将密钥复制到远程主机,
并追加到远程账号的~/.ssh/authorized_keys
文件中。
复制SSH密钥到目标主机,开启无密码SSH登录。 如果还没有密钥,请使用ssh-keygen命令生成。
ssh-copy-id username@hostname
也可以一步将SSH公钥传输到另一台机器
ssh-keygen; ssh-copy-id user@host; ssh user@host
注意,如果在本地机器的~/.ssh
目录下已经有一个SSH密钥对,
ssh-keygen
命令生成的新密钥可能会覆盖它们,
复制stdin到本地缓冲区
将标准输入(stdin)复制到你的X11缓冲区
你是否使用scp将文件复制到工作用电脑上,以便复制其内容到电子邮件中? xclip可以帮到你,它可以将标准输入复制到X11缓冲区, 你需要做的就是点击鼠标中键粘贴缓冲区中的内容。
ssh user@host cat /path/to/some/file | xclip
压缩与加密
强制使用IPv4,压缩数据流,使用Blowfish加密。
ssh -4 -C -c blowfish-cbc
跳板机登录
通过中间主机建立SSH连接
ssh -t reachable_host ssh unreachable_host
Unreachable_host
表示从本地网络无法直接访问的主机,
但可以从reachable_host
所在网络访问,
这个命令通过到reachable_host
的「隐藏」连接,
创建起到unreachable_host
的连接。
连接屏幕
通过SSH连接屏幕 直接连接到远程屏幕会话(节省了无用的父bash进程)。
ssh -t remote_host screen –r
终端复用
人们总是喜欢在一个文本终端中打开许多shell,如果会话突然中断,
或你按下了Ctrl-a d
,远程主机上的shell不会受到丝毫影响,你可以重新连接,
其它有用的screen命令有Ctrl-a c
(打开新的shell)和Ctrl-a a
(在shell之间来回切换),请访问
http://aperiodic.net/screen/quick_reference
阅读更多关于screen命令的快速参考。
如果建立一个可以重新连接的远程GNU screen
ssh -t user@some.domain.com /usr/bin/screen –xRR
另一种方式: 打开一个SSH会话后,让其保持永久打开,对于使用笔记本电脑的用户, 如果需要在Wi-Fi热点之间切换,可以保证切换后不会丢失连接。
autossh -M50000 -t server.example.com 'screen -raAd mysession'
持久化连接
创建到目标主机的持久化连接
ssh -MNf @
在后台创建到目标主机的持久化连接,将这个命令和你~/.ssh/config
中的配置结合使用:
Host host ControlPath ~/.ssh/master-%r@%h:%p ControlMaster no
所有到目标主机的SSH连接都将使用持久化SSH套接字, 如果你使用SSH定期同步文件(使用rsync/sftp/cvs/svn),这个命令将非常有用, 因为每次打开一个SSH连接时不会创建新的套接字。
SSH传输
麦克风
将你的麦克风输出到远程计算机的扬声器 这样来自你麦克风端口的声音将在SSH目标计算机的扬声器端口输出,但遗憾的是,声音质量很差,你会听到很多嘶嘶声。
dd if=/dev/dsp | ssh -c arcfour -C username@host dd of=/dev/dsp
挂载目录
通过SSH挂载目录/文件系统
从http://fuse.sourceforge.net/sshfs.html
下载sshfs,
它允许你跨网络安全挂载一个目录。
sshfs name@server:/path/to/folder /path/to/mount/point
比较远程和本地文件
在比较本地文件和远程文件是否有差异时这个命令很管用。
ssh user@host cat /path/to/remotefile | diff /path/to/localfile –
控制带宽
使用cstream控制带宽
tar -cj /backup | cstream -t 777k | ssh host ‘tar -xj -C /backup’
使用bzip压缩文件夹,然后以777k bit/s速率向远程主机传输。 Cstream还有更多的功能,请访问http://www.cons.org/cracauer/cstream.html#usage了解详情,例如:
echo w00t, i’m 733+ | cstream -b1 -t2
断点传输大文件
rsync –partial –progress –rsh=ssh $file_source $user@$host:$destination_file
它可以恢复失败的rsync命令,当你通过VPN传输大文件, 如备份的数据库时这个命令非常有用,需要在两边的主机上安装rsync。
rsync –partial –progress –rsh=ssh $file_source $user@$host:$destination_file local -> remote # 或 rsync –partial –progress –rsh=ssh $user@$host:$remote_file $destination_file remote -> local
SSH进行网络测试
端口检测
knock 3000 4000 5000 && ssh -p user@host && knock 5000 4000 3000
在一个端口上敲一下打开某个服务的端口(如SSH),再敲一下关闭该端口,
需要先安装knockd
,下面是一个配置文件示例。
[options] logfile = /var/log/knockd.log [openSSH] sequence = 3000,4000,5000 seq_timeout = 5 command = /sbin/iptables -A INPUT -i eth0 -s %IP% -p tcp –dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 5000,4000,3000 seq_timeout = 5 command = /sbin/iptables -D INPUT -i eth0 -s %IP% -p tcp –dport 22 -j ACCEPT tcpflags = syn
吞吐量测试
通过SSH连接到主机,显示实时的传输速度,将所有传输数据指向/dev/null
,需要先安装pv
。
# 如果是Debian: apt-get install pv # 如果是Fedora:(可能需要启用额外的软件仓库)。 yum install pv
yes | pv | ssh $host "cat > /dev/null"
抓包流量分析
通过SSH W/ WIRESHARK分析流量
ssh root@server.com 'tshark -f "port !22" -w -' | wireshark -k -i –
使用tshark
捕捉远程主机上的网络通信,通过SSH连接发送原始pcap数据,
并在wireshark中显示,按下Ctrl+C将停止捕捉,但也会关闭wireshark窗口,
可以传递一个-c #
参数给tshark,让它只捕捉#
指定的数据包类型,
或通过命名管道重定向数据,而不是直接通过SSH传输给wireshark
我建议你过滤数据包,以节约带宽,tshark
可以使用tcpdump
替代:
ssh root@example.com tcpdump -w – ‘port !22′ | wireshark -k -i –
SSH代理
从某主机的80端口开启到本地主机2001端口的隧道
现在你可以直接在浏览器中输入http://localhost:2001
访问这个网站。
ssh -N -L2001:localhost:80 somemachine
ssh 命令除了登陆外还有三种代理功能:
-
正向代理(
-L
):相当于 iptable 的 port forwarding -
反向代理(
-R
):相当于 frp 或者 ngrok -
socks5 代理(
-D
):相当于 ss/ssr
如要长期高效的服务,应使用对应的专用软件。如没法安装软件, 比如当你处在限制环境下想要访问下某个不可达到的目标,或者某个临时需求, 那么 ssh 就是你的兜底方案。
正向代理:
所谓「正向代理」就是在本地启动端口,把本地端口数据转发到远端。
用法1:远程端口映射到其他机器
HostB 上启动一个 PortB 端口,映射到HostC:PortC
上,在 HostB 上运行:
HostB$ ssh -L 0.0.0.0:PortB:HostC:PortC user@HostC
这时访问HostB:PortB
相当于访问HostC:PortC
(和 iptable 的 port-forwarding 类似)。
用法2:本地端口通过跳板映射到其他机器
HostA 上启动一个 PortA 端口,通过 HostB 转发到HostC:PortC
上,在 HostA 上运行:
HostA$ ssh -L 0.0.0.0:PortA:HostC:PortC user@HostB
这时访问HostA:PortA
相当于访问HostC:PortC
。
两种用法的区别是,第一种用法本地到跳板机 HostB 的数据是明文的,
而第二种用法一般本地就是 HostA,访问本地的 PortA,数据被 ssh 加密传输给 HostB
又转发给HostC:PortC
。
反向代理:
所谓「反向代理」就是让远端启动端口,把远端端口数据转发到本地。
HostA 将自己可以访问的HostB:PortB
暴露给外网服务器HostC:PortC
,在 HostA 上运行:
HostA$ ssh -R HostC:PortC:HostB:PortB user@HostC
那么链接HostC:PortC
就相当于链接HostB:PortB
。使用时需修改HostC
的
/etc/ssh/sshd_config
,添加:
GatewayPorts yes
相当于内网穿透,比如 HostA 和 HostB 是同一个内网下的两台可以互相访问的机器, HostC是外网跳板机,HostC不能访问 HostA,但是 HostA 可以访问 HostC。
那么通过在内网 HostA 上运行ssh -R
告诉 HostC,创建 PortC 端口监听,
把该端口所有数据转发给我(HostA),我会再转发给同一个内网下的HostB:PortB
。
同内网下的 HostA/HostB 也可以是同一台机器,换句话说就是内网 HostA 把自己可以访问的端口暴露给了外网 HostC。
相当于在 HostA 上启动了 frpc,而再 HostC 上启动了 frps。
本地 socks5 代理
在 HostA 的本地 1080 端口启动一个 socks5 服务,通过本地 socks5 代理的数据会通过 ssh 链接先发送给 HostB,再从 HostB 转发送给远程主机:
HostA$ ssh -D localhost:1080 HostB
那么在 HostA 上面,浏览器配置 socks5 代理为127.0.0.1:1080
,
看网页时就能把数据通过 HostB 代理出去,类似 ss/ssr 版本,只不过用 ssh 来实现。
使用优化
为了更好用一点,ssh 后面还可以加上:-CqTnN
参数,比如:
$ ssh -CqTnN -L 0.0.0.0:PortA:HostC:PortC user@HostB
其中:
-
-C
:为压缩数据, -
-q
:安静模式, -
-T
:禁止远程分配终端, -
-n
:关闭标准输入, -
-N
:不执行远程命令。 -
-f
:参数,把 ssh 放到后台运行。
这些 ssh 代理没有短线重连功能,链接断了命令就退出了,所以需要些脚本监控重启, 或者使用 autossh 之类的工具保持链接。
功能对比
-
正向代理(
-L
)的第一种用法可以用 iptable 的 port-forwarding 模拟, iptable 性能更好,但是需要 root 权限,ssh -L
性能不好,但是正向代理花样更多些。 -
反向代理(
-R
)一般就作为没有安装 frp/ngrok/shootback 时候的一种代替, 但是数据传输的性能和稳定性当然 frp 这些专用软件更好。 -
socks5 代理(
-D
)其实是可以代替 ss/ssr 的,区别和上面类似。所以要长久使用, 推荐安装对应软件,临时用一下 ssh 挺顺手。
补充下 iptable 的 port-forwarding 怎么设置,十分管用的功能,两个函数即可:
#! /bin/sh # create forward rule by source interface # http://serverfault.com/questions/532569/how-to-do-port-forwarding-redirecting-on-debian PortForward1() { local IN_IF=$1 local IN_PORT=$2 local OUT_IP=$3 local OUT_PORT=$4 local IPTBL="/sbin/iptables" echo "1" > /proc/sys/net/ipv4/ip_forward $IPTBL -A PREROUTING -t nat -i $IN_IF -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT} $IPTBL -A FORWARD -p tcp -d $OUT_IP --dport $OUT_PORT -j ACCEPT $IPTBL -A POSTROUTING -t nat -j MASQUERADE } # create forward rule by source ip # http://blog.csdn.net/zzhongcy/article/details/42738285 ForwardPort2() { local IN_IP=$1 local IN_PORT=$2 local OUT_IP=$3 local OUT_PORT=$4 local IPTBL="/sbin/iptables" echo "1" > /proc/sys/net/ipv4/ip_forward $IPTBL -t nat -A PREROUTING --dst $IN_IP -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT} $IPTBL -t nat -A POSTROUTING --dst $OUT_IP -p tcp --dport $OUT_PORT -j SNAT --to-source $IN_IP }
第一个函数是按照网卡名称设置转发:
PortForward1 eth1 8765 202.115.8.2 8765
这时,本地 eth1 网卡的8765
端口就会被转发给202.115.8.2
的8765
端口。
第二个函数是按照本机的 ip 地址,比如本机是192.168.1.2
:
PortForward2 192.168.1.2 8765 202.115.8.2 8765
那么任何访问本机192.168.1.2
这个地址8765
端口,都会被转发到202.115.8.2:8765
这个 iptable 的 port forwarding 是内核层运行的,性能极好, 只不过每次重启都需要重新设置下。
配置文件
基本语法
按服务器器保存配置在~/.ssh/config
,方便以后连接:
Host Server1 Hostname 172.16.0.1 User zhangsan Port 22 ServerAliveInterval 180 IdentityFile ~/.ssh/secret_key.pem
每台服务器都可以定义一段配置:
-
起个名字
Server1
-
它的 IP 是
172.16.0.1
(也可以填 Hostname) -
用户名是
zhangsan
-
SSH 服务监听端口号为
22
(即默认值,也可以不写这一行) -
ServerAliveInterval 180
表示在建立连接后, 每 180 秒客户端会向服务器发送一个心跳,避免用户长时间没操作连接中断 - 最后一行表示使用一个专用的密钥,如果没有专用的密钥则删除该行即可。
以后连接直接输入:
ssh Server1
复制文件的命令也简化很多:
scp /path/to/local/file Server1:/path/to/remote/
配置免密也相同,输入以下命令并输入密码:
ssh-copy-id Server1
通配符配置
如果有一批服务器都是相同的配置,更是可以用通配符统一处理:
Host Server* User zhangsan Port 22 ServerAliveInterval 180 Host Server1 Hostname 172.16.0.1 Host Server2 Hostname 172.16.0.2 Host Server3 Hostname 172.16.0.3
第一段表示所有名字为Server*
开头的服务器,
然后下面列了 3 台服务器,我们只需要指定它们的 IP 地址。
多文件管理
如果需要管理非常多的服务器,全写到一个文件里会很乱很难维护。
~/.ssh/config
中支持引用其它文件。
新建一个这样的配置~/.ssh/config-cluster-shanghai
,
然后在~/.ssh/config
的开头加入如下一行即可:
Include config-cluster-shanghai
事实上这里也可以用通配符,比如:
Include config-*
这样~/.ssh/
目录下的所有config-*
开头的文件都会被引用到。
跳板
很多集群需要跳板机才可登录,我们需要先登录跳板机,再从跳板机登录内部机器。 这会引入两个麻烦,一是登录要两次, 如果配置 SSH config 还需要在跳板机也配置一份儿; 二是拷贝文件十分麻烦,要拷贝两次。
对此可以这样写配置:
Host Jumper Hostname 1.2.3.4 User zhangsan Host Server* User zhangsan ProxyJump Jumper ServerAliveInterval 180 Host Server1 Hostname 172.16.0.1 Host Server2 Hostname 172.16.0.2
第一段为跳板机的登录方式,第二段中新增了一个ProxyJump
字段,
表示所有 Server 开头的服务器,在登录的时候都要从 Jumper 这个服务器跳转一下。
这时候我们想登录172.16.0.1
,只需要直接输入:
ssh Server1 scp /path/to/local/file Server1:/path/to/remote/
注意一个细节是,这种配置下我们是直接从本地登录内部服务器,所以在配置免密时, 是需要把本地的公钥放到内部服务器的。
SCP 服务器间拷贝文件
scp 的基本用法相信大家都会,上文也多次提到。但如果想在两台服务器之间拷贝文件, 事实上是可以在本地执行 scp 的:
scp Server1:/path/to/file Server2:/path/to/file2
这个命令要求Server1
可以直接访问Server2
。如果不满足这个条件,可以用本机转发,
只需要增加一个参数-3
表示用本地机器当转发机:
scp -3 Server1:/path/to/file Server2:/path/to/file2