본문으로 바로가기

웹서비스를 위한 퍼미션 문제

category 리눅스/Linux 일반 2013.09.07 15:18

워드프레스를 설치하다가 config.php 파일을 생성할 수 없다(쓰기 권한이 없어서)는 에러를 접하게 되곤 합니다. 대부분 이와 같은 경우, config.sample.php 파일을 복사해서 수정해서 쓰곤 합니다.

왜 이런 현상이 나타나는지에 궁금증이 생겨 이에 대해 파헤쳐 보기로 했습니다.

전반적인 문제

이 문제는 Apache와 PHP의 파일생성 권한과 연관되어 있다. Apache의 데몬실행 권한은 Apache 설정파일에 설정되어 있는데 우분투의 경우는 www-data이고 기타 다른 배포판에서는 nobody, 혹은 apache로 명명되어 있다(설명을 위해 우분투의 www-data를 기준으로 한다).

이말인즉, 서버에서 웹서비스를 구동할때 그 웹사이트를 구동하는 Owner(소유주)가 서버계정의 소유주가 아니라 Apache의 www-data가 된다는 것이다.

이로인해 PHP를 실행하게 되는 소유주 또한 www-data이기에 PHP를 이용해 파일을 생성하게 되는 경우, 예를들어 fopen을 이용한 파일생성, 업로드를 통해 생성되는 파일등의 소유주가 www-data가 된다.

개념의 혼동이 좀 올 수가 있는데, 한가지 예를 들어보자.

  • 홈디렉토리 경로 : /home/unclepapa/public_html
  • 홈디렉토리 권한 : drwxr-xr-x 6 unclepapa unclepapa

일반적으로 위와 같이 사용자(unclepapa)가 디렉토리에 대한 소유자이며 그룹사용자이다.
디렉토리 퍼미션은 755 로 일반적으로 권장되는 퍼미션이다.(umask 022)

위와 같은 디렉토리에서 서비스되는 웹페이지는 원래 uncelpapa의 권한으로 서비스가 되어야 하지만 보안과 모종의 이유로 이를 www-data로 실행하게 되는 것이다.

계정의 소유주와 퍼미션이 서버에 이미 정해져 있기에 www-data가 파일을 생성할때 퍼미션 755의 마지막 5(Other)의 권한으로 실행되기에 쓰기 권한이 없다는 오류를 접하게 되는 것이다. 이로인해 국내의 XE보드, 그누보드등이 설치시에 설치디렉토리의 퍼미션을 777 혹은 707을 요구하게 된다.

또한 이렇게 PHP등을 이용해 생성하게 되는 파일들의 소유권은 아래와 같이 www-data:www-data 가 된다.

rwxr--r-- www-data www-data  config.php

위와 같이 생성된 파일들은 퍼미션이 644로 이 파일의 소유권자(www-data)만이 이를 수정/삭제가 가능하기에 서버계정의 소유주 조차도 이 파일에 대한 수정 권한이 없게 된다(Other의 권한뿐이 부여받지 못하기에).

물론, 대부분의 업로드관련 소스들은 umask()chmod()함수로 업로드시에 파일및 디렉토리 퍼미션을 666 / 777 으로 설정하여 Other 권한으로 접근하여 수정할수 있게 하고 있다. 하지만 이 또한 보안상으로 위험을 감수해야 하는 방식이다.

얽힌 실타래 풀기

보안과 편의라는 두가지 시점에서 이를 풀어보자.

보안을 중시한 방법

웹서비스의 홈디렉토리의 소유자를 www-data:www-data 로 변경하는 방법이 있다.

sudo chown -R www-data:www-data /home/unclepapa/public_html

위와 같은 방식은 www-data의 권한을 탈취당해도 www-data가 가진 권한이 매우 적기에 보안상 추천되고 있다. 하지만 이는 FTP 접속에 제한이 될 수 밖에 없는데 계정사용자가 홈디렉토리에 접속해도 소유권이 모두 www-data 이기에 업로드/수정이 불가능하게 된다.

FTP 사용에 편의를 위해서는 어떻게든 디렉토리와 파일의 소유권이 계정사용자를 포함해야 하는데, Owner 값은 id 값으로 중복될 수 없기때문에 www-data 값을 변경할 수는 없다.

Group 값은 중복될 수 있기때문에 www-data의 group에 FTP 계정을 사용할 사용자를 추가할 수 있다.

sudo usermod -a -G www-data unclepapa

이 경우 기본적인 리눅스 umask 값에 의해 디렉토리 퍼미션이 755이기에 umask 값을 002로 변경하여 생성하는 디렉토리나 파일들이 775 / 664의 값을 갖도록 해야 파일의 업로드/수정이 가능해진다.

sudo chmod -R 775 /home/unclepapa/public_html

혹은 umask 값을 수정( 특정사용자의 umask 값을 변경하려면 ~/.bashrc 에 값을 적용)

sudo vi /etc/profile

  umask 002

관리의 편의를 위한 방법

Apache의 모듈중에 mod_ruid2가 있는데 이 모듈은 소유권과 퍼미션 조정을 수월하게 함으로써, 편의를 적용하지만 몇가지 제약사항도 있고 보안상으로 추천하는 방법은 아니다. 오직 리눅스에서만 작동한다.

mod_ruid2는 자바 서블릿이나 jsp에 대한 요청을 제외한 모든 http 요청에 적용된다. 많은 호스팅업체와 서버관리자들은 편의를 위해 이 방법을 사용하곤 한다.

비호환성

mod_ruid2는 복잡한 보안 모델이기에 mod_ruid2와 함께 사용할때 모듈 취약점을 소개한다. mod_ruid2를 활성화할 경우 아래에 언급하는 것들을 사용할수 없게 된다.

option Module Identifier Description
Cache cache_module This module caches content that is keyed to URIs. Local and proxy content can be cached. mod_ruid2 caused problems with the ownership of cache lock files. It may be possible to patch the cache modules or mod_ruid2 to solve the issue, but the patch may introduce security vulnerabilities.
Disk Cache disk_cache_module This module caches content that is keyed to URIs. This module uses disk-based storage management and is usually used with cache_module. mod_ruid2 caused problems with the ownership of cache lock files. It may be possible to patch the cache modules or mod_ruid2 to solve the issue, but the patch may introduce security vulnerabilities.
FastCGI mod_fcgi This module is a language-agnostic extension of CGI that allows Apache to serve PHP faster. When using FastCGI, requests are processed by a separate and persistent process. mod_ruid2 cannot force the processes to change UID or GID based on the domain.
MemCache  mod_mem_cache This module caches content that is keyed to URIs. This module requires the cache_module and provides a memory-based storage management system. mod_ruid2 causes problems with the ownership of cache lock files. It may be possible to patch the cache modules or mod_ruid2 to solve the issue; however, the patch may introduce security vulnerabilities.
MPM Worker

