본문 바로가기

리눅스

심볼릭 링크란 무엇일까

리눅스 프로그래밍이나 관련 수업을 듣다보면 '심볼릭 링크'라는 말을 듣게 된다. 이것은 무엇일까?

바로가기(.lnk)

간단하게 생각하면 Windows 운영체제의 바로가기를 예로 들 수 있다. 바로가기를 클릭하면 원본 파일을 실행하게 되는 것처럼 심볼릭 링크도 원본 파일을 가리키는 '링크'이다. 하지만 다른점이 있는데 바로 '하드 링크'와 '소프트 링크'로 종류가 나뉜다는 것이다.

i-node(아이노드)

이를 구분하기 전에 리눅스 파일 시스템의 'inode'란 것에 대해 알아보자.

inode는 시스템의 파티션에 있는 각 파일에 대한 정보를 기억하는 120바이트의 고정된 크기의 구조체이다(출처: 알기사 정보보안기사/산업기사). 이는 파티션의 inode list에 저장되는 메타데이터로써 파일에 대한 정보라 하면 파일타입, 접근권한, 링크 개수, 소유자, 소유그룹, 파일크기, MAC(Modification, Access, Change) Time 등 여러 정보를 포함한다.

 

당연히 이들은 각각의 파일을 가리키기 때문에 서로 구분되는데 이때 여기서 우리가 볼 것은 inode의 번호이다. 이는 유닉스 파일 시스템에서 파일마다 고유하게 가지는 일종의 일련번호라 할 수 있으며 하드 링크, 소프트 링크를 구분하는 데 핵심이 된다. 물론 터미널 상에서도 소프트 링크는 화살표 표시가 붙는다.

 

정의하자면 하드 링크는 가리키는 파일과 inode가 같은 링크, 소프트 링크는 가리키는 파일과 inode가 다른 링크이다.

하드 링크(Hard Link)

inode는 파일마다 각각 존재한다고 하였는데 가리키는 파일과 같은 inode를 가진다는 것은 무엇일까? 이는 원본 파일이 두 개의 파일(원본 파일, 하드 링크 파일)로 서로다른 이름으로 존재하면서 같은 파일 정보를 가지게 되는 것이다. 그렇다면 원본 파일이나 하드 링크 파일에서 변경사항을 적용하면 어떻게 될까? 그 변경사항은 자동으로 서로에게 반영된다. 즉 동기화 되는 것이다.

실험을 위한 원본 파일(originalFile)

확인을 위해 하나의 파일을 만들어보았다. 쉘의 stat 명령어를 사용하여 파일의 정보를 조회하면 다음과 같다.

stat 명령어로 조회한 파일 정보

Inode 항목을 보면 545694라는 숫자가 보인다. 이것이 원본 파일의 inode 번호이며 이는 고유한 값을 가진다.

그렇다면 쉘의 ln 명령어를 사용하여 링크를 생성해 보자(C언어의 로우레벨 API link(), symlink()로도 가능하다).

동일한 Inode를 가진다.

생성한 링크를 stat 명령어로 파일 정보를 조회하니 같은 Inode 값을 가지고 있다. 즉 같은 파일 정보를 가리킨다는 것이며 실질적으로 동일한 파일이라고 할 수 있다. 또한 Links 항목을 보면 2라는 값을 가지고 있는데 이는 하드 링크의 갯수, 즉 이 Inode에 연결된 파일의 갯수를 의미하며 현재 원본 파일과 하드 링크 파일 두 개가 이 Inode를 가리키므로 2개 인 것이다. 하드 링크는 동기화가 된다고 말했는데 한번 확인해보도록 하자.

먼저 원본 파일을 간단한 C언어 코드로 작성하였다. 그렇다면 하드 링크 파일은 어떻게 되어있을까?

아무런 조작이 없었음에도 같은 내용으로 바뀌어 있었다. 그렇다면 하드 링크 파일에서 수정사항을 적용해보면 어떻게 될까?

printf("Hello World!\n"); 을 추가하였다.

역시 원본파일에도 수정사항이 반영되었다. 이는 둘 다 같은 Inode를 가리키고 있기 때문에 가능한 것이다.

그렇다면 원본파일을 삭제하면 하드 링크 파일도 삭제될까?

아무런 영향도 없다. 여전히 파일의 내용은 그대로 유지되며 Inode도 동일한 값을 가지고 있다. 즉 별개의 파일이라고 해도 무방한 것이다. 그렇다면 파일의 복사본이랑 무엇이 다르냐고 생각할 수도 있겠지만 복사본은 하드 링크처럼 같은 Inode를 가리키지 않으며 변경사항이 자동적으로 반영되지도 않는다.

소프트 링크(Soft Link)

그렇다면 소프트 링크는 어떨까? ln 명령에 s옵션을 줘서 심볼릭 링크(소프트 링크)를 생성해보자.

사진에는 나와있지 않지만 파일을 복사했다가 삭제하느라 사진과 Inode 번호가 달라졌다.

하드 링크에 비교하여 소프트 링크는 크게 두 가지의 차이가 있다. 첫번째는 이름에 화살표(->)가 붙어 원본 파일을 가리키며, 두 번째로는 Inode 번호가 다르다. 위의 사진을 보면 원본 파일은 546818이지만 링크 파일은 546821의 Inode 번호를 가지고 있다.

그런데 소프트 링크 파일도 같은 내용을 가지는 건 그렇다고 쳐도 수정을 해보니 하드 링크처럼 두 파일에 모두 반영된다. 링크 파일과 원본 파일은 Inode가 다른데 어떻게 하드 링크처럼 동기화가 일어나는 걸까?

 

이유는 간단하다. 위에서 cat이나 vim으로 링크 파일을 읽고 쓰는 행위는 링크 파일 자체가 아니라 링크 파일이 가리키는 원본 파일을 따라가서 명령어를 수행한 것이다. 그렇기 때문에 하드 링크와 달리 원본 파일이 삭제된다면 이를 읽지 못한다.

하드 링크에서는 원본 파일이 사라져도 내용을 유지했지만...

또한 원본 파일이 수정되거나 아예 달라져도 이름만 같다면 상관없이 링크를 유지할 수 있다.

새로 생성한 원본 파일을 읽는다.

그렇기 때문에 이 소프트 링크는 Windows의 바로가기와 유사하다고 할 수 있다.

정리

원본파일(originalFile)과 하드링크파일(hardLinkFile)은 같은 Inode값(545694)을 가지며 파일 크기도 동일하다.

이에 비해 소프트링크파일(softLinkFile)은 546821로 다른 Inode값을 가지며 파일 크기도 다르다. 위의 사진에서는 우연히 다른 파일들과 크기가 같은 것 뿐이다.

수정 후 달라진 파일들의 크기. 원본과 하드 링크는 동일하게 바뀌었지만 소프트 링크는 그대로다.

편집 시에도 서로에게 변경사항이 바로 반영되는 동기화가 가능한 하드 링크와 달리 소프트 링크는 그렇지 못하다. 소프트 링크는 링크 파일 자체가 아니라 링크 파일이 가리키는 원본파일로 따라가서 수행하는 것.

 

이 심볼릭 링크를 이용한 권한 상승 공격도 있는데 이는 추후 포스팅하도록 하겠다.

'리눅스' 카테고리의 다른 글

/etc/passwd, /etc/shadow에 관하여  (0) 2020.07.17
데몬(daemon)이란?  (4) 2019.01.10