이번에는 SFTP 공유를 설정하는 방법에 대해서 알아보도록 하겠습니다.
SFTP가 무엇인가요?
SFTP는 SSH File Transfer Protocol의 약자입니다. SSH는 Secure SHell의 약자로써 안전이 보장되지 않은 네트워크 상에서 안전하게 통신을 할 수 있도록 하는 쉘입니다. 즉, SFTP는 SSH를 이용한 파일 전송 프로토콜이라고 할 수 있겠네요.
아마 많은 분들이 FTP(File Transfer Protocol)은 아실겁니다. 쉽게 생각하면, SFTP는 FTP에서 보안이 강화된 버전이라고 말 할 수 있겠네요. 하지만, SFTP는 SSH 기반으로 동작하는 FTP는 아닙니다. 애초에 2개는 서로 다릅니다. 설계도 다르게 되었구요. FTP의 보안 강화판은 FTPS라고 해서 따로 있습니다. 그러니 쉽게 이해하기 위해서 FTP에 보안이 강화된 버전이라고 생각 할 수 있습니다.
그래서 안전한 네트워크인 내부망에서는 SMB 등을 이용하여 그냥 공유를 하지만, 안전한지 모르는 외부 네트워크와 파일을 주고받을 때에는 SFTP를 이용하는 것이 안전합니다.
TrueNAS 호스트의 SSH를 바로 연결하는 것은 보안적으로 좋지 않습니다. 따라서 jail을 하나 만들어서 jail 내부의 SSH를 연결하는 방식으로 SFTP 공유를 구축하도록 하겠습니다. 또한, Fail2Ban을 설치하여 무차별 대입 공격을 방어할 수도 있습니다.
Jail 만들기
Jails로 가 주세요. Add를 눌러 Jail을 만듭니다.
Jail의 이름은 SFTP로 설정해 주세요.
Jail Type은 Basejail로 설정해 주세요.
네트워크 설정에서 VNET를 체크해 주세요.
마운트 포인트 폴더 만들기
Jail 내부에서 서버에 설치된 데이터 디스크에 접근하기 위해서는 마운트 포인트를 설정하여야 합니다. Jail 내부의 특정 폴더로 접근하면 Data 디스크의 특정 dataset에 접속할 수 있는 식이죠.
iocage console SFTP
일단 putty를 이용하여 SFTP jail에 접속해 줍니다.
mkdir -p /mnt/chroot/personal/Bongtae /mnt/chroot/Media
/mnt/chroot/ 아래에 공유할 디렉토리를 만들어 줍니다. 저는 Bongtae의 개인 데이터 폴더와 Media 폴더만 만들었지만, 원하시는 만큼 더 만들면 됩니다. 하지만 꼭 /mnt/chroot/ 아래에 폴더를 만들어 주세요.
chown -R root:wheel /mnt/chroot
chown 명령어를 이용하여 chroot 폴더를 chroot 시켰습니다. chroot된 디렉토리의 소유자는 root, 그룹은 wheel로 설정하였습니다.
exit
SFTP jail을 빠져나옵니다.
iocage stop SFTP
SFTP jail을 정지시킵니다.
마운트 포인트 설정하기
WebUI에서 Jails로 가 주세요.
SFTP jail의 메뉴를 클릭하면 Mount Points 메뉴가 있습니다. 클릭해 줍니다.
Actions – Add를 눌러서 마운트 포인트를 설정하는 화면으로 이동합니다.
다음의 마운트 포인트를 설정해 주세요. 하나씩 해 주시면 됩니다. 화살표 왼쪽은 Source, 오른쪽은 Destination을 의미합니다.
- /mnt/Data/Personal/Bongtae → /mnt/chroot/personal/Bongtae
- /mnt/Data/Media → /mnt/chroot/Media
사용자 계정 만들기
iocage start SFTP
SFTP jail을 다시 시작해 주세요.
iocage console SFTP
SFTP jail로 접속해 줍니다.
먼저, 유저가 속할 그룹을 만들도록 하겠습니다.
pw group add -n media -g 8675309
media라는 이름을 가진 그룹을 만들어 줍니다. GID는 TrueNAS 호스트의 GID와 같아야 합니다.(기본적으로 8675309로 설정되어 있을 테지만, 혹시 모르니 확인해 주세요.)
이제 사용자를 만들도록 하겠습니다.
pw user add Bongtae -d /nonexistent -s /usr/sbin/nologin -u 1000 -g media -c "Bongtae for SFTP" -h 0
Bongtae라는 사용자를 만들었습니다. UID는 TrueNAS 호스트의 UID와 동일하게 1000으로 설정하였고, 주 그룹은 media로 하였습니다. 또한, 쉘에 접근할 수 없도록 nologin으로 설정하였습니다. 해당 커맨드를 입력하면 아래와 같은 문구가 뜰 것입니다.
password for user Bongtae:
이때, SFTP 로그인에 사용할 사용자의 비밀번호를 설정해주면 됩니다.
SSH 설정하기
SSH 설정을 통해 로그인 시간 등 다양한 설정들을 직접 해보도록 하겠습니다.
* 앞으로 해당 메뉴얼에는 vi 에디터를 이용하여 텍스트를 편집할 것입니다. vi 에디터 사용법의 경우 따로 포스팅 하지 않을 것이니, 인터넷에서 직접 찾아 보시기를 바랍니다.
vi /etc/ssh/sshd_config
sshd_config 파일을 수정해 주도록 하겠습니다. 수정해야 할 부분은 아래와 같습니다.(기본적으로 #으로 주석처리가 되어 있으니 #을 지워주셔야 합니다.)
Port 22
사용할 포트를 22번으로 설정합니다.
LoginGraceTime 2m
로그인 허용 시간을 설정합니다. 만약 2분안에 로그인 하지 않는다면, 해당 연결은 끊어지도록 설정하였습니다.
PermitRootLogin no
루트 로그인을 허용할 지 묻습니다. 안전을 위해서 no로 설정합니다.
MaxAuthTries 6
로그인 시도를 몇번까지 허용할 것인지 묻습니다. 비밀번호를 6번 틀리면 연결이 끊어지도록 설정하였습니다.
PubkeyAuthentication no
공개키 방식으로 인증을 할 것인지 묻습니다. 우리는 비밀번호를 이용하여 인증을 할 것이므로, no로 바꾸어 줍니다.
PasswordAuthentication yes
패스워드를 사용하여 인증할 것인지 묻습니다. yes로 바꾸어 줍니다.
PermitEmptyPasswords no
빈 패스워드를 허용할 지 묻습니다. no로 바꾸어 줍니다.
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
SFTP를 사용할 것이므로 Tcp, X11 등의 모든 포워딩을 금지할 것입니다. 모두 no로 바꾸어 주세요.
TCPKeepAlive yes
TCP 연결이 끊어지지 않도록 하기 위한 옵션입니다. yes로 바꾸어 줍니다.
Compression no
파일을 주고받을 때, 압축을 여부를 묻는 옵션입니다. 압축을 하게 되면 cpu 사용량이 상당히 높아지므로 권장되는 옵션은 아닙니다. 일반적인 경우에는 no로 해 주시고, 만약 압축을 해야한다면 lz4나 gzip-9과 같은 압축 형식을 no 대신에 적어주시면 됩니다.
Subsystem sftp internal-sftp
SFTP의 동작 방식을 결정합니다. 위와 같이 internal-sftp로 설정하면, TrueNAS에 기본적으로 설치되어 있는 OpenSSH가 SFTP 역할을 하여 설정이 간단해집니다.
Match LocalPort 22 AllowUsers Bongtae ChrootDirectory /mnt/chroot ForceCommand internal-sftp
위와 같이 Match 명령어를 수정해 주시면 됩니다. 하나 하나 설명하자면,
LocalPort 22
SFTP jail의 22번 포트를 통해 접근한 유저에 대해서
AllowUsers Bongtae
Bongtae 사용자만 로그인을 허락하고
ChrootDirectory /mnt/chroot
chroot된 디렉토리는 /mnt/chroot이며
ForceCommand internal-sftp
internal-sftp 사용을 강제한다는 의미입니다.
이렇게 Match 명령은 특정 조건을 만족시키는 연결에 대해서 특별한 작업을 수행하도록 만들 수 있습니다.
만약 SFTP 사용자가 여러명 이라면 AllowUsers Bongtae Family1 Family2처럼 사용자를 추가해주면 됩니다.
또한 chroot된 디렉토리가 /mnt/chroot이므로, Bongtae 사용자는 SFTP에 로그인 하였을 때, SFTP jail의 chroot를 벗어나지 못합니다. chroot 상위 폴더로는 못 가고, 하위 폴더만 갈 수 있다는 것이죠. 따라서 보안적으로 우수합니다.
Fail2Ban 설치하기
무차별 대입 공격을 막기 위해서 Fail2Ban을 설치하도록 하겠습니다.
Fail2Ban 설치
pkg를 이용하여 설치할 것인데, 기본적으로 pkg가 설치되어 있지 않습니다.
pkg
그냥 위의 코드를 입력하면 아래와 같은 메세지가 뜹니다.
The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]:
이때 y를 눌러서 pkg를 설치해 줍니다.
pkg update
또한 pkg 업데이트를 해 줍니다.
pkg install py38-fail2ban
fail2ban을 설치해 줍니다.(파이썬이 계속 업데이트 되기 때문에 py38-fail2ban이 없을 수도 있습니다. 이럴 때에는 pkg search를 이용하여 최신 버전의 fail2ban을 설치해 주세요.)
방화벽 설정 변경
vi /etc/rc.conf
방화벽 설정 파일을 열어줍니다.
firewall_enable="YES" firewall_type="workstation" firewall_logging="YES" firewall_myservices="22/tcp" firewall_allowservices="any" firewall_logdeny="YES"
파일 맨 밑 부분에 위의 코드를 추가해 줍니다. 22번 TCP 포트를 열어주는 코드입니다.
service ipfw start
ipfw 서비스를 시작해 줍니다.
Fail2Ban 설정하기
vi /usr/local/etc/fail2ban/jail.d/ssh-ipfw.local
fail2ban 설정 파일을 만들겠습니다.
[ssh-ipfw] enabled = true filter = sshd action = ipfw[name=SSH, port=22, protocol=tcp] logpath = /var/log/auth.log findtime = 600 maxretry = 3 bantime = 3600 ignoreip = 192.168.122.0/24
파일에 위의 코드를 적어주시면 됩니다.
로그인을 3번 틀리면 1시간동안 밴 되도록 하였습니다. 또한, ignoreip를 설정하여 192.168.122.0/24(저의 경우 내부망) 대역에서의 접속 시도는 3번 이상 틀려도 밴하지 않도록 설정하였습니다.
IPFW의 action 옵션 수정하기
vi /usr/local/etc/fail2ban/action.d/ipfw.conf
ipfw의 action 옵션을 수정하겠습니다.
actionstart = ipfw add 2410 <blocktype> tcp from "table(100)" to <localhost> 22 actionban = ipfw table 100 add <ip> actionunban = ipfw table 100 delete <ip> localhost = me
파일 내에서 위에 해당되는 내용을 위와 같이 수정해 주세요.
ipfw 테이블에 밴을 할 IP를 등록했다가 1시간이 지나면 해당 테이블에서 IP를 삭제하는 방식으로 작동됩니다.
Fail2Ban 서비스 등록하기
sysrc fail2ban_enable="YES"
fail2ban 서비스가 jail 시작시에 자동으로 시작하도록 설정합니다.
service fail2ban start
fail2ban 서비스를 시작합니다.
SSHD 서비스 시작
SFTP를 사용하기 위해서 SSHD 서비스를 시작하겠습니다.
sysrc sshd_enable="YES"
sshd 서비스가 jail 시작시에 자동으로 시작하도록 설정합니다.
service sshd start
sshd 서비스를 시작해 줍니다.
포트포워딩 하기
SFTP는 외부망에서 접속하는 것을 기본으로 하기 때문에 포트포워딩을 해 주어야 합니다. 그런데, 22번 포트는 굉장히 잘 알려져 있기 때문에 외부 포트를 22번으로 설정하면 굉장히 많은 공격이 들어옵니다. 그렇기 때문에 잘 알려진 포트나 이미 등록된 포트는 피해서 아무 포트나 정해주세요. 저의 경우 2580으로 정하였습니다.
SFTP jail의 TCP 22번 포트 ↔ 외부망의 TCP 2580번 포트
SFTP 접속하기
SFTP 접속은 FileZila 또는 RaiDrive 등을 이용하여 할 수 있습니다. 다양한 소프트웨어가 많으니 자신에게 맞는 소프트웨어를 사용하시면 되겠습니다.
자신의 외부망 IP의 TCP2580번 포트로 접속하면 SFTP jail에 접속할 수 있습니다.
마치면서
이로써 무차별 대입 공격을 방어할 수 있는 SFTP 시스템을 구축하였습니다.
다음에는 도메인에 대한 내용을 다루도록 하겠습니다.
감사합니다. 사이트 정보 덕분에 nas 구축을 잘 마칠 수 있었습니다. 검색을 통해 들어오실 분들을 위해 정보를 드리자면, sftp 계정 생성 후 비밀번호를 설정 해주셔야 접속이 가능합니다. 본문에 아마 누락하신 듯 합니다. 처음에 접속이 안 되서 고생하다, 비밀번호 문제임을 깨닫고 해결하였습니다.
아울러 추가로 질문 하나 드리겠습니다.
IPFW의 action 옵션 수정하기 파트에서
VI 에디터로 해당 내용을 작성한 뒤에
:w 명령어로 저장이 되지 않는데 어떤 이유인지 궁금합니다.
현재는 해당 항목은 건너 뛰고 실행한 상태인데,
서버는 정상 작동하는 듯 합니다.
위 가이드에서 알려주신
각종 서비스 시작 명령어의 경우
해당 명령어로 실행이 불가능하고, onestart 옵션을 주라고 결과가 출력되어
해당 옵션으로 실행이 가능했는데, 문제가 있을지도 궁금합니다.
고생해서 공유해주신 정보 다시 한 번 감사드립니다.
먼저, 늦은 답변 사과드립니다.
SFTP 계정을 생성할 때, 비밀번호를 설정하는 것을 제가 빼먹었네요. 알려주셔서 감사합니다. 비밀번호를 설정하는 단계를 추가했습니다.
IPFW의 action 옵션 수정하기 부분에서 :w 명령어로 저장이 되지 않는다고 말씀해주셨는데, 제가 다시 테스트 해 본 결과 정상적으로 작동됩니다. :w 명령어만 사용할 시에는 저장한 하고 에디터를 나가는것은 아니라서 아마 저장이 되지 않았다고 생각하신것 같습니다. :wq 명령어를 사용하면 저장하고 에디터를 나가게 됩니다. 만약 제가 생각한것과 다르다면 댓글로 말해주세요.
마지막으로, onestart 옵션을 주라는 결과가 출력되는 경우는 해당 서비스가 /etc/rc.conf에 등록되지 않았기 때문입니다. 등록하도록 해주는 명령어가 sysrc 명령어인데, 아마 sysrc 명령어를 입력하시면서 오타가 발생하여 제대로 등록이 되지 않은것 같습니다. 제 글을 참고하여 정확하게 sysrc 명령어를 입력해 주세요. 또한 onestart 명령어를 사용하였을 때 문제가 있을지 궁금하시다고 말해주셨는데, onestart 옵션을 이용하여 서비스를 시작하였을 때에는 서버를 껐다가 다시 키게되면 해당 서비스가 자동적으로 시작되지 않는 문제가 생깁니다. /etc/rc.conf에 등록하는 이유가 서비스들을 서버 부팅시에 자동적으로 시작하도록 하기 위함인데, 이 과정을 건너뛰면 서비스가 자동적으로 시작되지 않습니다. 따라서 /etc/rc.conf에 서비스를 등록해주시기만 하면 될 것 같습니다.
이해가 안되는 점이 있으시다면 댓글로 알려주세요.
TrueNAS CORE 13.0-u2 설치후
WEB UI
http://192.168.1.198
https://192.168.1.198
가 생겼습니다
그리고 POOLS DATASET Accounts Group User 다 만들었습니다
ACL 권한도 설정하였습니다
내부 네트워크에서 SMB 도 됩니다
그런데 jails 설정이 안됩니다
jail 설정시 release 선택이 안됩니다
그래서 외부에서 접속하려고 Webdav 설정하였습니다. 포트포워딩으로 포트도 9000으로 열었습니다
그런데 외부에서 접속하려고
https://192.169.1.198:9000/
시도해도 안열립니다
외부에서 Truenas 에 접근하는 방법 좀 알려 주시면 고맙겠습니다
안녕하세요. 늦은 답변 사과드립니다.
Jail 설정 시에 release 선택이 되지 않는 문제는 TrueNAS 서버가 외부 인터넷과 연결이 되지 못하여 freebsd의 release 정보를 받아오지 못하기 때문입니다. TrueNAS 서버가 외부 인터넷과 연결되어 있는지 확인해 주세요.
또한, 일반적인 공유기의 게이트웨이 IP는 192.168.0.1인데, 현재 설정하신 IP는 192.168.1.198입니다. 192.168.0.198로 변경하시고 다시 한번 시도해 보세요.
fail2ban 설정에
action = ipfw[name=SSH, port=22 protocol=tcp]
포트와 프로토콜 사이에 , 를 원래 안 넣는 건가요?
앗 오타인거 같습니다. 지적해 주셔서 감사합니다!