본문 바로가기
카테고리 없음

리버스 SSH 설정하기

by 꺄꺄꺄 2023. 3. 24.

내가 가기 힘든 먼곳에 라즈베리파이를 세팅하고, SSH로 접속해야할 일이 생겼다. 가까이 있는 라즈베리파이야 SSH연결은 문제 없는게 IP가 바뀌어도 어떻게든 알아낼 수 있고, 공유기에 물려서 SSH에 바로 접근하지 못한다면 포트 포워딩 해주면 되는건데, 설치 하는 곳에는 그런 설정하기가 어려운 곳이다. 공유기도 내가 마음대로 접근할 수 있는 것도 아니라서 포트 포워딩 세팅도 못하고, 고정 아이피 할당도 못하닌까 어쩌다가 아이피가 바뀌기라도 한다면, 어떡하냐...

 

그래서 내가 컨트롤이 가능한 고정 서버를 마련해서, 라파가 어디에서 세팅이되던간에 안정적으로 리버스 SSH를 고정 서버로 연결되게끔 세팅을 하기로 했다. 고정 서버는 아마존의 라이트세일을 3개월간 무료 해주는 것을 썼다. 이제 먼곳으로 유배 될 라파를 역방향 프록시 설정해서 고정 서버로 연결 되게 하자. 

 

역방향 SSH 설정하는 것은 쉽다.

ssh -R proxy_port:localhost:22 user@proxy_server

-R 옵션을 주면 리버스 SSH 연결한다. 

라즈베리파이(localhost)의 SSH 포트(22)를 proxy_server에 user로 로그인하여 proxy_server의 proxy_port로 돌려준다. 

명령어가 살짝 복잡해 보이는데, localhost:22 로 접속하는 SSH를 proxy_server:proxy_port에도 접속할 수 있게 해주겠다는 것이다.

근데 여기서 그냥 명령어를 ssh -R localhost:22 proxy_server:proxy_port 이런식으로 해도 될 거같은데 이상하게 꼬아놓고, user@proxy_server 같은게 있냐? 그건 라즈베리파이도 프록시 서버에 로그인을 해야 포트를 붙여줄 수 있으닌까 요구를 하는 것이다. 

그래서 이 명령어를 쓰면 그 계정에 대한 패스워드를 요구를 할 것이다. 그래서 다시 정리하자면

proxy_server에 user로 로그인해서 그 proxy_server의 proxy_port에 localhost:22 ssh 접속을 가능하게 설정해라 이다. 

 

근데, 나는 라이트 세일을 고정 서버로 쓴다. 라이트 세일은 로그인을 패스워드로 하지 않고, public key로 하닌까. 역방향 SSH 설정할 때, public key 로그인을 같이 넣어줘야한다. 그래서 명령어는 다음과 같이 된다.

ssh -i public-key.pem -R proxy_port:localhost:22 user@proxy_server

-i 옵션을 줘서 라이트 세일에 라즈베리파이가 로그인 할 수 있도록 했다. 물론 라즈베리파이에다가 라이트세일 public-key.pem 파일을 넣어주고 해주자. 아마 public-key.pem 을 넣어주고 바로 커맨드 실행하면, 오류가 뜰 수 있는데, 그건 key파일 권한이 너무 열려있어서 문제라고 하는  거니 다음 명령어를 실행시켜서 key 파일 권한을 자신만 쓸수 있게 수정하자.

chmod 400 .ssh/public-key.pem

 

그럼 다시 잘 실행이 될거다. 여기까지 내 커맨드 예시이다.

ssh -i ~/.ssh/lightsail-public-key.pem -R 2222:localhost:22 ubuntu@lightsail_ip

나는 라이트세일 로그인 키 lightsail-public-key.pem 파일을 ~/.ssh 폴더에 넣어 두고, 내 라이트세일 2222포트에다가 역방향 프록시를 걸어 두었다. 이 커맨드가 정상적으로 수행이 되면, 라이트세일 서버에 로그인 하고 다음 커맨드를 입력하면 리버스 ssh 연결된 포트에 ssh를 연결하여 라파에 연결 해볼 수 있다.

ssh -p 2222 pi@localhost

현재 라이트세일(localhost)의 2222번 포트에 라즈베리파이의 ssh의 포트가 열려있다. 그래서 그 localhost:2222포트로 pi 계정으로 라즈베리파이에 접속할 수 있게 된다. 그럼 언제 어디서든지 라즈베리파이가 정상적으로 역방향 ssh를 라이트세일 2222포트에 걸어놓으면, 라즈베리파이가 언제 어디에 설치 되든, 라이트세일에 연결하기만 하면 라즈베리파이에 정상적으로 ssh를 연결 해볼 수 있다.

 

