sudoers 커스텀 하기

개인용 데스크탑은 OSX든 윈도우즈든 원하는 걸 쓴다지만 서버를 관리해야 하는 입장에서 요즘은 리눅스를 안 쓸 수 없다. 그리고 지금은 석기시대가 아니기 때문에 root권한으로 바로 로그인을 하는 멍청한 짓은 아무도 하지 않고 모두 sudo를 이용해서 권한을 빌려 쓰게 된다.1
하지만 sudo를 써야 할 때 패스워드를 입력하는 건 귀찮고 그렇다고 해서 sudo 커맨드를 쓸 수 있는 계정의 암호를 쉽게 설정하는 건 또 난감하다. 시스템을 관리하기 위해 자주 써야 하는 커맨드들은 sudoer 파일을 이용해서 패스워드를 입력 받지 않도록 수정할 수 있다.

sudo visudo 커맨드를 사용하면 /etc/sudoers 파일을 수정할 수 있는 에디터가 뜬다. 이 커맨드를 이용해서만 편집을 해야 하고 그렇지 않으면 로컬에서 복구모드로 부팅하지 않는 한 영원히 sudo를 못 쓰게 되는 경우가 있다./etc/sudoers 파일의 권한 설정은 0400으로 되어 있어야 하고 그렇지 않을 경우 sudo 커맨드가 자체적으로 잠가버리기 때문이다.
커맨드 이름은 vi/Vim을 노린 것 같지만 우분투 등의 OS에서는 기본 에디터가 nano이기 때문에 좀 이상한데 sudo EDITOR=vim visudo 등을 사용해서 원하는 에디터를 사용할 수 있으니 참고 바란다.

visudo를 하게 되면 굉장히 난감한데 fstab이나 crontab 같은 경우는 코멘트로 대략적인 예시가 적혀 있지만 visudo만은 그냥 manpage를 보라고 불친절하게 쓰여있고 각각의 필드도 90% 이상이 그냥 ALL로 적혀 있어 대체 어떤 필드가 어떤 역할인지 알 수가 없다. 대충 적어보자면 아래와 같다.

user host=(runas) command
%group host=(runas) command

user host=(ALL:ALL)OPTION command
user host=(ALL:ALL)OPTIONS:OPTIONS: command
  • 첫 번째 필드는 sudo를 실행하려고 하는 유저를 지정한다. 그냥 적으면 user고 그룹을 지정하고 싶으면 %를 붙이면 된다.
  • 두 번째 필드는 sudo를 사용하려고 하는 호스트를 지정할 수 있다. 로컬에서 접속한 유저들만 권한을 주려면 localhost로 적으면 된다는데 실제로 해보면 잘 안 되는 걸 보아 그냥 ALL로 두는 게 나은 것 같다.
  • 세 번째 필드는 sudo를 통해 얻으려는 권한이다. sudo는 root 권한을 얻을 때 주로 쓰기 때문에 잘 모르는 사실이지만 sudo -u postgres psql 등과 같이 굳이 su 커맨드를 같이 쓰지 않고도 특정 유저의 권한으로 실행 할 수 있다. 그냥 ALL을 적으면 모든 권한을 사용할 수 있는데 콜론으로 구분해서 유저:그룹을 지정해 줄 수 있다. chown을 사용할 때 사용하던 그것과 포맷이 일치한다.
  • 네 번째 필드는 옵션을 지정할 수 있는데 그냥 비워 두면 당연하겠지만 아무런 옵션이 안 붙은 거고 NOPASSWD, SETENV 등을 사용할 수 있다. 반드시 옵션마다 콜론을 뒤에 붙여줘야 한다. 여러 가지 옵션이 있겠지만 대표적으로 NOPASSWDsudo를 사용할 때 패스워드를 입력 할 필요가 없게 되고(sudoers를 편집하는 가장 큰 이유), SETENV는 환경변수를 유지시킨다.
  • 다섯 번째 필드는 실제 커맨드를 지정할 수 있다. 특정 유저에게 sudo를 사용해서 nginx만 켜고 끄는 권한을 준다든지 할 때 굉장히 유용하다. 모든 커맨드를 다 실행 할 수 있게 하려면 ALL을 사용하면 된다. 당연하겠지만 bash 같은 걸 실행 할 수 있게 해버리면 그 안에서 다른 커맨드들도 모조리 사용 가능하니 지양해야 한다. 커맨드는 안전을 위해서 절대경로를 적도록 강제하고 있다. (eg: nginx가 아니라 /usr/bin/nginx로 적는다)

이를 이용해서 몇 가지 예시를 들면 아래와 같다.

# adm 그룹에 있는 유저들에게 패스워드 입력 없이도 서비스를 켜고 끄는 권한을 준다.
%adm ALL=(ALL:ALL)NOPASSWD: /usr/sbin/service * stop, /usr/sbin/service * start

#dokku 커맨드를 패스워드 입력 없이 사용하게 한다.
user ALL=(dokku:dokku)NOPASSWD:SETENV: /usr/bin/dokku

