Linux
Security
SELinux

SECMARK を使用して SELinux でパケットを制御する

More than 1 year has passed since last update.


概要

SECMARK を利用すると、パケットに対しSELinuxのラベルを付与することができ、

SELinux のポリシーでアクセス制限を行うことができる。

つまり、ユーザ毎やアプリケーション毎に細かくパケットを制御することも可能。


検証環境

CentOS Linux release 7.3.1611 (Core)


  • sestatus

SELinux status:                 enabled

SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28


検証環境の準備


Disable firewalld

検証を行う上で firewalld は邪魔なので無効化

# systemctl disable --now firewalld


Install packages

# yum install setools-console selinux-policy-devel


Create user

# useradd -m user1

# semanage login -a -s user_u user1
# useradd -m user2
# semanage login -a -s staff_u user2
# semanage login -l

Login Name SELinux User MLS/MCS Range Service

__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
user1 user_u s0 *
user2 staff_u s0-s0:c0.c1023 *

[user1@localhost]$ id -Z

user_u:user_r:user_t:s0


検証


未設定状態

[user1@localhost]$ curl -I www.google.com

HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.co.jp/?gfe_rd=cr&dcr=0&ei=Z9SuWYz6KLTEXvPYsKAN
Content-Length: 269
Date: Tue, 05 Sep 2017 16:44:23 GMT

[user1@localhost]$ curl -I 54.64.138.248
HTTP/1.1 301 Moved Permanently
Date: Tue, 05 Sep 2017 16:45:21 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Server: Apache
Location: https://cookpad.com/


Policyの作成

secmark.cil

;; Definition of myhttp_client_packet_t

(type myhttp_client_packet_t)
(roletype object_r myhttp_client_packet_t)
(typeattributeset packet_type (myhttp_client_packet_t))

;; Definition of default_http_client_packet_t
(type default_http_client_packet_t)
(roletype object_r default_http_client_packet_t)
(typeattributeset packet_type (default_http_client_packet_t))

;; Rule
(allow user_t myhttp_client_packet_t (packet (send recv)))
(neverallow user_t default_http_client_packet_t (packet (send recv)))

この CIL ファイルは以下のことを行っている


  • myhttp_client_packet_t の定義


    • roletype は object_r

    • packet_type と関連付ける



  • default_http_client_packet_t の定義


    • roletype は object_r

    • packet_type と関連付ける



  • user_t が myhttp_client_packet_t:packet の send と recv を許可する(allow)

  • user_t が default_http_client_packet_t:packet の send と recv を許可しない(neverallow)

この定義を以下のコマンドで読み込む。

# semodule -i secmark.cil


packet にSecurityラベルをつける

iptables コマンドを利用します。

# iptables -t security -A OUTPUT -p tcp --dport 80 -j SECMARK --selctx "system_u:object_r:default_http_client_packet_t:s0"

# iptables -t security -A OUTPUT -p tcp -d 54.64.138.248 --dport 80 -j SECMARK --selctx "system_u:object_r:myhttp_client_packet_t:s0"
# iptables -t security -A OUTPUT -p tcp --dport 80 -j CONNSECMARK --save
# iptables -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore
# iptables -t security -vnL
Chain INPUT (policy ACCEPT 1014 packets, 74846 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 607 packets, 145K bytes)
pkts bytes target prot opt in out source destination
25 1653 SECMARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 SECMARK selctx system_u:object_r:default_http_client_packet_t:s0
0 0 SECMARK tcp -- * * 0.0.0.0/0 54.64.138.248 tcp dpt:80 SECMARK selctx system_u:object_r:myhttp_client_packet_t:s0
25 1653 CONNSECMARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 CONNSECMARK save
545 142K CONNSECMARK all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED CONNSECMARK restore


試す

[user1@localhost ~]$ curl -I www.google.com

curl: (7) Failed to connect to 172.217.24.132: 接続を拒否されました
[user1@localhost ~]$ curl -I 54.64.138.248
HTTP/1.1 301 Moved Permanently
Date: Tue, 05 Sep 2017 16:54:08 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Server: Apache
Location: https://cookpad.com/

54.64.138.248 へのリクエストだけ許可された。

もちろん user_t ではない Context だとポリシーが定義されていないので許可されない。

[user2@localhost ~]$ id -Z

staff_u:staff_r:staff_t:s0-s0:c0.c1023
[user2@localhost ~]$ curl -I www.google.com
curl: (7) Failed to connect to 216.58.200.196: 接続を拒否されました
[user2@localhost ~]$ curl -I 54.64.138.248
curl: (7) Failed to connect to 54.64.138.248: 接続を拒否されました

unconfined_t なユーザは CentOS(RHEL) の targeted モードだと全て許可するポリシーがデフォルトで定義されているのでパケットは出ていくことができる。

[root@localhost ~]# id -Z

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

[root@localhost ~]# curl -I www.google.com
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.co.jp/?gfe_rd=cr&dcr=0&ei=9NauWfGhOILR8gfV1ZegDA
Content-Length: 271
Date: Tue, 05 Sep 2017 16:55:16 GMT

[root@localhost ~]# curl -I 54.64.138.248
HTTP/1.1 301 Moved Permanently
Date: Tue, 05 Sep 2017 16:55:43 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Server: Apache
Location: https://cookpad.com/


参考文献