FTP 서비스 제한 (chroot 실습)

chroot 설정

** chroot : 사용자 계정의 home 디렉토리를 root로 변경
#chroot_local_user=YES (d:No)
#chroot_list_enable=YES
- chroot_local_user가 NO일 때 chroot_list_file에 지정된 사용자만 chroot를 적용한다.
- chroot_local_user가 YES일 때 chroot_list_file에 지정된 사용자만 chroot를 적용하지 않는다.


#chroot_list_file=/etc/vsftpd/chroot_list
- Default 값 : /etc/vsftpd/chroot_list


#allow_writeable_chroot=YES
- chroot 적용 사용자의 경우 이 설정이 반드시 필요하다.


• chroot 설정은 외부 디렉토리로 연결된 link 디렉토리에 접근도 금지된다. 

 mount 명령을 이용하여 외부 링크파일 디렉토리로 접근 가능
mount --bind [원본 디렉토리] [연결할 디렉토리]

 


 

test case

case 1. chroot_local_user = YES / chroot_list_enable = YES

case 2. chroot_local_user = NO / chroot_list_enable = YES

case 3. chroot_local_user = YES / chroot_list_enable = NO

case 4. chroot_local_user = NO / chroot_list_enable = NO

 

접속계정 : st(chroot_list설정), te

case 1. chroot_local_user = YES / chroot_list_enable = YES

1) vi /etc/vsftpd/vsftpd.conf

 

2) /etc/vsftpd/chroot_list  파일에 일반사용자 st를 넣어준다.

 

3) ftp 서비스를 재시작한다.

systemctl restart vsftpd

 

4) 192.168.10.130 클라이언트에서 ftp 접속

chroot_list에 등록한 사용자 st로 로그인하면 디렉토리 이동이 가능하다.

 

chroot_list에 등록하지 않은 사용자 te로 로그인하면 자신의 home 디렉토리를 루트로 인식한다.

 

▶ chroot_local_user 가 YES, chroot_list_enable 가 YES 이면 chroot_list 파일에 있는 사용자는 chroot를 적용하지 않는다.

 

case 2. chroot_local_user = NO / chroot_list_enable = YES

1) vi /etc/vsftpd/vsftpd.conf

2) /etc/vsftpd/chroot_list  파일에 일반사용자 st를 넣어준다.

 

3) ftp 서비스를 재시작한다.

systemctl restart vsftpd

 

4) 192.168.10.130 클라이언트에서 ftp 접속

chroot_list에 등록한 사용자 st로 로그인하면 자신의 홈 디렉토리를 루트로 인식한다.

 

chroot_list에 등록하지 않은 사용자 te로 로그인하면 상위 디렉토리로 이동이 가능하다.

 

▶ chroot_local_user 가 NO, chroot_list_enable 가 YES 면 chroot_list 파일에 있는 사용자는 chroot를 적용한다.

 

case 3. chroot_local_user = YES / chroot_list_enable = NO

1) vi /etc/vsftpd/vsftpd.conf

cat /etc/vsftpd/vsftpd.conf | grep chroot

 

2) /etc/vsftpd/chroot_list  파일에 일반사용자 st를 넣어준다.

 

3) ftp 서비스를 재시작한다.

systemctl restart vsftpd

 

4) 192.168.10.130 클라이언트에서 ftp 접속

chroot_list에 등록한 사용자 st로 로그인하면 자신의 홈 디렉토리를 루트로 인식한다.

 

chroot_list에 등록하지 않은 사용자 te로 로그인하면 자신의 home 디렉토리를 루트로 인식한다.

 

▶ chroot_local_user 가 YES, chroot_list_enable 가 NO 이면 chroot_list 파일에 상관없이 사용자 모두 chroot를 적용한다.

 

case 4. chroot_local_user = NO / chroot_list_enable = NO

1) vi /etc/vsftpd/vsftpd.conf

cat /etc/vsftpd/vsftpd.conf | grep chroot

 

2) /etc/vsftpd/chroot_list  파일에 일반사용자 st를 넣어준다.

 

3) ftp 서비스를 재시작한다.

systemctl restart vsftpd

 

4) 192.168.10.130 클라이언트에서 ftp 접속

chroot_list에 등록한 사용자 st로 로그인하면 디렉토리 이동이 가능하다.

 

chroot_list에 등록하지 않은 사용자 te로 로그인하면 상위 디렉토리로 이동이 가능하다.

 

▶ chroot_local_user 가 NO, chroot_list_enable 가 NO 이면 chroot_list 파일에 상관없이 사용자 모두 chroot를 적용하지 않는다.

 


 

chroot 로 지정된 사용자 계정 마운트 실습

chroot를 지정해준 st 사용자는 자신의 홈 디렉토리가 / 라 /외부에 있는 곳은 접근 불가능

 

ftp를 통해 192.168.10.133 서버에 접속하여 st로 로그인하면 자신의 홈 디렉토리를 / 로 인식한다.

 

/home 디렉토리와 /home/st 디렉토리 하위에 mkdir 명령으로 abc라는 디렉토리 생성

st 사용자 계정 밑에도 마운트할 abc 디렉토리를 생성해준다.

 

192.168.10.130 컴퓨터에서 ftp접속해서 st 계정에서 잘 마운트 되었는지 확인한다.

 

FTP

- 대용량의 파일 전송 서비스에 적합
- 웹 서비스의 일부로 통합 운영되는 추세
- xinetd보다는 standalone 형태로 운영

 (xinetd : 슈퍼데몬- 스스로 listen 하지 않음 / standalone : 스스로 listen, 메모리에 상주)
시스템에 리소스를 많이 차지하는 서비스
- Out of band
 • 21 : control connection
 • 20 : data connection(Active mode)
  - Passive mode : 임의의 포트를 이용 (1024 이후것으로)

get - ftp 파일 받기

put - ftp 파일 올리기

 

접속및 전송 과정
1. FTP client는 21번 port를 통해서 서버와 control connection을
설정한다.
2. 이 제어연결을 통해 사용자 계정과 비밀번호를 전송한다.
3. Client는 제어연결을 통해 원격지의 디렉토리 변경과 같은 명령을 전
송한다.
4. 서버측은 제어연결을 통해 파일 전송을 위한 명령을 받으면 TCP data
connection을 초기화 한다.
5. 하나의 파일 전송이 끝나면 data연결은 close된다.
6. 다음 파일 전송을 위해서는 새로운 TCP connection을 생성한다.

 

