조직 기계에 원격으로 닿기
원격 접속과 사설망, 「우리만」이 아니라 「가입한 기계 전부」
현장 AX에서 조직의 서버와 사무실 PC에 원격으로 닿으며 넘어진 자리를 정리한 글입니다. 사례는 품앗이와 함께 일한 협동조합 현장에서 나왔고, 조직 이름과 기계 이름, 주소는 지웠습니다.
요지
조직 AX는 남의 기계를 우리 사설망에 넣는 일입니다. 사무실 PC, 매장 POS, 조합 서버가 한 망에 들어오면 일은 편해지지만, 그 망은 이제 「우리만」이 아니라 「가입한 기계 전부」입니다. 그리고 접속 설정은 써 넣었다고 끝나지 않습니다. 그 설정이 실제로 쓰이는지까지 재야 끝납니다. 이 글은 사설망을 조직별로 가르는 법, 설정이 통째로 건너뛰어진 사례, 윈도 PC를 원격으로 다룰 때의 함정을 차례로 적습니다.
1. 사설망을 조직별로 가르기
한 사설망, 곧 테일넷에 여러 조합의 기계가 섞여 있으면 조직별 태그로 가릅니다. 태그는 기계를 건드리지 않아서, 관리 쪽에서 붙이면 다시 가입하거나 다시 인증할 필요 없이 바로 적용되고 연결도 끊기지 않습니다. 그래서 남의 조합 PC나 매장 POS에 붙여도 그 기계 앞의 사람 손이 필요 없습니다.
그런데 SSH 접속 규칙은 태그가 붙는 순간 바뀝니다. 「사용자 본인 기기끼리 허용」 같은 규칙은 태그가 붙은 기기에는 걸리지 않습니다. 태그 기기는 더 이상 한 사용자의 소유가 아니기 때문입니다. 규칙을 고치지 않고 태그만 붙이면 그 기계로 가는 SSH가 바로 끊기므로 다음 순서를 지킵니다.
- 규칙을 먼저 넣되, 이때는 전체 허용을 유지합니다.
- 그다음 조합 기기에 태그를 붙입니다.
- 우리가 접속해 들어가는 쪽 기기는 맨 나중에 붙입니다.
전환하는 동안 임시로 넣은 허용 규칙은 끝나면 반드시 뺍니다. 남겨 두면 정리되지 않은 옛 기기가 조합 서버에 들어갈 수 있습니다.
정책 검증은 공짜입니다. 사설망 관리 API의 정책 검증 기능에 「A에서 B로 허용」, 「A에서 B로 거부」 같은 시험을 같이 보내면 채점해 줍니다. 이때 일부러 틀린 단정, 예를 들어 「조합 A에서 조합 B로 허용」을 먼저 넣어 시험이 실패로 나오는 것을 봅니다. 그래야 시험이 무시되는 게 아니라 실제로 평가된다는 걸 압니다. 우리가 직접 시험해 볼 수 없는 통로, 예를 들어 다른 조직 담당자의 PC에서 그 조합 서버로 가는 길은 이 시험으로 먼저 증명한 뒤에 태그를 붙입니다. 거기가 깨지면 그 사람의 업무가 멈추는데, 우리는 재현조차 못 합니다. 실제로 규칙을 일괄 수정하는 스크립트가 한 조합의 규칙에 다른 기기를 섞어 넣은 것을 이 거부 시험으로 잡았습니다.
우리가 현장에서 쓰는 설계는 이런 모양입니다.
| 기기 | 닿을 수 있는 곳 |
|---|---|
| 배관을 맡은 우리 기기 | 전부 |
| 매장 PC, 직원 개인 작업 PC | 우리 서버에만 |
| 조합 기기 | 같은 조합 기기끼리, 그리고 우리 배관 통로 |
조합 쪽에서 우리 쪽으로 꼭 열어 둬야 하는 통로, 예를 들어 업무 화면의 음성 인식 통로를 빠뜨리면 업무 화면이 조용히 반쪽이 됩니다. 적용한 뒤에는 통해야 할 것과 막혀야 할 것을 둘 다 실제로 접속해 봅니다. 꺼져 있거나 사설망을 떠난 기계는 접속이 안 되니 「막혔다」로 잘못 읽기 쉽습니다. 사설망 관리 화면에서는 꺼짐, 탈퇴, 로그아웃이 모두 같은 모양으로 보입니다.
태그로 가른 망은 다른 사설망과 기기를 공유하는 기능과 함께 쓰기 어렵습니다. 공유받은 기기에는 태그 붙은 기기가 닿지 못한다는 것이 공식 문서의 설명입니다. 조합이 자기 사설망으로 독립한 뒤에도 백업처럼 상시 연결이 필요하면 사설망 말고 다른 통로를 함께 설계합니다.
사설망에만 붙였다는 것은 인증이 아닙니다. 사설망 안에 조합 POS PC가 있으면 사설망 주소에만 붙인 관리 화면도 그 PC 앞에 앉은 누구나 엽니다. 이 이야기는 문은 전부 닫아라 3절에서 이어집니다.
2. 사설망 SSH는 서버의 SSH 설정을 건너뛸 수 있다
한 협동조합 서버에 백업 보관 전용 계정을 만들고 「읽기만, 지정한 폴더에 가두기」를 SSH 서버 설정에 걸었습니다. 서버가 자기 자신에게 접속해 시험하니 잘 걸렸습니다. 그런데 다른 기계가 사설망 주소로 들어오자 제한이 하나도 걸리지 않았습니다. 그 서버는 사설망의 SSH 기능이 켜져 있어서, 사설망으로 들어온 22번 접속을 사설망 프로그램이 직접 처리하고 일반 SSH 서버는 아예 거치지 않았습니다. 백업 보관용으로 만든 계정으로 서버 전체에 셸이 열려 있었던 것입니다.
판정은 설정이 아니라 경로로 합니다. 접속한 셸의 부모 프로세스가 무엇인지 봅니다. 사설망 프로그램이면 SSH 서버 설정은 하나도 적용되지 않은 것이고, SSH 서버면 적용된 것입니다. 「SSH 서버 설정 출력」 명령은 「SSH 서버가 처리한다면 이렇게 된다」를 보여 줄 뿐, 실제로 적용됐다는 증거가 아닙니다. 우리는 그 출력이 맞게 나오는 걸 보고 「설정은 맞다」고 읽었습니다. 설정은 맞았고, 그 설정이 쓰이지 않았습니다. 사설망 전체의 기기 상태를 한 번에 받아 보면 이 기능이 켜진 기기를 기기마다 들어가지 않고 전부 셀 수 있습니다.
이 기능이 켜져 있다는 것 자체가 사고는 아닙니다. 사고는 거기에 SSH 서버 제한을 걸어 놓고 걸렸다고 믿는 것입니다. 기능을 끌 때는 일반 SSH 서버가 받을 포트를 먼저 열어 둡니다. 우분투 24.04는 SSH가 소켓 방식으로 떠서 설정 파일에 적은 포트를 무시하므로 소켓 설정에 써야 합니다. 이때 IPv4 주소를 명시하지 않으면 IPv6 쪽에만 열려 사설망 주소로는 접속이 거부될 수 있습니다.
같은 기능 위에서 큰 파일을 보내다 81MB에서 오류 없이 멈춘 일도 있습니다. 회선은 직접 연결에 15ms로 멀쩡했으니 회선이 아니라 전송 쪽 문제였습니다. 일반 SSH 서버를 다른 포트에 띄워 보내니 초당 약 11MB로 끝까지 갔습니다. 동기화 도구 rsync도 같은 이유로 그 경로에서는 쓰지 못합니다.
3. 움직이는 쪽은 클라이언트다
노트북을 들고 사무실로 옮기자 집에 있는 서버에 접속이 안 됐습니다. 원인은 서버가 아니라 노트북의 접속 앱 설정에 서버의 내부망 주소가 적혀 있던 데 있었고, 내부망 주소는 건물을 넘지 못합니다. 주소를 사설망 주소나 사설망 이름으로 바꾸자 노트북이 어디로 가든 상관없어졌습니다.
- 「연결이 안 된다」는 말을 들으면 서버부터 파지 말고, 클라이언트와 서버가 같은 망에 있는지 먼저 봅니다. 양쪽의 공인 주소를 비교하면 한 번에 압니다.
- 「노트북」이 몇 대인지 먼저 셉니다. 서버가 노트북인 경우도 있습니다. 「노트북을 옮겼다」는 말은 움직일 수 있는 쪽을 가리킵니다.
- 접속 앱이 SSH 설정 파일과 별개로 주소를 따로 들고 있을 수 있습니다. 설정 파일만 고쳐서는 소용이 없습니다. 같은 실패가 되풀이되면 전혀 다른 곳을 봅니다.
4. 윈도 PC를 원격으로 다루는 법
길은 사설망, 문은 윈도 자체 SSH
윈도에는 사설망의 SSH 서버 기능이 없습니다. 사설망으로 길만 뚫고, SSH 문은 윈도에 들어 있는 OpenSSH 서버로 따로 엽니다. 윈도 기능 설치가 막혀 진행 표시가 영원히 끝나지 않으면 패키지 관리자 winget으로 설치합니다. 패키지 이름은 짐작하지 말고 검색해서 확인합니다. 새로 붙인 기기는 사설망의 키 만료를 그 자리에서 해제합니다. 그리고 윈도인 채로는 정전이나 재부팅 뒤 아무도 로그인하지 않으면 서비스가 다시 뜨지 않는다는 한계를 알고 얹습니다.
열쇠를 넣었는데 비밀번호를 묻는다면
- 관리자 계정은 개인 폴더의 열쇠 파일을 아예 읽지 않습니다. 관리자용 공용 열쇠 파일 한 곳만 봅니다. 그 파일의 권한이 관리자와 시스템에게만 있어야 하고, 다른 계정 권한이 하나라도 남아 있으면 오류 없이 조용히 무시합니다.
- 권한을 줄 때는 그룹 이름 대신 고유 번호인 SID로 지정해야 한국어 윈도에서도 깨지지 않습니다. 파일은 BOM 없는 ASCII로 씁니다.
- 없는 계정으로 접속해도 「열쇠 인증 실패」로 답합니다. 프로필 폴더 이름과 계정 이름이 다를 수 있습니다. 폴더 이름만 영문으로 바꾼 경우가 그렇습니다. 열쇠를 대조하기 전에 계정 이름부터 확인합니다.
원격 PowerShell의 인용 지옥
리눅스에서 SSH로 윈도에 PowerShell 명령을 보내면 bash, cmd, PowerShell 세 겹이 따옴표를 각자 해석해서 자주 깨집니다. 아래는 효과가 컸던 순서입니다.
- 윈도의 일반 프로그램은 PowerShell을 끼우지 말고 cmd로 직접 부릅니다.
- 스크립트는 한 줄로 끼워 보내지 말고 파일로 올려서 실행합니다.
- 스크립트에 한글을 넣지 말고, 걸러야 할 것이 있으면 전부 받아서 리눅스 쪽에서 거릅니다.
- 화면 출력은 한글이 깨지므로 결과는 파일로 남겨 거두어 옵니다.
- 그래도 복잡하면 명령을 인코딩해 보내 따옴표 문제를 통째로 없앱니다. 다만 이미 PowerShell인 셸 안에서 PowerShell을 또 부르는 중첩 실행은 거부될 수 있습니다.
PowerShell 5.1은 BOM 없는 UTF-8 스크립트를 한국어 코드 페이지로 읽습니다. 그러면 한글이 따옴표를 무너뜨려 해석 오류가 나거나, 더 나쁘게는 운 좋게 통과해서 출력만 깨지고 뒷부분이 실행되지 않습니다. 한 사무실 PC의 동기화 스크립트가 「가끔 안 돈다」고 했던 이유가 이것이었습니다. 증상은 로그 깨짐, 로그에 스크립트 내용이 섞임, 뒷부분 미실행 셋이었지만 원인은 하나였습니다. 우리는 처음에 로그 파일 쪽을 고쳤고, 그건 틀린 처방이었습니다.
- 파일 첫 3바이트를 찍어 BOM이 있는지 봅니다.
- 같은 틀로 찍어 낸 형제 스크립트를 전부 찾아봅니다. 배관을 복제하면 결함도 같이 복제됩니다. 실제로 다른 작업 PC의 스크립트에서 같은 결함을 찾아 미리 고쳤습니다.
- PowerShell이 없는 기계에서 고쳐서 보내지 말고, 처음부터 그 기계에 있는 쪽, 곧 그 PC의 AI나 담당자에게 넘깁니다. 증상을 재현할 수 없는 곳에서는 증상과 원인을 가를 수단이 없습니다.
그 밖의 함정
- 한국어 윈도의 출력 항목 이름을 영어로 가정하지 않습니다. 영어 항목 이름만 가리던 비밀번호 가림 로직이 한국어 출력을 못 잡아 비밀번호가 화면에 그대로 찍힌 일이 있습니다.
- 원격으로 띄운 화면 프로그램은 다른 세션에 뜹니다. 화면 자동화의 벽과 우회 1절을 봅니다.
- 남의 작업 PC에서 프로세스를 이름으로 쓸어 담아 끄지 않습니다. 정리하겠다며 브라우저를 전부 꺼 버린 일이 있습니다.
5. 남의 PC 자료를 서버로 당겨 오기
「서버의 AI가 PC 자료를 못 읽는다」는 문제의 원인은 망이 아니라 공유 폴더와 계정이 없던 것이었습니다. PC 담당자와 합의해, 로그인 화면에 보이지 않는 로컬 계정과 공유 폴더 하나를 만들고, 서버에서는 권한을 잠근 자격 파일로 그 폴더를 연결합니다. PC가 꺼져 있어도 서버 부팅이 막히지 않게 걸어 둡니다. 비밀번호는 PC 쪽 AI가 만들어 서버에 직접 쓰고, 사람이 옮겨 적는 단계는 두지 않습니다. 조합 서버처럼 실제 기계에 깐 리눅스에서는 PC를 껐다 켜도 저절로 다시 연결되게 할 수 있습니다.
이미 있는 것부터 봅니다. 한 의료사협에서 외근 간호사가 원격으로 진료 차트 프로그램에 붙는 문제를 두고 VPN, 가상 머신, 노트북 구매까지 설계했다가, 옆 팀이 이미 「사무실의 본인 PC를 켜 두고 폰으로 그 화면을 당겨 쓰는」 방식을 늘 쓰고 있다는 걸 보고 접었습니다. 그런데 접은 뒤에 결론을 「노트북만 사면 된다」로 다시 적었습니다. 옆 팀이 노트북을 쓴다는 관찰을 그대로 결론으로 옮긴 것입니다. 설계를 접었으면 결과는 더 싸져야 합니다. 바른 결론은 새로 살 것 없이 있는 PC와 폰으로 시작하고, 써 보고 모자란 것이 있으면 그때 장비를 논의하는 것이었습니다. 「현행 방식이 이미 있다」는 기록을 새 설계를 하는 이유로 읽지 않습니다.
6. 공유기를 원격으로 만질 때
한 국산 공유기의 설정을 자동으로 바꾸며 겪은 일입니다.
- 설정을 보내는 요청에 정상 응답이 와도 실제로는 반영되지 않았습니다. 판정은 응답 코드가 아니라 설정 목록을 다시 열어 보는 것으로 합니다.
- 설정 화면을 단독 주소로 열면 입력은 되는데 「적용」 버튼이 아무 반응이 없습니다. 화면이 바깥 프레임을 참조하기 때문입니다. 전체 관리 화면으로 들어가 메뉴를 눌러 진입합니다.
- 적용 직후 화면이 새로 고쳐지며 자동화 스크립트가 죽을 수 있습니다. 실패로 단정하지 말고 목록을 다시 엽니다. 우리 경우엔 실제로 성공해 있었습니다.
- 포트 포워딩이 됐는지는 바깥 회선에서 시험합니다. 내부에서 자기 공인 주소로 접속해 보면 공유기 구조 때문에 되든 안 되든 판정이 안 됩니다. 다른 회선에 있는 사설망 기기가 좋은 시험대입니다.
- 포워딩을 걸었으면 그 기기의 내부 주소를 고정 할당으로 묶습니다. 재부팅 뒤 주소가 바뀌면 규칙은 남은 채 조용히 죽습니다.
일곱 줄로 줄이면
- 사설망은 「가입한 기계 전부」라서 사설망에만 붙인 화면에도 인증을 따로 건다.
- 태그를 붙이기 전에 접속 규칙부터 넣고, 조합 기기 먼저, 우리 기기는 나중에 붙인다.
- 직접 시험할 수 없는 통로는 정책 검증으로 먼저 증명하고, 일부러 틀린 시험을 먼저 넣는다.
- 접속 제한이 걸렸는지는 설정 출력이 아니라 실제 접속 경로로 판정한다.
- 연결이 안 되면 서버보다 클라이언트가 어느 망에 있는지 먼저 본다.
- 윈도에 보내는 스크립트는 파일로, 한글 없이, 한글이 있으면 BOM을 붙여서.
- 새 장비를 사기 전에 이미 돌아가는 방식이 있는지부터 본다.
도구 메모
- 접속 경로 판정(리눅스):
pstree -ps $$ | head -1. 부모가 사설망 프로그램이면 SSH 서버 설정은 적용되지 않은 것이다. - BOM 확인:
od -An -tx1 -N3 파일.ps1. 결과가ef bb bf면 있다. - 윈도 관리자 열쇠 파일 권한:
icacls <파일> /inheritance:r /grant '*S-1-5-32-544:F' /grant '*S-1-5-18:F'