-
McConahy, Renee Margaret authored
As I noted in an earlier commit, restricting Docker's ingress traffic is more complicated than adding a few rules to the filter table's INPUT chain. I had thought that relying on LOCKSS's "LOCKSS_ACCESS_SUBNET" variable would be sufficient; unfortunately, that is not the case: LOCKSS sees all of its traffic as coming from the Docker overlay network (by default, 10.0.0.0/8), regardless of its true origin. Fortunately for us, Docker provides us with a chain, DOCKER-USER, called by Docker's rules from the FORWARD chain in the filter table, that is suitable for filtering Docker's ingress traffic. Accordingly, this commit: - Removes the misleadingly ineffective 'lockss_trusted_ips' variable and provides new variables 'lockss_network_ips' and 'lockss_admin_ips'. - Replaces ufw or firewalld with ferm. Neither ufw nor firewalld is capable of satisfying this use case without employing significant violence; ferm is elegant and has beautiful configuration files. Beauty over bloodshed. - Adds tasks to configure a local firewall that denies inbound and forwarded traffic by default, permits ssh from anywhere, and permits access to LOCKSS's data and configuration ports from 'lockss_network_ips' and 'lockss_admin_ips' respectively. Said firewall cooperates with Docker: Docker and the firewall can be started in any order, and restarting either preserves rules created by the other. * * * I got the suggestion of using ferm for this, as well as the bulk of the Docker-related rules, from a blog post: Ben Chavet, Convincing Docker and Iptables to Play Nicely, Aug. 8, 2019, <https://www.lullabot.com/articles/convincing-docker-and-iptables-play-nicely>.
McConahy, Renee Margaret authoredAs I noted in an earlier commit, restricting Docker's ingress traffic is more complicated than adding a few rules to the filter table's INPUT chain. I had thought that relying on LOCKSS's "LOCKSS_ACCESS_SUBNET" variable would be sufficient; unfortunately, that is not the case: LOCKSS sees all of its traffic as coming from the Docker overlay network (by default, 10.0.0.0/8), regardless of its true origin. Fortunately for us, Docker provides us with a chain, DOCKER-USER, called by Docker's rules from the FORWARD chain in the filter table, that is suitable for filtering Docker's ingress traffic. Accordingly, this commit: - Removes the misleadingly ineffective 'lockss_trusted_ips' variable and provides new variables 'lockss_network_ips' and 'lockss_admin_ips'. - Replaces ufw or firewalld with ferm. Neither ufw nor firewalld is capable of satisfying this use case without employing significant violence; ferm is elegant and has beautiful configuration files. Beauty over bloodshed. - Adds tasks to configure a local firewall that denies inbound and forwarded traffic by default, permits ssh from anywhere, and permits access to LOCKSS's data and configuration ports from 'lockss_network_ips' and 'lockss_admin_ips' respectively. Said firewall cooperates with Docker: Docker and the firewall can be started in any order, and restarting either preserves rules created by the other. * * * I got the suggestion of using ferm for this, as well as the bulk of the Docker-related rules, from a blog post: Ben Chavet, Convincing Docker and Iptables to Play Nicely, Aug. 8, 2019, <https://www.lullabot.com/articles/convincing-docker-and-iptables-play-nicely>.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
10-in-lockss.ferm.j2 1.12 KiB
@def $LOCKSS_NET = ({{ lockss_network_ips | join(" ") }});
@def $MGMT_NET = ({{ lockss_admin_ips | join(" ") }});
@def $LOCKSS_CONFIG_PORTS = (
24640 24641 # metadata-extraction-service
24602 # postgres
24650 24651 # metadata-service
24610 # repository-service
24600 24606 24620 24621 # configuration-service
24630 24631 24670 24672 24674 24680 # poller
24681 # pywb
24603 # solr
);
@def $LOCKSS_NET_PORTS = (
9729 # poller
);
domain (ip ip6) table filter chain DOCKER-USER {
# Incoming traffic bound for a docker service will come in to the FORWARD
# chain and exit on docker_gwbridge.
outerface docker_gwbridge {
# The destination ports here are the ports listening inside the
# container. These may differ from those on the host.
saddr $LOCKSS_NET proto tcp dport $LOCKSS_NET_PORTS ACCEPT;
saddr $MGMT_NET proto tcp dport $LOCKSS_CONFIG_PORTS ACCEPT;
}
}