SMB 는 윈도우가 기본적으로 지원하는 파일 공유 프로토콜입니다. 하지만 외부에서는 접속하기가 쉽지 않다는 문제점이 있습니다.
그래서 이번에는 SFTP 프로토콜을 통해 파일 공유를 하는 방법에 대해 다뤄 보도록 하겠습니다.
SFTP는 SSH File Transfer Protocol 의 약자로서 SSH를 통한 파일 전송을 의미합니다. SSH를 통과하기 때문에 속도가 빠르고 보안이 높으며, FreeBSD 시스템에 기본적으로 설치되어 있기 때문에 구축이 간단하다는 장점이 있습니다.
FreeNAS 시스템에도 SSH 가 있으며, SFTP공유를 사용할 수는 있지만, FreeNAS 의 SSH를 인터넷에 노출시키는 것은 좋지 않은 생각입니다. 대신 SFTP 공유를 수행할 Jail 을 만들어서 SFTP 공유를 하도록 하겠습니다.
Jail 에서도 독립된 SSH 를 실행할 수 있으니, SFTP 감옥에 공유하고자 하는 리소스만 마운트하고, 권한을 제한한 다음, SFTP 만 실행할 수 있도록 제한하면 SFTP 를 안전하게 운용할 수 있을 것입니다. 거기다 Fail2Ban 까지 설치해 주면 무작위 대입 시도를 차단할 수 있겠죠.
그럼 만들어보겠습니다.
Jail 만들기
jail 의 이름은 SFTP
자동 시작 설정 해 주세요.
필요한 파일 마운트
SFTP 감옥의 /mnt/chroot 디렉토리 아래에 공유하고자 하는 디렉토리를 마운트 할 것입니다.
iocage exec SFTP mkdir -p /mnt/chroot/Media/Movie /mnt/chroot/Media/Drama /mnt/chroot/persnal/admion
미디어가 마운트 될 디렉토리와 개인 파일이 마운트 될 디렉토리를 만들어주었습니다.
iocage exec SFTP chown -R root:wheel /mnt/chroot
/mnt/chroot 는 chroot 시킬 디렉토리입니다. chroot 설정될 디렉토리의 소유자는 root 이고 그룹은 wheel 이여야 합니다.
iocage stop SFTP
감옥을 정지시켜 주고
- /mnt/Data/Media/Movie ↔ /mnt/chroot/Media/Movie
- /mnt/Data/Media/Drama ↔ /mnt/chroot/Media/Drama
- /mnt/Data/persnal/admion↔ /mnt/chroot/persnal/admion
마운트 해 줍니다.
계정 만들기
iocage console SFTP
감옥 안으로 로그인 해 주세요.
감옥 내부에 유저와 그룹을 만들어야 합니다. 먼저 media 그룹부터 만들겠습니다.
pw group add -n media -g 8675309
그룹의 이름은 달라도 되지만, GID 는 호스트와 동일해야 합니다.
그 후 admion 계정을 만들겠습니다.
pw user add admion -d /nonexistent -s /usr/sbin/nologin -u 1000 -g media -c "admion sftp only user"
admion 계정은 쉘을 사용할 수 없도록 nologin으로 설정하였고, UID 는 호스트와 동일하게 1000, 주 그룹은 media 로 설정하였습니다.
media 그룹과 admion 계정을 만들어주었습니다.
SSH 설정
vi /etc/ssh/sshd_config
sshd 설정 파일을 수정해줍니다. 수정해 주어야 할 부분은 아래와 같습니다.
Port 22
무슨 포트를 들을 것인지를 설정합니다. 여러 개의 포트를 들을 수도 있습니다.
LoginGraceTime 2m
몇 분 동안 로그인을 받을 지 설정합니다. 이 경우, 2분안에 로그인 하지 않으면 접속이 끊어집니다.
PermitRootLogin no
Root 로그인을 허용할지 설정합니다. 허용하지 않는 것이 좋습니다. no.
MaxAuthTries 6
몇 번의 로그인 시도를 허용할지 설정합니다. 이 경우 6번의 로그인을 허용하고, 암호가 6번 틀리면 접속이 끊어집니다.
PubkeyAuthentication no
공개 키 인증을 사용할지 설정합니다. 비밀번호를 이용할 것이므로 no.
PasswordAuthentication yes
암호 기반 인증를 사용할지 설정합니다. 비밀번호를 이용할 것이므로 yes
PermitEmptyPasswords no
빈 암호를 허용할지 설정합니다. no.
DisableForwarding yes
x11 포워딩, tcp 포워딩 등의 포워딩을 전부 금지합니다. sftp 전용으로 사용할 것이므로 포워딩이 필요하지 않습니다. yes.
GatewayPorts no
TCP 포워딩에 관련된 설정입니다. no.
TCPKeepAlive yes
연결이 끊어지지 않도록 KeepAlive 메세지를 보냅니다. yes.
Compression No
압축을 할지 설정합니다. 압축을 원한다면 Gzip-9 과 같은 식으로 압축 프로토콜의 이름을 입력하거나 yes 를 입력합니다.
Subsystem sftp internal-sftp
sftp 를 어덯게 동작시킬지 설정합니다. internal-sftp 으로 설정하면 openssh 자체적으로 sftp 를 수행함으로, chroot 설정을 하였을 때 추가적인 설정 없이 sftp 를 사용할 수 있습니다.
Match LocalPort 22 AllowUsers admion ChrootDirectory /mnt/chroot ForceCommand internal-sftp
Match 설정은 아주 유용하고 편리한 설정입니다. Match 뒤에 붙은 조건에 부합하는 경우, 해당하는 유저에게 아래 설정들이 적용됩니다.
예를 들어, Match Address 192.30.1.3 이라는 설정이 있다면, 192.30.1.3 으로 접근한 유저에게 Match 아래의 설정이 적용됩니다.
AllowUsers 는 허용하는 유저를 의미합니다. AloowUsers admion asdf 라는 설정이 있다면, admion과 asdf 유저만 허용됩니다.
ChrootDirectory 는 루트 디렉토리를 변경하는 것입니다. chroot 가 /mnt/chroot 라면 접속한 유저는 /mnt/chroot 보다 상위의 디렉토리에 접근할 수 없습니다.
ForceCommand 는 말 그대로 강제 명령입니다. 강제로 이후에 서술된 명령을 실행시키는데, internal-sftp 의 경우는 sftp를 실행시킵니다. 만약, ForceCommand exit 라는 설정을 입력했다면 로그인 하자 마자 로그아웃합니다. 어디에 쓰냐구요? 음… 그냥 그렇다구요.
Match 구문의 몇가지 예제를 살펴 보도록 하겠습니다.
Match Users admion PermitTTY no ChrootDirectory /mnt/chroot ForceCommand internal-sftp
위 설정을 사용할 경우, admion 유저가 접속할 경우, PTY를 금지하고, /mnt/chroot 를 chroot로 설정하며, internal-sftp 를 강제로 실행시킵니다.
Match Address 123.45.67.89 AllowUsers asdf ForceCommand date '+%F %r'
123.45.67.89 의 주소에서 로그인 할 경우 asdf 유저만 로그인을 허용하고, date ‘+%F %r’ 명령을 실행하고 연결을 끊습니다.
Match 키워드와 Allow, Deny 등의 제한을 잘 활용하면 다양한 설정이 가능합니다.
Match Address 192.168.1.123 AllowUsers asdf root PermitRootLogin
192.168.1.123 으로 접속하였을 때, asdf 와 root 유저만 로그인 가능하며, root 로그인을 허용합니다.
(...) Port 22 (...) LoginGraceTime 1m PermitRootLogin no StrictModes yes MaxAuthTries 3 (...) PubkeyAuthentication no (...) PasswordAuthentication yes PermitEmptyPasswords no (...) DisableForwarding yes GatewayPorts no TCPKeepAlive yes Compression No (...) Subsystem sftp internal-sftp (...) #SFTP Match LocalPort 22 AllowUsers admion ChrootDirectory /mnt/chroot ForceCommand internal-sftp
위는 설정 예시입니다.
Fail2Ban
fail2ban 을 설치하여 SSH 에 무차별 대입 공격을 하는 것을 막을 것입니다.
fail2ban을 ssh 에 적용하는 것도 nginx fail2ban 과 거의 동일하게 진행됩니다. 참고하시면 좋습니다.
레포 바꾸기
‘pkg 와 port – 레포 바꾸기‘ 를 참고하여 레포를 최신으로 바꿔 주세요.
fail2ban 설치
pkg install py36-fail2ban
fail2ban 만 설치하면 됩니다.
IPFW 구성
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 포트를 연 것이 보일 것입니다. 설정하였다면 ipfw 를 시작해 줍니다.
service ipfw start
Jail.d 설정 만들기
vi /usr/local/etc/fail2ban/jail.d/ssh-ipfw.local
[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.1.0/24
ssh 인증을 3번 이상 틀리면 1시간동안 차단하는 룰을 사용하였습니다.
ignoreip 는 차단하지 않는 IP 또는 대역입니다. 192.168.1.0/24 대역은 차단하지 않습니다.
IPFW action 수정
vi /usr/local/etc/fail2ban/action.d/ipfw.conf
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
위와 같이 해당되는 설정을 찾아 수정해 주세요.
Fail2Ban 서비스 등록
sysrc fail2ban_enable="YES"
Jail 시작시 자동으로 시작되도록 하고
service fail2ban start
Fail2Ban 을 시작해 줍니다.
SSH 시작
sysrc sshd_enable="YES"
Jail 시작시 자동으로 시작되도록 하고
service sshd start
sshd 를 시작해 줍니다.
포트포워딩
22 포트를 그대로 사용하는 것은 좋은 생각이 아닙니다. 공격이 너무 많이 들어오기 때문입니다. 외부 포트를 22가 아닌 다른 포트로 바꾸어 주는 것이 좋습니다. 잘 알려진 포트 나 등록된 포트 를 피해서 (예를 들어 1234) 등록해주는 것이 좋습니다.
SFTP Jail 22 ↔ 외부 1234 TCP 포트
접속
윈도우의 경우는 Raidrive 나 FileZila 와 같은 프로그램을 이용해 사용할 수 있습니다.
안드로이드의 경우는 SFTP 공유를 지원하는 파일 탐색기를 사용하면 됩니다. 많은 수의 파일 탐색기 어플에서 SFTP 공유를 지원합니다.
마치면서
이로서 SFTP 공유를 설정하고 Fail2Ban으로 무차별 대입 공격을 막는 방법을 알아 보았습니다.
다음 포스팅은 FEMP 를 구축하는 것에 대해 다룰 것입니다.