Haru Utils

NETWORK STORAGE · 설치·설정 레시피

NFS 서버·클라이언트 안전 구성

Ubuntu NFS 서버에 전용 공유 경로와 일관된 UID/GID 권한을 구성하고, export를 클라이언트 CIDR로 제한해 root squashing을 유지합니다. 임시 NFSv4 마운트와 쓰기를 검증한 뒤에만 fstab 자동 마운트를 반영합니다.
NFS 서버 설치NFS 클라이언트 마운트NFS exportsroot squashNFSv4 fstab
지원 환경Ubuntu Server 24.04 LTS NFS 서버
예상 시간45
난이도중급
검토일2026-08-28

BEFORE YOU START

시작 전에 준비하세요

01

서버·클라이언트 sudo 권한, 유지 중인 SSH 세션과 각 호스트의 콘솔 복구 경로

02

고정 사설 DNS·서버 사설 IP·정확한 클라이언트 CIDR과 상위 ACL

03

공유 데이터의 소유 팀·백업·복원 시험과 합의된 <SHARED_GID>

04

신뢰 경계 밖 네트워크라면 sec=sys 대신 Kerberos krb5p를 설계할 수 있는 KDC·DNS·시간 동기화

권장 대상 사설망 애플리케이션 서버 사이에 파일을 공유하고 권한·자동 마운트·복구까지 안전하게 구성하려는 운영자

FOLLOW THE RECIPE

8단계 구성·점검 레시피

1
확인시스템을 변경하지 않는 점검 단계

서버·클라이언트 환경과 ID 체계 확인

NFS의 기본 sec=sys 권한은 숫자 UID/GID에 의존합니다. 서버와 모든 클라이언트의 운영체제·NFS 지원·사용자 ID를 먼저 대조합니다.

서버 운영체제
cat /etc/os-release
uname -r
서버 NFS 지원
grep nfs /proc/filesystems
modinfo nfsd
서버 공유 사용자 ID
id <NFS_APP_USER>
getent group <SHARED_GID>
클라이언트 사용자 ID
id <NFS_APP_USER>
getent group <SHARED_GID>
이 명령은 각 클라이언트에서 실행합니다.
  • 서버와 클라이언트가 지원 중인 Ubuntu LTS다.
  • 동일한 업무 사용자가 모든 호스트에서 합의된 숫자 GID를 사용한다.
  • 클라이언트 CIDR이 넓은 사내 전체망이 아니라 실제 소비 호스트 범위다.
결과 읽기

이름이 같아도 숫자 UID/GID가 다르면 소유권이 엉뚱하게 보입니다. 디렉터리를 과도하게 개방하지 말고 ID 체계를 먼저 맞춥니다.

다음 판단

기존 export·마운트·포트·공유 경로 데이터를 점검합니다.

2
확인시스템을 변경하지 않는 점검 단계

기존 export·마운트·데이터 사전 점검

기존 NFS 서비스와 export를 기록하고 공유 경로가 올바른 전용 파일시스템인지 확인합니다. 클라이언트 마운트 지점은 비어 있어야 기존 파일이 가려지지 않습니다.

서버 기존 export
sudo exportfs -v
sudo cat /etc/exports
서버 서비스
systemctl status nfs-server.service --no-pager
서버 포트
sudo ss -lntup | grep -E ':(111|2049) '
공유 경로와 용량
sudo namei -l /srv/nfs/team
df -hT /srv/nfs/team
클라이언트 기존 마운트
findmnt /mnt/team
sudo find /mnt/team -mindepth 1 -maxdepth 1 -print -quit
클라이언트에서 실행합니다. 출력이 있으면 마운트 시 파일이 가려지므로 소유자 확인 전 진행하지 않습니다.
  • 기존 export가 있으면 소유 팀과 접속 중인 클라이언트를 확인했다.
  • /srv/nfs/team 데이터의 백업과 복원 시험이 있다.
  • /mnt/team은 기존 마운트가 없고 빈 디렉터리다.
  • 상위 ACL과 UFW에서 2049를 <NFS_CLIENT_CIDR>로 제한할 수 있다.
