라즈베리파이 5를 활용한 저비용 웹 서버 구축하기(1)
요즘 클라우드 서비스가 대세라서 다들 AWS, GCP 같은 걸로 서버를 띄우는데, 2년간 계속 사용해오다보니 돈이 아깝기도 하고, 마침 운 좋게 라즈베리파이 5를 얻게 돼서 이걸 웹 서버로 활용해보려고 한다.
구축하고 나서 결론만 말하자면 정말 재밌었고 앞으로 뭘 만들어보든 매번 AWS 계정 만들고 환경 구축하는거 신경안써도 되고 너무 좋다.
1. SD 카드 대신 USB로 OS 설치하기
라즈베리파이를 쓰려면 SD 카드에 OS를 설치해야 하는데, 내 주변에 SD 카드를 쓸 수 있는 컴퓨터가 라즈베리파이밖에 없어서 우선 USB로 설치해보기로 했다.
준비물: 라즈베리파이 Imager
- 먼저, 라즈베리파이 공식 사이트에서 Raspberry Pi Imager를 다운받았다.
- USB에 우분투 Desktop OS를 설치하기로 결정. 이걸로 부팅한 다음, SD 카드에 서버 OS를 다시 설치하는 방식으로 진행한다.
설치 과정
- 라즈베리파이 Imager를 실행해서 'Choose OS'에서 Ubuntu Desktop 선택.
- USB에 설치한 다음, 라즈베리파이 5에 USB만 연결해서 부팅.
- 우분투 Desktop이 설치되고 나면, SD 카드를 꽂고 다시 라즈베리파이 Imager 실행.
- 이번엔 SD 카드에 Ubuntu Server OS를 설치.
- 설치 끝나면 USB 빼고 라즈베리파이 재부팅! 이제 서버 OS로 부팅된다.
2. 외부에서 접속할 수 있도록 SSH 설정하기
라즈베리파이를 모니터 없이 헤드리스로 사용할 거라서, 외부에서 SSH로 접속해야 한다.
1. SSH 설치 및 포트 변경
우분투 Server에는 기본적으로 openssh-server가 설치돼 있는데, 혹시 모르니 다시 설치해봤다.
sudo apt update
sudo apt install openssh-server
이제 SSH 서버가 잘 돌아가는지 확인.
sudo systemctl status ssh
여기서 상태가 'active'로 떠야 제대로 실행 중인 거다. 만약 실행 안 되고 있으면 아래 명령어로 시작하고 자동 실행도 설정.
sudo systemctl enable ssh
sudo systemctl start ssh
기본 포트(22번)는 공격 대상이 되기도 쉽고 ISP(인터넷 서비스 제공 업체) 차원에서 막아둔건지 접속이 안되서 2222번 포트로 바꿨다.
sudo nano /etc/ssh/sshd_config
파일에서 Port 22를 찾아 Port 2222로 수정한 다음 저장. 그리고 SSH 서버를 재시작.
sudo systemctl restart ssh
2. 방화벽 설정
포트를 바꿨으니까 방화벽 설정도 잊지 말아야 한다. ufw를 이용해서 2222번 포트를 열어줬다.
sudo ufw allow 2222/tcp
sudo ufw reload
sudo ufw status
3. 외부에서 라즈베리파이에 접속하기
이제 SSH 클라이언트에서 내 라즈베리파이에 접속해볼 차례다.
ssh -p 2222 username@공인_IP
공인 IP는 hostname -I 명령어로 확인할 수 있다. 근데 대부분 공유기를 쓰니까, 여기서 한 가지 더 해야 할 게 있다.
4. 라우터 포트 포워딩 설정(추가)
공유기를 사용 중이라면, 라우터 설정에 들어가서 포트 포워딩을 해줘야 외부에서 접근이 가능하다. 라우터마다 메뉴가 다르지만, 'Port Forwarding' 항목에서 2222번 포트를 내 라즈베리파이의 로컬 IP로 연결해주면 된다.
5. 보안을 위해 SSH 키 인증 설정하기(선택)
비밀번호로만 접속하는 건 보안에 취약하니까 SSH 키 인증 방식으로 바꿔보자.
라즈베리파이가 아닌 내 컴퓨터에서 SSH 키를 생성했다.
ssh-keygen -t rsa -b 4096
위 명령어를 실행하면 SSH 공개키와 개인키를 생성하는 과정에서 여러 가지 출력 메시지가 나온다. 이 명령어는 RSA 방식의 4096비트 길이의 키 쌍을 생성해주는 역할을 한다.
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
이 메시지가 나오면, 생성된 키 파일을 저장할 위치를 입력하라는 의미인데 그냥 Enter를 누르면 괄호안의 기본 위치에 저장된다.
Enter passphrase (empty for no passphrase):
그 다음에 패스프레이즈(passphrase)를 입력하라는 메시지가 나오는데, SSH 키에 추가적인 암호를 설정할 수 있다. 개인키가 털렸을때도 보안을 지키기 위해 설정해주자!
Enter same passphrase again:
패스프레이즈를 입력했다면, 같은 값을 다시 입력하라는 메시지가 나오고 두 번 일치해야 설정이 완료된다.
Your identification has been saved in /home/username/.ssh/id_rsa
Your public key has been saved in /home/username/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX username@hostname
The key's randomart image is:
+---[RSA 4096]----+
| .o=.o= |
| + +o o |
| . = .oo.. |
| + o= o |
| . . S o.. |
| . . +. |
| . E |
| . |
| |
+----[SHA256]-----+
완료되었다는 출력이다. 궁금해서 찾아봤는데 아래 image는 사실 전혀 의미 없는 이미지라고 한다.
생성된 파일은 개인키: ~/.ssh/id_rsa, 공개키: ~/.ssh/id_rsa.pub 이렇게 두 개이다.
공개키를 서버의 ~/.ssh/authorized_keys 파일에 추가하자
생성된 공개키를 라즈베리파이 서버에 복사해준다.
ssh-copy-id -p 2222 username@공인_IP
이제 생성한 SSH 키를 사용해서 서버에 접속할 수 있다.
ssh -i ~/.ssh/id_rsa -p 2222 username@공인_IP
- i 옵션은 사용할 개인키 경로를 지정
- p옵션은 포트 번호 지정
3. 데이터베이스 생성 및 외부 접속 허용
1. MariaDB 설치
우분투에서 최신 버전의 MariaDB를 설치한다.
sudo apt update
sudo apt install mariadb-server
MariaDB 서비스 시작 및 확인
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo systemctl status mariadb
2. MariaDB 초기 설정 (보안 설정)
sudo mysql_secure_installation
- 비밀번호 설정: 'y'를 눌러 루트 사용자 비밀번호를 설정
- 기본 보안 설정:
- 익명 사용자 제거 y
- 원격 루트 로그인 비활성화 n
- 테스트 데이터베이스 제거 y
- 권한 테이블 새로 고침 y
3. MariaDB 외부 접근 허용 설정
MariaDB 설정 파일을 열어 외부 접근을 허용한다.
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
아래 항목을 찾아서 수정
bind-address = 0.0.0.0
MariaDB 서비스 재시작
sudo systemctl restart mariadb
4. MariaDB 사용자 계정에 외부 접근 권한 부여
MariaDB에 접속
sudo mysql -u root -p
모든 IP에서 접근 가능한 사용자를 생성하고 권한을 부여합니다.
CREATE USER '사용자이름'@'%' IDENTIFIED BY '비밀번호';
GRANT ALL PRIVILEGES ON *.* TO '사용자이름'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
계정 설정 확인
SELECT user, host FROM mysql.user;
5. 방화벽(UFW)에서 3306 포트 열기
우분투 서버에서 UFW를 사용하여 3306 포트를 외부에 허용합니다.
sudo ufw allow 3306/tcp
sudo ufw reload
sudo ufw status
6. 라우터에서 포트 포워딩 설정
SSH와 마찬가지로 라우터 페이지로 접속해서 포트 포워딩을 설정해준다.
라우터 접속 방법은 로컬 라우터 주소를 검색하면 되는데 우리집은 192.168.168.1 이었다.
7. 외부에서 MariaDB 접속 테스트
외부 컴퓨터에서 MariaDB 클라이언트를 사용하여 접속해보자
mysql -h 공인_IP -P 3306 -u 사용자이름 -p
4. Nginx, SpringBoot, HTTPS 적용
1. Nginx 설정: Spring Boot 리버스 프록시 구성 및 HTTPS 자동 리다이렉션
1.1 Nginx 사이트 설정 파일 생성
sudo nano /etc/nginx/sites-available/myapp
설정 파일 내용:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# HTTP에서 HTTPS로 리다이렉트
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Spring Boot 애플리케이션으로 리버스 프록시 설정
location / {
proxy_pass <http://localhost:8080>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
1.2 심볼릭 링크 생성 및 Nginx 재시작
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
2. Let's Encrypt SSL 인증서 발급 및 자동 갱신 설정
2.1 certbot 설치 및 SSL 인증서 발급
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
2.2 인증서 자동 갱신 확인
sudo certbot renew --dry-run
2.3 Crontab을 이용한 인증서 자동 갱신 설정
sudo crontab -e
Crontab에 추가:
0 3 * * * /usr/bin/certbot renew --quiet && sudo systemctl reload nginx
3. Spring Boot 애플리케이션 설정 및 서비스 등록
3.1 application.yml에서 HTTPS 포트 설정
server:
port: 8080
3.2 myapp.service 파일 생성
sudo nano /etc/systemd/system/myapp.service
서비스 파일 내용:
[Unit]
Description=Spring Boot Application
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/usr/bin/java -jar /home/ubuntu/myapp/app.jar
Restart=always
[Install]
WantedBy=multi-user.target
3.3 서비스 등록 및 시작
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp