Playbook ansible permisos

I have many vulnerabilities on different servers on different routes on each server, I must remove the write permission from others just remove the write permission from others… there are many servers and on different routes how could I do using ansible?

Hello @Jasonroot1. It isn’t clear to me what you mean by “routes on … servers”. I’m going to guess you aren’t talking about network routes, partly because that involves firewalls, DNS, and other things I’m particularly uninterested in and rather useless at anyway. (Just ask my co-workers!) I’m also hoping it’s not about http server configuration such as Apache Location, Directory, or Alias directives.

If you mean permissions on directories, then you can probably fix your permissions issues with the ansible.builtin.file module. That module lets you manage pretty much everything about files (and directories) except their content. If the path parameter is a directory name, and you set the state parameter to "directory", then you can use the mode parameter to specify the permissions that directory should have. In the case where state: directory, you can also set recurse: true to set the mode as specified for that directory and all subdirectories of that directory. Like this:

    - name: Recursively remove "read,write,execute" mode for "other"
      ansible.builtin.file:
        path: '{{ tgt }}'
        mode: 'o-rwx'
        state: directory
        recurse: true

You can loop over a list of top-level directories and remove the “other” mode bits like this:

    - name: Recursively remove "read,write,execute" mode for "other" in several places
      ansible.builtin.file:
        path: '{{ item }}'
        mode: 'o-rwx'
        state: directory
        recurse: true
      loop:
        - /opt/local/server1/data
        - /var/tmp/server1
        - /tmp/server1/foo

Beware though. You mentioned “many servers on different routes”. If you run the above task on multiple hosts, it will create those directories on any hosts where they don’t already exist. This may not be acceptable, in which case you could either:

  • check their existence on each host first with the ansible.builtin.stat module, and execute the above task only on directories that already exist, or
  • use the ansible.builtin.shell module to find directories on your list and chmod them as appropriate using a carefully crafted shell script.

Let us know if this addresses your issue, and how you get on with solving the problem. As always, please include any relevant details. Reducing the guess work we have to do increases the quality of the help we can offer you — a win-win!

1 Like

I have a list of servers where there are many different directories for each server where I must remove write permissions for others in each directory, is there a way to generate the server inventory with the directories and that the removal of the write permission is applied?

You have a list of servers, so that’s your inventory.

I don’t particularly like putting variable values (with perhaps an exception for connection parameters) in inventories. I prefer to create group_vars files where possible, and host_vars files where necessary, and to populate them with whatever variables I need.

But to answer your question: sure, there are lots of ways to associate lists of directories that match whatever criteria you want with individual hosts or groups of hosts.

Let me turn the question around, since I know nothing about these hosts or the directories on them: On any given server, how would you identify which directories you need to “fix” the permissions on? That is, if you had to do this by hand, how would you find them? Once that’s understood, you can use Ansible to automate that discovery process.

Alternatively, perhaps you can produce a “global” list of all such directories across all your hosts, with the understanding that not all these directories will necessarily exist on all the hosts. If so, you can use Ansible to fix the directories in that list on each host, skipping the ones that don’t exist on particular hosts of course.

A third method would be to start at the root level and exclude all the “normal” directories - those that are part of all systems - leaving only the potential target directories. But that’s a rather scary way to go about it; one mistake could leave a lot of machines in a bad way. Maybe better to forget I even mentioned this “3rd rail” approach.

Whichever way you choose, you also have to decide whether to combine the “problem directory discovery” process with the “fix problem directory” process, or alternatively to use the discovery process to generate lists to use in a later process.

You’re in a much better position than I am to determine which approach to take, since you presumably have some idea about your directory layouts and I certainly don’t. But once you pick a method, after that it’s “just” filling in the details.

1 Like

Hi,

The case is the following, I have vulnerabilities about permissions in different directories on different servers, not all directories are on all servers, I must remove write permissions for others for example ( permissions 664 ) I thought of copying a file with the hosts and the corresponding routes on each server and create a playbook that will first run join me and print the result in the following as a variable and execute a command, for example: FIND . -name ‘hostname’ awk print $2 ( it would be the directory ) and this print it in the next task so that it looks like this way: chmod o-w directory

There are many directories, manually it takes a lot of time and for security reasons it is not allowed to run a script

and

This is beginning to point at useful details. Specifically:

  1. Can you produce a list of directories of interest?
  2. For any such directory, can we assume that all of its subdirectories are subject to the same treatment?
1 Like

They are files files, I have the list of everything, for example. /example/example/example.log, which I don’t know is how to do it in bulk, How to tell him to look for the server within a list and look for the files and change the permission, I don’t know how to tell him to look for uj file where the directories or files are, I have only worked with inventory hosts, I don’t know how to do it

If you have your list of everything, you can plug it into the following and fix the mode bits for “other”. Feel free to ask about anything that isn’t clear.

