홈 서버 구축하기

Moseoh·2022년 3월 22일
0

메모

목록 보기
2/3
post-thumbnail

우분투 설정


우분투 다운로드

https://ubuntu.com/download/server

Option 2 - Manual server installation
Download Ubuntu Server 20.04.4 LTS

부팅 USB 만들기

https://rufus.ie/ko/

우분투 설치

부팅 USB를 이용하여 우분투 설치.
아래에 훨씬 더 잘 정리되어 있습니다.

https://velog.io/@chch1213/build-home-server-2

부팅시 인터넷 연결 해제

sudo vi /etc/netplan/00-installer-config.yaml
network:
	ethernets:
    	eno1:
        	dhcp4: true
            optional: true
    version: 2
sudo netplan apply
sudo reboot now

Wi-Fi 설정

Intel Nuc Kit이 와이파이를 지원하여 무선으로 설정합니다.

# 무선랜 인터페이스 확인
# 결과: interface ${name}
iw dev

# 무선랜 활성화
sudo ip link set ${name} up

# 공유기 이름과 비밀번호로 설정 파일 만들기
sudo wpa_passphrase ${essid} ${pwd} > /etc/wpa_supplicant/wpa_supplicant.conf

# Wi-Fi 연결
sudo wpa_supplicant -B -i ${name} -c /etc/wpa_supplicant/wpa_supplicant.conf

# 연결 정보 확인
sudo iw ${name} link
# 연결 확인
ping 8.8.8.8
# DHCP 주소 할당
sudo dhclient ${name}

다운로드 서버 변경

서버 리스트

sudo vi /etc/apt/sources.list

:%s/archive.ubuntu.com/mirror.kakao.com

SSH 설정


sudo apt update
sudo apt install openssh-server -y

설치 이후 ifconfig 를 통해 ip를 확인하여 putty, iterm2 등으로 연결한다.

홈서버 IP 고정

아래 링크 참조
https://velog.io/@chch1213/build-home-server-3

sudo apt update && sudo apt upgrade -y

Root 계정 비밀번호 생성

sudo passwd

SSH 계정 제한

사용자 계정 외 다른 계정으로 SSH 접속을 하지 못하도록 설정

sudo vi /etc/ssh/sshd_config

아래 내용에 계정명을 넣어 제일 아래 줄에 입력

AllowUsers ${계정명}

재시작

sudo service sshd restart

방화벽


iptables라는 리눅스 기본으로 제공, 방화벽을 설정해주는 도구.

sudo iptables -L

정책 종류

  • INPUT 서버를 목적지로 하여 들어오는 모든 패킷은 이 체인을 거침
  • OUTPUT 서버에서 만들어진 모든 패킷은 이 체인을 거쳐서 다른 곳으로 가게 됨
  • FORWARD 이 체인은 INPUT 체인을 통해 들어온 패킷 중 목적지가 서버가 아닌 패킷이 거친 후 다른 곳으로 가게 되는 체인임

초기화

sudo iptables -F
sudo iptables -X 
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

iptables 옵션

  • -F 체인들의 모든 규칙을 삭제
  • -X 규칙이 없는 모든 체인 삭제
  • -P 해당 체인의 기본 정책을 설정

설정

  1. 로컬에서 로컬로(Loopback)의 모든 접속은 허용한다.
  2. 22번 포트(SSH)로 들어오는 것을 허용한다.
  3. 패키지 업데이트에 관한 패킷들을 허용한다.
    새로운 연결 요청이지만, 기존의 연결과 관련된 패킷(RELATED)과 새로운 연결 요청에 관한 그후의 패킷(ESTABLISHED)을 허용하는 것인데 그냥 패키지 업데이트를 허용하는 것이라 생각하면 된다.
  4. 위에서 허용하지 않는 모든 패킷은 DROP(폐기) 처리 한다.
  5. 서버를 거쳐 다른곳으로 가는 모든 패킷도 DROP(폐기) 처리 한다.
sudo iptables -A INPUT -s 127.0.0.1 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT 
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP

# 확인
sudo iptables -L

규칙 제거

sudo iptables -D INPUT [규칙 위치]

INPUT 체인명인데 다른 체인들은 다루지 않고 항상 INPUT 만 설정할 것입니다.
[규칙 위치] 제거하고자 하는 규칙이 몇 번째 줄에 있는지 입력해주시면 됩니다.

만약 잘못된 정보가 입력되었으면 초기화 명령어를 입력한 후 다시 설정해도 되지만 잘 설정된 것들도 다시 입력해야하는 불편함이 생기니 규칙 제거 명령어도 알아두는 것이 좋습니다.

저장

sudo apt install iptables-persistent

아래 명령어는 방화벽 관리 패키지를 이용해 설정을 저장하고 적용하는 명령어 입니다.
항상 방화벽 설정을 하고난 뒤에 저장 및 갱신해주는 습관을 들여야 합니다.

sudo netfilter-persistent save
sudo netfilter-persistent reload

침입 차단


fail2ban은 비밀번호를 무작위로 대입해서 로그인을 시도하는 것을 막아준다.

설치

sudo apt install fail2ban

# 체인 생성 확인
sudo iptables -L

설치해도 체인이 생기지 않았다.

fail2ban 새 버전에서는 첫 차단이 일어날 때 chain을 형성한다고 함.

