jasonish / docker-suricata

A Suricata Docker image.
https://hub.docker.com/r/jasonish/suricata/
MIT License
250 stars 76 forks source link

cannot create regular file '/etc/suricata/classification.config': Permission denied #12

Closed ghost closed 3 years ago

ghost commented 3 years ago

Operating System

CentOS 7

Ansible

I am creating the container using the Ansible docker_container module.

Ansible Options

pyx_docker_container:
  name: rick-poc-suricata-image
  image: jasonish/suricata:latest
  interactive: true
  tty: true
  auto_remove: false
  recreate: true
  capabilities:
    - net_admin
    - sys_nice
  cap_drop:
    - all
  command: ["echo", "hello suricata"]
  entrypoint: ["/bin/sh", "/docker-entrypoint.sh"]
  network_mode: host
  user: suricata:suricata
  volumes:
    - /vagrant/playbooks/log:/var/log/suricata:rw
    - /vagrant/playbooks/lib:/var/lib/suricata:rw
    - /vagrant/playbooks/etc:/etc/suricata:rw

Ansible Command

$ ansible-playbook -vvv -i hosts install_security_tool.yml

Expected Outcome

container successfully created and running

Actual Output

fatal: [127.0.0.1]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "api_version": "auto",
            "auto_remove": false,
            "blkio_weight": null,
            "ca_cert": null,
            "cap_drop": [
                "all"
            ],
            "capabilities": [
                "net_admin",
                "sys_nice"
            ],
            "cleanup": false,
            "client_cert": null,
            "client_key": null,
            "command": [
                "echo",
                "hello suricata"
            ],
            "comparisons": null,
            "cpu_period": null,
            "cpu_quota": null,
            "cpu_shares": null,
            "cpuset_cpus": null,
            "cpuset_mems": null,
            "debug": false,
            "detach": false,
            "device_read_bps": null,
            "device_read_iops": null,
            "device_write_bps": null,
            "device_write_iops": null,
            "devices": [],
            "dns_opts": null,
            "dns_search_domains": null,
            "dns_servers": null,
            "docker_host": "unix://var/run/docker.sock",
            "domainname": null,
            "entrypoint": [
                "/bin/sh",
                "/docker-entrypoint.sh"
            ],
            "env": null,
            "env_file": null,
            "etc_hosts": null,
            "exposed_ports": [],
            "force_kill": false,
            "groups": [
                "users"
            ],
            "healthcheck": null,
            "hostname": "",
            "ignore_image": false,
            "image": "jasonish/suricata:latest",
            "init": false,
            "interactive": true,
            "ipc_mode": null,
            "keep_volumes": true,
            "kernel_memory": null,
            "kill_signal": null,
            "labels": {},
            "links": null,
            "log_driver": null,
            "log_options": null,
            "mac_address": null,
            "memory": "0",
            "memory_reservation": null,
            "memory_swap": null,
            "memory_swappiness": null,
            "mounts": null,
            "name": "rick-poc-suricata-image",
            "network_mode": "host",
            "networks": [],
            "networks_cli_compatible": true,
            "oom_killer": null,
            "oom_score_adj": null,
            "output_logs": false,
            "paused": false,
            "pid_mode": null,
            "pids_limit": null,
            "privileged": false,
            "published_ports": null,
            "pull": false,
            "purge_networks": false,
            "read_only": false,
            "recreate": true,
            "restart": false,
            "restart_policy": null,
            "restart_retries": null,
            "runtime": null,
            "security_opts": null,
            "shm_size": null,
            "ssl_version": null,
            "state": "started",
            "stop_signal": null,
            "stop_timeout": null,
            "sysctls": null,
            "timeout": 60,
            "tls": false,
            "tls_hostname": "localhost",
            "tmpfs": null,
            "trust_image_content": false,
            "tty": true,
            "ulimits": null,
            "user": "suricata:suricata",
            "userns_mode": null,
            "uts": null,
            "validate_certs": false,
            "volume_driver": "",
            "volumes": [
                "/vagrant/playbooks/log:/var/log/suricata:rw",
                "/vagrant/playbooks/lib:/var/lib/suricata:rw",
                "/vagrant/playbooks/etc:/etc/suricata:rw"
            ],
            "volumes_from": [],
            "working_dir": ""
        }
    },
    "msg": "Creating /etc/suricata/classification.config.\r\ncp: cannot create regular file '/etc/suricata/classification.config': Permission denied\r\n",
    "status": 1
}

## Inspecting the Container

$ sudo docker run --rm -it jasonish/suricata:latest /bin/bash

ls -l /etc/suricata

total 92 -rw-------. 1 suricata suricata 4258 Sep 15 05:55 classification.config -rw-------. 1 suricata suricata 1375 Sep 15 05:55 reference.config -rw-------. 1 suricata suricata 70491 Sep 15 05:55 suricata.yaml -rw-------. 1 suricata suricata 1644 Sep 15 05:55 threshold.config -rw-rw-r--. 1 suricata suricata 43 Sep 15 05:49 update.yaml



## Thoughts?
jasonish commented 3 years ago

In your Ansible config you'll have to remove the cap-drop and user settings. The user setting will start the container as the the Suricata user. For Suricata to run properly it needs to be root. If it has the capabilities sys_nice and net_admin, it will change its uid to the suricata user after its done what it needs to do as root.

And the cap-drop option appears to remove capabilities that are previously added. So unless you need to drop specific capabilities, I'd leave this option out. Suricata needs the sys_nice and net_admin capabilities so it can stop running as root, yet operate normally.

ghost commented 3 years ago

Thanks @jasonish. That solved this issue. Now I need to figure out why the container exits as soon as it is started.

jasonish commented 3 years ago

Try a command of "-i "..

I'm not really sure how Ansible is doing this.. Maybe its rebuilding the image? But you want to replicate this:

docker run --rm -it --net=host \
    --cap-add=net_admin --cap-add=sys_nice \
    jasonish/suricata:latest -i <interface>

with your own mounts of course. Your volume mounts do look OK.

I still need to streamline (or simply document) the process of rule updates and log rotation with Suricata in Docker though.

ghost commented 3 years ago

I think that is the problem. The Ansible module doesn't have an obvious way to specify the interface for the host network. I need to work with them to see if it can or can't be done now. Feel free to close this issue. Your code is working fine. Thanks for your help.

jasonish commented 3 years ago

That shouldn't be needed.. Host network in Docker just exposes all the interfaces on the host inside the container, almost as if the app wasn't running in the container.. So eno1 on the host is eno1 inside the container and so on.

ghost commented 3 years ago

That makes sense. I just wish Ansible had a way to specify the one I want to use then it would support the -i option.

ghost commented 3 years ago

I figured out I can specify the -i option through CMD. Now the container runs fine. I will close this as everything is now working perfectly.