給Salt-Master添加加強版的白名單功能

測試環境: salt 2015.8python

##問題 現有的salt-minion有個disable_modules功能,用來禁用指定模塊,簡單粗暴, 不過遠遠不能知足需求,例如管理員經常使用的cmd.run功能,禁用了影響使用體驗, 不由用若是不當心輸入個cmd.run 'rm / -rf',那也是不行的。git

##解決方案 建立白名單功能,例如管理員運行cmd.run,只容許運行指定白名單中的命令如cmd.run 'echo 123', 這個時候若是我想運行cmd.run 'rm / -rf'則直接報錯。github

##設計正則表達式

  • 在master端過濾命令
  • 使用git ext_pillar存放白名單,若是你願意,能夠改爲其餘的。
  • 使用正則表達式匹配命令與參數

pillar樣例:ubuntu

whitelist:
  cmd.run.*:
    - 'echo 1.*'

##具體實現 參考whitelist模塊,源碼在: http://git.oschina.net/fmnisme/salt-whitelistvim

白名單系統值檢查只檢查在whitelist.check_fun_map中的fun,其它命令都是放行的.app

目前只實現了cmd.run.*命令的過濾,若有其它需求,須要本身實現。python2.7

##安裝 個人是ubuntu系統,salt安裝在/usr/lib/python2.7/dist-packages/saltide

  1. whitelist模塊拷貝到salt安裝目錄測試

  2. 修改salt/master模塊

    修改Master.publish方法,在self._send_pub(payload)替換爲以下代碼:

    # whitelist
    from salt.exceptions import SaltCacheError
    from salt.whitelist import check as whitelist_check
    # set git_pillar module
    from salt.pillar import git_pillar
    setattr(git_pillar, "__opts__", self.opts)
    setattr(git_pillar, "__grains__", {})
    git_repo = [x.values()[0] for x in self.opts.get("ext_pillar", {}) if x.keys()[0] == "git"][0]
    # check
    filtered_minions = []
    for minion in minions:
        pillar_data = git_pillar.ext_pillar(minion, git_repo, None)
        check_whitelist_ret = whitelist_check(payload, pillar_data)
        if check_whitelist_ret:
            try:
                load = {
                    'fun_args': payload["arg"],
                    'jid': payload["jid"],
                    'return': check_whitelist_ret,
                    'success': False,
                    'cmd': '_return',
                    'fun': payload["fun"],
                    'id': minion
                }
                salt.utils.job.store_job(self.opts, load, event=self.event, mminion=self.mminion)
            except SaltCacheError:
                log.error('Could not store job information for load: {0}'.format(check_whitelist_ret))
        else:
            filtered_minions.append(minion)
    # send message to filtered_minions
    if filtered_minions:
        # convert `tgt_type` from whatever to `list`
        tgt_list = ",".join(filtered_minions)
        payload["tgt_type"] = "list"
        payload["tgt"] = tgt_list
        # Send it!
        self._send_pub(payload)

    效果以下圖:

    輸入圖片說明

  3. 修改/etc/salt/master

    ext_pillar:
    	  - git:
    	    - master https://your-repo.git:
    	      - user: USERNAME
    	      - password: PASSWORD
    
    	git_pillar_provider: pygit2
    	git_pillar_root: salt/_pillars
    	git_pillar_base: master
  4. 安裝pygit2

    salt目前不支持libgit2-v0.23.2,這裏安裝v0.23.1

    wget https://github.com/libgit2/libgit2/archive/v0.23.1.tar.gz
    	tar xzf v0.23.1.tar.gz
    	cd libgit2-0.23.1/
    	cmake .
    	make
    	make install 
    	ldconfig
    
    	# 使用豆瓣pip源
    	pip install  -i http://pypi.douban.com/simple  pygit2"==0.23.1"
  5. 重啓salt-master

    service salt-master restart

  6. 在git中配置pillar

    # vim salt/_pillars/top.sls
    
    	base:
    	  '*':
    	    - whitelist
    # vim salt/_pillars/whitelist.sls
    
    	whitelist:
    	  cmd.run.*:		#module匹配支持正則
    	    - 'echo 1.*'	#cmd支持正則

    等待salt同步git同步就能夠測試了,由於是在master端,因此不用執行salt '*' saltutil.pillar_refresh

##測試

salt '*39*' cmd.run  'echo 111'
192.168.19.39:
    111
    
salt '*39*' cmd.run  'echo 000'
192.168.19.39:
    'cmd.run' is not in whitelist. arg: ['echo 000']
ERROR: Minions returned with non-zero exit code

#不在whitelist.check_fun_map中的模塊則放行。
salt '*39*' test.ping
192.168.19.39:
    True
相關文章
相關標籤/搜索