本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fbysss/archive/2010/07/26/5767148.aspx
之前的开发服务器,所有人都是用root账号登录,一开始,用起来确是很爽很自由,也没发现什么问题。但逐渐的,几次莫名的文件丢失、数据库无法正常启动的问题,使得权限管理问题成为亟待解决的任务。实际上,仅仅是一个简单的reboot、shutdown或者是rm命令,破坏性是非常大的。而且,误操作的人也不好定位。root只能掌握在少数人手中。
一、团队构建环境,文件读写共享
项目代码位于/svn/prj下,通过svn up更新代码,调用ant来编译、部署。那么,prj这个目录,对于每个人都是需要可读写的。
我们知道,用什么用户登录,新创建的文件宿主,就是当前用户。而默认的文件权限是644(-rw-r--r--),张三从代码仓库中update的文件,或者编译后生成的class文件,李四是没法删除的。执行ant clear必然不成功,每次都用chmod去修改相应文件,总不是个事,那怎么办呢?
目标很明确:我们希望,开发团队中,每一个开发人员之间的权限是平等的,谁新建的文件都可以被其他人读写。
分解出来是两个事情:
1.目录/svn/prj应该属于开发团队,即一个用户组。这很简单,建立一个组,比如叫dev,使用chown即可
#gruopadd dev
#useradd zhangshan
#useradd lisi
#useradd zhangsan -G dev -g dev
#useradd lisi -G dev -g dev
#chown -R :dev /svn/prj
这里要特别说明一下,-g和-G是有区别的。-G是大家自然理解的,把一个用户加到一个组或者多个组(逗号分隔)里面去。-g呢,则是
设置用户的gid。也就是用户登陆后初始group(initial group)。
使用id zhangsan命令,可以看到,uid=zhangsantest,gid=dev,groups=zhangsan,dev。或者使用groups zhangsan,结果是zhangsan dev
要注意,创建一个用户,默认会创建一个同名的组,如果不加-g参数,gid就是那个组的id,新建文件,组属也是用户同名组。所以在这里,-g和-G都是缺一不可的。
2.更改文件创建的默认权限为664(-rw-rw-r--)。
这里涉及到一个知识,就是umask,umask主要用来控制默认创建文件或目录的权限。可以使用umask命令直接修改。在我们的linux环境中,默认的umask是022。
umask:设置哪位为1,则哪位就没有权限。放开哪位,哪位有权限。但文件例外,最高到666(默认没有执行权限)。目录则可以到777
比如设置umask为022,则目录最高可以到755,umask为002,则最高目录可以到775
解决思路:每个用户登录都会执行一些初始化脚本,可以在脚本中修改用户的umask。
脚本片段如下:
USERGROUP=`/usr/bin/id -Gn $USER`
echo $USERGROUP | grep -q dev
if [ $? -eq 0 ]; then
umask 0002
fi
意思很简单,这里不赘述。要注意的是,Linux中,应该放在/etc/bashrc里面,而不是/etc/profile中。
登录shell配置文件执行顺序
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
我们应该把这个设置放在最后执行的文件/etc/bashrc的末尾位置,以防止设置被覆盖(实际上,linux的/etc/bashrc文件开头就有一段类似的umask设置)。
要说明一点:控制用户对某个目录的默认读写权限,是没有直接支持的。在实际中,暂时也没必要,如果真有特殊需要,可以通过crontab设置监控进程定时进行修改,也很简单,在此不做说明。
二、普通用户的特权身份
OK,在第一部分中,我们解决了多人文件共享读写,该运行服务器了。不就是tomcat吗,startup一下。事情没想象那么简单,Tomcat运行过程中,会写日志文件,一开始,简单的把logs目录组属划分给dev,但后来陆续又遇到一系列不同的权限问题。于是反思一下:与其一点点修改运行Tomcat涉及的那么多文件权限,不如把自己身份临时换一下?这就是我们要说的sudo。
sudo命令就是sudoer用来执行root操作的。sudoer配置,通过visudo来编辑。
visudo实际上就是vi /etc/sudoers的包装版。但用这个命令的最大好处是,它有语法检查。
%dev ALL =NOPASSWORD: /usr/local/tomcat/bin/startup.sh
%dev ALL =NOPASSWORD: /usr/local/tomcat/bin/shutdown.sh
百分号表示组,如果是多个组,用%dev,%dev2
ALL为所有主机。如果要指定主机,可换成某个ip地址。
NOPASSWORD表示不需要sudoer输入密码。
最后为授权执行的命令全路径。
sudoer的配置还有很多,比如可以设置别名等,请读者自行学习。
执行:组员只需要在原有命令前面加上sudo 即可。
如此一来,Tomcat停启问题也解决了。
补充:sudo命令通配符的设置,如果某个目录下的所有命令都可以给sudoers开放,可以使用xxxx/*.sh,但这样一来,使用者必须使用绝对路径执行。而在当前路径也不能使用./xxx.sh。是何原因,待研究。
三、sftp用户的umask设置
似乎万事大吉了。但有一天,发现还是有一些文件没有权限覆盖,为什么呢?后来发现这部分文件,都是使用winscp上传的。
解决办法:
vi /etc/ssh/sshd_config文件,找到SubSystem sftp /usr/libexec/openssh/sftp-server这一行,修改为
SubSystem sftp /usr/libexec/openssh/sftp-server.sh
然后vi /usr/libexec/openssh/sftp-server.sh
添加
umask 0002
/usr/libexec/openssh/sftp-server
chmod 755 /usr/libexec/openssh/sftp-server.sh 即可。
当然,umask 0002这行可以跟上面的策略一致
变成
USERGROUP=`/usr/bin/id -Gn $USER`
echo $USERGROUP | grep -q developers
if [ $? -eq 0 ]; then
umask 0002
fi
四、NFS文件设置问题
A、B 两台服务器,A为NFS服务器,B为挂载服务器。开发中,发现这个目录老是出现权限问题。但查看组属又没什么问题。甚是奇怪。
具体事例:
一个NFS的源路径,比如是hostA:/share,该目录在hostA上的属于用户组dev,hostB mount了这个目录,看到该目录用户组是一个组号,比如105,其实就是hostA上的dev用户组号。但这个组号,在hostB上并不存在(hostB上也有一个dev组),如何让hostB上的用户也能读写该目录?最后,终于发现症结所在:两边的组号不一致,而文件的拥有者和组属,本质是认id不认name的。修改了哪边,都会让另一边无法写,产生了冲突。
解决办法:把两边的组号修改为一致。
1.首先,保证hostB上没有105号的组,如果有,则需要协调一个两边都不产生冲突的组号,可能需要修改两边的组号。
2.组号确定之后,假设105就行,在hostB上执行:groupmod –g 105 dev。变化可以通过/etc/group查看
3.重新设置改组涉及到的文件的组属。
4.属于该组的用户需要重新登录,这样才会生效。
五、root用户的行为限制
权限问题中,还有root的滥用。如果使用root来编译部署,root产生的文件,dev用户又无权访问了。也就是说,既然已经划分好了小组构建目录,每个用户都应该是dev组成员才对。root用户应该只在授权或普通用户无法解决的时候,再切换使用。