반응형

OS: Ubuntu 14.04



Xrdp를 이용해서 xfce4 세션을 사용하는 원격 데스크탑에 로그인하는 것은 잘 되는데, 사용이 끝나고 나서 로그아웃을 하려고 하면 상단의 작업표시줄 패널과 창, 아이콘들만 사라지고 바탕화면이 그대로 남은 채 더이상 진행되지 못하는 문제가 있다.



그림 1. xfce4에서 우측 상단의 사용자 계정명을 눌러서 나오는 로그아웃 메뉴를 통해서

위의 화면에서 Log Out 버튼을 눌러도 로그아웃이 되지 않는 문제가 있다.



이 문제에 대해서 여러 사용자들이 우분투 커뮤니티를 비롯한 여러 곳에 질문을 올렸지만, 어느 곳에서도 근본적인 해결책을 찾을 수 없었다. xfce4 개발자가 해결해 주어야 하는데, 몇 년째 별다른 진전이 없는 것 같다. ㅠㅠ


만약 xfce4 세션을 완전히 로그아웃시키지 못하면 결국 위와 같이 세션 하나가 바탕화면만 남겨진 먹통 상태로 남겨진 채 메모리와 포트 번호(XRDP 설정에 따라 다르지만 보통 5910부터 시작)를 더이상 사용하지 못하게 되고, 다음에 다시 원격 데스크탑을 쓰려면 새로운 포트 번호를 할당받는 새로운 세션을 만들어야만 한다.


좋은 방법은 아니지만, 아예 세션을 강제로 종료시키는 방법으로 해결할 수는 있다.

$ killall --user $USER -TERM


또는 직접 사용자 계정명을 지정해도 된다. (예: odroid)

$ killall --user odroid -TERM



주의사항:

위와 같이 하면, xfce4 뿐만 아니라 해당 사용자 계정으로 켜져 있는 터미널 세션까지 모두 다 종료되어 버린그래도 터미널 세션은 다시 ssh로 접속하면 되므로원격 머신을 재부팅하기는 싫고 좀비 상태로 남은 xfce4 세션을 정리하고 싶다면 이 방법이 그나마 효과적일 것이다.



<참고자료>

[1] https://bbs.archlinux.org/viewtopic.php?id=159958



반응형
블로그 이미지

Bryan_

,
반응형

무선 메쉬 네트워크에서 멀티홉 라우팅을 하면서, 라우팅을 해야 되는 flow가 아래와 같이 다르면, iptables를 쓸 때에도 필터링을 서로 다른 곳에서 해 주어야 한다:


1) 다른 노드가 source가 되고, 현재의 메쉬 라우터는 중간 노드가 되는 경우

2) (실제로 그럴 일은 별로 없겠지만) 메쉬 라우터 자체에서 패킷이 생성되었을 경우, 즉 메쉬 라우터 자신이 출발지 노드(source)가 돼서 응용 계층으로부터 패킷이 주입되는 경우


특정 포트 또는 목적지로 가는 패킷을 필터링/분류하고 라우팅을 변경하고자 할 때:

- 1번의 경우에는 PREROUTING 단계에서 hook을 걸어야 패킷이 걸린다.

- 2번의 경우는 OUTPUT 단계에 hook을 걸어야 패킷이 걸린다.



<2016.07.17 추가>


내가 하려는 작업은:

  • 멀티홉 라우팅 경로에서 중간노드 역할을 수행하는 라우터가 특정 조건의 패킷에 대하여 마킹을 한다. (--set-mark 옵션)
  • 특정 번호로 마팅된 패킷에 대응하는 별도의 라우팅 테이블을 만들어서 해당 패킷들만을 위한 라우팅 경로를 설정한다.


이 작업을 수행하려면 iptables에서 mangle 테이블을 써야 하고, 이 때 PREROUTING, OUTPUT 체인이 갖는 의미는 참고자료 [1] 에 잘 설명되어 있다.



<참고자료>

[1] http://marcof.tistory.com/35

반응형
블로그 이미지

Bryan_

,
반응형

OS: Raspbian Jessie


TC는 리눅스에서 트래픽 컨트롤 기능을 제공하는 도구이고, shaping (응용 레벨에서의 data rate 설정), scheduling (패킷 전송 순서를 조절), policing (arriving traffic에 대한 제어인 듯? 자세히는 모르겠음), dropping (들어오고 나가는 패킷에 대한 drop)을 지원한다.