결과 읽기

활성 클라이언트가 있으면 export 변경은 중단을 일으킬 수 있습니다. 신규 경로·새 export로 검증한 뒤 계획된 유지보수 시간에 전환합니다.

다음 판단

서버와 클라이언트에 Ubuntu 지원 패키지를 설치합니다.

3
변경패키지·설정·서비스 상태가 달라지는 단계

NFS 서버·클라이언트 패키지 설치

서버에는 nfs-kernel-server, 클라이언트에는 nfs-common을 설치합니다. 변경 목록을 먼저 확인하고 무인 승인 없이 설치합니다.

변경 단계입니다. 대상 서버, 백업 파일, 서비스 중단 영향과 바로 이전 상태로 돌아가는 방법을 다시 확인하세요.
서버 패키지 인덱스
sudo apt-get update
서버 설치 미리 보기
apt-get --simulate install nfs-kernel-server
서버 패키지 설치
sudo apt-get install nfs-kernel-server
클라이언트 설치 미리 보기
apt-get --simulate install nfs-common
각 클라이언트에서 실행합니다.
클라이언트 패키지 설치
sudo apt-get install nfs-common
각 클라이언트에서 실행합니다.
설치 버전 확인
dpkg -l nfs-kernel-server nfs-common
  • 설치 미리 보기에 의도하지 않은 패키지 제거가 없다.
  • 서버와 클라이언트에 필요한 패키지만 설치했다.
  • 설치만으로 외부 export를 만들지 않았다.
결과 읽기

패키지 설치 후 서비스가 자동 기동돼도 export가 없으면 공유되지는 않습니다. 포트를 넓게 열기 전에 경로와 export를 먼저 구성합니다.

다음 판단

공유 그룹·경로 권한과 CIDR 제한 export를 구성합니다.

4
주의권한·연결·중단 영향을 확인할 단계

공유 경로 권한과 root-squashed export 구성

공유 그룹의 숫자 GID를 고정하고 디렉터리에 setgid를 적용해 새 파일의 그룹을 유지합니다. export는 정확한 클라이언트 CIDR만 허용하고 root_squash와 동기 쓰기를 명시합니다.

고유 백업 접미사
date -u +%Y%m%dT%H%M%SZ
exports 백업
sudo cp --preserve=all --no-clobber /etc/exports /etc/exports.<BACKUP_SUFFIX>.bak
공유 GID 충돌 확인
getent group <SHARED_GID>
getent group nfs-share
공유 그룹 생성
sudo groupadd --gid <SHARED_GID> nfs-share
해당 GID와 그룹이 아직 없을 때만 실행합니다. 기존 그룹을 임의로 바꾸지 않습니다.
업무 사용자 그룹 추가
sudo usermod -aG nfs-share <NFS_APP_USER>
각 클라이언트의 GID 충돌 확인
getent group <SHARED_GID>
getent group nfs-share
승인된 각 NFS 클라이언트에서 실행합니다. 같은 숫자 GID가 다른 그룹에 사용 중이면 변경을 중단하고 ID 체계를 조정합니다.
각 클라이언트에 동일 그룹 생성
sudo groupadd --gid <SHARED_GID> nfs-share
해당 GID와 그룹이 없는 클라이언트에서만 실행합니다. 중앙 ID 관리 환경이면 로컬 그룹 대신 기존 체계를 사용합니다.
각 클라이언트 업무 사용자 그룹 추가
sudo usermod -aG nfs-share <NFS_APP_USER>
새 그룹 멤버십은 신규 로그인 세션에서 확인하며 현재 관리 세션을 종료하지 않습니다.
공유 경로 준비
sudo install -d -o root -g nfs-share -m 2770 /srv/nfs/team
exports 편집
sudoedit /etc/exports
export 적용 검사
sudo exportfs -rav
구문 오류가 있으면 방화벽을 열지 말고 백업본과 비교해 수정합니다.
설정 예시 · /etc/exports
신뢰된 클라이언트 CIDR만 허용하는 공유
/srv/nfs/team <NFS_CLIENT_CIDR>(rw,sync,no_subtree_check,root_squash,secure)
<NFS_CLIENT_CIDR>는 실제 소비 서버 대역으로 교체합니다. 여러 대역은 각각 별도 client(options) 항목으로 명시하고 와일드카드 전체 허용을 사용하지 않습니다.
  • 서버·클라이언트의 nfs-share GID가 동일하다.
  • 공유 경로는 root:nfs-share와 2770 권한이다.
  • export가 정확한 CIDR과 root_squash를 사용한다.
  • async와 no_root_squash를 사용하지 않았다.
