分类目录归档:技术

限制线程数避免Hugo资源耗尽被杀

如果项目很大,hugo默认启动物理核心数个线程并发,但如果已有程序占用,就可能导致 hugo 进程杀死。

hugo --gc --minify

此时可以尝试使用下面这个命令:

HUGO_NUMWORKERMULTIPLIER=2 hugo --gc --minify --cacheDir /root/archive/cacge

主要是这两个参数:

  • HUGO_NUMWORKERMULTIPLIER: (int) The number of workers used in parallel processing. Default is the number of logical CPUs.
  • --cacheDir: 指定一个缓存目录,可能有助于减少内存消耗。

References

#Hugo

apt 源 Connection reset by peer 问题解决

在 apt 2.1.9 及以后的版本中,apt 的 HTTP Pipelining 特性与 Nginx 服务器疑似存在一定的不兼容问题,可能导致高带宽从镜像站下载大量软件包 (例如系统升级)时出现偶发的 Connection reset by peer 错误

目前,用户可以通过关闭 HTTP Pipelining 特性解决此问题。 如果需要关闭,可以在使用 apt 命令时加上 -o Acquire::http::Pipeline-Depth=0 参数,或使用以下命令将相关设置加入 apt 系统配置中:

echo "Acquire::http::Pipeline-Depth \"0\";" > /etc/apt/apt.conf.d/99nopipelining

Reference

Linux 能否使用 ACL 默认为新目录配置粘滞位

答案是不能直接实现,可以简介做到,详情向下看:

This is a configuration that allows members of a group, acltest, to create and modify group files while disallowing the deletion and renaming of files except by their owner and “others,” nothing. Using the username, lev and assuming umask of 022:

groupadd acltest
usermod -a -G acltest lev

Log out of the root account and the lev account. Log in and become root or use sudo: 注销 root 账户和 lev 账户。登录并成为 root 或使用 sudo:

mkdir /tmp/acltest
chown root:acltest /tmp/acltest
chmod 0770 /tmp/acltest
chmod g+s /tmp/acltest
chmod +t /tmp/acltest

setfacl -d -m g:acltest:rwx /tmp/acltest
setfacl -m g:acltest:rwx /tmp/acltest

ACL cannot set the sticky bit, and the sticky bit is not copied to subdirectories. But, you might use inotify or similar software to detect changes in the file system, such as new directories, and then react accordingly. ACL 无法设置粘滞位,并且粘滞位不会复制到子目录。但是,您可以使用 inotify 或类似软件来检测文件系统中的更改,例如新目录,然后做出相应的反应。

For example, in Debian:

apt-get install inotify-tools

Then make a script for inotify, like /usr/local/sbin/set_sticky.sh.

#!/usr/bin/env bash
inotifywait -m -r -e create /tmp/acltest |
while read path event file; do
    case "$event" in
        *ISDIR*)
            chmod +t $path$file
            ;;
    esac
done

Give it execute permission for root: chmod 0700 /usr/local/sbin/set_sticky.sh. Then run it at boot time from, say, /etc/rc.local or whichever RC file is appropriate:

/usr/local/sbin/set_sticky.sh &

Of course, in this example, /tmp/acltest should disappear on reboot. Otherwise, this should work like a charm.

References

软件架构开发模型特征总结

  • 瀑布模型:结构化方法。开发阶段性、需求明确、文档齐全、风险控制弱;
  • 原型模型:迭代方法,分为原先开发与目标软件开发,需求不太明确;
  • 螺旋模型:迭代方法。瀑布与原型(演化)模型i结合体。适用于大型、复杂、风险项目。
  • 喷泉模型:面向对象方法。复用好、开发过程无间隙、节省时间;
  • V模型:开发与测试结合;
  • 变换模型:适用于形式开发;
  • 智能模型:适用于i基于规则的专家系统;
  • 快速应用开发RAD:基于构件的开发方法。用户参与、开发或复用构件、模块化要求高,不适用新技术;
  • RUP/UP:用例驱动、架构为中心、迭代、增量
  • 可重用构建模型:基于构件的开发方法。开发或复用构件

#系统架构设计

Linux 文件管理之隐藏属性

linux文件属性包括文件的许多特征,通常有文件类型、文件大小、文件所有者、文件所属组、文件最后修改时间等,而隐藏属性是属于文件的特殊性质。这些隐藏属性在linux中可以通过chattr命令进行设置,通过lsattr命令查看。

chattr

chattr是一个linux命令,用于设置文件的某些隐藏属性,以保护重要文件和文件夹免受意外删除或修改,而且是少有的能够直接限制root用户的命令。

chattr的语法如下,

chattr [选项] [操作符] [属性] 文件...

