内网主机ssh安全暴露公网的frp实现方式
ssh暴露是否有必要通常作为服务器，一般向外提供http/https服务，通用端口80或者443端口向外暴露即可，对于现在主流的微服务架构，每个服务会通过内网的方式连接自己的数据库服务（小规模网站实现）这种实现的好处是可以非常方便的整体服务迁移，迁移成本会很低。对外暴露的80或者443端口通常由网关程序或者代理程序（如nginx）负责网络入口监听，服务器的管理由内网ip主机进行ssh连接管理。从安全和维护角度ssh公网暴露似乎没有太大必要。ssh公网暴露的需求首先公网暴露ssh肯定是对于有跨域远程访问需求的用户，服务主机在远端或者代理背后的主机，需要远程维护管理。自建服务器网络方式对于自建服务器的网络（不包括VPS，购买的公有云主机默认是分配公网ip的）可以分为两种情况，一种是用户公网ip（ipv4），另一种是运营商不提供公网只是普通的家庭宽带网络。这两种不同网络对应不同对外提供服务的拓扑形式。对于ssh安全维护也会不同。我的网络拓扑拿我的环境来说，家里网络分为对内网络和对外网络，也就是网络进行了隔离处理。首先家庭宽带申请了公网ip（非固定ip），修改光猫为桥接模式（对于不同运营商配置形式不同），使用主路由器进行拨号上网，将主路由器配置DMZ主机到对外网络服务主机。该主机只提供FRPS服务。主路由器通过网线连接拓展路由器，拓展路由连接内网服务主机，内网服务主机通过FRPC连接FRPS对外网络服务主机提供公网网络服务。公网ip下frps服务主机ssh安全配置对于上述网络环境，可以看到对外服务主机是直接可以通过公网ip进行访问的。下面聊聊我个人对于在公网环境下的主机ssh安全配置（仅代表个人意见，可能还有更好的方式），首先对外服务主机firewall肯定是要开启的如下图配置firewall-cmd --list-all-zones：图中frps是自定义服务（firewall添加自定义服务后面文章可能会提到，或者需要的小伙伴百度即可），rich rules里面是fail2ban添加的reject规则。只开放需要开放的服务端口即可。对于ssh服务要配置足够复杂的密码，并且修改默认22端口为其它端口。配置这些之后起码不会被很快的完成暴力破解。可以查看ssh的登陆日志cat /var/log/secure可以看到有很多非法尝试，只要对外开放ssh服务，不管是否是22端口对于不怀好意的人来说总能扫描到。所以还要对ssh进行防爆破配置。使用的工具是fail2ban,可以检测secure日志的非法尝试然后对非法ip进行限制。我之前的策略是只要找到的ip会一直进行封锁，后来策略改成封禁72小时，这样是考虑大家使用的ip可能是动态变化的，而且fail2ban配置iptables规则会越来越多，就导致每次主机启动都要重新配置规则启动会比较慢。所以改为72小时，其实也够了72小时尝试5次，对于用户名和密码两个进行暴力匹配不知道要多少年才能成功。使用上面加固手段基本可以保证公网环境下的ssh安全。私网ip下frpc服务主机ssh安全配置对于通过frpc连接frps提供公网服务的主机来说，通常只会配置http和https两个隧道来对外提供服务。但是如果有ssh连接的需求就需要配置tcp隧道，来穿透ssh服务。对于这种网络环境下的ssh安全配置就不能使用fail2ban来进行保护了，因为对于通过frp穿透的网络，到主机是都经过127.0.0.1到达主机的，也就是ssh服务记录的登录请求都是来自localhost，fail2ban即使检查到登录尝试也不能对localhost进行封禁。好了内网主机通过frpc主机对外暴露的tcpssh服务端口就又可以被整个网络进行扫描和爆破了。即使密码比较复杂，同时要匹配用户和密码，也不想总被被人尝试连接吧。总感觉有人想害你的感觉~~这个问题也是困扰了很久，很长一段时间都是直接使用tcp隧道进行裸奔，每天last或者lastb命令查看一下登录记录，看看是否有在你非登录时段进行的登录请求，当然lastb肯定是很长很长，因为裸奔吗：后来查看frp官网，其实官网有对sshd服务有专门的安全配置策略。如官网介绍的stcp，但是这种方式需要进行登录的主机也要连接frps服务，也就意味这登录主机也要配置frpc客户端，这种方式我个人感觉比较麻烦不太想使用这种方式。所以这里使用第二种方式，也就是本文核心多个 SSH 服务复用同一端口，按官网配置好frps的tcpmux对外暴露端口和frpc的tcpmux隧道即可。原理就是远程客户端使用http连接服务器5002端口，使用配置的域名解析到对应的sshd内网主机。这样基本就不是对外直接暴露sshd服务了所以也就不会再有爆破主机对内网的服务器进行爆破请求了。ssh连接的说明按官网描述可以使用下面命令进行连接ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-a.example.com，当然这是linux下的命令连接方式，运行该命令还要提前安装socat软件包，使用apt或者dnf直接安装即可。这里对上面字段进行一下详细的使用说明：命令中x.x.x.x表示frps的ip地址或者域名，%h：%p就是你frpc中配置的域名和端口号，后面proxyport=5002这里的port要填写frps配置中tcpmuxHTTPConnectPort对外暴露的端口，最后面字段就是用户名和主机名了。如我的连接命令为ssh -o 'proxycommand socat - PROXY:ssh.zhangshuo.com:nas.zhangshuo.com:22,proxyport=5002' zhangshuo@nas。不要直接抄写，请使用你对应自己参数。scp连接的说明scp其实和ssh命令基本类似，也是使用scp -o选项即可，只不过主机名要写在后面。如我的命令为scp -o 'proxycommand socat - PROXY:ssh.zhangshuo.com:nas.zhangshuo.com:22,proxyport=5002' file1 zhangshuo@nas:~rsync连接的说明除了ssh/scp通常我们还会使用rsync进行本地或者远程文件的备份。命令示例如下rsync -avz -e"ssh -o 'proxycommand socat - PROXY:ssh.zhangshuo.com:nas.zhangshuo.com:22,proxyport=5002'" /path zhangshuo@nas:/pathwindos下使用MobaXterm连接如图所示：需要对ssh进行额外配置，图中1 host需要填写frpc中配置的域名，2 port填写frpc中配置的映射到内网的端口，3选择networksettings进行代理的配置，4 proxytype选择http，5 host填写frps的域名或者ip地址，6 login和1填写相同即可。7 port填写frps中配置的对外暴露端口。总结使用frp的tcpmux隧道模式完成对内网主机ssh的安全加固。并且描述了该加固方式下linux和windows连接服务器的方法。--EOF--