결과 읽기

exportfs 오류가 있으면 서비스 재시작 전에 /etc/exports 문법을 고칩니다. root_squash는 클라이언트 root가 서버 root 권한으로 쓰는 위험을 줄입니다.

다음 판단

export와 서비스를 적용하고 서버에서 실제 상태를 확인합니다.

5
변경패키지·설정·서비스 상태가 달라지는 단계

NFS 서비스 시작과 export 적용

현재 SSH 세션과 콘솔을 유지한 상태에서 export를 적용하고 서비스를 활성화합니다. export 목록이 계획한 경로·CIDR·옵션과 정확히 일치해야 합니다.

변경 단계입니다. 대상 서버, 백업 파일, 서비스 중단 영향과 바로 이전 상태로 돌아가는 방법을 다시 확인하세요.
export 적용
sudo exportfs -rav
서비스 활성화와 시작
sudo systemctl enable --now nfs-server.service
서비스 상태
systemctl status nfs-server.service --no-pager
적용 export
sudo exportfs -v
최근 로그
sudo journalctl -u nfs-server.service -n 100 --no-pager
  • nfs-server.service가 active와 enabled 상태다.
  • exportfs -v에 계획한 한 경로와 CIDR만 보인다.
  • root_squash와 sync가 유효하다.
결과 읽기

예상하지 못한 export가 보이면 방화벽을 열지 말고 /etc/exports와 /etc/exports.d의 소유자를 확인합니다.

다음 판단

2049를 승인 CIDR에만 열고 임시 마운트·권한을 검증합니다.

6
주의권한·연결·중단 영향을 확인할 단계

임시 NFSv4 마운트 후 fstab 영구 반영

방화벽을 클라이언트 CIDR로 제한한 뒤 임시 마운트와 비-root 사용자 쓰기를 먼저 검증합니다. 성공 후에만 fstab을 백업·편집하고 systemd 구문 검사를 수행합니다.

