Browsing Tag

#EC2

IT/Linux/Kubernetes

[Linux] ftp, sftp 그리고 키 생성

안녕하세요. ManVSCloud 김수현입니다.

오늘은 FTP 실습을 통하여 다시 공부 해보는 시간을 가졌습니다.

Environment

Amazon Linux 2 x86_64 + 4.14.203-156.332.amzn2.x86_64
vsftpd-3.0.2-25.amzn2.x86_64
FileZilla

FTP는 vsftpd를 이용할 것입니다.
vsftpd는 가장 많이 사용되는 ftp솔루션 중에 하나입니다.
vsftpd는 Virtual ip configuration 및 Virtual Users, 전송 대역폭 조절 기능, 환경 설정 파일을 IP별로 독립적 지원이 가능하며, IPv6 지원 등 다양한 기능이 존재합니다.

SFTP는 기존 FTP에서 데이터 전송을 암호화하여 보안상의 문제로부터 보완하기 위한 프로토콜로 이번 글에서는 FTP와 SFTP 둘 다 다뤄볼 것입니다.

Practice

아래와 같은 3개의 계정을 생성합니다.
계정의 조건은 다음과 같습니다.
1. master
: 키를 이용하여 인스턴스에 접근 및 루트 진입도 가능해야합니다.

2. sftpuser
: SFTP를 키를 이용하여 접근하며, 인스턴스에 접근하나 루트 권한은 사용하지 못합니다.
: 생성된 key는 180일 동안만 사용할 수 있어야합니다.

3. ftpguest
: FTP를 사용하며, 인스턴스 접속은 불가능해야합니다.
: 이 계정은 30일 동안만 사용 가능하며, 홈 디렉토리 경로는 /home/img 입니다.

  • master 계정 생성

master 계정 생성을 통해서 키를 생성 방법에 대해 이야기하겠습니다.
key 생성은 puttygen, xshell 사용자 키 생성, openssl 등을 이용한 다양한 방법이 있습니다.
(AWS에서는 [EC2] – [네트워크 및 보안] – [키 페어]에서 생성을 통해 간단하게 생성 가능합니다.)

저는 openssl을 이용하여 생성을 할 것입니다.

# 계정 및 키 생성

[root@ip-10-0-0-20 ~]# useradd master // master 계정 생성
[root@ip-10-0-0-20 ~]# cd /home/master
[root@ip-10-0-0-20 master]# openssl genrsa -out master.pem 4096 // 키 길이는 임의로 4096
[root@ip-10-0-0-20 master]# chmod 600 master.pem
[root@ip-10-0-0-20 master]# mkdir .ssh
[root@ip-10-0-0-20 master]# ssh-keygen -y -f master.pem > .ssh/authorized_keys
[root@ip-10-0-0-20 master]# chown -R master:master .ssh // 마무리 권한 작업
[root@ip-10-0-0-20 master]# chmod 700 .ssh
[root@ip-10-0-0-20 master]# chmod 600 .ssh/authorized_keys

# master

생성된 키를 통해 sftp와 ssh 접속을 해보도록 하겠습니다.
생성된 키는 lrzsz를 통해 내보냈습니다.



생성된 키를 파일질라 설정에서 키 파일을 추가 후 접속을 해줍니다.

정상적으로 접근이 되는 것을 확인할 수 있습니다.
생성된 키를 이용하여 접속합니다.
접속은 가능하지만 현재 master 조건 중 하나인
root 진입을 하려면 패스워드를 요구하고 있습니다.
/etc/sudoers, /etc/sudoers.d/90-cloud-init-users 등에서 다음과 같이 추가하게되면
해당 계정은 패스워드 없이 sudo를 사용할 수 있습니다.
사용자명 ALL=(ALL) NOPASSWD:ALL
master 계정 조건 완성

  • sftpuser 계정 생성

master 계정 생성에 성공하였다면, sftpuser 생성은 해줄 것이 별로 없습니다.
openssl 에서 옵션 하나를 추가하여 기간을 주는 것과 root 권한을 사용하지 못하도록 이 계정은 sudoer에 등록하지 않을 것입니다.

[root@ip-10-0-0-20 ~]# useradd sftpuser
[root@ip-10-0-0-20 ~]# cd /home/sftpuser
[root@ip-10-0-0-20 sftpuser]# openssl genrsa -out sftpuser.pem 4096 -days 180
[root@ip-10-0-0-20 sftpuser]# chmod 600 sftpuser.pem
[root@ip-10-0-0-20 sftpuser]# mkdir .ssh
[root@ip-10-0-0-20 sftpuser]# ssh-keygen -y -f sftpuser.pem > .ssh/authorized_keys
[root@ip-10-0-0-20 sftpuser]# chown -R sftpuser:sftpuser .ssh
[root@ip-10-0-0-20 sftpuser]# chmod 700 .ssh
[root@ip-10-0-0-20 sftpuser]# chmod 600 .ssh/authorized_keys

root 권한 불가능

SFTP에서 또 다른 설정을 하고싶다면 /etc/ssh/sshd_config 파일을 수정하여 가능합니다.
#Port 22 를 주석 해제하고 Port 50022 등 자유롭게 포트를 변경하거나
sftp-server / internal-sftp 사용, Match LocalPort, Match User 등 설정이 가능합니다.
sftp-server와 internal-sftp의 차이는 아래에 참고 링크를 남기도록 하겠습니다.

https://zetawiki.com/wiki/Sftp-server%EC%99%80_internal-sftp_%EC%B0%A8%EC%9D%B4

  • ftpguest 계정 생성

마지막으로 ftpguest 계정을 생성할 것입니다.
ftpguest를 생성하기 위해 vsftpd를 설치할 것이며, 계정에 여러가지 제한을 줄 것입니다.
계정을 생성하기 이전에 vsftpd를 먼저 설치하겠습니다.

yum install vsftpd
cd /etc/vsftpd
vi vsftpd.conf

vsftpd.conf에서 기본적으로 다음과 같은 설정을 해주도록 합니다.

#chroot_local_user=YES <- 주석 처리 해제 및 allow_writeable_chroot=YES 추가
chroot_local_user=YES
allow_writeable_chroot=YES

[root@ip-10-0-0-20 ~]# systemctl enable vsftpd
[root@ip-10-0-0-20 ~]# systemctl start vsftpd

위 설정을 통해 상위 디렉토리로 접근을 하지 못하게 하며, FTP 접근이 가능하게 되었습니다.

ftpguest 계정은 쉘 접속은 불가능하여야하며, ftp는 사용 가능해야합니다.
해당 계정 생성 시 -s /bin/nologin 옵션을 주면 ftp와 shell 접속이 둘 다 불가능하게 됩니다.
ftp 접속 시 vsftp가 shell의 유효성을 체크를 하기 때문입니다.

이를 해결하기 위해 2가지 방법이 존재합니다.
첫번째로 /etc/pam.d/vsftpd 에서 vsftp가 쉘 유효성 체크를 하지않도록
auth required pam_shells.so 라인을 주석 처리하는 것입니다.
이 설정을 해두면 ftp를 사용하는 모든 계정에 적용이 됩니다.

[root@ip-10-0-0-20 sftpuser]# cat /etc/pam.d/vsftpd
#%PAM-1.0
session optional pam_keyinit.so force revoke
auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
auth required pam_shells.so -> #auth required pam_shells.so
auth include password-auth
account include password-auth
session required pam_loginuid.so
session include password-auth

두번째 방법으로는 /bin/nologin 을 이용하는 것입니다.
이를 사용하기 위해 /etc/shells 에 /bin/nologin을 추가 해주어야 합니다.

[root@ip-10-0-0-20 sftpuser]# echo “/bin/nologin” >> /etc/shells

/etc/shells에 /bin/nologin 을 넣어주게되면 해당 계정의 shell이 /bin/nologin일 경우
ftp는 접속 가능하지만 shell 접속은 불가능하게 됩니다.
저는 2번째 방법으로 진행하도록 하겠습니다.

[root@ip-10-0-0-20 ~]# useradd -d /home/img -f 30 -s /bin/nologin ftpguest
[root@ip-10-0-0-20 ~]# passwd ftpguest // ftpguest 계정의 패스워드 지정
[root@ip-10-0-0-20 ~]# grep ftpguest /etc/passwd
ftpguest:x:1007:1007::/home/img:/bin/nologin
[root@ip-10-0-0-20 ~]# grep ftpguest /etc/shadow
ftpguest:$6$hH–생략–Pfv7Esh91:18601:0:99999:7:30::