이렇게 여러가지 기능이 있고, traffic shaping만 해도 사용하는 queue의 종류와 옵션 설정에 따라 다양한 목적 달성이 가능한데, 일단 내 실험에서는 말그대로 "특정 어플리케이션에서 내보내는 트래픽(outgoing traffic)을 원하는 대역폭으로 제한"을 거는 것만 필요하기 때문에 이와 관련된 가장 간단한 설정 방법만 정리하게 되었다.


<NOTE>

여기 정리된 방법이 tc를 설정하는 유일한 방법이 아니고, 항상 가장 좋은 방법이 될 수는 없다. 같은 목적을 다른 큐(queue)와 다른 설정, 심지어 iptables 같은 도구와의 연동을 통해서도 달성할 수 있다. 일반론적인 얘기지만, 결국 목적과 네트워크 상황에 맞춰서 쓰는 수밖에 없다.




<조건 생성>


1. qdisc 생성하기


어떤 경우에는 qdisc를 나중에 생성하는 경우도 있던데 그냥 먼저 만들어도 상관이 없으므로 먼저 만들어 두기로 했다.

HTB (HIerarchical Token Bucket)이라는 큐를 쓸 경우의 명령어는 다음과 같다.


$ sudo tc qdisc add dev [IFNAME] root handle [ROOT_HANDLE_NO]: htb default 12


[IFNAME]은 네트워크 인터페이스 이름, 

[ROOT_HANDLE_NO]는 루트 qdisc에 대한 핸들 번호(아이디) 이다.

default 뒤에 붙는 숫자는 별 의미가 없다. 아무 조건으로도 분류되지 않는 모든 트래픽이 1:12라는 클래스에 할당된다는 의미이고, 아직 tc를 가지고 1:12라는 아이디를 갖는 class를 만들지 않았기 때문에 아무 조건 없이 보통의 트래픽처럼 처리된다.


(예)

무선랜 인터페이스(wlan0)에 대한 qdisc를 1번으로 생성:


$ sudo tc qdisc add dev wlan0 root handle 1: htb default 12




2. Class 생성하기


생성된 qdisc를 거쳐 가는 모든 트래픽을 분류하기 위해서, 분류되는 각 클래스와 그 클래스에 대한 조건(이 글에서는 traffic shaping만 설정하므로 bandwidth 제한)을 설정한다.


$ sudo tc class add dev [IFNAME] parent [ROOT_HANDLE_NO]: classid [ROOT_HANDLE_NO]:[CLASS_NO] htb rate [DATA_RATE]


[CLASS_NO]는 새로이 traffic shaping을 적용할 클래스에 붙이는 번호이고, 원하는 대로 아무 번호나 붙여도 된다. 1부터 시작해서 증가시키면 별 문제가 없을 것이다.

참고로 qdisc 생성할 때 지정한 default 번호를 염두에 두고 설정해야 한다. Default traffic에 제한을 걸고 싶지 않다면 앞서 설정한 default 클래스 번호는(qdisc 예시에서 1:12) 피해야 한다.

[DATA_RATE]는 제한을 걸 bandwidth 표현이다. 만약 100 KB/s (초당 100 킬로바이트)를 허용하는 최대치로 두고 싶다면 100kbps 라고 써야 한다. 보통 우리가 알기로 kbps는 Kilobits per second인데 여기서는 Kilobytes per seconds로 쓰이고 있으므로(왜 그렇게 했는지는 모르겠지만...) 혼동하지 말아야 한다.


(예)

무선랜 인터페이스로 나가는 트래픽 중에서 최대 대역폭 200KB/s의 제한을 갖는 클래스를 5번으로 정의하고 생성:


$ sudo tc class add dev wlan0 parent 1: classid 1:5 htb rate 200kbps




3. Filter 생성하기


클래스를 먼저 만들고, 그 뒤에 특정 클래스로 패킷을 분류시켜서 traffic shaping 효과를 내기 위한 필터를 만든다. 필터는 source IP, source port, destination IP, destination port, traffic type (TCP, UDP 등), network interface 등의 조건으로 패킷을 분류할 수 있다.


$ sudo tc filter add dev [IFNAME] protocol ip parent [ROOT_HANDLE_NO]:0 prio 1 u32 match ip src [SRC_IP] match ip sport [SPORT] match ip dst [DST_IP] match ip dport [DPORT] 0xffff flowid [ROOT_HANDLE_NO]:[CLASS_NO]

SRC_IP는 source IP주소,

SPORT는 source port number,

DST_IP는 destination IP주소,

DPORT는 destination port 이다.


조건은 모두 match로 시작하고, 조건을 걸고 싶은 경우에만 match를 명시하면 된다. 즉, source port number 조건을 걸 필요가 없으면 match ip sport [SPORT] 부분은 없어도 된다.


(예)

무선랜 인터페이스로 나가는 트래픽 중에서 도착지 IP주소 192.168.4.8, 포트번호 22에 대해서 클래스 1:5로 분류하기:


$ sudo tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.4.8 match ip dport 22 0xffff flowid 1:5


참고로 다른 조건의 트래픽을 같은 클래스에 추가로 분류시킬 수도 있다. 192.168.4.8에서 포트번호 5001도 추가로 1:5에 분류하고자 하면:


$ sudo tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.4.8 match ip dport 5001 0xffff flowid 1:5


각 명령에 대해서 아무 메세지가 출력되지 않고 쉘이 나오면 성공적으로 적용된 것이다.





<생성된 조건 확인>


생성된 qdisc, class, filter 설정이 올바른지 확인하려면 아래와 같이 입력한다:


$ sudo tc qdisc show dev [IFNAME]

$ sudo tc class show dev [IFNAME]

$ sudo tc filter show dev [IFNAME]



실제 생성된 설정 예시:


pi@raspberrypi ~/exp $ sudo tc qdisc show dev wlan0

qdisc htb 1: root refcnt 5 r2q 10 default 12 direct_packets_stat 13267 direct_qlen 1000


pi@raspberrypi ~/exp $ sudo tc class show dev wlan0

class htb 1:5 root prio 0 rate 400Kbit ceil 400Kbit burst 1600b cburst 1600b 


pi@raspberrypi ~/exp $ sudo tc filter show dev wlan0
filter parent 1: protocol ip pref 1 u32 
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1 
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:5 
  match c0a80408/ffffffff at 16
  match 00000016/0000ffff at 20
filter parent 1: protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:5 
  match c0a80408/ffffffff at 16
  match 00001389/0000ffff at 20

참고로 필터는 위의 생성 예시에서 192.168.4.8:22 및 192.168.4.8:5001 두 개의 조건을 걸었기 때문에 필터 핸들 번호를 기준으로 800:800과 800::8001 이렇게 두 개가 생성되어 있음을 알 수 있다. filter를 입력할 때는 10진수로 조건을 입력했지만 show 에서는 match 부분이 16진수로 표현되어 있다. 잘 보면 윗 라인은 IP주소, 아래 라인은 포트번호이다.





<조건 삭제>


보통은 filter와 class를 삭제하면 설정한 트래픽 제한이 사라진다. 삭제는 생성의 역순으로 해야 한다. qdisc는 굳이 삭제하지 않아도 트래픽에 대한 조건은 모두 사라지므로, 향후 다시 설정하고자 하는 경우 클래스까지만 삭제하면 된다.


$ sudo tc filter del dev [IFNAME] parent [ROOT_HANDLE_NO]: handle [FILTER_HANDLE] pref 1 u32

$ sudo tc class del dev [IFNAME] classid [ROOT_HANDLE_NO]:[CLASS_NO]

$ sudo tc qdisc del dev [IFNAME]


[FILTER_HANDLE]은 위의 생성된 조건을 확인할 때 표시되는 필터 핸들 번호(filter handle)이고, 필자의 경우에는 거의 다 800::800 부터 시작하는 번호가 할당됐다. 필터 핸들을 쓰지 않고, filter를 생성할 때 입력했던 라인을 그대로 가져와서 add만 del로 바꾸게 되면, 놀랍게도 그 외에 설정했던 필터들이 모두 다 같이 삭제되는 현상을 볼 수 있다. 왜 그런지는 모르겠지만, 같은 문제를 호소하는 질문과 그 해결책으로 필터 핸들 번호를 이용한 삭제 방법이 StackOverflow 페이지에 제시되어 있다 [2].




<조건 변경>


add 대신 change를 쓰면 기존에 생성한 조건을 변경할 수 있다.

qdisc는 바꿀 일이 별로 없으므로 넘어가고, 클래스의 경우는 이미 할당된 번호와 parent를 변경할 수는 없고 rate 조정은 가능하다.


$ sudo tc class change dev [IFNAME] parent [ROOT_HANDLE_NO]: classid [ROOT_HANDLE_NO]:[CLASS_NO] htb rate [DATA_RATE]


(예)

