FTP로 연결해서 IZ*ONE Private Mail 통계의 질문 항목을 추가 하다가, FTP 접속이 먹통이 되면서 검색용 스크립트가 앞부분만 남고 뒷부분 절반이 날아갔다. 코드는 어떻게든 새로 짜 넣었지만, 매번 이런식이면 곤란하겠다 싶어 자동 백업을 설치해보기로 했다.

정해진 시간에 원하는 폴더와 데이터베이스를 백업하고, 구글드라이브까지 올려주는 기능이 필요했는데, 웹호스팅용 무료 백업툴은 찾기가 힘들었다. 무료 툴은 이것저것 다 깔아서 시도해봤지만, 백업조차 제대로 되는 것이 없었다. 결국 구글드라이브로의 업로드는 포기하고 백업 파일 생성 후 rsync로 개인 NAS에 업로드하는 선에서 타협을 했다. 웹호스팅 내에서 모든 것을 처리하려면, 워드프레스를 하나 더 설치하고 백업 플러그인을 사용해서 구글드라이브로 올리는 것이 더 나은 방법일 것 같다.

대부분 shell에서 작업을 해야 하기 때문에, 기본적으로 웹호스팅 서버에 SSH 접속이 가능하고, 웹호스팅 서버에서 SSH Client를 사용할 수 있어야 한다.

1. 백업 파일 생성

