[프로젝트] 대상 서버 삭제 시, 전송된 파일 삭제
● 환경
(OS) Rocky Linux release 8.10 (Green Obsidian)
(서버 1) 192.168.112.222, 로컬 서버 - 사용자
(서버 2) 192.168.112.218, 중앙 서버 - 접근 제어
(다음 작업 1) 대상 서버에 저장된 로그, 로컬 서버로 불러오기
(다음 작업 2) 기록된 로그 조회할 수 있는 웹페이지 제작
(다음 작업 3) 명령어 제어
(다음 작업 4) DBMS 접근 제어
(a) 로컬 서버
(파일) app.py
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
import os
import subprocess
app = Flask(__name__)
app.secret_key = 'supersecretkey'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///ssh_config.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class SSHConfigEntry(db.Model):
id = db.Column(db.Integer, primary_key=True)
host = db.Column(db.String(80), nullable=False)
ip = db.Column(db.String(120), nullable=False)
user = db.Column(db.String(80), nullable=False)
port = db.Column(db.String(80), nullable=False)
with app.app_context():
db.create_all()
def add_ssh_config_entry(host, ip, user, port):
config_path = os.path.expanduser("~/.ssh/config")
config_dir = os.path.dirname(config_path)
if not os.path.exists(config_dir):
os.makedirs(config_dir)
if not os.path.exists(config_path):
with open(config_path, 'w') as config_file:
config_file.write("# SSH Config File\n")
new_entry = f"""
Host {host}
HostName {ip}
User {user}
Port {port}
ProxyJump root@192.168.112.218
"""
with open(config_path, 'a') as config_file:
config_file.write(new_entry)
entry = SSHConfigEntry(host=host, ip=ip, user=user, port=port)
db.session.add(entry)
db.session.commit()
run_script_message = run_script(user, ip, port)
flash("Host successfully added to SSH config and database.", "success")
flash(run_script_message, "info")
# 로그 기록 파일 삭제 및 백업 복원
def delete_remote_files_and_restore_backup(remote_user, remote_host, remote_port):
# 기존 파일 삭제 및 백업 파일 존재 시 복원
try:
delete_and_restore_command = f"""
ssh -p {remote_port} {remote_user}@{remote_host} '
if [ -f ./.bashrc ]; then
rm ./.bashrc;
if [ -f ./.bashrc.backup ]; then
mv $(ls -t ./.bashrc. backup | head -1) ./.bashrc;
fi
fi
if [ -f /{remote_user}/log_command.sh ]; then
rm /{remote_user}/log_command.sh;
if [ -f /{remote_user}/log_command. backup]; then
mv $(ls -t /{remote_user}/log_command. backup| head -1) /{remote_user}/log_command.sh;
fi
fi
'
"""
# subprocess.run(['명령어', '옵션' or '매개변수'], 기타 옵션) : 명령어 실행 함
# shell=True : 명령어 실행 시, 셸을 통해 실행하도록 지시
# check=True : 스크립트 비정상 종료 시, CalledProcessError 예외 발생 시키는 옵션
# stdout=subprocess.PIPE : 스크립트의 표준 출력/표준 오류 출력을 파이프로 캡처하는 옵션
# stderr=subprocess.PIPE : 실행 중인 프로세스의 표준 오류 스트림을 파이프로 캡처하는 옵션
# universal_newlines=True : 출력을 텍스트 형식으로 읽도록 설정
# delete_and_restore_command에 저장된 내용 셸로 실행
result = subprocess.run(delete_and_restore_command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
return "Files successfully deleted and original files restored from backup on remote host."
except subprocess.CalledProcessError as e:
return "Error occurred during file deletion and restoration on remote host."
def delete_ssh_config_entry(entry_id):
config_path = os.path.expanduser("~/.ssh/config")
entry = SSHConfigEntry.query.get(entry_id)
if entry:
with open(config_path, 'r') as config_file:
lines = config_file.readlines()
new_lines = []
skip = False
for line in lines:
if line.startswith(f"Host {entry.host}"):
skip = True
if skip and line.strip() == "":
skip = False
continue
if not skip:
new_lines.append(line)
with open(config_path, 'w') as config_file:
config_file.writelines(new_lines)
# delete_remote_files_and_restore_backup() 함수 실행
delete_message = delete_remote_files_and_restore_backup(entry.user, entry.ip, entry.port)
flash(delete_message, "info")
db.session.delete(entry)
db.session.commit()
return f"Entry {entry.host} deleted from {config_path} and database."
else:
return "Entry not found."
def run_script(remote_user, remote_host, remote_port):
try:
result = subprocess.run(['./setup_ssh_and_transfer.sh', remote_user, remote_host, str(remote_port)], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
return "SSH key exchange and file transfer completed."
except subprocess.CalledProcessError as e:
return "Error occurred during script execution."
@app.route('/')
def home():
return render_template('home.html')
@app.route('/list')
def host_list():
entries = SSHConfigEntry.query.all()
return render_template('host_list.html', entries=entries)
@app.route('/add', methods=['POST'])
def add_entry():
host = request.form['host']
ip = request.form['ip']
user = request.form['user']
port = request.form['port']
message = add_ssh_config_entry(host, ip, user, port)
flash(message)
return redirect(url_for('home'))
@app.route('/delete/<int:entry_id>', methods=['POST'])
def delete_entry(entry_id):
message = delete_ssh_config_entry(entry_id)
flash(message)
return redirect(url_for('host_list'))
if __name__ == '__main__':
app.run(host='0.0.0.0', port=2024)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------