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

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

只有 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

《芯片战争:世界最关键技术的争夺战(财之道丛书)》

阅读感悟

暂略

阅读笔记

《芯片战争:世界最关键技术的争夺战(财之道丛书)》

 克里斯·米勒

 17个笔记

 推荐序 国运升级点

  • 客观地说,当今中国的经济和科技发展水平,不但比不了美国,而且连20世纪80年代正在崛起中的日本都比不了。当时日本已经有索尼、夏普、丰田、本田、东芝、佳能、尼康等一系列拥有自己的核心技术、自己的设计、自己的品牌,且受到全世界消费者追捧的公司。日本曾经在芯片上把美国打到近乎绝望。就连韩国,早在一二十年前,也已经有了三星、LG、现代这样的全球知名企业。而当今中国除了华为和字节跳动,全球品牌还很少,独家技术也很少
  • 中国排在前列的大公司都是像石油、银行、电网和电信这些国有企业,一些国产品牌只在中国能做到家喻户晓。中国经济体量大、数字好看,而我们的真实经济实力,特别是创新能力,距离发达国家还很远
  • 中国被“卡脖子”的绝不仅仅是芯片。我们在工业母机、医疗仪器、农牧业育种等很多领域都受制于人。我们的产业升级远远没有完成。芯片只是一个聚焦点,但是透过芯片,我们也许可以反思一下一些人过去那种比较幼稚的世界观
  • 简单说,米勒这本书能纠正我们三个错误认知。
  • 第一个错误认知是任何高科技都可以用“堆积”的方法获得。
  • 不可堆积的东西往往要求高水平人才的奇思妙想,要求复杂的环境,要求可遇不可求的机遇。
  • 而要造芯片,从芯片设计软件到光刻机,再到硅材料,每一个步骤都需要很多个聪明人的奇思妙想,这里没有“大力出奇迹”。你需要成千上万个“邓稼先”和“于敏”,而且他们必须都在自己的行业里做得树大根深。
  • 芯片的科学原理没有秘密,都是公开的。但是要做到技术上的可行性,尤其是商业上的可盈利性,那可就太难了。花一亿元人民币造出一颗芯片是没有意义的,我们必须保证大规模制造、保证良品率、保证更新速度,还得保证做出来很便宜才行
  • 现实是中国制造从未离开过全世界的技术支持
  • 是,我们现在有一些像量子信息、碳纳米管芯片之类的领先研究,但是这些都还处于探索科学可能性的阶段——全世界有无数个类似的研究在赌,它们距离技术可行性、商业可盈利性还差十万八千里,根本谈不上“第四次工业革命”。
  • 第二个错误认知是创新应该由政府来主导。
  • 第三个错误认知是我们应该独立自主。
  • 现实是就芯片技术而言,连美国都不能独立自主。美国必须依赖荷兰的光刻机、日本的硅片和中国台湾的制造
  • 所谓的芯片战,美国卡中国脖子,恰恰就是逼着中国去独立自主。这叫作“把互相依赖武器化”:为了打击你,我不让你依赖我
  • 互相依赖是一种生存条件,被孤立是一种打压。现代化已经形成了一个全球“圈子”,只有圈里人得到这个圈的各种好处和帮助,互相依赖,才能把事情做成,独立于圈外没有任何前途。
  • 不被卡脖子的正确做法不是独立自主,而是让自己变得更值得依赖,让包括美国在内的全世界不得不依赖我们,以此跟美国讨价还价,若你要再敢卡我脖子我就卡你脖子
  • 然而进入21世纪,中国经济就到了下一个阶段。允许引进的技术已经引进完毕,剩下的得自己研发,创新走到了无人区。人口步入老龄化,劳动力越来越贵。全球化在退潮,美国等国家已经不拿中国当发展中国家,开始对抗

 来自微信读书

架构风格总结

架构风格总结

mindmap
  root((软件架构风格))
    数据流
      批处理
        (一个接一个,以整体为单位)
      管道/过滤器
        (前一个输出是后一个输入)
        (实例: 传统编译器)
    调用/返回
      主程序/子程序
        (显式调用,主程序直接调用子程序)
      面向对象
        (对象是构件,通过对象调用封装的方法和属性)
      层次结构
        (分层,每层最多影响其上下两层,有调用关系)
    独立构件
      进程通信
        (进程间独立的消息传递,同步异步)
      事件驱动
        (不直接调用,通过事件驱动)
        (实例: 语法高亮、错误提示)
    虚拟机
      解释器
        (解释自定义规则,解释引擎、存储区、数据结构)
      规则系统
        (规则集、规则解释器、选择器和工作内存)
        (用于DSS和人工智能、专家系统)
      (实例: 自定义流程,按流程执行,规则随时改变)
    仓库/数据共享风格
      数据库
        (中央共享数据源,独立处理单元)
      超文本
        (网状连接,多用于互联网)
      黑板
        (用于问题复杂、解空间大的软件系统)
        (实例: 语音识别、知识推理)
    闭环-过程控制
      (发出控制命令并接受反馈,循环往复达到平衡)
      (实例: 汽车定速巡航、空调温度调节)
    C2风格
      (通过连接件绑定的并行构件网络)
      (构件和连接件、顶部和底部)

背诵版

数据流

实例:传统编译器,每个阶段产生的结构作为下一个阶段的输入,区别在于整体。

批处理

一个接一个,以整体为单位。

管道/过滤器

一个接一个,前一个输出是后一个输入。

调用/返回

主程序/子程序

显示调用,主程序直接调用子程序。

面向对象

对象是构件,通过对象调用封装的方法和属性。

层次结构

分层,每层最多影响其上下两层,有调用关系。

独立构件

进程通信

进程间独立的消息传递,同步异步。

事件驱动

不直接调用,通过事件驱动。

