[Bash] 서버에서 자료 가져오기 (port, 방화벽)

2023. 10. 27. 16:13Developers 공간 [Shorts]/Software Basic

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

서버에서 데이터를 빼내고자 합니다. 하지만 22번 port가 막힌 상황이라면 다른 어떤 방법들이 있을지 살펴보겠습니다.


2. Why? (원인)

아래와 같은 다양한 방법으로 파일을 가져와 보겠습니다.

  1. 방법1. jupyter를 활용해 파일 다운로드
  2. 방법2. python을 활용해 http 서버 포트 열기 - wget, curl 
  3. 방법3. 22번 포트 대신 다른 포트를 활용하기 - scp

3. How? (해결책)

먼저 상황을 설명하겠습니다.

  1. A 서버의 컴퓨터에 /home/tkay/FOLDER/home/tkay/FILE이 위치하고 있습니다.
  2. B 서버에서 해당 위치의 폴더와 파일을 가져오고 싶습니다. 가져오고 싶은 곳은 그냥 현재 위치(./)입니다.
  3. A서버의 ip는 10.10.10.10입니다.

위 상황에서 파일과 폴더를 가지고 오고 싶다면, A서버에서 해당 포트를 Listening하고 있는 프로세스가 있어야 B서버의 요청에 대응을 할 수가 있습니다. 따라서 A서버에서 HTTP 서버를 띄우거나, sshd와 같은 이미 있는 daemon을 활용해야하는데, 이로 인해 아래와 같은 3가지 방법을 제안합니다.

 

  • 방법1. jupyter를 활용해 파일 다운로드

/home/tkay/ 위치에서 아래와 같이 jupyter notebook을 띄워주는 방법입니다.

jupyter notebook --ip 0.0.0.0 --NotebookApp.token='aa' --NotebookApp.password='bb'

 

jupyter는 8888 포트를 기본적으로 활용하기 때문에 8888포트가 열릴 것입니다. 다른 포트를 사용하고 싶다면 아래 더보기를 눌러 참조하시면 됩니다.

더보기

----------------------------------------------------------------------

 <Port Forwarding을 하기 위해 Docker를 활용하는 방법>

위와 같이 jupyter를 실행하기 위해 8888 포트 외에 다른 포트를 열고 싶을 땐, 아래와 같이 docker를 활용해 Port Forwarding을 할 수 있습니다. 

 

아래 예는 8888 포트 대신 1110포트를 활용하고 싶은 상황을 예시입니다. 아래와 같이 container를 만들어 준 다음에 내부에서 jupyter notebook을 이후에 설명드릴 과정과 같이 실행해주면 1110포트를 활용할 수 있습니다.

docker run -it -d --name remote_jupyter -p 1110:8888 —-mount type=bind,source=/home/tkay,target=/root python

docker exec -ti remote_jupyter bash

jupyter notebook

 

----------------------------------------------------------------------

