SSH LINUX Security Settings

SSH 配置安全控制限制登录

1. 只允许某个IP登录,拒绝其他所有IP

在 /etc/hosts.allow 增加:

1
sshd: 1.2.3.4

在 /etc/hosts.deny 增肌:

1
sshd: ALL

用 iptables 也行:

1
2
iptables -A INPUT -p tcp --dport 22 -j DROP
iptables -A INPUT -p tcp --dport 22 -s 1.2.3.4 -j ACCEPT

2. 禁止某个用户通过ssh登录

在/etc/ssh/sshd_conf添加

1
2
3
4
5
AllowUsers 用户名
或者
AllowGroups 组名
或者
DenyUsers 用户名

3. 设定登录黑名单
1
2
3
[root@6 ~]# vim /etc/pam.d/sshd
auth required /lib/security/pam_listfile.so item=user sense=deny file=/etc/sshd_user_deny_list onerr=succeed
# 所有/etc/sshd_user_deny_list里面的用户被拒绝ssh登录
4. sshd_config配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式
Port 22          # SSH 预设使用 22 这个 port,您也可以使用多的 port
              # 亦即重复使用 port 这个设定项目即可!
Protocol 2,1        # 选择的 SSH 协议版本,可以是 1 也可以是 2 ,
              # 如果要同时支持两者,就必须要使用 2,1 这个分隔了!
#ListenAddress 0.0.0.0   # 监听的主机适配卡!举个例子来说,如果您有两个 IP,
              # 分别是 192.168.0.100 及 192.168.2.20 ,那么只想要
              # 开放 192.168.0.100 时,就可以写如同下面的样式:
ListenAddress 192.168.0.100 # 只监听来自 192.168.0.100 这个 IP 的SSH联机。
                   # 如果不使用设定的话,则预设所有接口均接受 SSH
PidFile /var/run/sshd.pid      # 可以放置 SSHD 这个 PID 的档案!左列为默认值
LoginGraceTime 600     # 当使用者连上 SSH server 之后,会出现输入密码的画面,
              # 在该画面中,在多久时间内没有成功连上 SSH server
              # 就断线!时间为秒!
Compression yes      # 是否可以使用压缩指令?当然可以啰!

# 说明主机的 Private Key 放置的档案,预设使用下面的档案即可!
HostKey /etc/ssh/ssh_host_key    # SSH version 1 使用的私钥
HostKey /etc/ssh/ssh_host_rsa_key  # SSH version 2 使用的 RSA 私钥
HostKey /etc/ssh/ssh_host_dsa_key  # SSH version 2 使用的 DSA 私钥
# 关于 version 1 的一些设定!
KeyRegenerationInterval 3600     # 由前面联机的说明可以知道, version 1 会使用
                   # server 的 Public Key ,那么如果这个 Public
                   # Key 被偷的话,岂不完蛋?所以需要每隔一段时间
                   # 来重新建立一次!这里的时间为秒!
ServerKeyBits 768           # 没错!这个就是 Server key 的长度!

# 关于登录文件的讯息数据放置与 daemon 的名称!
SyslogFacility AUTH         # 当有人使用 SSH 登入系统的时候,SSH会记录资
                   # 讯,这个信息要记录在什么 daemon name 底下?
                   # 预设是以 AUTH 来设定的,即是 /var/log/secure
                   # 里面!什么?忘记了!回到 Linux 基础去翻一下
                   # 其它可用的 daemon name 为:DAEMON,USER,AUTH,
                   # LOCAL0,LOCAL1,LOCAL2,LOCAL3,LOCAL4,LOCAL5,
LogLevel INFO            # 登录记录的等级!嘿嘿!任何讯息!
                   # 同样的,忘记了就回去参考!

# 登入设定部分
PermitRootLogin no     # 是否允许 root 登入!预设是允许的,但是建议设定成 no
UserLogin no        # 在 SSH 底下本来就不接受 login 这个程序的登入!
StrictModes yes      # 当使用者的 host key 改变之后,Server 就不接受联机,
              # 可以抵挡部分的木马程序!
#RSAAuthentication yes   # 是否使用纯的 RSA 认证!?仅针对 version 1 !
PubkeyAuthentication yes  # 是否允许 Public Key ?当然允许啦!只有 version 2
AuthorizedKeysFile .ssh/authorized_keys
              # 上面这个在设定若要使用不需要密码登入的账号时,那么那个
              # 账号的存放档案所在档名!
Allowusers root@222.XX.XX.XX. #设置允许root帐号只能以222.XX.XX.XX这个IP进行ssh连接

# 认证部分
RhostsAuthentication no  # 本机系统不止使用 .rhosts ,因为仅使用 .rhosts 太
              # 不安全了,所以这里一定要设定为 no
IgnoreRhosts yes      # 是否取消使用 ~/.ssh/.rhosts 来做为认证!当然是!
RhostsRSAAuthentication no # 这个选项是专门给 version 1 用的,使用 rhosts 档案在
              # /etc/hosts.equiv配合 RSA 演算方式来进行认证!不要使用
HostbasedAuthentication no # 这个项目与上面的项目类似,不过是给 version 2 使用的!
IgnoreUserKnownHosts no  # 是否忽略家目录内的 ~/.ssh/known_hosts 这个档案所记录
              # 的主机内容?当然不要忽略,所以这里就是 no 啦!