30일동안 사용 가능한 홈 디렉토리가 /home/img인 ftpguest 계정이 생성되었습니다.
이제 해당 계정을 파일질라에서 사용 가능하지만 ssh 접속은 되지않을 것입니다.
(AWS EC2에서는 sshd_config 에서 PasswordAuthentication 옵션이 no로 되어있어서
원래 패스워드를 이용하여 ssh 접속은 되지않습니다.)

하지만 NAT 나 클라우드 환경에서는 정상적으로 되지않을 수 있습니다.
아래와 같은 에러가 발생하면서 말이죠.

“상태: 서버가 라우트 불가능한 주소의 수동형 응답을 보냈습니다. 수동형 모드가 실패했습니다.”

NAT는 무엇인가?, 수동형(passive)은 무엇인가에 대해서는 링크로 남겨두도록 하겠습니다.

https://azurecourse.tistory.com/555 // NAT

https://madplay.github.io/post/ftp-active-passive // active 모드와 passive 모드의 차이점

이어서 해당 문제를 해결하기 위해 passive mode를 설정을 해주도록 합시다.
/etc/vsftpd/vsftpd.conf에서 아래와 같은 내용을 추가해줍니다.

pasv_address=52.?.?.118 // FTP 서버의 공인 IP
pasv_enable=YES
pasv_min_port=20000
pasv_max_port=20050
#listen_ipv6=YES -> listen_ipv6=NO
#listen=NO -> listen=YES

systemctl restart vsftpd 를 사용해 vsftpd를 재시작해주고 파일질라를 통해
ftp 접속을 다시 해봅니다.

정상 접속 완료

이로써 3가지 조건의 계정을 전부 생성해보았습니다.
간단한 FTP 설정 글이지만 저와 같은 초보자 분들에게 많은 도움이 됐길 바랍니다.


마지막으로 vsftpd.conf의 설정값을 정리하는 내용으로 마무리 하겠습니다.

# anonymous=YES or NO
익명 사용자의 접속 허용/거부를 결정합니다.

# local_enable=YES or NO
로컬 계정 사용자들의 접속 허용/거부를 결정합니다. 

# write_enable=YES or NO
FTP 접속 시 사용할수 있는 ftp 명령어 중에 write명령어를 허용/거부 결정합니다.

# local_umask=022 
umask값을 설정합니다.
-. 폴더 권한 : 777 – 022 = 755
-. 파일 권한 : 666 – 022 = 644

# anon_upload_enable=YES  or NO
익명 사용자에게 파일 업로드에 대하여 허용/거부 설정합니다.

# anon_mkdir_write_enable=YES or NO
익명 사용자에게 디렉토리 생성권한에 대하여 허용/거부 설정합니다.

# ftpd_banner=Welcome to ManVSCloud FTP service.
ftp서버로 접속 시 안내메시지 출력 내용을 설정합니다.

# dirmessage_enable=YES or NO
ftp서버에 접속한 사용자가 특정디렉토리로 이동하였을 때
개별 디렉토리의 메시지를 보여줄지 허용/거부 설정합니다.

# message_file=hello
 “dirmessage_enable”이 YES로 설정되어 있을 때 적용됩니다.
개별 디렉토리안내 파일로 사용할 파일명을 지정할 수 있습니다.

# xferlog_enable=YES or NO
ftp접속후에 파일 업로드와 다운로드에 대한 로그를 남길 것인가, 남기지 않을 것인가 설정합니다. 이 설정은 디스크의 용량을 고려하여 결정해야 합니다.
즉 파일 업로드/다운로드 로그는 굉장히 많은 용량이 필요하며 또한 시스템 부하율도 함께 고려하여 신중히 결정해야합니다. 물론 로그를 남기는 것이 로그분석과 개별 사용자의 파일 업로드/다운로드 상황을 알수 있는 방법이지만 시스템 자원을 고려해야합니다.

# xferlog_file=/var/log/vsftpd.log
ftp로그파일의 위치를 결정합니다.

# xferlog_std_format=YES or NO
로그파일에 남길 포맷을 기본포맷으로 남길 것인가, 남기지 않을 것인가 설정합니다.

# connect_from_port_20=YES or NO
ftp서비스는 기본적으로 21번포트와 20번포트를 사용합니다.
ftp접속과 명령어에 사용되는 포트는 21번이며 실제 데이터전송에 사용되는 기본포트는 20번입니다. 이때 20번포트의 데이터전송 연결을 허용할 것인가, 허용하지 않을 것인가 설정합니다.