다음으로 아래 중 하나의 방법을 활용해 파일을 가져오려면 B서버에서 직접 browser를 통해 jupyter notebook에 접근합니다. (위 예시의 경우 http://10.10.10.10:8888) jupyter에는 데이터를 다운로드 할 수 있는 GUI를 제공하기 때문에 이를 활용해 데이터를 받습니다.

 

  • 방법2. python을 활용해 http 서버 포트 열기 - wget, curl 

먼저 /home/tkay/ 위치에서 아래와 같이 HTTP 서버를 띄워줍니다. 이 방법의 경우 포트를 지정해줄 수 있으므로, 1112라는 포트로 임의로 실행해보겠습니다.

python3 -m http.server 1112

 

이번엔 wget 혹은 curl 명령어 를 활용해 가져와 봅니다. wget은 recursive하게 파일을 가져 올 수 있으므로 폴더를 가져올 수도 있습니다. 이 방법의 경우 위의 http 서버 작동위치인 /home/tkay/  기준으로 파일이름을 적어줘야합니다.

**wget, curl : Web Server로부터 컨텐츠를 가져오는 Linux 커맨드

wget tkay@10.10.10.10:1112/FILE
wget -r --no-parent tkay@10.10.10.10:1112/FOLDER

curl -O tkay@10.10.10.10:1112/FILE

 

  • 방법3. 22번 포트 대신 다른 포트를 활용하기 - scp

일반적으로 scpssh연결을 활용하기 때문에 default로 22번 port를 사용합니다. 

** ssh : 패스워드를 가로챌 수 있는 것에 비해 ssh는 패킷자체를 암호화하여 전송하기 때문에 원격 관리에혁명을 일으킨 프로그램.
** scp(Secure Copy) 프로토콜 : ssh연결을 사용하여 네트워크 컴퓨터 간의 파일을 전송하기 위한 프로토콜. 안전하고 쉽게 복사하며 ssh 보안 연결을 사용하여 파일을 전송.

 

아래는 scp를 활용해 데이터를 가져오는 명령어 입니다.

scp -r tkay@10.10.10.10:/home/tkay/FOLDER ./
scp tkay@10.10.10.10:/home/tkay/FILE ./
더보기

----------------------------------------------------------------------

<key파일(.pem)을 활용해 서버에 접속 하는 경우 >

AWS와 같은 서버에서는 key파일을 통해 인증을 요구하는 경우가 있기도 합니다. 이때 아래와 같이 -i 옵션을 활용할 수 있습니다.

ssh -i /home/tkay/mykey.pem tkay@10.10.10.10

scp -r -i /home/tkay/mykey.pem ./FILE tkay@10.10.10.10:/home/tkay/

 

----------------------------------------------------------------------

 

앞서 언급한 바와 같이 default로 22번 port를 사용하기 때문에 port를 바꾸어 줄 수 있습니다. 바꾸기 위해서는 먼저 /etc/ssh/sshd_config 파일의 아래 부분을 원하는 포트와 옵션으로 바꾸어 줍니다. 필자는 1113포트를 사용하겠습니다.

** 위 파일이 없으면 아래 명령어를 통해 설치하세요

apt-get install openssh-server
...
Port 1113
...
PermitRootLogin yes
...

 

이제 다시 ssh daemon 서비스를 재시작하겠습니다.

# Check services
service --status-all

# Restart service
sudo service sshd restart # CentOS/Fedora
sudo service ssh restart # Ubuntu/Debian

 

외부로 접근시 user를 따로 추가해주고 싶으면 아래 더보기를 클릭하세요

더보기

----------------------------------------------------------------------

<Ubuntu에서 user추가하기>

 

1. user 확인하기

user의 리스트는 /etc/passwd에서 확인할 수 있습니다.

 

2. user 추가하기

# Case1. -m -d (home directory), -s (shell type)
useradd -m -d /home/tkay -s /bin/bash tkay

# Case2. only name
adduser tkay

 

3. 비밀번호 바꾸기

passwd tkay

 

4. user의 group 확인하기

groups tkay

 

5. user에게 sudo 권한 주기

Ubuntu 20.04에서는 default로 own group에만 추가되어 있으므로 sudo group에 추가해줍니다.

usermod -aG sudo tkay

 

혹은 아래와 같은 방법으로 할 수 있습니다.  sudo 리스트를 확인해봅니다.

apt-get install sudo
visudo

 그리고 root의 내용 아래 본인을 추가해줍니다.

root ALL=(ALL:ALL) ALL
tkay ALL=(ALL:ALL) ALL

 

5. user 삭제하기

deluser tkay

----------------------------------------------------------------------

 

테스트 해보겠습니다. 아래와 같이 ssh로 포트로 접속하거나 데이터를 가져와 봅니다.

ssh tkay@10.10.10.10 -p 1113

scp -r -P 1113 tkay@10.10.10.10:/home/tkay/FOLDER ./
scp -P 1113 tkay@10.10.10.10:/home/tkay/FILE ./

 


 

ssh로 접속하고 싶은 경우 Docker로 띄워 줄 수도 있습니다. Docker로 실행할 때도 위와 같은 셋팅을 해주면 되지만, 특별히 주의해야 할 점은 포트를 열어주는 것과 network 설정을 잘해주어야 한다는 것 뿐입니다.

 

먼저, 포트를 열어주는 방법은 Dockerfile을 실행하는 경우 아래와 같은 명령어를 넣어줍니다.

** 사실 EXPOSE를 하지 않아도 포트는 노출된 상태로 컨테이너를 생성합니다. 단지 이미지 제작자와 컨테이너 사용자 사이의 정보 공유를 위한 정보라고 보시면 좋습니다.

...
EXPOSE 1113
...

docker 명령어로 실행하는 경우에는 포트번호를 명시해줍니다. 이때는 외부 포트를 같은 포트로 해주지 않아도 되므로, 여기서는 5555로  port-forwarding해 보겠습니다.

docker run -it -p 5555:1113 ubuntu

 

 

두번째로 주의할 점은 docker 실행시 network를 어떤 걸로 주어야하냐는 것인데, 필자는 network는 아래 네가지 중 default인 bridge를 활용하니 접속이 원활했습니다.

** host일 때는 이유는 모르겠지만 scp가 동작하지 않았습니다.

  • bridge(default) : 따로 bridge를 설정해주지 않으면 docker0라는 브리지에 연결될 것입니다.
    ** docker0 : 도커가 설치될 때, 기본적으로 구성되는 브리지. 호스트의 네트워크인 eth0과 컨테이너의 네트워크와 연결을 해주는 역할.
  • host : 호스트의 네트워크 환경을 그대로 사용, 성능 향상 및 최적화가 필요하거나 광범위한 포트 처리를 해야 하는 경우 사용.
  • none : 아무런 네트워크를 사용하지 않는 것
  • container : 해당 컨테이너의 네트워크를 공유

[https://rimo.tistory.com/entry/Docker-Network-호스트와-컨테이너를-위한-네트워크를-구성해보자]

 

 

자 이제 컨테이너의 IP가 무엇인지 확인해보겠습니다. 아래 명령어 중 CONTAINER_NAME 위치에 container 이름을 넣어줍니다.

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER_NAME

 

위의 경우 외부에서 해당 서버에 5555포트로 접근하면(Dockerfile의 경우 1113 그대로) 접근이 가능한 것을 확인할 수 있습니다.

 

더보기

----------------------------------------------------------------------

<Linux에서 Port와 관련된 명령어 정리>

 

Linux에서는 방화벽으로 인해 Port가 막혀 있는 경우가 있기도 합니다. 이와 관련된 다양한 명령어를 정리해보겠습니다.

** 방화벽(Firewall) : network traffic을 filtering하는 과정

 

1. Linux 에서 Listen 하고 있는 port를 확인하기 위한 명령어

 

Linux에서 target & source 서버의 어떤 port들이 현재 Listen하고 있고, 방화벽 상태가 어떤지(Open, Filtered, Closed, Unfiltered) 볼 수 있는 명령어들을 먼저 살펴보겠습니다.

 

1-a. netstat

open 되어 있는 port들을 확인할 수 있는 명령어 입니다. 주로 사용하는 명령어는 아래와 같으며 결과를 보면 어떤 port들이 listening상태인지 확인할 수 있습니다. (80 port 는 website 를 host하기 위해 항상 열려 있습니다)

netstat -tnlp
[netstat의 결과]

 

위와 같이 상태가 많기 때문에 아래와 같은 명령어로 특정 프로세스의 상태를 확인할 수도 있습니다.

netstat -tnlp | grep sshd

 

Options -t -n -l -p -u -a -r
Abbr tcp number port listen PID udp all  
Desc tcp로 연결된 포트  프로세스의 포트  프로세스의 연결 상태  프로세스를 사용하고 있는 서비스명  udp로 연결된 포트  수신 대기 및 연결된 모든 포트  라우팅테이블

 

1-b. ss

ss 또한 위와 같이 open된 포트들을 확인하는 명령어이며 netstat과 결과가 비슷합니다.

ss -lntu
[ss의 결과]

 

1-c. nmap

가장 많이 쓰이는 명령어이며, 아래와 같은 명령어로 확인할 수 있습니다. 

nmap localhost

 

[nmap의 결과]

 

 

1-d. lsof

열려 있는 port를 확인하는 또다른 방법입니다.

lsof -i
[lsof의 결과]

sudo를 활용한 프로세스 중 root권한으로 실행된 프로세스들 또한 볼 수 있습니다.

sudo lsof -i
[lsof의 결과]

 

2. Linux 에서 방화벽을 다루기 위한 명령어

 

Ubuntu 에서는 보안상의 이유로 default로 대부분의 port가 closed되어 있습니다. 즉, 허용(ACCEPT) 하게되어 있지만 listening하고 있는 port는 존재하지 않습니다. (예를 들어 ssh를 설치하면 22번 port가 listen을 하게 됩니다.)

** Open Port : 서비스가 Listening하고 있으며, Connection을 Accept한다는 뜻으로 정의

 

이때, 아래 명령어들을 활용해 허용(ACCEPT)로 만들어 주거나 차단(DROP) 해줄 수 있습니다.

 

2-a. iptables

리눅스의 기본 방화벽으로, netfilter 라는 network stack관련 프레임워크를 활용해 패킷을 필터링하는 명령어입니다.

 

아래 명령어는 현재 방화벽 상태를 확인하기 위한 명령어 입니다. 세가지로 나누어 표시됩니다.

** Inbound : 내부로 들어오는 Packet
** Outbound : 외부로 나가는 Packet
** Forward : 내부 서버에서 Forwarding되는 Packet

sudo iptables -L -v
[방화벽 현재 상태]

아래 명령어를 활용하면 특정 포트의 방화벽을 허용하고 차단할 수 있습니다.

# Open Port
sudo iptables -I INPUT -p tcp —dport 1234 -j ACCEPT
sudo iptables -I OUTPUT -p tcp —dport 1234 -j ACCEPT

# Open Port for the specific IP
sudo iptables -I INPUT -p tcp —dport 1234 -s 10.10.10.11 -j ACCEPT
sudo iptables -I OUTPUT -p tcp —dport 1234 -s 10.10.10.11 -j ACCEPT

# Close All Port
sudo iptables -I INPUT -p tcp —dport 0:65535 -j DROP

 

Options -A -D -I -L
Abbr Append Delete Insert List
Desc 새로운 규칙 추가 기존 규칙 제거 새로운 규칙 삽입 규칙들을 출력

 

Options -p -s -d --dport -v -j
Abbr protocol source destination desnitation port verbose jump
Desc 프로토콜 혹은 포트번호
(tcp,udp,21,22) 
패킷 출발 주소  패킷 도착 주소 포트 번호 verbose모드  처리 방식 

 

2-b. ufw(uncomplicated firewall)

위 iptables의 작업을 간편화 해주는 명령어입니다. 많은 Linux가 pre-installed firewall 을 제공하지만 ubuntu에서는 설치해야합니다. 이때 enable하면 default로 incoming과 outcoming을 모두 deny하게 됩니다.

# Install
sudo apt-get install ufw

# Enable & Disable
sudo ufw enable
sudo ufw disable

# Allow Port
sudo ufw allow 22

# Allow Port with protocol
sudo ufw allow 22/tcp

# Check status
sudo ufw status
[ufw의 결과]

 

 

3. Routing Table을 편집하기 위한 명령어 : route

하나의 서버가 네트워크를 통해 다른 서버에 메시지를 전송할 수 있도록 Route를 구축하고, 현재 상태를 확인하기 위한 명령어 입니다.

** Routing Table : Packet 데이터조각을 전달하기 위한 목적 게이트웨이의 정보를 기록해두는 IP Table입니다. 

# Check Routing Table
route

# Add Routing Table (192.168.1.x --> eth0)
route add -net 192.168.1.0 -netmask 255.255.255.0 dev eth0
[Route의 결과]

 

**(참고) 공격을 확인할 수 있는 방법은 아래와 같습니다.

ufw의 경우 아래와 같이 logging을 가능하게 할 수 있습니다. 이렇게 로깅된 것들을 실시간으로 확인하거나 linux에 존재하는 파일을 통해 확인할 수 있습니다.

방화벽과 관련된 로그는 /var/log/syslog(주로 ufw)과 /var/log/kern.log(주로 iptables)의 내용을 통해 확인할 수 있습니다. 

접속정보나 접속실패 로그는 /var/log/btmp/var/log/wtmp에서 확인할 수 있습니다.

# Enable logging for ufw
sudo ufw logging on

# Check Real-time Logging Message 
journalctl -f 

# Check Logged file
grep -r "Attack Detected" /var/log/kern.log

# Check Logged file for log-in
last -f /var/log/btmp

----------------------------------------------------------------------

 


 

 

https://circleci.com/blog/ssh-into-docker-container/

https://www.digitalocean.com/community/tutorials/how-to-add-and-delete-users-on-ubuntu-20-04

https://jungfo.tistory.com/93

https://data-newbie.tistory.com/239

728x90
반응형