标签 ssh 下的文章

OpenSSH建立二层和三层加密隧道

OpenSSH 可以使用tun/tap设备来创建一个加密隧道,SSH隧道类似mode TCP模式下的OpenVPN,对于有需求快速设置一个基于IP的VPN来说非常方便。使用SSH隧道的优点:

  1. 不需要安装和配置额外的软件
  2. 使用SSH认证并自带加密,不需要使其它VPN软件一样配置共享密钥或者证书
  3. 兼容性强,可以建立二层隧道或三层隧道,所有3/4层协议如:ICMP、TCP/UDP 等都可支持
  4. 配置过程简单

当然也有缺点:

  1. 基于TCP协议,其传输效率较低
  2. 隧道依赖于单个TCP连接,容易中断或假死
  3. 需要ROOT权限

这里还要说明一下二层和三层的区别:

  • layer 2 : 交换单元是帧,只识别MAC地址,只有交换功能,相关协议:Ethernet、VLAN、STP、PPP、FDDI、ARP(OSI模型)、MPLS(介于2层3层之间)等,在Linux中是虚拟点对点设备,显示为tap
  • layer 3 : 交换单元是包,能识别MAC地址和IP,有交换和路由功能,相关协议:IP、ICMP、IGMP、IPsec等,在Linux中是虚拟以太网设备,显示tun

在Linux中tun/tap都可以设置IP,只是模拟的工作层有区别,tun是模拟三层网络设备,收发的是IP包,无法处理以太网数据帧。tap模拟的是二层设备,收发的是以为网数据帧,更接近物理网卡,可以和物理网卡通过网桥绑定。我们日常用的wmware虚拟机中的nat网络,对应的就是tun,桥接网络对应的就是tap。

一、ssh server端配置

首先要使用ssh的二层和三层隧道,尽量保证系统差别不要太大,我这里两边都是oracle linux 8,SSH版本更新到最新。server端需要允许root登录和隧道,编辑/etc/ssh/sshd_config:

PermitRootLogin yes
PermitTunnel yes
#建议添加
TCPKeepAlive yes

PermitTunnel yes代表允许point-to-point (layer 3)和ethernet (layer 2)

二、三层隧道配置

2.1 建立三层隧道

在client端执行:

ssh -w any:any  root@[server_ip] 

如果客户端和服务器端没有其它的tun设备,就会在客户端和服务器端各生成一个名为tun0设备,指定any可以自动分配可用的设备。查看设备:

[root@centos8 ~]# ip addr
3: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 500
    link/none 

可以看到有个tun0 <POINTOPOINT,MULTICAST,NOARP>,这个设备是未激活的状态,如果用ifconfig命令查看,需要加上-a参数才能看到。

为安全起见,建议使用以下命令:

ssh -NTCf -w 5:5 root@[server_ip]
  • “-N”:不执行远程命令
  • “-T”:不分配终端
  • “-C”:压缩传输的流量
  • “-f”:在客户端后台运行

执行完该命令client和server各自会创建一个tun5的点对点设备,下一步就是需要激活设备并分配IP。

2.2 分配IP并激活隧道

分配IP不要与服务器和客户端网段有冲突,这里假设:

客户端IP:10.0.0.2 tun5
服务器IP:10.0.0.1 tun5

服务器激活点对点设备并分配IP和路由:

ip link set tun5 up
ip addr add 10.0.0.1/32 peer 10.0.0.2 dev tun5

客户端同理:

ip link set tun5 up
ip addr add 10.0.0.2/32 peer 10.0.0.1 dev tun5

这时隧道已经建立成功,此时用查看一下状态:

[root@centos8 ~]# ip addr
14: tun5: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none 
    inet 10.0.0.1 peer 10.0.0.2/32 scope global tun5

可以看到比之前多了“UP,LOWER_UP”,说明已经激活。正常情况下客户端和服务器已经可以相互ping。

客户端用一条命令也能搞定:

ssh \
  -o PermitLocalCommand=yes \
  -o LocalCommand="ip link set tun5 up && ip addr add 10.0.0.2/32 peer 10.0.0.1 dev tun5 " \
  -o TCPKeepAlive=yes \
  -w 5:5  root@[server_ip] \
  'ip link set tun5 up && ip addr add 10.0.0.1/32 peer 10.0.0.2 dev tun5'
  