PasswordAuthentication yes # 密码验证当然是需要的!所以这里写 yes 啰!
PermitEmptyPasswords no  # 若上面那一项如果设定为 yes 的话,这一项就最好设定
              # 为 no ,这个项目在是否允许以空的密码登入!当然不许!
ChallengeResponseAuthentication yes # 挑战任何的密码认证!所以,任何 login.conf
                   # 规定的认证方式,均可适用!
#PAMAuthenticationViaKbdInt yes # 是否启用其它的 PAM 模块!启用这个模块将会
                   # 导致 PasswordAuthentication 设定失效!

# 与 Kerberos 有关的参数设定!因为我们没有 Kerberos 主机,所以底下不用设定!
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosTgtPassing no
 
# 底下是有关在 X-Window 底下使用的相关设定!
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
# 登入后的项目:
PrintMotd no # 登入后是否显示出一些信息呢?例如上次登入的时间、地点等
             # 等,预设是 yes ,但是,如果为了安全,可以考虑改为 no
PrintLastLog yes     # 显示上次登入的信息!可以啊!预设也是 yes
KeepAlive yes       # 一般而言,如果设定这项目的话,那么 SSH Server 会传送
             # KeepAlive 的讯息给 Client 端,以确保两者的联机正常!
             # 在这个情况下,任何一端死掉后, SSH 可以立刻知道!而不会
             # 有僵尸程序的发生!
UsePrivilegeSeparation yes # 使用者的权限设定项目!就设定为 yes 吧!
MaxStartups 10      # 同时允许几个尚未登入的联机画面?当我们连上 SSH ,
             # 但是尚未输入密码时,这个时候就是我们所谓的联机画面啦!
             # 在这个联机画面中,为了保护主机,所以需要设定最大值,
             # 预设最多十个联机画面,而已经建立联机的不计算在这十个当中

# 关于使用者抵挡的设定项目:
DenyUsers *        # 设定受抵挡的使用者名称,如果是全部的使用者,那就是全部
             # 挡吧!若是部分使用者,可以将该账号填入!例如下列!
DenyUsers test
DenyGroups test      # 与 DenyUsers 相同!仅抵挡几个群组而已!

# 关于 SFTP 服务的设定项目!
Subsystem sftp /usr/lib/ssh/sftp-server
如果不愿意开放 SFTP 的话,将这一行批注掉即可!

使用mosh代替ssh连接服务器

身为一名服务器运维人员,每天打交道最多的就是服务器了,最常用的连接服务器的工具就是SSH,因为SSH是一个不可持续的连接,当网络出现波动时,SSH断开会导致当前正在运行的服务中断,对工作产生非常大的影响,无意间看到了Mosh这个东西,安装使用下,发现网络波动这种事情不会导致服务器连接断开了,特意查了下,原来Mosh使用的是UDP方式传输:虽然也支持使用SSH配置进行认证登录,但是数据传输本身是使用UDP方式的,Mosh支持在会话中断时,不会立即退出,而是启用一个计时器,当网络恢复后会自动连接,同时会延续之前的会话,不会重新开启一个。

Mosh 主页

1. 安装配置

需要在服务端和客户端同时安装Mosh:

1
2
3
# 以centos 6.x 为例:
[user@host ~]$ sudo yum install -y epel-release
[user@host ~]$ sudo yum install -y mosh

2. 采用SSH配置进行认证登录,只需要将ssh 替换为mosh即可

1
2
3
4
[user@host ~]$ mosh user@host

# 如何需要指定特定的ssh port或者使用ssh keyfile. 可以使用-ssh参数:
[user@host ~]$ mosh -ssh="ssh -i ~/.ssh/id_rsa -p 10002" user@host

3. Other

另外Mosh还支持使用临时key的方式认证,需要服务器端创建临时key,然后客户端通过这个key进行登录,该key在会话结束的十分钟后自动失效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 创建临时key
[user@host ~]$ mosh-server
MOSH CONNECT 53371 asdAADfdse234LSDSdIbow
mosh-server (mosh 1.2.4)
Copyright 2012 Keith Winstein <mosh-devel@mit.edu>
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[mosh-server detached, pid = 27290]

# 然后在client定义MOSH_KEY
[user@host ~]$ export MOSH_KEY=asdAADfdse234LSDSdIbow
# 注意mosh-client只能跟上具体的ip和临时端口,不支持主机名和域名方式

# 使用临时key连接服务器
[user@host ~]$ mosh-client 10.0.2.4 53371

