Search code examples
ubuntupatchansibleaptshellshock-bash-bug

with Ansible and apt, how do I update bash to for the remotely exploitable security vulnerability CVE-2014-6271?


Given bash's remote code execution vulnerability announced on Sept 24 2014, how can I update my apt-based systems using Ansible?


Solution

  • Here's my preferred solution in a fairly homogenous environment. The advantage of this is the update won't take a lot of time in the future, unlike the version=latest pattern others are using.

    - name: update apt cache if not done today
      apt: update_cache=yes cache_valid_time=86400
    
    # http://seclists.org/oss-sec/2014/q3/650
    - name: ensure secure ansible, ubuntu 1204 edition
      apt: pkg=bash=4.2-2ubuntu2.5 state=present
      when: ansible_distribution=='Ubuntu' and ansible_distribution_version=='12.04'
    
    - name: ensure secure ansible, ubuntu 1404 edition
      apt: pkg=bash=4.3-7ubuntu1.3 state=present
      when: ansible_distribution=='Ubuntu' and ansible_distribution_version=='14.04'
    
    # based on the following gist and comments below. there have been several exploits, this covers them well.
    # https://gist.github.com/kacy/2b9408af04c71fab686e
    - name: ensure bash is not vulnerable to 201409 problem
      shell: "foo='() { echo not patched; }' bash -c foo"
      register: command_result
      ignore_errors: yes
      failed_when: "'command not found' not in command_result.stderr"
    

    Explanation: updating the apt-cache is expensive if done many times per day. The cache time can be adjusted. The code actually tests to make sure the vulnerability is fixed- tests are good. This will highlight any hosts that aren't covered by the distributions/versions coded.

    SO user @jarv posted a great solution too. Instead of always updating apt, it only does so if the problem hasn't been fixed. This is the fastest solution possible (in this answer, at least). jarv has also added a distribution test in the linked repo, useful for heterogeneous environments.

    - name: Check if we are vulnerable
      shell: executable=/bin/bash env x='() { :;}; echo vulnerable'  bash -c "echo this is a test"
      register: test_vuln
    
    - name: Apply bash security update if we are vulnerable
      apt: name=bash state=latest update_cache=true
      when: "'vulnerable' in test_vuln.stdout"
    
    - name: Check again and fail if we are still vulnerable
      shell: executable=/bin/bash env x='() { :;}; echo vulnerable'  bash -c "echo this is a test"
      when: "'vulnerable' in test_vuln.stdout"
      register: test_vuln
      failed_when: "'vulnerable' in test_vuln.stdout"
    

    There are other ways. Michael DeHaan, creator of Ansible, and the official @ansible account tweeted a few solutions:

    Here's a one-liner:

    ansible all -m apt -a 'update_cache=yes name=bash state=latest'
    

    Here's a update-and-check solution:

    - name: update apt
      command: apt-get update
    
    - name: update bash
      command: apt-get --only-upgrade install bash
    
    - name: check bash fix
      command: env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
      register: command_result
      failed_when: "'error' not in command_result.stderr"