리눅스로 배우는 30일 로드맵, 실패와 복구의 실전기

리눅스 스터디 아이콘
커서는 깜빡이고, 나는 멈춥니다. 엔터 한 번, 숨 한 번. 실패할지도 모른다는 두려움이 목을 타고 내려오는데, 이상하게도 그게 좋았습니다. 리눅스는 늘 솔직했습니다. 잘못을 숨겨주지 않았고, 대신 다시 일어나는 방법을 가르쳤습니다. 이 글은 30일 동안 내가 몸으로 부딪히며 만든, 아주 개인적인 로드맵입니다. 감정이 섞였고, 문장이 조금 비뚤고, 그래도 손에 남는 것들만 남겼습니다.

0일차 — 시작의 자세: 왜 지금, 왜 리눅스인가

통제와 자유. 두 단어가 싸웁니다. 리눅스는 그 사이를 묶습니다. 규칙은 단단하고, 수정은 열려 있습니다. 내가 바꾸면 바뀌는 세계. 그래서 시작했습니다. 그리고, 기록하기로 했습니다. 잊지 않기 위해, 스스로를 설득하기 위해.

1~3일차 — 안전한 모래밭에서 넘어지기: VM·WSL·클라우드

  • 가상머신(VM): 스냅샷이 구원입니다. 망치면 되돌립니다.
  • WSL: 윈도우에서 가볍게. 파일 경로만 주의.
  • 클라우드: 원격이 편하지만 과금과 키 관리를 배워야 합니다.

나는 VM으로 시작했습니다. 실패를 많이 할 생각이었거든요. Ubuntu LTSDebian Stable, Rocky Linux 정도면 충분합니다.

첫 업데이트와 사용자

# Debian/Ubuntu
sudo apt update && sudo apt -y upgrade
sudo adduser dev
sudo usermod -aG sudo dev

# RHEL/Rocky
sudo dnf -y update
sudo adduser dev
sudo usermod -aG wheel dev

# 시간대
sudo timedatectl set-timezone Asia/Seoul
  

지금 필요한 건 화려함이 아니라 안정. 기본을 정갈하게 밟아둡니다.

4~7일차 — 쉘과 파일, 손에 익히는 질서

터미널은 무심합니다. 그래서 더 믿게 됩니다. 길을 잃으면 pwd, 주변은 ls -al, 다음 한 걸음은 cd. 파일은 손때 묻어야 내 것이 됩니다.

# 작은 루틴
mkdir -p ~/projects/notes
echo "hello" > ~/projects/notes/day1.txt
grep -R "hello" ~/projects | wc -l

# 위험한 명령 앞에서는 두 번 읽기
rm -rf /tmp/safe   # 엔터 전, 심호흡
  

권한은 관계의 언어입니다. 사용자/그룹/모든 사람, r w x. 심플하지만 세다.

ls -l
chmod 640 plan.md
chmod +x deploy.sh
sudo chown dev:dev *.log
  

개념이 헷갈리면 문서를 봅니다. GNU coreutils는 사전처럼 든든합니다.

8~10일차 — 패키지와 서비스: 세계와 연결되는 방법

# 설치/삭제/업데이트 감각 익히기
sudo apt install curl git nginx  # 또는 dnf/pacman

# 서비스의 생명선: systemd
sudo systemctl status nginx
sudo systemctl enable --now nginx
sudo systemctl restart nginx
  

서비스가 멈추면 사람이 멈춥니다. 급할수록 로그를 천천히 읽습니다.

journalctl -u nginx --since "1 hour ago"
tail -n 200 /var/log/nginx/error.log
  

11~13일차 — 네트워크: 보이지 않는 길 만들기

# IP/포트/라우팅의 감각
ip a
ss -tulpen | head

# 방화벽 (택1)
sudo ufw allow 22,80,443/tcp && sudo ufw enable
# or
sudo firewall-cmd --add-service={ssh,http,https} --permanent && sudo firewall-cmd --reload
  

막히면 DNS를 의심합니다. dig, ping은 의외로 큰 힌트를 줍니다. 깊이 파고들고 싶다면 ArchWiki 네트워킹을 추천합니다. 느리지만 탄탄하게.

14~16일차 — SSH: 비밀번호를 놓는 연습

# 키 생성/배포
ssh-keygen -t ed25519 -C "dev@linuxstudy"
ssh-copy-id dev@server.example.com

# 하드닝 (예시)
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

# 재시작
sudo systemctl restart sshd  # (Ubuntu는 ssh)
  

설정이 낯설면 해설을 펼쳐둡니다: sshd_config 가이드. 불안이 줄어듭니다. 손이 덜 떨립니다.

17~19일차 — 자동화: 반복을 기계에게

