최근에 홈 서버를 장만했다.
usb에 ubuntu 20.04 LTS를 설치하고 집에 사용하지 않는 컴퓨터에 설치한 다음 여러 세팅을 했다.
하지만, 공유기를 사용한 탓인지 외부 네트워크에서 홈 서버로의 접근이 불가능했다.
이는 공유기 방화벽 문제 같은데, 아무리 구글링을 해봐도 해결을 할 수 없었다.
어쩔 수 없이 ssh tunneling을 이용하여 외부와의 터널을 뚫어보자!
secure shell의 줄임말.
원격 호스트에 접속하기 위한 방법으로, 다른 컴퓨터의 shell에 접근하는 방식으로 많이 사용한다.
기본 포트는 22번 포트를 사용하며, ubuntu의 경우 /etc/ssh/sshd_config 파일을 수정하여 설정을 변경할 수 있다.
ssh통신을 이용하여 컴퓨터의 통신을 연결시키는 기술.
구글에 검색해 보면 많은 정보가 있다.
간단히 말하면, A컴퓨터의 특정 포트(8000)으로 들어온 네트워크 요청을 ssh를 통해 B컴퓨터의 포트(80)으로 전달하는 기술이다.
B컴퓨터의 80번 포트가 방화벽으로 막혀 있어도 ssh를 통해 요청을 전달하므로, B컴퓨터의 80번 포트를 사용할 수 있다.
이번에 사용할 기술은 reverse tenneling.
주로 B컴퓨터의 모든 포트가 막혀 외부에서 접속이 불가능 할때 사용한다.
터널링을 위해서는 외부에서 접속 가능한 컴퓨터가 한대 필요하다.
이 컴퓨터는 요청을 전달하는 역할만 하므로 성능이 좋지 않아도 상관없다.
AWS의 free tier로 사용할 수 있는 t1-micro를 사용하면 편하다.
free tier ec2를 A컴퓨터라고 하고 홈 서버를 B컴퓨터라고 지칭하겠다.
먼저 B컴퓨터에서 A컴퓨터로 reverse tunnel을 뚫어야 한다.
B컴퓨터의 .ssh 폴더 안에 id_rsa 라는 이름으로 파일을 하나 생성한다.
그리고 A 컴퓨터와 ssh 연결에 필요한 private key를 복사하여 저장한다.
이후, 터미널에 다음 명령어를 입력한다.
ssh -R 2222:localhost:22 -N -f ubuntu@{A의 ip주소}
-R : reverse tunneling
-N : 명령어를 실행하지 않음
-f : 백그라운드에서 실행
ps aux|grep ssh
를 입력하면 해당 명령어가 잘 실행되었는지 알 수 있다.
/etc/ssh/sshd_config
도 수정 해줘야 한다.
GatewayPorts yes
AllowTcpForwarding yes
TCPKeepAlive no
이후 명령어를 통해 ssh를 새로 고침한다.
sudo service ssh restart
이제 외부에서 ssh -p 2222 ubuntu@{A의 ip주소}
를 이용하여 B컴퓨터에 접근할 수 있다.
B컴퓨터의 8080번 포트 또한 A컴퓨터의 8080번 포트로 연결하여 사용할 수 있다.
하지만 오랜 기간 사용해 본 경험으로, 외부에서 컴퓨터를 재부팅하면 tunneling이 풀려버린다.
이는 crontab을 이용하여 해결해 보자.
A컴퓨터의 80번 포트를 B컴퓨터의 80번 포트로 연결하는것은 약간의 문제가 있다.
A컴퓨터의 root 권한 뿐 아니라 B 컴퓨터의 root 권한 모두 사용해야 한다.
이를 편하게 하는 방법은 socat을 이용하는 방법이다.
socat은 포트를 연결하여, 80번 포트로 들어온 요청을 8000번 포트로 변경해 줄 수 있다.
따라서, ssh -R 8000:localhost:80 -N -f ubuntu@{A의 ip주소}
명령어를 이용하여 A컴퓨터의 8000번 포트와 B컴퓨터의 80번 포트를 연결한 후, $ socat TCP-LISTEN:80,fork TCP:localhost:8000
명령어를 통해 A컴퓨터의 80번 포트를 A컴퓨터의 8000번 포트로 연결한다.
결과적으로 A컴퓨터의 80번 포트와 B컴퓨터의 80번 포트를 연결할 수 있다.
하지만 문제는 socat을 백그라운드로 실행시키는 방법이 복잡하다는 것인데, 이는 tmux로 해결하였다.
일정 시간이나 조건마다 명령어를 실행시켜주는 기술.
crontab -e
를 통해 설정할 수 있다.
원하는 위치에 script를 작성한다.
/settings
위치에 setting.sh
를 만들고 ssh tunneling 명령어를 작성한다.
ssh -R 2222:localhost:22 -N -f ubuntu@{A의 ip주소}
그 후에
@reboot /home/ubuntu/settings/setting.sh
를 작성하고 저장한다.
이러한 방법을 사용한다면, 재부팅 후 자동으로 ssh tunnel을 뚫게 된다.
따라서, 방화벽 밖에서 재부팅 하여도 다시 연결할 수 있다.