study

Ubuntu 홈 서버 구축 - 원격 접속 환경과 기본 보안 설정

렁치 2026. 6. 26. 18:18

오늘은 집에서 남는 노트북으로 운영할 ubuntu 서버의 기본 환경을 정리했다. 목표는 단순히 SSH 접속이 되는 서버를 만드는 것이 아니라, 외부에서도 비교적 안전하게 관리할 수 있는 개발 서버의 기반을 만드는 것이다.

 

앞으로 Docker, PostgreSQL, Nginx, GitHub Actions 등을 올릴 예정이라, 그 전에 운영체제 수준에서 필요한 기본 보안과 원격 관리 환경부터 먼저 구축하기로 했다.


목표

오늘의 목표는 다음과 같았다.

  • Cloudflare를 이용한 도메인 구성
  • Windows와 Ubuntu를 각각 서브도메인으로 분리
  • SSH 공개키 인증 적용
  • 비밀번호 로그인 차단
  • Root 로그인 차단
  • UFW 방화벽 구성
  • Fail2Ban 설치
  • 자동 보안 업데이트 설정

웹 서비스를 올리기 전에 OS 자체를 먼저 단단하게 만드는 과정이라고 보면 된다.


1. 서브도메인 구성

도메인은 이미 Cloudflare에서 관리하고 있었다.

이번에는 서버별로 관리하기 쉽게 서브도메인을 분리했다.
Windows 데스크탑에서도 RDP를 설정해서 외부에서 자주 사용하고 있었기에 이번에 같이 서브도메인 설정을 마쳤다.

win.example.com
ubuntu.example.com

 

둘 다 같은 공인 IP를 바라보도록 A 레코드를 추가했다.

여기서 중요한 점은 SSH나 RDP는 Cloudflare Proxy를 사용할 수 없기 때문에 반드시 DNS Only 로 설정해야 한다.


2. 포트포워딩

공유기에서는 이미 포트포워딩이 되어 있었지만 다시 한번 구조를 정리했다.

외부포트
      ↓
공유기
      ↓
Ubuntu 22번 SSH

 

Ubuntu 내부에서는 기본 SSH 포트인 22번을 그대로 유지하고, 외부에서만 다른 포트 번호를 사용하도록 구성했다.

 

Windows RDP 역시 동일한 방식으로 외부 포트를 변경해두었다.

외부 포트를 변경한다고 해서 보안이 크게 향상되는 것은 아니지만, 기본적인 스캔을 줄이는 효과는 있다.


3. SSH 공개키 인증

기존에는 비밀번호 로그인도 가능했지만 이번에는 공개키 인증 방식으로 변경했다.

 

Windows에서 먼저 키를 생성했다.
OpenSSH에서 권장하는 ed25519 알고리즘을 사용했다.

ssh-keygen -t ed25519

 

ed25519의 이름은 Edwards-curve Digital Signature Algorithm으로 공개키 암호 알고리즘 중 하나이다. RSA와 용도는 같지만 내부적으로 사용하는 수학적 알고리즘은 서로 다르다.

오래된 장비나 서버에서 ed25519를 지원하지 않는 경우 rsa 방식을 사용하면 된다.

 

ssh-keygen -t ed25519 -C "my-laptop"

 

위와 같이 my-laptop같은 코멘트를 붙일 수 있다. 해당 코멘트는 암호와는 상관없이 키를 구분하기 위한 메모이다.

생성되는 파일은 다음과 같다.

 

id_ed25519
id_ed25519.pub

 

여기서

  • id_ed25519 → 개인키
  • id_ed25519.pub → 공개키

이다.

개인키는 절대로 외부에 공개하면 안 된다.

 

공개키만 Ubuntu의

~/.ssh/authorized_keys

 

파일에 등록했다.

권한도 함께 수정했다.

 

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

설정 후 새 터미널에서 SSH 접속을 테스트해서 정상적으로 공개키 인증이 되는 것을 확인했다.


4. SSH 설정 변경

SSH 설정 파일은

/etc/ssh/sshd_config

이다.

 

이번에 변경한 핵심 옵션은 다음과 같다.

PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin no

PubkeyAuthentication

공개키 인증을 허용한다.

PasswordAuthentication

비밀번호 로그인 자체를 막는다.

공개키가 없으면 접속할 수 없다.

공개키 인증이 정상적으로 동작하는 것을 확인한 뒤에만 적용하는 것이 안전하다.

PermitRootLogin

root 계정의 직접 로그인을 차단한다.

관리 작업은 일반 사용자로 로그인한 뒤 sudo를 사용하는 것이 기본이다.


설정을 수정한 뒤에는 반드시 문법 검사를 했다.

 

sudo sshd -t

 

아무 출력도 없으면 정상이다.

그 후 SSH 서비스만 다시 시작했다.

 

