特殊事件处理篇

特殊问题解决汇整

有一些常见的小问题,或者是突然发现的一些困扰,不是可以长篇大论的文档,那就写成 FAQ 吧!

最近更新时间: 2024/07/15

很多时候,我们玩 Linux 会遇到很多软件或者是硬件的问题,尤其是硬件的问题最奇怪了!因为担心未来鸟哥自己还会遇到相同的状况, 所以,将自身遇到的状况给他写下来~希望大家如果有遇到相同的问题时,可以很快速的解决呦!

2024/07/15: openssh-server 无法从 RockyLinux 9 登录其他旧的系统

  • 问题说明

这个已经是发生在半年以前的事情了!刚刚因为同事在询问,所以才又回想起来,应该要写写才对。 因为 RockyLinux 9 已经稳定的运行一段时间了,当初刚刚设置好 RockyLinux 9 的 server 时,要从旧的系统登录进来, 或者是从 RL9 登录到其他系统去,似乎都无法 ssh。以为是防火墙的问题~检查老半天,并不是!后来查找到,应该是 ssh key 交换的问题所致,但是似乎也无法简单通过 ssh -o "option..." 的方式来解决!就很头疼!

  • 解决流程

解决的方案很简单!但是确实很担心会出问题...所以不要在比较重要的 server 上面实施~比较次要的系统加装比较严谨的防火墙机制后, 或许就通过将 RockyLinux 9 的加密机制降级,就能解决这个问题。鸟哥底下的动作,其实是在内部系统上面实施的, 这部系统是用来收集学生课堂作业,无法直接对外,也没有对 Internet 连接,所以这样进行就还算保险...

[root@linuxserver ~]# yum -y install crypto-policies-scripts
[root@linuxserver ~]# update-crypto-policies --show
DEFAULT
[root@linuxserver ~]# update-crypto-policies --set LEGACY
[root@linuxserver ~]# update-crypto-policies --check
The configured policy matches the generated policy

这样,就将 RockyLinux 9 的加密机制降级回以前的版本,跟旧版的系统互通就没啥问题了。

2023/01/10: openssh-server 在 CentOS8 系统上面,不知为何,突然无法远程登录

  • 问题说明

系上有一部电脑教室内的防火墙系统,用来作为电脑教室内所有电脑的对外主控 gateway 功能,架设的时候,最新的系统是 CentOS 8, 所以,安装的是 CentOS8 的环境。大部分的服务都没有对外,主要进行 IP forwarder 的功能 (SNAT),没有开放 Internet 的主动连接, 因此,相对上是比较安全一点。防火墙规则设置上,也是仅有针对内网放行,外网几乎都关闭!过去也不曾发生什么严重的资安漏洞,原因是... 资安监测环境根本就无法 touch 到我们的主机啊!哈哈哈!

有趣的问题来了,学生因为还是觉得 CentOS 8 已经没有维护,所以, 2022 年底认为,应该要『升级』一下才对吧! 所以,将 yum 的 repository 改成 Rocky Linux 9...对!是鸟哥没有教好...很抱歉...然后,该行为只是改变 url 位置而已, 学生们并没有使用 yum update 之类的。只是,因为某些缘故,系统上面竟然自动更新了 glibc, openssl 等服务!很怪异! 会发现这个问题,其实是因为,我们需要管理该部主机时,竟然只能在近端使用键盘屏幕接触,无法使用 ssh 连接! 连接虽然会成功,可以输入『 yes 』的接受密钥指令,但是...之后就被踢掉了!连出现可以输入密码的画面也没有!

  • 解决流程

主要是无法使用 ssh 连接进系统的问题,所以,一开始怀疑 openssh-server 以及 openssl 的软件问题!先检查这两个软件! 使用 rpm -V openssh-server 等功能,确认软件并没有被移植!最终也使用 rpm -Va 去全部软件检查一次!都没有 binary programs 被窜改的信息。会不会是设置档被改错了?所以,连设置档都回溯到最原始版本,重新启动 sshd 服务!很怪!就是服务都可以启动成功! 但是,就是无法登录系统!使用 ssh -v 去查找连接过程的信息, key 的交换等等也都没有问题!最后就是会被 sshd 停止连接...很怪异!

今天比较有时间去好好检查一下,使用了底下的指令来看看,到底有多少软件被错误更新了?

[root@linuxserver ~]# rpm -qa | grep el9
openssl-libs-3.0.1-43.el9_0.x86_64
glibc-common-2.34-28.el9_0.2.x86_64
compat-openssl11-1.1.1k-4.el9_0.x86_64
glibc-2.34-28.el9_0.2.x86_64
glibc-langpack-zh-2.34-28.el9_0.2.x86_64
glibc-gconv-extra-2.34-28.el9_0.2.x86_64
rsync-3.2.3-9.el9_0.2.x86_64
glibc-langpack-en-2.34-28.el9_0.2.x86_64
openssl-3.0.1-43.el9_0.x86_64
glibc-headers-2.34-28.el9_0.2.x86_64
glibc-devel-2.34-28.el9_0.2.x86_64

映入眼帘的第一个就是我的怀疑,openssl 耶!因为 openssh 后面使用到的,好像也跟 openssl 有关! 因此,我的动作是,先将 /etc/yum.repos.d/ 里面的 repository,不重要的先关闭,设置成 RockyLinux 9 的, 直接改回 Rocky Linux 8,然后使用 yum clean all 先将清单关闭,之后使用 yum downgrade openssl 降级~ 这样 openssl 就可以恢复正常!不过...sshd 还是不能用啊!

接下来,我来看看到底 sshd 用了哪些函数库,

[root@linuxserver ~]# ldd /usr/sbin/sshd
        linux-vdso.so.1 (0x00007ffe5a8b4000)
        libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f4b32923000)
        libpam.so.0 => /lib64/libpam.so.0 (0x00007f4b32713000)
....
        libc.so.6 => /lib64/libc.so.6 (0x00007f4b30537000)
....

有趣的是,反而函数库里面没有 openssl 相关的字眼!倒是有个 libc.so 呢!刚刚上面 rpm -qa 去查找时,就有发现 glibc 喔! 看起来,这家火也需要降级才对!因此:

[root@linuxserver ~]# yum downgrade glibc

降级了 glibc 之后,系统大部分都回溯到 Rocky Linux 8 的环境,应该 (只能这样猜想) 没有 Rocky Linux 9 的软件了! 这时,突然之间 ssh 可以使用了!很开心啊!

这个故事告诉我们,不要乱更动 yum 的 repository 网址!如果乱升级到不该去的地方,因为目前的软件大多是动态函数库链接方式, 很多指令与函数库都有向外调用其他函数库的功能!那就很可能会产生你可以升级,但是用到这个升级函数库的其他旧软件, 可能就像我们这次的情况一样,旧软件突然无法正常运作...虽然是可以顺利启动喔~这也是相当有趣的经验!提供大家参考!

2022/12/07: 升级到 RockyLinux 9.1 过程中当机,导致的问题分析与解决

  • 问题说明

本日,强者我同事蔡董,突然拿笔电给我,说他最近将 RockyLinux 9 的系统升级到 9.1 (对!这两周发布了!)。不过不巧的是, 不知道为啥,升级过程当中,笔电竟然当机了!当掉了!因为是升级过程当掉的,因此,问题可能很严重 (很多基础软件可能没有设置好)。 再次开机后,无论选择哪个内核,都无法顺利进入系统了。

蔡董大大先使用 RockyLinux 9.1 的原版 USB 进行开机,进入 troubleshooting 模式,然后进入 chroot 的环境中, 启动网络之后,通过 yum 重新进行安装与整理。使用了 rpm -Va 去检查所有系统之后,发现到没有重大问题!于是, 就又重新开机。不过有几个问题发生了:

  • 选新的内核:说找不到 initramfs 文件,所以连开机都不行!
  • 选旧的内核:可以加载内核与 initramfs 进行开机,但是最后一刻要进入 X window 时,就死掉了!无法顺利进入系统。
  • 用旧的内核进入 rd.break 环境:这样是可以的!由 rd.break 环境进入 chroot,操作上也没有问题。

所以,分析问题,很可能就是:

  • 没有 initramfs
  • X window 有问题!
  • 解决流程

首先,鸟哥进入 RockyLinux 9.1 的 USB 开机后的救援环境中,然后使用 chroot /mnt/sysroot 的方式切换,之后到 /boot 里面, 使用 dracut 指令将 initramfs 重新创建!由于蔡董之前已经将 RockyLinux 9.1 的软件全部更新完毕!看起来就剩下 initramfs 有问题而已。 因此,使用 dracut 创建 initramfs 是没有问题的!很快就搞定!

鸟哥去查了查 /var/log/messages 里面,说是 Xorg 有一些问题,无法顺利加载。但是,去查了主要信息 /var/log/Xorg.0.log, 里面却没有显示任何错误消息!甚至 Xorg.0.log 里面还说,已经顺利启动 X 了...有点昏倒!因为找不到 X window 的问题, 所以,鸟哥就将开机环境设置为文本界面,使用 systemctl set-default multi-user 来处理。

