왜 Linux 데스크톱에서 GUI와 systemd를 같이 쓰나
많은 사용자가 Linux에서 Clash Meta(실무에서는 mihomo 코어 이름으로 더 자주 불립니다)를 쓸 때, 그래픽 클라이언트만 실행해 두었다가 로그아웃·재부팅·디스플레이 매니저 재시작 뒤에 프록시가 통째로 내려가는 경험을 합니다. 원인은 단순합니다. GUI 앱은 보통 사용자 세션에 묶여 있어서, 세션이 끊기면 자식 프로세스인 코어도 함께 종료되기 때문입니다.
반면 systemd 사용자 서비스나 시스템 서비스로 코어를 올리면, 부팅 직후나 SSH 세션만 있는 상태에서도 127.0.0.1의 혼합 포트·API가 유지됩니다. GUI는 “설정 편집·구독 갱신·트레이에서 켜고 끄기”에 집중하고, 실제 패킷 처리는 항상 떠 있는 데몬에 맡기는 구조가 장기 운영에 유리합니다. 이 글은 Debian·Ubuntu 계열을 기준으로, 흔한 Mihomo 기반 데스크톱 클라이언트 설치부터 systemd 자동 기동까지 한 흐름으로 묶어 설명합니다.
사전 준비: 배포판·권한·네트워크 스택
우분투 22.04/24.04, Debian 12, Linux Mint 등 데비안 계열은 패키지 설치 방식이 비슷해 이 가이드의 대부분을 그대로 적용할 수 있습니다. Fedora·openSUSE 등은 패키지 이름만 바꿔 맞추면 됩니다. TUN 모드를 쓸 계획이라면 커널 모듈과 권한 정책을 미리 확인하고, 다른 VPN이나 방화벽 규칙과 충돌하지 않는지 점검하는 것이 좋습니다.
데스크톱 환경(GNOME·KDE 등)에서는 시스템 프록시 연동을 GUI 클라이언트가 대신 켜 주는 경우가 많습니다. 반면 코어만 systemd로 띄운 뒤에는 “환경 변수(HTTP_PROXY)”나 데스크톱의 수동 프록시 설정을 직접 맞춰야 할 때도 있습니다. 어떤 방식이든 혼합 포트나 별도 HTTP/SOCKS 포트가 무엇인지 설정 파일에서 먼저 확인해 두세요.
처음에는 TUN 없이 규칙 모드 + 로컬 프록시 포트만 검증하고, 필요할 때 TUN을 켜면 문제 범위를 좁히기 쉽습니다. 방화벽(ufw, firewalld)이 로컬 루프백을 막고 있지 않은지도 함께 확인하세요.
Mihomo 기반 데스크톱 클라이언트 설치
Linux용 Clash 계열 GUI는 배포 형태가 AppImage·deb·rpm·Flatpak 등으로 나뉩니다. 공식 또는 신뢰하는 릴리스 페이지에서 아키텍처(amd64, arm64)에 맞는 파일을 고릅니다. AppImage는 실행 권한만 부여하면 되고, deb 패키지는 sudo apt install ./패키지.deb 형태로 설치하는 경우가 많습니다.
설치 후 첫 실행에서 구독 URL이나 로컬 config.yaml을 불러오면, 클라이언트가 프로필 디렉터리 아래에 설정을 펼쳐 둡니다. 이 경로는 뒤에서 systemd 유닛이 참조할 구성 파일 위치를 정할 때 핵심이 됩니다. 이미 Clash Meta로 이전한 프로필이 있다면, 동일한 YAML을 복사해 Linux 쪽 작업 디렉터리에 맞추면 됩니다.
GUI에서 외부 컨트롤 API(보통 127.0.0.1:9090 등)와 혼합 포트를 켜 두면, 브라우저 확장이나 다른 앱이 같은 포트를 바라보게 설정하기 쉽습니다. 다만 이후 systemd 서비스가 같은 포트를 점유해야 하므로, 포트 충돌이 없도록 한쪽만 리스닝하게 정리해야 합니다. 일반적인 패턴은 “systemd 쪽 코어가 리스닝하고, GUI는 외부 컨트롤만 붙는 것”입니다.
코어 바이너리 위치와 설정 파일 경로 잡기
systemd 유닛을 쓰려면 mihomo 실행 파일의 절대 경로와 구성 파일 절대 경로가 필요합니다. GUI가 함께 설치했다면 /usr/bin/mihomo 또는 /opt/... 아래에 있을 수 있습니다. 없다면 upstream 릴리스에서 바이너리를 내려받아 /usr/local/bin/mihomo에 두고 실행 권한을 부여하는 방식이 흔합니다.
설정 파일은 홈 디렉터리 아래 클라이언트별 데이터 폴더에 있습니다. 예를 들어 ~/.config/앱이름/config.yaml처럼 고정된 이름을 쓰기도 하고, 프로필별로 하위 디렉터리를 나누기도 합니다. 중요한 점은 systemd 서비스가 동일한 YAML을 읽도록 맞추는 것입니다. GUI에서 저장할 때마다 같은 파일이 갱신되어야 규칙·구독 변경이 즉시 반영됩니다.
권한 문제를 피하려면 서비스를 일반 사용자 유닛(systemd --user)으로 두는 방법이 안전합니다. 이렇게 하면 홈 디렉터리 안의 설정 파일을 자연스럽게 읽고 쓸 수 있고, root 권한을 과도하게 쓰지 않아도 됩니다. 반대로 TUN 장치를 전역으로 잡아야 하는 특수한 경우에는 capabilities나 별도 정책이 필요할 수 있으니, 배포판 문서를 함께 확인하세요.
systemd 사용자 서비스 예시
아래는 개념을 보여 주는 예시입니다. 실제 경로·사용자 이름·실행 파일 위치는 환경에 맞게 바꿔야 합니다. 사용자 유닛 파일은 보통 ~/.config/systemd/user/mihomo.service에 둡니다.
[Unit]
Description=Mihomo (Clash Meta) core for desktop
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /home/USER/.config/mihomo
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target
-d 인자는 “작업 디렉터리”를 의미하는 경우가 많아, 그 안에 config.yaml이 있어야 합니다. 배포판·빌드에 따라 플래그 이름이 다를 수 있으니 --help로 확인하세요. 서비스를 등록한 뒤에는 systemctl --user daemon-reload, systemctl --user enable --now mihomo.service 순으로 활성화합니다.
로그인 시 자동 시작을 위해선 사용자 매니저가 켜져 있어야 합니다. 대부분의 최신 데스크톱 배포판은 기본적으로 user@uid 서비스가 살아 있지만, SSH만 있는 최소 설치 환경에서는 loginctl enable-linger 사용자명이 필요할 수 있습니다. 이렇게 해야 로그아웃 후에도 사용자 유닛이 계속 돌아갑니다.
GUI 클라이언트와 systemd 서비스가 동시에 두 벌의 코어를 띄우면 포트가 겹쳐 실패합니다. 한쪽은 “외부 코어 연결 모드”로 전환하거나, GUI가 내장 코어를 끄는 옵션이 있는지 확인하세요.
데스크톱 프록시와 브라우저 연동
코어가 상시 기동되면 GNOME 설정의 “네트워크 프록시”에 127.0.0.1과 포트를 넣거나, 환경 변수를 셸 프로필에 선언해 터미널 앱 전체에 적용할 수 있습니다. Firefox·Chromium 계열은 각자 확장 프로그램으로 프록시를 분리해 쓰기도 합니다.
중요한 것은 루프백 주소와 프로토콜(HTTP vs SOCKS5)을 설정과 일치시키는 것입니다. 잘못 맞추면 “코어는 떠 있는데 앱만 안 나간다”는 증상이 납니다. YAML에서 포트·DNS·규칙을 조정했다면, 데스크톱 쪽 프록시 설정도 같은 전제를 쓰는지 다시 점검하세요.
TUN·권한·보안에 대한 짧은 메모
TUN 모드는 편하지만 커널 인터페이스를 건드리므로 권한 요구가 커질 수 있습니다. 데스크톱 세션 안에서만 TUN을 켜고, 코어 데몬은 사용자 권한으로 유지하는 식의 역할 분리를 쓰는 팀도 있습니다. 회사 보안 정책상 가상 어댑터 생성이 막혀 있다면 규칙 기반 분할 라우팅과 애플리케이션별 프록시로 타협하는 편이 현실적입니다.
방화벽 규칙을 직접 다룬다면, 로컬 프록시 포트는 외부 인터페이스에 노출되지 않게 제한하는 것이 좋습니다. API 포트 역시 기본적으로 루프백에만 바인딩되게 두고, 필요 시 토큰 인증을 켜 두면 실수로 외부에 열리는 일을 줄일 수 있습니다.
문제가 생겼을 때 점검 순서
운영 중 오류가 나면 아래 순서로 좁히면 빠릅니다.
systemctl --user status mihomo.service로 유닛이 active인지, 최근 로그에 무엇이 찍혔는지 본다.- 설정 YAML 문법 오류나 구독 다운로드 실패가 없는지 GUI 로그·코어 로그를 확인한다.
ss -lntp로 기대한 포트가 실제로 열려 있는지, 다른 프로세스가 먼저 잡고 있지 않은지 본다.- DNS 모드(Fake-IP 등)와 데스크톱/브라우저 설정이 충돌하지 않는지 확인한다.
- 재부팅 직후에는 네트워크가 올라오기 전에 서비스가 시작했다가 실패했을 수 있으니,
Restart=on-failure와network-online.target의존성을 재검토한다.
이 중 많은 항목은 Windows·macOS에서 겪는 증상과 본질이 같습니다. 차이는 Linux가 init 시스템·권한 모델·패키징이 투명하게 드러난다는 점이라, 로그만 확실히 읽으면 원인 파악이 오히려 쉬운 편입니다.
업데이트와 백업 습관
mihomo 코어는 프로토콜·규칙 문법이 진화합니다. GUI의 업데이트 알림이나 배포판 패키지 채널을 주기적으로 확인하고, 변경 전에는 config.yaml과 커스텀 규칙 파일을 백업해 두세요. Git으로 프로필을 관리하는 사용자는 민감한 토큰이 커밋되지 않게 주의해야 합니다.
오픈소스 저장소에서 릴리스 노트·이슈를 참고할 수 있지만, 설치 패키지를 받는 주 경로로는 이 사이트의 다운로드 페이지를 쓰는 편이 버전 선택이 명확합니다. 소스와 신뢰 정보는 별도로 안내하는 것이 혼선을 줄입니다.
정리
Linux 데스크톱에서 Clash Meta를 안정적으로 쓰려면, GUI 세션에 묶이지 않는 systemd 계층을 두는 것이 재부팅 이후에도 프록시가 끊기지 않는 핵심입니다. Mihomo 코어를 사용자 서비스로 올리고, GUI는 설정과 모니터링에 집중하게 정리하면 운영 부담이 줄어듭니다. 포트·프로필 경로·API 설정만 서로 일치시키면 Windows용 Verge 계열과 마찬가지로 일상 업무에 녹여 쓸 수 있습니다.
장기적으로는 규칙·DNS·구독 갱신이 한 파일에 모이므로, 백업과 업데이트 습관만 잡아 두면 다른 플랫폼으로 옮길 때도 같은 개념으로 이어 갈 수 있습니다. 최신 클라이언트와 코어 조합은 Clash 다운로드 페이지에서 확인할 수 있습니다. → Clash를 무료로 내려받아 Linux 환경에 맞는 Mihomo 데스크톱 빌드를 고르고, systemd와 함께 한 번에 정돈해 보시기 바랍니다.