其中操作符有以下几个符号:

  • +:将指定的属性添加到现有属性
  • -:从现有属性中删除指定的属性
  • =:将指定的属性设置为唯一属性,覆盖原来的属性

操作符后可接多个属性,下面是一些常见属性:

  • a:文件只能以追加模式写入。
  • A:文件的访问时间(atime)记录不会被修改,可以减少磁盘IO。
  • e:文件使用extents映射磁盘上的块,这个属性无法被chattr修改,与文件系统有关,例如ext4文件系统。
  • i:文件不可变,即文件不能被删除或修改。

更多说明内容可以使用man chattr查询。

lsattr

lsattr命令主要用于查看文件对应的隐藏属性。

例如

lsattr /etc/passwd

chattr锁定文件

前面提到chattr是少有的能够直接限制root用户的命令,但同时它也需要谨慎使用。

可以通过以下命令创建并锁定文件,即使root用户也无法直接删除和修改。

touch ~/immutable.txt
sudo chattr +i ~/immutable.txt
lsattr ~/immutable.txt

sudo rm -rf ~/immutable.txt

要删除文件,只能使用chattr重新取消i属性。

sudo chattr -i ~/immutable.txt

rm -rf ~/immutable.txt

chattr命令虽然可以阻止文件被意外删除或修改,但是它所针对的文件或目录对象,通常是一些内容不会去改动的系统配置文件、日志文件、备份文件等,而且这些文件和目录不应该对其他的文件和目录有依赖关系。例如,你对那些linux命令的可执行文件使用chattr锁定,那它们大概率会无法正常工作。

References

宝塔面板手动编译安装 PHP 插件 fileinfo

以 php 8.2 为例,具体根据实际情况调整,主要是其中的 -O2 参数,在低性能服务器下容易编译死机。

需先配置 2~4 GB 的 SWAP 后继续。

cd /www/server/php/82/src/ext/fileinfo
/www/server/php/82/bin/phpize
./configure --with-php-config=/www/server/php/82/bin/php-config
sed -i "s#CFLAGS = -g -O2#CFLAGS = -std=c99 -g #g" Makefile
make && make install

echo "extension=/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/fileinfo.so" >> /www/server/php/82/etc/php.ini
echo "extension=/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/fileinfo.so" >> /www/server/php/82/etc/php-cli.ini
/etc/init.d/php-fpm-82 restart

References

Linux 文件管理之默认权限 umask

一般来说 Linux 上的文件或目录使用一组默认的权限进行创建,umask 命令可用于查看或设置创建新文件的时的默认权限。

不带任何选项参数的情况下使用 umask 命令就是查看当前的掩码值:

umask
0022

可以看到当前的掩码值是 0022,在一些发行版中也常见为 0002

然后使用 touch 和 mkdir 创建一个文件和目录再看看它们的权限是怎样的:

touch file.txt
mkdir dir

ls -l
drwxr-xr-x 2 toor toor 4096 Sep  2 14:46 dir
-rw-r--r-- 1 toor toor    0 Sep  2 14:46 file.txt

也就是说这些权限是默认值减去 umask 掩码值得到的:

  • 目录 dir:0777 – 0022 \= 755(rwxr-xr-x);
  • 文件 file.txt:6000 – 0022 \= 644(rw-r–r–);

此时我想要更改默认权限,就可以反推一下进行设置掩码值,如:

umask 0002 # 之前是 0022

touch test.txt

ls -l test.txt
-rw-rw-r-- 1 toor toor 0 Sep  2 14:52 test.txt

可以看到新创建的文件默认权限已经变成了 664(rw-rw-r–)

使用 umask 掩码值并不会改变之前文件的权限,而且仅临时生效于当前 shell 会话,如果想要永久生效需要修改 shell 的配置文件。

References

Linux 文件管理之特殊权限

除了读取、写入、执行权限之外还有其他一些较少用到的特殊权限设置。

SUID(Set User ID)

ls -l /usr/bin/passwd /etc/passwd /etc/shadow
-rw-r--r-- 1 root root    1443 Apr  7 22:39 /etc/passwd
-rw-r----- 1 root shadow   974 Apr  7 22:39 /etc/shadow
-rwsr-xr-x 1 root root   63960 Feb  7  2020 /usr/bin/passwd

在使用 passwd 命令(/usr/bin/passwd)修改密码时,会修改存储密码的配置文件 /etc/shadow(在之前的文章有提到,历史上密码存储于 /etc/passwd 中但现在已经不是了)。

但只是普通用户权限的我们是如何得以修改 /etc/shadow 文件的?答案是 setuid。

setuid 位(八进制表示为 4000),如果将其应用于可执行文件,会将有效用户ID(effective user ID)从真实用户(实际执行程序的用户)ID更改为程序属主的有效用户ID。

