-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0410accountmanager.html
2613 lines (2611 loc) · 221 KB
/
0410accountmanager.html
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Author" content="VBird, 鸟哥">
<meta name="Description" content="在 Linux 系统下管理用户的身份与帐号!">
<title>鸟哥的 Linux 私房菜 -- 第十三章、Linux 帐号管理与 ACL 权限设置</title>
<style type="text/css">
</style>
<link href="./vbird_files/style_2013.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="tablearea">
<div class="mainarea">
<div class="block1">
<!-- 本文的档头部分 -->
<h1>第十三章、Linux 帐号管理与 ACL 权限设置</h1>
<div style="text-align:right">
<span class="text_history">最近更新日期:2015/07/27</span>
</div>
<!-- 本文的档头部分 -->
<div class="abstract">
<p>要登录 Linux 系统一定要有帐号与密码才行,否则怎么登录,您说是吧?不过,
不同的用户应该要拥有不同的权限才行吧?我们还可以透过 user/group 的特殊权限设置,
来规范出不同的群组开发项目呢~在 Linux 的环境下,我们可以透过很多方式来限制用户能够使用的系统资源,
包括 <a href="0320bash.html">第十章、bash</a> 提到的 <a href="0320bash.html#variable_ulimit">ulimit</a> 限制、还有特殊权限限制,如 <a href="0220filemanager.html#umask">umask</a> 等等。
透过这些举动,我们可以规范出不同用户的使用资源。另外,还记得系统管理员的帐号吗?对!
就是 root 。请问一下,除了 root 之外,是否可以有其他的系统管理员帐号?
为什么大家都要尽量避免使用数字型态的帐号?如何修改用户相关的信息呢?这些我们都得要了解了解的!</p>
</div>
<!-- 本文的链接区部分 -->
<div class="links">
<ul>
<li><a href="0410accountmanager.html#account">13.1 Linux 的帐号与群组</a>
<ul>
<li><a href="0410accountmanager.html#account_id">13.1.1 用户识别码: UID 与 GID</a></li>
<li><a href="0410accountmanager.html#account_user">13.1.2 用户帐号</a>:<a href="0410accountmanager.html#passwd_file">/etc/passwd 文件结构</a>,
<a href="0410accountmanager.html#shadow_file">/etc/shadow 文件结构</a></li>
<li><a href="0410accountmanager.html#account_group">13.1.3 关于群组</a>: <a href="0410accountmanager.html#group_file">/etc/group 文件结构</a>,
<a href="0410accountmanager.html#account_group_init">有效与初始群组</a>, <a href="0410accountmanager.html#groups">groups</a>,
<a href="0410accountmanager.html#newgrp">newgrp</a>, <a href="0410accountmanager.html#gshadow_file">/etc/gshadow</a></li>
</ul></li>
<li><a href="0410accountmanager.html#users">13.2 帐号管理</a>
<ul>
<li><a href="0410accountmanager.html#users_adduser">13.2.1 添加与移除用户</a>: <a href="0410accountmanager.html#useradd">useradd</a>,
<a href="0410accountmanager.html#users_adduser_env">useradd 参考档</a>, <a href="0410accountmanager.html#passwd">passwd</a>,
<a href="0410accountmanager.html#chage">chage</a>, <a href="0410accountmanager.html#usermod">usermod</a>, <a href="0410accountmanager.html#userdel">userdel</a></li>
<li><a href="0410accountmanager.html#normal_user">13.2.2 用户功能</a>:<a href="0410accountmanager.html#id">id</a>, <a href="0410accountmanager.html#finger">finger</a>,
<a href="0410accountmanager.html#chfn">chfn</a>, <a href="0410accountmanager.html#chsh">chsh</a></li>
<li><a href="0410accountmanager.html#group_add">13.2.3 添加与移除群组</a>:<a href="0410accountmanager.html#groupadd">groupadd</a>,
<a href="0410accountmanager.html#groupmod">groupmod</a>, <a href="0410accountmanager.html#groupdel">groupdel</a>,
<a href="0410accountmanager.html#gpasswd">gpasswd 群组管理员</a></li>
<li><a href="0410accountmanager.html#user_ex">13.2.4 帐号管理实例</a></li>
<li><a href="0410accountmanager.html#user_other">13.2.5 使用外部身份认证系统</a></li>
</ul></li>
<li><a href="0410accountmanager.html#acl_talk">13.3 主机的细部权限规划:ACL 的使用</a>
<ul>
<li><a href="0410accountmanager.html#acl_talk_what">13.3.1 什么是 ACL 与如何支持启动 ACL</a></li>
<li><a href="0410accountmanager.html#acl_talk_cmd">13.3.2 ACL 的设置技巧</a>:
<a href="0410accountmanager.html#setfacl">setfacl</a>, <a href="0410accountmanager.html#getfacl">getfacl</a>,
ACL 的设置(<a href="0410accountmanager.html#acl_user">user</a>, <a href="0410accountmanager.html#acl_group">group</a>
<a href="0410accountmanager.html#acl_mask">mask</a>, <a href="0410accountmanager.html#acl_default">default</a>)</li>
</ul></li>
<li><a href="0410accountmanager.html#userswitch">13.4 用户身份切换</a>
<ul>
<li><a href="0410accountmanager.html#su">13.4.1 su</a></li>
<li><a href="0410accountmanager.html#sudo">13.4.2 sudo</a>: <a href="0410accountmanager.html#sudo">sudo 指令</a>, <a href="0410accountmanager.html#visudo">visudo (/etc/sudoers)</a> (
<a href="0410accountmanager.html#sudo-1">帐号</a>, <a href="0410accountmanager.html#sudo-2">群组</a>, <a href="0410accountmanager.html#sudo-3">限制指令</a>,
<a href="0410accountmanager.html#sudo-4">别名</a>, <a href="0410accountmanager.html#sudo-5">时间间隔</a>, <a href="0410accountmanager.html#sudo-6">配合 su</a>)</li>
</ul></li>
<li><a href="0410accountmanager.html#usershell">13.5 用户的特殊 shell 与 PAM 模块</a>
<ul>
<li><a href="0410accountmanager.html#nologin">13.5.1 特殊的 shell :/sbin/nologin</a>, <a href="0410accountmanager.html#nologin.txt">nologin.txt</a></li>
<li><a href="0410accountmanager.html#pam_what">13.5.2 PAM 模块简介</a></li>
<li><a href="0410accountmanager.html#pam_setting">13.5.3 PAM 模块设置语法</a>:验证类别(type)、控制标准(flag)、模块与参数</li>
<li><a href="0410accountmanager.html#pam_module">13.5.4 常用模块简介</a>: <a href="0410accountmanager.html#securetty">securetty</a>,
<a href="0410accountmanager.html#nologin_pam">nologin</a>, <a href="0410accountmanager.html#cracklib">pam_pwquality</a>,
<a href="0410accountmanager.html#login_pam">login流程</a></li>
<li><a href="0410accountmanager.html#pam_file">13.5.5 其他相关文件</a>: <a href="0410accountmanager.html#limits">limits.conf</a></li>
</ul></li>
<li><a href="0410accountmanager.html#uselinux">13.6 Linux 主机上的用户消息传递</a>
<ul>
<li><a href="0410accountmanager.html#uselinux_find">13.6.1 查找用户: w, who, last, lastlog</a></li>
<li><a href="0410accountmanager.html#uselinux_talk">13.6.2 用户对谈: write, mesg, wall</a></li>
<li><a href="0410accountmanager.html#mail">13.6.3 用户邮件信箱: mail</a></li>
</ul></li>
<li><a href="0410accountmanager.html#manual">13.7 CentOS 7 环境下大量建置帐号的方法</a>
<ul>
<li><a href="0410accountmanager.html#manual_tools">13.7.1 一些帐号相关的检查工具</a>:<a href="0410accountmanager.html#pwck">pwck</a>,
<a href="0410accountmanager.html#pwconv">pwconv</a>, <a href="0410accountmanager.html#pwunconv">pwunconv</a>, <a href="0410accountmanager.html#chpasswd">chpasswd</a></li>
<li><a href="0410accountmanager.html#manual_account_1">13.7.2 大量建置帐号范本(适用 passwd --stdin 选项)</a></li>
</ul></li>
<li><a href="0410accountmanager.html#hint">13.8 重点回顾</a></li>
<li><a href="0410accountmanager.html#ex">13.9 本章习题</a></li>
<li><a href="0410accountmanager.html#reference">13.10 参考数据与延伸阅读</a></li>
</ul>
</div>
</div>
<!-- 本文的正式部分 -->
<a id="account"></a>
<div class="block1">
<h2>13.1 Linux 的帐号与群组</h2>
<p>管理员的工作中,相当重要的一环就是『管理帐号』啦!因为整个系统都是你在管理的,
并且所有一般用户的帐号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务器主机的帐号啦!
在管理 Linux 主机的帐号时,我们必须先来了解一下 Linux 到底是如何辨别每一个用户的!</p>
<a id="account_id"></a>
<div class="block2"><div class="gototop"><a href="0410accountmanager.html#top">Top</a></div>
<h2>13.1.1 用户识别码: UID 与 GID</h2>
<p>虽然我们登录 Linux 主机的时候,输入的是我们的帐号,但是其实 Linux
主机并不会直接认识你的『帐号名称』的,他仅认识 ID 啊 (ID 就是一组号码啦)。
由于电脑仅认识 0 与 1,所以主机对于数字比较有概念的;至于帐号只是为了让人们容易记忆而已。
而你的 ID 与帐号的对应就在 /etc/passwd 当中哩。</p>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 如果你曾经在网络上下载过 <a href="0240tarcompress.html#pack">tarball</a> 类型的文件,
那么应该不难发现,在解压缩之后的文件中,文件拥有者的字段竟然显示『不明的数字』?奇怪吧?这没什么好奇怪的,因为 Linux
说实在话,他真的只认识代表你身份的号码而已!
</fieldset><br>
<p>那么到底有几种 ID 呢?还记得我们在<a href="0210filepermission.html">第五章</a>内有提到过,
每一个文件都具有『拥有人与拥有群组』的属性吗?没错啦~每个登录的用户至少都会取得两个 ID ,一个是用户
ID (User ID ,简称 UID)、一个是群组 ID (Group ID ,简称 GID)。</p>
<p>那么文件如何判别他的拥有者与群组呢?其实就是利用 UID 与 GID 啦!每一个文件都会有所谓的拥有者 ID
与拥有群组 ID ,当我们有要显示文件属性的需求时,系统会依据 /etc/passwd 与 /etc/group 的内容,
找到 UID / GID 对应的帐号与群组名称再显示出来!我们可以作个小实验,你可以用 root 的身份
vim /etc/passwd ,然后将你的一般身份的用户的
ID 随便改一个号码,然后再到你的一般身份的目录下看看原先该帐号拥有的文件,你会发现该文件的拥有人变成了
『数字了』呵呵!这样可以理解了吗?来看看底下的例子:</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd"># 1. 先察看一下,系统里面有没有一个名为 dmtsai 的用户?</span>
[root@study ~]# <span class="term_command">id dmtsai</span>
uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel) <span class="term_note"><==确定有这个帐号喔!</span>
[root@study ~]# <span class="term_command">ll -d /home/dmtsai</span>
drwx------. 17 <span class="term_write">dmtsai</span> dmtsai 4096 Jul 17 19:51 /home/dmtsai
<span class="term_say"># 瞧一瞧,用户的字段正是 dmtsai 本身喔!</span>
<span class="term_hd"># 2. 修改一下,将刚刚我们的 dmtsai 的 1000 UID 改为 2000 看看:</span>
[root@study ~]# <span class="term_command">vim /etc/passwd</span>
<span class="term_say">....(前面省略)....</span>
dmtsai:x:<span class="term_write">2000</span>:1000:dmtsai:/home/dmtsai:/bin/bash <span class="term_note"><==修改一下特殊字体部分,由 1000 改过来</span>
[root@study ~]# <span class="term_command">ll -d /home/dmtsai</span>
drwx------. 17 <span class="term_write">1000</span> dmtsai 4096 Jul 17 19:51 /home/dmtsai
<span class="term_say"># 很害怕吧!怎么变成 1000 了?因为文件只会记录 UID 的数字而已!
# 因为我们乱改,所以导致 1000 找不到对应的帐号,因此显示数字!</span>
<span class="term_hd"># 3. 记得将刚刚的 2000 改回来!</span>
[root@study ~]# <span class="term_command">vim /etc/passwd</span>
<span class="term_say">....(前面省略)....</span>
dmtsai:x:<span class="term_write">1000</span>:1000:dmtsai:/home/dmtsai:/bin/bash <span class="term_note"><==『务必一定要』改回来!</span>
</pre></td></tr></tbody></table>
<p>你一定要了解的是,上面的例子仅是在说明 UID 与帐号的对应性,<span class="text_import2">在一部正常运作的 Linux 主机环境下,上面的动作不可随便进行</span>,
这是因为系统上已经有很多的数据被创建存在了,随意修改系统上某些帐号的 UID
很可能会导致某些进程无法进行,这将导致系统无法顺利运作的结果,
因为权限的问题啊!所以,了解了之后,请赶快回到 /etc/passwd 里面,将数字改回来喔!</p>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 举例来说,如果上面的测试最后一个步骤没有将 2000 改回原本的 UID,那么当 dmtsai 下次登录时将没有办法进入自己的家目录!
因为他的 UID 已经改为 2000 ,但是他的家目录 (/home/dmtsai) 却记录的是 1000 ,由于权限是 700 ,
因此他将无法进入原本的家目录!是否非常严重啊?
</fieldset><br> </div><br>
<a id="account_user"></a>
<div class="block2"><div class="gototop"><a href="0410accountmanager.html#top">Top</a></div>
<h2>13.1.2 用户帐号</h2>
<p>Linux 系统上面的用户如果需要登录主机以取得 shell 的环境来工作时,他需要如何进行呢?
首先,他必须要在电脑前面利用 tty1~tty6 的终端机提供的 login 接口,并输入帐号与密码后才能够登录。
如果是透过网络的话,那至少用户就得要学习 ssh 这个功能了 (服务器篇再来谈)。
那么你输入帐号密码后,系统帮你处理了什么呢?</p>
<ol class="text_import2">
<li>先找寻 /etc/passwd 里面是否有你输入的帐号?如果没有则跳出,如果有的话则将该帐号对应的
UID 与 GID (在 /etc/group 中) 读出来,另外,该帐号的家目录与 shell 设置也一并读出;<br><br></li>
<li>再来则是核对密码表啦!这时 Linux 会进入 /etc/shadow 里面找出对应的帐号与
UID,然后核对一下你刚刚输入的密码与里头的密码是否相符?<br><br></li>
<li>如果一切都 OK 的话,就进入 Shell 控管的阶段啰!</li>
</ol>
<p>大致上的情况就像这样,所以当你要登录你的 Linux 主机的时候,那个 /etc/passwd 与 /etc/shadow
就必须要让系统读取啦 (这也是很多攻击者会将特殊帐号写到 /etc/passwd 里头去的缘故),所以呢,如果你要备份
Linux 的系统的帐号的话,那么这两个文件就一定需要备份才行呦!</p>
<p>由上面的流程我们也知道,跟用户帐号有关的有两个非常重要的文件,一个是管理用户 UID/GID 重要参数的
/etc/passwd ,一个则是专门管理密码相关数据的 /etc/shadow 啰!那这两个文件的内容就非常值得进行研究啦!
底下我们会简单的介绍这两个文件,详细的说明可以参考 man 5 passwd 及 man 5 shadow (<a href="0410accountmanager.html#ps1">注1</a>)。</p>
<a id="passwd_file"></a>
<ul class="toplist"><li>/etc/passwd 文件结构</li></ul>
<p>这个文件的构造是这样的:<span class="text_import2">每一行都代表一个帐号,有几行就代表有几个帐号在你的系统中!
不过需要特别留意的是,里头很多帐号本来就是系统正常运作所必须要的,我们可以简称他为系统帐号,
例如 bin, daemon, adm, nobody 等等,这些帐号请不要随意的杀掉他呢!</span>这个文件的内容有点像这样:</p>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 鸟哥在接触 Linux 之前曾经碰过 Solaris 系统 (1999 年),当时鸟哥啥也不清楚!由于『听说』Linux
上面的帐号越复杂会导致系统越危险!所以鸟哥就将 /etc/passwd 上面的帐号全部删除到只剩下 root
与鸟哥自己用的一般帐号!结果你猜发生什么事?那就是....调用升阳的工程师来维护系统 @_@!糗到一个不行!大家不要学啊!
</fieldset><br>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">head -n 4 /etc/passwd</span>
<span class="term_write">root:x:0:0:root:/root:/bin/bash</span> <span class="term_note"><==等一下做为底下说明用</span>
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
</pre></td></tr></tbody></table>
<p>我们先来看一下每个 Linux 系统都会有的第一行,就是 root 这个系统管理员那一行好了,
你可以明显的看出来,每一行使用『:』分隔开,共有七个咚咚,分别是:</p>
<ol>
<li><span class="text_import1">帐号名称</span>:<br>
就是帐号啦!用来提供给对数字不太敏感的人类使用来登录系统的!需要用来对应 UID 喔。例如 root 的 UID 对应就是 0 (第三字段);<br><br></li>
<li><span class="text_import1">密码</span>:<br>
早期 Unix 系统的密码就是放在这字段上!但是因为这个文件的特性是<span class="text_import2">所有的进程都能够读取</span>,这样一来很容易造成密码数据被窃取,
因此后来就将这个字段的密码数据给他改放到 <a href="0410accountmanager.html#shadow_file">/etc/shadow</a>
中了。所以这里你会看到一个『 x 』,呵呵!<br><br></li>
<li><span class="text_import1">UID</span>:<br>
这个就是用户识别码啰!通常 Linux 对于 UID 有几个限制需要说给您了解一下:<br><br>
<table class="news" style="width: 95%">
<tbody><tr class="theader"><td style="width: 120px">id 范围</td><td>该 ID 用户特性</td></tr>
<tr><td class="tcenter">0<br>(系统管理员)</td><td>当 UID 是 0 时,代表这个帐号是『系统管理员』!
所以当你要让其他的帐号名称也具有 root 的权限时,将该帐号的 UID 改为 0 即可。
这也就是说,一部系统上面的系统管理员不见得只有 root 喔!
不过,很不建议有多个帐号的 UID 是 0 啦~容易让系统管理员混乱!</td></tr>
<tr><td class="tcenter">1~999<br>(系统帐号)</td><td>保留给系统使用的 ID,其实<span class="text_import2">除了 0 之外,其他的 UID 权限与特性并没有不一样</span>。缺省 1000
以下的数字让给系统作为保留帐号只是一个习惯。<br><br>
由于系统上面启动的网络服务或背景服务希望使用较小的权限去运作,因此不希望使用 root 的身份去运行这些服务,
所以我们就得要提供这些运作中程序的拥有者帐号才行。这些系统帐号通常是不可登录的,
所以才会有我们在<a href="0320bash.html">第十章</a>提到的 /sbin/nologin 这个特殊的 shell 存在。<br><br>
根据系统帐号的由来,通常这类帐号又约略被区分为两种:
<ul style="margin-top: 10px;">
<li>1~200:由 distributions 自行创建的系统帐号;</li>
<li>201~999:若用户有系统帐号需求时,可以使用的帐号 UID。</li></ul></td>
</tr><tr><td class="tcenter">1000~60000<br>(可登录帐号)</td><td>给一般用户用的。事实上,目前的 linux 核心 (3.10.x 版)已经可以支持到
4294967295 (2^32-1) 这么大的 UID 号码喔!</td></tr>
</tbody></table><br>
上面这样说明可以了解了吗?是的, UID 为 0 的时候,就是 root 呦!所以请特别留意一下你的
/etc/passwd 文件!<br><br></li>
<li><span class="text_import1">GID</span>:<br>
这个与 /etc/group 有关!其实 /etc/group
的观念与 /etc/passwd 差不多,只是他是用来规范群组名称与 GID 的对应而已!<br><br></li>
<li><span class="text_import1">用户信息说明栏</span>:<br>
这个字段基本上并没有什么重要用途,只是用来解释这个帐号的意义而已!不过,如果您提供使用 finger 的功能时,
这个字段可以提供很多的消息呢!本章后面的 <a href="0410accountmanager.html#chfn">chfn</a> 指令会来解释这里的说明。<br><br></li>
<li><span class="text_import1">家目录</span>:<br>
这是用户的家目录,以上面为例, root 的家目录在 /root ,所以当 root 登录之后,就会立刻跑到 /root 目录里头啦!呵呵!
如果你有个帐号的使用空间特别的大,你想要将该帐号的家目录移动到其他的硬盘去该怎么作?
没有错!可以在这个字段进行修改呦!缺省的用户家目录在 /home/yourIDname<br><br></li>
<li><span class="text_import1">Shell</span>:<br>
我们在<a href="0320bash.html">第十章 BASH</a> 提到很多次,当用户登录系统后就会取得一个 Shell
来与系统的核心沟通以进行用户的操作任务。那为何缺省 shell 会使用 bash 呢?就是在这个字段指定的啰!
这里比较需要注意的是,有一个 shell 可以用来替代成让帐号无法取得 shell 环境的登录动作!那就是
/sbin/nologin 这个东西!这也可以用来制作纯 pop 邮件帐号者的数据呢!</li>
</ol>
<a id="shadow_file"></a>
<ul class="toplist"><li>/etc/shadow 文件结构</li></ul>
<p>我们知道很多程序的运作都与权限有关,而权限与 UID/GID 有关!因此各程序当然需要读取 /etc/passwd 来了解不同帐号的权限。
<span class="text_import2">因此 /etc/passwd 的权限需设置为 -rw-r--r-- 这样的情况</span>,
虽然早期的密码也有加密过,但却放置到 /etc/passwd 的第二个字段上!这样一来很容易被有心人士所窃取的,
加密过的密码也能够透过暴力破解法去 trial and error (试误) 找出来!</p>
<p>因为这样的关系,所以后来发展出将密码移动到 /etc/shadow 这个文件分隔开来的技术,
而且还加入很多的密码限制参数在 /etc/shadow 里头呢!在这里,我们先来了解一下这个文件的构造吧!
鸟哥的 /etc/shadow 文件有点像这样:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">head -n 4 /etc/shadow</span>
<span class="term_write">root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhO...:16559:0:99999:7:::</span> <span class="term_note"><==底下说明用</span>
bin:*:16372:0:99999:7:::
daemon:*:16372:0:99999:7:::
adm:*:16372:0:99999:7:::
</pre></td></tr></tbody></table>
<p>基本上, shadow 同样以『:』作为分隔符号,如果数一数,会发现共有九个字段啊,这九个字段的用途是这样的:</p>
<ol>
<li><span class="text_import1">帐号名称</span>:<br>
由于密码也需要与帐号对应啊~因此,这个文件的第一栏就是帐号,必须要与 /etc/passwd 相同才行!<br><br></li>
<li><span class="text_import1">密码</span>:<br>
这个字段内的数据才是真正的密码,而且是<span class="text_import2">经过编码的密码 (加密) </span>啦!
你只会看到有一些特殊符号的字母就是了!需要特别留意的是,虽然这些加密过的密码很难被解出来,
但是『很难』不等于『不会』,所以,这个文件的缺省权限是『-rw-------』或者是『----------』,亦即只有 root
才可以读写就是了!你得随时注意,不要不小心更动了这个文件的权限呢!<br><br>
另外,由于各种密码编码的技术不一样,因此不同的编码系统会造成这个字段的长度不相同。
举例来说,旧式的 DES, MD5 编码系统产生的密码长度就与目前惯用的 SHA 不同(<a href="0410accountmanager.html#ps2">注2</a>)!SHA
的密码长度明显的比较长些。由于固定的编码系统产生的密码长度必须一致,因此『<span class="text_import2">当你让这个字段的长度改变后,该密码就会失效(算不出来)</span>』。
很多软件透过这个功能,<span class="text_import2">在此字段前加上 ! 或 * 改变密码字段长度,就会让密码『暂时失效』了。
</span><br><br></li>
<li><span class="text_import1">最近更动密码的日期</span>:<br>
这个字段记录了『更动密码那一天』的日期,不过,很奇怪呀!在我的例子中怎么会是 16559
呢?呵呵,这个是因为计算 Linux 日期的时间是以 1970 年 1 月 1 日作为 1 而累加的日期,1971 年 1 月 1 日则为 366 啦!
得注意一下这个数据呦!上述的 16559 指的就是 2015-05-04 那一天啦!了解乎?
而想要了解该日期可以使用本章后面 <a href="0410accountmanager.html#chage">chage</a> 指令的帮忙!至于想要知道某个日期的累积日数,
可使用如下的程序计算:<br>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">echo $(($(date --date="2015/05/04" +%s)/86400+1))</span>
16559
</pre></td></tr></tbody></table>
上述指令中,2015/05/04 为你想要计算的日期,86400 为每一天的秒数, %s 为 1970/01/01 以来的累积总秒数。
由于 bash 仅支持整数,因此最终需要加上 1 补齐 1970/01/01 当天。<br><br></li>
<li><span class="text_import1">密码不可被更动的天数</span>:(与第 3 字段相比)<br>
第四个字段记录了:这个帐号的密码在最近一次被更改后需要经过几天才可以再被变更!如果是 0 的话,
表示密码随时可以更动的意思。这的限制是为了怕密码被某些人一改再改而设计的!如果设置为
20 天的话,那么当你设置了密码之后, 20 天之内都无法改变这个密码呦!<br><br></li>
<li><span class="text_import1">密码需要重新变更的天数</span>:(与第 3 字段相比)<br>
经常变更密码是个好习惯!为了强制要求用户变更密码,这个字段可以指定在最近一次更改密码后,
在多少天数内需要再次的变更密码才行。<span class="text_import2">你必须要在这个天数内重新设置你的密码,否则这个帐号的密码将会『变为过期特性』</span>。
而如果像上面的 99999 (计算为 273 年) 的话,那就表示,呵呵,密码的变更没有强制性之意。<br><br></li>
<li><span class="text_import1">密码需要变更期限前的警告天数</span>:(与第 5 字段相比)<br>
当帐号的密码有效期限快要到的时候 (第 5 字段),系统会依据这个字段的设置,发出『警告』言论给这个帐号,提醒他『再过 n
天你的密码就要过期了,请尽快重新设置你的密码呦!』,如上面的例子,则是密码到期之前的
7 天之内,系统会警告该用户。<br><br></li>
<li><span class="text_import1">密码过期后的帐号宽限时间(密码失效日)</span>:(与第 5 字段相比)<br>
密码有效日期为『更新日期(第3字段)』+『重新变更日期(第5字段)』,过了该期限后用户依旧没有更新密码,那该密码就算过期了。
虽然密码过期但是该帐号还是可以用来进行其他工作的,包括登录系统取得 bash 。<span class="text_import2">不过如果密码过期了,
那当你登录系统时,系统会强制要求你必须要重新设置密码才能登录继续使用喔,这就是密码过期特性</span>。<br><br>
那这个字段的功能是什么呢?是在密码过期几天后,如果用户还是没有登录更改密码,那么这个帐号的密码将会『失效』,
亦即该帐号再也无法使用该密码登录了。要注意<span class="text_import2">密码过期与密码失效并不相同</span>。<br><br></li>
<li><span class="text_import1">帐号失效日期</span>:<br>
这个日期跟第三个字段一样,都是使用 1970 年以来的总日数设置。这个字段表示:
<span class="text_import2">这个帐号在此字段规定的日期之后,将无法再使用</span>。
就是所谓的『帐号失效』,此时不论你的密码是否有过期,这个『帐号』都不能再被使用!
这个字段会被使用通常应该是在『收费服务』的系统中,你可以规定一个日期让该帐号不能再使用啦!<br><br></li>
<li><span class="text_import1">保留</span>:<br>
最后一个字段是保留的,看以后有没有新功能加入。</li>
</ol>
<p>举个例子来说好了,假如我的 dmtsai 这个用户的密码栏如下所示:</p>
<table class="term"><tbody><tr><td class="term"><pre>dmtsai:$6$M4IphgNP2TmlXaSS$B418YFroYxxmm....:16559:5:60:7:5:16679:
</pre></td></tr></tbody></table>
<p>这表示什么呢?先要注意的是 16559 是 2015/05/04 。所以 dmtsai 这个用户的密码相关意义是:</p>
<ul>
<li>由于密码几乎仅能单向运算(由明码计算成为密码,无法由密码反推回明码),因此由上表的数据我们<span class="text_import2">无法得知 dmstai 的实际密码明文</span> (第二个字段);<br><br></li>
<li>此帐号最近一次更动密码的日期是 2015/05/04 (16559);<br><br></li>
<li>能够再次修改密码的时间是 5 天以后,也就是 <span class="text_import2">2015/05/09 以前 dmtsai
不能修改自己的密码</span>;如果用户还是尝试要更动自己的密码,系统就会出现这样的消息:<br>
<table class="term"><tbody><tr><td class="term"><pre>You must wait longer to change your password
passwd: Authentication token manipulation error
</pre></td></tr></tbody></table>
画面中告诉我们:你必须要等待更久的时间才能够变更密码之意啦!<br><br></li>
<li>由于密码过期日期定义为 60 天后,亦即累积日数为: 16559+60=16619,经过计算得到此日数代表日期为 2015/07/03。
这表示:『<span class="text_import2">用户必须要在 2015/05/09 (前 5 天不能改) 到 2015/07/03 之间的 60
天限制内去修改自己的密码,若 2015/07/03 之后还是没有变更密码时,该密码就声明为过期</span>』了!<br><br></li>
<li>警告日期设为 7 天,亦即是密码过期日前的 7 天,在本例中则代表 2015/06/26 ~ 2015/07/03 这七天。
如果用户一直没有更改密码,那么在这 7 天中,只要 dmtsai 登录系统就会发现如下的消息:<br>
<table class="term"><tbody><tr><td class="term"><pre>Warning: your password will expire in 5 days
</pre></td></tr></tbody></table><br></li>
<li>如果该帐号一直到 2015/07/03 都没有更改密码,那么密码就过期了。但是由于有 5 天的宽限天数,
因此 <span class="text_import2">dmtsai 在 2015/07/08 前都还可以使用旧密码登录主机。
不过登录时会出现强制更改密码的情况</span>,画面有点像底下这样:<br>
<table class="term"><tbody><tr><td class="term"><pre>You are required to change your password immediately (password aged)
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user dmtsai.
Changing password for dmtsai
(current) UNIX password:
</pre></td></tr></tbody></table>
你必须要输入一次旧密码以及两次新密码后,才能够开始使用系统的各项资源。如果你是在 2015/07/08 以后尝试以
dmtsai 登录的话,那么就会出现如下的错误消息且无法登录,因为此时你的密码就失效去啦!<br>
<table class="term"><tbody><tr><td class="term"><pre>Your account has expired; please contact your system administrator
</pre></td></tr></tbody></table><br></li>
<li>如果用户在 2015/07/03 以前变更过密码,那么第 3 个字段的那个 16559 的天数就会跟着改变,因此,
所有的限制日期也会跟着相对变动喔!^_^<br><br></li>
<li>无论用户如何动作,到了 16679 (大约是 2015/09/01 左右) 该帐号就失效了~</li>
</ul>
<p>透过这样的说明,您应该会比较容易理解了吧?由于 shadow 有这样的重要性,因此可不能随意修改喔!
但在某些情况底下你得要使用各种方法来处理这个文件的!举例来说,常常听到人家说:『我的密码忘记了』,
或者是『我的密码不晓得被谁改过,跟原先的不一样了』,这个时候怎么办?</p>
<ul>
<li><span class="text_import2">一般用户的密码忘记了</span>:这个最容易解决,请系统管理员帮忙,
他会重新设置好你的密码而不需要知道你的旧密码!利用 root 的身份使用 <a href="0410accountmanager.html#passwd">passwd</a>
指令来处理即可。<br><br></li>
<li><span class="text_import2">root 密码忘记了</span>:这就麻烦了!因为你无法使用 root 的身份登录了嘛!
但我们知道 root 的密码在 /etc/shadow 当中,因此你可以使用各种可行的方法开机进入 Linux 再去修改。
例如重新开机进入单人维护模式(<a href="0510osloader.html">第十九章</a>)后,系统会主动的给予 root 权限的 bash 接口,
此时再以 passwd 修改密码即可;或以 Live CD 开机后挂载根目录去修改 /etc/shadow,将里面的 root 的密码字段清空,
再重新开机后 root 将不用密码即可登录!登录后再赶快以 passwd 指令去设置 root 密码即可。</li>
</ul>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 曾经听过一则笑话,某位老师主要是在教授 Linux 操作系统,但是他是兼任的老师,因此对于该系的电脑环境不熟。
由于当初安装该电脑教室 Linux 操作系统的人员已经离职且找不到联系方式了,也就是说 root 密码已经没有人晓得了!
此时该老师就对学生说:『在 Linux 里面 root 密码不见了,我们只能重新安装』...感觉有点无力~
又是个被 Windows 制约的人才!
</fieldset><br>
<p>另外,由于 Linux 的新旧版本差异颇大,旧的版本 (CentOS 5.x 以前) 还活在很多服务器内!因此,如果你想要知道 shadow 是使用哪种加密的机制时,
可以透过底下的方法去查找喔!</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">authconfig --test | grep hashing</span>
password hashing algorithm is <span class="term_write">sha512</span>
<span class="term_say"># 这就是目前的密码加密机制!</span>
</pre></td></tr></tbody></table>
<br></div><br>
<a id="account_group"></a>
<div class="block2"><div class="gototop"><a href="0410accountmanager.html#top">Top</a></div>
<h2>13.1.3 关于群组: 有效与初始群组、groups, newgrp</h2>
<p>认识了帐号相关的两个文件 /etc/passwd 与 /etc/shadow 之后,你或许还是会觉得奇怪,
那么群组的设置档在哪里?还有,在 /etc/passwd 的第四栏不是所谓的 GID 吗?那又是啥?
呵呵~此时就需要了解 /etc/group 与 /etc/gshadow 啰~</p>
<a id="group_file"></a>
<ul class="toplist"><li>/etc/group 文件结构</li></ul>
<p>这个文件就是在记录 GID 与群组名称的对应了~鸟哥测试机的 /etc/group 内容有点像这样:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">head -n 4 /etc/group</span>
<span class="term_write">root:x:0:</span>
bin:x:1:
daemon:x:2:
sys:x:3:
</pre></td></tr></tbody></table>
<p>这个文件每一行代表一个群组,也是以冒号『:』作为字段的分隔符号,共分为四栏,每一字段的意义是:</p>
<ol>
<li><span class="text_import1">群组名称</span>:<br>
就是群组名称啦!同样用来给人类使用的,基本上需要与第三字段的 GID 对应。<br><br></li>
<li><span class="text_import1">群组密码</span>:<br>
通常不需要设置,这个设置通常是给『群组管理员』使用的,目前很少有这个机会设置群组管理员啦!
同样的,密码已经移动到 /etc/gshadow 去,因此这个字段只会存在一个『x』而已;<br><br></li>
<li><span class="text_import1">GID</span>:<br>
就是群组的 ID 啊。我们 /etc/passwd 第四个字段使用的 GID 对应的群组名,就是由这里对应出来的!<br><br></li>
<li><span class="text_import1">此群组支持的帐号名称</span>:<br>
我们知道一个帐号可以加入多个群组,那某个帐号想要加入此群组时,将该帐号填入这个字段即可。
举例来说,如果我想要让 dmtsai 与 alex 也加入 root 这个群组,那么在第一行的最后面加上『dmtsai,alex』,注意不要有空格,
使成为『 root:x:0:dmtsai,alex 』就可以啰~</li>
</ol>
<p>谈完了 /etc/passwd, /etc/shadow, /etc/group 之后,我们可以使用一个简单的图标来了解一下 UID / GID 与密码之间的关系,
图标如下。其实重点是 /etc/passwd 啦,其他相关的数据都是根据这个文件的字段去找寻出来的。
下图中, root 的 UID 是 0 ,而 GID 也是 0 ,去找 /etc/group 可以知道 GID 为 0 时的群组名称就是 root 哩。
至于密码的寻找中,会找到 /etc/shadow 与 /etc/passwd 内同帐号名称的那一行,就是密码相关数据啰。</p>
<a id="fig13.1.1"></a>
<div style="text-align:center; margin: 0 auto 0 auto; "><img src="./vbird_files/centos7_id_link.jpg" alt="帐号相关文件之间的 UID/GID 与密码相关性示意图" title="帐号相关文件之间的 UID/GID 与密码相关性示意图" style="border: 1px solid black; padding: 10px "></div>
<div style="text-align: center;">图13.1.1、帐号相关文件之间的 UID/GID 与密码相关性示意图</div>
<p>至于在 /etc/group 比较重要的特色在于第四栏啦,因为每个用户都可以拥有多个支持的群组,这就好比在学校念书的时候,
我们可以加入多个社团一样! ^_^。不过这里你或许会觉得奇怪的,那就是:『<span class="text_import2">假如我同时加入多个群组,那么我在作业的时候,到底是以那个群组为准?</span>』
底下我们就来谈一谈这个『有效群组』的概念。<br><br></p>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 请注意,新版的 Linux 中,初始群组的用户群已经不会加入在第四个字段!例如我们知道 root 这个帐号的主要群组为 root,但是在上面的范例中,
你已经不会看到 root 这个『用户』的名称在 /etc/group 的 root 那一行的第四个字段内啰!这点还请留意一下即可!
</fieldset><br>
<a id="account_group_init"></a>
<ul class="toplist"><li>有效群组(effective group)与初始群组(initial group)</li></ul>
<p>还记得每个用户在他的 /etc/passwd 里面的第四栏有所谓的 GID 吧?那个 GID 就是所谓的『初始群组
(initial group) 』!也就是说,当用户一登录系统,立刻就拥有这个群组的相关权限的意思。
举例来说,我们上面提到 dmtsai 这个用户的 /etc/passwd 与 /etc/group 还有 /etc/gshadow
相关的内容如下:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">usermod -a -G users dmtsai</span> <span class="term_note"><==先设置好次要群组</span>
[root@study ~]# <span class="term_command">grep dmtsai /etc/passwd /etc/group /etc/gshadow</span>
/etc/passwd:dmtsai:x:1000:<span class="term_write">1000</span>:dmtsai:/home/dmtsai:/bin/bash
/etc/group:wheel:x:10:<span class="term_write">dmtsai</span> <span class="term_note"><==次要群组的设置、安装时指定的</span>
/etc/group:users:x:100:<span class="term_write">dmtsai</span> <span class="term_note"><==次要群组的设置</span>
/etc/group:dmtsai:x:<span class="term_write">1000</span>: <span class="term_note"><==因为是初始群组,所以第四字段不需要填入帐号</span>
/etc/gshadow:wheel:::<span class="term_write">dmtsai</span> <span class="term_note"><==次要群组的设置</span>
/etc/gshadow:users:::<span class="term_write">dmtsai</span> <span class="term_note"><==次要群组的设置</span>
/etc/gshadow:dmtsai:!!::
</pre></td></tr></tbody></table>
<p>仔细看到上面这个表格,在 /etc/passwd 里面,dmtsai 这个用户所属的群组为 GID=1000 ,搜索一下 /etc/group
得到 1000 是那个名为 dmtsai 的群组啦!这就是 initial group。因为是初始群组,
用户一登录就会主动取得,不需要在 /etc/group 的第四个字段写入该帐号的!</p>
<p>但是非 initial group 的其他群组可就不同了。举上面这个例子来说,我将 dmtsai 加入 users
这个群组当中,由于 users 这个群组并非是 dmtsai 的初始群组,因此,
我必须要在 /etc/group 这个文件中,找到 users 那一行,并且将 dmtsai 这个帐号加入第四栏,
这样 dmtsai 才能够加入 users 这个群组啊。</p>
<p>那么在这个例子当中,因为我的 dmtsai 帐号同时支持 dmtsai, wheel 与 users 这三个群组,
因此,在读取/写入/运行文件时,针对群组部分,只要是 users, wheel 与 dmtsai 这三个群组拥有的功能,
我 dmtsai 这个用户都能够拥有喔!这样瞭呼?不过,这是针对已经存在的文件而言,
如果今天我要创建一个新的文件或者是新的目录,请问一下,<span class="text_import2">新文件的群组是 dmtsai, wheel 还是
users</span> ?呵呵!这就得要检查一下当时的有效群组了 (effective group)。</p>
<a id="groups"></a>
<ul class="toplist"><li>groups: 有效与支持群组的观察</li></ul>
<p>如果我以 dmtsai 这个用户的身份登录后,该如何知道我所有支持的群组呢?
很简单啊,直接输入 groups 就可以了!注意喔,是 groups 有加 s 呢!结果像这样:</p>
<table class="term"><tbody><tr><td class="term"><pre>[dmtsai@study ~]$ <span class="term_command">groups</span>
dmtsai wheel users
</pre></td></tr></tbody></table>
<p>在这个输出的消息中,可知道 dmtsai 这个用户同时属于 dmtsai, wheel 及 users 这三个群组,而且,
<span class="text_import2">第一个输出的群组即为有效群组 (effective group) 了</span>。
也就是说,我的有效群组为 dmtsai 啦~此时,如果我以 touch 去创建一个新档,例如:
『 touch test 』,那么这个文件的拥有者为 dmtsai ,而且群组也是 dmtsai 的啦。</p>
<table class="term"><tbody><tr><td class="term"><pre>[dmtsai@study ~]$ <span class="term_command">touch test</span>
[dmtsai@study ~]$ <span class="term_command">ll test</span>
-rw-rw-r--. 1 dmtsai <span class="term_write">dmtsai</span> 0 Jul 20 19:54 test
</pre></td></tr></tbody></table>
<p>这样是否可以了解什么是有效群组了?通常有效群组的作用是在新建文件啦!那么有效群组是否能够变换?</p>
<a id="newgrp"></a>
<ul class="toplist"><li>newgrp: 有效群组的切换</li></ul>
<p>那么如何变更有效群组呢?就使用 newgrp 啊!不过使用 newgrp 是有限制的,那就是<span class="text_import2">你想要切换的群组必须是你已经有支持的群组。</span>举例来说, dmtsai 可以在 dmtsai/wheel/users
这三个群组间切换有效群组,但是 dmtsai 无法切换有效群组成为 sshd 啦!使用的方式如下:</p>
<table class="term"><tbody><tr><td class="term"><pre>[dmtsai@study ~]$ <span class="term_command">newgrp users</span>
[dmtsai@study ~]$ <span class="term_command">groups</span>
users wheel dmtsai
[dmtsai@study ~]$ <span class="term_command">touch test2</span>
[dmtsai@study ~]$ <span class="term_command">ll test*</span>
-rw-rw-r--. 1 dmtsai dmtsai 0 Jul 20 19:54 test
-rw-r--r--. 1 dmtsai <span class="term_write">users</span> 0 Jul 20 19:56 test2
[dmtsai@study ~]$ <span class="term_command">exit</span> <span class="term_note"># 注意!记得离开 newgrp 的环境喔!</span>
</pre></td></tr></tbody></table>
<p>此时,dmtsai 的有效群组就成为 users 了。我们额外的来讨论一下 newgrp 这个指令,这个指令可以变更目前用户的有效群组,
而且是<span class="text_import2">另外以一个 shell 来提供这个功能</span>的喔,所以,以上面的例子来说,
dmtsai 这个用户目前是以另一个 shell 登录的,而且新的 shell 给予 dmtsai 有效 GID 为
users 就是了。如果以图标来看就是如下所示:</p>
<a id="fig13.1.2"></a>
<div style="text-align:center; margin: 0 auto 0 auto; "><img src="./vbird_files/newgrp.gif" alt="newgrp 的运作示意图" title="newgrp 的运作示意图" style="border: 1px solid black; padding: 10px "></div>
<div style="text-align: center;">图13.1.2、newgrp 的运作示意图</div>
<p>虽然用户的环境设置(例如环境变量等等其他数据)不会有影响,但是用户的『群组权限』将会重新被计算。
但是需要注意,由于是新取得一个 shell ,因此如果你想要回到原本的环境中,请输入 exit 回到原本的 shell 喔!</p>
<p>既然如此,也就是说,只要我的用户有支持的群组就是能够切换成为有效群组!好了,
那么如何让一个帐号加入不同的群组就是问题的所在啰。你要加入一个群组有两个方式,一个是透过系统管理员 (root) 利用
<a href="0410accountmanager.html#usermod">usermod</a> 帮你加入,如果 root 太忙了而且你的系统有设置群组管理员,那么你可以透过群组管理员以
<a href="0410accountmanager.html#gpasswd">gpasswd</a> 帮你加入他所管理的群组中!详细的作法留待下一小节再来介绍啰!</p>
<a id="gshadow_file"></a>
<ul class="toplist"><li>/etc/gshadow</li></ul>
<p>刚刚讲了很多关于『有效群组』的概念,另外,也提到 newgrp 这个指令的用法,但是,如果 /etc/gshadow 这个设置没有搞懂得话,那么 newgrp 是无法动作的呢!
鸟哥测试机的 /etc/gshadow 的内容有点像这样:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">head -n 4 /etc/gshadow</span>
<span class="term_write">root:::</span>
bin:::
daemon:::
sys:::
</pre></td></tr></tbody></table>
<p>这个文件内同样还是使用冒号『:』来作为字段的分隔字符,而且你会发现,这个文件几乎与 /etc/group
一模一样啊!是这样没错~不过,要注意的大概就是第二个字段吧~第二个字段是密码栏,
如果密码栏上面是『!』或空的时,表示该群组不具有群组管理员!至于第四个字段也就是支持的帐号名称啰~
这四个字段的意义为:</p>
<ol class="text_import2">
<li>群组名称</li>
<li>密码栏,同样的,开头为 ! 表示无合法密码,所以无群组管理员</li>
<li>群组管理员的帐号 (相关信息在 <a href="0410accountmanager.html#gpasswd">gpasswd</a> 中介绍)</li>
<li>有加入该群组支持的所属帐号 (与 /etc/group 内容相同!)</li></ol>
<p>以系统管理员的角度来说,这个 gshadow 最大的功能就是<span class="text_import2">创建群组管理员</span>啦!
那么什么是群组管理员呢?由于系统上面的帐号可能会很多,但是我们 root 可能平时太忙碌,所以当有用户想要加入某些群组时,
root 或许会没有空管理。此时如果能够创建群组管理员的话,那么<span class="text_import2">该群组管理员就能够将那个帐号加入自己管理的群组中</span>!
可以免去 root 的忙碌啦!不过,由于目前有类似 <a href="0410accountmanager.html#sudo">sudo</a> 之类的工具,
所以这个群组管理员的功能已经很少使用了。我们会在后续的 gpasswd 中介绍这个实作。</p>
<br></div>
</div>
<a id="users"></a>
<div class="block1">
<h2>13.2 帐号管理</h2>
<p>好啦!既然要管理帐号,当然是由添加与移除用户开始的啰~底下我们就分别来谈一谈如何添加、
移除与更改用户的相关信息吧~</p>
<a id="users_adduser"></a>
<div class="block2"><div class="gototop"><a href="0410accountmanager.html#top">Top</a></div>
<h2>13.2.1 添加与移除用户: useradd, 相关设置档, passwd, usermod, userdel</h2>
<p>要如何在 Linux 的系统添加一个用户啊?呵呵~真是太简单了~我们登录系统时会输入 (1)帐号与 (2)密码,
所以创建一个可用的帐号同样的也需要这两个数据。那帐号可以使用 useradd 来新建用户,密码的给予则使用 passwd
这个指令!这两个指令下达方法如下:</p>
<a id="useradd"></a>
<ul class="toplist"><li>useradd</li></ul>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">useradd [-u UID] [-g 初始群组] [-G 次要群组] [-mM]\</span>
> <span class="term_command"> [-c 说明栏] [-d 家目录绝对路径] [-s shell] 用户帐号名</span>
<span class="term_say">选项与参数:
-u :后面接的是 UID ,是一组数字。直接指定一个特定的 UID 给这个帐号;
-g :后面接的那个群组名称就是我们上面提到的 initial group 啦~
该群组的 GID 会被放置到 /etc/passwd 的第四个字段内。
-G :后面接的群组名称则是这个帐号还可以加入的群组。
这个选项与参数会修改 /etc/group 内的相关数据喔!
-M :强制!不要创建用户家目录!(系统帐号默认值)
-m :强制!要创建用户家目录!(一般帐号默认值)
-c :这个就是 /etc/passwd 的第五栏的说明内容啦~可以随便我们设置的啦~
-d :指定某个目录成为家目录,而不要使用默认值。务必使用绝对路径!
-r :创建一个系统的帐号,这个帐号的 UID 会有限制 (参考 /etc/login.defs)
-s :后面接一个 shell ,若没有指定则缺省是 /bin/bash 的啦~
-e :后面接一个日期,格式为『YYYY-MM-DD』此项目可写入 shadow 第八字段,
亦即帐号失效日的设置项目啰;
-f :后面接 shadow 的第七字段项目,指定密码是否会失效。0为立刻失效,
-1 为永远不失效(密码只会过期而强制于登录时重新设置而已。)</span>
<span class="term_hd">范例一:完全参考默认值创建一个用户,名称为 vbird1</span>
[root@study ~]# <span class="term_command">useradd vbird1</span>
[root@study ~]# <span class="term_command">ll -d /home/vbird1</span>
drwx------. 3 vbird1 vbird1 74 Jul 20 21:50 /home/vbird1
<span class="term_say"># 缺省会创建用户家目录,且权限为 700 !这是重点!</span>
[root@study ~]# <span class="term_command">grep vbird1 /etc/passwd /etc/shadow /etc/group</span>
/etc/passwd:vbird1:x:1003:1004::/home/vbird1:/bin/bash
/etc/shadow:vbird1:!!:16636:0:99999:7:::
/etc/group:vbird1:x:1004: <span class="term_note"><==缺省会创建一个与帐号一模一样的群组名</span>
</pre></td></tr></tbody></table>
<p>其实系统已经帮我们规定好非常多的默认值了,所以我们可以简单的使用『 useradd 帐号 』来创建用户即可。
CentOS 这些默认值主要会帮我们处理几个项目:</p>
<ul class="text_import2">
<li>在 /etc/passwd 里面创建一行与帐号相关的数据,包括创建 UID/GID/家目录等;</li>
<li>在 /etc/shadow 里面将此帐号的密码相关参数填入,但是尚未有密码;</li>
<li>在 /etc/group 里面加入一个与帐号名称一模一样的群组名称;</li>
<li>在 /home 底下创建一个与帐号同名的目录作为用户家目录,且权限为 700</li>
</ul>
<p>由于在 /etc/shadow 内仅会有密码参数而不会有加密过的密码数据,因此我们在创建用户帐号时,
还需要使用『 passwd 帐号 』来给予密码才算是完成了用户创建的流程。如果由于特殊需求而需要改变用户相关参数时,
就得要透过上述表格中的选项来进行创建了,参考底下的案例:</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例二:假设我已知道我的系统当中有个群组名称为 users ,且 UID 1500 并不存在,
请用 users 为初始群组,以及 uid 为 1500 来创建一个名为 vbird2 的帐号</span>
[root@study ~]# <span class="term_command">useradd -u 1500 -g users vbird2</span>
[root@study ~]# <span class="term_command">ll -d /home/vbird2</span>
drwx------. 3 vbird2 <span class="term_write">users</span> 74 Jul 20 21:52 /home/vbird2
[root@study ~]# <span class="term_command">grep vbird2 /etc/passwd /etc/shadow /etc/group</span>
/etc/passwd:vbird2:x:<span class="term_write">1500:100</span>::/home/vbird2:/bin/bash
/etc/shadow:vbird2:!!:16636:0:99999:7:::
<span class="term_say"># 看一下,UID 与 initial group 确实改变成我们需要的了!</span>
</pre></td></tr></tbody></table>
<p>在这个范例中,我们创建的是指定一个已经存在的群组作为用户的初始群组,因为群组已经存在,
<span class="text_import2">所以在 /etc/group 里面就不会主动的创建与帐号同名的群组了!</span>
此外,我们也指定了特殊的 UID 来作为用户的专属 UID 喔!了解了一般帐号后,我们来瞧瞧那啥是系统帐号 (system
account) 吧!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例三:创建一个系统帐号,名称为 vbird3</span>
[root@study ~]# <span class="term_command">useradd -r vbird3</span>
[root@study ~]# <span class="term_command">ll -d /home/vbird3</span>
ls: cannot access /home/vbird3: No such file or directorya <span class="term_note"><==不会主动创建家目录</span>
[root@study ~]# <span class="term_command">grep vbird3 /etc/passwd /etc/shadow /etc/group</span>
/etc/passwd:vbird3:x:<span class="term_write">699:699</span>::/home/vbird3:/bin/bash
/etc/shadow:vbird3:!!:16636::::::
/etc/group:vbird3:x:<span class="term_write">699</span>:
</pre></td></tr></tbody></table>
<p>我们在谈到 UID 的时候曾经说过一般帐号应该是 1000 号以后,那用户自己创建的系统帐号则一般是小于 1000 号以下的。
所以在这里我们加上 -r 这个选项以后,系统就会主动将帐号与帐号同名群组的 UID/GID 都指定小于 1000 以下,
在本案例中则是使用 699(UID) 与 699(GID) 啰!此外,由于系统帐号主要是用来进行运作系统所需服务的权限设置,
所以<span class="text_import2">系统帐号缺省都不会主动创建家目录的</span>!</p>
<p>由这几个范例我们也会知道,使用 useradd 创建用户帐号时,其实会更改不少地方,至少我们就知道底下几个文件:</p>
<ul class="text_import2">
<li>用户帐号与密码参数方面的文件:/etc/passwd, /etc/shadow</li>
<li>用户群组相关方面的文件:/etc/group, /etc/gshadow</li>
<li>用户的家目录:/home/帐号名称</li>
</ul>
<p>那请教一下,你有没有想过,为何『 useradd vbird1 』会主动在 /home/vbird1
创建起用户的家目录?家目录内有什么数据且来自哪里?为何缺省使用的是 /bin/bash 这个 shell
?为何密码字段已经都规范好了 (0:99999:7 那一串)?呵呵!这就得要说明一下 useradd 所使用的参考文件啰!</p>
<a id="users_adduser_env"></a>
<ul class="toplist"><li>useradd 参考档</li></ul>
<p>其实 useradd 的默认值可以使用底下的方法调用出来:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">useradd -D</span>
GROUP=100 <span class="term_note"><==缺省的群组</span>
HOME=/home <span class="term_note"><==缺省的家目录所在目录</span>
INACTIVE=-1 <span class="term_note"><==密码失效日,在 shadow 内的第 7 栏</span>
EXPIRE= <span class="term_note"><==帐号失效日,在 shadow 内的第 8 栏</span>
SHELL=/bin/bash <span class="term_note"><==缺省的 shell</span>
SKEL=/etc/skel <span class="term_note"><==用户家目录的内容数据参考目录</span>
CREATE_MAIL_SPOOL=yes <span class="term_note"><==是否主动帮用户创建邮件信箱(mailbox)</span>
</pre></td></tr></tbody></table>
<p>这个<span class="text_import2">数据其实是由 /etc/default/useradd</span> 调用出来的!你可以自行用 vim
去观察该文件的内容。搭配上头刚刚谈过的范例一的运作结果,上面这些设置项目所造成的行为分别是:</p>
<div class="illus">
<ul><li>GROUP=100:新建帐号的初始群组使用 GID 为 100 者</li></ul>
<p>系统上面 GID 为 100 者即是 users 这个群组,此设置项目指的就是让新设用户帐号的初始群组为 users 这一个的意思。
但是我们知道 CentOS 上面并不是这样的,在 CentOS 上面<span class="text_import2">缺省的群组为与帐号名相同的群组</span>。
举例来说, vbird1 的初始群组为 vbird1 。怎么会这样啊?这是因为针对群组的角度有两种不同的机制所致,
这两种机制分别是:</p>
<div class="illus">
<ul style="list-style-type: square; "><li>私有群组机制:</li></ul>
<p>系统会创建一个与帐号一样的群组给用户作为初始群组。
这种群组的设置机制会比较有保密性,这是因为用户都有自己的群组,而且家目录权限将会设置为 700
(仅有自己可进入自己的家目录) 之故。使用这种机制将不会参考 GROUP=100 这个设置值。代表性的 distributions
有 RHEL, Fedora, CentOS 等;</p>
<ul style="list-style-type: square; "><li>公共群组机制:</li></ul>
<p>就是以 GROUP=100
这个设置值作为新建帐号的初始群组,因此每个帐号都属于 users 这个群组,
且缺省家目录通常的权限会是『 drwxr-xr-x ... username users ... 』,由于每个帐号都属于 users
群组,因此大家都可以互相分享家目录内的数据之故。代表 distributions 如 SuSE等。</p>
</div>
<p>由于我们的 CentOS 使用私有群组机制,因此这个设置项目是不会生效的!不要太紧张啊!</p>
<ul><li>HOME=/home:用户家目录的基准目录(basedir)</li></ul>
<p>用户的家目录通常是与帐号同名的目录,这个目录将会摆放在此设置值的目录后。所以 vbird1 的家目录就会在
/home/vbird1/ 了!很容易理解吧!</p>
<ul><li>INACTIVE=-1:密码过期后是否会失效的设置值</li></ul>
<p>我们在 <a href="0410accountmanager.html#shadow_file">shadow</a> 文件结构当中谈过,第七个字段的设置值将会影响到密码过期后,
在多久时间内还可使用旧密码登录。这个项目就是在指定该日数啦!如果是 0 代表密码过期立刻失效,
如果是 -1 则是代表密码永远不会失效,如果是数字,如 30 ,则代表过期 30 天后才失效。</p>
<ul><li>EXPIRE=:帐号失效的日期</li></ul>
<p>就是 <a href="0410accountmanager.html#shadow_file">shadow</a> 内的第八字段,你可以直接设置帐号在哪个日期后就直接失效,而不理会密码的问题。
通常不会设置此项目,但如果是付费的会员制系统,或许这个字段可以设置喔!</p>
<ul><li>SHELL=/bin/bash:缺省使用的 shell 程序文件名</li></ul>
<p>系统缺省的 shell 就写在这里。假如你的系统为 mail server ,你希望每个帐号都只能使用 email 的收发信件功能,
而不许用户登录系统取得 shell ,那么可以将这里设置为 /sbin/nologin ,如此一来,新建的用户缺省就无法登录!
也免去后续使用 <a href="0410accountmanager.html#usermod">usermod</a> 进行修改的手续!</p>
<ul><li>SKEL=/etc/skel:用户家目录参考基准目录</li></ul>
<p>这个咚咚就是指定用户家目录的参考基准目录啰~举我们的范例一为例, vbird1 家目录 /home/vbird1
内的各项数据,都是由 /etc/skel 所复制过去的~所以呢,未来如果我想要让添加用户时,该用户的环境变量 ~/.bashrc
就设置妥当的话,您可以到 /etc/skel/.bashrc 去编辑一下,也可以创建 /etc/skel/www 这个目录,那么未来添加用户后,在他的家目录下就会有 www
那个目录了!这样瞭呼?</p>
<ul><li>CREATE_MAIL_SPOOL=yes:创建用户的 mailbox</li></ul>
<p>你可以使用『 ll /var/spool/mail/vbird1 』看一下,会发现有这个文件的存在喔!这就是用户的邮件信箱!</p>
</div>
<a id="login.defs"></a>
<p>除了这些基本的帐号设置值之外, UID/GID 还有密码参数又是在哪里参考的呢?那就得要看一下 /etc/login.defs 啦!
这个文件的内容有点像底下这样:</p>
<table class="term"><tbody><tr><td class="term"><pre>MAIL_DIR /var/spool/mail <span class="term_note"><==用户缺省邮件信箱放置目录</span>
PASS_MAX_DAYS 99999 <span class="term_note"><==/etc/shadow 内的第 5 栏,多久需变更密码日数</span>
PASS_MIN_DAYS 0 <span class="term_note"><==/etc/shadow 内的第 4 栏,多久不可重新设置密码日数</span>
PASS_MIN_LEN 5 <span class="term_note"><==密码最短的字符长度,已被 pam 模块取代,失去效用!</span>
PASS_WARN_AGE 7 <span class="term_note"><==/etc/shadow 内的第 6 栏,过期前会警告的日数</span>
UID_MIN 1000 <span class="term_note"><==用户最小的 UID,意即小于 1000 的 UID 为系统保留</span>
UID_MAX 60000 <span class="term_note"><==用户能够用的最大 UID</span>
SYS_UID_MIN 201 <span class="term_note"><==保留给用户自行设置的系统帐号最小值 UID</span>
SYS_UID_MAX 999 <span class="term_note"><==保留给用户自行设置的系统帐号最大值 UID</span>
GID_MIN 1000 <span class="term_note"><==用户自订群组的最小 GID,小于 1000 为系统保留</span>
GID_MAX 60000 <span class="term_note"><==用户自订群组的最大 GID</span>
SYS_GID_MIN 201 <span class="term_note"><==保留给用户自行设置的系统帐号最小值 GID</span>
SYS_GID_MAX 999 <span class="term_note"><==保留给用户自行设置的系统帐号最大值 GID</span>
CREATE_HOME yes <span class="term_note"><==在不加 -M 及 -m 时,是否主动创建用户家目录?</span>
UMASK 077 <span class="term_note"><==用户家目录创建的 umask ,因此权限会是 700</span>
USERGROUPS_ENAB yes <span class="term_note"><==使用 userdel 删除时,是否会删除初始群组</span>
ENCRYPT_METHOD SHA512 <span class="term_note"><==密码加密的机制使用的是 sha512 这一个机制!</span>
</pre></td></tr></tbody></table>
<p>这个文件规范的数据则是如下所示:</p>
<ul>
<li><span class="text_import2">mailbox 所在目录</span>:<br>
用户的缺省 mailbox 文件放置的目录在 /var/spool/mail,所以 vbird1 的 mailbox 就是在
/var/spool/mail/vbird1 啰!<br><br></li>
<li><span class="text_import2">shadow 密码第 4, 5, 6 字段内容</span>:<br>
透过 PASS_MAX_DAYS 等等设置值来指定的!所以你知道为何缺省的 /etc/shadow 内每一行都会有『
0:99999:7 』的存在了吗?^_^!不过要注意的是,由于目前我们登录时改用 PAM 模块来进行密码检验,所以那个
PASS_MIN_LEN 是失效的!<br><br></li>
<li><span class="text_import2">UID/GID 指定数值</span>:<br>
虽然 Linux 核心支持的帐号可高达 2<sup>32</sup> 这么多个,不过一部主机要作出这么多帐号在管理上也是很麻烦的!
所以在这里就针对 UID/GID 的范围进行规范就是了。上表中的 UID_MIN 指的就是可登录系统的一般帐号的最小 UID ,至于
UID_MAX 则是最大 UID 之意。<br><br>
要注意的是,系统给予一个帐号 UID 时,他是 (1)先参考 UID_MIN 设置值取得最小数值; (2)由 /etc/passwd 搜索最大的 UID 数值,
将 (1) 与 (2) 相比,找出最大的那个再加一就是新帐号的 UID 了。我们上面已经作出 UID 为 1500 的 vbird2 ,
如果再使用『 useradd vbird4 』时,你猜 vbird4 的 UID 会是多少?答案是: 1501 。
所以中间的 1004~1499 的号码就空下来啦!<br><br>
而如果我是想要创建系统用的帐号,所以使用 useradd -r sysaccount
这个 -r 的选项时,就会找『比 201 大但比 1000 小的最大的 UID 』就是了。 ^_^<br><br></li>
<li><span class="text_import2">用户家目录设置值</span>:<br>
为何我们系统缺省会帮用户创建家目录?就是这个『CREATE_HOME = yes』的设置值啦!这个设置值会让你在使用 useradd 时,
主动加入『 -m 』这个产生家目录的选项啊!如果不想要创建用户家目录,就只能强制加上『 -M 』的选项在 useradd
指令运行时啦!至于创建家目录的权限设置呢?就透过 <a href="0220filemanager.html#umask">umask</a>
这个设置值啊!因为是 077 的缺省设置,因此用户家目录缺省权限才会是『 drwx------ 』哩!<br><br></li>
<li><span class="text_import2">用户删除与密码设置值</span>:<br>
使用『USERGROUPS_ENAB yes』这个设置值的功能是:<span class="text_import2">
如果使用 userdel 去删除一个帐号时,且该帐号所属的初始群组已经没有人隶属于该群组了,
那么就删除掉该群组</span>,举例来说,我们刚刚有创建 vbird4 这个帐号,他会主动创建 vbird4 这个群组。
若 vbird4 这个群组并没有其他帐号将他加入支持的情况下,若使用 userdel vbird4 时,该群组也会被删除的意思。
至于『ENCRYPT_METHOD SHA512』则表示使用 SHA512 来加密密码明文,而不使用旧式的 MD5(<a href="0410accountmanager.html#ps2">注2</a>) 。</li>
</ul>
<p>现在你知道啦,使用 useradd 这支程序在创建 Linux 上的帐号时,至少会参考:</p>
<ul class="text_import2" style="font-family:'细明体'">
<li>/etc/default/useradd</li>
<li>/etc/login.defs</li>
<li>/etc/skel/*</li></ul>
<p>这些文件,不过,最重要的其实是创建 /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow
还有用户家目录就是了~所以,如果你了解整个系统运作的状态,也是可以手动直接修改这几个文件就是了。
OK!帐号创建了,接下来处理一下用户的密码吧!</p>
<a id="passwd"></a>
<ul class="toplist"><li>passwd</li></ul>
<p>刚刚我们讲到了,使用 useradd 创建了帐号之后,在缺省的情况下,该帐号是暂时被封锁的,
也就是说,该帐号是无法登录的,你可以去瞧一瞧 /etc/shadow 内的第二个字段就晓得啰~
那该如何是好?怕什么?直接给他设置新密码就好了嘛!对吧~设置密码就使用 passwd 啰!</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">passwd [--stdin] [帐号名称]</span> <span class="term_note"><==所有人均可使用来改自己的密码</span>
[root@study ~]# <span class="term_command">passwd [-l] [-u] [--stdin] [-S] \</span>
> <span class="term_command">[-n 日数] [-x 日数] [-w 日数] [-i 日数] 帐号</span> <span class="term_note"><==root 功能</span>
<span class="term_say">选项与参数:
--stdin :可以透过来自前一个管线的数据,作为密码输入,对 shell script 有帮助!
-l :是 Lock 的意思,会将 /etc/shadow 第二栏最前面加上 ! 使密码失效;
-u :与 -l 相对,是 Unlock 的意思!
-S :列出密码相关参数,亦即 shadow 文件内的大部分信息。
-n :后面接天数,shadow 的第 4 字段,多久不可修改密码天数
-x :后面接天数,shadow 的第 5 字段,多久内必须要更动密码
-w :后面接天数,shadow 的第 6 字段,密码过期前的警告天数
-i :后面接天数,shadow 的第 7 字段,密码失效天数</span>
<span class="term_hd">范例一:请 root 给予 vbird2 密码</span>
[root@study ~]# <span class="term_command">passwd vbird2</span>
Changing password for user vbird2.
New UNIX password: <span class="term_note"><==这里直接输入新的密码,屏幕不会有任何反应</span>
BAD PASSWORD: The password is shorter than 8 characters <span class="term_note"><==密码太简单或过短的错误!</span>
Retype new UNIX password: <span class="term_note"><==再输入一次同样的密码</span>
passwd: all authentication tokens updated <span class="term_write">successfully</span>. <span class="term_note"><==竟然还是成功修改了!</span>
</pre></td></tr></tbody></table>
<p>root 果然是最伟大的人物!当我们要给予用户密码时,透过 root 来设置即可。
root 可以设置各式各样的密码,系统几乎一定会接受!所以您瞧瞧,如同上面的范例一,明明鸟哥输入的密码太短了,
但是系统依旧可接受 vbird2 这样的密码设置。这个是 root 帮忙设置的结果,那如果是用户自己要改密码呢?
包括 root 也是这样修改的喔!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例二:用 vbird2 登录后,修改 vbird2 自己的密码</span>
[vbird2@study ~]$ <span class="term_command">passwd</span> <span class="term_note"><==后面没有加帐号,就是改自己的密码!</span>
Changing password for user vbird2.
Changing password for vbird2
(current) UNIX password: <span class="term_note"><==这里输入『原有的旧密码』</span>
New UNIX password: <span class="term_note"><==这里输入新密码</span>
BAD PASSWORD: The password is shorter than 8 characters <span class="term_note"><==密码太短!不可以设置!重新想</span>
New password: <span class="term_note"><==这里输入新想的密码</span>
BAD PASSWORD: The password fails the dictionary check - it is based on a dictionary word
<span class="term_note"># 同样的,密码设置在字典里面找的到该字符串,所以也是不建议!无法通过,再想新的!</span>
New UNIX password: <span class="term_note"><==这里再想个新的密码来输入吧</span>
Retype new UNIX password: <span class="term_note"><==通过密码验证!所以重复这个密码的输入</span>
passwd: all authentication tokens updated <u>successfully</u>. <span class="term_note"><==有无成功看关键字</span>
</pre></td></tr></tbody></table>
<p>passwd 的使用真的要很注意,尤其是 root 先生啊!鸟哥在课堂上每次讲到这里,说是要帮自己的一般帐号创建密码时,
有一小部分的学生就是会忘记加上帐号,结果就变成改变 root 自己的密码,最后.... root 密码就这样不见去!唉~
<span class="text_import2">要帮一般帐号创建密码需要使用『 passwd 帐号 』的格式,使用『
passwd 』表示修改自己的密码</span>!拜托!千万不要改错!</p>
<p>与 root 不同的是,一般帐号在更改密码时需要先输入自己的旧密码 (亦即 current 那一行),然后再输入新密码 (New 那一行)。
要注意的是,密码的规范是非常严格的,尤其新的 distributions 大多使用 PAM 模块来进行密码的检验,包括太短、
密码与帐号相同、密码为字典常见字符串等,都会被 PAM 模块检查出来而拒绝修改密码,此时会再重复出现『 New 』这个关键字!
那时请再想个新密码!若出现『 Retype 』才是你的密码被接受了!重复输入新密码并且看到『 successfully
』这个关键字时才是修改密码成功喔!</p>
<fieldset class="vbirdface"><legend style="font-family: serif; font-size:12pt; color: darkblue;">Tips</legend><img src="./vbird_files/vbird_face.gif" alt="鸟哥的图标" title="鸟哥的图标" style="float: right;"> 与一般用户不同的是, root 并不需要知道旧密码就能够帮用户或 root 自己创建新密码!
但如此一来有困扰~就是如果你的亲密爱人老是告诉你『我的密码真难记,帮我设置简单一点的!』时,
千万不要妥协啊!这是为了系统安全...
</fieldset><br>
<p>为何用户要设订自己的密码会这么麻烦啊?这是因为密码的安全性啦!如果密码设置太简单,
一些有心人士就能够很简单的猜到你的密码,如此一来人家就可能使用你的一般帐号登录你的主机或使用其他主机资源,
对主机的维护会造成困扰的!所以新的 distributions 是使用较严格的 PAM 模块来管理密码,这个管理的机制写在 /etc/pam.d/passwd
当中。而<span class="text_import2">该文件与密码有关的测试模块就是使用:pam_cracklib.so,这个模块会检验密码相关的信息,
并且取代 /etc/login.defs 内的 PASS_MIN_LEN 的设置</span>啦!关于 PAM 我们在本章后面继续介绍,这里先谈一下,
理论上,你的密码最好符合如下要求:</p>
<ul class="text_import2">
<li>密码不能与帐号相同;</li>
<li>密码尽量不要选用字典里面会出现的字符串;</li>
<li>密码需要超过 8 个字符;</li>
<li>密码不要使用个人信息,如身份证、手机号码、其他电话号码等;</li>
<li>密码不要使用简单的关系式,如 1+1=2, Iamvbird 等;</li>
<li>密码尽量使用大小写字符、数字、特殊字符($,_,-等)的组合。</li></ul>
<p>为了方便系统管理,新版的 passwd 还加入了很多创意选项喔!鸟哥个人认为最好用的大概就是这个『 --stdin 』了!
举例来说,你想要帮 vbird2 变更密码成为 abc543CC ,可以这样下达指令呢!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例三:使用 standard input 创建用户的密码</span>
[root@study ~]# <span class="term_command">echo "abc543CC" | passwd --stdin vbird2</span>
Changing password for user vbird2.
passwd: all authentication tokens updated successfully.
</pre></td></tr></tbody></table>
<p>这个动作会直接更新用户的密码而不用再次的手动输入!好处是方便处理,缺点是这个密码会保留在指令中,
未来若系统被攻破,人家可以在 /root/.bash_history 找到这个密码呢!所以这个动作通常仅用在 shell script
的大量创建用户帐号当中!要注意的是,这个选项并不存在所有 distributions 版本中,
请使用 man passwd 确认你的 distribution 是否有支持此选项喔!</p>
<p>如果你想要让 vbird2 的密码具有相当的规则,举例来说你要让 vbird2 每 60 天需要变更密码,
密码过期后 10 天未使用就声明帐号失效,那该如何处理?</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例四:管理 vbird2 的密码使具有 60 天变更、密码过期 10 天后帐号失效的设置</span>
[root@study ~]# <span class="term_command">passwd -S vbird2</span>
vbird2 PS 2015-07-20 0 99999 7 -1 (Password set, SHA512 crypt.)
<span class="term_say"># 上面说明密码创建时间 (2015-07-20)、0 最小天数、99999 变更天数、7 警告日数与密码不会失效 (-1)</span>
[root@study ~]# <span class="term_command">passwd -x 60 -i 10 vbird2</span>
[root@study ~]# <span class="term_command">passwd -S vbird2</span>
vbird2 PS 2015-07-20 0 <span class="term_write">60</span> 7 <span class="term_write">10</span> (Password set, SHA512 crypt.)
</pre></td></tr></tbody></table>
<p>那如果我想要让某个帐号暂时无法使用密码登录主机呢?举例来说, vbird2 这家伙最近老是胡乱在主机乱来,
所以我想要暂时让她无法登录的话,最简单的方法就是让她的密码变成不合法 (shadow 第 2 字段长度变掉)!
处理的方法就更简单的!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例五:让 vbird2 的帐号失效,观察完毕后再让她失效</span>
[root@study ~]# <span class="term_command">passwd -l vbird2</span>
[root@study ~]# <span class="term_command">passwd -S vbird2</span>
vbird2 <span class="term_write">LK</span> 2015-07-20 0 60 7 10 (<span class="term_write">Password locked</span>.)
<span class="term_say"># 嘿嘿!状态变成『 LK, Lock 』了啦!无法登录喔!</span>
[root@study ~]# <span class="term_command">grep vbird2 /etc/shadow</span>
vbird2:<span class="term_write">!!</span>$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10::
<span class="term_say"># 其实只是在这里加上 !! 而已!</span>
[root@study ~]# <span class="term_command">passwd -u vbird2</span>
[root@study ~]# <span class="term_command">grep vbird2 /etc/shadow</span>
vbird2:$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10::
<span class="term_say"># 密码字段恢复正常!</span>
</pre></td></tr></tbody></table>
<p>是否很有趣啊!您可以自行管理一下你的帐号的密码相关参数喔!接下来让我们用更简单的方法来查阅密码参数喔!</p>
<a id="chage"></a>
<ul class="toplist"><li>chage</li></ul>
<p>除了使用 passwd -S 之外,有没有更详细的密码参数显示功能呢?有的!那就是 chage 了!他的用法如下:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">chage [-ldEImMW] 帐号名</span>
<span class="term_say">选项与参数:
-l :列出该帐号的详细密码参数;
-d :后面接日期,修改 shadow 第三字段(最近一次更改密码的日期),格式 YYYY-MM-DD
-E :后面接日期,修改 shadow 第八字段(帐号失效日),格式 YYYY-MM-DD
-I :后面接天数,修改 shadow 第七字段(密码失效日期)
-m :后面接天数,修改 shadow 第四字段(密码最短保留天数)
-M :后面接天数,修改 shadow 第五字段(密码多久需要进行变更)
-W :后面接天数,修改 shadow 第六字段(密码过期前警告日期)</span>
<span class="term_hd">范例一:列出 vbird2 的详细密码参数</span>
[root@study ~]# <span class="term_command">chage -l vbird2</span>
Last password change : Jul 20, 2015
Password expires : Sep 18, 2015
Password inactive : Sep 28, 2015
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 60
Number of days of warning before password expires : 7
</pre></td></tr></tbody></table>
<p>我们在 <a href="0410accountmanager.html#passwd">passwd</a> 的介绍中谈到了处理 vbird2 这个帐号的密码属性流程,使用 passwd -S
却无法看到很清楚的说明。如果使用 chage 那可就明白多了!如上表所示,我们可以清楚的知道 vbird2 的详细参数呢!
如果想要修改其他的设置值,就自己参考上面的选项,或者自行 man chage 一下吧!^_^</p>
<p>chage 有一个功能很不错喔!如果你想要让『<span class="text_import2">用户在第一次登录时,
强制她们一定要更改密码后才能够使用系统资源</span>』,可以利用如下的方法来处理的!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例二:创建一个名为 agetest 的帐号,该帐号第一次登录后使用缺省密码,但必须要更改过密码后,
使用新密码才能够登录系统使用 bash 环境</span>
[root@study ~]# <span class="term_command">useradd agetest</span>
[root@study ~]# <span class="term_command">echo "agetest" | passwd --stdin agetest</span>
[root@study ~]# <span class="term_command">chage -d 0 agetest</span>
[root@study ~]# <span class="term_command">chage -l agetest | head -n 3</span>
Last password change : password must be changed
Password expires : password must be changed
Password inactive : password must be changed
<span class="term_say"># 此时此帐号的密码创建时间会被改为 1970/1/1 ,所以会有问题!</span>
<span class="term_hd">范例三:尝试以 agetest 登录的情况</span>
You are required to change your password immediately (root enforced)
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user agetest.
Changing password for agetest
(current) UNIX password: <span class="term_note"><==这个帐号被强制要求必须要改密码!</span>
</pre></td></tr></tbody></table>
<p>非常有趣吧!你会发现 agetest 这个帐号在第一次登录时可以使用与帐号同名的密码登录,
但登录时就会被要求立刻更改密码,更改密码完成后就会被踢出系统。再次登录时就能够使用新密码登录了!
这个功能对学校老师非常有帮助!因为我们不想要知道学生的密码,那么在初次上课时就使用与学号相同的帐号/密码给学生,
让她们登录时自行设置她们的密码,如此一来就能够避免其他同学随意使用别人的帐号,也能够保证学生知道如何更改自己的密码!</p>
<a id="usermod"></a>
<ul class="toplist"><li>usermod</li></ul>
<p>所谓这『人有失手,马有乱蹄』,您说是吧?所以啰,当然有的时候会『不小心手滑了一下』在 useradd
的时候加入了错误的设置数据。或者是,在使用 useradd 后,发现某些地方还可以进行细部修改。
此时,当然我们可以直接到 /etc/passwd 或 /etc/shadow 去修改相对应字段的数据,
不过,Linux 也有提供相关的指令让大家来进行帐号相关数据的微调呢~那就是 usermod 啰~</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">usermod [-cdegGlsuLU] username</span>
<span class="term_say">选项与参数:
-c :后面接帐号的说明,即 /etc/passwd 第五栏的说明栏,可以加入一些帐号的说明。
-d :后面接帐号的家目录,即修改 /etc/passwd 的第六栏;
-e :后面接日期,格式是 YYYY-MM-DD 也就是在 /etc/shadow 内的第八个字段数据啦!
-f :后面接天数,为 shadow 的第七字段。
-g :后面接初始群组,修改 /etc/passwd 的第四个字段,亦即是 GID 的字段!
-G :后面接次要群组,修改这个用户能够支持的群组,修改的是 /etc/group 啰~
-a :与 -G 合用,可『增加次要群组的支持』而非『设置』喔!
-l :后面接帐号名称。亦即是修改帐号名称, /etc/passwd 的第一栏!
-s :后面接 Shell 的实际文件,例如 /bin/bash 或 /bin/csh 等等。
-u :后面接 UID 数字啦!即 /etc/passwd 第三栏的数据;
-L :暂时将用户的密码冻结,让他无法登录。其实仅改 /etc/shadow 的密码栏。
-U :将 /etc/shadow 密码栏的 ! 拿掉,解冻啦!</span>
</pre></td></tr></tbody></table>
<p>如果你仔细的比对,会发现 usermod 的选项与 <a href="0410accountmanager.html#useradd">useradd</a> 非常类似!
这是因为 usermod 也是用来微调 useradd 增加的用户参数嘛!不过 usermod 还是有添加的选项,
那就是 -L 与 -U ,不过这两个选项其实与 passwd 的 -l, -u 是相同的!而且也不见得会存在所有的
distribution 当中!接下来,让我们谈谈一些变更参数的实例吧!</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例一:修改用户 vbird2 的说明栏,加上『VBird's test』的说明。</span>
[root@study ~]# <span class="term_command">usermod -c "VBird's test" vbird2</span>
[root@study ~]# <span class="term_command">grep vbird2 /etc/passwd</span>
vbird2:x:1500:100:<span class="term_write">VBird's test</span>:/home/vbird2:/bin/bash
<span class="term_hd">范例二:用户 vbird2 这个帐号在 2015/12/31 失效。</span>
[root@study ~]# <span class="term_command">usermod -e "2015-12-31" vbird2</span>
[root@study ~]# <span class="term_command">chage -l vbird2 | grep 'Account expires'</span>
Account expires : Dec 31, 2015
<span class="term_hd">范例三:我们创建 vbird3 这个系统帐号时并没有给予家目录,请创建他的家目录</span>
[root@study ~]# <span class="term_command">ll -d ~vbird3</span>
ls: cannot access /home/vbird3: No such file or directory <span class="term_note"><==确认一下,确实没有家目录的存在!</span>
[root@study ~]# <span class="term_command">cp -a /etc/skel /home/vbird3</span>
[root@study ~]# <span class="term_command">chown -R vbird3:vbird3 /home/vbird3</span>
[root@study ~]# <span class="term_command">chmod 700 /home/vbird3</span>
[root@study ~]# <span class="term_command">ll -a ~vbird3</span>
drwx------. 3 vbird3 vbird3 74 May 4 17:51 . <span class="term_note"><==用户家目录权限</span>
drwxr-xr-x. 10 root root 4096 Jul 20 22:51 ..
-rw-r--r--. 1 vbird3 vbird3 18 Mar 6 06:06 .bash_logout
-rw-r--r--. 1 vbird3 vbird3 193 Mar 6 06:06 .bash_profile
-rw-r--r--. 1 vbird3 vbird3 231 Mar 6 06:06 .bashrc
drwxr-xr-x. 4 vbird3 vbird3 37 May 4 17:51 .mozilla
<span class="term_say"># 使用 chown -R 是为了连同家目录底下的用户/群组属性都一起变更的意思;
# 使用 chmod 没有 -R ,是因为我们仅要修改目录的权限而非内部文件的权限!</span>
</pre></td></tr></tbody></table>
<a id="userdel"></a>
<ul class="toplist"><li>userdel</li></ul>
<p>这个功能就太简单了,目的在删除用户的相关数据,而用户的数据有:</p>
<ul class="text_import2" style="font-family:'细明体'">
<li>用户帐号/密码相关参数:/etc/passwd, /etc/shadow</li>
<li>用户群组相关参数:/etc/group, /etc/gshadow</li>
<li>用户个人文件数据: /home/username, /var/spool/mail/username..</li>
</ul>
<p>整个指令的语法非常简单:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">userdel [-r] username</span>
<span class="term_say">选项与参数:
-r :连同用户的家目录也一起删除</span>
<span class="term_hd">范例一:删除 vbird2 ,连同家目录一起删除</span>
[root@study ~]# <span class="term_command">userdel -r vbird2</span>
</pre></td></tr></tbody></table>
<p>这个指令下达的时候要小心了!通常我们要移除一个帐号的时候,你可以手动的将 /etc/passwd 与 /etc/shadow
里头的该帐号取消即可!一般而言,如果该帐号只是『<span class="text_import2">暂时不启用</span>』的话,那么将
/etc/shadow 里头帐号失效日期 (第八字段) 设置为 0 就可以让该帐号无法使用,但是所有跟该帐号相关的数据都会留下来!
使用 userdel 的时机通常是『<span class="text_import2">你真的确定不要让该用户在主机上面使用任何数据了</span>!』</p>
<p>另外,其实用户如果在系统上面操作过一阵子了,那么该用户其实在系统内可能会含有其他文件的。
举例来说,他的邮件信箱 (mailbox) 或者是<a href="0430cron.html">例行性工作调度 (crontab, 十五章)</a> 之类的文件。
所以,如果想要完整的将某个帐号完整的移除,最好可以在下达 userdel -r username 之前,
先以『 find / -user username 』查出整个系统内属于 username 的文件,然后再加以删除吧!</p>
<br></div><br>
<a id="normal_user"></a>
<div class="block2"><div class="gototop"><a href="0410accountmanager.html#top">Top</a></div>
<h2>13.2.2 用户功能</h2>
<p>不论是 useradd/usermod/userdel ,那都是系统管理员所能够使用的指令,
如果我是一般身份用户,那么我是否除了密码之外,就无法更改其他的数据呢?
当然不是啦!这里我们介绍几个一般身份用户常用的帐号数据变更与查找指令啰!</p>
<a id="id"></a>
<ul class="toplist"><li>id</li></ul>
<p>id 这个指令则可以查找某人或自己的相关 UID/GID 等等的信息,他的参数也不少,不过,都不需要记~反正使用 id 就全部都列出啰!
另外,也回想一下,我们在前一章谈到的循环时,就有用过这个指令喔! ^_^</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">id [username]</span>
<span class="term_hd">范例一:查阅 root 自己的相关 ID 信息!</span>
[root@study ~]# <span class="term_command">id</span>
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:
s0-s0:c0.c1023
<span class="term_say"># 上面信息其实是同一行的数据!包括会显示 UID/GID 以及支持的所有群组!
# 至于后面那个 context=... 则是 SELinux 的内容,先不要理会他!</span>
<span class="term_hd">范例二:查阅一下 vbird1 吧~</span>
[root@study ~]# <span class="term_command">id vbird1</span>
uid=1003(vbird1) gid=1004(vbird1) groups=1004(vbird1)
[root@study ~]# <span class="term_command">id vbird100</span>
id: vbird100: No such user <span class="term_note"><== id 这个指令也可以用来判断系统上面有无某帐号!</span>
</pre></td></tr></tbody></table>
<a id="finger"></a>
<ul class="toplist"><li>finger</li></ul>
<p>finger 的中文本面意义是:『手指』或者是『指纹』的意思。这个 finger 可以查阅很多用户相关的信息喔!
大部分都是在 /etc/passwd 这个文件里面的信息啦!不过,这个指令有点危险,所以新的版本中已经缺省不安装这个软件!
好啦!现在继续来安装软件先~记得<a href="0310vi.html#tips_dos">第九章 dos2unix</a> 的安装方式!
假设你已经将光驱或光盘映像档挂载在 /mnt 底下了,所以:</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">df -hT /mnt</span>
Filesystem Type Size Used Avail Use% Mounted on
/dev/sr0 iso9660 7.1G 7.1G 0 100% /mnt <span class="term_note"># 先确定是有挂载光盘的啦!</span>
[root@study ~]# <span class="term_command">rpm -ivh /mnt/Packages/finger-[0-9]*</span>
</pre></td></tr></tbody></table>
<p>我们就先来检查检查用户信息吧!</p>
<table class="term"><tbody><tr><td class="term"><pre>[root@study ~]# <span class="term_command">finger [-s] username</span>
<span class="term_say">选项与参数:
-s :仅列出用户的帐号、全名、终端机代号与登录时间等等;
-m :列出与后面接的帐号相同者,而不是利用部分比对 (包括全名部分)</span>
<span class="term_hd">范例一:观察 vbird1 的用户相关帐号属性</span>
[root@study ~]# <span class="term_command">finger vbird1</span>
Login: vbird1 Name:
Directory: /home/vbird1 Shell: /bin/bash
Never logged in.
No mail.
No Plan.
</pre></td></tr></tbody></table>
<p>由于 finger 类似指纹的功能,他会将用户的相关属性列出来!如上表所示,其实他列出来的几乎都是 /etc/passwd 文件里面的东西。列出的信息说明如下:</p>
<ul>
<li>Login:为用户帐号,亦即 /etc/passwd 内的第一字段;</li>
<li>Name:为全名,亦即 /etc/passwd 内的第五字段(或称为注解);</li>
<li>Directory:就是家目录了;</li>
<li>Shell:就是使用的 Shell 文件所在;</li>
<li>Never logged in.:figner 还会调查用户登录主机的情况喔!</li>
<li>No mail.:调查 /var/spool/mail 当中的信箱数据;</li>
<li>No Plan.:调查 ~vbird1/.plan 文件,并将该文件取出来说明!</li>
</ul>
<p>不过是否能够查阅到 Mail 与 Plan 则与权限有关了!因为 Mail / Plan 都是与用户自己的权限设置有关,
root 当然可以查阅到用户的这些信息,但是 vbird1 就不见得能够查到 vbird3 的信息,
因为 /var/spool/mail/vbird3 与 /home/vbird3/ 的权限分别是 660, 700 ,那 vbird1 当然就无法查阅的到!
这样解释可以理解吧?此外,我们可以创建自己想要运行的预定计划,当然,最多是给自己看的!可以这样做:</p>
<table class="term"><tbody><tr><td class="term"><pre><span class="term_hd">范例二:利用 vbird1 创建自己的计划档</span>
[vbird1@study ~]$ <span class="term_command">echo "I will study Linux during this year." > ~/.plan</span>
[vbird1@study ~]$ <span class="term_command">finger vbird1</span>
Login: vbird1 Name:
Directory: /home/vbird1 Shell: /bin/bash
Last login Mon Jul 20 23:06 (CST) on pts/0