서버에 파일을 올린 뒤 Permission denied가 나오거나, Nginx에서 정적 파일이 보이지 않거나, 쉘 스크립트가 실행되지 않을 때 가장 먼저 떠올리는 명령이 chmod 755입니다. 이 글은 755가 어떤 권한인지 설명하는 데서 끝내지 않고, 실제 Debian/Ubuntu 계열 VPS에서 권한 오류를 확인하고 필요한 대상에만 안전하게 적용하는 순서를 정리합니다.
이 글에서 해결할 문제
리눅스 파일 권한 문제는 겉으로 보기에는 단순합니다. 파일이 안 열리면 권한을 주면 될 것처럼 보입니다. 하지만 서버 운영 중에는 파일 권한, 디렉토리 권한, 소유자, 그룹, 실행 사용자, 상위 경로 권한이 함께 얽혀 있는 경우가 많습니다.
특히 웹 서버나 Node.js 앱을 운영하다 보면 내 SSH 계정에서는 파일이 잘 보이는데, Nginx나 서비스 계정에서는 접근하지 못하는 일이 생깁니다. 이때 바로 chmod 755를 실행하기보다, 먼저 누가 어떤 경로에 접근하려는지 확인해야 같은 문제가 반복되지 않습니다.
먼저 확인할 핵심 요약
755는 소유자에게 읽기, 쓰기, 실행 권한을 주고 그룹과 기타 사용자에게 읽기, 실행 권한을 주는 값입니다.- 디렉토리의 실행 권한은 파일 실행이 아니라 그 디렉토리 안으로 진입할 수 있는 권한에 가깝습니다.
- 일반 문서, 설정 파일, 이미지 파일은 보통 실행 권한이 필요하지 않으므로 무조건 755가 정답은 아닙니다.
- 웹 서버가 접근하는 파일은 권한뿐 아니라 소유자와 서비스 실행 계정도 함께 확인해야 합니다.
- 운영 서버에서
chmod -R 755처럼 전체 경로에 일괄 적용하는 작업은 예상보다 많은 파일을 열 수 있으므로 주의해야 합니다.
chmod 755 뜻
chmod는 파일이나 디렉토리의 권한을 변경하는 명령어입니다. 숫자 755는 세 자리로 나뉘며, 각각 소유자, 그룹, 기타 사용자의 권한을 뜻합니다.
| 숫자 | 대상 | 권한 | 문자 표기 |
|---|---|---|---|
| 7 | 소유자 | 읽기, 쓰기, 실행 | rwx |
| 5 | 그룹 | 읽기, 실행 | r-x |
| 5 | 기타 사용자 | 읽기, 실행 | r-x |
숫자 권한은 각 권한 값을 더해서 만듭니다. 읽기는 4, 쓰기는 2, 실행은 1입니다. 그래서 7은 4+2+1, 5는 4+1입니다.
읽기 r = 4
쓰기 w = 2
실행 x = 1
7 = 4 + 2 + 1 = rwx
5 = 4 + 0 + 1 = r-x
실제 서버 운영 중 헷갈리기 쉬운 지점
처음에는 Permission denied만 보고 파일 실행 권한이 없다고 판단하기 쉽습니다. 하지만 실제 원인은 파일이 아니라 상위 디렉토리 권한인 경우도 많습니다. 예를 들어 /var/www/app/public/index.html 파일 권한이 맞더라도, 중간 경로인 /var/www/app에 접근 권한이 없으면 웹 서버가 파일까지 도달하지 못할 수 있습니다.
또 하나 자주 놓치는 부분은 현재 SSH 사용자와 실제 서비스를 실행하는 사용자가 다르다는 점입니다. Ubuntu에서 Nginx는 보통 www-data 계정으로 동작하는 경우가 많고, Node.js 앱은 PM2나 systemd 설정에 따라 별도 사용자로 실행될 수 있습니다. 내 계정에서는 읽히는 파일이 서비스 계정에서는 막히는 상황이 여기서 생깁니다.
처음 의심하기 쉬운 원인과 실제 원인의 차이
| 겉으로 보이는 증상 | 처음 의심하기 쉬운 원인 | 실제로 자주 확인해야 하는 부분 |
|---|---|---|
./deploy.sh: Permission denied |
스크립트 실행 권한 없음 | 파일 권한, 현재 사용자, 파일 시스템 마운트 옵션, 스크립트 경로 |
| Nginx 403 Forbidden | Nginx 설정 오류 | root 경로, index 파일 존재 여부, 파일 소유자, 디렉토리 실행 권한 |
| 앱에서 로그 파일 생성 실패 | 앱 코드 오류 | 로그 디렉토리 쓰기 권한, 앱 실행 사용자, 소유자 불일치 |
| 파일은 있는데 웹에서 열리지 않음 | 파일이 깨졌거나 업로드 실패 | 상위 경로 권한, 웹 서버 계정 접근 권한, SELinux/AppArmor 등 환경별 보안 정책 |
실제로 자주 막히는 상황
- 배포 스크립트에 실행 권한이 없어
./deploy.sh실행이 실패하는 경우 /var/www아래 파일을 올렸지만 Nginx에서 403이 나는 경우- 디렉토리에는 들어가야 하는데 상위 경로 중 하나에 실행 권한이 없어 막히는 경우
- SSH로 접속한 사용자와 서비스 실행 사용자가 달라 권한 판단이 어긋나는 경우
- 일반 파일까지 모두 755로 바꿔 불필요하게 실행 권한이 열린 경우
원인 분리: chmod를 실행하기 전에 보는 순서
권한을 바꾸기 전에 현재 상태부터 확인해야 합니다. 운영 서버에서는 원인을 모른 채 권한을 넓히면 문제는 잠깐 사라져도 보안상 좋지 않은 상태가 남을 수 있습니다.
1. 현재 사용자 확인
whoami
id
출력 예시는 다음과 같습니다.
ubuntu
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),27(sudo)
현재 명령을 실행하는 사용자가 누구인지 먼저 확인합니다. 파일 소유자가 root인데 일반 사용자로 수정하려 하면 권한 오류가 날 수 있습니다. 이때도 바로 권한을 넓히기보다 소유자와 작업 목적을 먼저 확인하는 것이 안전합니다.
2. 파일인지 디렉토리인지 확인
ls -l deploy.sh
ls -ld /var/www/app
file deploy.sh
예시 출력입니다.
-rw-r--r-- 1 ubuntu ubuntu 845 May 11 10:20 deploy.sh
drwxr-xr-x 3 ubuntu ubuntu 4096 May 11 10:20 /var/www/app
deploy.sh: Bourne-Again shell script, ASCII text executable
ls -l에서 첫 글자가 -이면 일반 파일, d이면 디렉토리입니다. 같은 755라도 파일에 적용하는 의미와 디렉토리에 적용하는 의미가 다릅니다.
3. 상위 경로 권한 확인
파일 자체 권한이 맞아도 상위 디렉토리 권한 때문에 막힐 수 있습니다. 이때는 namei 명령이 도움이 됩니다.
namei -l /var/www/app/public/index.html
예시 출력입니다.
f: /var/www/app/public/index.html
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-x--- ubuntu ubuntu app
drwxr-xr-x ubuntu ubuntu public
-rw-r--r-- ubuntu ubuntu index.html
위 예시에서 app 디렉토리가 drwxr-x---라면 기타 사용자는 접근할 수 없습니다. Nginx가 www-data로 동작하고 이 그룹에 포함되어 있지 않다면 파일까지 도달하지 못할 수 있습니다.
4. 웹 서버나 서비스 실행 사용자 확인
Ubuntu에서 Nginx를 사용한다면 보통 www-data 계정을 확인합니다. 환경에 따라 다를 수 있으므로 실제 프로세스 기준으로 보는 것이 좋습니다.
ps -eo user,comm,args | grep nginx | grep -v grep
예시 출력입니다.
root nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data nginx: worker process
www-data nginx: worker process
마스터 프로세스는 root로 보일 수 있지만, 실제 요청을 처리하는 워커 프로세스가 www-data인 경우가 많습니다. 그래서 파일 접근 권한을 판단할 때는 워커 프로세스의 사용자도 함께 봐야 합니다.
잘못된 예시
권한 문제를 빨리 해결하려고 전체 디렉토리에 넓은 권한을 주는 경우가 있습니다. 특히 운영 서버에서는 아래와 같은 방식은 신중해야 합니다.
chmod -R 755 /var/www/app
이 명령은 /var/www/app 아래의 모든 파일과 디렉토리에 755를 적용합니다. 디렉토리에는 적절할 수 있지만, 일반 설정 파일이나 업로드 파일에도 실행 권한이 붙을 수 있습니다. 범위가 넓은 명령은 되돌리기 어렵고, 의도하지 않은 파일까지 노출될 수 있으므로 적용 전에 반드시 현재 권한을 확인해야 합니다.
또 다른 잘못된 판단은 Nginx 403을 보고 곧바로 Nginx 설정만 수정하는 것입니다. 서버 운영에서는 403이 웹 서버 설정 문제처럼 보이지만 실제로는 root 경로와 실제 파일 위치가 다르거나, 파일은 있어도 웹 서버 계정이 상위 디렉토리를 통과하지 못하는 경우가 많습니다.
수정 예시
아래 예시는 Debian/Ubuntu 계열을 기준으로 설명합니다. CentOS, Rocky Linux, AlmaLinux 등에서는 웹 서버 계정명이나 로그 위치가 다를 수 있습니다.
예시 1. 쉘 스크립트 실행 권한 부여
먼저 현재 권한과 파일 종류를 확인합니다.
ls -l deploy.sh
file deploy.sh
head -n 1 deploy.sh
예시 출력입니다.
-rw-r--r-- 1 ubuntu ubuntu 845 May 11 10:20 deploy.sh
deploy.sh: Bourne-Again shell script, ASCII text executable
#!/usr/bin/env bash
실행해야 하는 스크립트가 맞고, 다른 사용자도 읽고 실행해야 하는 상황이라면 755를 적용할 수 있습니다.
chmod 755 deploy.sh
ls -l deploy.sh
수정 후에는 다음처럼 보여야 합니다.
-rwxr-xr-x 1 ubuntu ubuntu 845 May 11 10:20 deploy.sh
단, 개인 작업용 스크립트라면 모든 사용자에게 실행 권한을 줄 필요가 없을 수 있습니다. 그런 경우에는 chmod 700 deploy.sh처럼 소유자만 실행 가능하게 하는 방식도 검토할 수 있습니다.
예시 2. 웹 디렉토리 접근 권한 확인
Nginx에서 정적 파일이 403으로 보이는 경우, 설정을 바꾸기 전에 파일 위치와 권한을 확인합니다.
ls -ld /var/www/app
ls -ld /var/www/app/public
ls -l /var/www/app/public/index.html
namei -l /var/www/app/public/index.html
디렉토리는 웹 서버가 통과할 수 있어야 하므로 상황에 따라 755가 필요할 수 있습니다.
chmod 755 /var/www/app
chmod 755 /var/www/app/public
일반 HTML 파일은 실행 권한이 필요하지 않은 경우가 많습니다. 보통은 읽기 권한만 있으면 됩니다.
chmod 644 /var/www/app/public/index.html
위 예시는 디렉토리와 일반 파일을 구분해서 적용한 것입니다. 모든 파일에 755를 주는 것보다 의도가 명확합니다.
예시 3. 소유자 문제와 권한 문제를 구분
권한 숫자가 맞아도 소유자가 맞지 않으면 업로드나 로그 생성이 실패할 수 있습니다. 먼저 소유자를 확인합니다.
ls -ld /var/www/app/uploads
ps -eo user,comm,args | grep nginx | grep -v grep
예시 출력입니다.
drwxr-xr-x 2 root root 4096 May 11 10:20 /var/www/app/uploads
www-data nginx: worker process
웹 서버가 업로드 디렉토리에 파일을 생성해야 한다면 읽기와 실행만으로는 부족하고 쓰기 권한도 필요합니다. 이 경우 단순히 755를 반복 적용하는 것보다 소유자나 그룹 설계를 먼저 확인해야 합니다. 소유자 변경은 서비스 동작에 영향을 줄 수 있으므로, 적용 전 현재 상태를 기록해 두는 것이 좋습니다.
stat /var/www/app/uploads
소유자 변경이 필요한 상황이라면 운영 정책에 맞게 제한적으로 적용합니다. 예를 들어 해당 디렉토리를 웹 서버가 관리해야 하는 구조라면 다음과 같은 방식이 사용될 수 있습니다.
sudo chown www-data:www-data /var/www/app/uploads
sudo chmod 755 /var/www/app/uploads
sudo chown은 파일 소유자를 바꾸는 명령이므로 운영 서버에서는 적용 범위를 정확히 지정해야 합니다. 특히 -R 옵션으로 전체 하위 경로를 변경하기 전에는 어떤 파일이 포함되는지 반드시 확인해야 합니다.
수정 후 확인 방법
권한을 바꾼 뒤에는 명령이 성공했는지만 보지 말고 실제 서비스 관점에서 다시 확인해야 합니다.
1. 권한 문자열 확인
ls -l deploy.sh
ls -ld /var/www/app /var/www/app/public
예상 출력입니다.
-rwxr-xr-x 1 ubuntu ubuntu 845 May 11 10:20 deploy.sh
drwxr-xr-x 3 ubuntu ubuntu 4096 May 11 10:20 /var/www/app
drwxr-xr-x 2 ubuntu ubuntu 4096 May 11 10:20 /var/www/app/public
2. 실행 테스트
./deploy.sh
스크립트가 실행되지 않는다면 권한 외에도 셸 지정, 현재 작업 디렉토리, 내부 명령 권한을 확인해야 합니다.
3. 웹 서버 로그 확인
Nginx 403이나 접근 실패가 계속된다면 브라우저 화면만 보지 말고 로그를 함께 확인합니다.
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx --since "10 minutes ago" --no-pager
sudo tail -n 50 /var/log/nginx/error.log
로그에 Permission denied, directory index of ... is forbidden, open() ... failed 같은 메시지가 있으면 파일 위치, 디렉토리 권한, Nginx 설정의 root 경로를 함께 봐야 합니다. 환경에 따라 로그 파일 위치는 다를 수 있습니다.
4. 로컬에서 직접 접근 확인
웹 서버가 정상 응답하는지 서버 내부에서 확인할 수 있습니다.
curl -I http://localhost/
외부에서는 안 되지만 서버 내부에서는 응답한다면 권한 문제가 아니라 프록시, 방화벽, 클라우드 보안 그룹, DNS 문제가 섞여 있을 수 있습니다. 다만 이 글의 범위에서는 파일 권한과 접근 계정 확인에 집중하면 됩니다.
파일과 디렉토리에 755를 적용할 때의 기준
| 대상 | 755가 적절할 수 있는 경우 | 주의할 점 |
|---|---|---|
| 쉘 스크립트 | 여러 사용자가 읽고 실행해야 하는 배포 스크립트 | 개인용이거나 민감한 명령이 들어 있으면 더 제한적인 권한을 검토 |
| 웹 루트 디렉토리 | 웹 서버가 경로를 통과하고 정적 파일을 읽어야 하는 경우 | 업로드/캐시 디렉토리는 쓰기 권한 설계가 별도로 필요할 수 있음 |
| 일반 HTML, CSS, JS 파일 | 대부분 755까지 필요하지 않음 | 보통 644처럼 읽기 중심 권한으로 충분한 경우가 많음 |
| 설정 파일 | 일반적으로 755 대상이 아님 | 비밀번호, 토큰, API 키가 있으면 더 제한해야 함 |
재발 방지 체크리스트
- 권한을 바꾸기 전에
ls -l,ls -ld,namei -l로 현재 상태를 확인했는가 - 대상이 일반 파일인지 디렉토리인지 구분했는가
- 실행 권한이 실제로 필요한 파일인지 확인했는가
- SSH 사용자와 서비스 실행 사용자가 다른지 확인했는가
- 웹 서버 계정이 상위 디렉토리를 통과할 수 있는지 확인했는가
- 권한 문제인지, 소유자 문제인지, 경로 문제인지 분리했는가
- 운영 서버에서
-R옵션을 쓰기 전에 적용 범위를 확인했는가 - 수정 후 로그와 실제 서비스 응답을 확인했는가
chmod 755는 리눅스 서버에서 자주 쓰이는 권한이지만, 모든 파일에 적용하는 만능값은 아닙니다. 파일은 실행 권한이 필요한지, 디렉토리는 통과 권한이 필요한지, 웹 서버나 서비스가 어떤 사용자로 동작하는지까지 함께 봐야 안전하게 문제를 좁힐 수 있습니다. 권한 숫자를 외우는 것보다 현재 사용자, 소유자, 경로, 서비스 계정을 순서대로 확인하는 습관이 운영 중 장애를 줄이는 데 더 도움이 됩니다.
FAQ
Q1. chmod 755와 chmod 644의 차이는 무엇인가요?
755는 소유자에게 읽기, 쓰기, 실행 권한을 주고 그룹과 기타 사용자에게 읽기, 실행 권한을 줍니다. 644는 소유자에게 읽기, 쓰기 권한을 주고 그룹과 기타 사용자에게 읽기 권한만 줍니다. 일반 HTML, CSS, 이미지, 설정 파일은 실행할 필요가 없으므로 644가 더 적절한 경우가 많고, 실행 스크립트나 디렉토리는 상황에 따라 755가 필요할 수 있습니다.
Q2. 디렉토리에 실행 권한이 왜 필요한가요?
디렉토리의 실행 권한은 프로그램 실행이 아니라 그 디렉토리 안으로 들어가거나 하위 경로를 통과할 수 있는 권한에 가깝습니다. 파일 권한이 맞아도 상위 디렉토리에 실행 권한이 없으면 해당 파일에 접근하지 못할 수 있습니다. 그래서 웹 루트나 배포 경로 문제를 볼 때는 파일뿐 아니라 상위 디렉토리 권한도 함께 확인해야 합니다.
Q3. Permission denied가 나오면 바로 chmod 755를 실행해도 되나요?
먼저 whoami, id, ls -l, ls -ld, namei -l로 현재 사용자, 파일 권한, 소유자, 상위 경로를 확인하는 것이 좋습니다. 실행 파일이 아니라면 755가 필요하지 않을 수 있고, 실제 원인이 소유자나 서비스 실행 계정 불일치일 수도 있습니다. 운영 서버에서는 권한을 넓히기 전에 원인을 분리한 뒤 필요한 경로에만 제한적으로 적용하는 편이 안전합니다.