Firefish를 설치해보자 (비전문가 대상)

nginx 설치하고 "홈페이지" 올려보기

구매한 도메인에 이 컴퓨터의 IP주소를 연결하기 전에, 접속은 되는지 확인해봅시다.

nginx (엔진엑스) 라는 프로그램을 설치해볼거에요.

nginx 웹서버

nginx라는 프로그램은 웹서버 프로그램의 한 종류입니다.

"웹서버" 라는 프로그램은, 누군가가 여러분의 컴퓨터에 접속하면, 웹페이지 파일을 전송해주는 프로그램입니다. 그래서 누군가 내 컴퓨터에 접속하게 되면 웹사이트를 볼 수 있게 되는거죠.

이번에 설치한 nginx를 나중에는 SNS 서버에 보안 연결을 추가하는데도 쓸거에요.

지금은 컴퓨터에 접속이 되는지 확인하는데 쓸겁니다.

sudo apt install nginx

systemctl 로 nginx 서비스 실행하기

nginx는 쉬지 않고 계속 실행되는 "서비스"형 프로그램입니다. 그래서 직접 "nginx" 명령어를 실행해서 켤 수도 있지만, 보통은 이렇게 하지 않고 "systemctl" 이라는 명령어로 실행합니다.

# nginx 서비스를 활성화하고 실행까지 합니다.
sudo systemctl enable --now nginx

# 위 명령어는 아래의 두 개의 명령어와 동일합니다.
sudo systemctl enable nginx  # 컴퓨터가 재시작해도 자동으로 실행합니다.
sudo systemctl start nginx   # nginx 서비스... 프로그램을 실행합니다.

 실행 예시

ch@my-firefish-instance:~$ sudo systemctl enable --now nginx
[sudo] password for ch:
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable nginx
ch@my-firefish-instance:~$

한 번 상태를 확인해볼까요.

sudo systemctl status nginx
# q 키를 눌러 닫을 수 있습니다

실행 예시

ch@my-firefish-instance:~$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-08-02 12:58:51 UTC; 19min ago
       Docs: man:nginx(8)
   Main PID: 15441 (nginx)
      Tasks: 2 (limit: 7014)
     Memory: 2.4M
        CPU: 39ms
     CGroup: /system.slice/nginx.service
             ├─15441 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─15444 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">

Aug 02 12:58:51 my-firefish-instance systemd[1]: Starting A high performance web server and a reverse proxy server...
Aug 02 12:58:51 my-firefish-instance systemd[1]: Started A high performance web server and a reverse proxy server.
lines 1-14/14 (END)

잘 실행중이네요.

홈페이지에 접속해보기

인터넷 주소창에 내 컴퓨터의 IPv4 주소를 넣어봅시다.
(굳이 다른 사람에게 공유하지는 마세요!)

기억하시나요? IPv4 숫자 네 자리가 우리 컴퓨터의 집주소입니다.

헉... 접속이 안 되잖아...?

방화벽 두 개가 갈 길을 막고 있다고???

원인을 파악해보니 두 가지 원인이 있었습니다.

  • 오라클에서 제공하는 우분투 이미지(운영체제 설치파일)에는 기본적으로 리눅스 내장 기능을 사용한 방화벽이 있어요. 이게 우선되어서 ufw로 만든 방화벽이 무시되었습니다.
  • 이건 알고있던 문제인데, 컴퓨터를 만들 때 만들었던 "가상 네트워크"의 방화벽에서도 접속 허용을 해줘야 합니다.

일단 ufw부터 되도록 손볼까요.

기존 방화벽을 ufw로 대체하자

사실 오라클 클라우드는 기존 방화벽을 대체하지 말라고 합니다. 사전에 설정해놓은 게 있거든요.

Do not use UFW to edit firewall rules.

https://docs.oracle.com/en-us/iaas/Content/Compute/known-issues.htm

근데 ufw가 쉽다는 점을 손쉽게 포기할 수는 없죠.

일단 현재 방화벽 세팅을 출력해볼까요. 이걸 이해할 필요는 없습니다.

sudo iptables -L

실행 예시

ch@my-firefish-instance:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     udp  --  anywhere             anywhere             udp spt:ntp
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited
ufw-before-logging-input  all  --  anywhere             anywhere
ufw-before-input  all  --  anywhere             anywhere
ufw-after-input  all  --  anywhere             anywhere
ufw-after-logging-input  all  --  anywhere             anywhere
ufw-reject-input  all  --  anywhere             anywhere
ufw-track-input  all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

ufw 말고도 뭔가 있습니다. 그게 중요합니다.