# ~/bin/backup.sh
#!/usr/bin/env bash
set -euo pipefail
SRC="$HOME/projects"
DST="/backup/$(date +%F)"
mkdir -p "$DST"
rsync -av --delete "$SRC/" "$DST/"
echo "backup done: $DST"

# 크론
crontab -e
0 3 * * * /home/dev/bin/backup.sh > /var/log/backup.log 2>&1
  

자동화는 게으름이 아니라 지속성입니다. 로그는 보험. 실패가 나를 그냥 지나치지 못하게 합니다.

20~22일차 — 컨테이너: 깨끗이 만들고, 깨끗이 지우기

# docker-compose.yml (예시)
version: "3.9"
services:
  web:
    image: nginx:stable
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
  

설치는 공식 문서를 따라갑니다. Docker Install. 의심이 들면 한 줄씩 다시 읽습니다.

23~24일차 — 관측: 느낌 말고 증거

# 최근 이벤트만 좁혀서 보기
journalctl -p warning --since "2 hours ago"

# 로그 로테이션 감각 익히기
sudo logrotate -d /etc/logrotate.conf
  

문제는 대부분 조짐이 있습니다. 경고 한 줄, 지연 몇 초. 기록을 믿으면 마음이 덜 흔들립니다.

25일차 — 보안 기본기: 문단속의 미학

  • SSH 키 기반, 루트 로그인 금지.
  • 필요 포트만 열기. 기본 거부.
  • 정기 업데이트·점검은 달력에 고정.
  • 권한 최소화. sudo 이력 수시 확인.
  • 알림을 너무 늦게 받지 않도록 간단한 훅이라도.

화려한 도구보다 습관이 오래 갑니다. 그리고 습관이 시스템을 지킵니다.

26일차 — 사고 1: “No space left on device”

새벽 알림. 서비스 다운. 멘탈도 다운. 범인은 로그 폭주.

du -sh /var/log/* | sort -hr | head
# /etc/logrotate.d/nginx (예시)
 /var/log/nginx/*.log {
   daily
   rotate 14
   compress
   missingok
   notifempty
 }
  

그날 이후, 디스크 임계치 알림을 달았습니다. 같은 실수는 반복하지 않기로.

27일차 — 사고 2: 방화벽 자해

규칙을 한 줄 잘못 넣어 원격 접속이 끊겼습니다. 콘솔로 복구. 배운 것: 규칙은 주석·백업·단계적 적용.

# ufw 예시
sudo ufw allow 22/tcp
sudo ufw status numbered
sudo ufw delete 3   # 땜질보다 기록이 우선
  

28일차 — 사고 3: SSH 무차별 대입

로그인이 비밀번호 기반으로 열려 있었습니다. CPU가 비명을 질렀습니다. 그날, 나는 완전히 배웠습니다.

# fail2ban 도입 (예시)
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
  

그리고 키 기반, 포트 제한, 알림까지. 이후로는 조용합니다. 마음도요.

29일차 — 작은 배포, 작은 자신감

# systemd 유닛 예시 (/etc/systemd/system/myblog.service)
[Unit]
Description=My Blog
After=network.target

[Service]
User=dev
WorkingDirectory=/home/dev/myblog
ExecStart=/usr/bin/python3 app.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

# 적용
sudo systemctl daemon-reload
sudo systemctl enable --now myblog
  

“항상 돌기”의 감각을 배웠습니다. 재시작 정책 하나가 밤을 지켜줍니다.

30일차 — 회고: 나는 왜 덜 불안해졌을까

아마도, 실패를 기록했기 때문입니다. 망했다는 문장 뒤에 어떻게를 붙였기 때문입니다. 그리고 나의 템포를 리눅스에 맞췄기 때문입니다. 서두르지 않고, 한 줄씩 읽고, 한 단계씩 고쳤습니다.


체크리스트 — 새 서버를 맡았을 때

  • 사용자·키 배포, 루트 로그인 금지
  • 패키지 업데이트, 자동 보안 패치 확인
  • 필요 포트만 오픈, 방화벽 규칙 문서화
  • 로그 경로·로테이션 정책 점검
  • 백업 스크립트·복구 테스트 완료
  • 모니터링·알림 연결(디스크/CPU/메모리/포트)
  • 운영 문서 저장소와 접근 권한 정리

학습 길잡이 — 공식·오래가는 문서 위주

빠르게 늘어가려면 공식 문서가 뼈대여야 합니다. 아래 링크는 내가 실제로 곁에 두고 본 자료들입니다.

마침 — 다시 깜빡이는 커서 앞에서

나는 여전히 겁이 납니다. 하지만 이제 압니다. 겁이 난다는 건 내가 배울 준비가 됐다는 뜻. 오늘도 커서는 깜빡이고, 나는 한 줄씩 앞으로 갑니다. 넘어져도, 다시. 이게 리눅스였고, 이게 나였습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