实例:时间出发推动动作,如程序语言的语法高亮、语法错误提示。

虚拟机

实例:自定义流程,按流程执行,规则随时改变,灵活定义,业务灵活组合机器人。

解释器

解释自定义的规则,解释引擎、存储区、数据结构。

规则系统

规则集、规则解释器、选择器和工作内存,用于DSS和人工智能、专家系统。

仓库

实例:现代编译器的集成开发环境IDE,以数据为中心

又称为数据共享风格。

数据库

中央共享数据源,独立处理单元。

超文本

网状连接,多用于互联网。

黑板

语音识别、知识推理等问题复杂、解空间很大、求解过程不确定的这一类软件系统,黑板、知识源、控制。

闭环-过程控制

实例:汽车定速巡航、空调温度调节,设定参数,并不断调整。

发出控制命令并接受反馈,循环往复达到平衡。

C2 风格

构件和连接件、顶部和底部。

通过连接件绑定在一起按照一组规则运作的并行构件网络。

软件架构设计必备概念

背诵版。

软件架构风格

描述特定软件系统组织方式的惯用模式,组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义。

架构风险

架构设计中潜在的、存在问题的架构决策所带来的隐患。

风险点与非风险点

风险点:可能引起风险的因素。

某个做法如果有隐患,有可能导致一些问题,则为风险点。

非风险点:如果某件事是可行的可接受的,则为非风险点。

敏感点

为实现某种特定的质量属性,一个或多个构件所具有的特性。

权衡点

影响多个质量属性的特性,是多个质量属性的敏感点。

Kubernetes helm 部署 prometheus stack

Pometheus-Oerator 已经准备弃用,采用社区维护的 prometheus stack 部署。

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# install
helm install prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring --create-namespace

# upgrade
helm upgrade prometheus-stack prometheus-community/kube-prometheus-stack

# uninstall
helm uninstall prometheus-stack

References

kompose 转换 docker compose 应用为 k8s 资源清单

Compose是Docker Compose到容器编排(如Kubernetes或OpenShift)的转换工具。

官方Kubernetes项目,仓库位于github.com/kubernetes/kompose。

安装

# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-amd64 -o kompose

# Linux ARM64
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-arm64 -o kompose

# macOS
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-darwin-amd64 -o kompose

# macOS ARM64
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-darwin-arm64 -o kompose

chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose

使用

$ kompose convert -f compose.yaml

$ kubectl apply -f .

$ kubectl get po
NAME                            READY     STATUS              RESTARTS   AGE
frontend-591253677-5t038        1/1       Running             0          10s
redis-leader-2410703502-9hshf   1/1       Running             0          10s
redis-replica-4049176185-hr1lr  1/1       Running             0          10s

也可以修改控制器,比如指定使用 Statefulset 就这样:

$ kompose convert -f compose.yaml --controller statefulset

作者 使用这个工具快速成功部署了 logtolobechat

更多详情查询官网

References

kubernetes 部署 cert-manager 快速实现自动 ssl

简单记录,使用 cloudflare dns 自动完成域名 ssl 证书申请并配置到 ingress 的关键步骤。

安装

使用 helm 安装方法如下:

helm repo add jetstack https://charts.jetstack.io --force-update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.16.1 \
  --set crds.enabled=true

配置

使用 cloudflare 密钥自动认证

apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
  namespace: cert-manager
type: Opaque
stringData:
  api-token: xxxxxxxxxx

定义 issuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: issuer01
spec:
  acme:
    email: XXXXXX
      # 配置证书目录,演练环境使用Staging环境,正式环境使用另一个
    #server: https://acme-staging-v02.api.letsencrypt.org/directory
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Secret resource that will be used to store the account's private key.
      name: issuer-account-key
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token-secret
            key: api-token

示例程序

apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
      release: canary
  template:
    metadata:
      labels:
        app: whoami
        release: canary
    spec:
      containers:
      - name: whoami
        image: traefik/whoami:v1.10
        ports:
        - name: http
          containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  selector:
    app: whoami
    release: canary
  ports:
  - name: http
    port: 80
    targetPort: 80 # pod port

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-whoami
  annotations:
    cert-manager.io/cluster-issuer: issuer01
  #  kubernetes.io/tls-acme: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: whoami.hzc1.skybyte.me
    http:
      paths:
      - backend:
          service:
            name: whoami
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - whoami.hzc1.skybyte.me
    secretName: whoami-hzc1-skybyte-me-tls # Name of secret automatically generated.

References

临时解决 vagrant 不支持 virtualbox7.1

介绍一种临时解决 Recent version of Virtualbox 7.1.0 is not supported by vagrant 2.4.1 的方法:

解决方案

方案一

$ sudo viVirtualBoxVM|virtualboxvm)
     VBoxManage|vboxmanage)
-        exec "$INSTALL_DIR/VBoxManage" "$@"
+   if [[ $@ == "--version" ]]; then
+     echo "7.0.0r164728"
+   else
+          exec "$INSTALL_DIR/VBoxManage" "$@"
+   fi
         ;;
     VBoxSDL|vboxsdl)
         exec "$INSTALL_DIR/VBoxSDL" "$@"

方案二

$ sudo vim /opt/vagrant/embedded/gems/gems/vagrant-2.4.1/plugins/providers/virtualbox/driver
$ diff -u meta.rb.orig meta.rb
--- meta.rb.orig        2024-09-16 11:37:37.017440100 +0100
+++ meta.rb     2024-09-16 11:33:51.312254400 +0100
@@ -69,6 +69,7 @@
             "6.0" => Version_6_0,
             "6.1" => Version_6_1,
             "7.0" => Version_7_0,
+            "7.1" => Version_7_0,
           }

           if @@version.start_with?("4.2.14")

References