안녕하세요, 타이젠 개발자 윤진입니다.


2015년 마지막 날을 맞이하여,

<아프니까 개발자다> 블로그 총결산을 진행하고자 합니다.

제 블로그를 찾아주시는 극소수의 개발자분들조차 총결산 따위에 관심없으시겠지만,

블로거로서 지난 한해를 돌아보고,

더 나은 내일을 구상하기 위해 2015년을 돌아보고자 합니다.


<아프니까 개발자다> 블로그 정보를 훑어보겠습니다.

그 동안 총 159개의 글을 썼습니다.

대부분의 글은 외부에 발행한 공개글이고,

열개 남짓한 글은 차후에 게시하기 위해 가다듬고 있는 중입니다.

댓글은 글마다 평균 0.6개 정도가 달리고 있습니다.

타이젠에 대해 전문적인 내용을 다룬 포스팅에는 댓글이 거의 없네요.

문의가 없다는 것은 그만큼 완벽하게 포스팅을 하고 있는 것이겠죠...?


마지막에 블로그 개설일이 뚜렷하게 찍혀있습니다.

2015년 3월 1일!

그렇습니다. 올해 3월 1일 삼일절에 블로그를 개설하였습니다.

일부러 삼일절을 되새기기 위해 굳이 그날 개설했습니다.

(농담 아닙니다. 히히;)




제 블로그는 주로 구글링으로 접근해서 들어오는 분이 많습니다.

불과 두어달 전까지만 해도 네이버를 통해서 들어오는 분들이 많았는데요,

어느 순간 구글이 치고 올라오기 시작하더니 압도적으로 수치가 올라가고 있습니다.

1위는 구글, 2~5위는 네이버, 6위는 다음입니다.


10위에 티스토리가 있네요.

아마 포스팅을 할때마다 티스토리 주제별 스토리에 게재가 되는데요,

그 때 타고 오는 분들이 있겠지요.


11위에는 카카오톡입니다.

카톡으로 제 블로그를 검색해서 오시는 분들도 있군요.

아직 1위인 구글의 1/100에 불과하지만 차츰 점유율을 높이길 기대해봅니다.


13위, 구글 재팬으로 들어오는 분도 있고,

14위, 구글 인도도 제법 있네요.

16위에는 구글 캐나다가 보이고,

20위에는 구글 호주도 있습니다.

영어공부를 열심히 해서 포스팅을 영어로도 해야하지 않나 고민하게 만드네요.


매달 방문한 사람수를 보며 어떤 글이 관심을 받았는지 정리해보고,

올 한해의 방문트랜드를 엿보고 내년을 예상해보겠습니다.



사실 개설한 첫달 3월은 하루 방문자 수가 극히 미미하였습니다.

3월 1일부터 31일까지 하루 평균 2명 정도가 다녀갔네요.

겨우 한 명이 방문한 14, 15, 16, 23일은 아마 제가 방문한게 아닌가 싶네요.

게다가 3, 12, 13, 18, 19, 20, 22, 24, 25, 26, 27일은 방문자가 없습니다.

블로거가 방문하지 않는 블로그!

대단합니다;


29일에 방문자가 폭증(?)한 것은 코딩컨벤션을 다룬 세번째 글때문입니다.

[Coding convention] 코딩의 기본, 시대의 흐름으로 살펴본 헝가리안 표기법

사실 첫달에 하루 방문자수가 두자리수가 되리라고 생각하지 않았는데요,

아직도 세상은 코딩컨벤션으로 다투는 개발자로 가득차 있어서,

제 블로그 기준으로 '많은' 개발자가 다녀간 것으로 보입니다;




4월은 매우 고무적인 달입니다.

하루 평균 방문자수가 무려 3명이 넘는 기염을 토하였습니다.

그 덕에 방문자 수가 한 명도 없는 날은 12일(일) 하루뿐입니다.

원래 전통적으로 토/일은 제 블로그가 굉장히 한산하죠...


이 달에 가장 인기있던 포스팅은,

오픈소스 타이젠에서 소스 형상관리를 위해 사용하는 'git'과 관련된 내용이었습니다.

[git] 깃의 속사정, 4대 원소를 파헤치기

많은 개발자들에게 필수툴로 자리잡은 git의 위력을 실감할 수 있습니다.

위의 포스팅 이후에도 git에 대해서는 다양한 이야기를 나누고 싶었지만,

최근에 git과 관련된 정보가 인터넷에 넘쳐나고 있어서 자제하고 있습니다.




5월은 거의 매일 두자리 수의 방문객을 유치한 혁신의 달이었습니다.

4월달의 평균 3명 방문했던 블로그가 평균 34명 방문하는 블로그가 됩니다.

무려 10배가 늘어났네요.

이 달의 격한 감동은 아직도 마음 깊숙한 곳에 자리잡고 있습니다.

하루 3명오던 블로그에 30명이라니!

게다가 5월 21일에는 무려 187명이 방문합니다.

세자리수를 처음으로 찍었습니다.


[Tizen] 타이젠 최초의 모바일 기기, "Z1"의 늦은 개봉기

5월 21일 포스팅은 타이젠 상품과 관련된 내용이었습니다.

타이젠을 다루는 블로그에 타이젠 상품과 관련된 포스팅이 관심받지 못하면 문제가 있는거겠죠;

서남아 시장에만 출시한 Z1의 개봉기를 간단하게 다루었었는데요,

개발자의 손에 하드웨어를 쥐어주면 참 많은 걸 할 수 있겠구나 생각이 들었습니다.



6월에는 하루평균 백여명이 방문하게 됩니다.

5월에 비해 3배 이상의 성장율을 달성하게 됩니다.

5월에는 31일 중 고작 이틀동안만 백여명 이상의 방문자를 유치했었는데요,

6월에는 거의 절반에 가까운 14일동안 백여명 이상의 방문자를 유치하였습니다.


그 중 가장 많은 사람이 찾아주었던 6월 13일에는 타이젠 보안의 핵심,

스맥을 다룬 포스팅이었습니다.

[SMACK] 스맥 레이블을 긋기 위한 manifest의 모든 것 - 파일편