2.3 添加其它网段的路由

如果服务器端有其它内网段,需要继续添加客户端路由才能ping通,例如,客户端想与服务器端网段10.0.12.0/24互通,需在客户端执行:

ip route add  10.0.12.0/24 dev tun5

按需添加即可,更改路由是高风险操作,需要格外小心,同时也要确保ssh连接不要中断。

三、二层隧道配置

由于linux中允许为tap设备设置ip,所以二层隧道和三层隧道也可以完全一样的进行配置。区别是tap设备可以和物理网卡进行绑定,也就是桥接,同时由于工作在二层,允许Arp通过,能支持STP生成树、PPP等协议。

3.1 建立二层隧道

在客户端执行:

ssh  -o Tunnel=ethernet -w 6:6    root@[server_ip] 

这里参数 -o 需要在 -w 前面,查看一下客户端和服务器的网卡:

[root@centos8 ~]# ip addr
20: tap6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000

在ip命令中 tap6: <BROADCAST,MULTICAST>,和物理网卡显示的一样,说明模拟的是物理网卡。

3.2 创建并配置网桥

二层可以进行网卡桥接,桥接可以多块网卡,也可以一块网卡,这里测试为了省事只用一块网卡,创建网桥有三种工具:

  1. 使用bridge-utils中的brctl命令
  2. 使用oracle linux 8 系列自带的nmcli
  3. 使用ip命令

建议用ip命令建立:

ip link add br0 type bridge

将tap6加入网桥:

ip link set tap6 master br0

配置服务器端网桥IP信息并启动网桥:

ip address add 10.0.0.1/32 dev br0
ip link set tap6 up
ip link set br0 up

客户端流程一样,只是客户端的ip是10.0.0.2

在客户端测试ARP包能不能通过:

[root@oracle8 ~]# arping -I br0 10.0.0.1
ARPING 10.0.0.1 from 10.0.0.2 br0
Unicast reply from 10.0.0.1 [3A:E7:2F:3F:42:24]  193.222ms
Unicast reply from 10.0.0.1 [3A:E7:2F:3F:42:24]  191.903ms

如果是三层隧道,就无法使用arping。

看似很多内容,其实使用很简单,OpenSSH套件功能真强大。

参考文章
https://help.ubuntu.com/community/SSH_VPN
https://www.cyberciti.biz/faq/centos-8-add-network-bridge-br0-with-nmcli-command/
https://gobomb.github.io/post/build-l2-l3-vpn-by-openssh/

ssh启用两步验证的一些玩法

正常的服务器都是使用 用户名+密码或者用户名+ssh key的方式登录,配合防火墙及合理的ssh配置,能达到很好的安全性。但是无论密码还是ssh key都是固定不变的,一旦被渗透等就会导致登录信息泄露,这时如果启用了多因子认证,就能防止黑客通过ssh登录。多因子认证是在原有的认证基础上,在加一个或多个基于时间不断变化的验证码、或生物指纹、面部识别的认证,只要这个信息不泄漏,即使原认证信息泄露也无法登录。

最常见的多因子验证,就是谷歌的两步验证。类linux的系统中,很多软件都是使用pam模块做认证的,谷歌开源了google-authenticator-libpam工具,理论上支持pam认证的软件都可以启用谷歌两步认证。下面就说一下ssh配置两步认证的过程和一些玩法。

一、编译

centos 的epel源中有现成的包,debian中也有,直接使用dnf就能安装,我这里使用编译的方式安装。

dnf install git autoconf automake  make  libtool gcc   

在命令行显示二维码用到 libqrencode ,

dnf install qrencode

两步认证用到了pam认证框架,需安装pam-devel

dnf install pam-devel

编译:

git clone https://github.com/google/google-authenticator-libpam.git
cd google-authenticator-libpam

./bootstrap.sh
./configure

make
sudo make install

主要用到以下两个文件

  1. 执行程序: /usr/local/bin/google-authenticator
  2. pam库文件:/usr/local/lib/security/pam_google_authenticator.so

二、设置时间同步

TOTP是基于时间的,在初始化两步验证之前,先对一下时间,如果有ntpdate命令,执行:

ntpdate time.cloudflare.com

把这这个命令加到定时任务中,一定要确保服务器时间准确。

