자동으로 동기화가 될 수 있도록 시스템을 마련하자
[마스터 서버]에서 [두 서버 모두]에 접속할 수 있는지 확인
아래 참고하여 서버 관련 암호화 파일 생성
서버 정보 암호화(파이썬 cryptography, GPG)
from cryptography.fernet import Fernet
import os
# 비밀 키 생성
key = Fernet.generate_key()
cipher_suite = Fernet(key)
# 암호화할 데이터 JSON 형식으로 생성
server_info = b"""
{
"USER": "계정 이름",
"MASTER_KEY": "마스터 키 위치",
"OP_HOST": "온프레미스 IP주소",
"OP_SSH": 온프레미스 SSH 포트번호,
"OP_KEY": "온프레미스 접속 키 위치",
"CLODU_HOST": "클라우드 IP주소",
"CLOUD_SSH": 클라우드 SSH 포트번호,
"CLOUD_KEY": "클라우드 접속 키 위치",
}
"""
# 암호화
data = cipher_suite.encrypt(server_info)
# 작업 디렉토리 변경
os.chdir("/home/master/.forRsync/")
# pwd 변수에 작업 디렉토리 저장
pwd = os.getcwd()
# print(pwd)
# 암호화된 데이터와 키 파일로 생성
with open(pwd + "/SI.enc", 'wb') as enc_file:
enc_file.write(data)
with open(pwd + '/SOLVE.key', 'wb') as key_file:
key_file.write(key)
테스트
test.py
from cryptography.fernet import Fernet
import json
import os
os.chdir("/home/master/.forRsync/")
pwd = os.getcwd()
# 키를 읽어오기
with open(pwd + '/SOLVE.key', 'rb') as key_file:
key = key_file.read()
cipher_suite = Fernet(key)
# 암호화된 설정 파일 읽기
with open(pwd + '/SI.enc', 'rb') as enc_file:
cipher_text = enc_file.read()
# 복호화
data = cipher_suite.decrypt(cipher_text)
# JSON 데이터 로드
server_info = json.loads(data)
print(server_info)
from cryptography.fernet import Fernet
import json
import os
import paramiko
import subprocess
import json
# init
########## begin ##########
os.chdir("/home/master/.forRsync/")
pwd = os.getcwd()
# 키를 읽어오기
with open(pwd + '/SOLVE.key', 'rb') as key_file:
key = key_file.read()
cipher_suite = Fernet(key)
# 암호화된 설정 파일 읽기
with open(pwd + '/SI.enc', 'rb') as enc_file:
cipher_text = enc_file.read()
# 복호화
data = cipher_suite.decrypt(cipher_text)
# JSON 데이터 로드
server_info = json.loads(data)
########## end ##########
# var.json 파일 읽기 위함
def ReadJson():
with open(pwd+'/var.json', 'r') as f:
jsonData = json.load(f)
return jsonData
# var.json 파일 쓰기 위함
def WriteJson(jsonData):
with open(pwd+'/var.json', 'w') as make_file:
json.dump(jsonData, make_file, indent="\t")
# ping을 통해 서버가 살아있는지 확인
def CheckServer(ip):
try:
alive = subprocess.run(["ping", "-c", "1", ip], capture_output=True, text=True, check=True)
print(alive.stdout)
if "1 received" in alive.stdout:
print(ip, ": ON")
return True
else:
print(ip, ": Down")
return False
except subprocess.CalledProcessError:
print(ip, ": Down")
return False
# SSH 접속해서 동기화 명령어 실행
def SSHConnect(srcIp, srcPort, srcKeyPos, destIP, destPort):
key = paramiko.RSAKey.from_private_key_file(server_info['MASTER_KEY'])
s = paramiko.SSHClient()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
s.connect(srcIp, port=srcPort, username=server_info['USER'], pkey=key)
cmd = "sudo rsync -avruz --delete --stats -e \"ssh -p {0} -i {1}\" /home2 {2}@{3}:/".format(destPort, srcKeyPos, "root", destIP)
print(cmd)
try:
stdin, stdout, stderr = s.exec_command(cmd)
print(stdout)
print(stderr)
for line in iter(stdout.readline, ""):
print(line, end="")
for line in iter(stderr.readline, ""):
print(line, end="")
except Exception as e:
print(e)
s.close()
if __name__ == "__main__":
cloudToOp = ReadJson()
if CheckServer(server_info['OP_HOST']) :
if cloudToOp['Cloud_Rsync'] :
print("클라우드 -> 온프레미스 동기화 진행")
SSHConnect(server_info['CLOUD_HOST'], server_info['CLOUD_SSH'], server_info['CLOUD_KEY'], server_info['OP_HOST'], server_info['OP_SSH'])
cloudToOp['Cloud_Rsync'] = 0
WriteJson(cloudToOp)
print("asdasd", cloudToOp['Cloud_Rsync'])
else :
print("온프레미스 -> 클라우드 동기화")
SSHConnect(server_info['OP_HOST'], server_info['OP_SSH'], server_info['OP_KEY'], server_info['CLOUD_HOST'], server_info['CLOUD_SSH'])
else :
print("동기화 대기")
cloudToOp['Cloud_Rsync'] = 1
WriteJson(cloudToOp)
print("qweqweqwe", cloudToOp['Cloud_Rsync'])
{
"Cloud_Rsync": 0
}
python3 using_data.py
crontab 스케줄링으로 자동화구현
crontab -e
# 매익 새벽 5시
0 5 * * * /bin/python3 [using_data 파일 위치]
gpg -c [generate_cryptography.py 파일 위치]
rm -f generate_cryptography.py
chmod 600 ~/[상위 디렉토리]/*