mpm_worker_module This is a multi-processing module that allows Apache to serve additional requests by off-loading processing work to supporting threads. Thread-based MPMs will not work with mod_ruid2, because they alter the UID and GID at the process level.
MPM Event mpm_event_module This module is a variant of the worker MPM that allows Apache to serve additional requests by off-loading processing work to supporting threads. Thread-based MPMs will not work with mod_ruid2, because they alter the UID and GID at the process level.
MPM Leader mpm_leader_module This is an experimental variant of the worker MPM that allows Apache to serve additional requests by off-loading processing work to supporting threads. Thread-based MPMs will not work with mod_ruid2, because they alter the UID and GID at the process level.
MPM Perchild  mpm_perchild_module This is a multi-processing module that allows Apache processes to use different UIDs. Thread-based MPMs will not work with mod_ruid2, because they alter the UID and GID at the process level.
MPM Threadpool  mpm_threadpool_module This module is an experimental variant of the worker MPM that allows Apache to serve additional requests by off-loading processing work to supporting threads. This module queues idle worker threads and passes accepted connections to the next available worker. Thread-based MPMs will not work with mod_ruid2, because they alter the UID and GID at the process level.
Mono  mod_mono This module provides ASP.NET support for Apache 2.0 and 2.2. This applies to .NET 1.x and 2.x. Enabling mod_ruid2 prevents mod_mono from building. We may look into this further if there is sufficient demand.
UserDir mod_userdir The mod_userdir module allows visitors to access a site on your server using the http://example.com/~account syntax. This method of accessing websites causes a conflict with mod_ruid2
ModSecurity mod_security Under heavy load, an AcceptMutex can be held by another UID. This causes ModSecurity to fail and exit, which then causes Apache to crash. We are aware of this issue and are working on a solution. In the meantime, do not use ModSecurity with mod_ruid2.
Tomcat mod_jk The Apache Tomcat Connectors (mod_jk) allow Apache to communicate with Tomcat. There are compatibility issues between mod_jk and mod_ruid2 which cause Tomcat to fail.
설치

아래의 명령어를 한줄씩 입력

sudo apt-get install libcap2-dev
sudo apt-get install apache2-prefork-dev
sudo apt-get install gcc
wget http://downloads.sourceforge.net/project/mod-ruid/mod_ruid2/mod_ruid2-0.9.8.tar.bz2
tar xjf mod_ruid2-0.9.8.tar.bz2
cd mod_ruid2-0.9.8
sudo apxs2 -a -i -l cap -c mod_ruid2.c
sudo service apache2 restart

/etc/apache2/mods-enabled 디렉토리에 ruid2.load 가 존재하면 설치가 정상적으로 된 것이다.

옵션
  • RMode : mod_ruid의 적용방법을 설정 (stat : default, config : 유저설정)
  • RCoreDump : CoreDump 여부를 설정 (default : off)
  • RCoreDumpSize : Dump파일의 사이즈를 설정
  • RGroups : 변경 가능 대상의 group을 설정 (최대 지정개수 : 4개)
  • RMinUidGid : 변경 가능 UID와 GID의 제한선을 설정
  • RDefaultUidGid : 변경 UID, GID의 dafault 값을 설정
  • RUidGid : 변경할 USER와 GROUP을 설정
예제

간단히 가상호스트를 설정할 경우

<VirtualHost *:80>
  ...	
  RMode config
  RUidGid unclepapa unclepapa
  ...
</VirtualHost>

기본 아파치 설정파일에서 기본값을 셋팅하고 필요한 구간에서만 사용하는 경우

User                     www-data
Group                    www-data
RMode                    stat
RGroups                  apachetmp
RDocumentChRoot          /home /example.com/public_html

NameVirtualHost 192.168.0.1

<VirtualHost example.com>
  ServerAdmin    webmaster@example.com
  RDocumentChRoot /home /example.com/public_html
  ServerName     example.com
  ServerAlias    www.example.com
  RMode          config		# unnecessary since config is the default
  RUidGid        user1 group1
  RGroups        apachetmp

   <Directory /home/example.com/public_html/dir>
       RMode stat
   </Directory>



   <Directory /home/example.com/public_html/dir/test>
       RMode config
       RUidGid user2 group2
       RGroups groups1
   </Directory>

   <Directory /home/example.com/public_html/dir/test/123>
       RUidGid user3 group3
   </Directory>

   <Location /yustadir>
       RMode config
       RUidGid user4 user4
       RGroups groups4
   </Location>

 </VirtualHost>

 <VirtualHost example.net>
  ServerAdmin    webmaster@example.net
  DocumentRoot   /home/example.net/public_html
  ServerName     example.net
  ServerAlias    www.example.net
 </VirtualHost>

TroubleShooting

Some users have encountered problems with mod_ruid2 while using mutual exclusion. Lines similar to the following will appear in the Apache error logfile (/usr/local/apache/logs/error_log):

