온프레미스와 클라우드 데이터 동기화 - 마스터 서버 자동화

Se0ng_1l·2024년 5월 17일
0

[마스터 서버]에서 자동 동기화 구현하기

자동으로 동기화가 될 수 있도록 시스템을 마련하자

  • 알고리즘
    • 기본 상태
      • [온프레미스]에서 [클라우드]로 동기화
    • [온프레미스] UP → Down
      • 동기화 멈춤
    • [온프레미스] Down → UP
      • [클라우드]에서 [온프레미스]로 1회 동기화
      • 기본 상태로 돌아감
  1. [마스터 서버]에서 [두 서버 모두]에 접속할 수 있는지 확인

  2. 아래 참고하여 서버 관련 암호화 파일 생성

    서버 정보 암호화(파이썬 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)

  1. 테스트

    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)

  1. using_data.py 파일 및 var.json 파일 생성
    • using_data.py
      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'])
      
    • var.json
      {
      	"Cloud_Rsync": 0
      }
  1. 실행 결과
    python3 using_data.py
  1. crontab 스케줄링으로 자동화구현

    crontab -e
    
    # 매익 새벽 5시
    
    0 5 * * * /bin/python3 [using_data 파일 위치]

  1. GPG 암호화 등 보안 설정
    gpg -c [generate_cryptography.py 파일 위치]
    
    rm -f generate_cryptography.py
    
    chmod 600 ~/[상위 디렉토리]/*
profile
치타가 되고 싶은 취준생

0개의 댓글