sudo systemctl restart ssh

 

여기서 중요한 점은 SSH 서비스만 재시작되는 것이지 서버가 재부팅되는 것은 아니라는 것이다.

기존 SSH 세션은 유지되고 이후부터 새로운 설정이 적용된다.


5. UFW 방화벽

Ubuntu에는 UFW(Uncomplicated Firewall)라는 방화벽이 기본 제공된다.
UFW는 Ubuntu에서 iptables/nftables를 조금 더 쉽게 관리할 수 있도록 만든 방화벽 도구이다.

먼저 허용할 포트를 등록했다.

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

 

기본 정책은 다음과 같이 설정했다.

sudo ufw default deny incoming
sudo ufw default allow outgoing

 

의미는

  • 외부에서 들어오는 연결은 기본적으로 차단
  • 서버가 외부로 나가는 통신은 허용

이다.

설정 후 활성화했다.

 

sudo ufw enable

 

현재 허용된 포트는 다음 세 가지다.

 

22
80
443

 

웹 서버를 운영할 예정이라 HTTP와 HTTPS도 미리 열어두었다.


6. Fail2Ban

 

SSH를 외부에 공개하면 자동화된 봇이 root, admin, ubuntu 같은 계정으로 로그인 시도를 반복하는 경우가 많다.

Fail2Ban은 일정 횟수 이상 로그인에 실패한 IP를 자동으로 차단해주는 프로그램이다.

 

설치

sudo apt install fail2ban

 

동작 확인

sudo systemctl status fail2ban

 

현재 Jail 확인

sudo fail2ban-client status

 

SSH 상태 확인

sudo fail2ban-client status sshd

 

현재는 실패 시도도 없고 차단된 IP도 없는 상태였다.


7. 자동 보안 업데이트

 

보안 업데이트는 사람이 매일 확인하는 것보다 자동으로 관리하는 편이 훨씬 낫다고 생각했다.

 

설정

sudo dpkg-reconfigure -plow unattended-upgrades

 

설정 확인

cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

 

보안 업데이트가 자동으로 적용되도록 설정되었다.

자동 업데이트는 모든 패키지를 최신 버전으로 올리는 것이 아니라, 기본적으로 보안 업데이트 위주로 적용된다.

테스트는 다음 명령으로 했다.

 

sudo unattended-upgrade --dry-run --debug

 

실제 업데이트는 하지 않고 어떤 작업이 수행되는지만 확인할 수 있다.


UFW는 내부 포트를 기준으로 동작한다.

공유기에서

외부포트
↓
22

로 포트포워딩을 했다면,

UFW에서는 22번만 허용하면 된다. 즉, UFW는 공유기의 외부 포트가 아니라 Ubuntu가 실제로 수신하는 내부 포트를 기준으로 동작한다.

공유기가 외부 포트를 내부 포트로 변환한 뒤 Ubuntu에 전달하기 때문이다.


SSH 공개키 인증 구조

Windows

개인키
↓
SSH 연결
↓
Ubuntu

공개키

 

개인키와 공개키가 서로 맞는지 확인하는 방식이라 비밀번호를 서버에 전송하지 않는다.

SSH는 개인키 자체를 서버에 보내는 것이 아니라, 공개키와 개인키가 서로 짝이 맞는지만 검증하는 방식으로 인증을 수행한다.


현재 상태

오늘 기준 서버는 다음과 같은 상태가 되었다.

  • Cloudflare DNS 구성
  • SSH 공개키 인증
  • Root 로그인 차단
  • 비밀번호 로그인 차단
  • UFW 방화벽
  • Fail2Ban
  • 자동 보안 업데이트

오늘 작업으로 원격 접속 환경과 기본적인 보안 구성은 어느 정도 마무리된 것 같다. 이제부터는 이 기반 위에 Docker, PostgreSQL, Nginx 같은 개발 환경을 하나씩 올려보려고 한다.

조급하게 이것저것 설치하기보다는 왜 필요한지 이해하면서 하나씩 쌓아가는 방식으로 진행해볼 생각이다.

 

예전에는 SSH 접속만 되면 끝이라고 생각했는데, 실제로 하나씩 설정해보니 원격 접속 자체보다도 안전하게 접속할 수 있는 환경을 만드는 과정이 훨씬 중요하다는 것을 느꼈다.

특히 SSH 공개키 인증, UFW, Fail2Ban, 자동 보안 업데이트는 각각 따로 보면 단순한 설정처럼 보이지만, 함께 적용하니 하나의 보안 체계를 구성하는 느낌이었다.

 

앞으로 Docker와 PostgreSQL을 올리면서도 단순히 동작시키는 것에 그치지 않고, 왜 이런 설정이 필요한지 이해하면서 하나씩 기록해 나갈 생각이다.