꽃삽질 : nologin 사용자의 umask 는..?? 특히 www-data 는 어떻게?

지금껏, 내가 써왔던 글의 형식은 결론이 뒤에 나오는, 이른바 ‘미괄식’의 글이 많았다.
어쩌다가 이런 상황에 처했는지부터 시작해서, 꽃삽을 어떻게 휘둘렀는지에 대한 장황한 설명이 이어지고, 몇줄로 요약할 수 있는 ‘결론/명령어’는 문미에 위치한 경우가 많았다.

이러다보니, 나중에 그 ‘결과’가 필요해서 다시 글을 찾았을 때, 쉽게 답을 찾기가 어려운 경우가 대부분이다. (나도 잘 못찾는데, 아주 가끔, 내 글을 읽고 도움이 됐다는 사람들을 보면.. 놀랍기까지 하다.)

아무튼, 그리하여 이 글은, 결론부터 앞에 쓰고 나머지 장황한 추사졸구(醜辭拙句)는 그 이후에 넣어보기로 한다.


www-data 에 umask 002(0002) 를 주려면, 다음 파일(/etc/apache2/envvars) 에 딱 한 줄만 추가하면 된다.
단, Ubuntu/Debian 계열 Apache 에만 해당한다고 한다.

# /etc/apache2/envvars
umask 002

그리고 apache 를 재시동하면, www-data 가 자료를 저장할 때, 775 권한을 갖게 된다.
NextCloud 등에서 쓰기 권한이 필요할 때 사용하고, 기본값인 022(755) 를 대체하게 된다.

끝!


이제, 여기까지 오게된 계기, 경위에 대해 나불거릴(?) 차례다.

NextCloud 를 사용한지는 꽤 됐지만, 주로 ‘읽기’용도에 집중했었다. PC 로는 NFS 로 직접 마운트를 하니까 당연히 Nextcloud 는 불필요하고, 외부에서야 웹브라우저로 접속해서 내려받기만 가끔 하므로 굳이 ‘쓰기’ 권한까지 필요하진 않았었다.

그런데.. iPad 에서 Webdav 을 통해 Nextcloud 를 사용하다보니, 가끔이긴 하지만 직접 파일을 저장해야할 필요가 생겼다. 하여, Nextcloud 에 연결된 디렉토리에 쓰기 권한을 부여했는데, 여기엔 setgid 가 설정되어 있고, 따라서 그룹권한이 rw 가 되어야만 했다.

그런데.. 각종 꽃삽질에도 불구하고, 그룹은 여전히 r(read) 에만 머물렀다.

사실은, 위에 써 있는 방법(envvars)을 제일 처음에 시도했던 듯 하다. 그러나 실패했다.
왜냐? umask 002 라 쓰지 않고, umaks 라 썼기 때문이다. (아…)

결국 사소한 실수가 엄청난 재앙(?)을 불러일으킨 셈인데, 그 재앙의 결과로 시작된 삽질 목록은 다음과 같다.

  • /etc/pam.d/common-session
  • /etc/systemd/system/multi-user.target.wants/apache2.service
  • /etc/login.defs
  • /etc/passwd
  • /etc/profile
  • /etc/profile.d/10-umask.sh
  • .profile
  • /etc/bash.bashrc
  • /etc/init.d/apache2

위와 같이 여러 파일들을 건드렸었다. 모두 umask=002 로 설정했으나, 어느 하나도 그룹 쓰기 권한을 만족시켜 주질 못했다. (이 표현엔 모순이 있다. 바로 아래에서 설명한다.)

‘모순’의 이유는, 그룹 쓰기 권한을 만족시켰는지, 아닌지 확인할 방법이 없기 때문이다.
확인하려면 www-data 의 umask 를 확인하든가, 아니면 www-data 로 파일을 생성하여 그 권한을 보면 되는데… 이 두가지 방법에 오류가 있었다.

인터넷을 뒤져보니, 타인의 umask 는 이렇게 확인한다고 한다. (혹은 내가 제대로 보지 않고, 얼핏 보고 난 뒤 내가 아는 지식을 동원해서 이런 명령어를 만들어냈는지도 모르겠다.)

sudo -u www-data bash -c umask -S
0022

몇몇 글들에서, 저렇게 하여 타사용자의 umask 를 확인할 수 있다고 한다. 과연?

또는, 아래처럼 파일을 생성하여 허가권을 보는 방법도 있다.

sudo -u www-data touch abcd

생성된 abcd 파일을 확인해보면, 755 로, 결국 umask 는 022 임을 알 수 있다.

그럼, www-data 의 umask 가 정말 022 일까?
정답은, ‘알 수 없다’가 되겠다.

….

그렇다면, 현재 사용자인 ‘나’의 umask 를 저 명령으로 보면 어떨까?

$ umask # 현재 내 계정
002
$ sudo -u myid bash -c umask -S #내 계정을 sudo -u 로 알아본 결과
0022

음???
내 계정의 umask 는 0002 인데, sudo -u 로 해보니 0022 가 나왔다.
뭔가가 잘못됐다. 아주 크게.

위의 여러 설정 파일들을 수정(umask=002)해보면서, 그 결과를 sudo -u www-data … 로 확인했었다. 그 답은 언제나 ‘0022’ 였다.
그래서 결국 ‘실패’라는 답을 내렸는데..

지금 와 보니, 이게 실패인지 아닌지는 확인할 길이 없다.