대규모 플랫폼 중에서 타이젠이 가장 적극적으로 스맥을 사용하고 있습니다.

스맥을 알고 싶다면 타이젠 플랫폼을 분석하는 것도 의미가 있을 겁니다. 




7월에는 하루 평균 122명의 방문객이 다녀갑니다.

6월의 100명에 비해 22명이 더 늘어났습니다.

평일에는 거의 어김없이 세자리수를 유치하였고,

주말에는 역시 어김없이 두자리수에 머물고 있습니다.

제 블로그가 평일용으로 확정된 것이 7월달부터가 아닌가 싶습니다.

다들 업무시간에만 제 블로그를 찾는 것일까요?

그래서 업무 외의 시간에도 방문자를 유치할 수 있도록-

여러가지 다양한 내용을 다뤄야되겠단 생각을 했습니다.


7월에 가장 인기가 많았던 포스팅은,

[Tizen] 타이젠 스토어 182개국 오픈 중 4개국 유료판매가능

타이젠 앱스토어의 유료판매 정책에 대한 내용입니다.

182개국 중 4개국(인도, 방글라데시, 스리랑카, 네팔)에서 유료판매가 가능하게 되었죠.



8월에는 7월과 거의 유사한 수의 방문객이 다녀갔습니다.

7월에 122명이 다녀갔다면 8월에는 평균 123명이 다녀갔습니다.

하루 평균 2명 방문했던 블로그에 123명이 방문한다면 그야말로 대사건이긴 하지만,

100여명에서 정체된다면 아무래도 한계점에 다다른 것일 수도 있겠네요.


사실 8월에는 포스팅을 거의 하지 못한 기억이 납니다.

8월 29일에 서울 서초에서 타이젠 행사에서 세션발표를 맡게되어,

여러가지 준비를 하느라 정신없었죠.

[Tizen] 타이젠 DEVLAB @SEOUL 후기

위의 글이 가장 많은 방문자가 다녀간 날에 포스팅한 글입니다.

서울에서 열린 첫 타이젠 데브랩이니만큼 여러가지 많은 것을 느낄 수 있었습니다.




9월에는 하루 평균 120여명에 멈춰있었던 방문자수가 조금 증가하게 됩니다.

평균 145명으로 약 20여명의 방문자가 더 늘어났습니다.

타이젠에 관심을 가지고 있는 사람이 늘어났다기보다는,

일반적인 개발방법에 대해 다룬 글을 몇 개 올려서 외부 소프트웨어 개발자가 유입된 것으로 보입니다.


그 중 가장 많은 방문자를 유입한 날에 작성한 글은,

[소프트웨어 개발] Man-Month 허상과 히어로 개발자입니다.

위의 글은 타이젠 플랫폼을 만들고 계신 분들 중에 없어서는 안될 개발자분들을 떠올리며 작성했죠.

지금은 좀 더 늘어나긴 했지만,

저 글을 썼었던 당시에는 5명의 히어로 개발자 분들을 염두했죠.

물론 그 다섯 분들은 자신이 히어로 개발자들인 것을 인지하지 못하실 수도 있겠네요. :)

지극히 개인적인 생각입니다만,

저런 훌륭한 개발자들이 타이젠 플랫폼에 남아있는한,

타이젠은 점점 흥미로운 플랫폼으로 변모해나갈 것임을 확신할 수 있습니다.




시월에는 평균 145명 방문자가 192명으로 늘어납니다.

어느새 평균 200여명의 문턱에 다다르게 되었습니다.

이런 날이 이렇게 빨리 오게 될 줄은 상상하지 못했죠.


사실 시월에는 타이젠 외에 다양한 주제를 다루었습니다.

우선 삼성 오픈소스 컨퍼런스를 주제로 몇 건 포스팅하였죠.

삼성 대학생 프로그래밍 경진대회가 열린 달이기도 하고요.

코리아 리눅스 포럼에 대해서도 살짝 포스팅을 했습니다.

그래도 가장 많은 사람이 방문한 글은 SCSA에 대한 글이었습니다.

[SCSA] Samsung Convergence Software Academy를 말하다

삼성에서 만든 굉장히 독특한 제도이니 만큼,

외부의 관심도 많았습니다.

더불어 개인적으로도 아주 관심이 많습니다.

앞으로도 SCSA 전반을 계속 주시하며 정보를 '적극적으로' 갱신할 생각입니다.




11월은 앞으로 돌아오지 않을 호시절과 같은 달이었습니다.

이전달의 평균 192명 방문자는 이제 평균 378명으로 거의 두 배 가까이 늘어납니다.

방문자수가 폭발적으로 늘어나게된 이유는 기어S2가 출시되면서 타이젠에 관심이 많아진 것이겠지요.


가장 방문자가 많았던 글은,

[Tizen] 타이젠 세번째 웨어러블 기기, "Gear S2" 리뷰

위의 글이었습니다.

개발자들의 관심을 받게된 만큼,

타이젠은 생태계 구축에 더욱 힘을 쏟아야할 때입니다.



이 글을 쓰고 있는 12월 25일 기준으로,

하루 평균 218명의 방문자가 블로그를 찾고 있습니다.

기어 S2가 출시된 후 시간이 많이 흘렀기에 기어S2로 검색하여 들어오는 사람은 많이 줄었습니다.

그 대신 타이젠을 키워드로 들어오는 사람들이 200명이 넘습니다.


물론 이미 널리 알려진 여러 플랫폼들을 주제로 다룬 블로그는,

<아프니까 개발자다> 보다 10배 혹은 100배 많은 방문객을 유치하고 있겠죠?

내년에는 타이젠이 더 많은 사람들에게 사랑 받아서 덩달아 제 블로그에도 다시 호시절이 오면 좋겠습니다. :)

역시 타이젠 관련 블로그는 타이젠이 흥해야 같이 살아난다는 만고의 진리를 다시 한 번 확인하게 됩니다.


마지막으로 재미삼아서,

최근에 분석하기 시작한 구글 애널리틱스 분석자료를 보겠습니다.



제 블로그에 재방문자가 40%나 됩니다.

재방문자가 있다는 것은 뭔가 쓸만한 글이 있다는 반증이겠지요?