Linux 中的三个特殊权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Linux中除了普通权限之外,还有三个特殊权限。
SUID::以文件的所属用户执行,而非执行文件的用户,多用于可执行文件,设置suid后,在权限位中,所属用户的 最后一个权
限为变为s,添加SUID权限可用“+s”表示。
例如:passwd
[adam@ultraera ~]$ which passwd
/usr/bin/passwd
[adam@ultraera ~]$ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 25980 Feb 22 2012 /usr/bin/passwd
[adam@ultraera ~]$
SGID:主要针对文件夹,在设置了SGID的文件夹中创建任何新文件都继承该文件的所属组,设置sgid后,在权限位中,所属
组的最后一个权限位变为s,添加SGID权限可用“+s”表示。
例如:
[adam@ultraera ~]$ mkdir ultraera
[adam@ultraera ~]$ ls -l
total 4
drwxrwxr-x 2 adam adam 4096 Nov 27 21:09 ultraera
[adam@ultraera ~]$ chmod g+s ultraera/
[adam@ultraera ~]$ ls -l
total 4
drwxrwsr-x 2 adam adam 4096 Nov 27 21:09 ultraera
[adam@ultraera ~]$ su
Password:
[root@ultraera adam]# mkdir -p ultraera/test
[root@ultraera adam]# ls -l ultraera/
total 4
drwxr-sr-x 2 root adam 4096 Nov 27 21:09 test
[root@ultraera adam]#
sticky:针对文件夹,对目录拥有写权限的用户,仅可以删除其所拥有的文件,无法删除其他用户所拥有的文件,设置了sticky
之后,在权限位,other的最后一个权限位变为t,添加SGID权限可用“+t”表示。
例如:
[root@ultraera tmp]# mkdir ultraera
[root@ultraera tmp]# chmod a=rwx,o+t ultraera/
[root@ultraera tmp]# ls -ld ultraera/
drwxrwxrwt 2 root root 4096 Nov 27 21:29 ultraera/
[root@ultraera tmp]# useradd user1
[root@ultraera tmp]# useradd user2
[root@ultraera tmp]# su user1
[user1@ultraera tmp]$ touch ./ultraera/test
[user1@ultraera tmp]$ ls -l ultraera/
total 0
-rw-rw-r-- 1 user1 user1 0 Nov 27 21:31 test
[user1@ultraera tmp]$ exit
exit
[root@ultraera tmp]# su user2
[user2@ultraera tmp]$ rm -f ./ultraera/test
rm: cannot remove `./ultraera/test': Operation not permitted
[user2@ultraera tmp]$


同样使用chmod来设定特殊权限,与普通权限一样,特殊权限也可以用数字表示:
suid : 4
sgid : 2
sticky : 1
chmod 4644 filename #设置文件suid权限
chmod 2755 flodername #设置文件夹sgid权限
chmod 1755 flodername #设置文件夹sticky权限

Linux 笔试试题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
一. 选择题 (1题1分)
1. 当登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么( )
A. NID  B. PID  C. UID  D. CID
答案:B
2. 用vi打开一个文件,如何用字母"new"来代替字母"old" ( )
A. :s/old/new/g   B. :s/old/new  C. :1,$s/old/new/g   D. :r/old/new
答案:A
3. 请选择对标准的变量PS2正确的描述( )
A. 是一个主shell提示符变量    B. 是一个一般的shell提示符变量
C. 是第二主shell提示符变量   D. 是一个连续提示符变量
答案:B
4. 哪一个命令能用来查找文件TESTFILE中只包含四个字符的行?( )
A. grep '^????$' TESTFILE    B. grep '????' TESTFILE
C. grep '^....$' TESTFILE     D. grep '....' TESTFILE
答案:C
5. 一个bash shell脚本的第一行是什么( )
A. #!/bin/bash  B. #/bin/bash  C. #/bin/csh   D. /bin/bash
答案:A
6. 用标准的输出重定向(>)像"> file01"能使文件file01的数据( )
A. 被移动  B. 被复制  C. 被打印   D. 被覆盖
答案:D
7. 下面哪个命令是用来定义shell的全局变量( )
A. exportfs  B. alias  C. exports  D. export
答案:D
8. 如果想加载一个/dev/sdb1的windows95分区到/mnt/win95目录,需要运行哪个命令( )
A. mount -t hpfs /dev/sdb1 /mnt/win95
B. mount -t hpfs /mnt/win95 /dev/sdb1
C. mount -t vfat /dev/sdb1 /mnt/win95
D. mount -t vfat /mnt/win95 /dev/sdb1
答案:C
9. 哪个文件存放用户密码信息( )
A. /boot/passwd   B. /etc/shadow   C. /var/passwd  D. /dev/passwd
答案:B
10. 假定kernel支持vfat分区,下面哪一个操作是将/dev/sda1,一个window98分区加载到/win目录( )
A. mount -s win /dev'sda1 /win
B. mount -fs=msdos /dev/sda1 /win
C. mount -t vfat /dev/sda1 /win
D. mount -t windows /win /dev/sda1
答案:C
11. 默认情况下管理员创建了一个用户,就会在( )目录下创建一个用户主目录。
A. /usr  B. /home   C. /root  D. /etc
答案:B
12. 如果要列出一个目录下的所有文件需要使用命令行( )。
A. lsl  B. ls   C. ls –a   D. ls -d
答案:C
13. 利用哪个工具可以设置用户在文件系统中的空间大小( )。
A. turboservice  B. turbofscfg  C. turbonetcfg   D. turboxcfg
答案:B
14. 哪个命令可以将普通用户转换成超级用户( )
A. super  B. passwd  C. tar   D. su
答案:D
15. 哪个命令用来显示/home及其子目录下文件名( )
A. ls -R /home  B. ls -d /home  C. ls -a /home    D. ls -l /home
答案:A
16. 在vi模式下,哪个命令用来删除光标处的字符( )
A. xd   B. x   C. dd   D. d
答案:B  dd删除一行,x删除当前字符
17. 在一行内运行多个命令需要用什么字符隔开( )
A. @  B. $   C. ;  D. *
答案:C
18. 确定myfile的文件类型的命令是( )
A. whatis myfile
B. file myfile
C. type myfile
D. type -q myfile
答案:B
19. 哪些命令组合起来能统计多少用户登录系统( )
A. who | wc –w   B. who | wc –l   C. who | wc –c   D. who | wc
答案:BD
20. 用 "rm -i",系统会提示什么来让你确认( )
A. 命令行的每个选项  B. 是否真的删除  C. 是否有写的权限   D. 文件的位置
答案:B
21. Linux启动的第一个进程init启动的第一个脚本程序是( )。
A. /etc/rc.d/init.d   B. /etc/rc.d/rc.sysinit  C. /etc/rc.d/rc5.d  D. /etc/rc.d/rc3.d
答案:B
22. 按下( )键能终止当前运行的命令
A. Ctrl-C   B. Ctrl-F   C. Ctrl-B   D. Ctrl-D
答案:a
23. 用来分离目录名和文件名的字符是( )
A. dash (-)  B. slash (/)  C. period (.)   D. asterisk(*)
答案:B
24. 系统的配置文件在( )目录下
A. /home   B. /dev  C. /etc   D. /usr
答案:C
25. 显示用户的主目录的命令是什么?( )
A. echo $HOME  B. echo $USERDIR   C. echo $ENV  D. echo $ECHO
答案:A
26. 在vi编辑器里,哪个命令能将光标移到第200行( )
A. g200  B. G200  C. :200   D. 200g
答案:C
:200可以,200G也可以
27. 用"useradd jerry"命令添加一个用户,这个用户的主目录是什么?( )
A. /etc/jerry   B. /var/jerry  C. /home/jerry   D. /bin/jerry
答案:C
28. 哪一个命令能用来删除当前目录及其子目录下名为'core'的文件( )
A. find . -name core -exec rm {} \ ;
B. find . -name core -exec rm ;
C. find . -name core -exec rm {} ;
D. find . -name core -exec rm {} -;
答案:A
29. 以下哪条命令在创建一个xp用户的时候将用户加入到root组中( )
A. useradd -g xp root  B. useradd -r root xp  C. useradd -g root xp   D. useradd root xp
答案:C
30. 不改变运行级别而重新读入inittab文件的命令是( )。
A. init s  B. init q  C. init S   D. init Q
答案:B
31. 以下哪个命令可以终止一个用户的所有进程( )
A. skillall   B. skill  C. kill   D. killall
答案:D
32. 通过修改哪个文件可以在创建用户的时候改变用 户主目录的路径( )
A. /etc/default/passwd   B. /etc/default/useradd  C. /etc/profile  D. /etc/fstab
答案:B
33. 以只读方式打开一个文件并进入vi编辑器的命令是( )
A. view -r filename   B. view filename   C. vi filename   D. vi -r filename
答案:B
34. 以下哪个命令是将缓存中的内容粘贴到光标之前( )
A. a   B. i   C. P   D. p
答案:C
35. 以下哪条vi命令能将文档5-20行间出现的abc替换成为cba ( )
A. :1,$s/abc/cba/g   B. :5,20/abc/cba/g  C. :5-20s/abc/cba/g   D. :5,20s/abc/cba/g
答案:D
. 在vi中通过哪条命令可以将ps命令执行的结果插入到文档中( )
A. :r!ps   B. :!ps   C. :!rps    D. :w!ps
答案:A
36. 以下哪个vi命令可以在当前位置插入/etc/passwd文本文件( )
A. :r /etc/passwd   B. :i /etc/passwd  C. :w /etc/passwd   D. :s /etc/passwd
答案:A
37. vi中复制整行的命令是( )
A. y1   B. yy   C. ss   D. dd
答案:B
38. 以下哪个vi命令可以给文档的每行加上一个编号( )
A. :e number   B. :set number  C. :r!date     D. :200g
答案:B
38. 以下哪些文件只有根用户才能读写( )
A. /etc/bashrc   B. /etc/profile   C. /etc/shadow    D. /etc/passwd
答案:BC
39. 使用groupdel删除一个组的时候,命令执行失败,原因可能是( )
A. 该组是系统组   B. 该组是空的   C. 该组中成员非空   D. 该组不存在
答案:CD
40. Linux中文件名构成的规则比较灵活表现在( )
A. 文件名长度多达256个字符     B. 可以使用除了/符号外的所有ASCII字符
C. 不区分大小写            D. 无扩展名限制
答案:ABD
41. 对用户的口令进行加解锁的命令是passwd,参数选项是( )
A. –l  B. –L  C. –u   D. -U
答案:AC
42. 如果你对文件和目录的权限不确定,则不能用( )命令来检测权限
A. ps   B. ck    C. lsl   D. chown
答案:ABD
43. 选择对/proc文件系统不正确的描述( )
A. 通常情况下,不提供中断、IO端口、CPU等信息   B. /proc文件系统可以提供系统核心的许多参数
C. /proc是一个虚拟的文件系统            D. 可以得到系统中运行的进程的一些信息
答案:A
44. 以下哪些符号可以用来连接多条命令( )
A. ||    B. &&   C. ;   D. |
答案:ABCD
45. 在shell中,下面哪些字符串当作普通字符串时候需要使用"\"来转义( )
A. 分号(;)   B. 双引号(")  C. 单引号(')   D. 反斜杆(\)
答案:BCD
46. Linux中提供了几个重要的工具用来改变服务和进程的运行状态和运行级别以及初始化进程,它们是( )。
A. chkconfig  B. service  C. turboservice   D. ksysv
答案:ABCD
47. 在/etc/rc.d/init.d目录下的所有脚本至少支持两个运行参数,它们是( )。
A. start   B. restart    C. stop   D. reload
答案:AC
48. Linux一般被称为是稳定的服务器系统,它的安全性表现在( )
A. 网络防火墙  B. 用户管理策略 C. 系统、目录、文件的权限控制 D. 封闭源码便于及时修正漏洞等
答案:ABC
49. 在vi中下列哪些命令不能用来在光标前插入文本( )
A. p [text]  B. i [text]  C. o [text]   D. a [text]
答案:ACD
50. 在本地的文件系统中下列哪些linux路径结构是无效的( )
A. \usr/zhang/memo   B. /usr/zhang/memo   C. //usr\zhang/memo   D. \usr\zhang\memo
答案:ACD

二、简答题 (1题3分)

1.常见的Linux发行版本都有什么?你最擅长哪一个?它的官网网站是什么?说明你擅长哪一块?

2.Linux开机启动流程详细步骤是什么?系统安装完,忘记密码如何破解?

4.某一天突然发现Linux系统文件只读,该怎么办呢?完整操作步骤。

5.安装一台系统使用DVD光盘安装,如何安装50台Linux系统如何安装呢?思考一下。

6.用虚拟机安装了一台Linux系统,突然想克隆一台服务器,克隆后发现无法上网,如何解决?

7.Linux网卡配置文件路径是什么?要使服务器上外网,必须满足的条件有哪些?需要配置什么?

8.一般可以使用什么软件远程linux服务器?通过什么上传文件和下载文件?

9./mnt目录主要用于什么?/root目录跟root用户有什么关系?/根目录与/boot目录有什么联系?

10.某一天误操作,执行了rm -rf * ,会有哪些情况发生?请举例。



三、 公有云题目 (1题5分)
1. 请解释上云的好处是什么?传统业务类型与公有云也为类型有什么区别?请举例说明。

2. 列出你用过的阿里云\AWS\Azure服务?并讲述他们的作用?

3. 请列出你觉得阿里云\AWS\Azure目前的特色和不成熟的地方是那些?你觉得应该如何改正。

4. 请用阿里云\AWS\Azure设计一个视频网站的架构图并进行解释说明。

理解 Linux 的硬链接与软链接

从inode了解Linux文件系统

       硬链接与软链接是 Linux 文件系统中的一个重要概念,其涉及文件系统中的索引节点 (index node 又称 inode),而索引节点对象是 Linux 虚拟文件系统 (VFS) 的四个基本概念之一。通过剖析硬链接与软链接的联系与区别,我们可更好的了解 Linux 中 VFS 这一通用文件模型。并让 Linux 普通用户和系统管理员正确使用硬链接与软链接,帮助文件系统开发者获取 inode 的相关知识。

Linux的文件系统与目录


       现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程创建信息的逻辑单元可被多个进程并发使用。在 UNIX 系统中,操作系统为磁盘上的文本与图像、鼠标与键盘等输入设备及网络交互等 I/O 操作设计了一组通用 API,使他们被处理时均可统一使用字节流方式。换言之,UNIX 系统中除进程之外的一切皆是文件,而 Linux 保持了这一特性。为了便于文件的管理,Linux 还引入了目录(有时亦被称为文件夹)这一概念。目录使文件可被分类管理,且目录的引入使 Linux 的文件系统形成一个层级结构的目录树。清单1.所示的是普通 Linux 系统的顶层目录结构,其中 /dev 是存放了设备相关文件的目录。

清单 1. Linux系统的顶层目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 /              根目录
├── bin 存放用户二进制文件
├── boot 存放内核引导配置文件
├── dev 存放设备文件
├── etc 存放系统配置文件
├── home 用户主目录
├── lib 动态共享库
├── lost+found 文件系统恢复时的恢复文件
├── media 可卸载存储介质挂载点
├── mnt 文件系统临时挂载点
├── opt 附加的应用程序包
├── proc 系统内存的映射目录,提供内核与进程信息
├── root root 用户主目录
├── sbin 存放系统二进制文件
├── srv 存放服务相关数据
├── sys sys 虚拟文件系统挂载点
├── tmp 存放临时文件
├── usr 存放用户应用程序
└── var 存放邮件、系统日志等变化文件

       Linux 将设备当做文件进行处理,清单 2.展示了如何打开设备文件 /dev/input/event5 并读取文件内容。文件 event5 表示一种输入设备,其可能是鼠标或键盘等。查看文件 /proc/bus/input/devices 可知 event5 对应设备的类型。设备文件 /dev/input/event5 使用 read() 以字符流的方式被读取。结构体 input_event 被定义在内核头文件 linux/input.h 中。

清单 2. 打开并读取设备文件

1
2
3
4
5
6
7
int fd;
struct input_event ie;
fd = open("/dev/input/event5", O_RDONLY);
read(fd, &ie, sizeof(struct input_event));
printf("type = %d code = %d value = %d\n",
ie.type, ie.code, ie.value);
close(fd);


硬链接与软链接的联系与区别

       我们知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。图 1.展示了程序通过文件名获取文件内容的过程。

图 1. 通过文件名打开文件





       在Linux 系统中查看 inode号可使用命令stat 或 ls -i(若是 AIX 系统,则使用命令 istat)。清单 3.中使用命令 mv 移动并重命名文件 glibc-2.16.0.tar.xz,其结果不影响文件的用户数据及 inode 号,文件移动前后 inode 号均为:2485677。

清单 3. 移动或重命名文件


1
2
3
4
5
6
7
8
9
10
11
# stat /home/harris/source/glibc-2.16.0.tar.xz
File: `/home/harris/source/glibc-2.16.0.tar.xz'
Size: 9990512 Blocks: 19520 IO Block: 4096 regular file
Device: 807h/2055d Inode: 2485677 Links: 1
Access: (0600/-rw-------) Uid: ( 1000/ harris) Gid: ( 1000/ harris)
...
...
// 经网友指出,使用mv移动时不跨磁盘inode号不变,如果跨磁盘inode会改变。
# mv /home/harris/source/glibc-2.16.0.tar.xz /home/harris/Desktop/glibc.tar.xz
# ls -i -F /home/harris/Desktop/glibc.tar.xz
2485677 /home/harris/Desktop/glibc.tar.xz


       为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名(见 图 2.hard link 就是 file 的一个别名,他们有共同的 inode)。硬链接可由命令 link 或 ln 创建。如下是对文件 oldfile 创建硬链接。

