나는 그동안 AWS 프리티어를 통해 프로젝트를 배포해왔다. 그러나 프리티어는 단 1년만 주어졌기에 현재는 프로젝트들이 전부 내려간 상태고, 대체제를 찾고자 오라클 서버, GCP 등을 고려해봤지만 가입과정의 오류, 결국 필연적인 과금의 위험성 등의 문제로 인해 최적의 선택지가 되어주진 못했다.
그러던중 친구가 '미니PC 같은걸로 홈서버를 만들어보는게 어때?' 라는 제안을 해왔고, 내가 만들었던 작은 프로젝트들을 올려두기에 딱 맞는 선택지라는 판단하에 실행에 옮기게 되었다.
무릇 백엔드 개발자라면 서버 하나쯤 있어야지!
서버 자원으로는 일반PC, 미니PC, 안드로이드 스마트폰 등 다양한 선택지가 존재한다. 나는 그중에서도 라즈베리파이를 선택했다! 아무래도 학부생 시절 임베디드 프로젝트등을 해왔다보니, 집에 놀고있는 센서들로 차후 스마트홈을 만들어도 좋을것같아서였다.
아무튼, 내가 사용한 라즈베리파이는 라즈베리파이5로, 8GB의 램을 가지고 있는 모델이다.
홈서버를 추천해준 친구가 케이스와 실링팬까지 추천해줘서 야무지게 달아놓은 상태다. 이덕분인지 현재까지 과열문제가 없었다.
OS 설치 및 공유기 연결
라즈베리파이는 우선 OS를 까는 초기설정이 필요하다. 이러한 셋팅은 검색하면 많이 오는 부분이니 본 포스팅에선 과감히 생략하겠다. OS를 깐 후, 랜선을 통해 집 공유기와 연결했다.
아 주로 접속하는 프로그램은 Putty대신 Terminus를 선택했다. 각 서버정보를 가독성 좋게 저장하는 프로그램이다. 터미널도 사용하기 훨씬 편했음! VNC를 활용해서 GUI로 조작할수도 있긴 하지만, 개발을 하다보니 리눅스 환경은 터미널이 더 익숙하게 느껴져서 Terminus만 사용하고 있다.
공유기 설정 및 포트포워딩
이제 본격적인 홈서버 구축 방법이다.
그냥 순서대로 따라해도 되는거긴 하지만, 이 순서를 왜 따라가야 하는지 조금 설명을 해보려고 한다.
우선 라즈베리파이는 집 공유기에서 랜선을 연결해 인터넷에 접근하고 있다. 사실 라즈베리 파이 외에도, 스마트폰, 스마트TV, 집 컴퓨터 등 다양한 기기들이 한 공유기에 연결되어있다. 그리고 '홈서버'를 만들기 위해선, 외부에서 이 공유기의 '라즈베리파이'로만 연결되도록 해야하는것이다.
이를 위해서 몇가지 네트워크 지식이 등장한다. 우선 ISP, 즉 집 공유기들은 한개의 IP를 가지고 있고, 내부의 전자기기들엔 동적으로 주소를 할당한다. 이 동적 주소들은 같은 공유기 안에서만 통용되는 주소로, 외부에선 접근할 수 없다.(내 컴퓨터의 ipconfig 결과값을 다른 컴퓨터로 접속 시도해봐야 할 수 없는 이유와 같다). 따라서 '라즈베리파이'라는 특정 경로만 열어주기 위해선, 해당 '동적 주소'에 대해서 포트를 열어줘야한다. 그렇게하면 외부에서 '공유기IP:특정포트'형식으로 접근했을때 그 포트로 들어갈 수 있다. 즉, 라즈베리파이 안으로 접근할 수 있다.
위 과정을 위해서 해야할 일이 다음과 같은것이다.
1. DHCP 고정할당
2. 라즈베리파이와 공유기간 포트포워딩(SSH접근, HTTPS접근 등을 받을 포트)
3. 라즈베리파이의 방화벽 허용
4. DNS 설정(필수X)
DHCP 고정할당
우선 공유기 설정창에 들어간다. (나는 iptime을 쓰고있다.)
네트워크 관리 => 내부 네트워크 설정에 PC, TV, 스마트폰 등 다양한 연결정보가 뜨는데, 그중에서도 라즈베리파이에 할당된 내부망 주소를 확인한다. 나는 192.168.0.17이었다. 즉, 이게 라즈베리파이의 주소다.
사실 내부망 주소는 계속해서 변화하는 동적 주소다. 그런데 포워딩을 하려면 라즈베리파이 주소가 바뀌면 곤란하다. 따라서 해당 내부망 주소를 고정해서 사용한다는 규칙을 설정해줘야 한다.
위와같이 DHCP 설정창에 들어가서, 방금 찾은 IP를 고정한다. 이제 라즈베리파이가 사용하는 IP가 고정되었으므로, 해당 IP로의 접근을 공유기에서 열어주면 된다.
라즈베리파이와 공유기간 포트 포워딩
외부에서 '공유기IP주소:특정포트'로 접근했을때 '라즈베리파이IP:특정포트' 로 연결해주려고 한다.
이를 위해 시도하는것이 포트포워딩이다. '특정포트' 요청에대해, 내부의 '특정 내부망IP'와 '특정 포트'로 요청을 토스해주는 역할을 한다.
우선 내가 열어두려는 라즈베리파이의 포트는 다음과 같다.
1. 22번 포트 - SSH 접근을 위해
2. 80번 포트 - HTTP 접근을 위해
3. 3306번 포트 - MySQL 접근을 위해
4. 443번 포트 - HTTPS 접근을 위해
주의할점은, 공유기에서 열어둘 외부포트는 위 포트번호와 달라야한다. Well-Known포트이기 때문에 이미 사용중일수도 있고, 또 해킹에 취약하기 때문이다.
NAT/라우터관리 -> 포트포워드 설정으로 진입해서, 다음과같이 규칙을 추가해줌으로써 포트포워딩을 완료한다.
라즈베리파이 방화벽 허용
이렇게 외부 요청에 대해 라즈베리파이로 요청을 토스할 수 있게 됐지만, 막상 라즈베리파이가 해당 포트를 막아버린다면 말짱 도루묵이다. 따라서 위에서 포워딩했던 22,80,3306 포트에 대해 방화벽을 열어줘야한다.
-- 방화벽 상태 확인
sudo ufw status
-- 특정 포트 열기
sudo ufw allow 포트번호/프로토콜
DDNS 설정
배포했을때, 사람들에게 IP주소를 치고 들어오게 할 순 없다. 나도 까먹을것이다.
따라서 https://steam-egg.tistory.com/ 과 같이 DNS를 설정해주면 좋다. 특히 차후 HTTPS구현을 위해 SSL 인증서를 받고자 할 경우, DNS는 필수적이다. 따라서 아래와 같이 DNS를 등록해줬다.
참고로 Iptime의 경우, 무료로 사용할 수 있는 DDNS를 제공한다. '호스트명'.iptime.org로 제공되며, 한달에 한번씩 갱신해야 한다고 한다. 다만 문제가 하나 있다면,,, iptime.org라는 도메인에 대해서는 SSL인증서 발급이 불가능하다^^;; 그래서 나는 현재 duckdns와 같은 무료 도메인 사이트에서 따로 사용하고있다.
(트러블 슈팅) 정상적으로 포트포워딩 했는데도 외부망에서 접속이 안되는 이슈
나는 위 과정을 통해서 제대로 된 포트포워딩을 했는데도 외부망에서 접근할 수 없었던 이슈가 있었다. nginx의 로그를 확인해보니 아예 라즈베리파이단으로 요청이 오지도 않는것이다. SSH 접근도 마찬가지로 외부망에서 접근이 불가능했다.
이를 해결하는데엔 두가지 시도가 있었다. 첫째는 공유기 펌웨어 업데이트였다. 업데이트 한지가 오래되어.. 현재 V15버전이 최신버전인데, 내 공유기는 V10버전이었다. 그래서 공유기 업데이트부터 진행!
두번째 시도는 포트번호 변경이었다. 분명 Well-Known포트를 피하고자 꽤나 높은 번호대의 포트를 설정해뒀는데, 버전과 맞물려 문제가 생겼던것같다. 포트번호를 더 높은 번호로 변경해줌으로써 해결 할 수 있었다.
만약 같은 오류를 겪는분들이 있다면, (1)포트포워딩 규칙에 번호가 적절한지 확인, (2)서버의 방화벽에서 해당포트가 열려있는지 확인, 그럼에도 안된다면 포트번호를 변경해보길 바란다.
이렇게 난생 첫 홈서버를 완성할 수 있었다! 현재는 Docker와 NginX를 통해서 빼곡 서비스와 트래블캐리어 서비스를 배포해두었다. 클라우드 서버를 사용할때완 달리 기간이나 과금에 대한 걱정이 없는것이 아주아주 큰 장점이다(전기세정도 들긴하는데, 크게 많이들지 않는다).
백엔드 개발자로서 서버하나쯤 있어야지! 하는 마음으로서 시작한 홈서버 구축이었지만, 이 과정으로 배운게 많아서 다른분들에게도 추천하고싶다. 우선 학부생시절 추상적으로만 접해 어려웠던 포트포워딩, 내부망과 외부망, DHCP개념을 손쉽게 체화했다. 또한 프로젝트 배포시 모든 서버설정을 직접 해줘야 하므로, 아주 기본적인 설정, 즉 HTTP요청을 HTTPS로 리다이렉트 하는것, SSL자동화, 보안 등 자연스럽게 공부하게 됐다. 리눅스와 친해지는건 덤 😎
앞으로도 큰 이변이 없다면 내 서버를 적극 활용할것같다!
'프로젝트 > 빼곡' 카테고리의 다른 글
Spring 명시적 Null값으로 부분 업데이트(PATCH) 구현하기 (3) | 2025.01.02 |
---|---|
여러기기에서 로그인, 다중 로그인 Spring에서 구현하기 (4) | 2024.12.20 |
다른 도메인 환경에서 쿠키 셋팅하기(Feat.samesite Cookie) (4) | 2024.12.12 |
Redis로 최근검색어 구현하기 (1) | 2024.11.25 |
서버이전을 고려한 Jenkins기반 아키텍처 개선(Feat. GithubActions) (3) | 2024.11.22 |