재방문자들을 실망시키지 않도록 2016년에는 흥미로운 주제를 더 많이 찾아내겠습니다.

"단골이여, 영원하라."



방문객은 평균 2~3분 정도 블로그에서 글을 읽었습니다.

2~3분이 결코 긴 시간은 아닌 만큼,

좀 더 퀄리티가 높은 글을 공유해야겠다는 생각이 듭니다. 



방문객은 1.5개 정도의 글을 읽고 돌아갔네요.

검색한 하나의 글만 보고 가는 분들도 있겠지만,

두개 이상을 보고 가는 분도 있네요.

흥미롭군요.



위의 그래프는 매일매일 시간에 따라 방문자를 나타낸 겁니다.

예외없이 평일 오후 3시에 그래프가 정점을 찍습니다.

제 블로그는 오후 3시에 들어오기 좋은 블로그인가 봅니다.

도대체 그 시간에 무슨 일이 벌어지고 있는 건가요?


이상으로 어쩌면 제게만 유의미할 지 모르는 2015 총결산을 마치겠습니다.

2016년 새해 복 많이 받으세요.

2016년 총결산때 다시 찾아뵙겠습니다.


감사합니다.

끝_




  1. 시스템가이 2015.12.31 23:44

    타이젠에 대해 이렇게 멋진 블로그를 운영하시는 분이 또한분 계시다니 감동이에요 ^^ 총 결산 글을 보니 다른 글들도 보게 되네요 잘 읽고 갑니다 ^^

    • 안녕하세요, 시스템가이님.
      새해 복 많이 받으세요~!
      시스템 가이님의 댓글을 보니 더 흥미로운 글을 많이 써야되겠다는 생각이 듭니다. 아직은 많이 부족하니 올 한해 바짝 허리띠를 졸라매야겠네요 :) 좋은 말씀 감사해요!

  2. 코코콩 2016.01.05 18:12 신고

    오후 3시는 점심먹고 업무에 몰두하다가 안풀려서 쉬는타임이죠 ㅋㅋㅋ

    • 제 블로그를 보면서 쉬는 분이 계실 수도 있겠군요.
      3시 고객을 위해 좀 더 재미나게 읽을거리를 준비해야겠네요. :)

root 권한을 가진 프로세스는 모든 파일에 접근할 수 있습니다.

프로세스가 어떤 스맥레이블로 활성화되어있건 관계가 없죠.

사실 약간 깡패같은 느낌이 없잖아 있습니다.

그게 root의 막강한 권한이기도 하지요.


그렇지만, 플랫폼을 제품으로 출시할때,

root 권한은 최대한 제한하고 없애야 합니다.


스맥을 사용하는 시스템에서는 onlycap이 좋은 시작이 될 수 있습니다.

특정 스맥레이블을 onlycap이라 설정하고,

onlycap만이 "스맥레이블을 명시하지 않아도" 모든 파일에 접근할 수 있게 합니다. 


이 말은 root라 할지라도 onlycap이 아니면 모든 파일에 접근할 수 없다는 말이지요.



스맥이 활성화된 커널에서는 CAP_MAC_ADMIN을 가진 프로세스만이 스맥레이블을 변경할 수 있습니다.

CAP_MAC_ADMIN은 보통 관리자 권한의 프로세스가 가지고 있습니다.

일반적으로 root 권한으로 실행되는 프로세스가 관리자 권한이라고 여겨지지요.

CAP_MAC_ADMIN 프로세스만이 프로세스, 파일, 디렉토리에 명시된 스맥레이블을 변경할 수 있습니다.


CAP_MAC_OVERRIDE는 접근하려는 오브젝트에 어떤 레이블이 걸려있든 접근할 수 있는 권한입니다.

이것도 보통 관리자 권한이 지닌 막강한 권한 중에 하나입니다.

CAP_MAC_OVERRIDE 프로세스는 어떤 스맥레이블이 새겨진 파일이든 상관없이 접근합니다.


CAP_MAC_ADMIN이나 CAP_MAC_OVERRIDE는 막강한 권한입니다.

이런 권한을 가진 프로세스를 최대한 제한해야 시스템이 루팅으로부터 벗어날 수 있습니다.

곧, 관리자 권한의 프로세스라 하더라도 CAP_MAC_ADMIN이나 CAP_MAC_OVERRIDE를 제한해야한다는 것입니다.


If /smack/onlycap is empty (unset or null-string) privilege

is enforced in the normal way.

If /smack/onlycap contains a label only processes running with
that label may be MAC exempt.

If the label in /smack/onlycap is the star label ("*") the
semantics of the star label combine with the privilege
restrictions to prevent any violations of MAC, even in the
presence of privilege.

smack: limit privilege by label


onlycap은 2008년 7월 30일에 커널에 반영된 기능입니다.

/smack/onlycap에 명시된 스맥레이블을 가진 프로세스만이 CAP_MAC_OVERRIDE 기능을 사용할 수 있게 합니다.

관리자 권한을 가진 프로세스라 하더라도,

onlycap에 명시된 스맥레이블로 지정되어 있지 않다면,

자신이 룰셋에 정의한 스맥레이블에만 접근할 수 있습니다.

리눅스권한 레벨에서는 관리자권한이라 할지라도,

스맥 레벨에서는 일반유저와 동일한 수준의 권한을 가지게 되는 셈입니다.


/smack/onlycap파일에 어떤 값을 채우느냐에 따라 동작이 달라집니다.

- onlycap을 비워두면, 관리자 권한을 가진 프로세스들이 모든 파일에 접근할 수 있습니다.

- onlycap에 스맥레이블을 채워놓으면, 명시된 레이블로 실행되는 프로세스만이 모든 파일에 접근할 수 있습니다.

- onlycap에 "*"를 넣으면, onlycap 권한이 제한됩니다.


onlycap 파일은 CAP_MAC_ADMIN이나 CAP_MAC_OVERRIDE 권한을 지닌 프로세스만이 수정할 수 있습니다.

관리자 권한을 가진 프로세스라 할지라도 CAP_MAC_ADMIN이나 CAP_MAC_OVERRIDE가 없다면,

/smack/onlycap를 수정하여 시스템 해킹을 시도할 수 없겠죠.


