天天看點

【轉載】 屏蔽Ansible中的危險指令方法

批量執行指令時,需要把一些危險指令屏蔽掉,進而将降低使用人員的誤操作。

測試環境

ansible 2.3.0.0

os Centos 6.7 X64

python 2.6.6

需要過濾規則的子產品

command

shell

script

raw

需要過濾的指令

rm -rf /

halt

poweroff

reboot

shutdown -h now

shutdown -r now

編寫過濾代碼

我們在解析完task後進行過濾,這就是/usr/lib/python2.6/site-packages/ansible/playbook/play.py中的Play類的load方法

我們在這個檔案最後面,添加一個filter_cmd方法,進行過濾指令。代碼如下:

def filter_cmd(data):

  filter_modules = ('command', 'shell', 'script', 'raw')

  filter_commands = ('rm -rf /','halt', 'poweroff', 'reboot', 'shutdown -h now','shutdown -r now')

  filter_commands = map(lambda x:x.replace(' ', '').lower(), filter_commands)

  for t in data['tasks']:

    if'action' in t:

      if t['action']['module'] in filter_modules:

        if t['action']['args']['_raw_params'].replace(' ', '').lower() in filter_commands:

          raise AnsibleParserError("Refused to execute the [%s] command in the [%s] module." % (t['action']['args']['_raw_params'], t['action']['module']))

    else:

      for m in filter_modules:

        if m in t:

          args=parse_kv(t[m], check_raw=True)

          if args['_raw_params'].replace(' ', '').lower() in filter_commands:

            raise AnsibleParserError("Refused to execute the [%s] command in the [%s] module." % (t[m], m))

在Play類的load方法中引用filter_cmd過濾指令

在p = Play()上方添加filter_cmd(data)  ,如下紅色部分:

    @staticmethod

    def load(data, variable_manager=None, loader=None):

        if ('name' not in data or data['name'] is None) and 'hosts' in data:

            if isinstance(data['hosts'], list):

                data['name'] = ','.join(data['hosts'])

            else:

                data['name'] = data['hosts']

        filter_cmd(data)

        p = Play()

        return p.load_data(data, variable_manager=variable_manager, loader=loader)

在檔案頂部引入需要的子產品

from ansible.parsing.splitter import parse_kv

注意:不要加在from __future__ import (absolute_import, division, print_function)這行的上面,會報錯的。

測試ansible

[root@master ansible]# ansible node1 -m shell -a 'halt'

ERROR! Refused to execute the [halt] command in the [shell] module.

[root@master ansible]# ansible node1 -m shell -a 'rm -rf /'

ERROR! Refused to execute the [rm -rf /] command in the [shell] module.

[root@master ansible]# ansible node1 -m command -a 'shutdown -r now'

ERROR! Refused to execute the [shutdown -r now] command in the [command] module.

[root@master ansible]# ansible localhost -m command -a 'echo shutdown -r now'

localhost | SUCCESS | rc=0 >>

測試ansible-playbook

[root@master ansible]# cat  test_filter.yml

- hosts: node1

  tasks:

   - name: test

     command: "rm -rf / chdir=/tmp/ creates=/tmp/a.txt"

[root@master ansible]# ansible-playbook test_filter.yml

ERROR! Refused to execute the [rm -rf / chdir=/tmp/ creates=/tmp/a.txt] command in the [command] module.

     shell: "shutdown -r now"

ERROR! Refused to execute the [shutdown -r now] command in the [shell] module.

測試正常通過。

本文轉自 lirulei90 51CTO部落格,原文連結:http://blog.51cto.com/lee90/2069699,如需轉載請自行聯系原作者