1
2
link oldfile newfile
ln oldfile newfile


       由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:

文件有相同的 inode 及 data block; 只能对已存在的文件进行创建;
不能交叉文件系统进行硬链接的创建; 不能对目录进行创建,只可对文件创建;
* 删除一个硬链接文件并不影响其他有相同 inode 号的文件。

清单 4. 硬链接特性展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# ls -li
total 0

// 只能对已存在的文件创建硬连接
# link old.file hard.link
link: cannot create link `hard.link' to `old.file': No such file or directory

# echo "This is an original file" > old.file
# cat old.file
This is an original file
# stat old.file
File: `old.file'
Size: 25 Blocks: 8 IO Block: 4096 regular file
Device: 807h/2055d Inode: 660650 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
...
// 文件有相同的 inode 号以及 data block
# link old.file hard.link | ls -li
total 8
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 hard.link
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 old.file

// 不能交叉文件系统
# ln /dev/input/event5 /root/bfile.txt
ln: failed to create hard link `/root/bfile.txt' => `/dev/input/event5':
Invalid cross-device link

// 不能对目录进行创建硬连接
# mkdir -p old.dir/test
# ln old.dir/ hardlink.dir
ln: `old.dir/': hard link not allowed for directory
# ls -iF
660650 hard.link 657948 old.dir/ 660650 old.file

       文件 old.file 与 hard.link 有着相同的 inode 号:660650 及文件权限,inode 是随着文件的存在而存在,因此只有当文件存在时才可创建硬链接,即当 inode 存在且链接计数器(link count)不为 0 时。inode 号仅在各文件系统下是唯一的,当 Linux 挂载多个文件系统后将出现 inode 号重复的现象(如清单 5.所示,文件 t3.jpg、sync 及 123.txt 并无关联,却有着相同的 inode 号),因此硬链接创建时不可跨文件系统。设备文件目录 /dev 使用的文件系统是 devtmpfs,而 /root(与根目录 / 一致)使用的是磁盘文件系统 ext4。清单 5.展示了使用命令 df 查看当前系统中挂载的文件系统类型、各文件系统 inode 使用情况及文件系统挂载点。

清单 5. 查找有相同 inode 号的文件


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# df -i --print-type
Filesystem Type Inodes IUsed IFree IUse% Mounted on
/dev/sda7 ext4 3147760 283483 2864277 10% /
udev devtmpfs 496088 553 495535 1% /dev
tmpfs tmpfs 499006 491 498515 1% /run
none tmpfs 499006 3 499003 1% /run/lock
none tmpfs 499006 15 498991 1% /run/shm
/dev/sda6 fuseblk 74383900 4786 74379114 1% /media/DiskE
/dev/sda8 fuseblk 29524592 19939 29504653 1% /media/DiskF

# find / -inum 1114
/media/DiskE/Pictures/t3.jpg
/media/DiskF/123.txt
/bin/sync


       值得一提的是,Linux 系统存在 inode 号被用完但磁盘空间还有剩余的情况。我们创建一个 5M 大小的 ext4 类型的 mo.img 文件,并将其挂载至目录 /mnt。然后我们使用一个 shell 脚本将挂载在 /mnt 下 ext4 文件系统的 indoe 耗尽(见清单 6.)。

清单 6. 测试文件系统 inode 耗尽但仍有磁盘空间的情景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# dd if=/dev/zero of=mo.img bs=5120k count=1
# ls -lh mo.img
-rw-r--r-- 1 root root 5.0M Sep 1 17:54 mo.img
# mkfs -t ext4 -F ./mo.img
...
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
1280 inodes, 5120 blocks
256 blocks (5.00%) reserved for the super user
...
...
Writing superblocks and filesystem accounting information: done

# mount -o loop ./mo.img /mnt
# cat /mnt/inode_test.sh
#!/bin/bash

for ((i = 1; ; i++))
do
if [ $? -eq 0 ]; then
echo "This is file_$i" > file_$i
else
exit 0
fi
done

# ./inode_test.sh
./inode_test.sh: line 6: file_1269: No space left on device

# df -iT /mnt/; du -sh /mnt/
Filesystem Type Inodes IUsed IFree IUse% Mounted on
/dev/loop0 ext4 1280 1280 0 100% /mnt
1.3M /mnt/

       硬链接不能对目录创建是受限于文件系统的设计(见 清单 4.对目录创建硬链接将失败)。现 Linux 文件系统中的目录均隐藏了两个个特殊的目录:当前目录(.)与父目录(..)。查看这两个特殊目录的 inode 号可知其实这两目录就是两个硬链接(注意目录 /mnt/lost+found/ 的 inode 号)。若系统允许对目录创建硬链接,则会产生目录环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ls -aliF /mnt/lost+found
total 44
11 drwx------ 2 root root 12288 Sep 1 17:54 ./
2 drwxr-xr-x 3 root root 31744 Sep 1 17:57 ../

# stat /mnt/lost+found/
File: `/mnt/lost+found/'
Size: 12288 Blocks: 24 IO Block: 1024 directory
Device: 700h/1792d Inode: 11 Links: 2
Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-09-01 17:57:17.000000000 +0800
Modify: 2012-09-01 17:54:49.000000000 +0800
Change: 2012-09-01 17:54:49.000000000 +0800
Birth: -

       软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块(见 图 2.)。因此软链接的创建与使用没有类似硬链接的诸多限制:

  • 软链接有自己的文件属性及权限等;
  • 可对不存在的文件或目录创建软链接;
  • 软链接可交叉文件系统;
  • 软链接可对文件或目录创建;
  • 创建软链接时,链接计数 i_nlink 不会增加;
  • 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