Smack onlycap allows limiting of CAP_MAC_ADMIN and CAP_MAC_OVERRIDE to
processes running with the configured label. But having single privileged
label is not enough in some real use cases. On a complex system like Tizen,
there maybe few programs that need to configure Smack policy in run-time
and running them all with a single label is not always practical.
This patch extends onlycap feature for multiple labels. They are configured in the same smackfs "onlycap" interface, separated by spaces.

[PATCH 2/2] Smack: allow multiple labels in onlycap


onlycap과 관련된 따끈따끈한 패치도 있네요.

2015년 5월 21일에 리눅스 커널에 올라왔습니다.

패치는 onlycap에 다수의 스맥레이블을 등록할 수 있게 되었습니다.

(기존에는 오직 하나의 스맥레이블만 적을 수 있었습니다)

/smack/onlycap에 스페이스로 구분된 스맥레이블을 적어주면 됩니다.

위에 잠깐 언급되어 있지만, 타이젠 같은 복잡한 시스템을 위해 패치를 만들었네요.


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* References

https://www.kernel.org/doc/Documentation/security/Smack.txt

https://lwn.net/Articles/292128/

https://lkml.org/lkml/2012/6/5/497

https://lkml.org/lkml/2015/5/21/630


* SMACK 원리

[SMACK] 스맥체크의 7가지 단계


* SMACK Manifest

[SMACK] 스맥 레이블을 긋기 위한 manifest의 모든 것 - 파일편

[SMACK] 스맥 레이블을 긋기 위한 manifest의 모든 것 - DBUS편


* SMACK 기능

[SMACK] 스맥에서 onlycap으로 root 권한 축소하기


* SMACK 사용하기

[SMACK] 쉘의 /proc/self/attr/current로 스맥권한 조종하기


* SMACK & Privilege

[SMACK] 타이젠 Privilege의 모든 것



디버스의 메소드/시그널에도 스맥을 적용할 수 있습니다.

스맥이 적용된 디버스 메소드/시그널에는 권한이 있는 프로세스만 접근할 수 있습니다.

브로드캐스팅하는 인터페이스라 할지라도 권한이 없으면 접근할 수 없습니다.


스맥이 최초부터 디버스를 지원하진 않았습니다.

하지만, 디버스로 주고받는 정보를 누구에게나 노출하는 것은 위험할 수 있습니다.

따라서 2012년 2월에 한 용자가 디버스에 스맥을 이식해버렸습니다.


그리고 3년이 지난 지금은 스맥의 주요 기능 중 하나가 되었죠.



스맥을 위한 manifest 파일 만드는 법은 이전 포스팅에서 설명한 바 있습니다.

"SMACK 레이블을 긋기 위한 manifest의 모든 것 - 파일편", http://storycompiler.tistory.com/49

이 manifest 파일에서 디버스를 위한 스맥권한도 지정할 수 있습니다.



{service name}.manifest 파일은 패키지가 설치될 때 함께 설치됩니다.

manifest 내용 중 DBUS와 관련된 항목이 있으면,

rpm-security-plugin에 의해서 파싱되어 manifest.{service name}.conf 파일로 추출됩니다.

manifest.{service name}.conf 파일은 디버스 설정파일로 활용되지요.


<assign> <dbus name="org.dbus.name" own="DOMAIN_NAME" bus="system"> <!-- 중략 --> </dbus> </assign>

디버스는 <assign> 태그에서 설정해주어야 합니다.

<assign> 태그는 파일/디렉토리에 스맥룰을 적용할 때도 사용하고 있습니다.

- dbus name : D-Bus의 버스명을 적어줍니다.

- own : dbus-service를 정의한 프로세스의 도메인이름

- bus : "system" 혹은 "session"


<assign> <dbus name="org.dbus.name" own="DOMAIN_NAME" bus="system"> <node name="/org/dbus/object/name"> <interface name="org.dbus.interface.name1"> <method name="methodName1"> <annotation name="org.tizen.smack" value="DOMAIN_NAME::COMPONENT_1" /> </method> <method name="methodName2"> <annotation name="org.tizen.smack" value="DOMAIN_NAME::COMPONENT_2" /> </method> </interface> <interface name="org.dbus.interface.name2"> <annotation name="org.tizen.smack" value="DOMAIN_NAME::COMPONENT_3" /> </interface> </node> </dbus> </assign>

<node> 태그에는 오브젝트 이름을 적어줍니다. <node> 안에는 다수의 <interface>를 적어넣을 수 있습니다.

<interface> 태그에는 인터페이스 이름을 적어줍니다. <interface> 안에는 다수의 <method>를 적을 수 있습니다.

<method> 태그에는 메소드의 이름을 적어줍니다. <method> 내에는 <annotation> 태그가 하나 들어갑니다.

<annotation>에는 메소드에 접근하기 위한 스맥권한을 명시합니다.

annotation name은 스맥을 위한 키이름을 적어야 합니다.

키이름은 플랫폼마다 다를 수 있습니다.

여기서는 타이젠 플랫폼에서 사용하는 org.tizen.smack을 사용하겠습니다.

value에는 스맥레이블을 적으면 됩니다.


<assign> <dbus name="org.dbus.name" own="DOMAIN_NAME" bus="system"> <node name="/org/dbus/object/name"> <interface name="org.dbus.interface.name> <annotation name="org.tizen.smack" value="DOMAIN_NAME::COMPONENT" /> </interface> </node> </dbus> </assign> 

위의 예에서는 interface에 속한 모든 method / signal에 공통의 스맥레이블을 적용할 수 있습니다.

<interface> 태그 안에 <method> 대신 <annotation> 태그를 입력했습니다.

그러면 interface에 속한 모든 method에 annotation에서 지정한 스맥레이블이 적용됩니다.


타이젠 플랫폼에서 실제로 사용하고 있는 manifest를 보시죠.

"git://review.tizen.org/framework/system/crash-worker" / tizen_2.3 브랜치,

packaging/crash-worker.manifest 파일에서 디버스 항목을 추려보았습니다.

<assign>
<dbus name="org.tizen.system.crash" own="crash-worker" bus="system">
<node name="/Org/Tizen/System/Crash/Crash">
<interface name="org.tizen.system.crash.Crash">
<!-- dbus smack label "crash-worker::crashctl" -->
<method name="dump_log">
<annotation name="com.tizen.smack" value="crash-worker::crashctl" />
</method>
<method name="delete_dump">
<annotation name="com.tizen.smack" value="crash-worker::crashctl" />
</method>
</interface>
</node>
</dbus>
</assign>

위의 예제에서는 "dump_log"와 "delete_dump" 두 개의 메소드에,

"crash-worker::crashctl" 스맥레이블을 부여했습니다.

다른 메소드도 존재하지만 굳이 저 두 개의 메소드에만 스맥레이블을 부여하기 위하여 사용한 것으로 보입니다.


이것으로 manifest에 대한 설명을 정리하도록 하겠습니다.

그럼 오늘도 좋은 하루 보내세요~


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* References

https://wiki.tizen.org/wiki/Security/Application_installation_and_Manifest

https://wiki.tizen.org/wiki/Security/Tizen_2.X_dbus


SMACK을 사용하는 시스템에 있는 파일들은,

언제 스맥 레이블이 그어질까요?

파일이 설치되는 시점입니다.


- 사용자가 직접 파일을 생성/다운로드/카피/이동하는 경우

사용자가 직접 파일을 생성/다운로드/카피/이동하면,

사용프로세스 혹은 이동디렉토리의 스맥권한이 파일에 새겨집니다.


- 패키지를 풀어 그 안의 파일들을 설치하는 경우

패키지를 풀어 파일을 설치하면,

패키지를 만드는 시점에 지정한 방식으로 스맥레이블이 그어지겠지요.


이 포스팅에서는 패키지를 생성하는 시점에 "파일/디렉토리"에 스맥 레이블을 긋는 방법을 공유하도록 하겠습니다.



패키징하는 시점에 이미 존재하는 파일에는,

패키지마다 하나씩 존재하는 manifest 파일로 스맥 권한을 부여할 수 있습니다.

manifest 파일은 [패키지이름].manifest로 이름을 지어주게 됩니다.

어차피 패키지 내에 하나만 있으므로 패키지이름으로 지어주어도 되지요.


manifest 파일은 xml을 사용합니다.

최상위 태그는 <manifest></manifest>로 시작하지요.


<manifest>
    ...
</manifest>

manifest에는 패키지에서 사용할 스맥레이블을 정의할 수 있습니다.

여기서 정의한 레이블은 레이블을 정의한 방식에 따라,

한 패키지에서만 독점적으로 사용하거나,

다수의 패키지에서 사용할 수 있습니다.


<define> <domain name="YOUR_SMACK_LABEL" /> </define>

위의 예처럼 <domain> 태그로 스맥레이블을 정의할 수 있습니다.

레이블은 255자 이하로 지을 수 있습니다.

"A-Z", "a-z", "0-9", "_", "-", "."의 문자만 사용해야 합니다.

도메인 이름은 위에 명시된 문자들을 조합하여 고유하게 만들어야합니다.

그렇기 때문에 패키지이름으로 짓기도 하지요.


<define> <domain name="YOUR_SMACK_LABEL" policy="shared" /> </define>

위처럼 policy를 shared로 지정하여 다른 패키지에서도 스맥레이블을 사용할 수 있게 설정할 수 있습니다.

policy가 없으면 default는 private로 설정되게 됩니다.

오직 정의한 패키지에서만 사용할 수 있는 스맥레이블이 되는 셈이지요.

만약 private로 정의한 스맥 레이블과 동일한 스맥 레이블을 가진 패키지가 설치된다면,

나중에 설치되는 패키지는 설치할 수 없게 됩니다.

따라서 스맥레이블을 고유한 이름을 지정하는 것이 중요합니다.


<define> <domain name="YOUR_SMACK_LABEL" policy="restricted" plist="package1,package2" /> </define>

policy가 restricted로 설정되어 있으면,

스맥레이블을 정의하는 시점에 이 스맥을 사용할 수 있는 패키지를 선택할 수 있습니다.

다른 패키지와 스맥 레이블을 공유하지만 제한적으로 공유하게 됩니다.

plist, 곧 패키지 리스트에 명시된 패키지 이름만 여기서 정의하는 스맥레이블을 사용할 수 있습니다.


<define> <domain name="YOUR_SMACK_LABEL policy="shared" /> <request> <smack request="OTHER_SMACK_LABEL_1" type="w" /> <smack request="OTHER_SMACK_LABEL_2" type="rwxat" /> </request> </define>

직접 정의한 스맥레이블 외에 다른 패키지에 선언한 스맥레이블을 사용해야할 수도 있습니다.

다른 패키지에서 관리하는 파일에 접근하는 경우에 흔히 사용합니다.

그럴 경우, <define> 내에서 <request></request> 태그를 사용합니다.

그리고 사용하고자 하는 스맥레이블을 적고,

type으로 해당하는 스맥레이블에 원하는 권한을 적어둡니다.

위의 예에서는, YOUR_SMACK_LABEL이 Subject로, OTHER_SMACK_LABEL_1이 Object로 동작하겠지요.


<define> <domain name="YOUR_SMACK_LABEL" policy="shared" /> <permit> <smack permit="OTHER_SMACK_LABEL" type="rwx" /> </premit> </define>

permit을 정의할 수도 있습니다.

YOUR_SMACK_LABEL을 사용할때,

OTHER_SMACK_LABEL에 대한 rwx 권한도 함께 주는 것이지요.

개발자가 명시적으로 OTHER_SMACK_LABEL에 대한 권한을 요청하지 않아도 사용할 수 있게 됩니다.

다른 스맥 권한도 함께 부여하는 것이기에 사용에 주의를 기울여야합니다.


<request> <domain name="OTHER_SMACK_LABEL" /> </request>

자신이 정의한 스맥레이블을 사용하지 않고,

다른 패키지에서 정의한 스맥레이블을 기본으로 사용할 수도 있습니다.

위의 <request>는 <define>과 동일한 레벨의 <request> 태그로,

<define> 태그없이도 사용할 수 있습니다.

<define> 내에서 사용하는 <request>도 있었는데 두 개의 의미가 다릅니다.

<define> 내에서 선언한 것은,

<define>에서 정의한 도메인이 <request>에서 선언한 스맥레이블을 사용하도록 요청한 것입니다.

<define> 외에서 선언한 것은,

패키지에서 설치하는 모든 파일들을 <request>에서 설정한 스맥레이블로 지정하라는 의미이죠.

따라서 두 개의 request를 동시에 사용할 수 있습니다.

(이런 식의 작명은 별로 좋아보이지 않습니다.)


<manifest> <define> <domain name="YOUR_SMACK_LABEL" policy="restricted" plist="package1,package2" /> <request> <smack request="OTHER_SMACK_LABEL_1" type="rw" /> <smack request="OTHER_SMACK_LABEL_2" type="rx" /> </request> </define> <request> <domain name="OTHER_SMACK_LABEL_3" /> </request> </manifest>

위의 manifest를 살펴보면,

새로운 도메인 "YOUR_SMACK_LABEL"을 만들고 나서,

실제로 자신의 파일에는 "OTHER_SMACK_LABEL_3"를 사용하였습니다.

보통은 자신이 define하고 그걸 다시 request로 사용하게 됩니다.


<manifest> <request> <domain name="OTHER_SMACK_LABEL" /> </request> </manifest>

자신이 아예 define하지 않는 경우도 있습니다.

다른 패키지에서 define한 스맥레이블을 자신의 파일에 적용할 수 있습니다.


<manifest> <define> <domain name="YOUR_SMACK_LABEL" policy="shared" /> <provide> <label name="YOUR_SMACK_LABEL::COMPONENT_1" /> <label name="YOUR_SMACK_LABEL::COMPONENT_2" /> <label name="YOUR_SMACK_LABEL::COMPONENT_3" /> </provide> <permit> <smack permit="OTHER_SMACK_LABEL" to="YOUR_SMACK_LABEL::COMPONENT_1" type="rwxat" /> </permit> </define> </manifest>

위처럼 한 도메인 내에서 다수의 서브 스맥레이블을 만들 수도 있습니다.

서브도메인은 "::" 두개의 콜론으로 나눠야합니다.

위의 예에서는 <domain> 태그와 같은 레벨의 <provide> 태그를 만들고,

그 안에 세 개의 서브도메인을 만들었습니다.

서브도메인에서 정의한 스맥레이블은 모두 "::"로 도메인과 서브도메인 이름을 구분하고 있습니다.

추가로 permit을 지정하여 YOUR_SMACK_LABEL::COMPONENT_1에만,

OTHER_SMACK_LABEL을 permit 해주고 있네요.

"to"를 빼면 모든 provide된 서브도메인에 스맥레이블을 permit할 수 있습니다.


<assign> <filesystem path="/YOUR/DIRECTORY_1" label="YOUR_SMACK_LABEL::COMPONENT_1" /> <filesystem path="/YOUR/DIRECTORY_2" label="YOUR_SMACK_LABEL::COMPONENT_2" /> <filesystem path="/YOUR/DIRECTORY_3" label="YOUR_SMACK_LABEL::COMPONENT_3" /> </assign>

특정 파일에 별도의 스맥레이블을 지정할 수 있습니다.

그러려면 <assign> 태그를 사용하여야 합니다.

<filesystem> 밑에 path에 스맥레이블을 지정하고자 하는 디렉토리나 파일을 적어 놓습니다.

label에는 지정하고자 하는 스맥레이블을 적으면 됩니다.

위의 예에서는 그 전에 <provide> 태그로 설정한 스맥레이블을 지정하였습니다.


<assign> <filesystem path="/usr/local/command" label="YOUR_SMACK_LABEL::COMPONENT_1" exec_label="none" /> </assign>

실행파일에는 exec_label을 추가로 부여할 수 있습니다.

파일이 갖는 스맥레이블은 label 필드에 기입하지만,

exec_label 필드에는 프로세스가 갖는 스맥레이블을 기입합니다.


하지만, exec_label이 caller와 같은 스맥레이블을 지녀야하는 경우도 있습니다.

caller의 스맥레이블이 OTHER_SMACK_LABEL이고,

caller가 실행한 프로세스도 OTHER_SMACK_LABEL로 지정되어,

caller의 자원 중 OTHER_SMACK_LABEL로 지정된 자원에 자유롭게 접근하는 경우이지요.

그럴 때는, exec_label에 위처럼 none을 지정해주면 됩니다.


<assign> <filesystem path="/YOUR/DIRECTORY" label="YOUR_SMACK_LABEL::COMPONENT_2" type="transmutable" /> </assign>

디렉토리에 transmutable 타입을 설정할 수 있습니다.

transmutable은 디렉토리 내에서 생성하는 파일의 스맥레이블을,

파일을 생성한 프로세스의 스맥레이블이 아닌,

파일이 생성되는 디렉토리에 설정된 스맥레이블로 지정하는 경우에 사용합니다.

이 말을 뒤집어서 하면, 파일은 파일을 생성한 프로세스의 스맥레이블을 따른다는 것이지요.

transmutable은 특정 디렉토리를 다수의 프로세스에서 접근하여 사용하는 경우에 유용합니다.


<assign> <filesystem path="/YOUR/DIRECTORY/*" label="YOUR_SMACK_LABEL::COMPONENT_3" /> </assign>

디렉토리 내의 모든 파일과 디렉토리에 recursive하게 스맥레이블을 줄 수 있습니다.

디렉토리와 "*"를 사용하면 됩니다.


dbus의 interface나 method에도 스맥레이블을 부여할 수 있습니다.

이 부분은 다음에 다시 설명하도록 하겠습니다.

<무한도전>부터 보고... :)


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* Reference

https://wiki.tizen.org/wiki/Security/Application_installation_and_Manifest


  1. 2016.08.09 16:26

    비밀댓글입니다

스맥에 대해 하나씩 정리를 해보고자 마음을 먹었습니다만,

정리해야할 내용이 너무 많아서 고민하고 있습니다.


기본적인 원리는 간단할지 모르겠으나,

원리와 원리의 적용(현실화)에는 무척이나 깊은 간극이 있습니다.