# 실행 확인
sudo fail2ban-client status sshd

# 인위적으로 ip 차단
sudo fail2ban-client -vvv set sshd banip 192.0.2.0

# chain 확인
sudo iptables -L

# 차단 해제
sudo fail2ban-client -vvv set sshd unbanip 192.0.2.0

참조:
https://blog.dapucita.kr/46

/etc/fail2ban/jail.local 파일 작성 (생성)

[DEFAULT]
# 차단하지 않을 IP
ignoreip=192.168.0.0/24
# 24시간 차단
bantime=86400
# 5회 실패시 차단
maxretry=5
# 24시간 동안
findtime=86400

# 메일 수신자, 다중 X
destemail=azqazq195@gmail.com
# 메일 보낸 사람
sender=fail2ban@moeseh.com
# 메일 전송 프로그램
mta=sendmail
# 차단시 whois 정보와 관련 로그를 첨부하여 메일 전송
action=%(action_mwl)s

[sshd]
enabled=true
port=22
filter=sshd
logpath=/var/log/auth.log

apt install whois whois 패키지 설치하기

적용

# 적용
sudo service fail2ban restart

# 확인
sudo fail2ban-client status sshd

차단 풀기

본인의 홈서버인데 비밀번호를 잘못 쳐서 fail2ban 이 차단해버린다면 당황할 것입니다.
아래 명령어로 차단을 풀 수 있습니다.

sudo fail2ban-client set sshd unbanip [ip]
[ip] 는 본인이 접속을 시도한 PC의 외부 IP 를 입력하시면 됩니다.

OTP 인증

설치


Google Authenticator 및 App 설치

sudo apt install libpam-google-authenticator

SSH 설정

sudo vim /etc/pam.d/sshd

제일 하단에 다음 문자열을 추가 하시면 됩니다.

auth required pam_google_authenticator.so nullok

nullok 는 한 사용자만 Google Authenticator 인증을 사용하게 하는 것이므로 SSH로 접속할 수 있는 계정이 다수일 경우 이 옵션을 지우시면 됩니다.

sudo vim /etc/ssh/sshd_config

Vim 찾기 명령

명령 모드 에서 /[찾을내용] 을 입력하면 해당 문자열이 있는 라인으로 이동하게 됩니다.

위 방법을 통해 아래 내용을 수정해주세요.
또한 제일 앞에 # 이 있을 경우 주석 처리이니 삭제 해주도록 하세요.

PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes
PermitEmptyPassword no

이제 SSH 서비시에 변경 사항을 적용합시다.

sudo service sshd restart

otp 생성

google-authenticator -t -d  --label webserver --issuer example.com -r 3 -R 30 -s ~/.ssh/google_authenticator

인증서 발급


인증서 발급 전 방화벽 설정

# 추가
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 저장
sudo netfilter-persistent save
sudo netfilter-persistent reload
sudo vim /etc/nginx/sites-available/moseoh.xyz

server {
        listen 80 default_server;
        server_name moseoh.xyz;

        root /var/www/html;
        index index.html index.nginx-debian.html;

        location / {
                try_files $uri $uri/ =404;
        }
}
cd /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/moseoh.xyz
sudo rm default
sudo nginx -t
sudo service nginx restart
sudo apt install python3-certbot-nginx -y
# -d 가장 앞에 있는 도메인으로 name이 설정된다.
sudo certbot certonly --nginx --non-interactive --agree-tos -m azqazq195@gmail.com --cert-name moseoh.xyz -d www.moseoh.xyz -d api.moseoh.xyz -d portainer.moseoh.xyz -d jenkins.moseoh.xyz

Certbot을 이용해 발급받았기 때문에 자동 갱신

# 확인
cat /etc/cron.d/certbot

DH Param 키 생성

Diffie–Hellman 키를 추가해서 사이트의 보안을 강화할 것입니다.

sudo openssl dhparam -out /etc/ssl/dhparam.pem 4096

끝났다면 아래 코드로 파일이 있는지 확인해봅시다.

ls -l /etc/ssl/dhparam.pem

한 줄이 나온다면 잘 생성 된 것입니다.

Nginx 인증서 적용

아래 내용을 자신의 [도메인] 에 맞게 수정 후 작성합시다.

sudo vim /etc/nginx/sites-available/moseoh.xyz
server {
        listen 80 default_server;
        server_name moseoh.xyz;
        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl http2 default_server;
        server_name moseoh.xyz;
        root /var/www/html;

        ssl_certificate /etc/letsencrypt/live/moseoh.xyz/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/moseoh.xyz/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/moseoh.xyz/chain.pem;
        ssl_dhparam /etc/ssl/dhparam.pem;
        ssl_session_timeout 10m;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_ecdh_curve secp384r1;

        add_header Strict-Transport-Security max-age=31536000;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;

        ssl_stapling on;
        ssl_stapling_verify on;

        index index.html index.nginx-debian.html;

        location / {
                try_files $uri $uri/ =404;
        }
}
sudo nginx -t
sudo service nginx restart

기존에 http://[도메인] 의 접속은 https://[도메인] 으로 넘어가도록 301 리디렉션 코드를 작성했습니다.
이제 http 로 접속하면 자동으로 https 접속으로 바뀌게 됩니다.

profile
슬기로운 탐구생활

0개의 댓글