如果系统是redhat8,系统中ntp已经被chrony替代,执行以下命令:

dnf install -y chrony

systemctl enable chronyd

systemctl start chronyd

查看时间同步时间源服务器:

chronyc sources 

查看同步状态:

chronyc tracking 

三、初始化两步验证

准备工作做完后,就可以初始化两步验证,首先需要手机或个人电脑中安装两步验证的客户端,例如:谷歌验证器、authy等。

3.1 手动初始化

在服务器上执行:

google-authenticator

google-authenticator 初始化步骤:

  第1个:是否想启用基于时间的令牌,选择y

  第2个:是否更新认证文件(root用户是/root/.google_authenticator),由于第一次设置文件不存在,选择y 

  第3个:是否禁止多个用户公用认证口令,有可能会产生中间人欺骗,即令牌用过一次即失效,禁止选择y

  第4个:默认1个口令的有效期是30s,为了防止主机时间和口令客户端时间不一致,最多允许客户端和服务器误差4分钟,服务器上已经设置时间同步,选择n

  第5个:是否启用防暴力破解,30s内不得超过3次登陆测试,选择y

这里需要用手机客户端扫描生成的二维码,初始化完成后会生成两步验证的配置文件,root用户在/root/.google_authenticator,普通用户在/home/user/.google_authenticator,文件的属主要和用户一致,不然会导致无法登录。

3.2 使用参数方式初始化

和手动初始化一样,只是使用参数的方式,不需要交互,方便进行自动化和脚本调用

google-authenticator -t -d -r 3 -R 30 -w 3 -s /root/.google_authenticator
-t: 基于时间的令牌
-d: 不允许令牌重用
-r 3: 限制错误次数为3次
-R 30: 限制验证时间窗口为 30s
-w 3:  验证窗口为3个,当前验证令牌的前一个和后一个均是生效的,也就是允许误差
-s : 保存位置,默认为~/.google_authenticator

四、配置ssh

配置sshd_config,编辑 /etc/ssh/sshd_config,添加:

ChallengeResponseAuthentication yes
UsePAM yes

重启sshd

systemctl restart sshd

五、配置pam

5.1 登录时先输入两步验证码,在输入ssh密码的配置方法

编辑 /etc/pam.d/sshd,在第一行添加:

auth  required  /usr/local/lib/security/pam_google_authenticator.so  [authtok_prompt='请先输入两步验证码:' ]  secret=/root/.google_authenticator  no_increment_hotp

no_increment_hotp :不统计失败的两步认证,防止有被暴力破解时锁定用户。

配置好后,可以用ssh或者xshell客户端登录一下,登录过程:

ssh root@172.16.29.100                                                 
'请先输入两步验证码:'
Password:
Last login: Wed Jan 20 17:09:39 2021 from 172.16.29.1
[root@nixops.me ~]#

5.2 先输入ssh密码,在输入两步验证码

编辑 /etc/pam.d/sshd,在最后一行添加:

   auth  required  /usr/local/lib/security/pam_google_authenticator.so nullok

通过以上的配置,ssh密码 + 谷歌两步验证的登录方式就配置完成了。

六、一些玩法

因为使用了pam框架,有一些基于pam的程序,都可以试着启用两步验证

6.1 普通用户使用su命令时,需要两步验证码

编辑/etc/pam.d/su,找到开头这里:

#%PAM-1.0
auth            required        pam_env.so
auth            sufficient      pam_rootok.so

在 pam_rootok.so这一行下面,加入

    auth required /usr/local/lib/security/pam_google_authenticator.so [authtok_prompt='请先输入两步验证码:' ] secret=/root/.google_authenticator no_increment_hotp

加入后,root切换至普通用户不需要两步验证,普通用户切换至root,或者普通用户之间切换需要先进行两步验证

6.2 sudo命令需要两步验证码

sudo 实际上是以root用户执行命令,在pam的规则中指定一下user即可,编辑/etc/pam.d/sudo,在第一行加入

    auth requisite /usr/local/lib/security/pam_google_authenticator.so [authtok_prompt='请先输入两步验证码:' ] secret=/root/.google_authenticator user=root

6.3 特定IP或者网段不进行两步验证