비교적 간단한 원리부터 설명하여,

틈 나는 대로 하나씩 포스팅하겠습니다.



위의 그림은 펭귄...일겁니다.

이상한 모양의 삼각형 펭귄.

SMACK의 공식 로고입니다.

SMACK에 대한 신뢰를 한 순간에 무너뜨릴 만큼 허접한 로고입니다.


SMACK은 프로세스와 파일에 Label을 긋는 것에서 시작됩니다.

SMACK이 적용된 플랫폼의 모든 파일에는 SMACK Label이 그어지게 되죠.

Label은 흔히 그 파일을 설치한 패키지 이름이나 파일의 성격에 따라 작명합니다.


한 패키지에 다수의 파일이 있으면,

같은 패키지 이름으로 모든 파일에 같은 Label을 그어줄 수도 있고,

파일의 성격에 따라 서로 다른 Label을 지을 수도 있습니다.


이처럼 사용자가 지정하는 Label 외에 스맥이 사전에 정의한 Label도 있습니다.

아래 명시되어 있는 5가지 문자가 사전에 정의된 Label입니다.


Pronounced "floor", a single underscore character.

^  Pronounced "hat", a single circumflex character.

*  Pronounced "star", a single asterisk character.

?  Pronounced "huh", a single question mark character.

@  Pronounced "web", a single at sign character.


상위 3개(_, ^, *)는 자주 사용하지만,

아래 2개(?, @)는 사용해본 적이 없습니다.

'?' Label은 실제로 사용하는지 의문입니다.

'@' Label은 앱에서 인터넷을 특정 IP 주소를 누구나 사용하도록 열어줄때 사용합니다.

이 Label 또한 자주 사용하진 않으므로 생략하겠습니다.


상위 3개는 커널 소스에서도 그대로 사용됩니다.

커널 소스를 그대로 볼 필요는 없고,

아래 7가지 단계로 되어있다고 여기시면 됩니다.


  1. Any access requested by a task labeled "*" is denied.

2. A read or execute access requested by a task labeled "^"

   is permitted.

3. A read or execute access requested on an object labeled "_"

   is permitted.

4. Any access requested on an object labeled "*" is permitted.

5. Any access requested by a task on an object with the same

   label is permitted.

6. Any access requested that is explicitly defined in the loaded

   rule set is permitted.

7. Any other access is denied.


우선 프로세스가 "*" 실행권한인지 체크합니다(1).

프로세스가 "*" 권한이라면, 어떤 파일에도 접근할 수 없습니다.

바로 Access denied 에러를 리턴하게 되겠지요.

실행파일이지만 다른 파일에는 접근하게 하고 싶지 않을때 설정하면 됩니다.


프로세스가 "^" 실행권한이 있으면(2),

파일에 어떤 label이 그어져 있건,

읽고 실행할 수 있습니다.

쓰기 권한은 없습니다.

굉장히 막강한 권한입니다.

'^'는 제한적인 프로세스에 사용해야합니다.


파일에 "_" Label이 새겨져 있으면(3),

프로세스가 읽고 실행할 수 있는 파일입니다.

라이브러리에 "_" Label을 새겨놓으면 됩니다.

어느 프로세스나 접근할 수 있게 판을 깔아놓는 셈이지요.


파일에 "*" Label이 새겨져 있으면(4),

어느 프로세스이든 접근하여 읽고 쓰고 실행할 수 있습니다.

스맥이 적용되지 않은 시스템에 있는 파일과 같은 상태인 셈입니다.

오직 리눅스 권한만이 영향을 미칠 수 있습니다.

누구나 읽고 쓰고 실행할 수 있는 파일/디렉토리에 지정하면 됩니다.


프로세스와 파일의 Label이 같다면(5),

읽고 쓰고 실행할 수 있습니다.

같은 패키지인 경우가 이에 해당합니다.

자기가 설치한 파일을 관리하는 것이죠.


룰이 적혀있는 set에 명시적으로 프로세스와 파일을 관계가 적혀있는 경우(6),

이 경우에 룰에 적혀있는 범위 내에서의 접근할 수 있습니다.

룰 set에 읽기만 언급되어 있다면,

프로세스는 파일에 대해 읽기만 가능할테지요.


그 외의 경우는 접근할 수 없습니다(7).


이상의 7단계를 차례대로 거쳐서,

프로세스의 파일에 대한 접근이 확정됩니다.


여기서 오직 '*' 기호만 프로세스와 파일에 적용할 수 있습니다.

기호는 같지만 의미는 완전히 다릅니다.

'*'가 프로세스와 쓰일때는 프로세스가 어떤 파일에도 접근할 수 없게 됩니다.

하지만, '*'가 파일에 쓰인다면 어떤 프로세스나 읽고 쓰고 실행할 수 있게 되지요.

좀 더 분명한 역할정의를 위해,

서로 다른 기호를 썼으면 좋았을거란 생각이 듭니다.


'*' 기호와는 다르게 '^'는 프로세스에서만 사용하고,

'_'는 파일에서만 사용합니다.

만약 '^'를 파일에, '_'를 프로세스에 사용하면 의도치 않은 동작을 할 수 있습니다.


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* References

http://www.webcitation.org/6AqzohCXq

파일에 rwxrwxrwx처럼 새겨진 권한만으로는 디테일한 권한설정이 어렵습니다.

소유자나 그룹의 권한을 확인하여 파일에 접근하는 종래의 방식은,

그룹 내 사용자들 간에 세부적인 권한설정이 어려웠지요.

이를 위해서는 그룹을 세세히 쪼개 관리해야했죠.


하지만, SMACK을 사용하여 상황이 나아졌습니다.

스맥 코드는 커널소스에 추가되기 때문에,

커널이 프로세스가 가진 실행권한을 분석하며 파일 'label'에 대한 접근권한이 있는지 '추가'로 체크하게 됩니다.


리눅스 권한과 스맥 권한 두 가지를 모두 통과해야 비로소 파일에 대한 접근이 허용되죠.



SMACK 환경에서는,

모든 프로세스/파일이 스맥 label을 갖고 있습니다.


* SMACK 원리

- 프로세스 : Subject, 프로세스에는 실행권한 Label이 새겨집니다.

