서버에서 SFTP 접속만 허용하는 계정을 만들 일이 생겨서 계정을 만들면서 작업했던 내용을 정리하였다. 일단 계정을 만들면서 필요했던 것은 해당 계정은 지정해 준 디렉토리에만 접근할 수 있어야 하며, 다른 서버 디렉토리는 접근할 수 없도록 권한을 막아두어야 했다.
다행히 구글링을 통해 내가 원하는 방향으로 작업할 수 있는 내용이 있었고, 해당 내용으로 실제 작업을 진행하니 정상적으로 계정생성과 디렉토리 접근을 막을 수 있게 되었다.
작업 했던 내용을 잊지 않기 위해... 다시 한번 정리하여 업로드 해본다.
먼저 sftp만 사용할 계정의 그룹을 먼저 만들어준다. 나는 sftp-only라는 그룹을 만들어주었다.
[root@localhost ~]# groupadd sftp-only
[root@localhost ~]#
다음 sftp로만 접근할 수 있는 sftp전용 계정을 만들어준다. 명령어는 아래와 같다.
useradd -s /sbin/nologin -G 그룹이름 계정이름
여기서 /sbin/nologin 을 사용하면 ssh 접속은 가능하게 하지만 shell 사용 권한을 주지 않아 shell 접속은 불가능하게 만든다. (S)FTP, SMTP, POP3 등의 기타 목적을 위한 계정을 생성할때 사용한다.
[root@localhost ~]# useradd -s /sbin/nologin -G sftp-only sftp-test
[root@localhost ~]#
계정이 서버에 접근할 때 사용할 패스워드를 세팅해준다. 패스워드는 임의로 'test1234'로 세팅해준다. 여기서 주의할 점은 nologin 으로 만드는 계정은 root 사용자가 변경해주지 않는 한 패스워드 변경이 불가능하다. shell 접속이 되지 않으니... root 관리자에게 변경을 부탁하는게 제일 좋다.
[root@localhost ~]# echo 'test1234' | passwd --stdin sftp-test
Changing password for user sftp-test.
passwd: all authentication tokens updated successfully.
패스워드 세팅을 완료했으면 다음과 같이 만들어진 계정으로 ssh 접속을 시도해본다.
[root@localhost ~]# ssh sftp-test@localhost
sftp-test@localhost's password:
접속하려 하면 아래와 같이 출력되는데, 그 이유는 접속 하려는 계정이 패스워드는 맞지만 shell 접속 권한이 없어서 세션이 닫힌 상태이기 때문이다.
This account is currently not available.
Connection to localhost closed.
[root@localhost ~]#
여기까지 완료했으면 sftp 사용을 위한 계정생성이 완료된다.
다음 ssh 접속시 sftp 사용을 위한 설정을 살짝 변경해주어야 한다. 여기서 중요한게 internal-sftp이다.
일단 vi를 이용하여 /etc/ssh 경로에 있는 sshd_config파일을 열어준다.
[root@localhost ssh]# vi /etc/ssh/sshd_config
파일을 열고 맨 아래 마지막 부분을 보면 기본 세팅으로 다음과 같이 sftp-server로 되어있다.
...
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
해당 부분은 주석 처리하고 아래와 같이 변경해준다.
#Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp
Match Group sftp-only
ChrootDirectory /sftp_home/
ForceCommand internal-sftp -d %u
sftp-server를 internal-sftp로 변경해 주는 이유는 다음과 같다.
chroot는 루트 디렉토리를 변경하는 리눅스 명령어이다. 해당 명령이 실행된 위치를 루트(/)로 인식하게 해준다. (여기서는 /sftp_home을 '/'로 인식하게 된다.) 이렇게 되면 위에서 설정한 계정 혹은 그룹으로 로그인했을 때, 정해진 디렉토리의 상위 디렉토리로 접근하지 못하게 된다.
즉 sftp_home 디렉토리가 최상단이기 때문에 그보다 더 상위 디렉토리에는 접근이 안되는 것이다.
다만 chroot 사용 시 디렉토리의 소유자와 권한에 대해 주의해주어야 한다.
1. 소유자는 root 여야 함. 여기서는 sftp_home의 소유자가 root 이어야 한다.
[root@localhost /]# ll
total 16
...
drwxr-xr-x. 2 root root 6 May 19 16:40 sftp_home
drwxr-xr-x. 2 root root 6 Apr 11 2018 srv
...
3번의 내용에 대해 조금 자세하게 확인해보자.
먼저 루트(/sftp_home)경로에 sftp를 사용할 아이디 디렉토리와 그 하위에 uploads 디렉토리를 만들어준다.
명령어는 아래와 같다.
mkdir -p /sftp_home/계정 이름/uploads
[root@localhost sftp_home]# mkdir -p /sftp_home/sftp-test/uploads
[root@localhost sftp_home]# ll
total 0
drwxr-xr-x. 3 root root 21 May 19 16:42 sftp-test
[root@localhost sftp_home]# cd sftp-test/
[root@localhost sftp-test]# ll
total 0
drwxr-xr-x. 2 root root 6 May 19 16:42 uploads
실제 업로드 파일들은 위의 'uploads' 디렉토리에 들어가게 된다. sftp_home 경로 아래는 sftp를 사용할 계정들만 관리하게 된다.
디렉토리 생성을 완료했으면 아래와 같이 권한을 변경해준다.
chown 계정 이름:계정 그룹 /sftp_home/계정 이름/uploads
실제 아래와 같이 명령어를 입력하면 권한이 바뀐 모습을 볼 수 있다.
[root@localhost sftp-test]# chown sftp-test:sftp-only /sftp_home/sftp-test/uploads
[root@localhost sftp-test]# ll
total 0
drwxr-xr-x. 2 sftp-test sftp-only 6 May 19 16:42 uploads
[root@localhost sftp-test]#
권한 변경까지 완료되었으면 sshd를 재실행해준다. 재실행하지 않으면 아까 변경했던 sshd_config의 내용이 적용되지 않는다.
[root@localhost sftp-test]# service sshd restart
Redirecting to /bin/systemctl restart sshd.service
사용자와 그룹 권한이 변경된게 확인돠었으면 실제로 접속 해보자. 접속하면 아래 이미지와 같이 '/'가 sftp_home으로 잡히며, 그 하위에 만들어 둔 계정 디렉토리로 접근하게 된다. 그리고 해당계정에서 uploads 디렉토리로 접근 가능한 것을 볼 수 있다.
그럼 이제 실제 파일을 업로드 해보자.
현재 위치(/sftp-test) 경로에 파일을 업로드 하려면 업로드가 실패하는 것을 볼 수 있다.
그 이유는 sftp-test 디렉토리는 소유자 이외에는 쓰기 권한이 없기 때문이다.
아까 위에서 주었던 권한이 소유자를 제외하고는 쓰기권한이 없는 것을 기억하자.
(이 디렉토리의 소유자는 root 이며, 디렉토리의 권한은 755이다.)
upload 디렉토리로 이동한 후 파일을 업로드해보면 정상적으로 업로드 되는 것을 확인할 수 있다.
정상적으로 이미지 업로드가 된 모습