관련 파일
• 데몬 : /usr/sbin/vsftpd
• 설정 파일 : /etc/vsftpd/vsftpd.conf
• PAM 모듈 : /etc/pam.d/vsftpd
• 접근 제한 파일 : /etc/vsftpd/ftpusers
/etc/vsftpd/user_list

 

Active mode(액티브 모드)
클라이언트가 데이터를 수신 받을 임의의 포트를 서버에 알려주면 서
버는 20번 포트를 통해 클라이언트에게 데이터를 전송함
• Client에서 Server로 FTP 제어 연결 요청
• Client에서 제어 연결을 통해 자신의 Data 전송 Port(Random Port)
를 Server 측에 알려줌
• Server에서 Client로 Data 전송 연결 요청


Passive mode(패시브 모드)
서버가 데이터를 송신할 임의의 포트를 클라이언트에 알려주어 클라이
언트가 서버의 임의의 포트에 접속하여 데이터를 가져감
• Client에서 제어 연결을 통해 Server 측에 Passive 연결요청
• Server에서 제어 연결을 통해 자신의 Data 전송 Port(Random
Port)를 Client 측에 알려줌
• Client에서 Server로 Data 전송 연결 요청

 

 

실습 전 컴퓨터 구성

st04.sec

192.168.10.130 - win

192.168.10.131 - ns (로컬네임서버)

192.168.10.133 - www (ftp, smb)

 

192.168.10.133을 ftp 서버로 설정할 것이다.

 

vi /var/named/st04.zone

$TTL    1D
@   IN   SOA  ns.st04.sec.   root.ns.st04.sec. (
                                   1         ; Serial
                                   1D        ; Refresh
                                   1H        ; Retry
                                   1W        ; Expire
                                   3H )      ; Minimum
; Name Server
   IN   NS      ns.st04.sec.
; Host address
          IN     A       192.168.10.131
ns        IN     A       192.168.10.131
win       IN     A       192.168.10.130
www       IN     A       192.168.10.133
ftp       IN     A       192.168.10.133
smb       IN     A       192.168.10.133

 

192.168.10.133 컴퓨터의 ip주소와 DNS 설정이다. (vmware 에서 centos7_5)

 

FTP 실습

1. ftp 정상작동 여부

vsftp 설치 확인

# yum list vsftpd

 

vsftpd 설치

# yum install –y vsftpd

 

vsftpd 서버 실행

# systemctl start vsftpd

 

사용자 생성

 

192.168.10.130 컴퓨터에서 테스트

사용자 st 계정은 로그인이 되는 것을 볼 수 있다.

 

/etc/vsftp/vsftpd.conf 파일에서 설정한다.

 

Active mode 설정

pasv_enable=NO(default : YES)
• 클라이언트에서 passive 모드로 접속을 요청해도 active 모드로 접속
된다.

 

Passive mode 설정

pasv_enable=YES (default : YES)
pasv_min_port=0 (default : 0, any port)
pasv_max_port=0 (default : 0, any port)
방화벽이나 공유기 사용시에 passive mode에서 사용하는 port 번
호를 등록해줘야 하기 때문에 범위를 반드시 지정한다.

 

익명 사용자 관련 설정

anonymous_enable=YES
#anon_upload_enable=YES (d:NO)
#anon_mkdir_write_enable=YES (d:NO)
#deny_email_enable=YES (d:NO banned_email_file )
- banned 파일에 지정된 메일 계정은 접속이 불허된다.
#banned_email_file=/etc/vsftpd.banned_emails
#non_anon_password=NO
#anon_root=/var/ftp (d:/var/ftp)
#ftp_username=ftp (d:ftp)

 

제한 설정

#max_clients=30
#max_per_ip=3 (0은 무제한)
#ls_recurse_enable=YES (ls –R 명령은 부하가 크다)

 

2. FTP 서비스 제한 (chroot 설정)

 

FTP 실습 1 - FTP 서비스 제한 (chroot 실습)

FTP 서비스 제한 (chroot 실습) chroot 설정 ** chroot : 사용자 계정의 home 디렉토리를 root로 변경 #chroot_local_user=YES (d:No) #chroot_list_enable=YES - chroot_local_user가 NO일 때 chroot_list_..

lemonandgrapefruit.tistory.com

 

3. ip별로 접속 제한

 

FTP 실습 2 - IP 별로 접속 제한

IP 별로 접속 제한 standalone 인 경우만 사용 listen=YES > standalone 사용 tcp_wrappers=YES > 접근제어 사용 여부 - /etc/hosts.deny, /etc/hosts.allow 파일에 정의 - hosts.allow 파일의 보안 등급이 높..

lemonandgrapefruit.tistory.com

 

4. FTP 사용자 제한 users user_list

 

FTP 실습 3 - FTP 사용자 제한

FTP 사용자 제한 user_list를 이용한 사용자 제한 설정 - userlist_file(/etc/vsftpd/user_list)에 등록된 계정에 대한 접속 제어는 userlist_enable과 userlist_deny에 따라 결정. userlist_enable=YES => /etc..

lemonandgrapefruit.tistory.com

 

실습 내용

- 서버 구성 설계도

1. root 와 cache 네임서버 구성

2. root 하위에 sec 네임서버 구성

3. root 하위에 itc 네임서버 구성

4. sec 네임서버 하위에 st 네임서버 구성

5. itc 네임서버 하위에 te 네임서버 구성

위 내용 중 [ sec 네임서버 구성, te 네임서버 구성 ] 실습을 담당

 

vmware 사용 컴퓨터

 

sec 네임서버 구성

192.168.10.135 리눅스

sec.zone

$TTL    1D
@   IN   SOA  ns.sec.   root.ns.sec. (
                                   1         ; Serial
                                   1D        ; Refresh
                                   1H        ; Retry
                                   1W        ; Expire
                                   3H )      ; Minimum
; Name Server
   IN   NS      ns.sec.
; Host address
          IN     A       192.168.10.135