图 2. 软链接的访问




清单 7. 软链接特性展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# ls -li
total 0

// 可对不存在的文件创建软链接
# ln -s old.file soft.link
# ls -liF
total 0
789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 soft.link -> old.file

// 由于被指向的文件不存在,此时的软链接 soft.link 就是死链接
# cat soft.link
cat: soft.link: No such file or directory

// 创建被指向的文件 old.file,soft.link 恢复成正常的软链接
# echo "This is an original file_A" >> old.file
# cat soft.link
This is an original file_A

// 对不存在的目录创建软链接
# ln -s old.dir soft.link.dir
# mkdir -p old.dir/test
# tree . -F --inodes
.
├── [ 789497] old.dir/
│ └── [ 789498] test/
├── [ 789495] old.file
├── [ 789495] soft.link -> old.file
└── [ 789497] soft.link.dir -> old.dir/

       当然软链接的用户数据也可以是另一个软链接的路径,其解析过程是递归的。但需注意:软链接创建时原文件的路径指向使用绝对路径较好。使用相对路径创建的软链接被移动后该软链接文件将成为一个死链接(如下所示的软链接 a 使用了相对路径,因此不宜被移动),因为链接数据块中记录的亦是相对路径指向。

1
2
3
4
5
$ ls -li
total 2136
656627 lrwxrwxrwx 1 harris harris 8 Sep 1 14:37 a -> data.txt
656662 lrwxrwxrwx 1 harris harris 1 Sep 1 14:37 b -> a
656228 -rw------- 1 harris harris 2186738 Sep 1 14:37 data.txt 6