/etc/sudoers 파일을 그대로 두고 /etc/sudoers.d 디렉터리 아래에 같은 포맷으로 파일을 추가할 수 있기는 한데 별로 추천하고 싶지는 않다. visudo의 경우 얼마 전부터 잘못 된 양식일 경우 sudo를 아예 못 쓰는 걸 방지하기 위해 다시 편집 할 건지 아니면 수정사항을 다 취소할지 물어보게 되지만 해당 디렉터리 밑에 파일을 넣는 경우 그런 검사를 하지 않고 바로 잠겨버릴 수 있기 때문이다.


  1. Kali 같은 건 root권한이 기본이지만 이건 해킹을 위한 이지 메인 OS로 쓰라고 만든 건 아니기 때문에 예외다. 

개발환경을 정리하는 툴 direnv

direnv는 개발환경을 쉽게 정리하는 툴입니다.
헤로쿠의 등장을 기점으로 각종 프로그램의 설정은 환경변수를 이용하는 게 보편화 되었고 그 환경변수는 .env 파일에 저장하는 게 일반적입니다.
헤로쿠의 경우 foreman을 이용해 로컬에서 개발서버를 돌려 볼 때 자동적으로 .env를 읽어서 환경변수로 지정한 뒤에 실행하게 되고 파이썬 같은 경우 honcho라는 클론 버전이 있습니다.

하지만 개발서버를 돌리는 일 외에 DB 마이그레이션(eg: 장고의 ./manage.py migrate)등을 해야 할 때도 그 환경변수를 지정해야 할 일이 생겼고 그 때마다 honcho run ./manage.py migrate 등의 일을 하기란 굉장히 불편합니다.
그래서 해당 디렉터리에 들어갈 때 자동적으로 .env를 로드해 주는 autoenv라는 툴이 나왔습니다만, 이 툴은 해당 디렉터리를 빠져나갈 때 unload를 시켜주지 않는 문제가 있습니다.

그런 배경을 가지고 direnv가 나오게 된 것인데 이 툴은 기본적으로 디렉터리를 빠져나갈 때 unload를 해 주는 것은 물론이고 현대 개발언어 환경에 유용한 기능들을 많이 가지고 있습니다.
Python 개발의 경우 대부분 venv를 어떤 식으로든 사용을 하게 되는데 해당 디렉터리에 들어 갈 때마다 이를 활성화 해 주는 일도 여간 귀찮은 게 아닙니다. pyenv를 사용해서 .python-version을 이용하는 방법도 있지만 개인적으로 pyenv-virtualenv는 가상환경을 ~/.virtualenvs 밑에 만드는데 프로젝트를 삭제할 때 이 venv가 같이 삭제가 안 되는 게 좀 껄끄럽습니다. 일종의 강박증이죠.
direnv는 .envrc 파일에 layout python을 적어 넣으면 자동적으로 숨겨진 디렉터리(./.direnv) 안에 venv를 만들어 주고 해당 디렉터리에 들어가 있을 때만 활성화를 시켜 줍니다.
짜잔! 드디어 파이썬도 npm이나 bundle처럼 디렉터리마다 자동적으로 따로 관리 되는 개발환경을 가질 수 있게 되었군요!
direnv example
python 이외에 다른 언어들도 지원합니다. 자세한 내용은 해당 프로젝트의 wiki 페이지를 참고하시면 됩니다.

direnv의 문제

layout python 등의 명령어가 있으므로 .env를 사용하지 않고 .envrc를 사용하는 건 이해가 가지만 .envrcdotenv를 적어주지 않으면 .env에 적힌 환경변수를 로딩하지 않는 게 기본 설정입니다. 왜 이렇게 동작하는지 모르겠지만 전역 설정(~/.config/direnv/direnvrc or ~/.direnvrc)에 dotenv를 적어봤는데 내가 있는 디렉터리를 기준으로 .env를 읽어 오는 게 아니라 이 설정파일의 위치를 기준으로 읽어오기 때문에 사용할 수 없습니다.

Ubuntu 17.04 Systray fix

Ubuntu 17.04 zesty has a lot of changes. System tray is one of them and it has some problems to use it.

  • Dropbox menu doesn’t appeared.
  • Other Icons are not appeared on system tray.

Way to fix it

Temporarily: Set an environment variable like this: XDG_CURRENT_DESKTOP=Unity.
ex) XDG_CURRENT_DESKTOP=Unity dropbox start -i

permanently: Append XDG_CURRENT_DESKTOP=Unity to ~/.pam_environment file. It is like X version of .profile Usually, It has system locale settings.


우분투 17.04 zesty는 많은 변화가 있었고 시스템 트레이에 생긴 문제도 그 중 하나입니다. 대표적으로 드랍박스의 아이콘을 누르면 나오는 메뉴가 아무 것도 안 뜨고 다른 앱들은 아이콘조차 뜨지 않는 경우도 있습니다.
해결 방법은 앱을 실행할 때 XDG_CURRENT_DESKTOP 환경변수를 Unity로 세팅하는 것입니다.
임시적인 방법으로 셸에서 실행할 땐 XDG_CURRENT_DESKTOP=Unity dropbox start -i 같은 방법으로 실행할 수도 있고 모든 앱에 적용하려면 ~/.pam_environment파일에 XDG_CURRENT_DESKTOP=Unity라고 한 줄을 더 적어주시면 됩니다. 이 파일은 셸에서 ~/.profile과 비슷한 역할을 하는 파일입니다. 보통 시스템 언어설정 등이 담겨 있습니다.