玩Linux五年積累的技巧(1) -- 文件的屬性
本文主要介紹了文件的隱藏屬性和特殊權限,一個讓腳本具有類似SUID位的技巧,還有一個解決mp3文件亂碼的方法。 www.2cto.com
作者 JH Gao
從最開始接觸Linux到現在已經有5年了,和所有人一樣,少不了折騰。折騰後偶爾我會把方法記錄下來,現在簡單總結一下。
所以的命令功能通過man都能找到具體用法,我只把自己覺得常用的列舉出來。
1. 文件的隱藏屬性
www.2cto.com
lsattr : 列出文件的隱藏屬性
chattr : 修改文件的隱藏屬性
[plain]
[root@www ~]# chattr [+-=][ASacdistu] FileName
+ : Add one attribute
- : Remove one attribute
= : Set to be the only attributes that the files have
重要選項
"a":只能追加文件的內容,但不能修改或刪除內容
"i":文件不能被刪除、改名、不能創建指向它的鏈接,不能向文件寫內容
2. 文件的特殊權限 SUID/SGID/Sticky Bit
如果對一個可執行文件設置了SUID或者SGID位,則文件執行時,將會擁有文件所有者(設置了SUID)或者所在組(設置了SGID)的權限。
例子:普通用戶不能開啟httpd服務,因為httpd服務需要用到80端口,而1024以下的端口只有root用戶才能使用。如果我們把httpd可執行文件的所有者設置為root,同時設置SUID位,則普通用戶也可以開啟httpd服務了。
對一個目錄設置了Sticky位,則只有文件的所有者能刪除這個文件。在Linux系統中,/tmp目錄默認設置了這個位:
[plain]
drwxrwxrwt 12 root root 16384 Mar 6 09:04 tmp/
主要使用方法如下:
[plain]
SUID
對於文件:以文件所有者的權限運行
對於目錄:不能對目錄設置SUID
設置SUID:
chmod u+s FILE chmod 4755 FILE
SGID
對於文件:以文件所屬組的權限運行
對於目錄:目錄裡面的文件會繼承目錄的屬性
設置SGID:
chmod g+s FILE/DIR chmod 2771 FILE/DIR
Sticky
對於文件:不能對文件設置Sticky位
對於目錄:對於該目錄下的文件,只有它們的所有者才能刪除它們。
設置Sticky:
chmod o+t DIR chmod 1777 DIR
用字母設置特殊權限:
u+s g+s o+t
用數字表示特殊權限,則是:
4 for SUID
2 for SGID
1 for Sticky
需要注意的是,shell、python、perl等腳本文件不能設置SUID位,因為它們事實上是由bash、python、perl解釋器解釋運行的。要讓腳本文件也有類似於SUID這樣的功能,需要做一點小花招。
簡單地說,我們需要一層殼,這層殼可以設置SUID/SGID位,殼裡面真正工作的還是腳本。
比如說我們有一個腳本/home/jh/bin/myscript.sh,所有者是普通用戶,但腳本裡面的操作需要root權限,現在我們用C語言來寫這層殼,名稱叫做transeuid.c:
[cpp]
/* author: JH Gao
# Create Date: 2012-06-05
# Function: transmit euid and egid to other scripts
# since shell/python/... scripts can't get suid permission in Linux
# ******************************************************************** */
#include
#include
#include
#define BUFFSIZE 1024
/*
* usually euid is the uid who run the program
* but when stick is setted to the program
* euid is the uid or the program's owner
*/
int main(int argc, char *argv[]) {
char *cmd = "/home/jh/bin/myscript.sh";
char *pars[] = {"/home/jh/bin/myscript.sh", "par1", "par2"};
// set uid and gid to euid and egid
setuid(geteuid());
setgid(getegid());
if (execvp(cmd, pars)) {
printf("error");
free(cmd);
exit(1);
}
free(cmd);
}
編譯這個程序,在給這個程序設置希望取得的用戶,再設置suid,然後就可以用這個用戶的權限執行腳本或命令了:
[plain]
$ gcc -t transeuid transeuid.c
$ sudo chown root transeuid
$ sudo chmod +s transeuid
$ ./transeuid
......DO SOMETHING
當然具體要執行的腳本和參數可以從外部獲取,具體看我以前寫的:《傳遞euid和egid給腳本,使腳本具有特殊用戶的權限》。下文:
-------------------------------------------------------
傳遞euid和egid給腳本,使腳本具有特殊用戶的權限
使腳本實現類似於設置了stick位的效果
www.2cto.com
作者:高鵬 <
[email protected]>
shell, python, perl等腳本、程序不能取得suid,因為這些腳本程序需要解釋器-/bin/bash, /usr/bin/python等來執行,而這些解釋器本身沒有suid也不方便設置suid。碰到這種情況可以用c寫一個外殼,對這個外殼設置suid,而在c程序裡面把自身的uid,gid傳遞給實際執行任務的腳本。(這個方法是在讀周鵬(Roc Zhou <
[email protected]>)寫的工具時學到的)
www.2cto.com
c程序如下:
C代碼
/* # ScriptName: transeuid.c
# Author: JH Gao <
[email protected]>
# Create Date: 2012-06-05
# Function: transmit euid and egid to other scripts
# since shell/python/... scripts can't get suid permission in Linux
# usage: transeuid xxx.sh par1 par2 par3
# xxx.sh will get the euid and egid from transeuid
# ******************************************************************** */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFSIZE 1024
/*
* usually euid is the uid who run the program
* but when stick is setted to the program
* euid is the uid or the program's owner
*/
int main(int argc, char *argv[]) {
char *cmd = malloc(BUFFSIZE);
// set uid and gid to euid and egid
setuid(geteuid());
setgid(getegid());
cmd = argv[1];
int i = 0;
for(i = 0;i < argc - 1;i++) {
argv[i] = argv[i+1];
}
argv[argc-1] = NULL
// search $PATH find this cmd and run it with pars:argv
if (execvp(cmd, argv)) {
printf("error");
free(cmd);
exit(1);
}
free(cmd);
}
編譯這個程序,在給這個程序設置希望取得的用戶,再設置suid,然後就可以用這個用戶的權限執行腳本或命令了:
Shell代碼
$ gcc -t transeuid transeuid.c
$ sudo chown root transeuid
$ sudo chmod +s transeuid
$ ./transeuid ls /root /home
/home:
. .. data .directory gp_old jh jh_old lost+found
/root:
. .. .bash_history .bashrc .cache .dbus .profile .pulse .pulse-cookie .viminfo
-------------------------------------------------------------------------------------------------
但是需要注意的是,這種花招有很大的安全隱患。
3. 最後Linux中解決mp3文件亂碼的命令是:
[plain]
find . iname "*.mp3" -execdir mid3iconv -e gbk --remove-v1 {} \;