ns        IN     A       192.168.10.135
www       IN     A       192.168.10.134
; Sub Domain
st.sec.         IN      NS      ns.st.sec.
ns.st.sec.      IN      A       192.168.10.166


named.conf

options {
directory "/var/named";
};

zone "." {
type hint;
file "named.ca";
};

zone "sec" {
type master;
file "sec.zone";
};




named.ca
;; QUESTION SECTION:
;.                              IN      NS

;; ANSWER SECTION:
.                       518400  IN      NS      a.root-servers.net.

;; ADDITIONAL SECTION:
a.root-servers.net.     518400  IN      A       192.168.10.113

 

vi /etc/named.conf

 

vi /var/named/sec.zone

 

cd /etc/sysconfig/network-scripts

cat ifcfg-ens32

 

te 네임서버 구성

192.168.10.136 리눅스

vi /etc/named.conf

options {
directory "/var/named";
};

zone "." {
type hint;
file "named.ca";
};

zone "sec" {
type master;
file "sec.zone";
};



vi /var/named/sec.zone

$TTL    1D
@   IN   SOA  ns.sec.   root.ns.sec. (
                                   1         ; Serial
                                   1D        ; Refresh
                                   1H        ; Retry
                                   1W        ; Expire
                                   3H )      ; Minimum
; Name Server
   IN   NS      ns.sec.
; Host address
          IN     A       192.168.10.135
ns        IN     A       192.168.10.135
www       IN     A       192.168.10.134
; Sub Domain
st.sec.         IN      NS      ns.st.sec.
ns.st.sec.      IN      A       192.168.10.166

 

vi /etc/named.conf

 

cat /var/named/te.zone

 

cd /etc/sysconfig/network-scripts

cat ifcfg-ens33

 

vi /var/named/named.ca

 

 

로컬 DNS를 192.168.10.112 (캐시네임서버)로 지정 후 ping을 날려보면 잘 되는것을 확인할 수 있다.

예시 ping ns.sec

 

도메인 위임

각 DNS 서버는 하위에 독립적인 하부 도메인을 더 둘 수 있다.

 

상위 도메인 : 192.168.10.131

하위 도메인 : 192.168.10.132

 

st.st04.sec  st로 된 하위 도메인 생성

 

상위 도메인 : 192.168.10.131 구성

# vi /etc/named.conf 를 아래와 같이 수정한다.

 

# vi /var/named/st04.zone 파일을 아래와 같이 수정한다.

 

 

# systemctl restart named.service 로 named.service를 재시작한다.

 

하위 도메인 : 192.168.10.132 구성

# vi /etc/named.conf 수정

 

# vi /var/named/st.zone 수정

 

네임서버는 자기 자신으로 설정한다.

 

 

상위 도메인 192.168.10.131 st04.zone 파일 수정

상위 도메인 192.168.10.131 에서 /var/named/st04.zone 파일에 아래와 같이 sub domain 부분을 추가한다.

 

systemctl restart named.service 로 named.service를 재시작한다.

host로 확인한다.

 

확인

서버 테스트는 클라이언트에서 테스트한다.

서버를 구성한 컴퓨터가 아닌 브리지에 연결된 다른 컴퓨터에서 DNS주소를 바꾼 후 클라이언트에서 테스트한다.

 

windows(192.168.10.130) 컴퓨터에서 에서 로컬 DNS 서버 주소192.168.10.131로 변경한다.

 

cmd 창에서 실행

cmd 창에서 nslookup 를 이용해 다음과 같이 입력해 확인한다.

 

다중 도메인, 캐시 네임 서버 구축, Slave name  server 구축

1. 다중 도메인 만들기

# vi /etc/named.conf 에서 아래와 같이 수정한다.

 

vi /var/named/st04_itc.zone 에서 파일을 수정한다.

 

• 그룹 소유자 권한 수정

권한 수정 (권한은 수정 안 해도 된다.)

 

그룹 소유자 권한 수정한다.

/var/named/st04_itc.zone

 

실행 확인

 

2. 캐시 네임서버 만들기

# vi /etc/named.conf 에서 아래와 같이 수정한다.

 

# vi /etc/resolv.conf

 

# cd /etc/sysconfig/network-scripts 들어간다.

vi ifcfg-ens33 를 아래 DNS 주소를 아래와 같이 바꾼다.

 

 

3. slave name server를 만들기

[ 실습 내용 ]

 • master name server의 named.conf에서 이전될 zone을 지정