---
# file-mode-fix.yml
- name: File mode parameter
  hosts: localhost  # ← Use whatever is appropriate here
  gather_facts: false
  vars:
    paths_to_fix: # List of all "interesting" files and directories on all hosts
      - /tmp/file-mode-fix/aaa
      - /tmp/file-mode-fix/aaa/iii
      - /tmp/file-mode-fix/aaa/iii/w.ext
      - /tmp/file-mode-fix/aaa/iii/x.ext
      - /tmp/file-mode-fix/aaa/iii/y.ext
      - /tmp/file-mode-fix/aaa/jjj/v.ext
      - /tmp/file-mode-fix/aaa/jjj/z.ext
      - /tmp/file-mode-fix/bbb
      - /tmp/file-mode-fix/bbb/iii/x.ext
      - /tmp/file-mode-fix/bbb/iii/y.ext
      - /tmp/file-mode-fix/ccc
      - /tmp/file-mode-fix/ccc/iii/y.ext
      - /tmp/file-mode-fix/ccc/jjj/y.ext
      - /tmp/file-mode-fix/ccc/jjj/y.ext

  tasks:
    - name: Stat paths_to_fix
      ansible.builtin.stat:
        path: '{{ item }}'
      loop: '{{ paths_to_fix }}'
      register: paths_stats

    - name: Save stats of existing directories
      ansible.builtin.set_fact:
        stats_dirs: '{{ paths_stats.results
                        | selectattr("stat.exists")
                        | selectattr("stat.isdir") }}'

    - name: Fix mode of directories
      ansible.builtin.file:
        path: '{{ item.item }}'
        mode: 'o-rwx' # or however you want to change directory modes
        state: directory
        recurse: true  # or false if you don't want to do this to all sub-directories
      loop: '{{ stats_dirs }}'

    - name: Save stats of existing files
      ansible.builtin.set_fact:
        stats_files: '{{ paths_stats.results
                        | selectattr("stat.exists")
                        | selectattr("stat.isreg") }}'

    - name: Fix mode of files
      ansible.builtin.file:
        path: '{{ item.item }}'
        mode: 'o-rwx' # or however you want to change file modes
        state: file
      loop: '{{ stats_files }}'
3 Likes

paths_to_fix: # List of all “interesting” files and directories on all hosts

Couldn’t it be a txt file or a kind of inventory where I consult? There are a lot of directories/files

It could be, yes. There are lots of different ways to get a list into Ansible.

And that code I posted is just one way to go about it. If this is a one-off task, I wouldn’t put much effort into making it beautiful or efficient. On the other hand, if you intend to repeat the process periodically, then you may want to think about how to refresh the list, whether to come up with a way to do it host-by-host, etc.

You’ve said something equivalent to “a lot of directories/files” several times, but you’ve never given a hint what you think of as “a lot”. For me, it isn’t “a lot” until it’s more that 10,000. Others may reasonably draw the line at “a couple of screen fulls”. I routinely edit files with over a million lines. And by “edit” I mean “run some macros on”. One’s notion of “a lot” depends on how well your tool chain allows your processes to remain painless.

2 Likes

There are approximately 5000, the playbooks that I have generated have already been for another type of simpler tasks, and it is a relatively periodic task, I do not know how to use a list from a txt, I apologize my level in Ansible is still very basic I am still learning and so far what you have shared with me has filled me with great knowledge, I do not know if you could tell me how I could do it by calling a file where you are the directories, that I can use it next month, as I told you it is a topic related to remediation of vulnerabilities so it is something that will be executed in a cyclical way

Okay, here’s an even shorter version that loads the list of files and directories from a file.

The grep in the first task skips blank lines and lines where the first non-space character is a pound sign (#), so you can put in comments and some white-space to help manage the file.

There’s a commented-out one-line quick-n-dirty debug task in case you want to see how the registered output from the stat module is structured.

This version dispenses with the set_fact steps, instead looping over paths_stats filtered to include just the directory names or file names relevant to your target host.

Change the value of “paths_to_fix_filename” to point to your file of file and directory names. You might want to experiment with a very small subset of files – five or six maybe – on a very small subset of target hosts (1?) until you’re comfortable with what it’s doing.

The biggest question in the “what it’s doing” category is about the “recurse: true” on the “Fix mode of existing directories” task. That’s a mighty big hammer for a guy with only two thumbs, so be careful.

---
# file-mode-fix.yml
- name: File mode parameter
  hosts: localhost  # ← Use whatever is appropriate here
  gather_facts: false
  vars:
    paths_to_fix_filename: file-mode-fix-interesting_files.txt

  tasks:
    - name: Load interesting_files
      ansible.builtin.command:
        grep -v -E '^ *(#.*)?$' "{{ paths_to_fix_filename }}"
      changed_when: false
      register: paths_to_fix

    - name: Stat paths_to_fix
      ansible.builtin.stat:
        path: '{{ item }}'
      loop: '{{ paths_to_fix.stdout_lines }}'
      register: paths_stats

#   - debug: msg='{{ paths_stats }}'

    - name: Fix mode of existing directories
      ansible.builtin.file:
        path: '{{ item }}'
        mode: 'o-rwx' # or however you want to change directory modes
        state: directory
        recurse: true  # or false if you don't want to do this to all sub-directories
      loop: '{{ paths_stats.results
                | selectattr("stat.exists")
                | selectattr("stat.isdir")
                | map(attribute="stat.path") }}'

    - name: Fix mode of existing files
      ansible.builtin.file:
        path: '{{ item }}'
        mode: 'o-rwx' # or however you want to change file modes
        state: file
      loop: '{{ paths_stats.results
                | selectattr("stat.exists")
                | selectattr("stat.isreg")
                | map(attribute="stat.path") }}'
1 Like

It doesn’t work, the online routes, it takes them as if they were the same line

Interesting. It worked with my sample.
Do you know what the line termination character(s) is/are on the file? This would show us:

$ head online_routes.txt | od -tx1a

You’re looping over paths_to_fix_filename, which is supposed to be the name of the file that has the paths of interest. It’s just a string; a file name.

What you’re supposed to be looping over is the registered result from the prior step, which you have called variable_result.

Look over the code from earlier. It’s not what you are running. Study it a bit more. You’ll get there eventually.

2 Likes