godaddy-backup-script(https://github.com/etiennerached/godaddy-backup-script)를 이용해서, IZ*ONE 데이터베이스와 IZ*ONE 폴더를 백업한다. config파일만 맞게 작성하면 코드 수정없이도 잘 동작하였다. 백업할때 현재 시간으로 폴더를 만들게 되어 있는데, 웹호스팅 서버는 미국 시간 기준이라서 시차 보정만 추가하였다.

IZ*ONE 관련 파일들이 저장된 폴더를 묶고, IZ*ONE 데이터베이스를 덤프한 후 /home/junklab/backup/izone_backup/ 폴더 밑에 시간별로 차곡차곡 저장하게 된다. 보안을 위해서 웹에서 접근이 가능한 public_html 내부가 아닌, 사용자 홈 바로 아래에 별도의 백업 폴더를 생성했다. shell 권한이 있는 유저만 해당 폴더에 접근이 가능하다.

godaddy-backup-script 자체적으로 FTP 전송 기능도 있다. 혹시 웹호스팅에 FTP Client가 설치되어 있고 사용 가능하다면, 그냥 FTP로 전송하는 것이 낫다. JunkLAB이 있는 웹 호스팅 서버에는 FTP Client가 없어서, rsync를 시도해보게 되었다.

2. 웹호스팅 기능 확인

rsync를 사용하기 위해선 일단 웹호스팅 서버에서 NAS로 SSH 접속이 가능해야 한다. which 명령어를 사용해서 rsync, ssh가 설치되어 있는지 확인했다.

[junklab@us-west04 ~]$ which rsync
/usr/bin/rsync
[junklab@us-west04 ~]$ which ssh
/usr/bin/ssh
[junklab@us-west04 ~]$ which ssh-keygen
/usr/bin/ssh-keygen
[junklab@us-west04 ~]$ which ssh-copy-id
/usr/bin/ssh-copy-id

3. 웹호스팅에서 NAS로 SSH 연결 확인

ssh admin@nas주소로 SSH 접속이 가능한지를 확인해야 한다. 아래 처럼 Connection refused 또는 다른 에러 메시지가 나온다면 NAS쪽 설정에 문제가 있다고 볼 수 있다. nas주소는 ssh.nas.com으로, NAS IP는 123.123.123.123이라고 가정하도록 하겠다.

[junklab@us-west04 ~]$ ssh admin@ssh.nas.com
ssh: connect to host ssh.nas.com port 22: Connection refused

NAS 설정에 문제가 없으면 아래와 같이 보안 key fingerprint를 물어보게 되고, yes를 선택하면 admin 계정의 비밀번호를 물어본다. 정상적으로 접속 가능하다면, 6번으로 넘어가서 바로 rsync 설정을 해주면 된다.

[junklab@us-west04 ~]$ ssh admin@ssh.nas.com
The authenticity of host '[ssh.nas.com]:22 ([123.123.123.123]:22)' can't be established.
ECDSA key fingerprint is SHA256:XJTH632xNMvZBO+ObVIOU8SWh83CiaNiMwaLm9KThXM.
ECDSA key fingerprint is MD5:f8:68:11:b3:60:4a:4f:91:e9:53:84:46:b1:0e:8d:27.
Are you sure you want to continue connecting (yes/no)?

이미  NAS에 SSH 포트를 6782로 변경해서 잘 쓰고 있었기 때문에, -p 옵션으로 포트를 지정해서 접속을 시도해 보았지만 Connection refused 에러만 나왔다. 내 PC에선 아무 문제 없이 접속이 되는 걸로 봐서는 포트 포워딩의 문제도 아니었지만, 포트를 22로 아예 원복을 하면 문제 없이 접속이 되었다.

[junklab@us-west04 ~]$ ssh -p 6782 admin@ssh.nas.com
ssh: connect to host ssh.nas.com port 6782: Connection refused

Synology NAS 쪽에서 또 다른 설정이 있을 것 같아 SSH 관련 설정을 다시 확인 했다.

4. Synology NAS에서 SSH 설정

SSH 활성화는 제어판 -> 응용 프로그램 -> 터미널 및 SNMP에서 SSH 서비스 활성화에 체크만 해주면 된다.
Synology NAS의 경우 해킹 시도가 많기 때문에, 보안 목적으로 포트를 기본 22에서 다른 것으로 변경을 하라고 많이 권장하고 있다. SSH 포트를 6782로 변경하고, 공유기에서도 6782를 포트포워딩 시켜주었다.

몇가지 테스트를 해보니 SSH의 포트를 변경하면 동일망 내의 PC에선 SSH 접속에 문제가 없었지만, 외부망에서는 포트포워딩을 통해서도 SSH 접속이 안되는 것 같았다. 이 경우에는 NAS에서 라우터 구성을 추가해 줄 필요가 있다.

제어판 -> 연결성 -> 외부 액세스 -> 라우터 구성에서 라우터 설정을 눌러 라우터 인식을 먼저 시키면, 생성 버튼이 활성화 된다. 라우터 인식에서 오류가 뜨더라도 별다른 문제는 없는 것 같다. 생성 버튼을 눌러 사용자 지정 포트를 선택한 후 위에서 변경한 SSH 포트를 넣어주면, 라우터 포트가 자동으로 생성된다. 연결 테스트에 문제가 없다면, 이 라우터 포트를 이용해야 외부망에서도 SSH 접근이 제대로 되었다. 생성 버튼을 눌러 내장 응용 프로그램을 선택한 후 rsync 포트도 추가해주었다.

5. 포트 변경 후, 웹호스팅에서 NAS로 SSH 연결 확인

웹호스팅에서 변경된 포트로 접속 테스트를 해보았다. continue connecting 물음에 yes를 입력하면, NAS주소와 key값이 known hosts에 저장이 되고, 앞으로는 NAS로 SSH 연결할 때 연결 여부를 더이상 물어보지 않는다. 정상적으로 접속이 되면 exit로 빠져나오면 된다.

[junklab@us-west04 ~]$ ssh -p 63703 admin@ssh.nas.com
The authenticity of host '[ssh.nas.com]:63703 ([123.123.123.123]:63703)' can't be established.
ECDSA key fingerprint is SHA256:XJTH632xNMvZBO+ObVIOU8SWh83CiaNiMwaLm9KThXM.
ECDSA key fingerprint is MD5:f8:68:11:b3:60:4a:4f:91:e9:53:84:46:b1:0e:8d:27.
Are you sure you want to continue connecting (yes/no)?yes
Warning: Permanently added '[ssh.nas.com]:63703,[123.123.123.123]:63703' (ECDSA) to the list of known hosts.
admin@ssh.nas.com's password:
admin@DiskStation:~$ exit
logout
Connection to ssh.nas.com closed.
[junklab@us-west04 ~]$

6. Synology NAS에서 rsync 설정

제어판 -> 파일 공유 -> 파일 서비스 -> rsync로 가서 서비스 활성화를 하고, SSH 암호화 포트에는 라우터 포트가 아닌 로컬 포트를 입력하였다.

SSH 연결 테스트를 했던 admin 계정은 권한이 너무 많으니, 제어판 -> 파일 공유 -> 사용자 -> 생성으로 이동해서 rsync 전용 계정을 새로 만들었다.

  • Synology 보안상 administrators 그룹에 속한 계정만 외부 SSH 접속이 가능하기 때문에, rsync 계정의 사용자 그룹에 administrators를 추가했다.
  • 공유 폴더 권한은 NetBackup(기본 백업 폴더)을 제외하고는 모두 접근 금지로 설정하였다. NetBackup은 일단 읽기/쓰기.
  • 응용 프로그램 권한 할당도 rsync를 제외하고는 모두 거부로 설정하였다.

사용자 생성이 끝난 후, 고급 탭에서 사용자 홈 서비스 활성화가 체크되어 있는지 확인이 필요하다. Password 없는 SSH 접속에 사용되는 인증 key를 저장하려면, 해당 기능이 활성화 되어 있어야 한다.

마지막으로 File Station에서 NetBackup 선택 -> 오른쪽 마우스 클릭 -> 속성 -> 권한에 rsync 사용자를 추가한 후 모든 권한을 주었다. 뭔가 확인 메세지가 떴는데 별 문제 아닌 것 같아서 무시하고, 이 폴더, 하위 폴더 및 파일에 적용까지 체크 한 후에 확인을 눌러 저장했다. 이제 NetBackup 폴더는 rsync 사용자가 모든 권한을 가지게된다.

7. Password 없는 SSH 접속 설정

[junklab@us-west04 ~]$ ssh -p 63703 rsync@ssh.nas.com
rsync@ssh.nas.com's password:
rsync@DiskStation:~$ pwd
/var/services/homes/rsync
rsync@DiskStation:~$ exit
logout
Connection to ssh.nas.com closed.
[junklab@us-west04 ~]$

rsync 홈 서비스로 접근이 가능해졌다. 이제 웹호스팅 서버에서 SSH KEY를 생성 후 NAS로 복사하면 된다.
ssh-keygen 명령어로 RSA 키를 생성했다. 중간 질문은 모두 Enter를 쳐서 skip했고, /.ssh 폴더와 그 하위 파일들의 퍼미션을 재설정하였다.

[junklab@us-west04 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/junklab/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/junklab/.ssh/id_rsa.
Your public key has been saved in /home/junklab/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:2SgDtUp6rUDSaiKDgqTJ3cLVYposwRlXCQt6wmSWCcg junklab@us-west04
The key's randomart image is:
+---[RSA 2048]----+
|=*o  o o   .o    |
|OE = .o . .      |
|+* + .o + ..     |
|*B =o*+.+        |
|@+oB o.+ S .     |
|=..o.. o         |
| .               |
|                 |
|                 |
+----[SHA256]-----+
[junklab@us-west04 ~]$ chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
[junklab@us-west04 ~]$ ls -al ~/.ssh
total 20
drwx------ 2 junklab junklab 4096 Apr 13 02:13 .
drwx--x--x 35 junklab junklab 4096 Apr 11 05:26 ..
-rw------- 1 junklab junklab 1679 Apr 13 02:14 id_rsa
-rw------- 1 junklab junklab 416 Apr 13 02:14 id_rsa.pub
-rw------- 1 junklab junklab 207 Apr 13 02:11 known_hosts
[junklab@us-west04 ~]$

ssh-copy-id 명령어로 위에서 생성된 RSA key를 NAS의 rsync의 홈으로 복사를 해주었다.

[junklab@us-west04 ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub -p 63703 rsync@ssh.nas.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/junklab/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
rsync@ssh.nas.com's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh -p '63703' 'rsync@ssh.nas.com'"
and check to make sure that only the key(s) you wanted were added.

정상적으로 복사가 되어, SSH 접속을 다시 해보니, 더이상 Password를 물어보지 않았다.

[junklab@us-west04 ~]$ ssh -p 63703 rsync@ssh.nas.com
rsync@DiskStation:~$

Password를 여전히 물어본다면, Password를 입력해서 NAS에 접속한 후, 아래의 작업을 추가로 해주면 된다고 한다.

rsync@DiskStation:~$ chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
rsync@DiskStation:~$ chmod u=rwx,g=rx,o=rx /volume1/homes/rsync/
rsync@DiskStation:~$ ls -al ~/.ssh
total 12
drwx------ 2 rsync users 4096 Apr 13 18:20 .
drwxr-xr-x 3 rsync users 4096 Apr 13 18:20 ..
-rw------- 1 rsync users 416 Apr 13 18:20 authorized_keys
rsync@DiskStation:~$

혹시 웹호스팅 서버 쪽에 문제가 생겨 rsync 계정 접속 시 Password를 입력하게 하고 싶다면, 위의 ~/.ssh/authorized_keys 파일을 삭제하면 된다.

8. 웹호스팅에서 rsync 실행

다시 웹호스팅 서버로 가서 rsync를 시도해보았다. 기본적인 명령어는 다음과 같다.

rsync -avz -e "ssh -p ssh포트" 로컬 폴더 rsync@NAS주소:원격폴더

  • godaddy-backup-script가 자동 저장하는 웹호스팅 서버의 폴더 위치(로컬 폴더) : /home/junklab/backup/izone_backup/
  • NAS에서 rsync 계정 생성시 읽기/쓰기 권한을 줬던 백업 폴더 위치(원격 폴더) : /volume1/NetBackup/

NetBackup 폴더의 모든 권한을 rsync 계정에게 주었기 때문에, 해당 폴더는 rsync가 자동으로 새로운 폴더도 만들고 소유자도 변경할 수 있게 된다.
웹호스팅 서버의 /home/junklab/backup/izone_backup/ 안에 있는 내용을 NAS의 /volume1/NetBackup/izone_backup으로 모두 복사하려면 다음의 2가지 방법을 사용할 수 있다.

  1. rsync -avz -e "ssh -p 63703" /home/junklab/backup/izone_backup/ rsync@ssh.nas.com:/volume1/NetBackup/izone_backup
    >>> /home/junklab/backup/izone_backup/ 폴더 안의 내용을 /volume1/NetBackup/izone_backup에 복사한다.
  2. rsync -avz -e "ssh -p 63703" /home/junklab/backup/izone_backup rsync@ssh.nas.com:/volume1/NetBackup
    >>> /home/junklab/backup/izone_backup 폴더 통째로 /volume1/NetBackup에 복사한다.

로컬 폴더의 마지막에 /가 있고 없고에 따라 복사 방식이 달라지니 주의할 필요가 있다. 그리고, ssh.nas.com 바로 뒤에 나오는 :는 빼먹으면 안된다.

[junklab@us-west04 ~]$ rsync -avz -e "ssh -p 63703" /home/junklab/backup/izone_backup/ rsync@ssh.nas.com:/volume1/NetBackup/izone_backup
sending incremental file list
created directory /volume1/NetBackup/izone_backup
./
2019-04-12_04-00/
2019-04-12_04-00/config.sh
2019-04-12_04-00/files_2019-04-12_04-00.tar.gz
2019-04-12_04-00/izone.cnf
2019-04-12_04-00/izone_2019-04-12_04-00.sql.gz

sent 557,581,885 bytes received 512 bytes 2,038,692.49 bytes/sec
total size is 557,279,483 speedup is 1.00

godaddy-backup-script 마지막에 위의 rsync 명령어를 한줄 추가한 뒤, 매 12시간마다 script가 실행되게 Cron 설정을 해주었다. 구글드라이브로의 백업은 cloudsync를 사용하고 있다.