기존에 생성한 1:5 클래스의 bandwidth를 50KB/s로 변경할 경우:


$ sudo tc class change dev wlan0 parent 1: classid 1:5 htb rate 50kbps



TC가 잘 설정되었는지 확인하는 방법 중 하나로, iperf를 쓰는 방법이 있다. iperf는 받는 쪽에서 -s 옵션으로 받는 패킷에 대한 통계를 내고, 보내는 쪽에서 -c 옵션과 목적지 IP주소를 입력해서 최대 bandwidth를 측정할 수 있다.



보내는 쪽 예시:
먼저 200KB/s (1.6Mbps)로 클래스의 대역폭을 설정했다가, 나중에 50KB/s (400Kbps)로 변경한 경우이다.

pi@raspberrypi ~/exp $ sudo tc qdisc add dev wlan0 root handle 3: htb default 12

pi@raspberrypi ~/exp $ sudo tc class change dev wlan0 parent 1: classid 1:5 htb rate 200kbps 

pi@raspberrypi ~/exp $ sudo tc filter add dev wlan0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.4.8 match ip dport 5001 0xffff flowid 1:5

pi@raspberrypi ~/exp $ iperf -c 192.168.4.8

------------------------------------------------------------

Client connecting to 192.168.4.8, TCP port 5001

TCP window size: 43.8 KByte (default)

------------------------------------------------------------

[  3] local 192.168.4.6 port 55182 connected with 192.168.4.8 port 5001

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-10.8 sec  2.00 MBytes  1.56 Mbits/sec

pi@raspberrypi ~/exp $ sudo tc class change dev wlan0 parent 1: classid 1:5 htb rate 50kbps

pi@raspberrypi ~/exp $ iperf -c 192.168.4.8

------------------------------------------------------------

Client connecting to 192.168.4.8, TCP port 5001

TCP window size: 43.8 KByte (default)

------------------------------------------------------------

[  3] local 192.168.4.6 port 55183 connected with 192.168.4.8 port 5001

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-12.7 sec   640 KBytes   414 Kbits/sec

pi@raspberrypi ~/exp $


iperf의 기본 포트인 5001에 대해서 필터를 걸었더니, 보내는 트래픽이 처음에는 약 1.6Mbps로 전송되다가, 클래스를 수정한 뒤에는 약 400Kbps의 대역폭을 가짐을 볼 수 있다.



받는 쪽 예시:


cdsn@cdsn-ThinkPad-X200:~$ iperf -s

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 85.3 KByte (default)

------------------------------------------------------------

[  4] local 192.168.4.8 port 5001 connected with 192.168.4.6 port 55182

[ ID] Interval       Transfer     Bandwidth

[  4]  0.0-11.0 sec  2.00 MBytes  1.53 Mbits/sec

[  5] local 192.168.4.8 port 5001 connected with 192.168.4.6 port 55183

[  5]  0.0-13.7 sec   640 KBytes   384 Kbits/sec


받는 쪽에서도 보내는 쪽의 tc 설정대로 처음에는 약 1.6Mbps 정도의 incoming traffic을 보이다가, tc 설정을 변경한 이후에는 약 400Kbps 정도의 낮은 속도로 패킷이 도착했음을 확인할 수 있다.





<참고자료>

[1] HTB Linux queuing discipline manual - user guide, http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm

[2] TC hashing filters - single rule deletion, http://serverfault.com/questions/330581/tc-hashing-filters-single-rule-deletion


반응형
블로그 이미지

Bryan_

,
반응형

Test OS: Ubuntu 16.04 Server (amd64)


서버가 고정IP(IPv4)를 사용하는 경우를 기준으로 작성했다.



1. brctl 도구를 이용해서 br0 인터페이스 추가

  브릿지 인터페이스 이름은 꼭 br0이 아니어도 상관은 없다.


$ sudo brctl addbr br0



2. 인터페이스 설정


/etc/network/interfaces 파일

auto 이더넷_인터페이스_이름

iface 이더넷_인터페이스_이름 inet manual


auto br0 

iface br0 inet static

    address 고정IP주소

    netmask 넷마스크

    gateway 고정IP에_해당하는_게이트웨이

    dns-nameservers 도메인_네임_서버_IP주소

    bridge_ports 위에_manual로_설정된_물리적_이더넷_인터페이스

    bridge_fd 0

    bridge_maxwait 0

    bridge_stp off


# lo 인터페이스라던가, 그외 별도로 다른 인터페이스에 대해 설정해둔 것은 그대로 둘 것