链接相关的命令

       在 Linux 中查看当前系统已挂着的文件系统类型,除上述使用的命令 df,还可使用命令 mount 或查看文件 /proc/mounts。

1
2
3
4
5
6
7
# mount
/dev/sda7 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
...
...
none on /run/shm type tmpfs (rw,nosuid,nodev)

       命令 ls 或 stat 可帮助我们区分软链接与其他文件并查看文件 inode 号,但较好的方式还是使用 find 命令,其不仅可查找某文件的软链接,还可以用于查找相同 inode 的所有硬链接。(见 清单 8.

清单 8. 使用命令 find 查找软链接与硬链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 查找在路径 /home 下的文件 data.txt 的软链接
# find /home -lname data.txt
/home/harris/debug/test2/a

// 查看路径 /home 有相同 inode 的所有硬链接
# find /home -samefile /home/harris/debug/test3/old.file
/home/harris/debug/test3/hard.link
/home/harris/debug/test3/old.file

# find /home -inum 660650
/home/harris/debug/test3/hard.link
/home/harris/debug/test3/old.file

// 列出路径 /home/harris/debug/ 下的所有软链接文件
# find /home/harris/debug/ -type l -ls
656662 0 lrwxrwxrwx 1 harris harris 1 Sep 1 14:37 /home/harris/debug/test2/b -> a
656627 0 lrwxrwxrwx 1 harris harris 8 Sep 1 14:37 /home/harris/debug/test2/a ->
data.txt
789467 0 lrwxrwxrwx 1 root root 8 Sep 1 18:00 /home/harris/debug/test/soft.link ->
old.file
789496 0 lrwxrwxrwx 1 root root 7 Sep 1 18:01
/home/harris/debug/test/soft.link.dir -> old.dir

       系统根据磁盘的大小默认设定了 inode 的值(见清单 9.),如若必要,可在格式文件系统前对该值进行修改。如键入命令 mkfs -t ext4 -I 512/dev/sda4,将使磁盘设备 /dev/sda4 格式成 inode 大小是 512 字节的 ext4 文件系统。

清单 9. 查看系统的 inode 值

1
2
3
4
5
6
7
// 查看磁盘分区 /dev/sda7 上的 inode 值
# dumpe2fs -h /dev/sda7 | grep "Inode size"
dumpe2fs 1.42 (29-Nov-2011)
Inode size: 256

# tune2fs -l /dev/sda7 | grep "Inode size"
Inode size: 256

Linux VFS

       Linux 有着极其丰富的文件系统,大体上可分如下几类:

  1. 网络文件系统,如 nfs、cifs 等;
  2. 磁盘文件系统,如 ext4、ext3 等;
  3. 特殊文件系统,如 proc、sysfs、ramfs、tmpfs 等。

       实现以上这些文件系统并在 Linux 下共存的基础就是 Linux VFS(Virtual File System 又称 Virtual Filesystem Switch),即虚拟文件系统。VFS 作为一个通用的文件系统,抽象了文件系统的四个基本概念:文件、目录项 (dentry)、索引节点 (inode) 及挂载点,其在内核中为用户空间层的文件系统提供了相关的接口(见 图 3.所示 VFS 在 Linux 系统的架构)。VFS 实现了 open()、read() 等系统调并使得 cp 等用户空间程序可跨文件系统。VFS 真正实现了上述内容中:在 Linux 中除进程之外一切皆是文件。

图 3. VFS 在系统中的架构





       Linux VFS 存在四个基本对象:超级块对象 (superblock object)、索引节点对象 (inode object)、目录项对象 (dentry object) 及文件对象 (file object)。超级块对象代表一个已安装的文件系统;索引节点对象代表一个文件;目录项对象代表一个目录项,如设备文件 event5 在路径 /dev/input/event5 中,其存在四个目录项对象:/ 、dev/ 、input/ 及 event5。文件对象代表由进程打开的文件。这四个对象与进程及磁盘文件间的关系如图 4. 所示,其中 d_inode 即为硬链接。为文件路径的快速解析,Linux VFS 设计了目录项缓存(Directory Entry Cache,即 dcache)。

图 4. VFS 的对象之间的处理





### Linux 文件系统中的 inode
       在 Linux 中,索引节点结构存在于系统内存及磁盘,其可区分成 VFS inode 与实际文件系统的 inode。VFS inode 作为实际文件系统中 inode 的抽象,定义了结构体 inode 与其相关的操作 inode_operations(见内核源码 include/linux/fs.h)。

清单 10. VFS 中的 inode 与 inode_operations 结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct inode {
...
const struct inode_operations *i_op; // 索引节点操作
unsigned long i_ino; // 索引节点号
atomic_t i_count; // 引用计数器
unsigned int i_nlink; // 硬链接数目
...
}

struct inode_operations {
...
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,int);
int (*rmdir) (struct inode *,struct dentry *);
...
}

       如清单 10. 所见,每个文件存在两个计数器:i_count 与 i_nlink,即引用计数与硬链接计数。结构体 inode 中的 i_count 用于跟踪文件被访问的数量,而 i_nlink 则是上述使用 ls -l 等命令查看到的文件硬链接数。或者说 i_count 跟踪文件在内存中的情况,而 i_nlink 则是磁盘计数器。当文件被删除时,则 i_nlink 先被设置成 0。文件的这两个计数器使得 Linux 系统升级或程序更新变的容易。系统或程序可在不关闭的情况下(即文件 i_count 不为 0),将新文件以同样的文件名进行替换,新文件有自己的 inode 及 data block,旧文件会在相关进程关闭后被完整的删除。