编辑/etc/pam.d/sshd,在顶部添加:

    auth [success=1 default=ignore] pam_access.so accessfile=/etc/totp_access.conf
    
    auth       required /usr/local/lib/security/pam_google_authenticator.so [authtok_prompt='请先输入两步验证码:' ] secret=/root/.google_authenticator  no_increment_hotp

规则文件/etc/totp_access.conf的内容为:

    + : ALL : 10.20.10.100
    + : ALL : 172.16.19.0/24
    + : ALL : LOCAL
    - : ALL : ALL

6.4 ssh三重认证

安全不在于登录过程中多几道认证,但是对于某些要求较高或者特殊的场景下,可能会有需要多重认证的情况,三重认证包括以下认证方式:

  1. publickey (SSH key)
  2. password publickey (SSH key 的密码)
  3. keyboard-interactive (两步验证码)

和ssh密码认证的方式类似,只是把密码认证改成了ssh publickey + publickey password而已,配置思路也是一样,只是需要sshd_config中多加两条配置,用来指定登录使用的认证方式:

PubkeyAuthentication yes
AuthenticationMethods publickey,password publickey,keyboard-interactive

6.5 多用户启用两步认证

如果服务器中不只有一个用户,pam配置中可以使用变量${USER}来配置多用户,不需要为每个用户写一条pam配置,例如:

auth       required     pam_google_authenticator.so secret=/home/${USER}/.ssh/google_authenticator nullok

如果想做自动化,可以定制一个.bash_profile文件,将这个.bash_profile文件放到/etc/skel/中,这样每次创建用户后就会复制到用户目录下,当用户第一次登录后,调用其中的脚本生成/home/${USER}/.google_authenticator,从而自动绑定两步认证,这里只提供思路,不做具体实现。

参考文章:
https://www.redhat.com/sysadmin/mfa-linux
https://wiki.archlinux.org/index.php/Google_Authenticator
https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-centos-8

ssh通过代理连接服务器

网上用ssh隧道来翻墙的教程比较多,通过代理连接ssh的文章相对较少,这种方法适用于网络中防火墙屏蔽了ssh协议,或者其它原因无法通过ssh直连服务器的情况。配置好后ssh流量会通过指定的代理中转,从而突破防火墙的限制,主要用到了ssh client的ProxyCommand选项,需要配合第三方代理软件

一、 SSH over http

Corkscrew是专门为ssh提供http代理的软件,要使用corkscrew需要http代理支持HTTP CONNECT方法,建议使用squid或者ATS这类专业的代理软件,代理不建议设置认证

1.1 Corkscrew安装

下载:

wget http://agroman.net/corkscrew/corkscrew-2.0.tar.gz

编译安装:

./configure
make && make install

1.2 配置

假设我的http代理是proxy.nixops.me,端口是8080;ssh服务器是nixops.me,ssh端口2882,格式:

ssh user@server -o "ProxyCommand corkscrew 代理地址 代理端口 ssh服务器地址 ssh端口 "

测试一下:

ssh -p2882 root@nixops.me -o " ProxyCommand /usr/local/bin/corkscrew  proxy.nixops.me 8080  server.nixops.me 2882 "

正常会弹出ssh输入密码的提示,这时的ssh就是通过http代理连接到服务器的。每次都这样连接比较麻烦,将配置写入ssh_config文件中,配置全局使用http代理:

编辑ssh客户端配置文件 /etc/ssh/ssh_config,加入:

Host *
ProxyCommand corkscrew proxy.nixops.me 8080 %h %p

%h表示目标地址,%p是目标端口。这样配置后,用ssh user@host连接服务器就会通过http代理中转。
非全局配置,可以指定具体的ip:

Host nixops  #别名,可以不设置
Hostname server.nixops.me  #域名或者ip
User root
Port 2862
#IdentityFile 证书路径
ProxyCommand corkscrew proxy.nixops.me 8080  %h %p

使用下面命令连接即可:

ssh nixops

如果ssh配置无密码证书登录,是不是有种ssh跳板机的感觉?

二、ssh over socks

corkscrew不支持socks代理,如果是socks代理要使用nc,或者其它支持socks的软件,配置和上面类似:

ProxyCommand nc -X 5 -x socks5.nixops.me:1080 %h %p

nc非常强大,我的http代理支持CONNECT方法,即能打开https的网站,也可以用nc代替corkscrew:


ProxyCommand nc -X connect -x proxy.nixops.me:8080 %h %p

个人更喜欢用nc,因为各发行版的包管理中都有,使用起比方便。proxycommand 命令相当的灵活,不只是http和socks代理,如果有其它形式的代理,只要有客户端支持都可以用

putty免密码登陆

    putty是没有记住密码的功能的,出于安全性考虑官方也不会支持这一功能。
我自己翻墙使用的是ssh tunnel,经常有假死需要重连情况发生,每次都要输入密码很麻烦,于是谷歌找到了一个不用输入密码的自动登陆的方法,设置好后点下鼠标就可以了。正适合我这种懒人

我的系统是ubuntu 10.04

安装putty

apt-get install putty

- 阅读剩余部分 -

使用autossh隧道实现mysql的同步

一、准备知识

1.1 什么是 autossh?

假设有两台主机: A 主机为外网,B 主机为内网
通常来说外网主机 A 是无法直接连接到内网主机 B 的,这时如果要实现 A 主机通过 ssh 连接 B 主机,通常来说有两种方法:

  1. 端口映射: 将 B 主机的 ssh 端口映射到 B 的外网 ip,当然这要通过设置防火墙来实现
  2. ssh 的反向连接: B 主机通过 ssh 连接到 A 主机,并在 A 主机上打开一个端口进行监听。这时如果 A 主机连接本机的这个端口就可以实现控制 B 主机
ssh -NfR 1111:localhost:2222 user1@外网主机A -p22

2222 为 A 主机在 B 打开的监听端口,1111 为 A 主机本地的端口,这时访问 B 主机的 2222 端口就映射在 A 主机的 1111 端口了。这个也叫远程端口映射。

这种反向连接很有用,但是很不稳定,经常断开。每次断开都要重新执行上面的命令,如果想要断开时自动执行这个命令,这就需要 Autossh 来完成了。

1.2 为什么要使用 ssh 来完成 mysql 的主从同步?

和上面的情况一样,一台内网主机要和一台外网主机做主从同步

二、实现步骤

2.1 生成密钥

登陆内网主机 B 上执行下面的命令来生成 ssh 密钥,一路回车就可以

ssh-keygen -t rsa

2.2 上传密钥

将内网主机 B 生成的 pub 文件上传到 A 主机

ssh-copy-id -i .ssh/id_rsa.pub user@外网主机A

或者将 id_rsa.pud 文件 scp 过去,执行

cat id_rsa.pub >> ~/.ssh/authorized_keys

2.3 启用证书

编辑 A 主机上的 /etc/ssh/sshd_config, 去掉以下三行的注释:

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

2.4 测试登陆

这时 B 主机 ssh 到外网 A 主机就使用证书登陆了,不用输入密码了

2.5 安装软件

这里就用到了上面的 autossh,内网主机 B 需要安装 autossh,A 主机不需要

wget http://www.harding.motd.ca/autossh/autossh-1.4c.tgz
tar -xf autossh-1.4c.tgz
cd autossh-1.4c
./configure
make install

2.6 端口映射

在内网主机 B 上使用 autossh 将本机的 13306 端口映射到外网主机 A 的 3306 端口

autossh -M 20522 -f -N -L 13306:localhost:3306 user@外网主机A

2.7 mysql 同步

这时就可以使用本机的 13306 端口进行 MySQL 服务器的同步了

MySQL 服务器如何配置主从同步请参见:

http://www.nixops.me/mysql-server-replication-config.html

参考文档

http://www.cnblogs.com/eshizhan/archive/2012/07/16/2592902.html

最新文章

最近回复

  • LHL: 写了一个功能更加丰富...
  • immortal: 大佬好强!!!
  • myogg: 您好,这个能不能将发...
  • 大青蛙子: 照着大佬的命令行复刻...
  • see: 把虚拟机平台下面其他...
  • see: 感觉是兼容性问题,我...
  • see: 做了。因为inter...
  • see: 遇到一个ipv6问题...
  • pluveto: 这功能很好
  • mgt: 从fail2ban的...

分类

归档

统计

  • 文章总数:169篇
  • 分类总数:5个
  • 评论总数:131条
  • 页面总数:173个
  • 本站运行:5599天

其它