- 파일 : Object, 파일에는 접근권한 Label이 새겨집니다.

          프로세스는 파일이기도 하기에 실행권한/접근권한 Label이 모두 새겨지죠.

- 룰 : 프로세스(Subject)의 Label과 파일(Object)의 Label의 권한관계가 명시됩니다.

       권한관계에는 r,w,x,a,t,l 등이 있습니다.

       프로세스가 파일에 접근하기 위해서는 반드시 관련 룰이 추가가 되어야 합니다.


프로세스가 파일에 접근을 하려하면,

커널은 프로세스가 가진 실행권한 Lable을 가져옵니다.

그리고 파일의 접근권한 Label도 가져오죠.

룰에서 실행권한 Label과 접근권한 Label을 찾습니다.

만약 프로세스에게 파일에 지정된 스맥권한이 없다면,

커널에 의해 접근을 거부당하게 됩니다.


체크해야할 권한이 하나 더 늘어났다는 것은,

프로세스입장에서는 가져야할 권한이 하나 더 늘어났다는 것을 의미합니다.

자신이 접근하는 '모든' 파일의 스맥권한을 확인하여,

프로세스의 접근가능 스맥리스트, 룰에 필요한 접근권한 '모두'를 추가해줘야합니다.

그렇지 않으면 프로세스가 제대로 실행되지 않을 수 있습니다.

특정 파일에 접근할 때 Access denied 되어 튕겨나오게 됩니다.


이와 마찬가지로 쉘에서 무언가 실행하고자 할때도 스맥 권한이 필요합니다.

쉘 자체도 프로세스로 동작하는 것이니,

쉘이 갖고 있는 실행권한에 따라 프로세스 런칭 여부가 결정되겠지요.


만약 쉘이 root로 떠 있다면,

스맥설정상태에 따라 모든 스맥 권한을 통과할 수 있습니다.

(사실 root도 스맥 설정에 따라 스맥권한이 없으면 실행 못할 수 있습니다.)


하지만, root가 아닌 사용자계정으로 쉘을 사용하고 있다면,

쉘이 명령어를 실행할 수 있도록 쉘에 스맥권한을 줄 필요가 있습니다.


예를 들어, /usr/bin/gdb를 사용한다고 해보죠.

gdb는 "gdb"라는 스맥실행권한을 갖고 있고요.

쉘에서 gdb를 실행하려면,

- 쉘이 gdb와 동일한 스맥실행권한으로 되어 있거나,

- 쉘이 "gdb"라는 스맥권한에 접근할 수 있도록 쉘의 룰에 "gdb"를 추가해야겠지요?


룰에 접근권한을 추가하는 방법은 차후에 공유하도록 하겠습니다.

여기서는 간단하게 쉘의 스맥권한을 변경하도록 하겠습니다.

쉘의 스맥권한을 변경하려면,

/proc/self/attr/current 값을 변경해야 합니다.

우선 /proc/self에 대해 살펴볼까요?


/proc/self

    This directory refers to the process accessing the /proc

    filesystem, and is identical to the /proc directory named by

    the process ID of the same process.


/proc/self는 말 그대로 자신을 의미합니다.

프로세스는 자신의 pid를 몰라도 /proc/self를 통해 자기 pid의 상태를 알 수 있습니다.

쉘도 프로세스이기 때문에 /proc/self로 쉘 자신의 상태를 살펴볼 수 있습니다.


/proc/[pid]/attr

    The files in this directory provide an API for security

    modules.  The contents of this directory are files that can be

    read and written in order to set security-related attributes.

    This directory was added to support SELinux, but the intention

    was that the API be general enough to support other security

    modules.  For the purpose of explanation, examples of how

    SELinux uses these files are provided below.

    This directory is present only if the kernel was configured

    with CONFIG_SECURITY.


/proc/self/attr에는 자기 프로세스와 관련된 보안정보가 담겨 있습니다.

attr 디렉토리에 담겨있는 파일들은 각각의 역할이 있지요.


$ ls -al /proc/self/attr
합계 0
dr-xr-xr-x 2 user user 0  6월 10 16:29 .
dr-xr-xr-x 9 user user 0  6월 10 16:29 ..
-rw-rw-rw- 1 user user 0  6월 10 16:29 current
-rw-rw-rw- 1 user user 0  6월 10 16:29 exec
-rw-rw-rw- 1 user user 0  6월 10 16:29 fscreate
-rw-rw-rw- 1 user user 0  6월 10 16:29 keycreate
-r--r--r-- 1 user user 0  6월 10 16:29 prev
-rw-rw-rw- 1 user user 0  6월 10 16:29 sockcreate


그 중에서 우리는 current에 주목해야겠지요.

/proc/self/attr/current에는 현재 프로세스가 가지고 있는 스맥실행권한이 명시되어 있습니다.

쉘에서 echo /proc/self/attr/current를 실행하면,

프로세스로서의 쉘이 가지고 있는 스맥실행권한을 알 수 있습니다.


위의 값을 변경한다면,

쉘의 스맥실행권한도 바뀌게 되는 것이죠.

그리고 실행하고자 하는 커맨드와 동일한 스맥실행권한을 설정한다면,

쉘에서도 커맨드명령을 탈없이 실행할 수 있게됩니다.

그렇지 않으면, 쉘에서 도무지 앱을 실행할 수 없는 이상한 경험을 하게 될 겁니다.


# echo "gdb" > /proc/self/attr/current


위와 같은 방법으로 쉘의 스맥실행권한을 변경해보세요.

스맥을 사용하는 환경에서,

쉘이 프로세스의 스맥실행권한을 가져야한다는 것을 기억해두세요. :)


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* References

https://wiki.tizen.org/wiki/Security:Smack#Why_does_.22echo_label_.3E_.2Fproc.2Fself.2Fattr.2Fcurrent.22_change_the_current_process_label_instead_of_the_label_of_the_echo_command.3F

http://man7.org/linux/man-pages/man5/proc.5.html

http://www.apacheweek.gamma.ru/docs/manuals/enterprise/RHEL-4-Manual/en-US/Reference_Guide/s3-proc-self.html

+ Recent posts