# session_support=YES or NO
이 설정이 YES로 설정되면 바이너리파일인 wtmp에 ftp접속관련 기록을 남기게 됩니다.
따라서 last 명령어 결과에 ftp접속 기록도 남게됩니다.

# idle_session_timeout=600
ftp연결에서 idle타임에 대한 타임아웃값을 설정합니다.
예를 들어 이 값이 600으로 설정되어 있다면 ftp접속 후 600초동안 아무런 작업이 없다면 강제 로그아웃시킵니다.

# data_connection_timeout=120
데이터 전송시 적용되는 타임아웃값을 설정합니다.
만약 ftp연결시 큰 파일을 업로드 또는 다운로드 할때에 전송도중 접속이 끊기는 상황이 발생한다면 이 설정을 주석처리하거나 또는 이 값을 현재 설정값보다 크게 설정하면 됩니다.

# anon_max_rate=0
# local_max_rate=0
# trans_chunk_size=0
위의 세가지 설정은 ftp서비스의 전송속도를 제한하도록 하는 설정입니다.
즉 초당 byte수를 지정할 수 있으며 제한없이 허용하려면 0으로 설정하면 됩니다.
이 설정은 vsftpd가 standalone모드로 서비스될때에만 적용됩니다.

# max_clients=30
# max_per_ip=3
이 설정은 동시 ftp접속자 수를 제한하는 설정입니다.
첫번째 max_clients는 ftp접속을 최대 30명까지만 허용한다는 설정이며,
max_per_ip는 한 IP(호스트)에서 동시에 3번까지만 접속이 가능하도록하는 설정이다.
이는 서비스거부공격(dos)를 방어하기 위한 방법으로 활용될수 있습니다.

# ascii_upload_enable=YES
# ascii_download_enable=YES
기본적으로 ASCII모드로 업로드/다운로드하는것은 제한되어 있습니다.
이 설정으로 ASCII모드로 업로드/다운로드를 허용하도록 설정할수 있습니다.

# deny_email_enable=YES
# banned_email_file=/etc/vsftpd.banned_emails
익명 사용자 접속 시에 기본적으로 사용되는 계정명은 anonymous이며
패스워드는 email형식으로 입력하게 됩니다.
이때 패스워드로 인정하지 않을 즉 패스워드로 사용하지 못하도록 할 email주소를 사용하도록 하는 설정입니다.
즉 “deny_email_enable=YES”로 설정하고 “banned_email_file=/etc/vsftpd.banned_emails”라고 설정되어 있다면 패스워드로 허용하지 않을 email주소를 /etc/vsftpd.banned_emails파일에 넣어두면 됩니다.  vsftpd.banned_emails 파일에 등록된 email주소는 패스워드로 인정하지 않게됩니다. 따라서 해당 익명 사용자는 접속이 불가능하게 됩니다.
이 설정은 서비스거부공격(dos)를 방어하기 위한 방법으로도 사용됩니다.
(무차별 ftp 접속시도를 차단하기 위한 좋은 방법입니다.)

# chroot_list_enable=YES
# chroot_list_file=/etc/vsftpd.chroot_list
전체사용자가 아닌 특정사용자들에 대하여 자신의 홈디렉토리를 루트디렉토리로 인식하도록하는 기능으로서 이 기능은 사용자의 홈디렉토리의 상위 디렉토리로 벗어나지 못하도록 하는 설정입니다. 먼저 “chroot_list_enable=YES”로 설정하고 /etc/vsftpd.chroot_list파일에는 이 기능을 적용할 사용자 계정명을 등록하면 됩니다.
즉 /etc/vsftpd.chroot_list파일에 등록된 사용자들에 한하여 chroot()기능이 적용되어 자기 자신의 홈 디렉토리 상위디렉토리의 이동이 제한됩니다.
이 파일에 등록할 때에는 한 행에 한사용자 계정씩만 등록해야 합니다.

# chroot_local_user=YES
만약 전체사용자를 대상으로 chroot()기능을 적용하고자 한다면 “chroot_local_user=YES” 설정을 하면 됩니다. 만약 위의 “chroot_list_enable=YES”와 “chroot_local_user=YES”설정이 모두 YES로 되어있다면 /etc/vsftpd/chroot_list에 등록된 사용자들만 chroot()적용을 받지 않게 됩니다. 즉 이 두 설정이 모두 YES로 되어있다면 /etc/vsftpd/chroot_list에 등록된 사용자들을 제외한 나머지 사용자들만 chroot()가 적용되어 상위디렉토리로의 이동이 안된다는 의미입니다.

