리눅스는 파일마다(디렉토리도 특수한 종류의 파일이다) 그 파일에 대해 누가 어떤 행위를 수행할 수 있는지를 설정한다.
$ ls -l
-rw-rw-r-- 1 user1 users 29 Mar 22 19:39 somefile
drwxr-xr-x 1 user1 users 29 Mar 22 19:39 somedir
파일이 있는 디렉토리에서 ls -l을 입력해보면, 위와 비슷한 정보가 등장한다.
- 가장 처음에 나오는 10개의 문자로 구성된 문자열은, 파일의 권한을 의미한다. 해석하는 방법은 다음과 같다.
- 첫 번째 문자는 디렉토리와 파일을 구분해준다. 심볼릭 링크라는 것도 있는데, 이것은 궁금하면 추가로 알아보도록 하자. 말하자면 윈도우의 바로가기와 비슷한 것이다.
- r, w, x는 각각 read, write, execute이며...
- 파일의 경우 x는 말 그대로 실행,
- 디렉토리의 경우 x는 해당 디렉토리 안으로 들어갈 수 있는지를 의미한다.
- 다음에 등장하는 9개의 문자는 3개씩 끊어서 봐야 한다.
- r, w, x는 각각 read, write, execute이며...
- 파일의 경우 x는 말 그대로 실행,
- 디렉토리의 경우 x는 해당 디렉토리 안으로 들어갈 수 있는지를 의미한다.
- 첫 세 문자(:3)는 "파일의 소유자"가,
- 두 번째로 나오는 세 문자(3:7)는 "파일의 그룹 소유자"가,
- 세 번째로 나오는 세 문자(7:10)는 "그 외의 경우"가 해당 파일에 대해 수행할 수 있는 행위를 나타낸다.
- ex) rwxrw-r-- (파일)
- 파일 소유자: 읽고 쓰고 실행 가능
- 그룹 소유자: 읽고 쓰기 가능
- 그외: 읽기만 가능
- r, w, x는 각각 read, write, execute이며...
- 그 다음의 숫자는...
- 파일의 경우 link count (심볼릭 링크와 관련이 있다),
- 디렉토리의 경우 서브 디레토리의 수를 의미한다.
- 그 다음에 나오는 두 문자열은 각각 파일의 소유자, 소유 그룹을 의미한다.
파일 시스템마다 상이할 순 있으나, 이러한 정보는 일반적으로 inode에 저장된다.
파일의 권한을 바꾸고 싶다면, chmod 명령어를 이용하면 된다. chmod로 파일 권한을 변경하는 다양한 방법이 있지만, 본 글에서는 가장 헷갈리기 쉬운 방식의 이해를 목표로 한다.
앞서 설명했듯, 파일의 권한은 기본적으로 9개의 문자를 통해 결정된다. 이 문자를 3개 단위로 끊고, 각 자리에 rwx 대신 0 혹은 1이 들어갈 수 있다고 생각해보자. 이를 테면...
rwx rw- r--
111 110 100
이와 같이 영문자가 적혀있는 경우(즉 해당 권한이 있는 경우)에는 1, -가 적혀있는 경우 0을 집어넣어줬다.
세 자리별로 끊어서 2진수라고 생각해보자. 그렇다면 처음 나오는 111은 7이며, 110 은 6, 100은 4가 된다.
이를 chmod와 조합하면 특정 파일의 권한을 변경할 수 있다. 예를 들면,
$ chmod 470 somefile
$ ls -l somefile
-r--rwx--- ...
이런 식으로 변경이 가능하다.
sudo lastb 명령어를 통해 로그인 실패 로그를 조회해보면, 브루트포스로 로그인 시도를 해대는 악독한 무리들이 있음을 알 수 있다. public/private 키 쌍을 이용하면 이러한 공격으로부터 비교적 안전할 수는 있으나... AWS 인스턴스 생성 과정에서 다운로드한 pem 키는 sudo 권한을 가진 계정의 private 키이므로, 이게 공유되는 것 역시 보안상의 문제다. 하지만 종종 다양한 이유로 여러 사람이 한 인스턴스에 접속해야 하는 상황이 오게 되는데... 다운로드한 pem 키를 공유하지 않고 "여럿"이서 "안전"하게 인스턴스에 접속하려면 어떻게 해야 할까? 정석에 가까운 방법은 아래와 같다.
- AWS 인스턴스 생성 시 만든 .pem 파일은 정해진 인스턴스 관리자 1명만 소유하고, 공유하지 않는다.
- sudoer인 ubuntu 계정의 권한을 이용해 sudo 권한이 없고 비밀번호가 없는 계정을 만든다.
sudo adduser user1 --disabled-password
- 만든 계정들의 홈 디렉토리에 .ssh 디렉토리를 만들고, 해당 디렉토리 밑에 authorized_keys 파일을 만든다.
sudo mkdir /home/user1/.sshsudo touch /home/user1/.ssh/authorized_keys
- 디렉토리와 파일의 소유자를 해당 홈 디렉토리의 소유주로 변경하고, 알맞은 권한을 설정한다.
sudo chown -R user1:user1 /home/user1/.sshsudo chmod 700 /home/user1/.sshsudo chmod 600 /home/user1/.ssh/authorized_keys
- 인스턴스에 접속이 필요한 사람의 public key를 받아 authorized_keys에 붙여넣는다.
- 접속이 필요한 사람:
ssh-keygen을 이용해 키 페어를 만든다.- 생성된 파일 중 public 키, 즉
.pub확장자로 끝나는 파일의 내용물을 관리자에게 전달한다.
- 접속이 필요한 사람:
비밀번호도 비활성화되어 있어서 브루트포스에도 안전하고, 설령 개개인의 private 키가 털리더라도 연결된 계정에 sudo 권한이 없기에 시스템에 가할 수 있는 위해의 규모를 줄일 수 있다.
일반적으로 권장되진 않지만, 알아둔다고 손해볼 것은 없다.
sudo vim /etc/ssh/sshd_config로PasswordAthentication yes를 활성화시킨다.- 아마존도 비밀번호 로그인에 보안상 별로라는 걸 인식한 것인지, 저 파일 외에도 하나의 파일을 추가로 수정해야 한다.
/etc/ssh/sshd_config.d/60-cloudimg-settings.conf도 1번과 같은 조치를 취해주자.
- 이제 비밀번호가 설정된 계정은 비밀번호로 ssh를 통해 로그인할 수 있다. (물론 키페어를 이용한 로그인도 설정만 해두었다면 가능하다. 여러 방식으로 로그인이 가능한데 비밀번호를 써야 하는 경우,
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password $계정명$@$ip 혹은 호스트명$을 활용하자)
모두가 알고 있듯이, sudo는 다른 유저의 권한을 잠시 빌려(기본적으로는 root 권한을 빌리며, -u 플래그를 통해 바꿀 수 있다) 특정 명령어를 수행할 수 있도록 해준다. 즉 sudo를 앞에 붙여서 실행하는 모든 명령어는 내가 아니라 root가 수행하는 것이다. 터미널에서 sudo whoami를 해보면 root라고 나오고, sudo touch temp로 파일을 만들어보면 그 소유주가 root인 것이 그 증거다.
file $(which sudo)로 찍어보면 알겠지만 얘도 그냥 실행 가능한 바이너리의 일종일 뿐이다. 그런데 대체 어떻게 무슨 원리로 root의 권한을 빌려오는 걸까?
답은 setuid bit에 있다. ls -l $(which sudo)를 찍어보면 rwx 외의 s라는 특수한 권한이 이 파일에 부여되어 있음을 확인할 수 있다. 이 setuid bit의 역할은 해당 실행 가능한 바이너리를 실행할 때, 실제로 명령어를 수행하는 자의 권한이 아닌 그 바이너리 파일의 소유주의 권한으로 실행시키는 것이다. sudo 파일의 소유주는 root이므로, 우리는 sudo라는 바이너리를 항상 root의 권한으로 실행하게 된다. (더 궁금하면 setuid 시스템콜에 대해 알아보자)
모종의 이유로 어떤 계정에 sudo 권한을 부여하기 위해서는, /etc/sudoers 파일을 수정해야 한다. 근데 sudo vi /etc/sudoers 같은 것으로 스스로 수정해보려다가 오류 잘못 내면 꼬일 가능성이 높기 때문에, 문법 검사를 해주는 visudo를 이용하자.
sudo EDITOR=vi visudo를 통해...- 어떤 계정이
sudo를 사용할 수 있는지, - 어떤 그룹이
sudo를 사용할 수 있는지, sudo명령어를 적용할 수 있는 명령어의 범위가 어떻게 되는지를 설정할 수 있다.- 단일 계정에 적용되는 설정:
계정명 호스트명=(권한_스틸_대상) 적용_명령어
- 그룹에 적용되는 설정:
%그룹명 호스트명=(권한_스틸_대상) 적용_명령어
- 어떤 계정이
/etc/sudoers파일은 "마지막에 매칭되는 조건"이 다른 조건을 덮어쓴다.- 한 계정이 "단일 계정에 적용되는 설정"에도, "그룹에 적용되는 설정"에도 영향을 받는다면, 더 아래에 있는 설정이 적용된다.
sudo사용 시 비밀번호 치는 게 귀찮다면,적용_명령어앞에NOPASSWD:를 추가하면 된다.- ex)
user1 ALL=(ALL) NOPASSWD:ALL - 모든 호스트에 대해 모든 명령어를 모든 유저에 대해(root 포함) 패스워드 없이 sudo를 난사할 수 있음을 의미한다.
- ex)
- 그런데, AWS EC2를 Ubuntu 이미지로 생성 시 자동으로 만들어지는
ubuntu계정은/etc/sudoers에 뭔가 설정되어 있지 않음에도sudo를 비밀번호 없이 사용할 수 있다. 왜 그럴까?- 답은
/etc/sudoers.d/90-cloud-init-users에 있다. 그냥 설정 파일이 분리돼 있던 것.
- 답은
- 호스트를 지정하는 기능이 왜 있는지 궁금할 수 있는데, 이는
/etc/sudoers라는 하나의 통합된 파일로 여러 호스트에 설정을 적용하고 싶을 때 사용한다.