步骤/目录:
1.ssh登录日志
2.非frp穿透时的树莓派禁止ip
3.frp穿透时的树莓派守护
    (1)禁止root用户登录,设置登录专用用户
    (2)设置非常规端口
    (3)设置长密码(定期更换)或仅用密钥登录
        a. 使用PuTTY生成密钥
        b. 配置/home/用户名/.ssh/authorized_keys文件
        c. PuTTY密钥登录试用
        d. 设置用户仅允许密钥登录(不能密码登录)
    (4)定期查看/var/log/auth.log
    (5)及时备份
        a. 背景介绍
        b. 使用RaspberryBackup进行备份
        c. RaspberryBackup详解
    (6)使用docker
附:手机通过公网ip、密钥登录树莓派

本文首发于个人博客https://lisper517.top/index.php/archives/9/,转载请注明出处。
本文目的是提升树莓派在对外网开放时的安全性。
本文实验日期为2022年2月6日。使用的是树莓派4B(内存8G版),系统为Pi OS 32位桌面版(2022年1月28日更新,镜像名 2022-01-28-raspios-bullseye-armhf.img )。frpc版本为0.39.0。

1.ssh登录日志

ssh登录成功或失败都会在/var/log/auth.log中留下日志。其中登录失败的日志如下:

Feb  6 18:11:44 raspberrypi sshd[2409]: Failed password for root from 192.168.0.56 port 64103 ssh2

其中倒数第四个字段就是ip。但是如果用frp穿透树莓派,会发现登录失败的日志如下:

Feb  6 17:53:21 raspberrypi sshd[2378]: Failed password for pi from ::1 port 49178 ssh2

如果树莓派未使用内网穿透,那么就可以编写shell脚本来ban掉ip。

2.非frp穿透时的树莓派禁止ip

这里主要参考的2013年的这篇文章。但是由于笔者使用了frp+树莓派,以下内容皆未进行实验。

创建脚本文件:

touch /bin/deny_ip.sh
chmod +x /bin/deny_ip.sh
nano /bin/deny_ip.sh

写入脚本内容:

#!/bin/bash

last_ip=""
tail -f /var/log/auth.log | while read LINE; do
{
 if [[ "${LINE}" =~ "Failed" ]]; then
ip="$(echo ${LINE} | awk '{print $(NF-3)}')"
 if [[ "$last_ip" == "$ip" ]]; then
echo "block $ip"
iptables -A INPUT -s "$ip" -j DROP
 fi
last_ip=$ip
echo $LINE
 fi
}
done

脚本解读:读取/var/log/auth.log文件的末尾10行,找到其中含"Failed"的行,与上一次失败的ip比较,若相同就使用iptables(也可以换成ufw)封掉该ip。所以只要较短时间内连续输错2次密码就会被该脚本封ip,使用时要小心。
创建deny_ip.sh使用的log文件:

touch /var/logs/deny_ip.log
chmod 666 /var/logs/deny_ip.log

添加到开机服务,在/etc/rc.local中添加以下行:

nohup /bin/deny_ip.sh > /var/logs/deny_ip.log 2>&1 &

最后,使用iptables -L查看被封的ip;如果要解封ip,用iptables -F;解封某一个ip用iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP

由于本文中使用frp+树莓派进行内网穿透,所以以上的内容未经实验。

3.frp穿透时的树莓派防御

以下内容不只适用于树莓派。

另外需要说明,树莓派上使用frp时,从公网对被穿透的端口进行的操作都会从本地发起。比如说用frp将树莓派的22端口投射到云服务器的12345端口,那么即使在树莓派上禁用了22端口,只要云服务器的12345端口开放,还是可以从公网连接到树莓派ssh(但是局域网内不能连接树莓派,因为局域网发起的操作不在localhost,除非frps也运行在局域网机器)。所以ufw或者iptables对使用了frp等内网穿透工具的树莓派安全性提升可能不大,只能防止局域网内的访问。

(1)禁止root用户登录,设置登录专用用户

好处是ssh登录时不知道用户名就无法登录,自己登录上后可自行切换到root用户。更改设置文件/etc/ssh/sshd_configPermitRootLogin yes(树莓派中为PermitRootLogin prohibit-password,估计是root不能密码登录、只能密钥登录)改为no即可。

对于树莓派来说,默认的pi用户名太常用了,不如禁止pi用户远程登录,新建一个没有sudo权限、有su权限(切换用户)的用户:

nano /etc/pam.d/su

auth required pam_wheel.so前的#去掉,这项设置是只有wheel组中的用户才有su权限(如果auth required pam_wheel.so group=daslkfja就是将默认组名wheel改为daslkfja)。另外上面的auth sufficient pam_rootok.so最好是生效的,否则执行后面的操作后可能需要将root用户也加到wheel组中。
添加用户qifei并更改密码:

useradd -d /home/qifei qifei -m #创建用户并创建指定的家目录
passwd qifei
groupadd wheel #没有wheel组时添加该组
usermod -G wheel qifei #将qifei添加到wheel组中
usermod -L pi #锁定pi用户。可禁用该用户密码登录(仍可用密钥登录),除root外不可切换到pi用户。解锁用-U

如果要禁用用户ssh权限,用usermod -s /sbin/nologin 用户名(此时root用户也无法切换到该用户,因为用的shell不对);解禁用usermod -s /bin/bash 用户名

另外,对已创建的用户指定家目录用mkdir /home/qifei;chown qifei -R /home/qifei;usermod -d /home/qifei qifei;删除qifei用户用userdel qifei(不删除用户相关文件,下次创建qifei时可能会显示用户已存在。删干净用userdel -r qifei),删用户前记得关闭该用户的进程;删除wheel用户组用groupdel wheel;将用户移出wheel组用usermod -G qifei qifei(创建用户时会自动创建同名用户组,用户移到新组时会退出原来的组。或者直接用gpasswd -d 用户名 用户组名)。所有用户组保存在/etc/group文件中(文件末尾,用户组名:x:1003:用户名,其中1003可能为1001、1002等),所有用户可以在/etc/passwd或/etc/shadow中查看。

后面使用WinSCP等工具时可能涉及到为qifei添加sudo权限,所以最后添加一点关于sudo权限的设置方法。使用visudo命令(即用vi打开/etc/sudoers),在树莓派和nano /etc/sudoers.tmp一样。找到root ALL=(ALL:ALL) ALL,在下面添加行qifei ALL=(ALL) NOPASSWD: NOPASSWD: ALL,就可以为qifei用户添加sudo权限(如果是Ubuntu,建议在 /etc/sudoers.d/ 下新建文件,否则系统更新时 /etc/sudoers 会自动回到初始内容)。另外一种添加sudo权限的方法为usermod -aG sudo qifei,即将qifei用户加到sudo组中(移除用gpasswd -d 用户名 用户组名)。第一种方法删用户时记得更改/etc/sudoers文件,否则下次创建同名用户时会自动获得sudo权限。

(2)设置非常规端口

比如用frp穿透时,可以选择frps的22端口连frpc的22端口,但也可以使用frps的其他端口。据说端口号越大,越不容易攻击者被扫出来。

(3)设置长密码(定期更换)或仅用密钥登录

用95个可打印字符设置密码,10位密码就达到5.98e+19量级,每秒试10亿个也需要1898年全部试完。所以设置密码不要图简单,而要多使用不同字符、保证复杂度,最好能定期更换。

另外PuTTY也支持密钥登录,安全性高。使用密钥登录主要分以下几步:

a. 使用PuTTY生成密钥

在PuTTY目录中有puttygen.exe程序,专门用来生成密钥。点击Generate,在空白区域随意移动鼠标,设置Key passphrase(这样的话每次使用密钥时也要输入另外的密码。如果确认私钥文件不会泄露也可以不使用),Save private key即可。窗口不要关,里面的Public key for pasting into OpenSSH authorized_keys file:下方文本框中的内容复制下来,此为公钥(后面也可以看到公钥,比如用WinSCP)。

b. 配置/home/用户名/.ssh/authorized_keys文件

登录树莓派,切换到想使用密钥登录的用户(以qifei为例),并进行如下操作:

su qifei
mkdir /home/qifei/.ssh
touch /home/qifei/.ssh/authorized_keys
chmod 700 -R /home/qifei/.ssh #保证只有该用户对此文件夹有rwx权限,否则用密钥可能连不上
nano /home/qifei/.ssh/authorized_keys #将公钥粘贴到该文件中

多个公钥时每行保存一个公钥。

c. PuTTY密钥登录试用

在PuTTY用密钥登录需要注意设置3个地方:

Session里填主机ip;
Connection-Data里填一下Auto-login username(本例中为qifei);
Connection-SSH-Auth里选定一下刚才生成的私钥(Private key file)。

最后点击Open开启连接。如果刚才设置了Key passphrase,那么此时还需要输入这个私钥文件单独的密码。
另外,一个密钥可以同时、用于多对server-client(不推荐)。

d. 设置用户仅允许密钥登录(不能密码登录)

树莓派的sshd_config文件头中说明了,以#开头的都是默认项,更改时去掉#再改。

在树莓派的/etc/ssh/sshd_config中有以下几项需要注意:

#PubkeyAuthentication yes #启用密钥登录。默认就是yes
#AuthorizedKeysFile     .ssh/authorized_keys .ssh/authorized_keys2 #存放公钥的文件的位置。默认即可(注意这里是用户家目录下的相对路径)
PasswordAuthentication no #这行设为no表示禁止密码登录,只能密钥登录
# 下面GSSAPI的部分不太清楚具体干什么的,有些文章提到了,此处使用的都是默认值
#GSSAPIAuthentication no #是否启用GSSAPI认证。默认为no
#GSSAPIStrictAcceptorCheck yes #是否验证客户端(连接者)的主机名。

这些设置是对所有用户的。设置完成后,让sshd重新加载配置:

systemctl reload sshd

(4)定期查看/var/log/auth.log

如上文中提到,如果没有设置仅允许密钥登录,那么登录失败时会在/var/log/auth.log产生Failed信息。定期看看该文件,可以知道自己的服务器或树莓派有没有被试图登录。

(5)及时备份

这里简单介绍一下一种备份的方法,主要参考了此文

a. 背景介绍

树莓派初始化 一文中曾介绍过raspi-config的Expand Filesystem选项,这个选项是将系统能使用的空间扩展到整个sd卡,但要备份系统时不需要备份未使用的空间。所以可以把备份分为两种层次,1是单纯将整张sd卡复制,生成的备份镜像大,可使用Win32 Disk Imager、Pi OS自带的SD Card Copier(桌面左上角点开可找到)、或dd命令;2是只备份使用了的部分,生成的镜像小,可用的方法有PiShrink(此脚本需要先得到完整镜像后再压缩)、gparted(带图形界面的压缩工具,需要虚拟机)、RaspberryBackup。另外注意,第二类方法生成的是压缩镜像,恢复系统时需要重新Expand Filesystem一下。

b. 使用RaspberryBackup进行备份

树莓派4B插上另一张sd卡、接上电源,待备份sd卡插上读卡器后也通过usb插上树莓派。输入df -h检查:

df -h
#输出结果
文件系统        容量  已用  可用 已用% 挂载点
/dev/root        57G  4.1G   51G    8% /
devtmpfs        3.7G     0  3.7G    0% /dev
tmpfs           3.9G     0  3.9G    0% /dev/shm
tmpfs           1.6G  980K  1.6G    1% /run
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
/dev/mmcblk0p1  256M   49M  207M   20% /boot
tmpfs           790M   20K  790M    1% /run/user/1000
/dev/sdb2        58G  4.0G   51G    8% /media/pi/rootfs
/dev/sdb1       253M   49M  204M   20% /media/pi/boot
tmpfs           790M   16K  790M    1% /run/user/1002

发现sd卡已自动挂载。umount一下,并重新挂载(否则备份boot时可能提示cp命令不能复制文件权限信息):

umount /media/pi/rootfs
umount /media/pi/boot
mkdir /media/boot1
mkdir /media/root1
mount /dev/sdb1 /media/boot1
mount /dev/sdb2 /media/root1

写入脚本,为脚本增加执行权限,并执行:

nano /tmp/rpi-backup.sh
#复制tar法脚本内容
chmod 100 /tmp/rpi-backup.sh
/tmp/rpi-backup.sh /dev/sdb1 /dev/sdb2

注意,/tmp/rpi-backup.sh接受的两个参数,第一个是boot分区(容量较小的那个)的设备名,第二个是root分区的。
笔者实验时用时16min58s备份完毕。

c. RaspberryBackup详解

树莓派备份-RaspberryBackup详解

(6)使用docker

简单地说,docker是以镜像文件为模板运行一个虚拟环境,对安全性有较大提升,没有备份这么麻烦,还有其他好处。
树莓派使用docker详见 Docker入门(一)Docker入门(二)Docker树莓派实践 系列。

附:手机通过公网ip、密钥登录树莓派

作为随身终端,手机也可以使用ssh工具便捷登录树莓派,实现随时随地管理。
市面上的ssh工具有很多,由于笔者买了阿里云的服务器,所以也安装了阿里云app方便管理服务器,正好阿里云app里就有ssh工具。
第一步要先将密钥转换一下,putty用的密钥是ppk格式,和openssh不通用。windows下使用putty自带的puttygen即可:打开puttygen,load装载ppk文件,选择上方菜单栏Conversations下的Export OpenSSH key就行了,新文件有无扩展名都可以(也可以自己改成pem),密码不改的话和原来的ppk文件一样。然后把OpenSSH密钥拷贝到手机上。另外linux下,安装putty后也可以使用puttygen命令。
第二步就是使用阿里云app。打开app,在 控制台-常用工具 找到 SSH工具 ,点击右上角加号新建一个连接:IP是frp服务器的公网IP,登录名为密钥对应的用户名,选择密钥文件,填写密钥的密码,端口为frp服务器的穿透端口,别名不用自己填,然后点击连接即可。第一次连接可能有提示。

标签: 树莓派

添加新评论