# ls_recurse_enable=YES
ftp접속시에는 ls사용시 -R옵션을 허용하지 않는 것이 기본설정입니다.
-R옵션이란 서브디렉토리내의 파일들의 목록까지 모두 확인할수 있도록 하는것이며,
서버부하등의 이유로 ftp에서 기본적으로 지원하지 않지만 vsftpd에서는 이 옵션을 사용하여 허용하도록 설정할 수 있습니다. 즉 이 설정 값이 YES로 되어있다면 ftp접속후에 디렉토리 목록 확인 시에 서브디렉토리들의 목록들까지 한번에 볼수 있는 -R옵션을 허용하게 됩니다.

# listen=YES
# listen_port=21
만약 vsftpd를 xinetd모드가 아닌 standalone으로 서비스하려면 위의 listen지시자를 YES로 설정하고 listen_port에 서비스할 포트번호(기본 21번)를 지정하면 됩니다.

# pam_service_name=vsftpd
vsftpd에서 PAM설정파일명으로 사용할 파일명을 지정합니다.
이 설정이 적용되면 기본이 vsftpd이므로 /etc/pam.d/vsftpd파일이 사용됩니다.

# userlist_enable=YES or NO
이 설정은 /etc/vsftpd/user_list파일을 활성화 할것인가를 결정합니다.
즉 이 기능을 YES로 설정하는것과 NO로 설정하는것에는 큰 차이가 있습니다. /etc/vsftpd/user_list파일에 설정된 사용자들의 접근이 차단되기도 하고 허용되기도 합니다. 가능한 이 설정은 YES로 설정해 두는 것이 좋습니다.

# tcp_wrappers=YES or NO
vsftpd로 ftp서비스를 할때에 tcp_wrapper의 접근제어를 받도록 할것인가를 설정합니다.
즉 YES로 설정하면 ftp접속시에 tcp_wrapper의 접근제어를 받도록하여 /etc/hosts.allow, /etc/hosts.deny파일의 허용/차단 설정을 적용받게 됩니다.
반면 NO로 설정하면 tcp_wrapper의 영향을 받지 않습니다.

# force_dot_files=YES
“.”으로 시작하는 숨김파일을 볼수 있게 설정합니다.

# hide_ids=YES
특수한 목적으로 파일 및 디렉토리의 소유자를 숨길 경우가 있습니다.
이런 경우 위와 같이 설정하면 ftp라는 사용자로 보이며 본 ID는 보이지 않습니다.

# passwd_chroot_enable=YES
openssh에 패치를 가하면, ssh또한 자기 home디렉토리를 벗어나지 못하게 설정가능합니다.
이 정책은 /etc/passwd파일의 홈디렉토리부분에 /home/사용자/./ 과 같이 “/./”을 붙여 사용자를 홈디렉토리로 제한하게 됩니다. 이 정책에 따라 적용하려면, 위 설정을 적용하면 됩니다.

# use_localtime=YES
대부분의 ftp서버에서 시간 표현은 표준시각(GMT)를 보여주게 됩니다.
국내에서만 사용하는 ftp서버는 위 설정으로 국내시간으로 보여주게 됩니다.

# pasv_min_port=40000
# pasv_max_port=50000
ftp에서 데이터전송을 위해서 20번포트를 사용합니다.
이 경우 서버에서 클라이언트쪽으로 연결을 하기 때문에 중간에 방화벽 또는 공유기등을 사용한다면 정상작동하지 않을수 있습니다.
이런 문제를 해결하기 위해서 passive모드라는 것이 있고, 이 모드에서는 서버의 1024이후 포트를 사용합니다. 이 포트의 범위를 제한하기 위해서는 위와 같이 설정하게 됩니다.

# deny_file=
{*.mp3,*.wmv}
ftp를 통해 인증된 사용자가 파일을 올리는 것을 막는 방법은 거의 없습니다.
vsftpd는 특이하게 특정파일 패턴을 제한하는 기능이 있습니다.
위와 같이 설정하면 확장자가 mp3나 wmv인 파일은 전송을 못하게 됩니다.

# hide_file=
{*.mp3,.hidden,hide*,h?}
위 설정은 mp3파일, .hidden파일, hide로 시작하는 파일을 보여지지 않게 하는 옵션입니다.

읽어주셔서 감사합니다.