zone "bow02.com" {
zone "st04.itc" {
type master;
file "st04_itc.zone";
also-notify {192.168.10.132;};
};


 • slave named server named.conf에 zone 영역 지정
zone "st04.itc" {
type slave;
file "st04_itc.zone";
masters {192.168.10.131;};
};

 •  /var/named의 퍼미션이 named 그룹에 대해서 W 가능하도록 설정한다.
 - Slave 서버 측 : named 그룹

 

master name server : 192.168.10.131 

slave named server : 192.168.10.132 

 

• master에서 # vi /etc/named.conf  수정

master name server (192.168.10.131)에서 /etc/named.conf 파일을 수정한다.

vi /etc/named.conf

빨간 부분 추가

options {
directory "/var/named";
};

zone "." {
type hint;
file "named.ca";
};

zone "st04.sec" {
type master;
file "st04.zone";
};

zone "st04.itc" {
type master;
file "st04_itc.zone";
also-notify {192.168.10.132;};
};

 

• slave에서 /etc/named.conf 수정

slave named server (192.168.10.132)에서 /etc/named.conf 파일에 다음과 같이 수정한다.

vi /etc/named.conf

options {
directory "/var/named";
};

zone "." {
type hint;
file "named.ca";
};

zone "st04.itc" {
type slave;
file "st04_itc.zone";
masters {192.168.10.131;};
};

slave에서 st04_itc.zone 파일을 만들지 않아도 된다. 

master에서 자동으로 복사해간다.

 

• 실행을 위한 최소 권한 부여

slave에서 실행한다.

권한 주지 않았을 경우

 

처음에는 zone 파일이 없다.

 

권한을 변경한다. (권한은 변경 안 해도 되고 그룹 소유자만 변경하면 된다.)

 

그룹 소유자 변경

- chgrp /etc/named.conf

- chgrp /var/named

- chgrp /var/named/*

 

ls -al 통해 그룹 소유자를 확인하고 named로 소유자가 되어있지 않으면 위와 같이 수정한다.

 

• st04_itc.zone 파일 수정

master에서 vi /var/named/st04_itc.zone 을 수정한다.

/var/named/st04_itc.zone 파일을 수정할 때마다 serial을 수정한다.

 

named.service를 재시작하면 zone 파일이 master에서 slave로 받아오는 것을 확인할 수 있다.

 

st04_itc.zone 파일은 바이너리 파일이라 확인하기 어렵다.

 

• host를 이용한 확인

확인은 다음과 같이 한다.

slave에서 named.service를 재시작하고 테스트한다.

잘 실행되는 것을 확인한다.

 

'리눅스 공부 기록' 카테고리의 다른 글

리눅스 16 - FTP (+ 실습)  (0) 2021.11.11
DNS 서버 구축 실습 3 - 도메인 위임  (0) 2021.11.10
DNS 서버 구축 실습  (0) 2021.11.08
리눅스 15 - DNS 서버  (0) 2021.11.08
리눅스 14 - Service 등록 및 관리  (0) 2021.11.05

다중 행 서브 쿼리

SELECT [DISTINCT | ALL] 컬럼, 컬럼 ...
FROM 테이블
WHERE 컬럼 다중_행_연산자 (SELECT 문장 : Sub query문)

- 다중 행 연산자
. IN : 나열된(검색된) 값 중에 하나만 일치하면 참이다.
. ANY : 나열된(검색된) 값 중에 조건에 맞는 것이 하나 이

 

예제 1. 20번 부서원들과 동일한 관리자로부터 관리 받는 사원을 검색한다.

SELECT eno 사번, ename 이름
FROM emp
WHERE mgr IN (SELECT mgr
		FROM emp
		WHERE dno = '20')
AND dno != '20'; // 20번 부서원이 검색되는 것을 막기 위한 조건

사번    이름
------- ----------
1001    문시현
1003    양선호
2001    남궁연호
2003    정의찬

 

예제 2. 10번 부서원들보다 급여가 낮은 사원을 검색한다.

SELECT eno 사번, ename 이름, dno 부서번호
FROM emp
WHERE sal < ALL (SELECT sal
		FROM emp
		WHERE dno = '10');

사번    이름       부서번호
------- ---------- ---------
2008    윤고은     40
2007    이초록     30
2002    제갈민     20
0702    김민지     02
0309    김선유     02

 

SELECT eno 사번, ename 이름, dno 부서번호
FROM emp
WHERE sal < ALL (SELECT MIN(sal)
		FROM emp
		WHERE dno = '10');

사번    이름       부서번호
------- ---------- ---------
2002    제갈민     20
2007    이초록     30
2008    윤고은     40
0309    김선유     02
0702    김민지     02

 

* 다중 행 연산자와 그룹함수
다중 행 연산자인 ALL이나 ANY는 다음과 같이 그룹 함수를 이용 표현할 수 있다. 그룹 함수는 [19장
그룹 함수]에서 자세히 설명한다.
* 컬럼 > ALL → 컬럼 > MAX() : 가장 큰 값보다 크다
* 컬럼 < ALL → 컬럼 < MIN() : 가장 작은 값보다 작다.
* 컬럼 > ANY → 컬럼 > MIN() : 가장 작은 값보다 크다.
* 컬럼 < ANY → 컬럼 < MAX() : 가장 큰 값보다 작다.

 

다중 열 서브 쿼리

SELECT [DISTINCT | ALL] 컬럼, 컬럼 ...
FROM 테이블
WHERE (컬럼1, 컬럼2, ... ) IN (SELECT 문장 : Sub query문)

 

예제 3. 손하늘과 동일한 관리자의 관리를 받으면서 업무도 같은 사원을 검색한다.

SELECT eno 사번, ename 이름, mgr 관리자, job 업무
FROM emp
WHERE (mgr, job) IN (SELECT mgr, job
			FROM emp
			WHERE ename = '손하늘')
AND ename != '손하늘';

사번    이름       관리자   업무
------- ---------- -------- -------
0201    안영숙     0001     지원

손하늘이 두 명 이상이라면 수정이 불가능하다.

 

SELECT eno 사번, ename 이름, mgr 관리자, job 업무
FROM emp
WHERE mgr = (SELECT mgr FROM emp WHERE ename = '손하늘')
AND job = (SELECT job FROM emp WHERE ename = '손하늘')
AND ename != '손하늘';

사번    이름       관리자   업무
------- ---------- -------- -------
0201    안영숙     0001     지원

 

예제 4. 김선유와 부서 및 업무가 동일한 사원을 검색한다.

SELECT eno 사번, ename 이름, dno 부서번호, job 업무
FROM emp
WHERE (dno, job) IN (SELECT dno, job
			FROM emp
			WHERE ename = '김선유')
AND ename != '김선유';

사번    이름       부서번호  업무
------- ---------- --------- -------
0301    이승철     02        회계
0302    박선경     02        회계
0702    김민지     02        회계
0269    권나현     10        분석

 

SELECT eno 사번, ename 이름, dno 부서번호, job 업무
FROM emp
WHERE dno in (SELECT dno FROM emp WHERE ename = '김선유')
AND job in (SELECT job FROM emp WHERE ename = '김선유')
AND ename != '김선유';

사번    이름       부서번호  업무
------- ---------- --------- -------
0301    이승철     02        회계
0302    박선경     02        회계
0702    김민지     02        회계
0801    천유정     02        분석
0401    김진성     10        회계
0269    권나현     10        분석

 

SELECT ename, dno, job
FROM emp
WHERE ename = '김선유';

ENAME      DNO     JOB
---------- ------- -------
김선유     02      회계
김선유     10      분석

실습

1. 화학과 학생과 평점이 동일한 학생들을 검색한다.

SELECT sno 학번, sname 이름, major 전공
FROM student
WHERE avr IN (SELECT avr FROM student WHERE major = '화학')
AND major != '화학';

학번    이름       전공
------- ---------- -------
948209  유태지     식영
924505  서찬호     물리
913904  이호란     생물
933903  정승동     생물
915605  강은혜     유공
924502  은정현     물리
935604  권석현     유공

학번    이름       전공
------- ---------- -------
945605  오경운     유공
943905  유태지     생물
943903  유지아     생물
944512  서동조     물리
945603  정백영     유공

 


2. 화학과 교수와 부임일이 같은 직원을 검색한다.

SELECT eno 학번, ename 이름, hdate 부임일자
FROM emp
WHERE hdate IN (SELECT hiredate FROM professor WHERE section = '화학');

학번    이름       부임일자
------- ---------- ----------
0201    안영숙     1991/02/01
1001    문시현     1991/02/01


3. 화학과 학생과 같은 학년에서 평점이 동일한 학생들을 검색한다. (다중열 서브쿼리)

SELECT syear 학년, sno 학번, sname 이름, major 전공, avr 평점
FROM student
WHERE (syear, avr) IN (SELECT syear, avr FROM student WHERE major = '화학')
AND major != '화학';

      학년 학번    이름       전공          평점
---------- ------- ---------- ------- ----------
         1 945605  오경운     유공          2.99


4. 10번 부서 사원들보다 년봉을 많이 받는 사원을 검색한다.

SELECT eno 사번, ename 이름, sal*12+NVL(comm,0) 연봉, dno 부서번호
FROM emp
WHERE (sal*12+NVL(comm,0)) > (SELECT MAX(sal*12+NVL(comm,0)) FROM emp WHERE dno = 10)
AND dno != 10;

사번    이름             연봉 부서번호
------- ---------- ---------- ---------
0001    안영희          57600 01


5. 10번 부서 사원들과 업무와 성별이 동시에 일치하는 사원을 검색한다.

SELECT eno 사번, ename 이름, job 업무, sex 성별
FROM emp
WHERE (job, sex) IN (SELECT job, sex FROM emp WHERE dno = 10)
AND dno != 10;

사번    이름       업무    성
------- ---------- ------- ---
1003    양선호     모델링  남
2002    제갈민     개발    남
2003    정의찬     개발    남
2007    이초록     개발    남
3002    권아현     분석    여
0801    천유정     분석    여
0301    이승철     회계    남

사번    이름       업무    성
------- ---------- ------- ---
0309    김선유     회계    남
0702    김민지     회계    남

 

DNS 서버 구축 실습

Bind 서버 설치 확인 및 설치
# yum list bind
# yum install –y bind

available 는 파일은 있지만 설치가 되어있지 않으므로 # yum install –y bind 로 설치한다.

 

Bind 서버를 시작한다.
# systemctl start named.service

 

관련 파일
• 데몬 : /usr/sbin/named
• 관리 스크립트 : /usr/lib/systemd/system/named.service
• 환경 설정 파일 : /etc/named.conf
• 설정 파일 경로 : /var/named/
- named.ca와 여러 zone 파일들
• 이외 관련 파일 : /etc/resolv.conf, /etc/host.conf
• 실행을 위한 최소 권한
- /etc/named.conf, /var/named, /var/named/*
- 그룹 소유자는 반드시 named로 정의한다.

 

ntsysv로 named.service를 자동으로 시작하도록 설정한다.

 

 

# vi /etc/named.conf 에서 아래와 같이 수정한다.

vi /etc/named.conf

options {
directory "/var/named";
};

zone "." {
type hint;
file "named.ca";
};

zone "st04.sec" {
type master;
file "st04.zone";
};

 

Zone 파일 생성 (st04.sec)

/var/named/ 디렉토리에 생성한다.

zone 파일 이름은 st04.zone로 한다.

 

vi st04.zone으로 들어가 아래와 같이 수정한다.

vi /var/named/st04.zone

$TTL    1D
@   IN   SOA  ns.st04.sec.   root.ns.st04.sec. (
                                   0         ; Serial
                                   1D        ; Refresh
                                   1H        ; Retry
                                   1W        ; Expire
                                   3H )      ; Minimum
; Name Server
   IN   NS      ns.st04.sec.
; Host address
          IN     A       192.168.10.131
ns        IN     A       192.168.10.131
win       IN     A       192.168.10.130

 

• 실행을 위한 최소 권한 부여

- /etc/named.conf, /var/named, /var/named/*
- 그룹 소유자는 반드시 named로 정의한다.

권한 수정 전

권한 수정 (할 필요 없다.)

권한을 위와 같이 수정해준다.

 

권한 변경 후

 

그룹 소유자 변경

/var/named 에서 chgrp named st04_itc.zone 으로 변경한다.

 

리눅스에 설정된 DNS 서버 주소 바꾸기

1. vi /etc/resolv.conf 에서 아래와 같이 수정한다. 

 

2. cd /etc/sysconfig/network-scripts 들어간다.

vi ifcfg-ens32 를 아래 DNS 주소를 아래와 같이 바꾼다.

# systemctl restart network 를 통해 네트워크를 재시작 해준다.

 

Bind 서버를 다시 시작해준다.

에러메시지가 안나오는 것을 확인하면 잘 된것이다.

host 를 통해 IP 주소를 잘 받아오는 것을 확인한다.

DNS (Domain Name System)

• 분산 database
 - 수많은 name server들이 계층형구조로 구조화 되어있다.


 Application layer protocol (host name → ip로 반환)
다른 app layer protocol들이 HTTP, FTP, SMTP등 사용자가 제공한 호스트네임을 ip로 변환하는데 이용
 - 인터넷의 가장 중요한 기능중의 하나
 - Network edge에 구현된다.


 IP와 이름간 mapping 

 

 호스트명을 IP 주소로 변환 (클라이언트가 요청해서)

 

 호스트에얼리아싱 (host aliasing)
 - 정식 (canonical) 호스트명
 - 별칭(aliasing) 호스트명
 - DNS는 IP뿐아니라 정식 호스트명을 얻기 위해 이용되기도 한다.

 

 DNS 를 중앙집중식으로 하지 않는 이유
 - 서버 장애 (인터넷 다운…)
 - Traffic의 집중
 - 중앙 서버까지의 거리
 - 관리

 

 DNS 동작과정

 

- 책임 DNS 서버 : 자신이 관리하는 DNS 서버 있는 경우 (root DNS server, com DNS server 등) > zone 파일 생성

- 캐시 DNS 서버 : 자신이 관리하는 DNS 서버 없는 경우 > zone 파일X

- 로컬 DNS 서버 : 질의를 던지는 네임서버 (보통 캐시네임서버 사용) [ /etc/resolv.conf ]

 

예시) 클라이언트가 www.itclass.co.kr 접속시 DNS 동작과정

 

1. While문과 Do..While문

while (조건) {
	실행문;
}

- 조건이 참인 동안 실행문이 반복되어 실행된다.
- 반복을 벗어나기 위해서는 실행 문내에 조건을 변경하거나 break문이 필요하다.
- 조건에 변화가 없으면 무한 반복된다.
- 조건은 실행문이 반복될 때마다 반복해서 실행된다.

 

$a = 1; 		// 초기식
while ($a <= 10) { 	// 조건
echo(" {$a}<br> "); 	// 명령문
$a++; 			// 증감식
}

While뿐 아니라 do..while문이나 for문에서도 반복문의 네 가지 요소(초기식, 조건, 증감식, 명령문)는 항상 동
일하다.

 

2. For문 

for (초기식; 조건; 증감식) {
	실행문;
}

- 일반적으로 사용

- 조건이 참인 동안 실행문을 반복 실행한다.
- 초기식은 맨 처음 한 번만 실행된다.
- for문은 반복 횟수를 구체적으로 확인 가능함으로 반복문 중에 가장 가독성이 좋다.

 

잘못된 값 입력 시 사용하는 코드

if($num < 1 ) {
      echo("
           <script>
           window.alert('1보다 큰값을 입력하세요');
           history.go(-1);
           </script>
          ");
      exit;
   }

 

3. Continue 문

- Continue문은 반복문 내에서 쓰이는 제어문

- 이런 제어문으로는 앞에서 살펴본 break문이 있는데, break문은 반복문을 완전히 빠져나오는 기능을 수행하는 반면   continue문은 현재 수행중인 반복을 종료하고 다음 반복으로 건너뛰는 기능을 담당

<?
for($a = 1; $a <= 10; $a++) {
if($a%2==0) continue;
echo(" {$a}<br> ");
}
?>

<?
  $a = 1;
  while ($a <=10) {
	if($a%2==0){
	$a++;
	continue;
	}
	echo(" {$a}<br> ");
	$a++;
  }
  show_source(__FILE__);
?>

 

while, for문 실습

예제 3-1. 0 보다 큰 값을 입력받아 1에서 입력 값까지의 합을 출력한다.

3-1.html

<html>
<head>
<title>3-1.html 입력 폼파일</title>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
</head>
<form method="post" action="3-1.php">
	1보다 큰 값을 입력하세요 : <input type="text" name="num"><br>
		<input type="submit" name="확인" value="확인">
		<input type="reset" name="취소" value="취소"><br>
</form>
<hr>
<? show_source(__FILE__); ?>
</html>

 

while 문 3-1.php

<?
   $num = $_POST["num"];

   $sum = 0; // 누적 변수, 1..$num 까지 값을 누적한다.
   $a = 1 ; // 초기식
   if($num > 1) {
       while($a <= $num) { // 조건, $a가 $num보다 커지면 반복을 종료한다.
           $sum = $sum + $a;
           echo("\$a: {$a}, \$sum: {$sum}<br>");
           $a++; // 증감식
        }
        echo("<hr>");
        echo("1에서 {$num}까지의 합은 {$sum}입니다.");
     }
     else echo("입력 값이 올바르지 않습니다.");
     echo("<hr>");
     show_source(__FILE__);
?>

실행결과

 

예제 3-1 for문

3-1f.php 

<?
   $num = $_POST["num"];

   if($num < 1 ) {
      echo("
           <script>
           window.alert('1보다 큰값을 입력하세요');
           history.go(-1);
           </script>
          ");
      exit;
   }
   $sum = 0;
   for($a = 1; $a <= $num; $a++){
   $sum = $sum + $a;
   echo("\$a: {$a}, \$sum: {$sum}<br>");
   }
   echo("<hr>");
   echo("1에서 {$num}까지의 합은 {$sum}입니다.");
   echo("<hr>");
   show_source(__FILE__);
?>

실행결과

 

예제 3-2. 2~9 까지의 숫자를 입력받아 구구단을 출력하는 프로그램을 작성한다.

3-2f.html

<html>
<head>
<title>3-2f.html 구구단 폼파일</title>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
</head>
<form method="post" action="3-2f.php">
	출력하고자 하는 단을 입력 하세요 : <input type="text" name="gu"><br>
	<input type="submit" name="확인" value="확인">
	<input type="reset" name="취소" value="취소"><br>
</form>
</html>

 

3-2f.php

<?
	$gu = $_POST["gu"];
	if(!($gu >= 2 && $gu <= 9)) {
		echo("
		  <script>
		  window.alert('2에서 9사이에 값을 입력하세요');
		  history.go(-1);
		  </script>
		  ");
		  exit;
	}
	for($i = 1;$i <= 9;$i++){
		$s = $i * $gu;
		echo("{$gu}x{$i}={$s}<br>");
	}
?>

 

실습

실습 1. 0보다 큰 정수를 입력받아 입력받은 정수까지 홀수의 합과 짝수의 합을 각각 출력하는 프로그램을 작성한다.

* while문과 for문을 둘 다 사용해 작성 (두 번 출력하기)

3-ex01.html

<html>
<head>
<title>3-ex01.html 입력 폼파일</title>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
</head>
<form method="post" action="3-ex01.php">
	0보다 큰 값을 입력하세요 : <input type="text" name="num"><br>
		<input type="submit" name="확인" value="확인">
		<input type="reset" name="취소" value="취소"><br>
</form>
<hr>
<? show_source(__FILE__); ?>
</html>

 

3-ex01.php

<?
   $num = $_POST["num"];

   if($num < 0 ) {
      echo("
           <script>
           window.alert('0보다 큰값을 입력하세요');
           history.go(-1);
           </script>
          ");
      exit;
   }
   $sum_odd = 0;
   $sum_even = 0;
   $i=1;
   while($i <= $num) {
         if($i % 2 == 0){
            $sum_even += $i;
         }
         else {
            $sum_odd += $i;
         }
         echo("\$i: {$i}, \$sum_odd: {$sum_odd}, \$sum_even: {$sum_even}<br>");
         $i++;
   }
   echo("<hr>");
   echo("while문<br>");
   echo("0에서 {$num}까지 홀수합: {$sum_odd}, 짝수합: {$sum_even}");
   echo("<hr>");

   $sum_odd = 0;
   $sum_even = 0;
   for($a = 1; $a <= $num; $a++){
    if($a % 2 == 0){
      $sum_even += $a;
    }
    else{
      $sum_odd += $a;
    }
    echo("\$i: {$i}, \$sum_odd: {$sum_odd}, \$sum_even: {$sum_even}<br>");
   }
   echo("<hr>");
   echo("for문<br>");
   echo("0에서 {$num}까지 홀수합: {$sum_odd}, 짝수합: {$sum_even}");
   echo("<hr>");
   show_source(__FILE__);
?>

실행결과
실행결과 show_source(__FILE__)

 

실습2. 값을 입력받아 입력된 값이 소수인지 확인하는 프로그램을 작성한다.
* 소수란 : 약수가 1과 자신밖에 없는 수
* 소수 판별 방법
- 제수의 값을 2부터 시작해서 1씩 증가 하면서 피제수를 나눠서 나머지가 0이 될 때까지 수행한다.
- 나눠서 떨어졌을 때 제수와 피제수가 같으면 피제수는 소수이다.

 

pri.html

<html>
<head>
<title>pri.html 입력 폼파일</title>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
</head>
<form method="post" action="pri.php">
	3이상인 값을 입력하세요  <br>
  <input type="text" name="num">
	<input type="submit" name="확인" value="확인"><br>
</form>
<hr>
<? show_source(__FILE__); ?>
</html>

pri.php

<?
  $num = $_POST["num"];

  if($num < 3 ) {
        echo("
             <script>
             window.alert('3이상인 값을 입력하세요');
             history.go(-1);
             </script>
            ");
        exit;
     }

  for($i = 2; $num % $i != 0; $i++){
  }

  if($num == $i)
    echo("{$num}: 소수");
  else
    echo("{$num}: 합성수");
?>
<hr><p>
<? show_source(__FILE__); ?>

 

'PHP 공부 기록' 카테고리의 다른 글

(수정중) PHP 5 - 배열  (0) 2021.11.23
PHP 4 - 폼(Form)  (0) 2021.11.19
PHP 2 - 조건문 (IF, SWITCH)  (0) 2021.10.29
PHP 1 - 변수와 연산자  (0) 2021.10.22
PHP 0 - 프로그램 사용해보기  (0) 2021.10.22

서브 쿼리 : 단일 행 서브 쿼리

* 서브 쿼리란?
단일 행 서브 쿼리 :
- 서브 쿼리가 하나의 컬럼에서 하나의 행을 검색한다.
다중 행 서브 쿼리
- 서브 쿼리가 하나의 컬럼에서 여러 개의 행을 검색한다.
다중 열 서브 쿼리 (IN)
- 서브 쿼리가 여러 개의 컬럼을 검색한다.

 

서브 쿼리는 WHERE절, HAVING절과 같이 조건 절에 주로 쓰이고 FROM절에 쓰이는 경우도 있다. 특
히 FROM절에 쓰인 서브 쿼리는 인라인 뷰(Inline View)라고 부른다.

 

단일 행 서브 쿼리

SELECT [DISTINCT | ALL] 컬럼, 컬럼 ...
FROM 테이블
WHERE 컬럼 단일_행_연산자 (SELECT 문장 : Sub query문)

- 단일 행 연산자가 사용됨으로 반드시 서브 쿼리의 결과 값은 한 개만 검색돼야 한다.
- 단일 행 연산자 오른쪽에 기술한다.
   (=, <, >, <=, >=, !=)
- WHERE절에 기술된 열의 숫자와 타입은 SELECT절과 1:1 대응 관계가 되어야 한다.

 

 

예제 1. 남궁연호보다 급여를 많이 받는 사원을 검색한다.

SELECT eno 사번, ename 이름
FROM emp
WHERE sal > (SELECT sal
		FROM emp
		WHERE ename = '남궁연호');

사번    이름
------- ----------
0001    안영희
1001    문시현
1002    김주란
1003    양선호
2003    정의찬
0120    김경현

 

예제 2. 김선유보다 급여를 많이 받는 사원을 검색한다.

SELECT eno 사번, ename 이름
FROM emp
WHERE sal > (SELECT sal
		FROM emp
		WHERE ename = '김선유');
WHERE sal > (SELECT sal
                 *
3행에 오류:
ORA-01427: 단일 행 하위 질의에 2개 이상의 행이 리턴되었습니다.

동명이인이 있을 수 있기 때문에 검색이 안된다.

 

* 예측하기 힘든 단일 행 서브 쿼리를 수정하는 방법
① '=' 연산자는 'IN' 연산자로 바꾼다.
② 부등호 ('<', '>', '<=', '>=')는 any, all 연산자를 추가한다.

  (< 일때, any는 항목에 가장 큰값보다 작으면 가능, all은 가장 작은값보다 작으면 가능)
③ Max(), Min()과 같은 그룹 함수를 사용 한다.

 

예제 3. 문시현과 부서가 다르고 동일한 업무를 하는 사원의 정보를 검색한다.

SELECT eno 사번, ename 이름, dno 부서번호, job 업무
FROM emp
WHERE dno != (SELECT dno FROM emp WHERE ename = '문시현')
AND job = (SELECT job FROM emp WHERE ename = '문시현');

사번    이름       부서번호  업무
------- ---------- --------- -------
1002    김주란     20        모델링
1003    양선호     30        모델링

 

예제 4. 부산에서 근무하는 사원의 정보를 검색한다.

SELECT eno 사번, ename 이름
FROM emp
WHERE dno = (SELECT dno
		FROM dept
		WHERE loc = '부산');

사번    이름
------- ----------
1002    김주란
2002    제갈민
3002    권아현
0120    김경현

 

SELECT eno 사번, ename 이름
FROM emp e, dept d
WHERE e.dno = d.dno
AND loc = '부산';

사번    이름
------- ----------
1002    김주란
2002    제갈민
3002    권아현
0120    김경현

 

 

실습

1. 김혁윤 보다 평점이 우수한 학생의 학번과 이름을 검색한다.

SELECT sno 학번, sname 이름, avr 평점
FROM student
WHERE avr > (SELECT avr
		FROM student
		WHERE sname = '김혁윤');

학번    이름             평점
------- ---------- ----------
933904  임영현           3.98
924501  권석복              4
915601  강태용            3.9
925603  최지현           3.89
945601  심정용            3.9
918203  장운영           3.89
918205  독고낭도         3.99

학번    이름             평점
------- ---------- ----------
938202  신섭인           3.93
938204  최현             3.92


2. 권현와 동일한 학년 학생 중에 평점이 강은혜와 동일한 학생을 검색한다.

SELECT syear 학년, sno 학번, sname 이름, avr 평점
FROM student
WHERE syear = (SELECT syear FROM student WHERE sname = '권현')
AND avr = (SELECT avr FROM student WHERE sname = '강은혜');

      학년 학번    이름             평점
---------- ------- ---------- ----------
         1 925309  오우재           2.99
         1 945605  오경운           2.99


3. 이학수학 과목과 동일한 학점수인 과목을 검색한다.

SELECT st_num 학점, cno 과목번호, cname 과목명
FROM course
WHERE st_num = (SELECT st_num FROM course WHERE cname = '이학수학');

      학점 과목번호  과목명
---------- --------- ------------
         2 1211      일반화학실험
         2 1214      무기화학
         2 1216      환경화학
         2 1218      생화학
         2 1227      이학수학
         2 1228      위상수학
         2 2365      전자기학

      학점 과목번호  과목명
---------- --------- ------------
         2 2366      물리실험
         2 2369      무기화학실험
         2 1711      유전학실험
         2 1245      실험물리학
         2 2112      영양학실험
         2 2313      분류학실험


4. 타 학과에 송강 교수와 동일한 지위의 교수 명단을 검색한다.

SELECT pno 교수번호, pname 교수이름, orders 지위, section 학과
FROM professor
WHERE section != (SELECT section FROM professor WHERE pname = '송강')
AND orders = (SELECT orders FROM professor WHERE pname = '송강');

교수번호  교수이름   지위    학과
--------- ---------- ------- -------
1010      이규진     정교수  물리
1009      이준영     정교수  물리
1021      왕사진     정교수  생물
1029      주동평     정교수  생물
1030      김동평     정교수  유공
1033      박삭광     정교수  유공
1035      장관용     정교수  식영


5. 제갈민의 입사일보다 나중에 부임한 교수의 명단을 검색한다.

SELECT pno 교수번호, pname 교수이름, hiredate 부임일자
FROM professor
WHERE hiredate > (SELECT hdate FROM emp WHERE ename = '제갈민');

교수번호  교수이름   부임일자
--------- ---------- ----------
1001      송강       2002/08/12
1006      장청아     2003/05/20
1007      이초아     2010/07/06
1008      문규식     2005/02/11
1010      이규진     1998/10/07
1013      하영진     1999/04/19
1012      이영준     2000/05/18

교수번호  교수이름   부임일자
--------- ---------- ----------
1016      호연작     2009/10/21
1018      김응전     1999/02/18
1021      왕사진     1997/02/17
1027      임충원     2001/06/03
1029      주동평     2006/01/26
1030      김동평     2002/02/15
1017      최무송     2011/01/24

교수번호  교수이름   부임일자
--------- ---------- ----------
1033      박삭광     2005/07/14
1034      최해연     1998/07/02
1038      하영진     2004/03/02


6. 강태용보다 일반 화학 과목의 학점이 더 낮은 학생의 명단을 학점과 검색한다.

// 성적으로 검색
SELECT s.sno 학번, sname 이름, result 성적, cname 과목이름
FROM student s, course c, score r
WHERE s.sno = r.sno 
AND r.cno = c.cno
AND cname = '일반화학'
AND result < (SELECT result 
FROM student s, score r, course c
WHERE s.sno = r.sno 
AND r.cno = c.cno
AND sname='강태용'
AND cname='일반화학');

학번    이름             성적 과목이름
------- ---------- ---------- ------------
913902  황진혜             70 일반화학
913903  정도정             57 일반화학
913904  이호란             27 일반화학
914502  문수보             60 일반화학
915301  정동상             44 일반화학
915305  최정희             53 일반화학
915604  정성현             54 일반화학

// 학점으로 검색
SELECT s.sno 학번, s.sname 이름, result 성적, sc.grade 학점, cname 과목이름
FROM student s, score r, course c, scgrade sc
WHERE s.sno=r.sno
AND r.cno=c.cno
AND result between loscore and hiscore
AND grade > (SELECT grade
FROM student s, score r, course c, scgrade sc
WHERE s.sno=r.sno
AND r.cno=c.cno
AND result between loscore and hiscore
AND sname='강태용'
AND cname='일반화학')
AND cname='일반화학';

학번    이름             성적 학점  과목이름
------- ---------- ---------- ----- ------------
913903  정도정             57 C     일반화학
913904  이호란             27 F     일반화학
914502  문수보             60 C     일반화학
915301  정동상             44 D     일반화학
915305  최정희             53 D     일반화학
915604  정성현             54 D     일반화학
918201  이경철             62 C     일반화학


SELECT s.sno, sname, cname, grade
FROM student s, course c, score r, scgrade g
WHERE s.sno=r.sno AND r.cno=c.cno AND result BETWEEN loscore AND hiscore
AND cname = '일반화학'
AND grade > ( SELECT grade 
                FROM student s, course c, score r, scgrade g
                WHERE s.sno=r.sno AND r.cno=c.cno 
                AND result BETWEEN loscore AND hiscore
                AND sname = '강태용'
                AND cname = '일반화학');   
                
SNO     SNAME      CNAME        GRADE
------- ---------- ------------ -------
913903  정도정     일반화학     C
913904  이호란     일반화학     F
914502  문수보     일반화학     C
915301  정동상     일반화학     D
915305  최정희     일반화학     D
915604  정성현     일반화학     D
918201  이경철     일반화학     C

 

+ Recent posts