synology / self-hosting / security / performance

운영 요령

sed -i 한 줄로 사이트 전체가 500이 된 이유: 시놀로지 ACL

시놀로지에서 sed -i로 설정 파일 13개를 고쳤더니 ACL이 사라져 권한이 000이 되고 사이트가 500을 낸 원인, 복구 방법, inode를 유지하는 수정 방식과 busybox grep --include 함정을 정리했습니다.

DB 계정 비밀번호를 바꾸고, 그 비밀번호를 쓰는 설정 파일 13개(워드프레스 wp-config.php 11개와 PHP 파일 2개)를 sed -i로 한꺼번에 고쳤습니다. 명령은 문제없이 끝났습니다.

그리고 그 파일을 쓰는 사이트가 전부 HTTP 500이 됐습니다. 비밀번호가 틀려서가 아니었습니다. 파일 권한이 000, 즉 아무도 못 읽는 상태가 돼 있었습니다.

sed -i는 파일을 고치지 않고 바꿔치기합니다

sed -i는 원래 파일을 그 자리에서 수정하는 게 아니라, 옆에 임시 파일을 새로 만들어 내용을 쓰고 원래 이름으로 바꿔치기합니다. 이름은 같지만 사실상 새 파일입니다.

시놀로지 공유 폴더의 파일은 일반 리눅스 권한(rwx) 말고 시놀로지 ACL로 권한을 관리하는 경우가 많습니다. ls -l로 보면 권한 문자열 끝에 +가 붙어 있는 파일이 그렇습니다.

ls -l wp-config.php
# -rwxrwxrwx+ 1 ... wp-config.php   ← 끝의 + 가 ACL 표시

바꿔치기로 생긴 새 파일에는 원래 파일의 ACL이 따라오지 않았습니다. 결과적으로 웹 서버(PHP)가 설정 파일을 못 읽었고, DB 접속 정보를 못 가져온 워드프레스가 500을 냈습니다.

바로 되살린 방법

소유자와 권한을 다시 줬습니다. 설정 파일은 비밀번호가 들어 있으니 좁게, 일반 PHP 파일은 읽기만 되게 했습니다.

# 워드프레스 설정 파일: 소유자 읽기/쓰기, 웹 그룹 읽기
chown <user>:http wp-config.php
chmod 640 wp-config.php

# 일반 웹 PHP 파일
chown <user>:http config.php
chmod 644 config.php

권한을 다시 준 즉시 사이트들이 돌아왔습니다. 비밀번호 변경 자체는 제대로 들어가 있었습니다. 원본 설정 파일은 고치기 전에 따로 백업해 뒀기 때문에, 권한을 되돌려도 안 되면 원본으로 돌릴 수 있는 상태였습니다.

다음부터는 inode를 유지하는 방식으로 고칩니다

핵심은 새 파일을 만들지 않고 기존 파일에 내용만 덮어쓰는 것입니다. 그러면 파일의 ACL, 소유자, 권한이 그대로 남습니다.

# 1) 결과를 임시 파일로 만든 뒤, cat 으로 원래 파일에 "내용만" 덮어쓰기
sed 's/old_value/new_value/' wp-config.php > /tmp/wpc.tmp
cat /tmp/wpc.tmp > wp-config.php
rm /tmp/wpc.tmp

# 2) 덮어쓴 뒤 권한이 유지됐는지 확인
ls -l wp-config.php

> 리다이렉트는 기존 파일을 열어 내용을 비우고 다시 쓰기 때문에 파일 자체(inode)는 바뀌지 않습니다. PHP로 고친다면 file_put_contents()도 같은 방식으로 동작합니다.

perl -i나 편집기의 "안전한 저장" 기능도 대부분 바꿔치기 방식이라 똑같은 문제가 생길 수 있습니다. 여러 파일을 한 번에 고칠 때는 먼저 한 개로 시험하고 ls -l로 확인한 다음 나머지를 돌리는 게 안전합니다.

같이 걸린 함정: busybox grep의 --include

고칠 파일 목록을 뽑을 때 또 하나 헛걸음을 했습니다. 이 작업은 Alpine 컨테이너 안에서 했는데, Alpine의 grep은 busybox 버전입니다. busybox grep은 GNU grep의 --include 옵션을 모르는데, 에러를 내지 않고 조용히 무시합니다.

# GNU grep이면 *.php 만 찾지만, busybox grep은 --include 를 무시하고 모든 파일을 뒤짐
grep -rl --include='*.php' 'DB_PASSWORD' /volume/web

결과가 틀려도 경고가 없으니 모르고 지나가기 쉽습니다. 파일 종류를 거르는 건 find에 맡기고, grep은 내용만 보게 나눴습니다.

find /volume/web -name 'wp-config.php' | while read -r f; do
  grep -l 'DB_USER' "$f"
done

이미 망가졌다면 대상 파일부터 찾습니다

여러 폴더에 걸쳐 고쳤다면 어느 파일이 망가졌는지부터 뽑는 게 빠릅니다. 권한이 전부 빠진 파일은 find로 바로 찾을 수 있습니다.

# 권한 비트가 전부 0인 PHP 파일
find /volume/web -name '*.php' -perm 000

# 최근 10분 안에 바뀐 wp-config.php
find /volume/web -name 'wp-config.php' -mmin -10 -exec ls -l {} \;

시놀로지 ACL 자체를 보려면 DSM에 들어 있는 synoacltool을 씁니다. 같은 폴더의 멀쩡한 파일과 비교하면 무엇이 빠졌는지 보입니다.

synoacltool -get wp-config.php

저는 ACL을 원래대로 되살리는 대신 소유자와 권한 비트를 명시적으로 주는 쪽을 택했습니다. 설정 파일 13개의 권한을 한 가지 규칙으로 맞춰 두는 편이 나중에 확인하기도 쉬웠습니다.

정리

시놀로지에서 설정 파일을 일괄 수정할 때 확인할 것
상황문제대신 쓸 방법
sed -i, perl -i새 파일로 바꿔치기해 ACL·소유자 유실결과를 임시 파일로 만든 뒤 cat tmp > 원본
busybox grep --include옵션이 조용히 무시됨find -name로 파일을 먼저 고름
수정 직후권한이 바뀌어도 명령은 성공으로 끝남ls -l로 + 표시와 권한 확인

명령이 에러 없이 끝났다고 끝난 게 아니었습니다. 시놀로지에서는 파일을 고친 뒤 권한까지 봐야 확인이 끝납니다.

확인한 공식 자료

구현 과정에서 판단 기준을 교차 확인한 공식 문서입니다. 글의 사례와 결론은 운영자가 직접 겪은 작업을 바탕으로 작성했습니다.