因为这电脑毕竟是蔡董的!蔡董大大说,叫我先改 root 密码,等到测试完毕之后,他可以再改回他原本的密码!这样密码就不用流出来。 好喔!鸟哥在救援模式当中的环境下,确认一切文件系统都是可读写的状况,修改 root 密码,却一直出现『 passwd: Permission denied 』! 我谁?我 root 捏~我有几个怀疑:

  • /etc/passwd, /etc/shadow 是不是不小心加入了 chattr 的参数了?
  • /usr/bin/passwd 的 SetUID 功能是不是不小心被抹去了?

查了查相关的权限数据,上面的问题都不存在!没办法,只好 google 一下。google 到有朋友说, /etc/pam.d/system-auth 的内容要改。 我去查看了一下,该文件是链接到 /etc/authselect/ 目录去的!不找还好,一找吓一跳!靠腰啦! /etc/authselect/ 里面, 全部文件的容量都是 0...看起来就是升级过程中,在验证机制设置时,可能出问题,因此导致该目录底下跟系统最重要的验证机制全部都消失了! 那怪不得旧内核开机也会无法加载 login: 或 X window 了!

重建 /etc/authselect 里面的文件,方法也是很简单,使用底下的方式来处理即可:

[root@linuxserver ~]# authselect select sssd

这样就搞定 /etc/authselect/ 底下的文件,重新开机,选用新内核,顺利进入文本界面,登录 root 之后,下达『 systemctl isolate graphical 』 就可以转成图形界面!呵呵!搞定!

这是鸟哥第一次遇到这种状况!我自己觉得非常有趣!所以赶紧纪录下来!希望对大家能有帮助!

2021/12/08: 安装新的 10G 网卡后,UEFI 开机数据损毁消失,变成无法开机了

鸟哥的专题生跟我说,专题需要使用的网络速度似乎太慢,所以在某些 container 会用到的环境情境下,总是速度慢。 所以,我们跑去买了数张 10G 网卡,想说都换成 10G,可能性能会好一点。没想到,在正常关机,然后安装该网卡后,开机之后, 竟然发现,原本的 CentOS 的菜单不见了!进 UEFI BIOS 画面中,找不到该菜单的进入点...夭寿了...现在大四,东西都在里面! 消失怎么办?

这几部主机里面,全部都是使用 4 颗传统硬盘搭配主板内置的 Intel raid 功能,创建了 raid10 的模式。这种模式在 Linux 底下,都会以 software raid 的状态存在!而且设备名称,通常就是 /dev/md126 这样!我们想说那就先来检查一下 filesystem 好了。 没想到使用原版光盘的 USB 开机后, lsblk 竟然只抓到 /dev/sd{a,b,c,d} 而已,并没有找到 /dev/md126 耶!惨了! 会不会整体 RAID 死翘翘?

1. 进 BIOS 查了查硬件,结果 Intel 主板说,这个 RAID 是健康的!没有任何磁盘有问题,看起来也不曾坏掉!

2. 继续使用 USB 开机进入救援模式,尝试使用底下的指令来再次创建 RAID 看看:

[root@linuxserver ~]# mdadm --assemble --scan

结果确实可以唤醒磁盘数组喔!而且 (1)partition table 完整无缺 (使用了 gdisk /dev/md126 检查,没问题!) (2)文件系统是健康的 (尝试使用 mount 去挂载三个 partition,结果内容通通没问题!),也就是说,硬件没问题、分割表正常、文件系统正确, 并且将整个系统挂载后,使用 chroot 去瞧瞧,内容也没有不同!而且, EFI 的 partition 内容全部都在!

后来想说,会不会是因为安插了 10G 卡,导致主板会去分析目前的 UEFI 开机区,然后因为某些不明的原因, 导致 intel raid 的磁盘上面的 EFI boot menu 消失!导致无法找到进入点的缘故?所以,接下来的重点就变成『如何增加一个 UEFI 的开机菜单』。

