a file whose purpose is to point to a file or directory by specifying a path thereto
오늘의 주제는 심볼릭 링크이다. 과거 수행한 분석 프로젝트 회고를 읽어보던 중 눈에 들어온 이 개념을 과연 얼마나 이해하고 있을까 싶어, 오늘 날 잡고 정리해보려 한다.
심볼릭 링크(Symbolic Link)란, 특정 파일이나 디렉토리에 대한 경로 기반의 참조 정보를 저장하는 특수한 파일을 의미한다. 흔히 ‘소프트 링크(Soft Link)’라고도 불리며, 실제 데이터가 아닌 다른 파일의 경로를 문자열 형태로 저장하고 해당 경로를 통해 대상 파일에 접근하는 기능을 수행한다. 이는 마치 Windows 환경의 “바로 가기(shortcut)”와 유사하지만, 내부 구현은 파일 시스템 수준에서 다르게 작동한다.
Unix 계열 운영체제에서는 ln -s
명령을 통해 심볼릭 링크를 생성할 수 있으며, 생성된 링크는 일반 파일과 구분되는 특별한 파일 유형(l
로 표시됨, 예: lrwxrwxrwx
)으로 인식된다.
ls -l
명령어로 확인 시, ->
기호를 통해 링크 대상을 나타냄.이러한 방식은 시스템 자원에 대한 간접 참조를 가능하게 하며, 운영체제 및 응용 프로그램이 파일 경로를 동적으로 관리하거나 경량화된 접근 경로를 구성할 수 있도록 해준다.
심볼릭 링크와 종종 비교되는 개념으로는 하드 링크(Hard Link) 가 있다. 두 개념은 모두 한 파일을 여러 위치에서 접근 가능하게 만들지만, 작동 방식에는 본질적인 차이가 존재한다. 다음 표는 주요 차이점을 정리한 것이다:
구분 | 심볼릭 링크(Symbolic Link) | 하드 링크(Hard Link) |
---|---|---|
참조 방식 | 대상 파일의 경로를 참조 | 대상 파일의 inode(데이터 블록)를 공유 |
대상이 사라질 경우 | 링크가 끊어지고 "죽은 링크"가 됨 | 영향 없음 (데이터는 여전히 존재함) |
디렉토리 링크 | 일반 사용자 권한으로는 불가 | 대부분의 시스템에서 제한됨 |
파일 시스템 경계 | 다른 파티션/파일 시스템 간 허용 | 동일 파일 시스템 내에서만 가능 |
inode 번호 | 링크와 원본이 서로 다름 | 링크와 원본이 동일함 |
따라서 심볼릭 링크는 구조적으로 더 유연하며, 경로 재지정, 디렉토리 연결, 파일 시스템 간 링크 등에 적합하다. 반면, 하드 링크는 안정적인 접근이 가능하지만 제약이 많아 일부 특수한 경우에만 사용된다.
ln -s
명령의 사용법심볼릭 링크는 Unix/Linux 시스템에서 ln -s
명령어를 통해 생성된다. 이 명령어는 다음과 같은 형식으로 사용된다:
ln -s [대상 파일 또는 디렉토리] [생성할 링크 이름]
ex)
ln -s /home/user/config.txt ~/config-link.txt
위 명령은 /home/user/config.txt
파일에 대한 심볼릭 링크를 사용자의 홈 디렉토리에 config-link.txt
라는 이름으로 생성한다.
생성된 심볼릭 링크는 내부적으로 다음과 같은 구조를 가진다:
l
타입의 파일로 표시되며, ->
기호 뒤에 참조 경로가 나타난다.예:
lrwxrwxrwx 1 user user 21 Apr 29 13:42 config-link.txt -> /home/user/config.txt
이 경우, config-link.txt
는 길이가 21인 경로 문자열을 담고 있으며, 접근 시 커널이 해당 경로를 따라 실제 파일을 참조한다.
심볼릭 링크는 대상 파일과 inode 번호가 다르며, 이는 곧 파일 시스템 내에서 독립적인 객체임을 의미한다. 링크는 단순히 텍스트 문자열로 대상 파일의 경로를 저장하고 있을 뿐이다.
이와는 달리 하드 링크는 대상 파일과 동일한 inode를 공유한다. 즉, 동일한 데이터를 가리키는 또 하나의 이름에 불과하다.
리눅스의 가상 파일 시스템(VFS)은 심볼릭 링크 파일을 열 때, 다음과 같은 과정을 거친다:
커널은 심볼릭 링크를 해석할 때 최대 해석 깊이(MAXSYMLINKS
, 보통 40회)까지 따라가며, 무한 루프나 순환 링크(Circular Link)가 발생하지 않도록 제한을 둔다. 예를 들어 A → B, B → C, C → A 형태로 링크가 순환하는 경우, 시스템은 이를 감지하고 Too many levels of symbolic links
오류를 발생시킨다.
심볼릭 링크 생성 시 대상 파일 경로를 절대경로 또는 상대경로로 지정할 수 있으며, 이 방식에 따라 링크의 특성과 유연성이 달라진다.
ln -s /usr/local/bin/tool ~/tool-link
/usr/local/bin/tool
)를 참조한다.cd ~/projects/
ln -s ../bin/tool tool-link
../bin/tool
)를 참조한다.항목 | 절대경로 링크 | 상대경로 링크 |
---|---|---|
참조 경로 기준 | 루트(/ )부터 시작 | 현재 링크 파일 위치 기준 |
유연성 | 낮음 (링크 대상 경로 고정) | 높음 (상대 경로 기반 재사용 가능) |
이동 후 유효성 | 대상 파일 위치가 바뀌면 무효화됨 | 링크 파일 또는 대상이 이동하면 무효화 가능성 있음 |
디렉토리 변경 영향 | 없음 | 있을 수 있음 |
대규모 시스템에서는 상대경로 링크를 통해 포터블 환경 구성이나 버전 관리, 컨테이너화된 경로 구성 등을 유연하게 설계할 수 있다. 반면, 고정된 시스템 경로나 루트 권한이 필요한 구성에서는 절대경로 링크가 보다 안정적으로 사용된다.
심볼릭 링크는 파일 시스템의 객체 중 하나로, 경로를 저장하는 특수한 파일이다. 운영체제는 사용자가 심볼릭 링크를 통해 파일이나 디렉토리에 접근할 때, 이를 자동으로 해석하여 원본 경로로 전달하는 역할을 수행한다.
사용자가 심볼릭 링크를 열거나 실행할 경우, 커널은 다음과 같은 단계로 작업을 처리한다:
VFS(Virtual File System)는 요청한 경로가 일반 파일인지, 디렉토리인지, 혹은 심볼릭 링크인지 판단한다.
심볼릭 링크라면, 해당 inode에 저장된 경로 문자열(pathname string) 을 추출한다.
추출된 경로를 기반으로 다시 경로 탐색을 수행한다. 이 과정은 다른 심볼릭 링크를 참조할 수도 있으며, 최대 허용 횟수(MAXSYMLINKS
, 일반적으로 40회)를 초과할 경우 오류가 발생한다.
대상이 존재한다면 해당 파일 또는 디렉토리 inode를 참조하여 작업을 수행한다. 대상이 없을 경우, ENOENT
(No such file or directory) 오류를 반환한다.
cat link.txt
link.txt
가 심볼릭 링크라면:/home/user/realfile.txt
라는 문자열을 갖고 있다면/home/user/realfile.txt
를 다시 탐색ls -l
: 링크 자체 정보를 출력 (lrwxrwxrwx
등)cat link.txt
: 링크를 해석하여 대상 파일의 내용을 출력rm link.txt
: 링크 파일을 삭제, 원본에는 영향 없음심볼릭 링크는 단지 경로를 담고 있는 파일에 불과하기 때문에, 링크 대상의 실제 존재 여부와 무관하게 남아 있을 수 있다. 이런 경우, 해당 링크는 Dangling Symbolic Link(죽은 링크, 깨진 링크)라고 한다.
예:
ln -s /tmp/test.txt mylink
rm /tmp/test.txt
cat mylink
cat
명령은 No such file or directory
오류를 반환한다.mylink
는 여전히 존재하지만, 내부의 참조 경로(/tmp/test.txt
)가 무효하기 때문에 기능하지 않는다.깨진 심볼릭 링크를 탐지하기 위한 대표적인 명령은 다음과 같다:
find . -xtype l
-xtype l
: 참조 대상이 없는 심볼릭 링크를 찾는다.심볼릭 링크는 다른 심볼릭 링크를 참조할 수 있기 때문에, 잘못 설계된 경우 루프(loop) 또는 순환 참조(circular reference) 를 유발할 수 있다.
ln -s B A
ln -s A B
cat A
ELOOP
오류를 반환한다.Too many levels of symbolic links
MAXSYMLINKS
(glibc 기준 40) 이상 시 루프라고 판단한다.fs.h
헤더 등)에서 정의된다.readlink -f A
find . -type l -exec readlink -f {} \;
명령 등을 통해 경로를 일괄 해석하여 수상한 순환을 찾을 수 있다.운영체제 및 파일 시스템은 심볼릭 링크를 처리하는 방식에 차이를 보인다. 이는 내부 구조, 메타데이터 처리 방식, 경로 해석 방법 등에 기인한다. 여기서는 대표적인 파일 시스템인 Linux의 ext4, Windows의 NTFS, 그리고 기타 POSIX 호환 파일 시스템을 중심으로 비교한다.
ext4는 유닉스 계열의 전통을 계승한 POSIX 호환 파일 시스템으로, 심볼릭 링크를 inode의 한 형태로 처리한다.
짧은 경로(60바이트 이하)는 inode의 블록 포인터 공간에 직접 저장된다(fast symlink).
긴 경로는 별도의 데이터 블록에 저장된다(slow symlink).
ls -l
명령 시 l
로 표시되며, 일반 파일이나 디렉토리와 구분된다.
따라서 파일 시스템 수준에서의 퍼미션, 타임스탬프 등을 가진다. 단, 링크된 대상이 아닌 링크 자체에 대한 속성이다.
NTFS는 Linux의 심볼릭 링크와 유사하지만 구조와 사용법에서 중요한 차이가 존재한다.
Windows는 symlink
외에도 junction
, hard link
, reparse point
등의 다양한 링크 형태를 지원한다. 이 중 심볼릭 링크(symlink) 는 Windows Vista 이후부터 공식 지원되었다.
PowerShell 또는 명령 프롬프트에서 mklink
명령을 사용:
mklink target source
→ 파일용 symlinkmklink /D target source
→ 디렉토리용 symlinkWindows에서는 일반 사용자에게 symlink 생성을 제한한다. 관리자 권한이 필요하거나, 그룹 정책을 조정해야 사용할 수 있다.
Reparse Point
구조체에 의해 구현되며, 외부 드라이브도 참조 가능링크임을 명확히 보여주지 않으며, 탐색기에서는 일반 폴더처럼 보일 수 있어 오해의 여지가 있다.
이들 파일 시스템은 심볼릭 링크를 자체적으로 지원하지 않는다.
NTFS 환경에서만 가능한 symlink는 exFAT, FAT32 등에서는 사용할 수 없다.
POSIX 호환 파일 시스템으로, Linux에서 심볼릭 링크를 완전히 지원한다.
Btrfs의 경우 스냅샷 기능과 결합되어 링크 무결성에 주의가 필요하다.
심볼릭 링크는 파일 시스템 계층을 넘어 참조할 수 있다는 점에서 매우 유연한 구조이나, 이로 인해 마운트 경계와 관련된 몇 가지 복잡성이 발생한다.
/mnt
, /home
, /var
등 서로 다른 디렉토리 경로에 마운트하여 사용한다.예: /data/file1
이 /data
가 마운트 되기 전에는 존재하지 않는 경로로 인식됨
chroot
또는 컨테이너 환경에서의 링크 무력화 심볼릭 링크가 루트 경로(/
)를 기준으로 작성된 경우, 격리된 환경에서는 대상 파일이 존재하지 않게 된다. 예: /etc/passwd
를 가리키는 링크는 chroot /var/jail
환경에서는 의미 없음
심볼릭 링크를 통해 루트 파일 시스템 외부 경로에 접근할 수 있기 때문에, tmp
디렉토리 등에 생성된 링크는 심볼릭 링크 공격(Symlink Attack) 의 경로가 될 수 있음.
nosymfollow
옵션을 지정하면, 해당 파일 시스템 내의 심볼릭 링크를 해석하지 않도록 제한할 수 있다.mount -o nosymfollow /dev/sdb1 /mnt/data
/tmp
디렉토리 등을 nosymfollow
로 마운트한다.AppArmor
, SELinux
등의 보안 정책에서도 심볼릭 링크 추적을 제한하는 정책이 존재한다.readlink -f
: 심볼릭 링크를 따라가 최종 경로 출력realpath
: 전체 경로를 정규화mountpoint
: 특정 디렉토리가 마운트 지점인지 확인realpath /mnt/data/linkfile
mountpoint -q /mnt/data && echo "Mounted"
항목 | ext4 (Linux) | NTFS (Windows) | FAT32 / exFAT |
---|---|---|---|
심볼릭 링크 지원 | O | O (Vista+) | X |
링크 표현 방식 | inode + 경로 문자열 | Reparse Point | - |
디렉토리 링크 지원 | O | O (mklink /D ) | X |
루트/마운트 경계 가능 | O | O | - |
보안 제약 | 낮음 (권한 기반) | 관리자 권한 필요 | - |
심볼릭 링크(Symlink)는 본래 경량화된 파일 참조 방식으로 설계되었으나, 경로 해석 과정에서의 취약성을 악용한 다양한 공격 기법들이 존재한다. 이를 통칭하여 심볼릭 링크 공격(Symlink Attack) 이라 한다. 이러한 공격은 주로 임시 파일, 권한 상이한 프로세스 간의 파일 처리, 경로 검증 미비 상황에서 발생한다.
/tmp
디렉토리에 악의적인 심볼릭 링크 tempfile
생성ln -s /etc/passwd /tmp/tempfile
/tmp/tempfile
을 임시 저장소로 쓰기/etc/passwd
파일이 변경됨 → 시스템 치명적 훼손이는 심볼릭 링크의 “투명한 경로 해석”이라는 특성이 보안 취약점으로 전이되는 전형적인 사례이다.
심볼릭 링크와 관련된 보안 취약점은 그 자체로 발생하기보다는, 다른 요소와의 결합 또는 설계 미숙으로 인해 시스템 전체의 보안성을 저하시킨다. 아래는 주요 취약점 유형과 대응 방안을 정리한 것이다.
TOCTOU는 "검사 시점과 사용 시점의 불일치"에 의한 취약점이다. 이는 시스템이 경로의 유효성을 확인한 후 그 경로를 다시 사용하기까지의 시간 사이에 링크 대상이 변경되는 경우를 의미한다.
// check
if (access("/tmp/myfile", W_OK) == 0) {
// use
fd = open("/tmp/myfile", O_WRONLY);
}
위 코드에서, access()
호출과 open()
사이에 /tmp/myfile
이 심볼릭 링크로 변조되면, 공격자는 공격 파일을 열게 만들 수 있다.
심볼릭 링크가 루트 권한의 프로그램과 사용자 권한이 혼합된 환경에서 사용될 경우, 악의적인 사용자는 의도치 않게 고권한 리소스에 접근하거나 수정할 수 있다.
/tmp
, /var/tmp
, /run
등 공용 쓰기 디렉토리 사용O_EXCL
, O_CREAT
, O_NOFOLLOW
조합 사용:fd = open("/tmp/myfile", O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
mkstemp()
, mkdtemp()
등의 안전한 함수 사용 권장심볼릭 링크는 ../
경로 해석과 결합될 경우, 경로 제한 우회의 수단이 된다. 이를 통해 제한된 디렉토리에서 시스템 전체를 탐색하거나 접근하는 것이 가능하다.
readlink
, stat
등을 통한 철저한 링크 대상 검증대응 방안 | 설명 |
---|---|
O_NOFOLLOW | 심볼릭 링크를 무시하고 open 실패 유도 |
fstat() / lstat() | 파일 종류 식별 및 실제 파일 검사 |
realpath() | 링크 해석 후 절대경로 확인 |
/tmp 쓰기 제한 | Sticky bit 설정 및 디렉토리 권한 강화 |
AppArmor / SELinux | 링크 추적 제한 정책 적용 가능 |
mkstemp() 등 안전한 함수 사용 | 링크 회피와 경쟁 조건 방지에 효과적 |
readlink
, realpath
, stat
등의 진단 명령심볼릭 링크(Symlink)는 파일 시스템에서 경로를 간접적으로 참조하는 구조이기 때문에, 링크의 대상 경로 확인, 링크 유효성 검사, 속성 점검 등의 작업이 필수적이다. 이때 사용되는 주요 명령어로는 readlink
, realpath
, stat
, lstat
등이 있으며, 각각의 기능과 활용 목적은 다음과 같다.
readlink
$ ln -s /etc/passwd mylink
$ readlink mylink
/etc/passwd
readlink
는 링크의 경로 정보만 출력하며, 대상 파일의 존재 여부나 실제 경로 해석은 수행하지 않는다.
realpath
$ realpath mylink
/etc/passwd
stat
와 lstat
stat
: 파일이나 심볼릭 링크가 가리키는 실제 파일의 메타데이터를 보여준다.lstat
: 심볼릭 링크 자체의 메타데이터를 보여준다.$ stat mylink
File: mylink -> /etc/passwd
Size: 11 Blocks: 0 IO Block: 4096 symbolic link
...
$ lstat mylink
File: mylink
Size: 11 Blocks: 0 IO Block: 4096 symbolic link
...
lstat
은 심볼릭 링크의 생성 시간, 소유자, 권한, 링크 크기 등의 정보를 확인할 수 있어 디버깅 시 유용하다.심볼릭 링크는 시스템 관리와 유지보수에서 매우 중요한 도구이지만, 신중한 관리가 필요한 양날의 검이다. 다음은 실무에서의 고급 활용과 그에 따르는 제약사항들이다.
버전 관리 및 디렉토리 추상화
/usr/bin/python
을 /usr/bin/python3.11
로 링크하여 특정 버전을 기본으로 설정공통 설정 파일 공유
/etc/nginx/sites-enabled/
→ /etc/nginx/sites-available/
구조 등루트 경로 이외 위치에 있는 리소스 연결
/home/user/webapp/static
→ /mnt/storage/static-resources
처럼 외부 저장소 자원을 내부 경로로 매핑마운트된 파일 시스템 간 연결
권한 해석 혼동 가능성
chmod
가 의도와 다르게 작동할 수 있음chmod 600 symlink
는 링크 자체에만 적용되며, 대상에는 적용되지 않음보안성
링크 유효성 문제
백업/복원 시의 문제
rsync -a
와 같이 링크 보존 옵션(-l
, -a
)을 정확히 이해하고 사용해야 함find . -xtype l
find / -type l -ls 2>/dev/null
[ -e "$(readlink symlink)" ] && echo "Valid" || echo "Broken"