udev로 입력장치 권한, dialout·plugdev를 어떻게 고정하나

udev 입력장치 권한을 USB 시리얼·HID에 고정하려면 /etc/udev/rules.d/에 규칙을 두고, 부모 USB의 ATTRS{idVendor}·ATTRS{idProduct}(가능하면 serial)로 매칭한 뒤 GROUP="dialout", MODE="0660", SYMLINK+="…"를 걸면 됩니다. Debian/Ubuntu 시리얼 노드는 기본이 dialout 그룹입니다.

이 글은 USB serial/HID 그룹·심볼릭 링크만 다룹니다. 일반 udev 규칙 입문은 다루지 않습니다.

규칙은 어디?

한 줄 답: 사용자 규칙은 /etc/udev/rules.d/99-….rules에 두고, 사용자를 dialout(필요 시 배포판의 plugdev/대체 그룹)에 넣은 뒤 재로그인합니다.

권장 흐름:

  1. 장치를 꽂고 노드를 확인합니다: ls -l /dev/ttyUSB* /dev/ttyACM*, HID면 /dev/hidraw*.
  2. 사용자를 그룹에 추가합니다: sudo usermod -aG dialout "$USER" (로그아웃/로그인 필요).
  3. 규칙을 작성합니다. 예 — FTDI/CP210x류 시리얼:
# /etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
  ATTRS{serial}=="A1B2C3D4", GROUP="dialout", MODE="0660", SYMLINK+="myboard"

HID 예(벤더·제품을 실측값으로 교체):

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", \
  GROUP="plugdev", MODE="0660", SYMLINK+="myhid"

systemd 기본 규칙도 tty*류에 GROUP="dialout"을 줍니다. 커스텀 규칙은 영속 이름(SYMLINK)특정 VID/PID만 조이기가 목적입니다. ArchWiki 등은 Ubuntu식 plugdev를 데스크톱 USB에 쓰는 관행을 언급하지만, systemd 쪽에서는 plugdev 의존을 지양하고 uaccess 태그·시스템 그룹을 권하는 논의가 있습니다. 임베디드 보드 시리얼은 dialout + 로그인 세션이 가장 흔합니다.

이미 /dev/serial/by-id/… 링크가 있으면 앱 경로만 그쪽으로 바꿔도 열거 순서 문제를 피할 수 있습니다.

ATTR 매칭은?

한 줄 답: udevadm info -a -n /dev/ttyUSB0으로 부모 체인의 ATTRS{…}를 보고, 한 부모에 있는 속성끼리 조합합니다. 대소문자를 맞춥니다.

실측:

udevadm info -a -n /dev/ttyUSB0 | grep -E 'ATTRS\{(idVendor|idProduct|serial|manufacturer|product)\}'

매칭 팁:

  • ATTR{…}그 디바이스, ATTRS{…}부모를 올라가며 검색합니다. VID/PID는 보통 USB 부모에 있습니다.
  • 한 규칙 줄에서 ATTRS동일 부모 디바이스에서 만족해야 합니다. 서로 다른 조상의 속성을 한 줄에 섞지 않습니다.
  • 값은 소문자 헥사로 나오는 경우가 많습니다(0403). "0403""0403 "처럼 공백·대문자 불일치를 피합니다.
  • 여러 동종 동글이 있으면 ATTRS{serial}=="…"까지 넣어 보드를 고정합니다.
  • 시리얼은 SUBSYSTEM=="tty"(또는 KERNEL=="ttyUSB*")로 문자 디바이스를 잡고, USB raw(SUBSYSTEM=="usb")에만 SYMLINK를 걸면 앱이 기대한 tty가 아닐 수 있습니다.

udevadm 검증은?

한 줄 답: control --reload-rulestriggerudevadm test / info로 GROUP·SYMLINK·ACL을 확인합니다.

sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=tty
# 또는 해당 디바이스만
sudo udevadm trigger -n /dev/ttyUSB0

udevadm info -n /dev/ttyUSB0 | grep -E 'DEVNAME|DEVLINKS|ID_VENDOR|ID_MODEL|ID_SERIAL'
ls -l /dev/myboard /dev/ttyUSB0
# dry-run으로 규칙 적용 경로 확인
sudo udevadm test /sys/class/tty/ttyUSB0 2>&1 | tail -n 40

체크리스트:

  • ls -l의 그룹이 dialout(또는 지정 GROUP)인가
  • /dev/myboard SYMLINK가 기대한 tty를 가리키는가
  • 재로그인 후 일반 사용자로 cat/picocom/python -m serial.tools.miniterm이 Permission denied 없이 열리는가
  • 안 되면 groups에 dialout이 있는지, 규칙 파일 확장자·문법(== vs =), VID/PID 오타를 봅니다

마무리

USB 시리얼·HID 권한을 고정하려면 /etc/udev/rules.d + dialout 멤버십 → ② ATTRS VID/PID(/serial) 매칭 → ③ udevadm reload·trigger·test 순입니다. 일반 udev 개론이 아니라 그룹·SYMLINK·검증에 집중하면 보드를 바꿔 꽂아도 경로가 흔들리지 않습니다.

출처