大多数情况下,少数超级用户的程序才会做此设置。当普通用户执行 setuid root 程序时,该程序将以超级用户的权限来执行,可以访问普通用户通常被禁止访问的文件和目录。这显然会带来安全隐患,因此允许设置 setuid 位的程序数量必须控制在最小范围内。

chmod u+s <程序文件名>

# 八进制法表示为
chmod 4755 <程序文件名>

权限:-rwsr-xr-x,注意属主的s。

SGID(Set Group ID)

setgid 位类似于 setuid 位,它会将有效组ID(effective group ID)从真实用户的真实组 ID(real group ID)更改为文件属主的有效组 ID。

如果对目录设置 setgid 位,那么在该目录下新创建的文件将由该目录的属组所有,而非文件创建者的属组所有。

这在共享目录中非常有用,当一个共同属组的成员需要访问目录中的所有文件时,不用管文件属主的属组是什么。

chmod g+s <目录名>

# 八进制法表示为
chmod 2775 <目录名>

权限:drwxrwsr-x,注意属组的 s。

Sticky Bit

粘滞(sticky)位来自「远古」Unix 的遗留产物,用于将可执行文件标记为「不可交换」。

Linux 会忽略文件上设置的粘滞位,如果对目录设置了粘滞位,则能够阻止用户删除或者重命名其中的文件,除非用户是该目录的属主,或者是文件的属主,又或者是超级用户。

粘滞位常用来控制对共享目录(如 /tmp)的访问。

chmod +t <目录名>

# 八进制法表示为
chmod 1777 <目录名>

权限:drwxrwxrwt,注意最后的t。

References

Linux 文件管理常规操作

文件权限(文件模式)指定谁可以在 Linux 系统上访问、改变或执行一个文件。它确保只有授权的用户和进程可以访问文件和目录。

通过命令 ls -l 就可以获得文件的权限、属主与属组等信息:

ls -l /etc/hosts
-rw-r--r-- 1 root root 186 Aug 27 18:31 /etc/hosts

这些信息表示为:

  • 文件类型及权限:-rw-r--r--;
  • 硬链接数量:1;
  • 文件属主:root;
  • 文件属组:root;
  • 文件的字节数大小:186;
  • 最后修改日期及时间:Aug 27 18:31;
  • 文件名:/etc/hosts;

属主、属组以及其他用户

对于每个文件来说,权限被分配给三种不同类别的用户:

  • 属主:文件和目录所属于的用户;
  • 属组:属于由一个或多个用户组成的组,属组用户被文件和目录的属主授予访问权。
  • 其他用户:在 Unix 术语里这叫作「世界(world)」的(即除了属主与属组外的)其他用户授权。

以 -rw-r--r-- 为例,在之前的文章有提到第一个字母表示文件类型,剩余的每三个字母分别表示属主、属组和世界(其他用户)的权限:

文件类型 属主(Owner) 属组(Group) 世界(World)
– rw- r– r–

关于第一个字母表示的文件类型:

  • 普通文件:-
  • 目录:d
  • 字符设备文件:c
  • 块设备文件:b
  • 本地域套接字:s
  • 具名管道(FIFO):p
  • 符号链接:l

读取、写入和执行

举个例子,-rwxr-r-- 表示这是一个普通文件,属主拥有读取 r(ead)、写入 w(rite) 及执行 x(ecute) 权限,而属组和世界(其他用户)均有读取但没有写入和执行权限。

权限 文件 目录
r(ead) 允许打开和读取文件 允许列出目录文件(需同时含有执行权限)
w(rite) 允许将文件写入或截断,但不允许重命名或删除文件(由目录属性决定)。 允许在目录内创建、删除及重命名文件(需同时含有执行权限)
x(ecute) 允许将文件视为程序并执行,用脚本语言编写的程序文件也必须设置为可读才能执行 允许进入该目录
– 无权限 无权限

❓ 你可能对属组还不是很明白,举个例子有这么一个目录:

drwxr-x--- 3 a www 4096 Mar 30 15:30 wwwroot

属主是用户 a,属组是 www。这时用户 b 没有权限的,因为其他用户权限是 ---。 但让用户 b 加入到名为 www 到用户组就可以拥有权限 r-x。

💡思考

那么当一个文件的属主没有写入权限而属组有写入权限时,如:

-----w---- 2 user1 group1 4.0K Aug 23 08:45 README

注意 user1 用户属于 group1 用户组,这时可以写入吗?

这是一个权限冲突的问题,属主权限是 ---,属组权限是 -w-,当遇到这样的情况时以属主权限为准,即便该用户属于有写入权限的用户组。

修改文件权限:chmod