하지만, 이다음 문제는 라즈베리파이가 언제 어디서든 정상적으로 어떻게 리버스 ssh를 실행하냐는 것이다. 그에 대한 해답은 해당 커맨드를 서비스로 등록하여 라즈베리파이가 껏다 켜져도 자동으로 리버스 ssh연결하고, 연결에 실패하더라도 다시 시도하고, 연결이 끊어지지 않게 유지할 수가 있다.

 

일단 바로 커맨부터 수정하자, 해당 커맨드는 해당 커맨드를 실행한 터미널 세션이 끝나면 끊긴다. 그래서 해당 커맨드를 바로 서비스를 등록하면 연결하자마자 연결이 끊긴다. 연결이 끊이지 않게 하기 위해서 -N 옵션을 추가한다. 

ssh -i ~/.ssh/lightsail-public-key.pem -R 2222:localhost:22 -N ubuntu@lightsail_ip

이제 서비스로 등록하는 것을 해보자. 다음 커맨드를 실행하여 ssh-proxy.service 파일을 작성한다.

sudo nano /etc/systemd/system/ssh-proxy.service

그리고 나노 에디터가 열리면 다음과 같이 입력을한다.

[Unit]
Description=SSH Reverse Proxy

[Service]
User=pi
ExecStart=/usr/bin/ssh -i /home/pi/.ssh/lightsail-public-key.pem -R 2222:localhost:22 -N ubuntu@proxy_server
Restart=always
RestartSec=100

[Install]
WantedBy=multi-user.target

이 때, User은 라즈베리파이 계정으로 쓰고, ssh랑 public-key 경로도 절대 경로로 써준다. 그러니 /home/pi도 자신 계정에 맞게 수정을 해야한다. 그리고 저장하면 된다. 

 

이제 해당 서비스를 실행하고, 라즈베리파이가 켜질 때마다, 해당 서비스를 실행하게 하면 된다. 여기서 필요하게 될 커맨드를 묶어 보았다.

# 서비스를 시작
sudo systemctl start ssh-proxy

# 서비스 상태 확인하기
sudo systemctl status ssh-proxy

# 서비스 로그 보기
sudo journalctl -u ssh-proxy

# 서비스 중지하기
sudo systemctl stop ssh-proxy

# 서비스 수정시 리로드 하기
sudo systemctl daemon-reload

# 서비스 부팅시 시작되게 하기
sudo systemctl enable ssh-proxy

그리고 하다보면 라이트 세일 쪽에서 포트가 꼬일 수도 있는데 그럼 그 때 라이트세일에서 꼬인포트를 죽이고, 라즈베리파이에서 ssh-proxy 서비스를 재실행하면 다시 잘 될 것이다. 

# 해당 포트가 어떻게 되있나 확인
sudo lsof -i :2222

# 포트 꼬인거 다 죽이기
sudo kill $(sudo lsof -t -i:2222)

그래서 이 서비스가 이대로 쓰면 문제인게... 포트 연결하는데 실패했어도 다시 연결을 시도 하지 않는것이다. 그리고 성공했어도 오래 두면 연결이 끊긴다. 그래서 두가지 옵션을 추가해보았다. -o ExitOnForwardFailure=yes 옵션이랑 -o ServerAliveInterval=60 옵션이다. 

전자는 포트 포워딩 실패했을 때, 종료하게 해서, 다시 서비스가 재시작할 수 있게 하는 거고, 후자는 한번 연결하고난 뒤에도 지속적으로 핑을 때려서 리버스 프록시한게 끊기지 않게 하는 것이다. 그래서 다시 ssh-proxy.service를 수정하면 다음과 같다.

sudo nano /etc/systemd/system/ssh-proxy.service
[Unit]
Description=SSH Reverse Proxy

[Service]
User=pi
ExecStart=/usr/bin/ssh -i /home/pi/.ssh/lightsail-public-key.pem -R 2222:localhost:22 -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 ubuntu@proxy_server
Restart=always
RestartSec=100

[Install]
WantedBy=multi-user.target

그러면 이제, 무지성으로 라파를 껏다 켜도 라이트 세일에 잘 연결할것이고, 중간에 꼬이더라도 

# 해당 포트가 어떻게 되있나 확인
sudo lsof -i :2222

# 포트 꼬인거 다 죽이기
sudo kill $(sudo lsof -t -i:2222)

이걸 실행해보고 좀 기다리면 다시 연결 잘될 것이다. 그래도 안된다면 일단 포트 미리 다 죽여놓고, 연락해서 그 라즈베리파이... 한번 전원 뺏다가 꼽아줄 수 있냐고....

 

 

댓글