3. 想到开机,你应该会立刻想到 grub2 才对!不过,这次很特别,因为 UEFI 的开机是找 EFI partition,而不是找 MBR ! 所以使用 grub2-install 是错误的想法!毕竟全部的数据确实还在 /dev/md126p1 里面的 EFI/centos/* !并没有消失不见! 所以并不需要重建他!

4. 最后找到 efibootmgr 这个玩意儿!这东西很有趣,可以用来查看、创建 UEFI 的开机进入菜单呢!简单的使用方式如下:

# 1. 列出目前的 UEFI 开机菜单:
[root@linuxserver ~]# efibootmgr
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0000,0001,0004,0005,0003
Boot0000* CentOS
Boot0001* CentOS2
Boot0003  网络卡
Boot0004* 硬盘
Boot0005* UEFI: ADATA USB Flash Drive 11

如上,那个 0000, 0001 指的是开机的菜单编号,目前我们的 CentOS 菜单在编号 0000 上面,而且开机顺序 (Order) 是 0000, 0001, 0004, 0005, 0003 哩!另外,目前的开机 (BootCurrent) 用的是 0000 这个编号喔!

[root@linuxserver ~]# efibootmgr -v
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0000,0001,0004,0005,0003
Boot0000* CentOS        HD(1,GPT,f7d36e9d-434d-4615-905d-ba8090c7a44f,0x800,0x200000)/File(\EFI\centos\grubx64.efi)
Boot0001* CentOS2       HD(1,GPT,f7d36e9d-434d-4615-905d-ba8090c7a44f,0x800,0x200000)/File(EFIcentosgrubx64.efi)
Boot0003  网络卡        BBS(Network,,0x0)AMGOAMNO..........AMBO
Boot0004* 硬盘          BBS(HD,,0x0)AMGOAMNO............AMBO
Boot0005* UEFI:         PciRoot(0x0)/Pci(0x14,0x0)/USB(8,0)/HD(1,MBR,0x1a1f9b19,0x800,0x739f800)AMBO

如上,CentOS 使用的是硬盘,且使用第一个 partition ,用的是 GPT 分割表,至于文件则是在 \EFI\centos\grubx64.efi 上面! 这个当然是建置成功后鸟哥重回系统来查阅的数据!事实上,上面的 CentOS2 就是我们在测试时,写错了的开机数据! 开机引导程序一整个错误!哈哈!所以我们要删除他!

[root@linuxserver ~]# efibootmgr -b 0001 -B
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0000,0004,0005,0003
Boot0000* CentOS
Boot0003  网络卡
Boot0004* 硬盘
Boot0005* UEFI: ADATA USB Flash Drive 11

如上,很轻松的删除了错误的信息!如果要重建新的菜单,应该使用如下的方式处理:

[root@linuxserver ~]# efibootmgr -c -d /dev/md126 -p 1 -L check -l /EFI/centos/grubx64.efi
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0001,0000,0004,0005,0003
Boot0000* CentOS
Boot0003  网络卡
Boot0004* 硬盘
Boot0005* UEFI: ADATA USB Flash Drive 11
Boot0001* check

你应该使用『 efibootmgr --help 』查看一下所有的参数!另外,上面的 check 完全是暂时乱做的!测试完毕记得将他删除!

2021/12/01: RockyLinux 8 上面无法正常显示 big5 编码的 PHP 网页问题

鸟哥的网站因为多次移植与使用不同编辑器的关系,网站上面的数据充满着不同的语系编码版本! 老旧的数据大多数还是 big5 编码,新的网站数据则是鸟哥手动去进行 big5 转 utf8 的动作。但是... 有一阵子很疲劳,所以,还是有一堆数据尚未转到 utf8 啦!

过去在 CentOS6 的系统上,big5 网页的显示似乎没有什么问题!也都可以通过网页自己的 header 去展示语系, 没问题的。但是,昨天转到 RockyLinux 8 之后,一堆朋友就开始来信留言,说已经看到 big5 网页变乱码了! 鸟哥早就将 Apache 的 httpd.conf 里面的『 AddDefaultCharset 』关闭,所以 http 不会主动传出 utf8 的语系, 但这样还是不行!相当伤脑筋!

查了查数据,原来是 PHP 也会发送缺省语系编码...你可以在 /etc/php.ini 里面查到这一段:

[root@linuxserver ~]# vim /etc/php.ini
.....
default_charset = "UTF-8"
.....

鸟哥测试过将上述设置注解,然后重启 httpd 服务,结果也是持续传输出 UTF8 的编码,导致 big5 网页还是乱码! 后来发狠了!既然如此,我就来强迫 php 网页使用 big5 好了!所以在 .php 的网页上,最前面加上这样即可:

[root@linuxserver ~]# vim webdemo.php
<?php
	header('Content-Type: text/html; charset=big5');
?>

这样网页才终于可以顺利的展示中文...看起来,还是不要懒惰,渐渐将数据移转到 https 吧!顺道转换格式与编码!唉! 继续操下去!

2020/10/21: 如何让某一群组的帐号不能使用 GDM (X window)

今天有个朋友问到,假如我想要让某一群帐号不能在本机登录 X 窗口,该如何处理啊?鸟哥一直朝向 /etc/gdm/custom.conf 以及 /etc/dconf/ 的内容去搜索, 但是总是找不到比较好的解决方案,大部分的方案都是在解决登录的帐号隐藏的状态,而不是处理不许登录的状态!所以,想到很头疼!

最后还是回到 Linux 传统的登录控制嵌入模块,那就是 PAM 模块的处理。好佳在, gdm 提供了 gdm-password 的文件, 在这个文件里面添加一行,使用 pam_succeed_if.so 的模块,让 pam 判断某帐号有没有在某群组里面, 就能够让某群组不能使用 gdm 了!还挺简单的!很有趣!

[root@linuxserver ~]# vim /etc/pam.d/gdm-password
auth     [success=done ignore=ignore default=bad] pam_selinux_permit.so
auth        required      pam_succeed_if.so user notingroup denygroup
auth        substack      password-auth
.....

[root@linuxserver ~]# usermod -a -G denygroup username

将用户将入到该群组,那这个帐号就不能使用 GDM 登录了!其他方式的登录倒是没问题的!有趣吧!

2020/03/13: 系统一直发现无法使用 systemctl 重启服务,经常出现『timed out』问题

今日学生持续来哭喊,说没有网络啦!鸟哥紧急连接进去教室的 server 查看,结果...以为系统挂了!ping 的到, 但是 ssh 连接进去慢到想哭,不过,确实是可以连接进去,就是很慢!不过,连接成功之后,操作系统倒是还可以,只是, 想要重新启动感觉有问题的防火墙系统时,却发现到无法启动啊!一直会出现 timed out 的结果!但是,事实上却是有重新启动成功! 相当的令人难以理解:

[root@linuxserver ~]# journalctl
 3月 13 14:02:07 linuxserver dbus[1735]: [system] Failed to activate service 'org.freedesktop.systemd1': timed out
 3月 13 14:02:07 linuxserver systemd-logind[6300]: Failed to enable subscription: Failed to activate service 'org.freedesktop.systemd1': timed out
 3月 13 14:02:07 linuxserver systemd-logind[6300]: Failed to fully start up daemon: Connection timed out
 3月 13 14:02:07 linuxserver systemd[1]: systemd-logind.service: main process exited, code=exited, status=1/FAILURE
 3月 13 14:02:07 linuxserver systemd[1]: Failed to start Login Service.
 3月 13 14:02:07 linuxserver systemd[1]: Unit systemd-logind.service entered failed state.
 3月 13 14:02:07 linuxserver systemd[1]: systemd-logind.service failed.
 3月 13 14:02:07 linuxserver systemd[1]: systemd-logind.service has no holdoff time, scheduling restart.
 3月 13 14:02:07 linuxserver systemd[1]: Stopped Login Service.
 3月 13 14:02:07 linuxserver systemd[1]: Starting Login Service...

查了查一些论坛相关的说明,似乎是一个名为 polkit 的服务没有办法顺利启动的缘故,而 systemd-logind 又得要有这个服务的协助, 所以,就造成了 polkit 不见了,systemd-logind 启动不了,系统的认证一直出问题,所以后来又从 journalctl 里面看到这些数据:

[root@linuxserver ~]# journalctl
 3月 13 10:16:18 linuxserver systemd[1]: polkit.service start operation timed out. Terminating.
 3月 13 10:16:18 linuxserver systemd[1]: Failed to start Authorization Manager.
 3月 13 10:16:18 linuxserver systemd[1]: Dependency failed for Dynamic System Tuning Daemon.
 3月 13 10:16:18 linuxserver systemd[1]: Job tuned.service/start failed with result 'dependency'.
 3月 13 10:16:18 linuxserver systemd[1]: Unit polkit.service entered failed state.
 3月 13 10:16:18 linuxserver systemd[1]: polkit.service failed.

一直无法顺利重新启动!后来找到一篇说明,说是得要先检查 dbus 这个总线才对!所以,就赶紧检查看看:

[root@linuxserver ~]# busctl
NAME                                   PID PROCESS         USER             CONNECTION    UNIT                
:1.0                                     1 systemd         root             :1.0          -                  
fi.epitest.hostap.WPASupplicant          - -               -                (activatable) -                 
fi.w1.wpa_supplicant1                    - -               -                (activatable) -                   
org.freedesktop.DBus                  7516 dbus-daemon     dbus             org.freedesktop.DBus dbus.service
org.freedesktop.PolicyKit1               - -               -                (activatable) -                  
org.freedesktop.hostname1                - -               -                (activatable) -                 
org.freedesktop.import1                  - -               -                (activatable) -                
org.freedesktop.locale1                  - -               -                (activatable) -               
org.freedesktop.login1                   - -               -                (activatable) -              
org.freedesktop.machine1                 - -               -                (activatable) -             
org.freedesktop.nm_dispatcher            - -               -                (activatable) -            
org.freedesktop.timedate1                - -               -                (activatable) -           

有点类似上面这样,就是 PolicKit1 不见了!连带 login1 也无法启动!相当伤脑筋~最终的解决方法很好笑!因为无法重新启动是由于 systemd-logind 找不到 polkitd 服务, 因此,我们就先手动启动 polkitd (不是通过 systemctl),然后再重新启动 dbus 就好了!真见鬼!

[root@linuxserver ~]# /usr/lib/polkit-1/polkitd --no-debug &
[root@linuxserver ~]# systemctl restart dbus
[root@linuxserver ~]# systemctl restart systemd-logind

突然间,系统就正常了!这就正常了!但是,因为还没有重新开机过~鸟哥我也不敢肯定未来就一定会顺利... 这次是没问题了!希望下次重新开机,系统还是好好的...

2020/03/10: 使用 LDAP 搭配 Samba 验证,结果改了主机名称后,发现再也无法挂载 SMB 了

我们系上一直都用一台所谓的 ID server 来管理 LDAP 的验证,同时激活了 samba 进行 LADP 的处理。 一直都搭配的非常好!一直到今天,因为电力的问题,导致 ID server 断电,因此重新开机。开机过后, 系统运作都是没有问题,但,远程 windows 就是无法进行 samba 的验证~在 log (/var/log/messages) 里面, 一直重复这个错误:

Mar 10 16:20:05 idserver1 smbd[4760]: [2020/03/10 16:20:05.489537,  0] auth/check_samsec.c:492(check_sam_security)
Mar 10 16:20:05 idserver1 smbd[4760]:   check_sam_security: make_server_info_sam() failed with 'NT_STATUS_UNSUCCESSFUL'

查了查 google,随便找到两篇似乎有点关联的:

似乎是 Samba 里面有个 SID 被改变掉了,因此,原本帐号的 SID 与重新开机过后的 Samba SID 已经不同步了!所以就引起这个问题。 见鬼了!开机前到底学生做了什么事情呢?我想了想,啊!有请学生进行备援工作,可能是备援的问题嘛?去查了 /etc/hosts, 发现主机名称改变了,然后,在 Samba 这部 Linux 系统上面测试一下,先关闭 smb 之后,用 smbd 直接检测:

[root@idserver1 common]# /usr/sbin/smbd --interactive --debuglevel=3
......
Forcing Primary Group to 'Domain Users' for 4060C001
The primary group domain sid(S-1-5-21-1004358217-1889577509-1049132106-513) does not match the 
  domain sid(S-1-5-21-741082690-252565047-1259293557) 
  for 4060C001(S-1-5-21-741082690-252565047-1259293557-3086)
......

确实回答 SID 不匹配所致。左侧的 SID 应该是目前的,右侧的 SID 则是以前正常运作的情况。后来使用 samba 提供的 net 指令来查查看:

[root@idserver1 common]# net getdomainsid
SID for local machine IDSERVER1 is: S-1-5-21-1004358217-1889577509-1049132106
Could not fetch domain SID

确实回答是这个 SID!天呐~那以前的 SID 是什么?后来想想,以前登录系统的时候,系统的主机名称明明是 localhost,为啥这边显示 IDSERVER1 呢? 喔!原来是学生为了分辨实际运作机器与备援机器,分别重新设置主机名称成为 idserver1 与 idserver2,但是 smb.conf 里面却没有指定『 netbios name 』设置值! 因此可能就导致 SID 自己跑掉了!我将 smb.conf 里面增加『 netbios name = localhost 』之后,重新启动 smb, 再次检查 domainsid:

[root@idserver1 samba]# net getdomainsid
SID for local machine LOCALHOST is: S-1-5-21-741082690-252565047-1259293557
Could not fetch domain SID

确实变回原本的 SID 了!之后,使用这台 samba 的所有其他设备,又可以开始登录了!实在不简单... 原来随便更改主机名称,真的会倒大楣...

2019/09/24: 在 CentOS 底下,以不同的 gcc, gfortran 版本,进行开发的行为

不知道大家有没有这样的经验,就是啊,使用 CentOS 7 系统进行一些软件开发或安装时,由于第三方软件『要求以 gcc 6.x 以上版本进行软件编译与安装』的行为, 但是因为缺省的 CentOS 7 的 gcc 版本只有...

[user@localhost ~]$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

可以看到,版本仅到 4.8.5 而已,也就是说,官方发布的版本就是在 4.8.5 啦!但如果你到 gcc 的官方网站去查找时,可以发现到最新的版本在 2019/08 已经来到 9.2 版了~那你可以自己编译 gcc 来安装新版本嘛? 这个,对新手来说,不是很建议~因为 gcc 包涵太多的函数库数据,乱处理会出事的。

  • 使用 CentOS 发布的发展套件组 (devtoolset)

为了这样的需求,事实上, CentOS 有针对不同的版本提供了某些特殊的功能喔!包括提供不同的 gcc 发展软件组,以及更新版本的 libvirtd 或 qemu 的版本呢。 你可以这样追踪一下相关的发布软件数据:

[user@localhost ~]$ yum search centos-release
centos-release.x86_64 : CentOS Linux release file
centos-release-ansible26.noarch : Ansible 2.6 packages from the CentOS ConfigManagement SIG repository
centos-release-azure.noarch : Yum configuration for CentOS Virt SIG Azure repo
....
centos-release-qemu-ev.noarch : QEMU Enterprise Virtualization packages from the CentOS Virtualization SIG repository
centos-release-scl.noarch : Software collections from the CentOS SCLo SIG
centos-release-scl-rh.noarch : Software collections from the CentOS SCLo SIG (upstream scl only)
...

上面那个 centos-release-scl 相关的字样,就是软件开发套件组。鸟哥因为自己工作环境的需求,需要较高版本的 gcc 与 gfortran,那怎么处理?只好通过安装这个数据了。 基本上, centos-release-* 给予的,其实只是一个软件仓库,安装好之后 (其实就是设置 /etc/yum.repos.d/*.repo) ,还得要安装正确的软件才行。

# 先安装好软件仓库,并且查阅软件仓库的列表
[root@localhost ~]# yum -y install centos-release-scl
[root@localhost ~]# yum repolist
repo id                            repo name                      status
base/7/x86_64                      CentOS-7 - Base                10,097
centos-sclo-rh/x86_64              CentOS-7 - SCLo rh              8,548
centos-sclo-sclo/x86_64            CentOS-7 - SCLo sclo              804
extras/7/x86_64                    CentOS-7 - Extras                 304
updates/7/x86_64                   CentOS-7 - Updates                311
repolist: 20,064

# 查找 devtoolset 软件有哪些版本?并且安装最新版 (2019/09 时,最新为 devtoolset-8 喔!
[root@localhost ~]# yum search devtoolset
....
devtoolset-8-gcc.x86_64 : GCC version 8
devtoolset-8-gcc-c++.x86_64 : C++ support for GCC version 8
devtoolset-8-gcc-gdb-plugin.x86_64 : GCC 8 plugin for GDB
....

[root@localhost ~]# yum install devtoolset-8

此时你的系统里面会有两个 gcc 的版本,缺省系统还是会使用 gcc 4.8.x 那一版。而如果你需要使用到 gcc 8.x 的编译器与相关的函数库时, 就得先转到 devtoolset 的环境下才可以!否则,还是会使用到旧版的 gcc 函数库喔!那切换版本的方式为使用 scl 这个软件喔!

# 第一种方式,使用 scl 提供的软件功能
[user@localhost ~]$ scl enable devtoolset-8 bash
# 虽然官方建议使用这个方式,不过,鸟哥因为自己有额外的 bashrc 设置值,因此还是会导致使用到旧版 gcc 喔!

# 第二种方式,如果你跟鸟哥一样使用 bash 的话,可以直接调用环境变量即可
[user@localhost ~]$ source /opt/rh/devtoolset-8/enable
[user@localhost ~]$ gcc --version
gcc (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

这样你就可以开始使用新的 gcc 版本啰!

2019/09/20: 在 Linux terminal 的环境下,用 bash 将文件内容以行为单位,读入成为一个大数组

鸟哥在进行某些空气品质的研究时,经常需要修改内容很多的文件!但是,这些文件的内容只有少部份重复的数据需要变更, 不过,鸟哥又不想要重新写 fortran 程序来每一行都进行处理,毕竟只有少部份的数据要处理而已...那怎么办? 其实,可以使用 bash 的 shell script 来简易处理即可。

但是要使用 bash 来处理,又有个难度,以前文件的处理,鸟哥个人习惯使用这样的方式:

#!/bin/bash
filename="your_file_name"
lines=$( wc -l ${filename} | cut -d ' ' -f 1 )
for i in $(seq 1 ${lines} )
do
	line=$( sed -n ${i}p ${filename} )
	...
done

不过,这有个坏处~那就是,每一行都要从 sed 去重复读取!我们知道这个文件被读过一次之后,就会被缓存在内存内, 所以,基本上不会增加硬盘的读取困扰,问题是,如果底下的代码比较大,那就得要一直重复调用 sed 这个 bash 的外部指令, 对于程序的运行来说,会有很大的缺点,那就是速度会被拖很慢!

  • 使用 readarray 一口气将数据读进程式,并以 bash 的数组处理

比较好的解决方案,就是『只读一次该文件』,然后将这些文件内的数据用数组的方法纪录下来。因为数组也是 bash 的内置功能, 因此,我们就不用重复调用 sed,而是可以直接从 bash 内,将数据进行处理!在整理数据时,速度性能会快上很多! bash 有提供一个 readarray 的功能,能将数据一口气以行为单位进行数组的保存~方法如下:

#!/bin/bash
filename="your_file_name"
readarray myarray < ${filename}
myarray_count=${#myarray[@]}
for i in $( seq 0 $((${myarray_count}-1)) )
do
	echo ${myarray[${i}]}
	...
done

这样直接处理 myarray 这个数组,就可以直接在 bash 的内存进程里面进行各项任务,而无须重复读取外部文件!

2019/08/22: 使用 UEFI 的模式进行 grub2 的 Linux/Windows 多重开机时,出现『invalid sector size 65535』

在昆山资传系里面,我们有自己创建的多重开机操作系统,以前都是使用 MSDOS 模式,今年暑假期间想来处理成为 UEFI 的模式,毕竟硬盘越来越大, 使用 GPT 分割表会比较妥当一些。不过,再通过 CentOS 7 的 grub2 进行维护管理时,里面的设置值会失败!无法顺利开机! 最原本的设置值是这样的:

# 先来检查原本的设置值:
[root@localhost ~]# vim /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry "Windows 10 Class system" {
        insmod part_gpt
        insmod search_fs_uuid
        insmod chain
        set root=(hd0,gpt1)  <==这里是需要注意的项目!
        chainloader /EFI/win10class/Boot/bootmgfw.efi
}
menuentry "Windows 10 Exam environment" {
        insmod part_gpt
        insmod search_fs_uuid
        insmod chain
        set root=(hd0,gpt1)  <==这里是需要注意的项目!
        chainloader /EFI/win10exam/Boot/bootmgfw.efi
}

经过 grub2-mkconfig 输出设置值到 /boot/efi/EFI/centos/grub.cfg 之后,虽然可以顺利进入菜单,但是当选择上述的 Windows10 时,屏幕上就会出现黑压压的一片, 只会出现这个错误:

Invalid sector size 65535

原本以为是我们的硬盘磁区 (sector) 不是传统的 512bytes,而是 4K 的 sector 所致,但是查找了网络的文档,最后发现,我们当初使用 USB 硬盘来安装 Windows, 所以,windows 的 bootmgfw.efi 开机加载档恐怕有点误会了,因此使用『 set root=(hd0,gpt1) 』这种固定的磁盘代号,可能会无法顺利开机所致。那该如何是好? grub2 官方文档建议最好使用 filesystem 的 UUID 或 Label name 来指定磁盘位置较佳!所以,我们后来选择可以自己设置的 LABEL name 来处置。唯一要注意的, 就是 windows 缺省只使用大写字符,所以可以这样改写:

[root@localhost ~]# dosfslabel /dev/sda1 DICBOOT

[root@localhost ~]# vim /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry "Windows 10 Class system" {
        insmod part_gpt
        insmod search_fs_uuid
        insmod chain
        search --no-floppy --label --set DICBOOT  <==这里是需要注意的项目!
        chainloader /EFI/win10class/Boot/bootmgfw.efi
}
menuentry "Windows 10 Exam environment" {
        insmod part_gpt
        insmod search_fs_uuid
        insmod chain
        search --no-floppy --label --set DICBOOT  <==这里是需要注意的项目!
        chainloader /EFI/win10exam/Boot/bootmgfw.efi
}

之后再重新使用 grub2-mkconfig 去更新你的设置档,就可以躲避过这个 UEFI 的灾难了!

编译第三方软件出现『 error adding symbols: DSO missing from command line』的问题 (2019/03/06)

最近紧锣密鼓的处理环工方面的空气品质模式新版编译,遇到非常非常多的问题!其中一个很怪异的问题,发生在编译 CCTM 时产生的! 这个 CCTM 的软件主要是通过官方发布的编译模式,运行一个名为 bldit.csh 的程序,运行完毕后,该程序会主动的去创建 Makefile, 创建完成之后,在根据该 Makefile 的内容去处理后续的 make。

不过,因为软件的支持度比较广,某些软件的 library 可能没有考虑到它是动态还是静态函数库 (dynamic or static library), 因此,在最后的代码链接 (link) 时,总是可能会出现如下的问题:

[root@server ~]# mpif90  se_bndy_copy_info_ext.o se_pe_info_ext.o  ...\
  subhfile.o -L/cluster1/models/cmaq-5.2.1/lib/ioapi/lib -lioapi \
  -L/cluster1/models/cmaq-5.2.1/lib/netcdf/lib -lnetcdf -lnetcdff \
   -o CCTM_v521.exe
/bin/ld: /models/cmaq-5.2.1/ioapi/lib/libioapi.a(rdatt3.o): undefined reference to symbol 'nfmpi_inq_att_'
/programs/pnetcdf/lib/libpnetcdf.so.3: error adding symbols: DSO missing from command line
collect2: error:ld return 1
make: *** [CCTM_v521.exe] Error 1
**ERROR** while running make command

该错误主要的意思是说,链接函数库 libioapi.a 文件的时候,里面会用到 nfmpi_inq_att_ 的子程序链接, 而该 nfmpi_inq_att_ 则可能是在 libpnetcdf.so.3 那个文件里面!但是我们在链接的代码当中,并没有将 -lpnetcdf 写进去! 所以就产生这个错误!这个错误似乎没有办法在 bldit.csh 当中处理掉,因此,我们只能够通过修改 Makefile, 将该段代码加上如下的数据就可以编译成功:

[root@server ~]# mpif90  se_bndy_copy_info_ext.o se_pe_info_ext.o  ...\
  subhfile.o -L/cluster1/models/cmaq-5.2.1/lib/ioapi/lib -lioapi \
  -L/cluster1/models/cmaq-5.2.1/lib/netcdf/lib -lnetcdf -lnetcdff \
  -L/programs/pnetcdf/lib -lpnetcdf \
   -o CCTM_v521.exe

这种错误其实很常见,不过,鸟哥也是通过一次次的学习才知道处理的方法!为了避免自己忘记~写到这里来,分享给大家一起学习!

知道你的 Linux 缓存里面的文件名有哪些 (2019/02/11)

在鸟哥服务的单位中,我们的电脑教室每个学期常常需要进行大量的电脑裸机复原,电脑裸机复原需要用到很大型的 image file, 就是从已经安装好的电脑当中,将硬盘的数据以类似 partclone 的指令备份下来的大型文件,一个文件可能都有 40G 以上! 用来正课教学的映像档,甚至高达 80G 以上!

因为大量复原的关系,因此即使有 10G 网卡,如果我们的 Server 使用一般磁盘,恐怕性能也是很烂!不过,Linux 明明就有 cache (缓存) 啊! 第一个读取过这个文件后,下一个来读取,应该就是从内存读出才对!不过我们的 Server 内存没有大到 80G 啊!所以,所有的数据能否被 cache ? 那就值得讨论了。

查找一下网络上面的前辈高人,后来发现,其实 Linux 的文件 cache 并不是以文件来处理,而是以 block (区块) 来进行缓存处理! 所以,大型文件确实可以『部份缓存』而已,无须全部缓存!如果是这样的话,那么不用太快的硬盘,只要内存稍微大一些 (当然要比 8G 大), 而且所有的裸机复原时,速度相当一致的话,自然可以进行相当快速的磁盘缓存!

那么问题来了,你怎么知道这个文件被缓存多少了?其实前辈们有写一只 pcstat 的程序,在底下的链接中:

这只程序可以让你直接找到某个文件缓存的程度喔!相当简单!而且已经预先编译好,假设我以 CentOS 7 为基本系统, 那么直接下载 64 比特的版本来运行即可!

[root@server ~]# cd bin
[root@server bin]# curl -L -o pcstat https://github.com/tobert/pcstat/raw/2014-05-02-01/pcstat.x86_64
[root@server bin]# chmod a+x pcstat

这样就做好 pcstat 的可运行功能!接下来,假设我们要来探查某个大型文件,以鸟哥目前的环境下,有个名为 CentOSxxx 的文件名, 这个文件就是 CentOS 的光盘档,共有 4G 以上,有点像这样:

[root@server ~]# ll -h Cent*
-rw-r--r--. 1 root root 4.2G  5月  4  2018 CentOS-7-x86_64-DVD-1804.iso

先来看看这个文件有没有缓存呢?就直接使用 pcstat 加上这个文件名 (相对或绝对路径都可以):

[root@server ~]# pcstat Cent*
|------------------------------+----------------+------------+-----------+---------|
| Name                         | Size           | Pages      | Cached    | Percent |
|------------------------------+----------------+------------+-----------+---------|
| CentOS-7-x86_64-DVD-1804.iso | 4470079488     | 1091328    | 0         | 000.000 |
|------------------------------+----------------+------------+-----------+---------|

看起来是完全没有缓存!最右边的字段『 Percent 』就是纪录缓存的百分比!现在,来处理一下读取的任务:

[root@server ~]# time cat Cent* > /dev/null
real    0m11.108s
user    0m0.011s
sys     0m0.868s

总共花费了 11 秒喔!现在来看看有没有被缓存?

[root@server ~]# pcstat Cent*
|------------------------------+----------------+------------+-----------+---------|
| Name                         | Size           | Pages      | Cached    | Percent |
|------------------------------+----------------+------------+-----------+---------|
| CentOS-7-x86_64-DVD-1804.iso | 4470079488     | 1091328    | 1091328   | 100.000 |
|------------------------------+----------------+------------+-----------+---------|

[root@server ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:          31885        2992         307         420       28586       27988
Swap:          2047           0        2047

因为内存还够大 (32G),所以全部的 4G 都已经缓存在内存当中了!再来瞧瞧如果重新读一次这个文件,要花费多久的时间?

[root@server ~]# time cat Cent* > /dev/null
real    0m0.558s
user    0m0.008s
sys     0m0.550s

同样的文件,读取的速度从原本的 11 秒降低到只需要 0.56 秒,因为文件有 4.2G,因此读取的速度大致上可以到达 7Gbytes/s 的性能! 这就是高速缓存的好处!若以 Gbits/s 来看,则高达 56Gbps 的速度!比 10G 网卡还要快啊!

反正,这就是 pcstat 的功能,有兴趣玩一玩的,可以参考看看~下次你也可以在大量的用户端需要读取某个文件时, 事先使用类似 cat 的方式,将他读入缓存,并且使用 pcstat 确认一下是否读入了,再让用户端去读~当然网络性能就会单纯的卡在 1Gbps 网卡那端啰!

scp 在 10G NIC 的 Server 与 1G NIC 的 client 之间传输数据的问题 (2019/01/31)

我们系上为了教学方便,系上的网络系统就开始用了 10G 的网络设备,我们很骄傲的说,这是本系的骨干网络。 之前其实也拉了一条 giga 的骨干,不过当时的规划很糟糕,所以校内与系内的网络并没有分隔得很清楚,所以,某间电脑教室有风暴时, 其他间电脑教室以及骨干也会被垃圾封包塞好、塞满~因此在 2017 年中,我们就请学生自行布置 CAT6A 的网络线, 然后将主要的电脑教室串接在一起,当然,串接到这个线路的,只能是 Server 的对内端口口,对外端口口则额外连接到其他的线路, 然后在 Server 上面,再通过 iptables 的 FORWARD chain,严格限制能进入的封包这样。用了许多时候,并没有发现什么特别的问题。

去年 (2018) 年中开始,有比较大量的复原工作要进行,结果学生跑来跟鸟哥说,很奇怪,复原的速度很慢,另外,某间电脑教室改采双虚拟化系统, 通过一部 HOST 搭配两张实体显卡,来达成一部主机双人共用的环境。但是学生在拷贝 image file 时,使用 scp 的方式, 他们说,速度很慢啊!后来,看网络上面许多人都有类似的问题,将 MTU 改成 1300 左右,就可以顺利运作 scp。 不过,其他的服务会变得很奇怪~所以,这个解决方案应该不是好的方案!

鸟哥最近使用 iperf3 去查看到底出了什么事?后来发现很怪异,就是 10G --> GB 的方向,网络带宽使用非常糟糕~一下子到 500Mbps, 一下自降到 10Mbps 的情况,导致性能非常恶劣~但是 GB --> 10G 就没有这个问题~同时, 10G --> 10G 也同样没问题!

我一开始认为是驱动程序的问题,因此都朝向 NIC (网络卡) 的许多参数修改去着手,例如通过 ethtool 去修改许多参数这样。 不过查找到的方法,都没有效果~后来我突然想到, GB --> 10G 的方向,因为 10G 原本就能够覆载 1G 以上的速度,所以当然没问题! 那如果 10G --> GB 时,如果没有特别的控制,那么 GB 的网卡当然会抵挡不住 10G 来的大量封包!

朝这个方向去找寻后,发现了底下这两篇相当有趣的分析文章:

  • 10G 以太网路的错误假设,与最佳设置方式:AIXpert Blog
  • NETApp vs VMWare Flow control dilemma:Ranjit Singh

这两篇的大意是说,10G switch 上面可能会安插不同速度的网卡,例如我们的环境中,10G 网卡与 1G 网卡都安插在 10G switch 上面, 虽然通过自动协商机制,10G 自己跑 10G, 1G 自己跑 1G,速度倒是正常没问题~但是,当 1G 与 10G 进行交流时, 如果 switch 没有设置流量控制 (flow control) 时,那么慢速的网卡可能会出现来不及接收高速网卡的情况~因此上头第一篇建议, 全部的 10G switch port 都启动 flow control。不过,在鸟哥的测试中,没有 flow control 确实速度会高出这么一点点 (10G 性能可达到 9.7Gbps 左右, 加上 flow control 则大约到 9.5Gbps 左右),但是,在考虑到不同设备间的数据传输,鸟哥个人确实建议将所有的 switch 的 flow control 通通激活比较好! 至少让你的速度不会差太多!

结果查了一两个礼拜,方向都错了!直接改 switch 的 port settings ,将 flow control 勾选,解决!

# 1G 网卡的观察
[root@slow ~]# ethtool em4
Settings for em4:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Link partner advertised link modes:  100baseT/Full
                                             1000baseT/Full
        Link partner advertised pause frame use: Symmetric
        Link partner advertised auto-negotiation: Yes
        Link partner advertised FEC modes: Not reported
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 19
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: Unknown
        Supports Wake-on: g
        Wake-on: d
        Current message level: 0x00000000 (0)

        Link detected: yes

# 10G 网卡的观察
[root@fast ~]# ethtool eth4
Settings for eth4:
        Supported ports: [ TP ]
        Supported link modes:   100baseT/Half 100baseT/Full
                                1000baseT/Full
                                10000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Advertised link modes:  100baseT/Half 100baseT/Full
                                1000baseT/Full
                                10000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Link partner advertised link modes:  100baseT/Full
                                             1000baseT/Full
                                             10000baseT/Full
        Link partner advertised pause frame use: Symmetric
        Link partner advertised auto-negotiation: Yes
        Speed: 10000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 16
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: Unknown
        Supports Wake-on: g
        Wake-on: d
        Current message level: 0x00000000 (0)

        Link detected: yes

# 1G 网卡作为服务器,准备接收 client 的数据:
[root@slow ~]# iperf3 -s

# 10G 网卡作为用户端,准备发送数据
[root@fast ~]# iperf3 -c 172.31.255.101 -w 100M -t 30 -i 5
Connecting to host 172.31.255.101, port 5201
[  4] local 172.31.255.102 port 42772 connected to 172.31.255.101 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-5.00   sec   576 MBytes   967 Mbits/sec    0    505 KBytes
[  4]   5.00-10.00  sec   566 MBytes   950 Mbits/sec    0    506 KBytes
[  4]  10.00-15.00  sec   565 MBytes   948 Mbits/sec    0    506 KBytes
[  4]  15.00-20.00  sec   566 MBytes   950 Mbits/sec    0    506 KBytes
[  4]  20.00-25.00  sec   566 MBytes   950 Mbits/sec    0    506 KBytes
[  4]  25.00-30.00  sec   565 MBytes   948 Mbits/sec    0    508 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-30.00  sec  3.33 GBytes   952 Mbits/sec    0             sender
[  4]   0.00-30.00  sec  3.31 GBytes   949 Mbits/sec                  receiver

iperf Done.

简单的测试一下,确实 10G --> 1G 的速度回来了!测试完毕之后,记得两端重新变更,10G 变成 server 而 1G 变成 client ,交互测试一下喔!

鸟站的文章被入侵侦测系统抵挡的问题与解决 (2018/03/15)

前两天有个网友突然问到了跟正规表示法比较有关系的数据,属于延伸型的正规表示法。因为延伸正规表示法鸟哥真的很少用,所以许多的字符忘记了。 因此这个时候鸟站以前鸟哥自己写的文章就有帮助了。于是上网去查自己的网站,结果...整个正规表示法的网页竟然无法完全加载! 然后,还有第 13 章帐号管理的部份也没有办法加载!夭寿了!以为鸟站被攻击,赶紧登录系统去检查。

检查老半天检查不出什么问题,只发现到 /var/log/httpd/access_log 里面一直出现 304 的 http 代码。问了一下 google,知道这个是用户端自己停止继续下载! 所以是鸟哥自己的用户端浏览器自己关闭下载了...见鬼~难道是鸟哥的工作机中毒了?被当跳板了?于是赶紧跑去别台测试, 测试的结果...每一台都无法顺利打开该网页!鸟哥开始猜想,难不成是计中的问题?所以,赶紧请校外的朋友帮忙测试一下,咦! 他们可以顺利加载耶!没啥问题!所以,直觉上,鸟哥认为应该是这个网页被计中挡掉了!

电话请教计中维运的朋友,朋友说,前不久才上线一台 IPS 入侵防御系统,有没有可能是被该 IPS 所抵挡呢?所以,朋友很热心的帮鸟哥处理! 经过罗组长的努力之后,才发现到,原来鸟哥用来作为正规表示法说明的文件是 /etc/passwd,这个文件的内容中, 出现了底下这一行字样:

root:x:0:0:root:/root:/bin/bash

要命的是,在 IPS 的侦测系统中,它认为这个是很关键的字符串,很有可能是某些木马或攻击程序在窃取系统的机密数据~因此就抵挡掉了! 偏偏鸟哥有两、三个以上的网页都是以这个 /etc/passwd 的内容作为说明,因此,就有许多网页无法顺利的被加载了...真是好惨!

既然如此,那么有没有办法避免呢?可以的!只要让该字符串不要连续写下即可!也就是说,我们可以加上一些垃圾 CSS 码, 那么 IPS 就会认为该字符串没有伤害性~于是就可以顺利显示出来了!鸟哥的写法如下:

<span class="raw">root</span>:<span class="raw">x</span>:<span class="raw">0:0</span>:<span class="raw">root:/root</span>:/bin/bash

至于那个 .raw 的 class 请自行定义,如此一来,该字符串就可以不被视为有问题的攻击回传值了。真是学到了一个宝贵的经验啊!哈哈哈! 建议未来要做教学之用的说明文档,就不要使用 /etc/passwd 来做解释了!或者是可以使用画面截屏的方法来展示 (但是鸟哥不爱这个方法), 最终就是通过上述的说明,加上 CSS 码啰!

使用 Fail2Ban 进行重复连接的抵挡机制 (2018/01/29)

鸟哥在自己以前读书的实验室有摆放一 mail server,里面有激活 dovecot 的收发信件验证功能。近期经常发现有数千笔数据尝试猜测某些帐号的密码。 之所以对方会知道我们的帐号,原因很简单,只因为 email address 的写法: username@hostname 这样,所以攻击者就会知道帐号与主机名称, 接下来就可能会猜测密码了...

每天几千笔错误登录信息,害鸟哥疲于奔命~累了!还是让系统自己去抓算了。由底下的链接知道 fail2ban 拒绝 ssh 的重复连接:

那能不能用在其他的服务呢?是可以的~使用的方法很简单:

  1. 要先安装 epel 的软件套件
  2. 然后在激活 epel 的软件仓储情况下,用 yum install fail2ban 即可
  3. 在 CentOS 7 的环境下,添加 /etc/fail2ban/jail.local 文件,内容有点像这样:
    [root@cloud ~]# vim /etc/fail2ban/jail.local
    [DEFAULT]
    bantime  = 1800
    banaction = iptables-multiport
    
    [postfix-sasl]
    enabled = true
    
    [dovecot]
    enabled = true
    
    [root@cloud ~]# systemctl start  fail2ban
    [root@cloud ~]# systemctl enable fail2ban
    

这样就可以收工了。之后根据 log 文件的分析结果报告,原本动辄上千笔的信息,已经减少到 100 笔以内,效果相当不错!提供给大家参考。

VLAN 设置好之后导致的 SSH 停顿问题 (2017/11/01)

这学期的 Linux server 课程授课中,为了解决过去教学问题,所以有加上 VLAN 的设置,如 2017/09/14 所提到的项目。 而另外也为了特别强调 DHCP 的训练,因此又在实体网卡的 VLAN 附挂的桥接上,用 VM 又仿真了一层 VLAN,也就是产生了两层 VLAN 了。 这样的环境鸟哥在测试的过程中倒是没有问题,确实可以在两个独立的 KVM host 之间用两个 VM 互相 ping 到对方!鸟哥以为这样就通了! 没问题~所以就写入教学文档中。

问题是,实际教学过程中,却发现学生同样的设置却是 ping 到了不过 ssh 不成功。好怪!使用了 ssh -e server 之类的方式判断两者间的连接, 确定卡在某个点上面,将消息带入 google 中,找到了可能是 MTU 所导致的问题~不过我没有动过 MTU 啊!是标准的! 我猜,很可能是因为鸟哥的 switch 是无网管的简易型 switch,因此附挂了数层的 VLAN 之后,封包可能稍微臃肿了些~ 导致无法传递超过 switch 所致。因为如果 VM 是在同一个 KVM host 上面,就没问题!所以我当然会这么想。

怎么解决呢?将 vlan 所附挂的那张网卡之 MTU 降低到 1400 左右即可!好简单喔!就这样解决! 只是 server / client 两者都最好要设置 vlan 网卡的 MTU 到同样的数值较佳~一切顺畅!相当怪异的情境啊~所以特别写下来做个纪录!

在纯文本模式底下变更字体的方案 (2017/10/19)

网友来信问到如果是 tty2 ~ tty6 的纯文本模式下,能不能变更字体呢?因为他觉得字太小了!怎么都看不清楚!以前 kernel 2.6 的版本,可以通过修改 grub 的 kernel 参数修正, 新的 CentOS 7 可以使用一个名为 setfont 的指令来处理喔!至于有哪些字体呢? CentOS 将字体放置在这个位置:

[root@study ~]# ll /lib/kbd/consolefonts/
....
-rw-r--r--. 1 root root  4260  8月  2 21:07 LatArCyrHeb-19.psfu.gz
-rw-r--r--. 1 root root  3803  8月  2 21:07 latarcyrheb-sun16.psfu.gz
-rw-r--r--. 1 root root  5171  8月  2 21:07 latarcyrheb-sun32.psfu.gz
-rw-r--r--. 1 root root  6004  8月  2 21:07 LatGrkCyr-12x22.psfu.gz
....
-rw-r--r--. 1 root root  2084  8月  2 21:07 ruscii_8x16.psfu.gz
-rw-r--r--. 1 root root  2059  8月  2 21:07 ruscii_8x8.psfu.gz
-rw-r--r--. 1 root root  2708  8月  2 21:07 sun12x22.psfu.gz
-rw-r--r--. 1 root root  1515  8月  2 21:07 t850b.fnt.gz
....

至于缺省的字体是那一个呢?可以由底下的文件去查找一下!

[root@study ~]# cat /etc/vconsole.conf
KEYMAP="cn"
FONT="latarcyrheb-sun16"

一般来说,文件后面的数字越大,代表字体的大小越大,所以你可以尝试将自体修改成为 sun12x22.psfu.gz 看看, 字体会放大好多好多!如果想要让字体恢复一般大小,就使用数字为 16 的字体即可。操作的方式如下:

[root@study ~]# setfont sun12x22.psfu.gz

你可以自己测试一下喜欢的字体,并且搭配你的屏幕,应该就可以取得你想要的纯文本环境底下的文本大小啰! 也可以在底下的链接上面预览相关的字体显示方式:

想要在 KVM guest 环境下使用 vlan 的方式 (2017/09/14)

因为教学需求,所以需要云端电脑教室,但是每个同学都应该要有自己的区网,这样才能够进行许多的教学。不过,光是在 KVM hosts 之间创建区网, 就快要死掉了!哪有可能创建数个独立区网呢?后来想到不是有 VLAN 嘛?那就用 vlan 来玩玩看。 发现了可以通过网络卡直接加入 vlan 的信道!举例来说,如果网卡的代号是 eth0 ,那么 eth0.11 就是第 11 号 vlan 的信道 (tag=11), 然后创建一个新的 bridge 附挂在这个 eth0.11 的网卡上,那就是一个 VLAN 了!最后,让 VM 的 XML 文件中, 使用的网卡为 bridge 且附挂在刚刚创建的 bridge 上,就搞定了!整个流程很简单:

  • 在 KVM host 上面创建 11 号信道的 VLAN 网卡

我这里使用 CentOS 6 为范本,不过 CentOS 7 应该也差不多同样的方式吧:

[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0.11
DEVICE=eth0.11
VLAN=yes
ONBOOT=yes
BRIDGE=vbirdbr

[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-br11
DEVICE=br11
TYPE=Bridge
BOOTPROTO=none
ONBOOT=yes

[root@study ~]# ifup br11
[root@study ~]# ifup eth0.11
[root@study ~]# brctl show br11
bridge name     bridge id               STP enabled     interfaces
br11            8000.f46d041e83a3       no              eth0.11

重点是请看到 br11 搭配的 interfaces 是 eth0.11 这样就对了!

  • 让 Guest 的网卡支持到 VLAN 的网络中

然后你的 xml 文件改成类似这样:

    <interface type='bridge'>
      <mac address='52:54:00:87:42:42'/>
      <source bridge='br11'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

重新启动 VM 之后,你的 guest 就能够加入 VLAN 啰!怎样~不用 switch 也能够做 VLAN 了呢!

关于加密 shell script 的方式 (2017/03/06)

最近在写一些 Linux 操作系统基础训练的脚本,这些脚本有制作环境的、设置环境的、传输结果的、分析学生运行结果的等等部份。 以前都直接提供明码给学生,曾经有学生会分析脚本,直接做出对的答案...虽然这样的结果是,训练到这个厉害的学生。但是, 其他学生可能就会直接跟这个厉害的同学要求破解的方法,直接取得正确的结果,而没有实做....那就烦恼了!

在使用 google 查找了一下 shell script encryption 的结果,发现到底下的两个超链接:

主要的思考方式很简单,就是将 shell script 通过相对应的转换,将脚本变成可以直接运行的 binary program 这样!鸟哥下载的是 shc-3.8.9b.tgz 这个版本! 然后开始安装的动作!

[root@study ~]# yum install gcc glibc-static
[root@study ~]# tar -zxvf shc-3.8.9b.tgz
[root@study ~]# cd shc-3.8.9b
[root@study shc-3.8.9b]# make
[root@study shc-3.8.9b]# ll shc
-rwxr-xr-x. 1 root root 36057 2017-03-06 10:08 shc

[root@study shc-3.8.9b]# echo -e '#!/bin/bash\necho "This is a testing"' > zzz.sh
[root@study shc-3.8.9b]# cat zzz.sh
#!/bin/bash
echo "This is a testing"

[root@study shc-3.8.9b]# file zzz.sh
zzz.sh: Bourne-Again shell script text executable

[root@study shc-3.8.9b]# CFLAGS="-static " ./shc -v -r -f zzz.sh
shc shll=bash
shc [-i]=-c
shc [-x]=exec '%s' "$@"
shc [-l]=
shc opts=
shc: cc -static  zzz.sh.x.c -o zzz.sh.x
shc: strip zzz.sh.x
shc: chmod go-r zzz.sh.x

[root@study shc-3.8.9b]# ll zzz*
-rw-r--r--. 1 root root     37 2017-03-06 10:12 zzz.sh
-rwx--x--x. 1 root root 726584 2017-03-06 10:13 zzz.sh.x  <==注意这个!
-rw-r--r--. 1 root root   9396 2017-03-06 10:13 zzz.sh.x.c

[root@study shc-3.8.9b]# ./zzz.sh.x
This is a testing

[root@study shc-3.8.9b]# file zzz*
zzz.sh:     Bourne-Again shell script text executable
zzz.sh.x:   ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, 
            for GNU/Linux 2.6.18, stripped
zzz.sh.x.c: ASCII C program text

你就会取得一个 zzz.sh.x 的运行档~最后将这个运行档更名为 zzz ,并将 zzz 放置到 /bin 或 /sbin 底下,嘿嘿!就能够被运行而不被查找到代码! 之后鸟哥就可以轻松的放一些侦测脚本,而不被学生直接分析,导致被攻破啰!

关于 DRBL 还原之后,Linux 内核出错的问题!(2017/03/06)

鸟哥所服务的单位是在昆山科大资传系,系上的学生相当贴心,每个学期都会主动的协助鸟哥进行全系电脑的复原!我们的 PC 系统上面都会安装多重操作系统, 提供多个不同的操作系统,以利各种教学所需要的特别环境。使用的复原系统为 DRBL 以及 Clonzilla !

最近学生反应,五间教室里面,有两间复原 Linux 没问题,有三间复原就出事!鸟哥觉得很纳闷~去瞧了瞧,发现到:

  • 开机可以顺利出现 grub 的菜单
  • 按下菜单后,可以顺利的加载内核进行开机,但是等待大约 3 分钟左右,会出现 WARNING, dracut error 等字样
  • 之后系统丢一个 dracut 的 shell 画面提供登录与处理

因为最终出现 dracut ,而最新的 CentOS 使用的 initramfs 确实是在安装内核时才开始打包,并非一开始就直接提供的! 所以直觉上,鸟哥觉得应该是 initramfs 出错了!所以解决的方案是这样的:

  1. 使用原版 CentOS 7 的 USB 开机磁盘开机,选择『 Rescue 』选项,并进入救援模式中
  2. 系统会主动抓到 CentOS 的已安装系统,并且加挂在 /mnt/sysimage 当中!
  3. 使用 chroot /mnt/sysimage 来切换主系统,取得一个 root 的 shell 环境中。
  4. 进入 /boot ,将有问题的 initramfs 更名
  5. 通过『 dracut -v /boot/initramfs...(原本文件名) $(uname -r) 』其中 uname -r 是因为这个系统为全新的系统,并没有更新过! 如果你需要不同内核,就得要查找一下 /lib/modules 的内核版本才行。
  6. 下达 restorecon -Rv /boot 稍微处理一下 SELinux 可能会有的错误!
  7. 重新开机测试新的 initramfs 的结果!

鸟哥比较偷懒,不想要更改文件名,所以所创建的 initramfs 使用的是原本的文件名,这样就不用修改 /boot/grub2/grub.cfg 文件! 重新开机后就正常了! ^_^

关于 DNS 查找的问题解析!(专题服务器组所导致的问题)(2017/03/06)

三月初刚刚放假回到系上,立刻接到消息,说我们系上管理的一个 IP 一直对学校的 DNS 主机进行攻击!查了一下该 IP 的所在, 原来是系上提供给所有大三、大四进行专题实务的 Linux 服务器组!一开始鸟哥以为是整个系统被攻破了!非常紧张! 来到实体电脑实际使用 tcpdump 去抓封包,确实会对外查找学校的 DNS 系统!我是这样查找的:

  1. 使用 tcpdump -i eth0 -nn ,这个 eth0 假设是对外的网卡。从分析当中,确实发现到有本机对学校的 DNS IP 发起 port 53 的查找要求!
  2. 因为这个 IP 是 NAT 的功能,还有内部的四部实体主机 (主要提供学生虚拟化机器的 host) 是通过这个 IP 连外的!因此,鸟哥开始使用 tcpdump -i eth1 -nn, 这个 eth1 假设是内部连接的网卡。然后发现到 4 部内部主机有 3 部确实对 DNS IP 发起连接需求。
  3. 尝试登录内部主机中,那有问题的 3 部中的其中一部,发现到『登录非常的慢,大约要等 30 ~ 60 秒,但是登录后就一切顺畅!』
  4. 之后在该内部主机使用『 netstat -antup 』查找一下连接数据,却发现到『有从 NAT 主机来的连接,然后这条连接会发起 DNS IP 解析的需求』。 问了一下管理该系统的研究生,他说为了硕士论文的研究,确实有在 NAT 主控系统上面对内部四部主机进行数据收集, 但是该数据收集的脚本仅是针对主机内的资源 (如 CPU 使用率、磁盘使用率、内存使用状况等等),完全没有发起网络的功能! 鸟哥查看一下 shell script,确实如此!完全没有动到网络喔!
  5. 有一部主机是正常的,鸟哥比对一下两部主机之间的差异,竟然发现到 /etc/resolv.conf 内容不一致!原本这套系统缺省的 DNS 设置为内部的私有 IP, 但是后来系统改版 (从 CentOS 6 升级到 CentOS 7),可能安装的时候没有注意到,因此内部主机的 DNS 设置直接指向学校的 DNS server 去了。
  6. 最后将 DNS 设置改为我们自己的内部 IP 就直接 OK 了!

读者可能会问,那奇怪了!为啥之前都没问题,现在才发生问题呢?这是因为这样的情况:

  1. 前几个礼拜 meeting 后,对研究生下答要去收集虚拟机所在的主机的资源统计,所以这个脚本是最近才放上去的;
  2. 这个脚本是由 NAT 主控系统直接发派给四部内部提供虚拟化服务的主机,主要是通过 ssh 的方式来达成脚本传递的任务
  3. 内部主机使用缺省的 ssh 设置,因此连接时,会反查连接者的 IP 反查
  4. 整套系统原本设有内部 DNS 私有 IP 的 domain 设置,但因为系统重装,结果没有指向正确的 private IP,又没有更新 /etc/hosts, 所以每次传递 shell script (每 5 秒传一次),就会产生 DNS 的查找要求!
  5. 二月底全校停电,复电后计中的 DNS 系统据说被 DDoS 了!计中人员查找连接者 IP,发现到我们这个 IP 很频繁的对 DNS 主机发出查找要求, 但是却都查找失败 (因为是 private IP 啊!),所以误判为我们的系统对人家攻击了!

为了避免产生问题,所以鸟哥这样处理过后,应该就不会有其他状况的发生!

  • 将内部主机的 /etc/resolv.conf 设置,指向内部的 DNS server
  • 将内部的 private IP 通通写入 /etc/hosts ,提供内部查找 (与前一步骤双管齐下)
  • 将 sshd_config 加入『 UseDNS no 』的设置,让连接时不会反查 IP 来源了

bnx2x 网络卡经常反复断线的问题 (2017/02/17)

近年来因为云端的关系,鸟哥跟伙伴们买了不少的 10G 网卡以及 10G 少数 port 的 switch 来在云服务器内部加速。 不过,经常会看到 log 里面出现这样的消息呢:

[root@study ~]# tail /var/log/messags
Feb 17 06:40:35 host kernel: bnx2x 0000:05:00.0: eth4: NIC Link is Down
Feb 17 06:40:40 host kernel: bnx2x 0000:05:00.0: eth4: NIC Link is Up, 10000 Mbps full duplex, Flow control: none
Feb 17 07:11:12 host kernel: bnx2x 0000:05:00.0: eth4: NIC Link is Down
Feb 17 07:11:17 host kernel: bnx2x 0000:05:00.0: eth4: NIC Link is Up, 10000 Mbps full duplex, Flow control: none

很奇怪,每隔几个小时就会自动的断线再开~虽然不会影响到原本的系统运作 (没有持续性挂载的数据放在该网卡上), 不过就是心里不舒服~后来查了一下,似乎是网卡与 switch 之间沟通的 bug 所致,而且目前如果你没有更新 switch 固件的话, 应该是没有办法解决的,详情可查阅:

其实解决方案还挺简单的耶!就将网卡与 switch 之间的自动判断网络速度功能 (auto negotiation) 设置为不激活 (off) 即可。 设置方式如下:

[root@study ~]# ethtool -s eth4 autoneg off

测试个几天,如果问题解决了,将上述的指令写入 /etc/rc.d/rc.local 并将该文件权限改成正确,就 OK 了!

Windows 10 通过 KVM 与 spice 的显示问题 (2016/10/06)

一直以来教学测试的 VM 都是以 windows 7 为主,还没有安装过 windows10 在 VM 里面。因为考虑到未来的使用情况, 所以安装了 windows 10 的环境在 VM 底下,为了要加速,所以也使用了 KVM 建议使用的 spice (QXL) 显卡环境。

奇怪了! windows 10 的 VM 环境显示效果奇差无比!根据 netman 大大提供的意见,找到了底下这两篇文档:

看起来是 driver 的问题!然后跑到上面网站的链接,也就是底下的网站:

鸟哥安装的是 qxlwddm-0.16-flexvdi.zip 这个文件,结果竟然显示的效果就好很多了!真是奇怪奇怪奇奇怪怪!鸟哥也不知道为何会这样~ 真的是无奇不有~为了担心这个文件日后不见去,我把这个文件拷贝一份到 这里来 了, 单纯备份而已,不做其他应用!

插上 PCI-E 扩充卡在个人电脑主机上,原本主板上面的内存竟然消失不见了(2013/04/19)

在 2013 年初,鸟哥买了几片 10G 的 PCI-E 8x 的网卡在进行一些研究,我的主板上面原本有 8Gx4=32G 的内存在。插上 10G 的网卡后,竟然发现内存插槽第三槽 (slot 3) 上面的内存无法抓到了!拔掉 10G 网卡就恢复正常~很怪。更新了 BIOS 以及相关的 BIOS 内设置,都没有办法解决这个问题~困扰了一个多月啊!!

查找了很多数据,都没有人说到解决方案。最终询问一些常常帮客户作客制化的硬件厂商,他们的经验是,因为个人电脑制造商根本不会想到一般用户会拿主板安装这些高端扩充卡, 所以,当插了这些扩充卡之后,BIOS 恐怕会误判硬件,导致内存就凭空消失!这在他们的经验中,还挺常发现的!鸟哥的问题是 10G 网卡, 他们的问题则是发生在 RAID card 上头~因为他们经常帮客户组装白牌的 RAID 机器设备。

怎么解决呢?非常有趣!厂商跟我说,只要将 PCI-E 金手指,那个 pin 5, pin 6 脚位使用胶带黏起来,让它不会过电,一切问题就解决了! 鸟哥原本是半信半疑,后来跑去查 wiki 的 PCI-E 脚位定义,发现到 pin 5, pin 6 主要是定义 PCI-E 扩充卡总线的时脉 (SMBus) ,除此之外,并没有其他特殊的功能! 也不是负责传输的 LANE~于是乎,鸟哥就很开心的请会作手工艺的学生将两个脚位贴起来胶带。

效果惊人!立刻抓到消失的内存!太开心了!提供给大家参考!如果有发现同样问题的话,可以这样解决看看!相当有趣喔! ^_^!原本鸟哥会担心这样会不会造成性能方面的困扰 赶紧实测一下~竟然没有任何问题!运作上也很顺畅!真是开心又愉快啊! ^_^

不过,厂商说的也有道理,既然主板原本的设计就不是给这些设备用的,还是买高端的 server 设备来安装这些卡使用比较好~这...鸟哥也知道啊! 不过,穷老师有穷老师的苦处啊~~

其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计