저는 이걸 ChatGPT한테 ufw 규칙으로 바꿔달라고 했어요. ufw로 안 되는건 기존의 방화벽인 iptables로 세팅하게 했구요.

여기서 중요한 것: 홈페이지 운영을 위해 80, 443 포트를 허용해줘야 하고, 원격 접속을 위한 22번 포트는 허용해주거나 제한해야 합니다.

좀 긴데 아래의 내용을 붙여넣어서 실행하면 됩니다. 이게 잘못 실행되면 접속이 아예 안 되어서 새로 만들어야 할 수도 있으니 조심하세요!

# 일단 시스템 방화벽의 연결 기본 옵션을 모두 허용으로 만듭니다
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT

# 모든 방화벽을 푸드득 날려버리기!
sudo iptables -F

# 기본 OUTPUT 룰 추가: link-local 로 접속하는 것 제안
# 이 보안 설정이 먼저 적용될거에요. 이건 ufw로는 못 하거든요.
sudo iptables -N InstanceServices
sudo iptables -A InstanceServices -p tcp -d 169.254.0.2 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.2.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.4.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.5.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.2 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport domain -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.169.254 --dport domain -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.3 --dport http -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.4 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.169.254 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport bootps -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport tftp -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport ntp -j ACCEPT
sudo iptables -A InstanceServices -p tcp --destination link-local/16 -j REJECT --reject-with tcp-reset
sudo iptables -A InstanceServices -p udp --destination link-local/16 -j REJECT --reject-with icmp-port-unreachable
sudo iptables -A OUTPUT -d link-local/16 -j InstanceServices

# ufw가 설정한 규칙을 초기화
sudo ufw reset

sudo ufw default deny incoming
sudo ufw default allow outgoing

# OCI 규칙입니다
# 시간 자동 설정
sudo ufw allow from any to any port ntp proto udp comment "oci rule converted by ChatGPT"
# 원격 접속 허용
sudo ufw allow from any to any port ssh proto tcp comment "oci rule converted by ChatGPT"

# 이번에 추가한 nginx 웹서버의 접속을 허용해줍시다
sudo ufw allow from any to any port http proto tcp comment "allow 80 port"
sudo ufw allow from any to any port https proto tcp comment "allow 443 port"
sudo ufw allow from any to any port https proto udp comment "allow 443 port"

# 방화벽 활성화
sudo ufw enable

# 방화벽 설정도 됐겠다, 시스템 방화벽의 기본 설정을 바꿔줍니다.
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD DROP

실행 예시 - 명령어 실행 (좀 깁니다)

ch@my-firefish-instance:~$ # 일단 시스템 방화벽의 연결 기본 옵션을 모두 허용으로 만듭니다
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT

# 모든 방화벽을 푸드득 날려버리기!
sudo iptables -F
sudo iptables -X

# 기본 OUTPUT 룰 추가: link-local 로 접속하는 것 제안
# 이 보안 설정이 먼저 적용될거에요. 이건 ufw로는 못 하거든요.
sudo iptables -N InstanceServices
sudo iptables -A InstanceServices -p tcp -d 169.254.0.2 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.2.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.4.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.5.0/24 --dport iscsi-target -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.2 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport domain -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.169.254 --dport domain -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.3 --dport http -m owner --uid-owner root -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.0.4 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p tcp -d 169.254.169.254 --dport http -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport bootps -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport tftp -j ACCEPT
sudo iptables -A InstanceServices -p udp -d 169.254.169.254 --dport ntp -j ACCEPT
sudo iptables -A InstanceServices -p tcp --destination link-local/16 -j REJECT --reject-with tcp-reset
sudo iptables -A InstanceServices -p udp --destination link-local/16 -j REJECT --reject-with icmp-port-unreachable
sudo iptables -P FORWARD ACCEPT방화벽의 기본 설정을 바꿔줍니다.low 443 port"d by ChatGPT"
Resetting all rules to installed defaults. This may disrupt existing ssh
connections. Proceed with operation (y|n)? y
Backing up 'user.rules' to '/etc/ufw/user.rules.20230802_161736'
Backing up 'before.rules' to '/etc/ufw/before.rules.20230802_161736'
Backing up 'after.rules' to '/etc/ufw/after.rules.20230802_161736'
Backing up 'user6.rules' to '/etc/ufw/user6.rules.20230802_161736'
Backing up 'before6.rules' to '/etc/ufw/before6.rules.20230802_161736'
Backing up 'after6.rules' to '/etc/ufw/after6.rules.20230802_161736'

Default incoming policy changed to 'allow'
(be sure to update your rules accordingly)
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
ch@my-firefish-instance:~$

실행 예시 - 설정된 방화벽 확인 (좀 깁니다)