(예) 서버에서 쓰는 물리적 이더넷 인터페이스 이름이 eno1이고 고정IP를 10.0.4.11/24로 쓸 경우,


auto eno1

iface eno1 inet manual


auto br0 

iface br0 inet static

    address 10.0.4.11

    netmask 255.255.255.0

    gateway 10.0.4.1

    dns-nameservers 8.8.8.8

    bridge_ports eno1

    bridge_fd 0

    bridge_maxwait 0

    bridge_stp off 



3. 서비스 재시작 또는 재부팅해서 설정 적용


$ sudo /etc/init.d/networking restart  또는 sudo service networking restart

$ sudo /etc/init.d/libvirt-bin restart


아니면 그냥 깔끔하게 재부팅.



서버 쉘에서 ifconfig 쳤을 때, br0 인터페이스가 보이면서 고정IP주소가 제대로 설정되어 있고, HWaddr에 적힌 맥주소가 실제 물리적 이더넷 인터페이스와 똑같으면, 그리고 물리적 이더넷 인터페이스에는 아무 IP주소도 할당되어 있지 않으면 성공적으로 설정한 것이다.


혹시 재부팅 후에 SSH로 서버에 접근이 안되는 경우 (== 서버가 네트워크 연결을 못하는 경우), /etc/network/interfaces 파일에서 bridge_ports에 적힌 이름실제 물리적 이더넷 인터페이스 이름이 서로 맞지 않는지, 즉 오타가 없는지 먼저 점검할 것 (여기서 두 번 실수함. ㅠㅠ)

만약 물리적 인터페이스 이름을 정확히 매치하지 않으면, KVM (정확히 말하면 virt-manager GUI에서의 개별 VM 설정에서 네트워크 인터페이스 설정 창)에서는 br0이라는 이름 옆에 empty bridge라고 표시된다.





반응형
블로그 이미지

Bryan_

,
반응형

Host OS: Ubuntu 14.04 Desktop (amd64)

Guest OS: Windows 10 (64-bit)


우분투 머신에 원격 접속을 하게 되면, XRDP를 쓰든 VNC Server 종류를 쓰든 상관없이 키보드 키의 연속 입력이 안 되는 문제를 경험한다. 사실 문제가 있어어 안 되는 것이 아니고, 의도적으로 연속 키 입력을 꺼 놓아서 그렇다.


콘솔을 제외하고 (콘솔은 어차피 로컬 게스트 머신의 접속 프로그램에 의해 좌우되기 때문에) 리눅스 머신에 그래픽 기반의 원격 접속을 하면, 내부적으로는 VNC가 가장 밑단에서 작동하기 때문에 VNC에서 연속 키 입력 옵션이 꺼져 있으면 RDP 클라이언트에서 별 짓을 다 해도 소용없다. 확인해 보니 VNC에서 옵션으로 켜고 끌 수 있다. [1]


VNC 서버 입장에서 연속 키 입력을 켜는 방법:

$ x11vnc -R repeat


반대로 연속 키 입력 기능을 끄는 방법:

$ x11vnc -R norepeat



*추가

참고로 우분투에 x11vnc 패키지를 설치하고 나면 시스템 부팅 시 자동실행 되는데, 이 때 키입력 연속 설정을 켜려면 /etc/init/x11vnc.conf 파일을 고쳐야 한다.


/etc/init/x11vnc.conf 파일

start on login-session-start

script

x11vnc -xkb -noxrecord -noxfixes -noxdamage -R repeat -display :0 -auth /var/run/lightdm/root/:0 -forever -bg -o /var/log/x11vnc.log -rfbauth /etc/x11vnc.pass -rfbport 5900 

end script



다만 버그가 있는데, 괄호 문자 '(' 또는 ')'를 입력하면 연속으로 입력하지 않는데도 계속 입력되는 현상이 있다. 가만히 두면 계속 타이핑되기 때문에 백스페이스 키를 눌러서 중단시켜야 한다. 전체적으로 연속 키 입력이 안되는 것보다는 약간의 불편을 감수하고 쓰는 편이 나을 것 같다.

<2016.05.24 수정> 괄호 문자가 반복 입력되는 버그는 다음에 재접속할 때는 또 발생하지 않았다. 그때그때 다른 것 같은데 원인은 아직 모르겠다.




<참고자료>

[1] https://lighttomorrow.wordpress.com/2015/04/16/vnc-server-setup-guide-for-ubuntu/


반응형
블로그 이미지

Bryan_

,