Create TOC

2025년 12월 14일

udev+systemd 로 usb 마운트 자동 설정

목차

    2025년 7월 11일

    wlan0 자동 재연결 설정

    목차

      2025년 7월 4일

      SOYO M4 Pro Debian Linux 설정 가이드

      목차

        2024년 12월 14일

        Debian/systemd로 rclone mount하기

        2023년 4월 18일

        Debian/Gamepad 연결만 하면 Retroarch가 죽을 때

        2022년 6월 17일

        Debian/Wayland에서 탭하여 클릭이 동작하지 않을때

        2022년 4월 18일

        Debian/HDMI 로 TV 연결했지만 화면이 나오지 않을 때

        HDMI 로 TV를 연결했는데 TV가 연결되지 않고 /var/log/kern.log에서 아래와 같은 오류로그가 보인다.

        [drm:dc_link_detect_helper [amdgpu]] *ERROR* No EDID read.

        TV 제조사에 따라 다르지만 EDID를 제대로 알려주지 않은 경우 문제가 발생한다. 아래와 같은 순서로 문제를 해결할 수 있다.

        1. https://github.com/akatrevorjay/edid-generator/를 이용해서 EDID binary를 만든다(TV 해상도에 맞는 bin 파일이 있으면 파일을 받는다(이후 1920x1080.bin).
        2. bin 파일을 /usr/lib/firmware/edid/에 복사해 넣는다.
        3. initramfs를 다시 만든다.
          $ sudo update-initramfs -k all -c
        4. xrandr명령으로 포트 이름을 확인한다.
          $ xrandr
          Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
          eDP connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 194mm
             1920x1080     60.04*+
             1680x1050     60.04  
             1280x1024     60.04  
             1440x900      60.04  
             1280x800      60.04  
             1280x720      60.04  
             1024x768      60.04  
             800x600       60.04  
             640x480       60.04  
          HDMI-A-0 disconnected (normal left inverted right x axis y axis)
        5. /etc/grub/default 파일에서 GRUB_CMDLINE_LINUX_DEFAULT에 아래 값을 추가한다.
          drm.edid_firmware=HDMI-A-1:edid/1920x1080.bin
          만일 부팅할때 부터 HDMI에 출력하고 싶다면 아래 값을 추가한다.
          video=HDMI-A-1:e
        6. update-grub를 실행한다.
          $ sudo update-grub
        7. 재부팅한다.
        부팅 후 HDMI로 TV와 연결하면 화면이 나오는 것을 확인할 수 있다.

        2021년 10월 25일

        Wireguard client 설정

        wireguard 서버는 docker 로 설정했다면 client 설정은 간단하다. 아래는 docker-compose.yml 파일이다.

        version: "2.1"
        services:
            app:
                image: ghcr.io/linuxserver/wireguard
                cap_add:
                    - NET_ADMIN
                    - SYS_MODULE
                environment:
                    - PUID=1001
                    - PGID=1001
                    - TZ=Asia/Seoul
                    - SERVERURL=test.com #optional
                    - SERVERPORT=51820 #optional
                    - PEERS=5 #optional
                    - PEERDNS=1.1.1.1
                    - INTERNAL_SUBNET=10.13.13.0 #optional
                    - ALLOWEDIPS=0.0.0.0/0 #optional
                volumes:
                    - ./config:/config
                    - /lib/modules:/lib/modules
                ports:
                    - 51820:51820/udp
                sysctls:
                    - net.ipv4.conf.all.src_valid_mark=1
                restart: unless-stopped

        wireguard 앱

        iOS나 Android의 wireguard 앱을 사용할 경우 아래 명령으로 QR 코드를 출력해서 사용하면 된다.

        $ docker-compose exec app /app/show-peer 숫자
        

        linux

        w연결을 위해 config/peer숫자/peer1.conf(1은 사용하고자하는 peer 번호를 쓰면 된다) 내용을 /etc/wireguard/mywg.conf(파일 이름은 원하는대로)로 복사해오면 된다.

        $ cat config/peer1/peer1.conf
        

        이걸 그대로 /etc/wireguard/mywg.conf 로 복사해서 사용하면 된다. 복사 후 아래 명령으로 연결할 수 있다.

        $ sudo wg-quick up mywg
        

        img 파일 mount

        raspberry pi OS의 /boot폴더가 손상될 경우 부팅이 안된다. 이때 새로 설치하지 않고 raspberry pi OS에서 /boot만 추출해서 복구해본다.

        mount를 위해서 offset 값을 구해야 한다. 우선 fdisk 명령으로 시작 sector (Start)와 크기(Secror size)를 구한다.

        $ sudo fdisk -l 2021-05-07-raspios-buster-armhf-lite.img
        Disk 2021-05-07-raspios-buster-armhf-lite.img: 1.75 GiB, 1874853888 bytes, 3661824 sectors
        Units: sectors of 1 * 512 = 512 bytes
        Sector size (logical/physical): 512 bytes / 512 bytes
        I/O size (minimum/optimal): 512 bytes / 512 bytes
        Disklabel type: dos
        Disk identifier: 0x9730496b
        
        Device                                    Boot  Start     End Sectors  Size Id Type
        2021-05-07-raspios-buster-armhf-lite.img1        8192  532479  524288  256M  c W95 FAT32 (LBA)
        2021-05-07-raspios-buster-armhf-lite.img2      532480 3661823 3129344  1.5G 83 Linux
        

        8192에 512를 곱한 수를 offset으로 사용한다.

        $ sudo mount -o loop,offset=$((8192*512)) 2021-05-07-raspios-buster-armhf-lite.img /mmt/test
        

        2021년 5월 31일

        Debian/key scancode 확인하기

        udev의 hwdb를 이용해 키를 변경하려면 key scancode를 확인해야 한다. evtest를 실행하고 입력 장치를 고른 후 키를 누르면 key scancode를 확인할 수 있다.

        $ evtest
        No device specified, trying to scan all of /dev/input/event*
        Not running as root, no devices may be available.
        Available devices:
        /dev/input/event0:      AT Translated Set 2 keyboard
        ...
        /dev/input/event17:     Apple Wireless Trackpad
        /dev/input/event18:     Logitech K760 Keyboard
        ..
        Select the device event number [0-20]: 18
        ...
        Event: time 1622111951.465432, -------------- SYN_REPORT ------------
        Event: time 1622111957.763084, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
        Event: time 1622111957.763084, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
        Event: time 1622111957.763084, -------------- SYN_REPORT ------------
        Event: time 1622111957.967015, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70006
        Event: time 1622111957.967015, type 1 (EV_KEY), code 46 (KEY_C), value 1
        Event: time 1622111957.967015, -------------- SYN_REPORT ------------
        

        value 뒤의 값이 key scancode다.

        2021년 5월 27일

        Debian/Logitech K760 설정

        F1 ~ F12는 할당된 특수키 (화면 밝기 조절, 음량 조절 등)가 기본 값이고 펑션키(F1~F12)는 FN 키와 같이 눌러야 동작한다. 이것을 펑션키를 기본으로 하도록 설정한다.

        k760_conf 설치

        github에서 소스를 받아서 k760_conf을 설치한다.

        $ git clone https://github.com/neoesque/k760-linux-fn-conf
        $ cd k760-linux-fn-conf
        $ ./build.sh
        $ chmod +x k760_conf
        $ sudo cp k760_conf /usr/local/bin/
        

        수동으로 설정 변경

        아래와 같은 스크립트를 만들어 root 권한으로 실행하면 펑션키가 기본으로 동작하게 된다. 단, 장치를 다시 연결하면 설정이 초기화 되기 때문에 매번 다시 실행해줘야 한다.

        #!/bin/bash
        
        found=0
        hidraw_name=
        for x in /sys/class/hidraw/hidraw*; do
                for y in $x/device/input/input*; do
                        found=$(cat $y/name | grep "Logitech K760" | wc --lines)
                        if [ $found -gt 0 ]; then
                                break;
                        fi;
                done;
                if [ $found -gt 0 ]; then
                        hidraw_name=$(echo $x | sed -e 's/\/sys\/class\/hidraw\//\/dev\//')
                        break;
                fi;
        done;
        
        if [ "$hidraw_name" != "" ]; then
                echo "/usr/local/bin/k760_conf -d $hidraw_name -f off"
                /usr/local/bin/k760_conf -d $hidraw_name -f off
        fi;

        장치 연결시 자동으로 설정

        udev rule을 이용해서 K760이 연결되면 자동으로 k760_conf를 실행하게 만든다.

        /etc/bluetooth/input.conf에서 UserspaceHID 가 true/false 에 따라서 설정 방법이 조금 달라진다

        UserspaceHID==true

        k760_udev_userland.sh

        아래와 같은 내용으로 /usr/local/bin/k760_udev_userland.sh 파일을 만든다.

        #!/bin/bash
        
        LOGFILE=/tmp/logfile_k760sh.log
        echo "RUN: at `date` by `whoami` act=$ACTION param=$1 DEVPATH=$DEVPATH DEVNAME=$DEVNAME" >> ${LOGFILE}
        
        if [ "$ACTION" == "add" ];
        then
            for inp in /sys/class/hidraw/hidraw$1/device/input/*; do
                model_name=`cat $inp/name`
                if [ "$model_name" == "Logitech K760 Keyboard" ]; then
                    echo "CONF: /usr/local/bin/k760_conf -d /dev/hidraw$1 -f off" >> ${LOGFILE}
                    /usr/local/bin/k760_conf -d /dev/hidraw$1 -f off
                    break
                fi
            done
        fi

        실행 속성을 부여한다.

        $ sudo chmod +x /usr/local/bin/k760_udev_userland.sh
        

        udev rule 작성

        아래와 같은 내용의 /etc/udev/rules.d/99-k760.rules 파일을 만든다.

        KERNEL=="hidraw*", SUBSYSTEM=="hidraw", RUN+="/usr/local/bin/k760_udev_userland.sh %n"

        udev rule을 다시 읽는다.

        $ sudo udevadm control --reload-rules
        

        K760을 다시 연결한다.

        UserspaceHID=false

        k760_udev.sh

        아래와 같은 내용으로 /usr/local/bin/k760_udev.sh 파일을 만든다.

        #!/bin/bash
        
        LOGFILE=/tmp/logfile_k760sh.log
        echo "RUN: at `date` by `whoami` act=$ACTION param=$1 DEVPATH=$DEVPATH DEVNAME=$DEVNAME" >> ${LOGFILE}
        
        if [ "$ACTION" == "add" ];
        then
            echo "CONF: /usr/local/bin/k760_conf -d $DEVNAME -f off" >> ${LOGFILE}
            /usr/local/bin/k760_conf -d $DEVNAME -f off
        fi

        실행 속성을 부여한다.

        $ sudo chmod +x /usr/local/bin/k760_udev.sh
        

        udev rule 작성

        아래와 같은 내용의 /etc/udev/rules.d/99-k760.rules 파일을 만든다.

        KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idProduct}=="0029", ATTRS{idVendor}=="8087", RUN+="/usr/local/bin/k760_udev.sh %p"

        udev rule을 다시 읽는다.

        $ sudo udevadm control --reload-rules
        

        K760을 다시 연결한다.

        Fn+F4, Fn+F6, Fn+F7 키 보정

        위 작업을 끝낸 후 Fn+F4, Fn+F6, Fn+F7 키를 눌러보면 제대로 동작하지 않는다(Fn+F5는 XF86Home 키로 동작한다). Fn+F4, Fn+F6, Fn+F7의 scancode를 적당한 keycode로 바꿔줘야 한다.

        그리고 [alt][command][space][command][alt] 배열을 PC계열 키보드처럼 [win][alt][space][alt][menu] 로 바꿔준다.

        udev hwdbhttps://wiki.archlinux.org/title/Map_scancodes_to_keycodes를 이용하기 위해 아래와 같은 내용으로 /etc/udev/hwdb.d/99-k760.hwdb 파일을 만든다.

        # Logitech K760 map:
        # Fn + F4 -> scale
        # Fn + F6 -> brightnessdown
        # Fn + F7 -> birghtnessup
        # LWin -> LAlt
        # LAlt -> LWin
        # RWin -> RAlt
        # RAlt -> Menu
        evdev:input:b0005v046DpB316*
          KEYBOARD_KEY_700e0=scale
          KEYBOARD_KEY_70047=brightnessdown
          KEYBOARD_KEY_70048=brightnessup
          KEYBOARD_KEY_700e3=leftalt
          KEYBOARD_KEY_700e2=leftmeta
          KEYBOARD_KEY_700e7=rightalt
          KEYBOARD_KEY_700e6=compose

        파일이 만들어졌으면 hwdb를 갱신한다.

        $ sudo systemd-hwdb update
        $ sudo udevadm trigger
        

        적용 후 잠시 기다리면 Fn-F4, Fn-F7, Fn-F8이 원하는 키로 동작한다.

        2021년 5월 19일

        Debian/Cloudflare Warp VPN 설정

        Debian Linux에서 Cloudflare Warp VPN을 사용하는 방법을 기술한다.

        설치

        아래 패키지를 설치한다.

        $ sudo apt install resolvconf wireguard-tools
        
        https://github.com/ViRb3/wgcf에서 wgcf 을 받는다.

        VPN 설정

        아래 명령을 입력해서 wgcf-profile.conf 파일을 만든다.

        $ wgcf register
        $ wgcf generate
        

        만들어진 wgcf-profile.conf 파일을 /etc/wireguard에 복사한다.

        $ sudo cp wgcf-profile.conf /etc/wireguard
        

        사용 방법

        VPN 사용

        $ sudo wg-quick up wgcf-profile
        

        curl을 이용해서 연결이 잘 되었는지 확인할 수 있다.

        $ curl --silent https://www.cloudflare.com/cdn-cgi/trace | grep warp=
        warp=on
        

        VPN 중지

        $ sudo wg-quick down wgcf-profile
        

        2021년 4월 10일

        Debian/Apple Keyboard, Apple Wireless Touchpad 설정

        아래 몇가지 설정을 적용하면 Apple Bluetooth Keyboard와 Apple Wireless Touchpad를 좀 더 편하게 사용할 수 있다.

        F1 ~ F12 설정

        F1 ~ F12는 할당된 특수키 (화면 밝기 조절, 음량 조절 등)가 기본 값이고 펑션키(F1~F12)는 FN 키와 같이 눌러야 동작한다. 이것을 펑션키를 기본으로 하도록 변경한다.

        
        $ echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode
        

        부팅할 때 기본값을 변경하려면 아래와 같은 내용으로 /etc/modprobe.d/hid_apple.conf파일을 만든다.

        options hid_apple fnmode=2

        탭을 클릭으로

        탭을 클릭으로 설정하고 스크롤 방향을 MacOS 처럼 설정하기 위해, 아래 내용으로 /etc/X11/xorg.conf.d/apple_wireless_trackpad.conf 파일을 만들고 X를 다시 시작한다(간단하게는 재부팅).

        Section "InputClass"
            Identifier "Apple Wireless Touchpad"
            MatchProduct "Apple Wireless Touchpad"
            MatchDriver "libinput"
            Option "Tapping" "on"
            Option "Natural Scrolling" "on"
        EndSection

        연결이 불규칙하게 끊어질때

        /etc/bluetooth/input.conf 에서 serspaceHID=true 설정 후 재부팅한 뒤 문제가 없는지 확인해본다.

        만약 문제가 발생하면 아래와 같이 설정 변경 후 문제가 없는지 확인해본다.

        $ echo 1 | sudo tee /sys/module/bluetooth/parameters/disable_esco
        $ sudo systemctl restart bluetooth.service
        

        문제가 없다면 다음 부팅때도 적용할 수 있게 설정한다.

        $ echo "options bluetooth disable_esco=1" | sudo tee /etc/modprobe.d/bluetooth.conf
        

        2021년 3월 20일

        Debian/한성 TFX5670H에 각종 도구 설치

        한성 TFX5670H는 칭화통팡의 Tongfang PF5NU1G 제품을 사용한다. 동일한 모델을 KDE SlimbookTUXEDO Pulse 15 제품에서도 사용하는데, TUXEDO Computer github에서 Linux 에서 사용할 수 있는 드라이버와 툴을 제공한다.

        Touchpad

        Touchpad의 상태 표시 LED를 사용할 수 있게 한다.

        $ git clone https://github.com/tuxedocomputers/tuxedo-touchpad-switch
        $ cd tuxedo-touchpad-switch/
        $ sudo apt install libudev-dev libglib2.0-dev git-buildpackage debhelper
        $ rm -r build
        $ gbp buildpackage -uc -us
        $ cd ..
        $ sudo dpkg -i tuxedo-touchpad-switch_1.0.1_amd64.deb
        

        설치 후 재부팅한다.

        TUXEDO Control Center

        module 설치

        control center에서 사용하는 드라이버는 tuxedo-keyboard 에 포함되어 있다.

        $ git clone https://github.com/tuxedocomputers/tuxedo-keyboard.git
        $ cd  https://github.com/tuxedocomputers/tuxedo-keyboard.git
        $ make
        $ make package-deb
        $ sudo dpkg -i tuexdo-keyboard-3.0.3.deb
        $ cd dist/packages/
        

        SecureBoot를 쓴다면 sign도 한다(key는 /etc/refind.d/keys/refind_local.* 로 저장했고 MOK에 등록했다고 가정한다).

        $ for x in clevo_acpi.ko clevo_wmi.ko tuxedo_cc_wmi.ko tuxedo_io.ko tuxedo_keyboard.ko; do sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.der  /lib/modules/$(uname -r)/updates/dkms/$x; done;
        

        TUXEDO Control Center 설치

        빌드 환경은 docker를 이용해서 구성했다. node가 설치되어 있다면 설치되어 있는 node를 사용해도 된다.

        $ docker pull node:current-buster
        $ git clone https://github.com/tuxedocomputers/tuxedo-control-center.git
        $ cd https://github.com/tuxedocomputers/tuxedo-control-center.git
        $ docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/app -w /app node:current-buster npm install
        $ docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/app -w /app node:current-buster npm run pack-prod deb
        $ sudo apt install libappindicator3-1
        $ cd dist/packages/
        $ sudo dpkg -i tuxedo-control-center_1.0.11.deb 
        

        2021년 3월 9일

        KDE/qdbus로 단축키에 해당하는 기능 실행하기

        KDE에서 fusuma를 이용해 trackpad 제스쳐를 설정할때 xdotool을 사용해 KDE 단축키를 누른 것과 같은 효과를 낼 수 있다. 다만 이때 가상머신등을 사용하는 경우 단축키를 가상머신에서 받아들이기 때문에 원하는 단축키 실행이 되지 않을 수 있다. 이때는 xdotool 대신 qdbus을 이용해 KDE 단축키에 해당하는 기능을 바로 실행하면 문제가 해결된다.

        단축키를 가지는 component 목록 얻기

        $ qdbus org.kde.kglobalaccel
        

        모든 단축기 정보 얻기

        $ qdbus --literal org.kde.kglobalaccel /component/plasmashell allShortcutInfos | bat -l json 
        

        실행

        $ qdbus org.kde.kglobalaccel /component/plasmashell invokeShortcut activate\ widget\ 200
        

        자주 쓰는 단축키

        시작 메뉴

        $ qdbus org.kde.kglobalaccel /component/plasmashell invokeShortcut activate\ widget\ 200
        

        Expose All

        $ qdbus org.kde.kglobalaccel /component/kwin invokeShortcut ExposeAll
        

        Expose

        $ qdbus org.kde.kglobalaccel /component/kwin invokeShortcut Expose
        

        Latte Dock 첫번째 항목 활성

        $ qdbus org.kde.kglobalaccel /component/lattedock invokeShortcut activate\ entry\ 1
        

        2021년 2월 11일

        Wine/Total Commander

        Wine에 Total Commander를 설치해서 사용할 때 Linux 시스템과 연동하는 몇가지 방법을 기술한다.

        설정 파일 인코딩 수정

        Total commander 설치 위치의 *.bar*.ini파일의 인코딩을 UTF-16BE with BOM

        Linux 프로그램 실행

        적당한 경로에 linuxcaller.sh파일을 만든다(/home/user1/.local/bin/linuxcaller.sh로 생성했다고 가정한다).

        #!/bin/sh
        
        if [ $# -lt 2 ]; then
                exit 0
        fi
        cmd=$1
        filename=`wine winepath -u "$2"`
        shift
        shift
        "$cmd" "$filename" $*

        아래와 같이 버튼바에 등록해서 사용한다.

        확장자 기본 프로그램 연결

        적당한 경로에 tc_open.sh파일을 만든다(/home/user1/.local/bin/tc_open.sh로 생성했다고 가정한다).

        #!/bin/sh
        if [ $# -eq 0 ]; then
                exit 0
        fi
        
        /usr/bin/xdg-open "`wine winepath -u "$1"`"

        Total Commander에서 파일 - 내부 확장자 연결 메뉴를 선택하고 *.*를 추가하고 아래와 같이 등록한다.

        현재 경로를 konsole에서 열기

        적당한 경로에 tc_konsole.sh파일을 만든다(/home/user1/.local/bin/tc_konsole.sh로 생성했다고 가정한다).

        #!/bin/sh
        if [ $# -lt 1 ]; then
                exit 0
        fi
        workdir=`wine winepath -u "$1"`
        shift
        konsole --workdir "$workdir" $*

        버튼바에 버튼을 추가하고 아래와 같이 설정한다.

        Reference

        2021년 2월 9일

        Debian/ufw 설정

        ufw 기본 설정은 모든 나가기는 허용하고 모든 들어오기는 차단한다. 사용상 편의를 위해서 local network(192.168.0.0/24) 에서만 일부 들어오기 허용규칙을 추가 한다.

        파일 공유

        가상 머신(libvirt)에서 파일 공유 접근 허용 규칙을 추가한다.

        $ sudo ufw allow in on virbr0 to any app CIFS comment "CIFS on virbr0"
        

        local network 허용 규칙을 추가한다.

        $ sudo ufw allow from 192.168.0.0/24 to any app CIFS
        

        RDP

        포트를 직접 지정해도 되지만, app profile을 만들어 두는게 편리하다. root 권한으로 아래 내용과 같은 /etc/ufw/applications.d/RDP 파일을 만든다.

        [RDP]
        title=RDP
        description=Remote Desktop Protocol
        ports=3389

        ufw 규칙을 다시 읽는다.

        $ sudo ufw reload
        

        local network 허용 규칙을 추가한다.

        $ sudo ufw allow from 192.168.0.0/24 to any app RDP
        

        app profile을 만들지 않고 규칙을 추가하려면 아래와 같이 한다.

        $ sudo ufw allow from 192.168.0.0/24 to any port 3389 comment RDP
        

        KDEConnect

        포트를 직접 지정해도 되지만, app profile을 만들어 두는게 편리하다. root 권한으로 아래 내용과 같은 /etc/ufw/applications.d/kdeconnect 파일을 만든다.

        [KDEConnect]
        title=KDE Connect
        description=Remote smartphone control
        ports=1714:1764/tcp|1714:1764/udp

        ufw 규칙을 다시 읽는다.

        $ sudo ufw reload
        

        local network 허용 규칙을 추가한다.

        $ sudo ufw allow from 192.168.0.0/24 to any app KDEConnect
        

        app profile을 만들지 않고 규칙을 추가하려면 아래와 같이 한다.

        $ sudo ufw allow from 192.168.0.0/24 to any proto tcp port 1714:1764 comment "KDE Connect"
        $ sudo ufw allow from 192.168.0.0/24 to any proto udp port 1714:1764 comment "KDE Connect"
        

        2021년 1월 27일

        Debian/KDE에 xrdp 환경 설정

        KDE에 xrdp 환경을 설정한다.

        xrdp

        설치

        $ sudo apt install xrdp
        

        설정

        xrdp

        /etc/xrdp/xrdp.ini에 아래 내용을 추가한다.

        [x11vnc]
        name=x11vnc
        lib=libvnc.so
        ip=127.0.0.1
        port=5900
        username=na
        pamusername=ask
        pampassword=ask
        pamsessionmng=127.0.0.1

        설정이 끝나면 xrdp 서버를 재시작한다.

        $ sudo systemctl restart xrdp
        

        방화벽

        192.168.0.x 대역에서만 접속할 수 있게 방화벽을 설정한다.

        $ sudo ufw allow from 192.168.0.0/24 to any port 3389 comment RDP
        

        x11vnc

        xrdp에서 사용할 x11vnc 서버를 설정한다. KDE의 krfb를 사용하면 한글 입력시 자소가 분리된다.

        설치

        $ sudo apt install x11vnc
        

        systemd 설정

        아래 명령으로 x11vnc.service 파일을 편집한다.

        $ sudo systemctl edit --force --full x11vnc.service
        

        파일 내용은 아래와 같다. xrdp에서만 접속하기 때문에 -localhost옵션을 넣었고 비밀번호를 사용하지 않기 위해 -nopw옵션을 사용했다.

        [Unit]
        Description=x11vnc server for SDDM
        Requires=display-manager.service
        After=display-manger.service
        
        [Service]
        ExecStartPre=/bin/bash -c 'while ! find /var/run/sddm -type f; do sleep 2; done' 
        ExecStart=/bin/bash -c "/usr/bin/x11vnc -display :0 -auth $(/usr/bin/find /var/run/sddm/ -type f) -nopw -shared -xkb -norepeat -noxrecord -noxdamage -localhost -no6 -loop -forever"
        
        [Install]
        WantedBy=graphical.target

        테스트

        적당한 RDP client를 사용해 접속이 잘되는지 확인한다.

        자동 실행 설정

        재부팅 후 자동 실행하도록 설정한다.

        
        $ sudo systemctl enable x11vnc.service
        

        입력기 설정

        RDP Client 에 따라서 오른쪽 alt 키나 한/영 키가 동작 안할 수 있기 때문에, 사용하는 입력기 설정에서 한/영 전환 키에 shift+space를 추가해둔다.

        2021년 1월 13일

        Debian/UltraNav Travel 터치 패드 설정

        탭 클릭과 스크롤 방향을 자연스럽게 바꾸도록 설정한다.

        xinput을 사용해서 UltrNav의 터치 패드 장치를 찾는다.

        $ xinput list
        ⎡ Virtual core pointer                          id=2    [master pointer  (3)]
        ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
        ⎜   ↳ UNIW0001:00 093A:0255 Mouse               id=12   [slave  pointer  (2)]
        ⎜   ↳ UNIW0001:00 093A:0255 Touchpad            id=13   [slave  pointer  (2)]
        ⎜   ↳ Synaptics Inc. Composite TouchPad / TrackPoint (Stick)    id=15   [slave  pointer  (2)]
        ⎜   ↳ 2.4G Mouse                                id=16   [slave  pointer  (2)]
        ⎜   ↳ Synaptics Inc. Composite TouchPad / TrackPoint    id=20   [slave  pointer  (2)]
        ⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
            ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
            ↳ Power Button                              id=6    [slave  keyboard (3)]
            ↳ Video Bus                                 id=7    [slave  keyboard (3)]
            ↳ Power Button                              id=8    [slave  keyboard (3)]
            ↳ Lid Switch                                id=9    [slave  keyboard (3)]
            ↳ Sleep Button                              id=10   [slave  keyboard (3)]
            ↳ HD Webcam: HD Webcam                      id=11   [slave  keyboard (3)]
            ↳ AT Translated Set 2 keyboard              id=14   [slave  keyboard (3)]
            ↳ Lite-On Tech IBM USB Travel Keyboard with UltraNav Consumer Control       id=17   [slave  keyboard (3)]
            ↳ Lite-On Tech IBM USB Travel Keyboard with UltraNav        id=18   [slave  keyboard (3)]
            ↳ Lite-On Tech IBM USB Travel Keyboard with UltraNav System Control id=19   [slave  keyboard (3)]
        

        찾은 장치에서 Tapping, Natural Scrolling 속성이 있는지 찾아본다.

        $ xinput list-props "Synaptics Inc. Composite TouchPad / TrackPoint" | grep -i "Tapping Enabled"
                libinput Tapping Enabled (304): 0
                libinput Tapping Enabled Default (305): 0
        $ xinput list-props "Synaptics Inc. Composite TouchPad / TrackPoint" | grep -i "Natural Scrolling Enabled"
                libinput Natural Scrolling Enabled (286):       0
                libinput Natural Scrolling Enabled Default (287):       0
        

        xinput으로 속성을 바꾸고 원하는대로 동작하는지 확인한다.

        $ xinput set-prop "Synaptics Inc. Composite TouchPad / TrackPoint" "libinput Tapping Enabled" 1
        $ xinput set-prop "Synaptics Inc. Composite TouchPad / TrackPoint" "libinput Natural Scrolling Enabled" 1
        

        다음에 X를 다시시작해도 적용하기 위해서 아래 내용으로 /etc/X11/xorg.conf.d/ultranav.conf 파일을 만든다.

        Section "InputClass"
            Identifier "Synaptics Inc. Composite TouchPad / TrackPoint"
            MatchProduct "Synaptics Inc. Composite TouchPad / TrackPoint"
            MatchDriver "libinput"
            Option "Tapping" "on"
            Option "Natural Scrolling" "on"
        EndSection

        2020년 11월 29일

        KDE/일출, 일몰에 따라 자동으로 테마 변경하기

        KDE에는 일출, 일몰에 따라 자동으로 테마를 변경하는 설정이 없어서 따로 스크립트를 만들어서 변경한다.

        일몰, 일출 시간을 얻기 위해서 python3-astral 패키지를 설치한다.

        $ sudo apt install python3-astral
        

        아래 python 스크립트를 ~/.local/bin/lookandfeel_change.py 으로 저장한다.

        #!/usr/bin/env python3
        # -*- coding: utf-8 -*-
        # vim:set expandtab fenc=utf-8 ff=unix:
        
        import os
        import logging
        import datetime
        import subprocess
        import argparse
        from astral import Astral  # type:ignore
        
        
        logging.basicConfig(format='[%(asctime)s]{%(name)s}(%(levelname)s) %(message)s', level=logging.INFO)
        logger = logging.getLogger(os.path.basename(__file__))
        KST = datetime.timezone(datetime.timedelta(hours=9))
        
        DARK_THEME = 'org.kde.breezedark.desktop'
        LIGHT_THEME = 'org.kde.breeze.desktop'
        
        
        def kreadconfig(group: str, key: str) -> str:
            p = subprocess.run(['/usr/bin/kreadconfig5', '--group', group, '--key', key],
                               capture_output=True)
            return p.stdout.decode('utf-8').strip()
        
        
        def kwriteconfig(group: str, key: str, value: str):
            p = subprocess.run(['/usr/bin/kwriteconfig5', '--group', group, '--key', key, value],
                               capture_output=True)
            logger.debug(p.stdout.decode('utf-8').strip())
            logger.debug(p.stderr.decode('utf-8').strip())
        
        
        def apply_theme(theme: str):
            p = subprocess.run(['/usr/bin/lookandfeeltool', '-a', theme], capture_output=True)
            logger.debug(p.stdout.decode('utf-8').strip())
            logger.debug(p.stderr.decode('utf-8').strip())
            kwriteconfig('KDE', 'LookAndFeelPackage', theme)
        
        
        def main():
            ast = Astral()
            city = ast['Seoul']
            now = datetime.datetime.now(tz=KST)
            today = city.sun(date=now, local=True)
            logger.debug(f'{today["sunrise"]} <= {now} < {today["sunset"]}')
        
            new_theme = DARK_THEME
            if (today['sunrise'] <= now < today['sunset']):
                new_theme = LIGHT_THEME
        
            cur_theme = kreadconfig('KDE', 'LookAndFeelPackage')
        
            if cur_theme != new_theme:
                apply_theme(new_theme)
                logger.debug(f'apply {new_theme}')
            else:
                logger.debug(f'already applied {cur_theme}')
        
        
        if __name__ == '__main__':
            parser = argparse.ArgumentParser(description='일출/일몰시간을 기준으로 Plasma 테마를 변경')
        
            parser.add_argument('--debug', '-d', action='store_true')
        
            options = parser.parse_args()
        
            if options.debug:
                logger.setLevel(logging.DEBUG)
        
            main()

        저장 후 실행 속성을 준다.

        $ chmod +x ~/.local/bin/lookandfeel_change.py
        

        이대로 cron에 등록하면 제대로 동작하지 않는다. cron으로 실행하는 경우 login 했을 때와 환경 변수 구성이 다르기 때문이다. 아래 script를 ~/.local/bin/lookandfeel_change.sh으로 저장한다.

        #!/bin/bash
        
        export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/계정id/bus
        export DESKTOP_SESSION=plasma
        export DISPLAY=:0
        export PATH=/home/계정명/.local/bin:/usr/local/bin/:/usr/local/bin:/usr/bin:/bin:/usr/games
        export SHELL=/bin/bash
        export XDG_CURRENT_DESKTOP=KDE
        export XDG_RUNTIME_DIR=/run/user/계정id
        export XDG_DATA_DIRS=/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
        
        /home/계정명/.local/bin/lookandfeel_change.py

        계정id는 id 명령으로 확인할 수 있다. Debian 계열인 경우 첫번째로 추가한 사용자 id는 보통 1000 이다.

        $ id
        

        저장 후 실행 속성을 준다.

        $ chmod +x ~/.local/bin/lookandfeel_change.sh
        

        이제 10분마다 실행할 수 있게 crontab에 등록한다.

        */10 * * * * /home/계정명/.local/bin/lookandfeel_change.sh