清单 11. 文件系统 ext4 中的 inode

1
2
3
4
5
6
7
8
9
10
struct ext4_inode {
...
__le32 i_atime; // 文件内容最后一次访问时间
__le32 i_ctime; // inode 修改时间
__le32 i_mtime; // 文件内容最后一次修改时间
__le16 i_links_count; // 硬链接计数
__le32 i_blocks_lo; // Block 计数
__le32 i_block[EXT4_N_BLOCKS]; // 指向具体的 block
...
};

       清单 11. 展示的是文件系统 ext4 中对 inode 的定义(见内核源码 fs/ext4/ext4.h)。其中三个时间的定义可对应与命令 stat 中查看到三个时间。i_links_count 不仅用于文件的硬链接计数,也用于目录的子目录数跟踪(目录并不显示硬链接数,命令 ls -ld 查看到的是子目录数)。由于文件系统 ext3 对 i_links_count 有限制,其最大数为:32000(该限制在 ext4 中被取消)。尝试在 ext3 文件系统上验证目录子目录及普通文件硬链接最大数可见 清单 12.的错误信息。因此实际文件系统的 inode 之间及与 VFS inode 相较是有差异的。

清单 12. 文件系统 ext3 中 i_links_count 的限制

1
2
3
4
5
# ./dirtest.sh
mkdir: cannot create directory `dir_31999': Too many links

# ./linkcount.sh
ln: failed to create hard link to `old.file': Too many links

结束语

       本文最初描述了 Linux 系统中文件与目录被引入的原因及 Linux 处理文件的方式,然后我们通过区分硬链接与软链接的不同,了解 Linux 中的索引节点的相关知识,并以此引出了 inode 的结构体。索引节点结构体存在在于 Linux VFS 以及实际文件系统中,VFS 作为通用文件模型是 Linux 中“一切皆是文件”实现的基础。文章并未深入 Linux VFS,也没涉及实际文件系统的实现,文章只是从 inode 了解 Linux 的文件系统的相关内容。若想深入文件系统的内容,查看内核文档 Documentation/filesystems/ 是一个不错的方式。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×