**文件和目录只有其属主或 root 用户通过 chmod(Change Mode)命令修改文件或目录的文件模式(权限)。

chmod 命令有八进制表示法和符号表示法两种模式表示方式。

八进制表示法

八进制 二进制 模式
0 000 —
1 001 –x
2 010 -w-
3 011 -wx
4 100 r–
5 101 r-x
6 110 rw-
7 111 rwx

举个例子:

mkdir Documents && ls -l
drwxr-xr-x 2 conners conners 4096 Apr  8 11:32 Documents

这里新建了一个名为 Documents 的目录,并且可以看到权限是 rwxr-xr-x。

按照八进制表示法就是 755,也就是依照 3 个八进制数位表示属主、属组与其他用户的权限。

  7       5    5
 user   group  world
 r+w+x  r+x    r+x
 4+2+1  4+0+1  4+0+1 = 755

那么如果想要将其他用户的权限禁止掉,即修改为 rwxr-x--- 就可以使用八进制表示法:

# chmod <八进制表示法> <目标文件或目录>
chmod 750 Documents

符号表示法

符号 含义
u 属主(user 缩写)
g 属组(group 缩写)
o 其他用户(other 缩写)
a 所有(all 缩写,等同于 u、g、o 一起设置)
+ 添加权限
– 移除权限
\= 只赋予指定权限并移除其他权限

举几个例子:

# 为指定文件或目录的属组添加写入权限
chmod g+w <目标文件>

# 移除属主、属组与其他用户的写入权限
# 可以进一步简写为 -w 省去 a
chmod a-w <目标文件>

# 可以同时添加多个权限,如为属组同时添加写入与执行权限
chmod g+wx <目标文件>

# 等号会移除其他权限
# 如下,为属组与其他用户设置为仅有读取与执行权限,如果原有写入权限会被禁用
chmod go=rw <目标文件>

# 一次性为属主、属组与其他用户设置不同权限时,可用英文逗号隔开
chmod u+x,go=rx <目标文件>

💡 可以使用 -v 选项得出修改前后的差别及八进制表示:

chmod -v 755 file.txt
mode of 'file.txt' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)

复制已有文件的权限

可以使用 --reference 选项复制已有文件的权限:

# chmod --reference=<被复制权限文件> <复制权限文件>
chmod --reference=a.sh b.sh

如上,文件 b.sh 就拥有了和 a.sh 一样的文件权限。

递归设置子目录文件权限

chmod 还可以使用 -R 选项以递归的方式更新目录内所有文件的权限。但注意目录下的内容及子目录未必都是相同的属性,比如有的是可执行文件有的是文本文件。

在使用 chmod -R 进行执行权限调整需要谨慎,它不会去管执行权限对目录和普通文件有不同的含义。前面说过对于目录 x 表示进入目录,对于普通文件 x 表示执行。

针对这个问题,也就是如果只想对文件进行一个递归设置,但目录不要进行相应权限设置,可以搭配 find 命令:

find ~ -type f -exec chmod 640 {} \;

上面这条命令表示使用 fimd 查找主目录(~)下的普通文件(-type f),执行命令(-exec),命令为 chmod 640,针对查找到的文件({}),命令结束(\;)

修改文件属主与属组:chown 与 chgrp

使用 chown 和 chgrp 命令可以用于改变文件的属主和属组。

只有 root 用户可以改变文件的属主,普通用户只有在拥有该文件并且只能更改为其所属的组时才能更改该文件的属组,而 root 用户可以更改所有文件的属组。

修改文件的属主:

sudo chown <目标用户> <文件名>

在用户组前加上冒号即为修改文件的属组,属主不变:

chown :<目标群组> <文件名>

将两者结合,修改目录 wwwroot 的属主为 nginx,属组为 web:

# -R 选项用于递归修改目录下的子文件及子目录
sudo chown -R nginx:web wwwroot

除了使用 chown :<目标属组> <文件名>,使用 chgrp 命令也可以达到相同效果:

sudo chgrp <目标群组> <文件名>

References

Linux 粘滞位 Sticky Bit

粘滞(sticky)位来自「远古」Unix 的遗留产物,用于将可执行文件标记为「不可交换」。

Linux 会忽略文件上设置的粘滞位,如果对目录设置了粘滞位,则能够阻止用户删除或者重命名其中的文件,除非用户是该目录的属主,或者是文件的属主,又或者是超级用户。

粘滞位常用来控制对共享目录(如 /tmp)的访问。

chmod +t <目录名>

# 八进制法表示为
chmod 1777 <目录名>

权限:drwxrwxrwt,注意最后的t。

粘滞位主要控制 o 对文件的修改,故也采用 o+t 的形式配置。

References