[Wed Sep 12 20:21:50 2012] [emerg] (13)Permission denied: couldn't grab the accept mutex

[Wed Sep 12 20:21:51 2012] [alert] Child 27585 returned a Fatal error... Apache is exiting!

[Wed Sep 12 20:21:51 2012] [emerg] (43)Identifier removed: couldn't grab the accept mutex

[Wed Sep 12 20:21:51 2012] [emerg] (22)Invalid argument: couldn't release the accept mutex

[Wed Sep 12 20:22:25 2012] [emerg] (22)Invalid argument: couldn't grab the accept mutex

To resolve this issue, you may add the following line to /usr/local/apache/conf/mod_ruid2.conf:

AcceptMutex posixsem


신고

댓글을 달아 주세요

  1. 성대경 2013.10.09 00:34 신고

    안녕하세요.
    문의 드립니다. 리눅스가 뭔지, php가 뭔지도 모르는 생초보입니다.
    그런 제가 워드프레스로 개인블로그를 운영해 볼려고 합니다.
    근데 하다 보니 미디어 업로드가 안되서 퍼미션을 777로 줬더니 아무나 내 동영상을 다운받게 되어 뭔가 방법을 검색하다 알게 되었습니다.
    알려주신대로 하려다 보니(리눅스 명령어 같은데...)
    어디에 어떻게 작성해서 변경해야 되는지 잘 몰라 문의드립니다.
    간단하게 할 수 있는 방법이 없을까요?

    • BlogIcon 흉내쟁이 2013.10.11 16:08 신고

      반갑습니다.!!
      우선 일반적인 설정에서의 워드프레스에서 자료를 업로드하기 위해서(미디어 업로드) 퍼미션 777을 부여한것은 옳은 설정입니다. 운영하시는 워드프레스 블로그가 웹호스팅을 이용한 것이라면 대부분 그렇게 해야 작동합니다. 하지만 위에서 말했듯이 특정한 모듈을 설치함으로써 웹서버의 실행권한을 사용자의 계정 ID로 실행할 수 있게 되는데 이와 같은 모듈이 설치되어 있다면 퍼미션을 755 혹은 775로 설정해도 자료의 업로드 및 파일 생성이 가능하게 됩니다. 이와 같은 설정은 웹서버에서 이루어져야 하는 작업이기에 웹호스팅을 사용하고 계신다면 이를 설치하실 수 없습니다. 다만 직접 서버를 구축하고 사용하신다면 위에 언급한 내용을 따라 설치하실 수 있습니다.

      다른 접근방법으로는 업로드한 자료에 타인의 접근을 거부하시려면 글을 작성하시고 미디어를 삽입하실때 비공개 설정으로 글을 작성하시면 됩니다. 그 밖에 검색엔진을 통한 자료접근이 이루어진다면 사용하시는 홈디렉토리에(FTP의 루트디렉토리) robot.txt 파일을 작성하시면 됩니다. 업로드가 이루어지는 특정 디렉토리에 모든 검색엔진의 접근을 차단할 수 있습니다.

      또한 htpasswd 라는 아파치 웹서버의 기능을 이용하여 접근하는 디렉토리에 ID와 PW를 입력하는(인증) 방법으로 차단하실 수도 있습니다.

      위에서 언급한 내용들은 검색으로도 많은 내용을 찾아보실수 있을겁니다.

  2. 이헌주 2014.07.13 18:32 신고

    해결됬습니다. 너무 감사합니다ㅠㅠ

  3. BlogIcon daworks 2015.06.03 23:47 신고

    이 글 덕분에 웹서버 문제가 잘 해결되었습니다. 감사합니다 ^^

    • BlogIcon 흉내쟁이 2015.06.04 01:19 신고

      부족한 글이 얼마나 도움이 되었겠습니까. 모두 본인의 문제해결에 대한 의지로 길을 찾으신거지요. 축하드리며 밤도 늦었는데 편히 주무세요.

  4. 소래산 2015.06.18 13:26 신고

    좋은 정보 잘 봤습니다. 문제가 해결이 되었네요. 그런데 한가지 궁금한것은
    폴더의 권한을 775가 아니라 755로 하면 파일이 올라가지 않습니다.
    755라고 해도 www-data에 속한 개별 사용자가 소유자도 7이라는 권한이 있는데 왜 파일을 못 올리나요?

    • BlogIcon 흉내쟁이 2015.06.18 13:38 신고

      혼동이 좀 오신거같아요. 775의 두번째7은 그룹권한이죠. 사용자가 아파치 데몬의 그룹으로 편입되면서 쓰기권한을 받게됩니다.

      755의 경우 아파치 자신만 7이죠. 그룹과 기타는 5의 권한, 즉 읽고 실행만 가능합니다.

      웝서버의 계정을 부여받은 사용자가 주인이 아니라 아파치데몬이 주인이기에 기본적인 7의 권한은 사용자의 7이 아니라 아파치의 7입니다.

  5. 미키마우스 2015.07.08 19:50 신고

    안녕하세요
    우분투로 서버 돌리고 있고 거기에 wordpress를 로드해서 돌리고 있는 상황을 아는 분께 이어 받게 되었습니다
    저는 현재 서버는 잘 모르고 워드프레스는 공부하고 있습니다
    그러다가 테마와 플러그인을 추가,설정하는데 플러그인은 추가가 되는데 테마가 추가가 안되서 파일질라로 서버에 접속해서 파일을 확인해보니 권한이 플러그인파일은은 읽고 쓰고 실행가능한 777이고 테마파일은 755여서 파일권한을 수정하려니깐 권한수정을 할수가 없네요(Failed to change directory)
    우분투에서 파일권한을 직접 수정하거나
    서버에서 외부게스트가 접근해서 수정하는 권한을 따로 설정해야할 것 같은데 맞는건가요?
    사실 위에 글이 저한테는 너무 수준이 높아 이해가 잘 안가서 이렇게 댓글을 남깁니다

    • BlogIcon 흉내쟁이 2015.07.08 20:36 신고

      우선은, 해당 우분투 서버에서 FTP로 사용하고 계신 것이 VSFTP인지 확인해 보세요. 아마도 VSFTP 일거라 예상됩니다.

      그리고 접속해서 수정하려던 계정이 해당 권한이 부여되었는지도 살펴보셔야 합니다. 이런 것들을 간편히 해주는게 VSFTP 설정중에 있는데 그 부분을 살펴보셔야 합니다. 관련해서는 검색을 통해 정보를 얻으셔야 합니다.

      이런 설정들은 서버쪽 설정 권한이 있는 계정이여야 하며, 서버를 물려봤으셨다면 아마 root 의 계정을 소유하고 계실겁니다. 서버 셋팅을 이전 분이 어떻게 해놓았는지는 접속해서 살펴보지 않는 한 알수가 없는 부분이지요;

      문제 해결되시길 기원합니다~

  6. 전병선 2015.11.07 14:16 신고

    안녕하세요. 독학으로 웹사이트를 만드는 중인데요.
    저는 Flask 와 mod_wsgi 로 아파치를 구동시키고 있는데
    apache가 제 서버의 sshpass나 scp 같은 ssh모듈을 사용하게 할 수 없나요?

    Failed to get a pseudo terminal: Permission denied

    sshpass 를 사용하려고하면 error_log 에 이렇게 나오네요

    • taso 2015.11.23 17:38 신고

      http://stackoverflow.com/questions/33579411/run-ssh-on-apache-failed-to-get-a-pseudo-terminal-permission-denied/33866596#33866596

      여기에 답변달았는데 만족할만한 답변인지 모르겠네요.

  7. BlogIcon 삽질중 2016.07.06 11:27 신고

    안녕하세요.
    정보 찾고 있었는데 해결 했네요...
    좋은정보 너무 감사합니다.

    글좀 퍼갈께요... 출처 블러그 상단에 남기겠습니다.

티스토리 툴바