서버 2049 CIDR 허용
sudo ufw allow from <NFS_CLIENT_CIDR> to <NFS_SERVER_PRIVATE_IP> port 2049 proto tcp
현재 SSH 세션·콘솔과 같은 상위 ACL 제한을 유지합니다.
클라이언트 마운트 지점
sudo install -d -o root -g root -m 0755 /mnt/team
클라이언트 임시 NFSv4 마운트
sudo mount -t nfs4 -o vers=4.2,nosuid,nodev <NFS_SERVER_PRIVATE_DNS>:/srv/nfs/team /mnt/team
마운트 결과
findmnt /mnt/team
nfsstat -m
업무 사용자 쓰기 시험
sudo -u <NFS_APP_USER> touch /mnt/team/<CHANGE_ID>.write-test
stat /mnt/team/<CHANGE_ID>.write-test
고유 변경 ID의 비민감 빈 파일을 사용하고 정상 검증 후 공유 운영 절차로 정리합니다.
영구 설정 전 임시 마운트 해제
sudo fuser -vm /mnt/team
sudo umount /mnt/team
열린 파일이나 작업이 없음을 확인한 뒤 해제합니다. 해제 실패를 강제 옵션으로 우회하지 않습니다.
클라이언트 fstab 백업
sudo cp --preserve=all --no-clobber /etc/fstab /etc/fstab.<BACKUP_SUFFIX>.bak
클라이언트 fstab 편집
sudoedit /etc/fstab
fstab 검증과 반영
sudo findmnt --verify --verbose && sudo systemctl daemon-reload && sudo mount /mnt/team
설정 예시 · /etc/fstab
네트워크 준비 이후 자동 마운트하는 NFSv4 항목
<NFS_SERVER_PRIVATE_DNS>:/srv/nfs/team /mnt/team nfs4 rw,vers=4.2,_netdev,nofail,x-systemd.automount,nosuid,nodev 0 0
각 클라이언트에 반영합니다. 실행 파일이 필요한 공유라면 noexec 여부를 별도 위험 검토하되 nosuid·nodev는 유지합니다.
  • 승인 CIDR에서 NFSv4.2 임시 마운트가 성공한다.
  • 비-root 업무 사용자가 쓰고 서버에서 기대한 GID로 보인다.
  • 클라이언트 root가 서버 root 소유 파일을 임의로 만들 수 없다.
  • findmnt --verify가 성공한 뒤에만 fstab을 반영했다.
  • 비승인 네트워크에서는 2049에 접근할 수 없다.
결과 읽기

permission denied는 전체 권한을 풀 문제가 아니라 UID/GID, 디렉터리 execute 권한, export 옵션을 순서대로 확인할 문제입니다.

다음 판단

신뢰 경계·백업·마운트 옵션과 장애 시 동작을 최종 점검합니다.

7
주의권한·연결·중단 영향을 확인할 단계

신뢰 경계·권한·복구 운영 점검

sec=sys NFS는 네트워크와 숫자 UID/GID를 신뢰합니다. 신뢰할 수 없는 구간이나 사용자 단위 강한 인증이 필요하면 Kerberos krb5p로 전환합니다.

서버 export 최종 상태
sudo exportfs -v
공유 경로 권한
sudo namei -l /srv/nfs/team
sudo getfacl -p /srv/nfs/team
클라이언트 마운트 옵션
findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /mnt/team
서버 접속 통계
nfsstat --server
방화벽
sudo ufw status numbered
  • export는 정확한 사설 CIDR만 허용하고 root_squash를 유지한다.
  • 공유 경로와 하위 파일에 world-write 권한이 없다.
  • 클라이언트는 nosuid·nodev와 필요한 경우 noexec를 사용한다.
  • 신뢰 경계 밖에서는 Kerberos krb5p 없이 NFS를 사용하지 않는다.
  • 서버 데이터 백업·복원 시험과 클라이언트 장애 시 애플리케이션 동작 기준이 있다.
결과 읽기

방화벽 CIDR만으로 사용자 신원을 증명할 수는 없습니다. 높은 보안 요구에서는 Kerberos, 전용 네트워크, 저장 데이터 암호화를 함께 설계합니다.

다음 판단

서버 export와 클라이언트 fstab을 양쪽에서 되돌릴 절차를 확인합니다.

8
주의권한·연결·중단 영향을 확인할 단계

클라이언트 마운트와 서버 export 롤백

클라이언트 사용을 중단하고 열린 파일을 확인한 뒤 마운트를 해제합니다. 각 클라이언트 fstab과 서버 exports의 선택한 백업을 복원하고 이번 방화벽 규칙만 제거합니다.