정말 제대로 하려면, 이렇게 명령을 내려야 한다. (그러나 www-data 등, nologin 인 경우는 오류가 발생한다.)

sudo su www-data -c umask
This account is currently not available.

위에서 보는 바와 같이, www-data 로는 명령을 내릴 수가 없다. /etc/passwd 에 /usr/sbin/nologin 이 할당되어 있기 때문에, shell 명령을 내릴 수가 없는 모양이다.

sudo su myid -c umask
002

하지만, 내 ID 를 넣어줬더니 제대로 umask 가 표시되었다.

따라서, sudo -u userid 로는, 다른 사용자의 umask 를 확인할 수는 없다. 저 명령으로 나오는 umask 는 타사용자(userid)의 umask 가 아니고, sudoer((sudo visudo, 즉 /etc/sudoers) 의 umask 이다.

sudoer 에 할당된 기본 umask 는 0022 인데, 이게 어디에서 이렇게 할당이 되어있는지는 잘 모르겠다. 하지만 이 값은, /etc/sudoer 에서 바꿀 수는 있다.

sudo visudo
# 다음 행을 추가한다.
Defaults       umask=002

이렇게 되면, sudo 가 행하는 모든 작업에 대해 umask 002 값을 갖게 된다.
단! 여기에도 조건이 있다.

man sudoers 에서 umask_override 항목을 보면, 이렇게 설명이 되어 있다.

If set, sudo will set the umask as specified in the sudoers file without modification. This makes it possible to specify a umask in the sudoers file that is more permissive than the user’s own umask and matches historical behavior. If umask_override is not set, sudo will set the umask to be the union of the user’s umask and what is specified in sudoers. This flag is off by default.

man sudoers

이게 뭔 소리인지, 일단은 해석을 해보자.

만약 이 항목이 설정되면, sudoers(/etc/sudoers) 에 설정된 umask 값을 변형없이 따른다. 이렇게 해서 sudoers 파일에, 현재 사용자가 가진 허가권(umask)보다 더 권한을 더 많이 줄 수 있는 umask 값을 지정할 수 있게 된다. 만약 override 가 설정되지 않았다면(이게 기본값인데), sudo 는 sudo 를 실행하는 사용자의 umask 값과, sudoers 에 설정된 umask 값을 union 연산하여 umask 를 지정한다. 이 값은 기본으로 꺼져있다.

대강만.

이래도 사실 눈에 확 들어오진 않는다.
이 내용을 정리하면 다음과 같다.

현 사용자 umasksudoer umaskumask override off (default)umask override on
002022022022
077022077022
002002002002
077002077002

sudo 로 명령을 내리면, 그게 sudo -u userid 가 됐든 뭐가 됐든, umask 는 현재 사용자와 sudoer 에 설정되어있는 값의 union 값을 따른다. 이 union 연산이 어떻게 되는 건지 잘 모르겠는데, 합집합으로 생각해보면, 아마도 둘 중 큰 값을 취한다고 보면 맞을 듯 하다.

첫 행의 예를 보면, 002(사용자) 와 022(sudoer) 의 union 이 수행되어 결과는 022 가 되었다. 이건 override 가 꺼져있을 경우, 즉 기본값의 경우가 이렇고, override 가 켜져있다면 그대로 sudoer 의 값을 가져오므로, 역시 022 가 된다.

사용자가 077 이면, 좀 더 명확하게 차이를 알 수가 있다.
override 가 꺼져있으면, 077:022 의 union 으로 077 이 선택되고, 켜져있으면 022 가 선택된다.

위 내용은 아래 첫번째 글에서 단서를 찾아 알아낼 수 있었다.

이 내용을 모른채, 열심히 umask 관련 설정 파일을 바꾸고, 시험한답시고 sudo -u 로 명령을 내리고 그 결과값에 분통을 터뜨렸었다. 뭔 짓을 해봤자 umask 결과값은 같을 수 밖에 없었는데..

참고로, man sudoers 의 umask 항목도 옮겨본다.

Umask to use when running the command. Negate this option or set it to 0777 to preserve the user’s umask. The actual umask that is used will be the union of the user’s umask and the value of the umask option, which defaults to 0022. This guarantees that sudo never lowers the umask when running a command. Note: on systems that use PAM, the default PAM configuration may specify its own umask which will override the value set in sudoers.


내용은 위에서 설명한 그대로다.

지금 시점에서 내리는 결론은 두가지다.

  • 첫째 : www-data 등, nologin 사용자에게 umask 를 주는 방법은 확실하지 않다.
  • 둘째 : 그 사용자에게 제대로 umask 설정됐는지 시험해볼 수 있는 방법도 없다. (찾질 못했다.)

헌데, 어차피 저런 사용자들은, System Daemon 에 의해 작동하므로, Apache 처럼 나름대로 설정하는 방법을 갖고 있을테고, 그 방법을 사용하는게 umask 를 제대로 설정하는 옳은 길이라는게 마지막 최종 결론이 되겠다.

즉, 굳이 www-data 등에 umask 를, 일반 사용자와 같은 방식으로 설정하려 고민할 필요가 없다.
이들에겐 다른 방식으로 umask 를 설정해야만 하고, Debian 계열 Apache 의 경우는 /etc/apache2/envvars 에서 할 수 있었다.
다른 경우도 아마 비슷하리라 생각한다.

이렇게 또 하나, 어마어마한 꽃삽질을 끝냈다.
다음엔 또 뭐가 기다리고 있을지..

안녕하세요. 글 남겨주셔서 고맙습니다.