재택근무 환경 마련을 위한 VPN 세팅 삽질의 기록
Introduction
본격적으로 재택근무를 하게 되면서, 회사로부터 랩탑(Laptop: LT)과 데스크탑(WorkStation: WS)을 각각 지급받았다. LT 는 Windows 10, WS 는 Ubuntu 20.04 이다(이 글을 작성하며 21.04 로 업그레이드 했다).
개발하는 코드는 LT 으로는 “절대” 빌드가 불가능할 정도라서 언제든 WS 에 접근하여 원격으로 빌드하고 개발할 수 있는 환경을 구성하는게 목표이다.
즉, LT 으로는 어디서든 일할 수 있게 기동성을 챙기고 WS 로는 무거운 빌드를 하는 구조를 생각했다.
상황을 정리해보면 다음과 같다.
- LT 는 언제든 움직일 수 있도록 무선(wifi)연결한다.
- WS 는 안정적인 네트워크 환경을 위해서 유선(ethernet)연결한다.
- WS 의 유선네트워크 IP 는 불변에 가깝다. (아직까지는)
- LT 와 WS 는 모두 VPN 이 연결되어 있어야 된다.
- VPN 은 고정IP 를 할당받지 않는다.
- WS 에 모니터/키보드/마우스 를 연결해두고 싶지 않다. (번거로운 일이다)
가장 귀찮고 짜증나는 부분이 있다면, WS 의 VPN 이 끊어진 경우 VPN 을 연결하기 위해서 WS에 모니터/키보드/마우스를 일일이 연결을 하고 다시 필요없어 지기도 하고, 괜히 쓰지도 않을게 연결되어있는게 보기도 좋지 않은 것이다.
그리고 혹시라도 업무를 하다가 WS 를 당장 조작할 수 없는 상황에 처하더라도 문제 없을 상황을 만드는게 중요하다.
Objective
WS 가 재부팅이 된 경우 혹은 VPN 연결이 유실된 경우에 WS 를 가장 간편하게 VPN 연결시키고, LT->WS 연결을 해낸다.
Trials
1. 원격데스크톱 연결
- TL;DR; 이 방법은 결국 할당받은 VPN IP 를 알지 못하여 실패했다.
원격데스크톱이 가장 간단한 방법 같아서 진행했다.
- LT -> WS 로 연결을 한다. (VPN 아닌 고정에 가까운 IP)
- Ubuntu GUI 에서 VPN 연결을 한다. 다만, 이때 원격데스크톱 접근해있었던 IP 가 VPN 이 연결되면서 더이상 접근이 불가능하게 된다. 결국, VPN 으로 할당받은 IP 를 알 수 없게 되어, WS 에 모니터/마우스/키보드 를 연결하여 IP 를 확인해내야 된다.
2. nmap 을 이용한 브로드캐스팅 방법
- TL;DR; 이 방법은 확률적인 접근으로, 좋지 않다.
1번의 결과 할당받은 VPN IP 를 알 수 없는 경우에, 이건 다소 확률적인 접근으로 볼 수 있을 것 같다. IPV4 기준, d class 부분만 할당이 바뀌는 패턴을 확인할 수 있었고 아래와 같이 nmap
을 이용해서 256개 대상으로 확인을 하면 XX
개만 ssh
해보면 급한 경우에는 접근이 가능할 수 있다. 하지만 정말 좋은 방법은 아니다.
1
2
3
4
5
6
$ nmap -sn -n a.b.c.0/24
Nmap scan report for a.b.c.ee
Host is up (0.012s latency).
Nmap scan report for a.b.c.ff
Host is up (0.0082s latency).
Nmap done: 256 IP addresses (XX hosts up) scanned in 1.00 seconds
3. ssh 로 원격에서 shell-script 를 실행하는 방법
- TL;DR; 이 방법은 결국 아래에서 설명할
openconnect
의 bug 로 사용하지 않았다.
vpn 을 연결하는데 사용하는 openconnect
가 cli 처럼 동작할 수 있다는 사실을 알게 되었다. 그래서 LT->WS 로 ssh 연결하여 openconnect
를 WS 의 로컬에서 실행시키는 방법을 생각했다. 그리고 그 shell-script 에서 public 한 어느곳인가에 WS 가 할당받은 VPN IP 를 알려준다면 해결될 것이다. 이때 DDNS 를 이용하는 script 를 공유받았다. 자세한 코드를 공개할 수는 없지만 내 IP 를 지정된 domain name 으로 DNS 에 등록하여 다른곳에서 해당 domain name 을 이용해서 접근할 수 있게 하는 script 이다. 즉, WS 에서 vpn 을 연결하고, vpn ip 를 할당받은 뒤에 script 를 적절한 시점에 실행시켜 DNS 에 등록을 한다면 해결된다.
Errors
openconnect
는sudo
권한으로 실행이 필요하고, vpn 연결할때 사용하는 password 도 stdin 으로 입력이 필요한데, 둘 다 stdin 으로 직접 입력대신 pipe 로 넘기는 방법을 shell-script 짜는데 너무 많은 시행착오를 겪어 많은 시간을 낭비했다. 물론 보안적으로는 너무나 좋지 않은 방법이지만, 다른 방법을 찾지 못해 이 방법을 사용했다. 아래는sudo -S -k
를 이용해서 pipe 로 비밀번호를 넘기는 방식의 shell-script 이다.
1
2
3
4
5
6
#!/bin/bash
echo "vpn connection start"
echo "$PASSWORD_USER" | sudo -S -k zsh -c 'echo "$PASSWORD_VPN" | openconnect --protocol=$protocol --background --user=$user $vpn_host'
echo "vpn connection end"
사실 위에서 언급한 script 에서 바로 DNS 등록을 하려고 했지만, LT-WS 가 ssh 로 연결되어 있고, vpn 이 IP 를 할당받는 순간 ssh 의 통신이 끊어지는 당황스러운 상황을 겪었는데, 당연히 IP 가 유효하지 않게되니 shell 이 계속 실행될 수 없다는 사실을 늦게야 깨달았다. 즉, 후속 DNS 를 등록하는 script 실행을 자력으로 해결해야된다. 멋진 방법은 아니지만, 실속을 위해서
crontab
에 등록하여 주기적으로 실행시키는 방법을 택했다.그래도 빠른 연결을 시키기 위해
crontab
을 5분으로 설정했는데, 5분마다 DNS 에 등록하는 script 가 매번 실행된다고 생각하니 네트워크 팀에게 왠지 경고를 받진않을까 라는 막연한 걱정이 들기 시작하여 마지막 IP 를 캐싱하여 변경이 없는 경우에는 DNS 등록을 하지 않는 식으로 shell 을 개선했다.
아래는 추가한 내용 일부이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
# compare the last_ip and ip, only proceeds when the change occurred
if [ -f "${last_ip}" ]; then
if [ $(cat "${last_ip}") = ${ip} ]; then
echo "ip not changed: aborting"
exit 1
else
echo "ip changed"
echo "${ip}" > "${last_ip}"
fi
else
touch "${last_ip}"
echo "${ip}" > "${last_ip}"
fi
- VPN Disconnect 할때 버그 발생
openconnect vpn 을 pgrep
으로 찾아낸 PID 를 이용하여 kill
하는 방식으로 종료하니 (다른 방법은 가이드 되어있지 않다) /etc/resolv.conf
가 원상태로 돌아오지 못하여서 그런지 connection 이 비정상적인 형태를 보였다. 또한, 왜인지는 모르겠으나 (service 로 등록된 network-manager
혹은 resolvconf
가 비정상 동작하면서 시스템에 영향을 끼친건 아닐까 추측해본다) 이 이후에 WS 를 재부팅 하지 않으면 사용할 수 없을 정도로 상태가 좋지 않아져서 이 방법은 사용하지 않기로 했다.
확실하진 않지만 Ubuntu 20.04
를 사용하는게 영향이 있을까 하여 큰맘먹고 Ubuntu 21.04
로 업데이트 해봤지만 이 역시 효과가 없었다.
4. Cisco AnyConnect
cli 이용
- TL;DR; 최종 채택했다. 나에게 너무 큰 시련을 안겨준
openconnect
는 바로 삭제했다(sudo apt remove openconnect
).
Openconnect
에 버그가 있음이 확실해서 다른 vpn 연결 client 도 똑같이 재현되는지 궁금해서 한번 실험해보다가, Cisco Anyconnect
는 전혀 그런 증상이 발생하지 않는것을 뒤늦게 확인하게 됐다. 혹시나 하여 cli 지원이 되는지 확인해봤는데 찾을 수 있었고, 심지어 훨씬 더 깔끔하다.
- Link 에 아주 잘 설명되어있어서 참고하였다.
아주 잘되어있는 포인트가 몇 개 있는데, 그 중 하나는 stdin
으로 받을 값들을 차례로 다른 파일에 옮겨놓고 라인피드로 구분해놓고 cli 로 전달하는 방식이 사용 가능한 점이다. 파일의 내용이 terminal 에도 표시되지 않는것으로 보아 보안이 그나마 조금 나아졌다고 생각한다. 그리고 openconnect
와 다르게 root
권한이 아니라도 실행이 가능하고 정상적으로 세팅을 해주어서 사용하기 훨씬 편했고, 별다른 설정 없이 background 로 실행하여 따로 관리해줄 필요도 없었다.
App 의 도움을 받긴 했지만, 그만큼 Cisco 가 잘 만들었다고 생각한다. 진작 알았으면 더 좋았을 것 같다.
Conclusion
크게 돌아 결과적으로 Cisco 가 만든 정식 VPN 인 Anyconnect
에서 제공하는 cli 를 이용하여 아주 편하게 LT 에서 VPN 을 연결했다가 끊었다 할 수 있는 상태를 구축할 수 있었다. 심지어 중간에 네트워크가 끊어지지도 않아서 DNS 를 등록하는 것도 하나의 shell-script 에 작성해서 cron 이 돌때까지 기다릴 필요 없이 ssh 연결을 아주 빠르게 할 수 있게 되었다.
Comments powered by Disqus.