{"id":13588079,"url":"https://github.com/ryandaniels/ansible-role-iptables-docker","last_synced_at":"2025-04-10T20:41:03.319Z","repository":{"id":76096178,"uuid":"263222139","full_name":"ryandaniels/ansible-role-iptables-docker","owner":"ryandaniels","description":"Manage iptables configuration to secure Docker (and Docker Swarm) using Ansible","archived":false,"fork":false,"pushed_at":"2020-07-24T03:07:08.000Z","size":28,"stargazers_count":26,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T18:11:53.848Z","etag":null,"topics":["ansible","ansible-role","docker","docker-swarm","iptables","iptables-configuration"],"latest_commit_sha":null,"homepage":"https://galaxy.ansible.com/ryandaniels/iptables_docker","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryandaniels.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-05-12T03:25:43.000Z","updated_at":"2024-09-22T09:27:44.000Z","dependencies_parsed_at":"2023-03-03T02:46:07.695Z","dependency_job_id":null,"html_url":"https://github.com/ryandaniels/ansible-role-iptables-docker","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryandaniels%2Fansible-role-iptables-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryandaniels%2Fansible-role-iptables-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryandaniels%2Fansible-role-iptables-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryandaniels%2Fansible-role-iptables-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryandaniels","download_url":"https://codeload.github.com/ryandaniels/ansible-role-iptables-docker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248292618,"owners_count":21079466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-role","docker","docker-swarm","iptables","iptables-configuration"],"created_at":"2024-08-01T15:06:29.959Z","updated_at":"2025-04-10T20:41:03.296Z","avatar_url":"https://github.com/ryandaniels.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Ansible Role: iptables for Docker (and Docker Swarm)\r\n\r\nAdd firewall rules to server via iptables, for Docker, and Docker Swarm. This will actually protect your Docker containers!  \r\nThis Ansible Role exists because firewalld and Docker (and Docker Swarm) do not get along.  \r\n\r\nProblem being solved: When starting a container in Docker with a \"published\" port, you have no control and the port is exposed through your server's firewall. Even if you were using iptables, or another firewall on your server. Docker opens that \"published\" port to everyone, and bypasses your firewall.  \r\n\r\nUse case for this solution: Allow trusted IPs to connect to Docker containers (and Docker Swarm containers), along with other open OS ports. With an option to expose specified ports publicly (Docker/Docker Swarm and OS). The trusted IPs might not be in the same network IP range, or even the same network subnet.  \r\n\r\nThis was suppose to be simple. Secure Docker with a firewall. But unfortuanately it is not. I've tried to keep this as simple as possible.  \r\n\r\nThere could be unknown problems with this.. use at your own risk!  \r\n\r\nSee also: \u003chttps://ryandaniels.ca/blog/secure-docker-with-iptables-firewall-and-ansible/\u003e  \r\nAnd about Docker's use of the INPUT chain: \u003chttps://ryandaniels.ca/blog/docker-iptables-input-chain/\u003e\r\n\r\nCurrently tested and working on:\r\n\r\n* CentOS/RHEL 7\r\n* Ubuntu 18.04\r\n* Ubuntu 20.04\r\n\r\n## Features\r\n\r\n* Works with Docker, and Docker Swarm (aka Docker SwarmKit).\r\n* Secure by default. Once configured, only Docker IPs can access all containers, and all other OS processes that have open ports on the server.\r\n* Simple as possible. The less iptables rules, the faster performance will be (in theory at least).\r\n* Automatic. No manually adding ports to the firewall config (if you use a trusted set of IPs)\r\n* Add \"trusted\" IPs that are allowed to communicate with all Docker containers, and all other OS processes that have open ports on the server.\r\n* Open specified Docker container ports, or the server's OS ports to the public (everyone) through the firewall, like SSH.\r\n* Interfaces can also be specified. By default all interfaces are filtered. You could filter specific network interface(s) and allow all other interfaces (only specify an untrusted interface).\r\n* Everything done in \"offline\" mode. So there should be no issues with Docker when iptables rules are activated.\r\n* You don't need to be an expert with iptables to use this.\r\n* Works with Docker Swarm's undocumented use of iptables and encrypted overlay networks. (iptables rules are appeneded to the INPUT chain).\r\n\r\nThis solution is using `iptables` as the firewall, and `ipset` to allow iptables to have a list of IPs that are allowed. `ipset` also allows you to use a non-continueous range of IPs.  \r\n\r\niptables chains used, and how:  \r\n**INPUT**, not flushed. Rule inserted at top to jump to custom chain for OS related rules.  \r\n**DOCKER-USER**, flushed. All Docker (and Docker Swarm) related rules are here to block containers from being exposed to everyone by default. By default only the Docker server IPs are allowed. Other IPs and container ports can be added by user.  \r\n**FILTERS**, flushed. Custom chain for server's processes (that aren't Docker). By default only the Docker server IPs are allowed. Other IPs and container ports can be added by user.  \r\n\r\niptables manual: \u003chttp://ipset.netfilter.org/iptables.man.html\u003e  \r\n\r\n## Warnings\r\n\r\nDon't lock yourself out of your server. This is modifying your firewall. Always have another way to get in, like a \"console\".  \r\n\r\n**Note about IPs**: This is for IPv4 only. IPv6 has not been tested. It is safer if you disable IPv6 on your servers.  \r\n\r\n**Other security consideration**:  \r\nIf using non-Swarm (normal Docker), consider also binding a port to an internal IP for better security.\r\nIf using Swarm, consider using specific IPs for Docker Swarm communication.  \r\nEg. `docker swarm init --advertise-addr 192.168.100.100 --listen-addr=192.168.100.100 --data-path-addr=192.168.100.100`\r\n\r\n**Important Note**: Docker and firewalld do not get along. This Ansible Role has a check enabled to fail this role if the firewalld service is running or enabled.  \r\nFor more information about firewalld and Docker:  \r\n\u003chttps://success.docker.com/article/why-am-i-having-network-problems-after-firewalld-is-restarted\u003e  \r\n\u003chttps://www.tripwire.com/state-of-security/devops/psa-beware-exposing-ports-docker/\u003e  \r\n\u003chttps://docs.docker.com/network/iptables/\u003e  \r\n\r\n**SELinux Bug**:  \r\nCurrently there's a bug with SELinux that prevents saving the iptables rules to the iptables.save file.  \r\nImpact: Saving the iptables rules a 2nd time will silently fail.  \r\nWorkaround has been added so SELinux allows chmod to interact with the iptables.save file.  \r\nAlternatively you could disable SELinux, but that's not recommended.  \r\nBug report: \u003chttps://bugs.centos.org/view.php?id=12648\u003e  \r\nSee [below](#selinux-manual-workaround-for-iptables-and-chmod) for more details about manually performing the workaround.  \r\n\r\n**WARNING**:  \r\nMake sure you test in non-production first, I cannot make any guarantees or held responsible.  \r\nBe careful, this will remove and add iptables rules on the OS. Use with caution.  \r\nExisting iptables rules could be removed! Confirm what you have setup before running this.  \r\n\r\nThere could be unknown problems with this.. use at your own risk!  \r\n\r\n## Docker versions tested\r\n\r\nDocker Engine - Community Edition version:\r\n\r\n* 19.03.8\r\n* 19.03.9\r\n* 19.03.12\r\n\r\nTested in normal Docker mode, and with a 3 node Docker Swarm cluster.  \r\n\r\n## Distros tested\r\n\r\n* CentOS: 7.7, 7.8\r\n* Ubuntu 18.04\r\n* Ubuntu 20.04\r\n\r\n## Dependencies\r\n\r\n* iptables \u0026 iptables-services\r\n\r\nTested with v1.4.21 (Latest available in CentOS 7)  \r\n\r\n* ipset \u0026 ipset-service\r\n\r\nTested with v7.1 (Latest available in CentOS 7)  \r\n\r\n## Default Settings\r\n\r\n* Enable debug\r\n\r\n```yaml\r\ndebug_enabled_default: false\r\n```\r\n\r\n* Proxy (Needed when installing required packages if behind a proxy)\r\n\r\n```yaml\r\nproxy_env: []\r\n```\r\n\r\n* Role disabled by default. Change to true in group_vars or playbook etc\r\n\r\n```yaml\r\niptables_docker_managed: false\r\n```\r\n\r\n* Check if (Docker) service is running or enabled, and fail the role\r\n\r\n```yaml\r\niptables_docker_check_problem_service_managed: true\r\n```\r\n\r\n* Services to check, and fail the role\r\n\r\n```yaml\r\niptables_docker_check_problem_service:\r\n  - docker.service\r\n```\r\n\r\n* Show configuration from variables\r\n\r\n```yaml\r\niptables_docker_show_config: true\r\n```\r\n\r\n* Start iptables service\r\n\r\n```yaml\r\niptables_docker_start: true\r\n```\r\n\r\n* Install iptables package\r\n\r\n```yaml\r\niptables_docker_managed_pkg: true\r\niptables_docker_packages:\r\n  - iptables\r\n  - iptables-services\r\n  - ipset\r\n  - ipset-service\r\n  - policycoreutils-python #required for semodule\r\n```\r\n\r\n* Force copy of ipset file to trigger ipset reload\r\n\r\n```yaml\r\niptables_docker_copy_ipset_force: false\r\n```\r\n\r\n* Force copy of iptables file to trigger iptables reload\r\n\r\n```yaml\r\niptables_docker_copy_iptables_force: false\r\n```\r\n\r\n* iptables saved configuration location\r\n\r\n```yaml\r\niptables_docker_iptables_config_save: /etc/sysconfig/iptables\r\n```\r\n\r\n* ipset saved configuration location\r\n\r\n```yaml\r\niptables_docker_ipset_config_dir: /etc/sysconfig/ipset.d\r\n```\r\n\r\n* ipset maximum elements (IPs in the allow list)\r\n\r\n    If changed after first creation, must be deleted and re-created manually. 64k IPs should be enough.\r\n\r\n```yaml\r\niptables_docker_ipset_maxelem: 65536\r\n```\r\n\r\n## User Settings\r\n\r\n* Override Docker server IPs (Optional)\r\n\r\n    Optionally specify the Docker server IPs. If not set, IPs will be determined from docker_hosts group in Ansible inventory.\r\n\r\n```yaml\r\n# iptables_docker_server_ip_allow_set:\r\n#   - 192.168.100.100\r\n#   - 192.168.100.101\r\n#   - 192.168.100.102\r\n```\r\n\r\n* IPs allowed to use all Docker container's exposed ports and all server's processes' exposed ports.\r\n\r\n```yaml\r\n# iptables_docker_ip_allow_set: []\r\niptables_docker_ip_allow_set:\r\n  - 192.168.100.1\r\n  - 192.168.101.0/24\r\n  - 192.168.102.0/24\r\n```\r\n\r\n* Network adapter to restrict for OS rules\r\n\r\n    Only listed adapters will be blocked. Others will be allowed through. Defaults to block all (with '+').  \r\n    If you want to restrict only specific network interface use exact name.  \r\n    If you want to restrict all interfaces of the same type, use \"interface+\" to match every interface, since + is the wildcard for iptables.  \r\n    Eg. To restrict the ethX interfaces, use \"eth+\". \"eth+\" is a wildcard for anything starting with eth.  \r\n    DO NOT use \"*\". This is not a wildcard and matches nothing!  \r\n    The less here the better. Safer to block all ('+') but if cannot, add network adapters with high traffic first.  \r\n    local (lo) is not needed here.  \r\n\r\n```yaml\r\niptables_docker_external_network_adapter:\r\n  - \"+\" #Wildcard for everything\r\n  # - \"eth+\"\r\n  # - \"enp0s+\"\r\n  # - \"wlp1s+\"\r\n```\r\n\r\n* OS tcp ports open to public\r\n\r\n    Ports to allow everyone to connect (will be publicly accessible). Ports here will allow all tcp traffic to these ports from iptables level.  \r\n    Only for ports on OS, not for Docker containers.\r\n\r\n```yaml\r\niptables_docker_global_ports_allow_tcp:\r\n  - 22                   # SSH\r\n```\r\n\r\n* OS udp ports open to public\r\n\r\n    Ports to allow everyone to connect (will be publicly accessible). Ports here will allow all udp traffic to these ports from iptables level.  \r\n    Only for ports on OS, not for Docker containers.\r\n\r\n```yaml\r\niptables_docker_global_ports_allow_udp: []\r\n```\r\n\r\n* Network adapter to restrict for Docker rules\r\n\r\n    Defaults to use the same setup as the network adapter for the OS.\r\n\r\n```yaml\r\niptables_docker_swarm_network_adapter: \"{{ iptables_docker_external_network_adapter }}\"\r\n# iptables_docker_swarm_network_adapter:\r\n#   - \"+\" #Wildcard for everything\r\n#   # - \"eth+\"\r\n```\r\n\r\n* Docker tcp ports open to public\r\n\r\n    Add Docker container tcp ports you want open to everyone. For Docker and Docker Swarm.\r\n    Docker Swarm ports aren't needed here.\r\n\r\n```yaml\r\niptables_docker_swarm_ports_allow_tcp: []\r\n# iptables_docker_swarm_ports_allow_tcp:\r\n#   - 9000\r\n```\r\n\r\n* Docker udp ports open to public\r\n\r\n    Add Docker container udp ports you want open to everyone. For Docker and Docker Swarm.\r\n    Docker Swarm ports aren't needed here.\r\n\r\n```yaml\r\niptables_docker_swarm_ports_allow_udp: []\r\n```\r\n\r\n* Docker bridge network name (docker0), and IP range (for DOCKER-USER iptables source allow)\r\n\r\n```yaml\r\niptables_docker_bridge_name: docker0\r\niptables_docker_bridge_ips: 172.17.0.0/16\r\n```\r\n\r\n* Docker Swarm bridge network IP range (docker_gwbridge) (for DOCKER-USER iptables source allow)\r\n\r\n```yaml\r\niptables_docker_swarm_bridge_name: docker_gwbridge\r\niptables_docker_swarm_bridge_ips: 172.18.0.0/16\r\n```\r\n\r\n## Example config file (inventories/dev-env/group_vars/all.yml)\r\n\r\nFrom the example below:  \r\nIPs will be added to the trusted list:\r\n\r\n* `192.168.100.1`\r\n* `192.168.101.0/24`\r\n\r\nAll network interfaces will be restricted since using wildcard '+' for iptables_docker_external_network_adapter.  \r\n\r\nPort 22 will be open publicly.\r\n\r\n```yaml\r\n---\r\niptables_docker_ip_allow_set:\r\n  - 192.168.100.1\r\n  - 192.168.101.0/24\r\n\r\niptables_docker_external_network_adapter:\r\n  - \"+\" #Wildcard for everything\r\n\r\niptables_docker_global_ports_allow_tcp:\r\n  - 22                   # SSH\r\n```\r\n\r\n## Example inventory file\r\n\r\n```ini\r\n[docker_hosts]\r\ncentoslead1 ansible_host=192.168.100.100\r\ncentoswork1 ansible_host=192.168.100.101\r\ncentoswork2 ansible_host=192.168.100.102\r\n```\r\n\r\n## Example Playbook iptables_docker.yml\r\n\r\n```yaml\r\n---\r\n- hosts: '{{ inventory }}'\r\n  become: yes\r\n  vars:\r\n    # Use this role\r\n    iptables_docker_managed: true\r\n  roles:\r\n  - ryandaniels.iptables_docker\r\n```\r\n\r\n## Usage\r\n\r\nBefore running make sure you check if you are already using iptables! Nothing should be overwritten/removed, unless you are using the same iptables chains as this.  \r\n\r\nBy default no tasks will run unless you set `iptables_docker_managed=true`. This is by design to prevent accidents by people who don't RTFM.\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true\" -i hosts-dev\r\n```\r\n\r\nSkip installing packages (if known already there - speeds up task)\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true\" -i hosts --skip-tags=iptables_docker_pkg_install\r\n```\r\n\r\nShow more verbose output (debug info)\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true debug_enabled_default=true\" -i hosts-dev\r\n```\r\n\r\nDo not start iptables service or add rules for iptables\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true iptables_docker_start=false\" -i hosts-dev\r\n```\r\n\r\nForce ipset and iptables to update\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true iptables_docker_copy_ipset_force=true iptables_docker_copy_iptables_force=true\" -i hosts-dev\r\n```\r\n\r\nOnly show configuration (from variables)\r\n\r\n```bash\r\nansible-playbook iptables_docker.yml --extra-vars \"inventory=centos7 iptables_docker_managed=true iptables_docker_show_config=true\" -i hosts --tags \"iptables_docker_show_config\"\r\n```\r\n\r\n## Note about ipset size limit\r\n\r\nImportant: Make note of the size of \"Number of entries\". If that number is close to the maxelem size (65536), then you need to delete the ipset \"ip_allow\" and re-create it with a larger max size.  \r\n64K ought to be enough for anyone.  \r\n\r\nFile is in: `templates/ip_allow.set.j2`\r\n\r\n```text\r\ncreate -exist ip_allow hash:ip family inet hashsize 1024 maxelem 65536\r\n```\r\n\r\nCheck size of ipset list:\r\n\r\n```bash\r\nipset list |grep \"Number of entries\"\r\n```\r\n\r\nImportant output:\r\n\r\n```bash\r\nNumber of entries: 3\r\n```\r\n\r\n## SELinux manual workaround for iptables and chmod\r\n\r\nBug details: \u003chttps://bugs.centos.org/view.php?id=12648\u003e\r\n\r\nThe problem is when saving iptables a 2nd time, SELinux blocks it since chmod has a problem with the iptables.save file.\r\nUse below as workaround to allow chmod to modify iptables.save file if not using the Ansible role.  \r\nTo reproduce, restart iptables service after setting iptables config to save after restart/stop,\r\n\r\n```bash\r\nyum install audit policycoreutils policycoreutils-python\r\nausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -i|tail -55\r\nausearch -c 'chmod' --raw | audit2allow -M iptables_save_chmod\r\n#or grep \"iptables.save\" /var/log/audit/audit.log|tail | audit2allow -M iptables_save_chmod\r\nsemodule -i iptables_save_chmod.pp\r\n```\r\n\r\n## iptables Command Reference\r\n\r\nMore commands can be found in iptables documentation: \u003chttp://ipset.netfilter.org/iptables.man.html\u003e\r\n\r\nList iptables that are active:\r\n\r\n```bash\r\niptables -nvL --line-numbers\r\n```\r\n\r\nMisc CentOS/RHEL useful commands:\r\n\r\n```bash\r\ncat /etc/sysconfig/ipset.d/ip_allow.set\r\nsystemctl restart ipset\r\nipset list | head\r\n\r\niptables -F DOCKER-USER\r\niptables -F FILTERS\r\niptables-restore -n \u003c ansible_iptables_docker-iptables\r\n\r\ngrep -v \"^#\" ansible_iptables_docker-iptables\r\niptables -S INPUT\r\niptables -S DOCKER-USER\r\niptables -S FILTERS\r\n```\r\n\r\nMisc Ubuntu useful commands:\r\n\r\n```bash\r\nvi /etc/iptables/ipsets\r\n#Manually add 'flush' before add, if removing IPs manually.\r\n\r\n/usr/sbin/netfilter-persistent reload\r\n\r\ncat /etc/iptables/ipsets\r\n\r\ncat /etc/iptables/rules.v4\r\n```\r\n\r\n## Manual Commands (CentOS/RHEL)\r\n\r\nCheck what iptables rules you already have. Make note in case they are lost!\r\n\r\n```bash\r\niptables -nvL --line-numbers\r\n```\r\n\r\nInstall required packages:\r\n\r\n```bash\r\nyum install iptables iptables-services ipset ipset-service\r\n```\r\n\r\nIf using SELinux, also install:\r\n\r\n```bash\r\nyum install policycoreutils-python\r\n```\r\n\r\nConfigure ipset with your server IPs and other trusted IPs:\r\n\r\n```bash\r\nmkdir -p /etc/sysconfig/ipset.d\r\ncat \u003e /etc/sysconfig/ipset.d/ip_allow.set  \u003c\u003c 'EOF'\r\ncreate -exist ip_allow hash:ip family inet hashsize 1024 maxelem 65536\r\nadd ip_allow 192.168.1.123\r\nadd ip_allow 192.168.101.0/24\r\nadd ip_allow 192.168.102.0/24\r\nEOF\r\n```\r\n\r\nStart, and Enable the ipset service:\r\n\r\n```bash\r\nsystemctl status ipset\r\nsystemctl start ipset\r\nsystemctl enable ipset\r\n```\r\n\r\nSee what ipset has in it's loaded configuration:\r\n\r\n```bash\r\nipset list | head\r\n```\r\n\r\niptables rules being added (by default port 22 is open to everyone):\r\n\r\n```iptables\r\ncat \u003e ansible_iptables_docker-iptables \u003c\u003c 'EOF'\r\n*filter\r\n:DOCKER-USER - [0:0]\r\n:FILTERS - [0:0]\r\n#Can't flush INPUT. wipes out docker swarm encrypted overlay rules\r\n#-F INPUT\r\n#Use ansible or run manually once instead to add -I INPUT -j FILTERS\r\n#-I INPUT -j FILTERS\r\n-A DOCKER-USER -m state --state RELATED,ESTABLISHED -j RETURN\r\n-A DOCKER-USER -i docker_gwbridge -j RETURN\r\n-A DOCKER-USER -s 172.18.0.0/16 -j RETURN\r\n-A DOCKER-USER -i docker0 -j RETURN\r\n-A DOCKER-USER -s 172.17.0.0/16 -j RETURN\r\n#Below Docker ports open to everyone if uncommented\r\n#-A DOCKER-USER -p tcp -m tcp -m multiport --dports 8000,8001 -j RETURN\r\n#-A DOCKER-USER -p udp -m udp -m multiport --dports 9000,9001 -j RETURN\r\n-A DOCKER-USER -m set ! --match-set ip_allow src -j DROP\r\n-A DOCKER-USER -j RETURN\r\n-F FILTERS\r\n#Because Docker Swarm encrypted overlay network just appends rules to INPUT. Has to be at top unfortunately\r\n-A FILTERS -p udp -m policy --dir in --pol ipsec -m udp --dport 4789 -m set --match-set ip_allow src -j RETURN\r\n-A FILTERS -m state --state RELATED,ESTABLISHED -j ACCEPT\r\n-A FILTERS -p icmp -j ACCEPT\r\n-A FILTERS -i lo -j ACCEPT\r\n#Below OS ports open to everyone if uncommented\r\n-A FILTERS -p tcp -m state --state NEW -m tcp -m multiport --dports 22 -j ACCEPT\r\n#-A FILTERS -p udp -m udp -m multiport --dports 53,123 -j ACCEPT\r\n-A FILTERS -m set ! --match-set ip_allow src -j DROP\r\n-A FILTERS -j RETURN\r\nCOMMIT\r\n\r\nEOF\r\n```\r\n\r\nUse iptables-restore to add the above rules into iptables. The very important flag is -n. That makes sure we don't flush the iptables rules if we have rules already in Docker (or Docker Swarm).\r\n\r\n```bash\r\niptables-restore -n \u003c ansible_iptables_docker-iptables\r\n```\r\n\r\nNext, add a rule to the INPUT chain, so we start using the new rules in FILTERS. It has to be at the top, and only needs to be added once:\r\n\r\n```bash\r\niptables -I INPUT 1 -j FILTERS\r\n```\r\n\r\nSave the iptables rules:\r\n\r\n```bash\r\n/usr/libexec/iptables/iptables.init save\r\n```\r\n\r\nStart and Enable the iptables service:\r\n\r\n```bash\r\nsystemctl status iptables\r\nsystemctl start iptables\r\nsystemctl enable iptables\r\n```\r\n\r\nIf you want to customize the iptables rules to allow more ports to be open to everyone, just add the port to the appropriate rule in the iptables file (tcp or udp), then re-run the same commands from above:\r\n\r\n```bash\r\niptables-restore -n \u003c ansible_iptables_docker-iptables\r\n/usr/libexec/iptables/iptables.init save\r\n```\r\n\r\nDon't miss the [Warnings](#warnings) from above! Especially about SELinux.\r\n\r\n## Manual Commands (Ubuntu 20.04)\r\n\r\nCheck what iptables rules you already have. Make note in case they are lost!  \r\nUbuntu 18.04 is almost the same. Except the `ipset-persistent` package doesn't exist in Ubuntu 18.04, so omit that package and copy the files from `files/ubuntu/iptables-persistent*/plugins/*-ipset` to `/usr/share/netfilter-persistent/plugins.d/`.  \r\n\r\n```bash\r\niptables -nvL --line-numbers\r\n```\r\n\r\nInstall required packages:\r\n\r\n```bash\r\napt install iptables iptables-persistent netfilter-persistent ipset ipset-persistent\r\n```\r\n\r\nConfigure ipset with your server IPs and other trusted IPs:\r\n\r\n```bash\r\nmkdir -p /etc/iptables\r\ncat \u003e /etc/iptables/ipsets  \u003c\u003c 'EOF'\r\ncreate -exist ip_allow hash:ip family inet hashsize 1024 maxelem 65536\r\nflush\r\nadd ip_allow 192.168.1.123\r\nadd ip_allow 192.168.101.0/24\r\nadd ip_allow 192.168.102.0/24\r\nEOF\r\n```\r\n\r\nReload ipset:\r\n\r\n```bash\r\n/usr/sbin/netfilter-persistent reload\r\n```\r\n\r\nSee what ipset has in it's loaded configuration:\r\n\r\n```bash\r\nipset list | head\r\n```\r\n\r\niptables rules being added (by default port 22 is open to everyone):\r\n\r\n```iptables\r\nUse same command as above for CentOS/RHEL.\r\n```\r\n\r\nUse iptables-restore to add the above rules into iptables. The very important flag is -n. That makes sure we don't flush the iptables rules if we have rules already in Docker (or Docker Swarm).\r\n\r\n```bash\r\niptables-restore -n \u003c ansible_iptables_docker-iptables\r\n```\r\n\r\nNext, add a rule to the INPUT chain, so we start using the new rules in FILTERS. It has to be at the top, and only needs to be added once:\r\n\r\n```bash\r\niptables -I INPUT 1 -j FILTERS\r\n```\r\n\r\nSave the iptables rules:\r\n\r\n```bash\r\n/usr/sbin/netfilter-persistent save\r\n```\r\n\r\nStart and Enable the iptables service:\r\n\r\n```bash\r\nsystemctl status netfilter-persistent\r\nsystemctl start netfilter-persistent\r\nsystemctl enable netfilter-persistent\r\n```\r\n\r\nIf you want to customize the iptables rules to allow more ports to be open to everyone, just add the port to the appropriate rule in the iptables file (tcp or udp), then re-run the same commands from above:\r\n\r\n```bash\r\niptables-restore -n \u003c ansible_iptables_docker-iptables\r\n/usr/sbin/netfilter-persistent save\r\n```\r\n\r\nDon't miss the [Warnings](#warnings) from above!\r\n\r\n## TODO\r\n\r\n* [x] Check for firewalld and fail if running or enabled\r\n* [x] Problem with iptables saving Docker rules in iptables rules? Should be fine.\r\n* [x] iptables_docker_ip_allow_set can't be empty. If it is, there's no point to this since nothing is blocked!\r\n* [x] add check in network adapters for * and error\r\n* [x] add automatic list of docker IPs in allowed list (uses IPs from inventory group docker_hosts)\r\n* [x] Change auto Docker server trusted IPs so can override\r\n* [x] confirm \"when\" and \"tags\" are ok\r\n* [x] Ubuntu? Ubuntu doesn't have iptables-services or ipset-service. has iptables-persistent and ipset-? No ufw support\r\n* [ ] ipv6?? This is for ipv4 only\r\n* [x] test TCP, UDP Docker container and OS port work\r\n* [x] test outound traffic from Docker containers work\r\n* [ ] add test? Molecule? Single node swarm mode only? how to test connection doesn't work from \"untrusted\" ip?\r\n\r\n## Author\r\n\r\nRyan Daniels\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryandaniels%2Fansible-role-iptables-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryandaniels%2Fansible-role-iptables-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryandaniels%2Fansible-role-iptables-docker/lists"}