linux Basic
여기서는 리눅스에 대한 기초적인 내용을 다룹니다. 개발자의 입장에서, 보안전문가의 입장에서 모두 중요한 명령어와 팁들을 정리했으니, 편하게 보시면 될 것 같습니다. 또한 이 포스트는 KERT의 기초 보안교육에 활용하기 위해 제작되었습니다.
pwd ( print word direcetory )
현재 작업중인 디렉토리의 이름을 보여줍니다.
$pwd
cd ( change directory )
cd는 디렉토리를 이동할 때 쓰는 명령어 입니다. 기본적으로 .는 현재 디렉토리를 가르키고, ..는 하위 디렉토리를 가리키며 ~는 루트 디렉토리를 가리킵니다.
$cd ..
$cd .././testFolder
$cd ~/Desktop
$cd /
$cd testFolder
대충 예제를 적어 보았습니다. 첫번째부터 설명 들어가도록 하겠습니다. 첫번째는 하위 디렉토리로 가주세요 라는 의미입니다. 두번째는 하위 디렉토리에 있는 testFolder로 가주세요 라는 의미입니다. 세번째는 루트 디렉토리에 있는 Desktop폴더로 가주세요 라는 의미입니다. 네번째는 조금 생소하실 수도 있는데, 절대 경로입니다. 절대경로를 통해 /는 아무것도 없는 경로 이므로 루트 디렉토리를 의미합니다. 즉 루트 디렉토리로 가주세요 라는 의미입니다. 다섯번째는 ./testFolder와 같은 의미로 현재 폴더의 testFolder로 가주세요 라는 의미입니다.
ls ( list )
리눅스에서는 ls명령어를 사용하여 디렉토리에 있는 내용을 확인합니다.
우선 파일 목록을 출려하고 싶은 디렉토리로 들어가서 ls명령어를 쳐 줍니다. 그럼 아래와 같이 디렉토리의 파일들과 디렉토리가 다 나오게 됩니다. 여기서 디렉토리는 파란색으로 파일은 흰색으로 나온 것을 보실 수 있습니다.
$ls
ls에는 다양한 옵션이 존재합니다. 여기서 부터는 제가 자주 쓰는 옵션 위주로 설명해 드리도록 하겠습니다.
$ls -al
옴션을 분석해 보도록 하겠습니다. -al이라고 작성했지만 a, l 둘다 의미가 존재합니다. a는 all의 약자로 숨겨진 파일까지 다 출력해달라는 이야기입니다. ( 리눅스에는 파일 명이 .으로 시작하면 숨겨진 파일이 됩니다. ) 그리고 l은 long의 약자로 길게 출력해달라는 의미입니다. 즉 그 파일과 폴더의 많은 정보를 출력해 달라는 의미입니다.
$ls *.js
*는 대개 와일드 카드(wild card)라고 부릅니다. 모든 파일 이름과 매칭되게 끔 하는 역할을 합니다. 위 명령어에서 *.js는 모든 파일 이름인데, 마지막에 .js이름을 가진, 즉 js확장자를 가진 파일만 출력해 주세요! 라는 의미입니다.
$ls -alSrh
뭔가 명령어가 이번에는 복잡한데, 제가 개발을 할 때 단축키로 등록해 놓고 많이 쓰는 명령어 입니다. 이 명령어의 의미는 숨겨진 파일(a)까지 포함해서 파일크기(S) 역순(r)으로 보기좋게(h) 자세히(l)보여주세요~ 라는 의미입니다. 여기서 보기 좋게 라는 말의 의미는 K, B, G등 파일의 크기와 부가적인 상세한 설명을 사람이 보기 좋게 표현한 다는 것입니다.
IO Redirection
< input Redirection >
IO Redirection이란 Input Ouput을 조정할 수 있는 것을 말합니다. 간단히 말해서 화면에 출력될 것을 파일에 저장해 준다거나 이럴 때 많이 사용됩니다. 간한 Output Redirection 예시를 보시죠
$ls -l > result.txt && cat result.txt
다음그림의 결과를 직관적이게 설명하자면, ls -l의 결과가 result.txt로 저장되고, cat은 catch의 약자로 파일의 내용을 보는 것인데, result.txt을 cat명령어를 통해 보면 ls -l을 했을 때 사용자의 화면에 보여지는 결과와 똑같게 됩니다.
이 뿐만 아니라 error message도 redierction 시켜줄 수 있습니다. 이 때 error message는 standard output아 아니라 standard error이므로 조금 다르게 해주어야 합니다.
$rm result2.txt 2> test.txt
위와는 다르게 standard error를 처리할 때는 standard ouput >과는 다르게, 2>을 활용해 주어야 합니다.
< output Redirection >
위의 input과 비슷하게 output을 redirection시키는 법을 알아보도록 하겠습니다.
cat은 기본적으로 사용자의 입력을 받습니다. 이를 기반으로 다음 명령어를 봅시다
$cat < test.txt
이렇게 되면 cat으로 입력할 data가 test.txt로 입력할 데이터로 치환되어 출력되게 됩니다.
그리고 이 두개를 복합적으로도 사용할 수 있습니다. 다음과 같이 말이죠
$cat < test.txt > test2.txt
$cat test2.txt
으로 하게 되면 standard in으로 받은 test.txt의 결과를 test2.txt로 output을 redirection시켜 주는 것입니다. 즉 복사가 되는 효과를 거두게 되는 것이죠
Shell Script ( zsh )
쉘은 커널과 사용자간의 다리역할을 하는 것으로 사용자로부터 명령을 받아 그것을 해석하고 프로그램을 실행하는 역할을 하게 됩니다.
$echo $0
이는 자신의 쉘을 확인하는 방법입니다. ( 대표적으로는 bash, zsh가 있습니다. )
리눅스에서는 모든 명령어가 쉘 스크립트로 작성되고 실행됩니다.
$where zsh
저의 쉘은 zsh이기 때문에 ( 맥은 다 zsh ) zsh의 bin파일 ( 실행 파일 )이 어디있는지 쳐 보았습니다. 결과 경로로 들어가면 아주 많은 bin(실행 파일)이 존재 할 겁니다.
그럼 이제 저희는 간단한 쉘 스크립트 파일을 작성하고 실행시켜 보도록 하겠습니다.
< 쉘 스크랩트로 백업파일 만들기 >
우선 저의 $where zsh로 알아낸 zsh실행 파일은 /bin/zsh에 있습니다. 이를 기반으로 진행하도록 하겠습니다
먼저 리눅스에서 파일을 편집하기 위한 vim을 알아야 합니다.
$vim backup
을 하게 되면 backup을 편집할 수 있게 됩니다.( 파일이 없다면 만들게 됩니다. )
#!/bin/zsh
if ! [ -d bak ]; then
mkdir bak
fi
cp *.log bak
그리고 backup파일을 i를 눌러서 편집 모드로 들어 간다음에 다음과 같이 작성해 줍니다. 맨 위의 #!을 해시뱅이라고 하는데, backup이라는 파일을 실행할 때 zsh로 실행해 주세요~ 라는 의미입니다. 그리고 아래의 코드는 shell script 구문입니다. 우선 저희는 bak이라는 폴더에 현재 디렉토리의 모든 log파일을 복사 하는 것을 목적으로 하겠습니다.
if [ -d bak ]; then의 의미는 directory bak이 만약에 없다면
mkdir bak 즉 bak이라는 디렉토리를 만들어 주세요 라는 의미입니다.
fi는 if문 마지막에 무조건 붙여줘야 하는 코드이고,
cp *.log bak은 bak으로 확장자가 log인 것을 모두 복사해 주세요 라는 의미입니다.
이 과정이 끝나고 ls -l로 파일의 권한을 보면, 아래에서 볼 꺼지만 rwx중 x이 실행권한인데 x이 bakup에 없음을 확인하실 수 있습니다. 즉 실행 권한을 부여해 주기 위해 chmod라는 명령어를 입력해 주겠습니다.
$chmod u+x backup
일단은 모르셔도 됩니다. 그냥 그렇다~ 정도만 알고 갑시다. 그리고 임의의 .log파일을 만들기 위해 다음과 같이 a.log, b.log, c.log파일을 만들어 줍시다.
$touch a.log b.log c.log
그리고 ./backup을 통해 backup실행 파일을 실행하게 되면
다음과 같이 성공적으로 .log파일이 백업된 것을 보실 수 있습니다.
또한 여기에도 문제점이 있는데, 만약 다른 경로에서 backup을 실행하면 그 폴더 안에 backup폴더가 생긴다는 것입니다. 이를 방지하기 위해 절대 경로로 이동한 다음에 backup을 진행하도록 하겠습니다.
#!/usr/bin/bash
PATH_DIR="$(cd $(dirname $0) && pwd -P)"
PATH_BACKUP=$PATH_DIR/bak
echo "Check this PATH"
echo $PATH_DIR
echo $PATH_BACKUP
cd $PATH_DIR
if ! [ -d bak ]; then
mkdir bak
fi
cp *.log bak
echo "finish BackUP"
저희가 지금까지 살펴본 명령어는 대부분 ./은 작성해 주지 않았습니다. 이런것을 어떻게 해 주는 것일까요? 그냥 조금있다가 볼거지만 환경변수를 수정해 주면 됩니다. echo $PATH를 쳐보면 운영체제의 PATH 환경변수가 나타나게 됩니다.
이 환경변수를 바꿔주기 위해서는 /etc/bash.bashrc을 수정해 주면 됩니다. 다음과 같이 기존의 PATH에 backup이 있는 폴더인 /home/ubuntu/testDir을 추가해 줍시다.
그리고 수정된 bashrc파일을 적용해 주기 위해서 다음과 같은 명령어를 쳐줍니다.
$source /etc/bash.bashrc
그럼 저희가 최종적으로 작성한 backup bash실행파일이 실행되는 것을 보실 수 있습니다.
Process ( in node server )
대부분의 명령어는 스토리지에 프로그램으로써 저장이 되고 실행시 ram에 적재되고 cpu에 의해 실행이 됩니다. 이떄 실행중인 상태에 놓인 프로그램을 프로세스라고 부르게 됩니다.
우선 process에 대해서 알아보기 위해 local에 3001포트를 개방하였습니다. 이도 하나의 process라고 할 수 있습니다. cpu에 의해서 서버가 돌아가고 있기 때문입니다.
그럼 한번 리눅스 명령어로 3001번 포트의 PID를 알아보도록 하겠습니다.
$sudo lsof -PiTCP -sTCP:LISTEN
를 통해 현재 열린 포트 목록을 확인할 수 있습니다.
그럼 다음과 같이 TCP *:3001의 PID ( 25701 )가 node command로 LISTEN되어 있음을 알 수 있습니다. 이 외에도 htop을 설치해서
맥이라면 homebrew로 설치 가능 ( 다른건 모름 )
$brew install htop
다음과 같이 PID를 실행 위치와 점유율을 통해 알아볼 수 있습니다. 그리고 만약에 이 Process를 죽이고 싶다면 아래와 같은 명령어를 치면 됩니다. ( 이렇게 cli로 그림을 표현한다는건 참 대단한 것임... respect )
$sudo kill -9 PID
그럼 열린 node 서버가 죽었음을 보실 수 있습니다.
find File
개발이나 보안을 하다보면 자신이 찾고자 하는 파일을 찾고 싶을 때가 있습니다. 간단한 예시를 보겠습니다.
$find . -type f -name "*.log"
이 명령어의 의미는 . ( 현재 폴더부터 ) -type = f ( file )인 것과 -name = "*.log"즉 확장자가 log인 것을 찾는 명령어 인 것입니다.
아까 만든 백업 폴더에서 이를 실행하면 결과가 위와 같게 됩니다.
이 외에도 PipeLine이라는 중요한 명령어를 활용할 수도 있습니다.
PipeLine이란 명령어1 | 명령어2 이런형태로 명령어1의 처리 결과를 명령어2로 전달하는 것입니다.
$ls -l | grep ".log$"
grep은 grep "regex" "message" 이런식으로 message안에 있는 것 중에 regex에 해당하는 것만 찾는 것입니다. 위의 코드는 즉 현재 폴더의 ls -l의 결과중 .log으로 끝나는 것만 출력해 주세요 라는 의미로 위에서 알아본 find와 비슷하다는 것을 알 수 있습니다.
또한 실행파일을 찾을 수 있는 명령어가 있습니다. ( 이도 파일 중 하나임 ) 대부분 /bin안에 있게 됨
$whereis ls
만약에 ls이라는 명령어가 어디 있는지 궁금해서 이를 치게 되면
다음과 같이 2개의 파일이 찾아지게 됩니다.
직접 /bin안의 ls실행파일을 실행해 보면 위와 같습니다. 그 다음거는 ls의 설명서인데 한번 해보시길 바랍니다.
근데 어떻게 리눅스는 ls만 했는데 /bin/ls을 실행하는 것일까요?
$echo $PATH
를 한번 쳐 봅시다. 그럼 환경변수들이 쫙 나올 것입니다.
이 모든 절대경로들은 : (콜론)으로 구분되어 있으며, 운영체제는 이 폴더들을 하나씩 찾아가면서 그 디렉토리에 ls의 실행파일이 있는지 차례대로 검색해서 실행하는 겁니다. 잘 보시면 저기 :/bin:이 있는 것을 보실 수 있습니다.
*Important*
User, Group, Other ( Authorization in linux )
리눅스를 사용하면서 한 컴퓨터에 많은 사용자가 접근할 필요성을 느낄 때가 많습니다. 그리고 리눅스는 멀티 유저를 지원하게 됩니다. 리눅스에서 새로운 user를 만들고 ssh로 들어갈 수도 있지만, 저는 맥에서 login명령어로 guest사용자로 들어가 내용을 살펴보도록 하겠습니다.
일단 관리자 계정으로 접속하는 법을 알려드리겠습니다.
$su - root
저의 root이름은 ihyeonseo이므로 $su - ihyeonseo를 치고 비번 치며 root계정 ( ihyeonseo )으로 접속이 가능합니다.
그리고 아래와 같이 관리자 권한의 비밀번호를 lock시키고 풀 수도 있습니다.
// lock the password
$sudo passwd -l root
// unlock the password
$sudo passwd -u root
또한 그럼 이러한 사용자를 어떻게 추가하냐? 라고 한다면 아래의 명령어를 참고하시면 됩니다. 참고로 저는 맥이여서 리눅스와는 사뭇다르게 GUI로 추가할 수 있게끔 되어 있습니다.
// add the user
$sudo useradd -m addUserName
// set the password
$sudo passwd addUserName
// add newUser some sudo permissions
$sudo usermode -a -G sudo addUserName
// connect to the newUser
$su - addUserName
이와 같이 새로운 사용자를 만들고 -> 패스워드를 설정해 주고 -> sudo권한 설정해 주고 -> connect해주면 됩니다.
리눅스는 하나의 컴퓨터를 여러 사람이 사용할 수 있는 멀티유저 운영체제(OS)이기 때문에 권한 관리가 매우 중요합니다. 파일과 디렉토리의 권한을 변경하고 소유권을 변경하는 방법을 지금부터 알아보도록 하겠습니다. 보안에 중요한 내용이기 때문에 리눅스 관리자가 되려면 정확하게 이해하고 넘어가는 것이 좋습니다.
아까 살펴 보았던 ls -l로 디렉토리 리스트를 출력허게 되면 권한(퍼미션, 허가권)을 확인할 수 있습니다. 아래와 같이 말이죠
맨 앞을 보시면, 출력 결과는 각각 파일종류 및 권한, 링크수, 사용자(소유자) 그룹, 파일크기, 수정시간, 파일 이름을 나타내게 됩니다.
여기서 파일의 권한은 'drwxr-xr-x'와 같은 형태로 확인할 수 있고, 소유권은 'ihyeonseo staff'와 같이 확인할 수 있습니다.
이 것의 의미는 이 파일들을 만든 사람의 이름이 ihyeonseo라는 것이고 ihyunseo는 staff이라는 그룹에속해 있다는 뜻입니다.
'drwxr-xr-x'는 리눅스에서 권한을 나타내는 것인데 매우 중요합니다. 이는 'd rwx r-x r-x'로 나눌 수 있습니다. 와 같이 4 부분으로 나눌 수 있습니다. d는 디렉토리라는 것이고, 그 뒤로 3가지 묶음은 차례대로 사용자(owner, 소유자)권한이고, r-x그룹(group)권한, r-x다른 사용자(other)권한을 의미합니다.
- rwx 사용자 권한
- r-x 그룹 권한
- r-x 다른 사용자 권한
rwx는 각각 읽기(read), 쓰기(write), 실행(execute)권한을 나타냅니다. 'd rwx r-x r-x'을 해석해 보자면 사용자는 읽고 쓰고 실행까지 할 수 있지만, 그룹과, 다른 사용자는 읽고 실행만 가능하고 쓰기는 불가능하다는 의미입니다.
또한 매우 중요한 개념중 하나가 보통 권한은 리눅스에서 숫자로 표현됩니다. ( 755, 777 등으로 ) 이 숫자가 의미하는 바는 다음과 같습니다.
위 숫자는 각각의 실행 코드로 8진수로 나타냅니다. 예를 들어 777의 권한이 부여되었다면 각각의 7은 (4 + 2 + 1)을 의미하게 됩니다. 즉 일고 쓰고 실행 모두 가능하다는 의미입니다.
예를 들어 755의 권한이라면 어떤 권한을 가지는 것일까요??
5는 이제 (4 + 1)이기 때문에 그룹과, 다른 사용자는 읽기 쓰기는 가능하다 쓰기는 불가능하다고 보면 되고, 사용자는 읽고 쓰고 실행 다 가능하다고 보면 됩니다. 755 -> (111 101 101)_8 (8진수 표기법)
간단한 예시를 들기 위해서 root계정 ( ihyeonseo )으로 파일을 하나 만드는데 그 안의 내용을 hi로 만들어 보겠습니다.
$echo 'hi' > perm.txt
root계정이 아닌 다른 사용자 계정으로 들어와서 동일한 경ls -l령어를 칩니다. ( 여기서는 guest2 )
$ls -l perm.txt
그럼 다음과 같은 결과가 나오게 될 것입니다. 여기에는 파일을 만든 사람이 ihyeonseo ( root )로 되어 있고 guest입장에서의 권한은 other이므로 r--입니다. r--은 read만 있는 것이므로 write, execute가 되지 않습니다. 따라서 perm.txt파일을 읽을 순 있으나 수정할 순 없습니다.
만약 다른 사용자가 읽지도 못하게 하려면 어떻게 해야 할까요? root ( ihyeonseo ) 계정으로 들아와서 다음과 같이 권한을 바꾸어 주어야 합니다.
$chmod o-r perm.txt
$chmod g-r perm.txt
o-r은 other에게서 -r
즉 r을 빼겠다는 의미입니다. 추가는 +을 써주면 됩니다. 그리고 group은 o대신 g, current유저는 o대신 u을 사용해 주면 됩니다.
또한 chmod는 앞에서 알아본 8진수 표기법으로 권한을 줄 수도 있습니다.
$chmod 755 perm.txt
다음과 같이 other의 r권한이 사라져서 'r--' 가 '---'로 바뀐 것을 보실 수 있습니다. 또한 group의 r권한도 삭제 해 주었는데, 그 이유는 guest의 group을 확인해 보면 root와 동일한 group에 속해 있기 때문입니다. group은 더 뒤에서 알아보도록 하겠습니다.
다음과 같이 cat을 통해서 perm.txt를 읽으려 하면 permission error가 뜨는 것을 확인할 수 있게 됩니다.
이제 실행의 개념과 권한 설정에 대해 간단히 얘기해 보도록 하겠습니다. 이를 위해 실행가능한 쉘 스크립트 파일을 하나 만들 도록 하겠습니다.
// hi-machine.sh
#!/bin/zsh
echo 'hi hi hi hi'
간단히 실행하면 hi hi hi hi가 출력되는 쉘 스크립트 파일을 만들었습니다.
이를 /bin/zsh의 실행파일로 실행하면 잘 출력되는 것을 아래와 같이 확인할 수 있습니다.
$/bin/zsh hi-machine.sh
하지만 폴더에서 사용자의 권한으로 실행하는 것은 permission denied가 뜹니다. 그 이유는 다들 예상 하셨겠지만, user에 execute권한이 없어서 그렇습니다. ( rw- )
#!/bin/zsh
echo 'hi hi hi hi'
이를 실행시켜 주기 위해서 실행권한을 앞에서 살펴본 chmod를 통해 주어 주도록 하겠습니다.
$chmod u+x hi-machine.sh
$./hi-machine.sh
그 다음으로는 directory의 권한에 대해 알아보도록 하겠습니다.
directory의 권한은 file에서와 사뭇 다릅니다.
- read -> directory의 하위 파일을 조회할 수 있다. 즉 조회란 ls -l [directory name]으로 확인할 수 있다는 뜻
- write -> direcyory안에 하위 파일을 하나 생성할 수 있다. cd [directory name] && touch a.txt가 가능하다는 뜻
- execute -> directory에 들어갈 수 있는 지 (cd 명령어를 통해) cd [directory name] 가능하다는 뜻
위는 directory의 기본 권한입니다.
또한 하나의 팁을 더 드리자면 directory안의 모든 파일의 권한을 똑같이 변경해 주고 싶다면 chmod에 -R ( Recursive )옵션을 주어주면 됩니다.
$chmod -R o+w perm
과 같이 적어주게 되면 perm 디렉토리 안의 모든 파일의 other의 write권한을 추가해 주라는 뜻입니다.
마지막으로 group권한입니다.
간단한 예시를 들어보았는데, other모두에게는 주기 싫은데, 특정한 group인 (그림에서는 developer group )에 권한을 주고 싶을 때 사용하는 것입니다.
그럼 맥에 developer group을 만들고 예제 작성해 보도록 하겠습니다.
바로 developer그룹을 만들어 주고 guest2만 여기에 놓아 보도록 하겠습니다. 그리고 /etc/group이라는 파일 안에는 모든 group의 정보가 나타나 있는데, 이를 파이프 라인으로 확인해 보도록 하겠습니다.
< 리눅스에서 그룹을 생성하고 그 그룹에 사용자를 추가하는 방법은 다음과 같습니다. >
$sudo groupadd developer
$sudo gpasswd user1 developer
다음 명령어는 developer그룹을 생성하고, user1의 그룹을 developer로 설정한 것입니다.
$cat /etc/group | grep "developer"
그럼 group id가 204번인 group이름이 _developer로 나오는데, macOS에서는 _가 앞에 추가로 붙는것 같습니다. 각자 맞는 group이름을 찾아보도록 합시다..!!
그리고 developer라는 디렉토리를 만들고 이 디렉토리의 group을 원래 staff에서 developer로 변경해 보도록 하겠습니다. ( staff는 원래 default 그룹 인듯.. )
$sudo chown ihyeonseo:_developer .
와 같이 . ( 현제 폴더 )의 group이 _developer로 변경된 것을 보실 수 있게됩니다.
그리고 폴더의 group권한이 원래 write가 없습니다. (r-x)이기 때문. 그래서 이 디렉토리 안에 파일을 추가할 수가 없었는데, 아까 배웠던 chmod 명령어를 통해 group에 w권한을 추가 해보도록 하겠습니다.
$sudo chmod g+w .
이렇게 되게 됩니다. 그리고 저희가 developer로 추가해준 guest2로 다시 접속해서 이 폴더 안에 파일을 만들게 되면!!
다음고 같이 읽고 쓰고 다 되는 것을 보실 수 있습니다.
'School > Security' 카테고리의 다른 글
[ Web Hacking ] - Cookie & Session (0) | 2022.05.26 |
---|---|
[ Web Hacking ] - W31c0m3, w3b h4ck3rs! (0) | 2022.05.25 |
[ Security ] 비밀번호 단방향 암호화 (0) | 2022.05.23 |
[ Node.JS ] Express-Session과 암호화 (0) | 2022.05.23 |
[ Basic Security ] - Ubuntu in Server (0) | 2022.05.15 |