kh교육

(20250819038)NFS, tcp

boangod 2025. 8. 19. 23:29

NFS 

■  네트워크를 통해 파티션을 공유할 수 있도록 제공하는 서비스( nfs하드드라이브를 자신의 하드드라이브처럼 사용할수있도록 해주는것 )

■  Sun사에서 개발되어 대부분의 유닉스에서 사용

■  유닉스 계열의 거의 모든 시스템에서 공유 가능

 

만들기 쉬움, 하지만 효율적으로 사용하는건 다른문제

 

 

NFS 서버 설치 확인

# dnf list nfs-utils

 

관련 파일

• 데몬 : /usr/sbin/exportfs

• 관리 스크립트 : /usr/lib/systemd/system/nfs-server.service

• 환경 설정 파일 : /etc/exports

• 관련 서비스

      - centos6 : rpcbind.service

      - centos5 : portmap

      - 7부터는 별도의 서비스가 불 필요하다.

 

NFS 서버 실행

# systemctl start nfs-server.service

 

 

 

exports

- NFS로 제공될 자원과 권한 설정

 

 

클라이언트 지정 형식

[export 할 디렉토리] [허가할 클라이언트][(옵션)]

 

예) /home/a1 192.168.10.147(rw)

 

 

옵션

- ro : 읽기 전용, rw : 읽기 쓰기 허용

- root_squash : 클라이언트의 root를 nobody로 매핑한다.

- no_root_squash : 클라이언트의 root와 서버의 root를 일치시킨다.

- all_squash : 모든 사용자를 nobody로 매핑한다.

- no_all_squash : 서버의 사용자와 클라이언트의 사용자를 일치시킨다.

※ 서버-클라이언트간 계정 매핑은 UID를 기준으로 한다.

 

- anonuid=uid, anongid=gid : nobody로 매핑 될 경우, 계정과 그룹을 지정한다.

- sync : 파일 쓰기 후에 즉시 디스크를 동기화 한다.

 

일반유저 default  =   no_all_squash

root default        =   root_squash

 

 

NFS 클라이언트는 서버가 export한 디렉터리를 mount 해야 사용할 수 있다

 

 

mount 명령

 

mount –t nfs NFS서버IP:/공유디렉토리 /마운트할디렉토리

 

ex) mount 192.168.10.147:/home/a1 /home/a1

• 일반 mount와 동일하다.

• 재귀적인 mount는 불허된다.

 

 

nfs를 실제로 사용못하는 이유

 

유닉스는 계정을 이름이 아니라 uid로 구분하기 때문. 그러므로 서버와 클라이언트의 uid불일치가 생길수 있기 때문!

그리고 root는 디렉터리를 들어가는 순간에는 어나니머스로 인식되기 때문이기 때문에.

클라이언트에서 root 권한을 가진 사용자가 서버의 모든 파일을 마음대로 건드릴 수 없게 막기 위함.(root_squash)

 

 

 

조별 실습

 

NFS 서버의 exports 설정 옵션에 따른 클라이언트의 접근 권한 변화 분석

 

1. root일 때,

옵션  
no_root_squash 파일소유자:root 그룹 소유자:root
all_squash   파일소유자:nobody 그룹 소유자:nobody
no_all_squash 파일소유자:nobody 그룹 소유자:nobody
all_squash,root_squash    파일소유자:nobody 그룹 소유자:nobody
all_squash,no_root_squash 파일소유자:nobody 그룹 소유자:nobody
no_all_squash,root_squash 파일소유자:nobody 그룹 소유자:nobody
no_all_squash,no_root_squash 파일소유자:root  그룹 소유자:root

 


2. 일반 사용자 계정일 때,

옵션

옵션  
no_root_squash 파일소유자:aa1 그룹 소유자:a
all_squash   파일소유자:nobody 그룹 소유자:nobody
no_all_squash 파일소유자:aa1 그룹 소유자:a
all_squash,root_squash    파일소유자:nobody 그룹 소유자:nobody
all_squash,no_root_squash 파일소유자:nobody 그룹 소유자:nobody
no_all_squash,root_squash 파일소유자:aa1 그룹 소유자:a
no_all_squash,no_root_squash 파일소유자:aa1  그룹 소유자:a

 

 


tcp

 

Flow control

한꺼번에 보내면 데이터를 잃어버릴수있어서 윈도우 사이즈의 상한선을 정해주는거

ㄴ (지금은 큰 의미는 없다.)

ㄴ 현재 내가 가용한 버퍼 사이즈를 알려주는것

 

 

connection

ㄴ 센더하고 리시버가 소켓을 유지하고있는것

 

Connection-less

ㄴ 데이터를 보내지않으면 커넥션을 유지하고 있지 않은것

 

Connection-Oriented 프로토콜

ㄴ 데이터를 주고받기전에 미리 준비해라고 알려주는것( 항상 클라이언트가 접속을 요청함. )

 

 

Three way handshake

 

step 1: client가 server에게 TCP SYN segment를 전송

초기 seq# 설정 → 몇번부터 보낼께 하는거 알려주는거

data는 없다.

 

step 2: server는 SYN를 수신하고 SYNACK를 전송

• server : 변수및 buffer 할당

• server의 초기 seq# 설정

ㄴ ack보내면서 자신의 시퀀스번호, 윈도우사이즈도 보냄.

 

step 3: client는 SYNACK수신 ACK전송 (data를 추가해도 된다.)(규정 없음.세팅 안해서 보냄.)

• client : 변수및 buffer 할당

 

 

 

서버가 작동하는 방식떄문에 보안상문제가 있음

클라이언트가 의도적으로 많은 연결을 요청하면 서버에서는 그 많은 양을 전부 버퍼에 할당을 합니다. 그렇게 할당하다가 더이상 메모리에 할당을 하지 못하면 반응을 안합니다. 그래서 정상적인 다른 클라이언트가 접속 요청을 보내도 서버가 응답을 할수가 없습니다.

 

그래서 싱크쿠키 같은 방식을 사용합니다.

 

싱크 쿠키 : Three way handshake에서 스텝 2때 버퍼를 할당 안하고, 3번이 끝난 다음에 버퍼를 할당한다.

 

 

 

Closing a connection

 

Step 1: client는 connection 을 종료하기위해 FIN bit가 1로 설정된 TCP segment를 server에게 전달

Step 2: server는 FIN을 수신하면 ACK를 응답하고 connection을 종료한다는 FIN를 client에게 전송한다.

Step 3: client는 FIN을 수신하면 ACK를 응답하고 일정시간을 기다린후 (time wait) connection을 종료한다.

Step 4: server는 ACK를 수신하면 connection을 종료한다

 

좀비 프로세스 : fin을 보내지 않고 종료하면 서버가 메모리에 떠서 소캣열어두면서 그냥 계속 대기하고 있음

 

 

 

 

Congestion

 

 

혼잡 : 센더가 자신의 윈도우 사이즈를 줄이는것

timeout이 훨씬 더 네트워크에서 안좋음.

tcp는 네트워크의 도움을 전혀 안받음. 재전송이벤트가 일어나는가 보고 판단하는것