ch@my-firefish-instance:~$ sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ufw-before-logging-input  all  --  anywhere             anywhere
ufw-before-input  all  --  anywhere             anywhere
# 생략. UFW 룰이 있어야 합니다

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ufw-before-logging-forward  all  --  anywhere             anywhere
ufw-before-forward  all  --  anywhere             anywhere
# 생략. UFW 룰이 있어야 합니다

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
InstanceServices  all  --  anywhere             link-local/16
ufw-before-logging-output  all  --  anywhere             anywhere
ufw-before-output  all  --  anywhere             anywhere
# 생략. InstanceServices가 먼저 나오고, 그 다음에 UFW 룰이 있어야 합니다

Chain InstanceServices (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             169.254.0.2          tcp dpt:iscsi-target owner UID match root
ACCEPT     tcp  --  anywhere             169.254.2.0/24       tcp dpt:iscsi-target owner UID match root
# 생략

# 생략

중요한 부분은 주석을 확인해주세요. 헉헉

접속이 막혀버렸다면 OCI 콘솔 접속에서 복구하자

명령어를 잘못 실행해서 원격 접속이 막혀버렸다면, 오라클 클라우드 관리화면에서 "콘솔 접속"을 만들어 접속한 뒤, 다음의 명령어를 실행합시다.

로그인 후 아래 명령어를 실행해서 시스템 방화벽을 날려버립시다.

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

# 모든 방화벽을 푸드득 날려버리기!
sudo iptables -F
sudo iptables -X

가상 클라우드 네트워크의 방화벽 허용

이제... 빌린 컴퓨터 자체의 방화벽은 해결을 봤으니, 오라클 클라우드 환경의 네트워크망에서도 허용을 해줘야 합니다.

보안 목록으로 찾아들어가기

컴퓨터를 만들 때 같이 만들었던 가상 네트워크의 기본 보안 목록 설정화면으로 이동합시다.

수신 규칙 (ingress rule) 에 80포트와 443포트를 추가하기

이제, 인터넷에서 이 네트워크의 80 (비보안) & 443 (보안) 포트로 접속할 수 있게 설정해줍시다.

  • 수신 (ingress) 규칙은 바깥에서의 접근을 허용하는 규칙입니다.
  • 송신 (egress) 규칙은 이 네트워크에서 외부로의 접근을 허용하는 규칙입니다.

바깥에서 이 네트워크의 80, 443 포트로 접속할거니까, 수신 규칙을 추가해줍시다.

먼저 TCP 방식으로 접근하는 규칙을 추가한 뒤,

혹시 모르니까 UDP 규칙도 하나 더 추가해둡시다. (나머지 부분은 같습니다.)

 이제 규칙이 추가되었습니다.

 홈페이지에 다시 접속해보기

인터넷 창을 열어, 컴퓨터의 IPv4 주소를 주소창에 넣어봅시다.

 이제 접속이 됩니다...! 짝짝짝짝

눈여겨볼 점이 있습니다.

http: 보안 연결이 아니잖아?

자물쇠에 빗금이 그어진 게 보이시나요? 이번에는 80 포트로 접속했기에, 보안연결이 아닙니다.

  • 80포트는 "http" 라는 규약을 통해 웹사이트를 전송해줍니다. http 는 비보안 연결이구요.
    그래서, http://123.123.234.23 은 80포트로 접속하며, 비보안 연결입니다.
  • 443포트는 "https" 라는 규약을 통해 웹사이트를 안전하게 전송합니다.
    그래서 https://123.123.234.23 은 443포트로 접속하며, 보안 연결입니다.

사실, 보안연결인지 비보안연결인지의 전송규약은 포트랑은 별개라서, 생판 다른 포트에서도 http나 https로 전송할 수 있기는 합니다.

  • 보통은 http://123.123.234.23:8080 이라는 걸 많이 보실거에요.
    전송규약(프로토콜)은 http이며, 포트는 8080입니다.
  • 80포트는 http 규약을 사용한다면 생략됩니다.
    http://123.123.234.23:80http://123.123.234.23 과 같습니다.
    • 마찬가지로 https 보안연결은 443 포트를 사용한다면 생략됩니다.

https 보안 연결 설정은 나중에

우리가 설치할... 갈 길이 머네요... firefish는 보안 연결을 직접 지원하지 않습니다. 설사 제가 잘못 알고있어서 firefish가 보안 연결을 직접 지원하더라도, 그보다는 nginx한테 보안 연결을 맺게 만들고, firefish에는 비보안 연결로서 전달해주는 게 더 편리합니다.

이 설정은 나중에 할게요. 일단 개념만 이해해두고 갑시다.

댓글

댓글 본문