Linux 명령어 사용능력 검증 환경 개발

KKongten·2025년 7월 1일

Dev

목록 보기
1/1


I am not a developer.

그럼에도, 이 환경을 만든 이유는 신입사원 채용에 필요하다고 판단했다.

인프라 취약점 점검을 하기 위해서는 Shell/Batch 스크립트를 만들거나, 명령어를 입력하여 결과를 얻고 점검을 해야 하는데
명령어를 모른다면 이 모든것은 의미가 없다고 생각했다.

그래서, 신입사원을 채용할 때 Unix/Linux 에 대한 명령어 사용 능력이 어느정도인지 검증을 하고 싶었다.


Warning

신입사원 채용 과정에서 면접 시 명령어 사용 능력에 대한 검증을 하기 위해서는 여러 제약사항이 있었다.

  • 사용한 명령어는 단일이 아닌 다중 OS에서도 사용이 가능해야 함
  • 지원자의 정보와 함께 사용한 명령어와 결과를 확인할 수 있어야 하는 것
  • 이게 WebShell 이라고 볼 수 있기 때문에 시스템에 영향을 줄 수 있는 특정 명령어에 대해서는 사용을 금지 해야 하는 것

Function

환경을 만들기 위해서, 필요한 기능들을 생각해보았다.

  • 명령어 검증 환경은 Flask를 통한 웹 환경을 이용할 것
  • 코딩테스트처럼 다양한 Test Case(다양한 OS) 가 필요함
  • 최소 5개 이상의 문제를 제공하여, 명령어 사용 능력에 대한 검증이 되어야 할 것
  • 테스트 시간을 정확하게 측정하기 위한 기능이 필요할 것
    • 불가피하게 시스템 재부팅, 브라우저 재시작 등의 사유로 시험이 중단되었을 경우 잔여시간 동안 재시험을 치를 수 있게 할 것
    • 테스트 시간을 초과하여 응시할 수 없도록 제한할 것
  • 테스트는 1회 만 가능하며, 시험이 종료된 후 재시험을 볼 수 없게 할 것
  • 지원자에 대한 정보를 기록하기 위한 DB를 구축할 것
  • 이전 문제를 재확인하고, 다시 풀 수 있도록 되돌아가기 기능을 구현 할 것
  • 다른문제 선택 시, 지원자가 사용한 명령어가 저장되어 있을 것

Execute Structure

  1. 지원자는 웹페이지에서 주어진 문제에 대해 명령어를 입력하고 실행 버튼을 누른다.

  2. 실행 버튼을 누르면, 입력한 명령어를 하나의 쉘 스크립트 파일로 만들어서, OS Container 내부로 전송한다

  3. OS Container 내부에서는 전달받은 스크립트 파일에 실행권한을 붙여 실행한다

  4. 실행 결과를 텍스트 파일(.txt) 로 Redirect 하여, Host로 파일을 전송한다.

  5. Host는 전달받은 .txt 파일을 Flask 웹 화면 결과창에 표시하여 사용한 명령어에 대한 결과를 보여준다.


Project Structure

project/static : 각 문제에 대한 명령어 결과를 캡쳐해놓고 문제화면에서 보여줄 수 있도록 하기 위함
project/templates/home.html : 지원자의 이름, 전화번호 등을 작성하기 위한 페이지
project/templates/test.html : 문제가 나오는 페이지
project/templates/complete.html : 시험이 종료되었을 때 안내하는 페이지
Dockerfile : Docker Build를 통해 환경 구축하기 위한 파일
app.py : Main Python File


Dockerfile

FROM python:3.8-slim

# Flask 설치
RUN pip3 install flask
RUN pip3 install pymysql
# 작업 디렉터리 설정
WORKDIR /app

# Flask 앱 파일 복사
COPY . .

# Flask 실행: 외부에서 접속할 수 있도록 0.0.0.0으로 바인딩
CMD ["python3", "app.py", "--host=0.0.0.0", "--port=5000"]

grade.sh

  • grade.sh 는 Container 내부에서 사용되는 파일로,
  • 전달받은 스크립트 파일에 실행권한을 부여 및 실행하여 결과를 txt 파일로 Redirection 하는 목적
#!/bin/bash

SCRIPT="$1"             # user_script.sh 파일
echo $SCRIPT
os_type=$(hostname)     # 컨테이너의 호스트 이름
question_id=`echo $SCRIPT | awk -F_ '{print $5}'`
volunteer_id=`echo $SCRIPT | awk -F_ '{print $6}'`
phone_number=`echo $SCRIPT | awk -F_ '{print $7}' | awk -F. '{print $1}'`

chmod +x "$SCRIPT"

if [ `cat $SCRIPT | egrep ">|>>" | wc -l` -eq 0 ]
then
    RESULT_FILE="/shell_test/result_${os_type}_$question_id"_"$volunteer_id"_"$phone_number.txt"
    bash "$SCRIPT" > "$RESULT_FILE" 2>&1
else
    OUTPUT=bash "$SCRIPT"
fi

echo "Execution complete. Result saved to $RESULT_FILE"

app.py

containers = ["2143np9v8s9g", "2jv9sdjf5812"] # OS Container ID List 
def get_dbms_containerid():
	# DB는 MySQL Container 를 쓰므로Container ID 값 가져오기 위한 용도
	~~~

def get_db_connection():
	# DB 연결 
	~~~

@app.route("/", methods=["GET", "POST"])
def home():
	# 지원자 이름, 핸드폰 번호 입력 화면
	~~~

@app.route("/user_check", methods=["POST"])
def user_check():
	# 지원자 정보를 입력 후 시험시작 버튼을 눌렀을 때 올바른 지원자인지 확인하기 위함
	~~~

@app.route("/test", methods=["GET"])    
def test():
	# 올바른 지원자 이며, 시험 기록이 없는 경우 /test로 이동
	~~~

@app.route("/run_code", methods=["POST"])
def run_code():
	# 문제 화면에서 명령어 입력 후 "실행" 버튼을 눌렀을 때 작동되는 함수
	~~~

@app.route("/save_and_next", methods=["POST"])
def save_and_next():
	# 문제 화면에서 "다음 문제로 이동" 버튼을 눌렀을 때 작동되는 함수
    # 현재 입력까지 저장 후, 다음 문제로 이동    
	~~~

@app.route("/load_question", methods=["GET"])
def load_question():
	# 이미 완료되었거나, 넘어간 문제로 되돌아가기 위한 함수
	~~~

@app.route("/complete", methods=["GET"])
def complete():
	# 모든 문제 해결 혹은 일부 문제 해결 후 "제출" 버튼을 눌렀을 때 작동되는 함수
	~~~
    
@app.route("/save_and_complete", methods=["POST"])
def save_and_complete():
	# 모든 문제를 해결하면 마지막 문제에서 "다음 문제로 이동" 버튼을 눌렀을 때 
    # 다음 문제가 없으면 /save_and_complete 함수를 실행
    # "모든 문제가 완료되었습니다. 제출하시겠습니까?" 라는 표시창 출력 하기 위함
    # "예" 선택시 제출 / "아니오" 선택시 원하는 문제로 이동 가능 
	~~~

DB Data


Test Page


Notion 링크

Notion : 링크 업데이트 예정


profile
취미로 개발을 하는 보안컨설턴트

0개의 댓글