클라이언트 사용 프로세스 확인
sudo fuser -vm /mnt/team
클라이언트 마운트 해제
sudo umount /mnt/team
클라이언트 fstab 백업 확인
sudo test -f /etc/fstab.<BACKUP_SUFFIX>.bak
현재 fstab 보존
sudo cp --preserve=all --no-clobber /etc/fstab /etc/fstab.failed.<ROLLBACK_SUFFIX>
클라이언트 fstab 복원
sudo cp --preserve=all /etc/fstab.<BACKUP_SUFFIX>.bak /etc/fstab
sudo findmnt --verify --verbose && sudo systemctl daemon-reload
서버 exports 백업 확인
sudo test -f /etc/exports.<BACKUP_SUFFIX>.bak
현재 exports 보존
sudo cp --preserve=all --no-clobber /etc/exports /etc/exports.failed.<ROLLBACK_SUFFIX>
서버 exports 복원·적용
sudo cp --preserve=all /etc/exports.<BACKUP_SUFFIX>.bak /etc/exports
sudo exportfs -rav && sudo exportfs -v
이번 2049 규칙 제거
sudo ufw delete allow from <NFS_CLIENT_CIDR> to <NFS_SERVER_PRIVATE_IP> port 2049 proto tcp
  • 클라이언트 쓰기를 중단하고 열린 파일을 확인한 뒤 마운트를 해제했다.
  • 클라이언트와 서버에서 같은 작업의 백업 접미사를 명시적으로 선택했다.
  • 복원 전 현재 fstab과 exports도 별도 보존했다.
  • exportfs와 findmnt 검증이 성공한 뒤 이번 방화벽 규칙만 제거했다.
  • 공유 데이터 디렉터리는 삭제·이동하지 않았다.
결과 읽기

umount가 busy이면 강제 해제보다 사용 프로세스와 영향 범위를 확인합니다. 복원 후 기존 클라이언트의 읽기·쓰기를 다시 검증합니다.

다음 판단

포트·권한·DNS·네트워크 장애 대응 가이드로 이어갑니다.

SECURITY CHECK

운영 전 마지막 보안 점검

  • export를 정확한 사설 클라이언트 CIDR로 제한하고 root_squash를 유지한다.
  • 서버·클라이언트 숫자 UID/GID를 일관되게 관리하고 world-write를 사용하지 않는다.
  • 클라이언트 마운트에 nosuid·nodev와 업무에 맞는 noexec를 적용한다.
  • 신뢰할 수 없는 네트워크에서는 Kerberos krb5p 없이 sec=sys NFS를 사용하지 않는다.
  • 백업·복원 시험과 서버·네트워크 장애 시 클라이언트 애플리케이션 동작을 검증한다.

COMMON ERRORS

자주 막히는 지점

mount.nfs access denied by server

증상
클라이언트 마운트가 access denied by server while mounting 오류로 실패합니다.
가능한 원인
export 경로, 클라이언트 CIDR, 적용되지 않은 exports 또는 DNS 경로가 다릅니다.
확인 순서
서버 exportfs -v와 실제 클라이언트 출발지 IP를 비교하고 exportfs -rav 오류를 확인합니다.
트러블슈팅으로 이어보기

마운트는 되지만 쓰기 권한 없음

증상
목록 조회는 되지만 업무 사용자의 파일 생성이 Permission denied로 실패합니다.
가능한 원인
서버·클라이언트 UID/GID 불일치 또는 공유 경로의 그룹·execute 권한이 다릅니다.
확인 순서
id, getent, namei, getfacl로 숫자 ID와 전체 경로 권한을 비교하고 과도한 권한으로 우회하지 않습니다.
트러블슈팅으로 이어보기

부팅 후 NFS 마운트 지연

증상
클라이언트 부팅이 늦거나 네트워크 준비 전에 마운트가 실패합니다.
가능한 원인
fstab에 _netdev·automount·nofail이 없거나 DNS·서버 가용성이 늦습니다.
확인 순서
콘솔에서 fstab을 복원하고 systemd mount/automount 상태와 DNS·2049 경로를 확인합니다.
트러블슈팅으로 이어보기

PRIMARY REFERENCES

공식 문서

설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.

도구 빠른 검색

최근 사용한 도구를 다시 열거나, 이름과 기능으로 검색하세요.

검색어와 도구의 입력·결과는 저장하지 않습니다.

↑↓ 이동 · Enter 열기 · Esc 닫기