mirror of
https://github.com/chaifeng/ufw-docker.git
synced 2025-05-10 21:48:30 +02:00
Compare commits
39 commits
Author | SHA1 | Date | |
---|---|---|---|
|
1a51b59cf8 | ||
|
5908cde296 | ||
|
8f9335326f | ||
|
c9547cb4ec | ||
|
9474084f3f | ||
|
1fa425bf17 | ||
|
3d6896cdd1 | ||
|
6cdd4dfd2f | ||
|
17e6047590 | ||
|
a273ac9d51 | ||
|
cdad5e2a02 | ||
|
9d890ee3ee | ||
|
a1d3517aeb | ||
|
d1e6c13156 | ||
|
682d8b363f | ||
|
a689c4eb6e | ||
|
e99858510d | ||
|
712b0e8075 | ||
|
5033bf815c | ||
|
d110fc00ff | ||
|
9df291d39e | ||
|
c95d51c975 | ||
|
8aecb89d4e | ||
|
1333dcd298 | ||
|
e40bfd517c | ||
|
97543811ea | ||
|
afd62aa96b | ||
|
6986267d30 | ||
|
4833b190ff | ||
|
fc7840efef | ||
|
22f04125d6 | ||
|
4335d6fb82 | ||
|
cd783f91d7 | ||
|
80a691f084 | ||
|
0150af87dc | ||
|
cc58088bc5 | ||
|
2b4a44ff7a | ||
|
fa5cec9dc5 | ||
|
a444fb9457 |
8 changed files with 389 additions and 104 deletions
35
.github/workflows/build.yml
vendored
Normal file
35
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
name: Build Images
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Log into DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ github.actor }}/ufw-docker-agent
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
16
.github/workflows/testing.yml
vendored
Normal file
16
.github/workflows/testing.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
name: Unit Testing ufw-docker
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
name: Unit Testing
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
- name: Test ufw-docker
|
||||
run: ./test.sh
|
18
Dockerfile
18
Dockerfile
|
@ -1,18 +1,18 @@
|
|||
FROM ubuntu:20.04
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ARG docker_version="19.03.12"
|
||||
ARG docker_version="27.3.1"
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends apt-transport-https \
|
||||
ca-certificates curl software-properties-common gnupg dirmngr \
|
||||
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 \
|
||||
&& add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" \
|
||||
&& apt-get install -y ca-certificates curl gnupg lsb-release \
|
||||
&& mkdir -p /etc/apt/keyrings \
|
||||
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]" \
|
||||
"https://download.docker.com/linux/ubuntu" "$(lsb_release -cs) stable" \
|
||||
| tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends locales ufw \
|
||||
&& ( apt-get install -y --no-install-recommends "docker-ce=5:${docker_version}~*" || \
|
||||
apt-get install -y --no-install-recommends "docker-ce=${docker_version}~*" ) \
|
||||
&& apt-get install -y --no-install-recommends "docker-ce=$(apt-cache madison docker-ce | grep -m1 -F "${docker_version}" | cut -d'|' -f2 | tr -d '[[:blank:]]')" \
|
||||
&& locale-gen en_US.UTF-8 \
|
||||
&& apt-get clean autoclean \
|
||||
&& apt-get autoremove --yes \
|
||||
|
|
12
README.md
12
README.md
|
@ -2,7 +2,7 @@ To Fix The Docker and UFW Security Flaw Without Disabling Iptables
|
|||
==================
|
||||
|
||||
[](https://travis-ci.org/chaifeng/ufw-docker)
|
||||

|
||||
[](https://hub.docker.com/r/chaifeng/ufw-docker-agent)
|
||||
|
||||
- [English](#tldr)
|
||||
- [中文](#太长不想读)
|
||||
|
@ -210,7 +210,7 @@ Download `ufw-docker` script
|
|||
|
||||
sudo wget -O /usr/local/bin/ufw-docker \
|
||||
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
|
||||
chmod +x /usr/local/bin/ufw-docker
|
||||
sudo chmod +x /usr/local/bin/ufw-docker
|
||||
|
||||
Then using the following command to modify the `after.rules` file of `ufw`
|
||||
|
||||
|
@ -259,6 +259,10 @@ Expose the `443` port of the container `httpd` and the protocol is `tcp`
|
|||
|
||||
ufw-docker allow httpd 443/tcp
|
||||
|
||||
Expose the `443` port of the container `httpd` and the protocol is `tcp` and the network is `foobar-external-network` when the container `httpd` is attached to multiple networks
|
||||
|
||||
ufw-docker allow httpd 443/tcp foobar-external-network
|
||||
|
||||
Expose all published ports of the container `httpd`
|
||||
|
||||
ufw-docker allow httpd
|
||||
|
@ -563,6 +567,10 @@ UFW 是 Ubuntu 上很流行的一个 iptables 前端,可以非常方便的管
|
|||
|
||||
ufw-docker allow httpd 443/tcp
|
||||
|
||||
如果容器 `httpd` 绑定到多个网络上,暴露其 `443` 端口,协议为 `tcp`,网络为 `foobar-external-network`
|
||||
|
||||
ufw-docker allow httpd 443/tcp foobar-external-network
|
||||
|
||||
把容器 `httpd` 的所有映射端口都暴露出来
|
||||
|
||||
ufw-docker allow httpd
|
||||
|
|
103
Vagrantfile
vendored
103
Vagrantfile
vendored
|
@ -3,16 +3,29 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
ENV['VAGRANT_NO_PARALLEL']="true"
|
||||
|
||||
config.vm.box = "chaifeng/ubuntu-20.04-docker-19.03.11"
|
||||
#config.vm.box = "chaifeng/ubuntu-16.04-docker-18.03"
|
||||
Vagrant.configure('2') do |config|
|
||||
ubuntu_version = File.readlines("Dockerfile").filter { |line|
|
||||
line.start_with?("FROM ")
|
||||
}.first.match(/\d\d\.\d\d/)[0]
|
||||
|
||||
docker_version = File.readlines("Dockerfile").filter { |line|
|
||||
line.start_with?("ARG docker_version=")
|
||||
}.first.match(/"([\d\.]+)"/)[1]
|
||||
|
||||
config.vm.box = "chaifeng/ubuntu-#{ubuntu_version}-docker-#{docker_version}"
|
||||
|
||||
config.vm.provider 'virtualbox' do |vb|
|
||||
vb.memory = '1024'
|
||||
vb.default_nic_type = "virtio"
|
||||
end
|
||||
|
||||
config.vm.provider 'parallels' do |prl|
|
||||
prl.memory = '1024'
|
||||
prl.check_guest_tools = false
|
||||
end
|
||||
|
||||
ip_prefix="192.168.56"
|
||||
|
||||
config.vm.provision 'docker-daemon-config', type: 'shell', inline: <<-SHELL
|
||||
|
@ -57,15 +70,16 @@ Vagrant.configure('2') do |config|
|
|||
private_registry="#{ip_prefix}.130:5000"
|
||||
|
||||
config.vm.define "master" do |master|
|
||||
master_ip_address = "#{ip_prefix}.130"
|
||||
master.vm.hostname = "master"
|
||||
master.vm.network "private_network", ip: "#{ip_prefix}.130"
|
||||
master.vm.network "private_network", ip: "#{master_ip_address}"
|
||||
|
||||
master.vm.provision "unit-testing", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "unit-testing", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
/vagrant/test.sh
|
||||
SHELL
|
||||
|
||||
master.vm.provision "docker-registry", type: 'docker' do |d|
|
||||
master.vm.provision "docker-registry", preserve_order: true, type: 'docker' do |d|
|
||||
d.run "registry",
|
||||
image: "registry:2",
|
||||
args: "-p 5000:5000",
|
||||
|
@ -73,35 +87,38 @@ Vagrant.configure('2') do |config|
|
|||
daemonize: true
|
||||
end
|
||||
|
||||
ufw_docker_agent_image = "#{private_registry}/chaifeng/ufw-docker-agent:test"
|
||||
ufw_docker_agent_image = "#{private_registry}/chaifeng/ufw-docker-agent:test-legacy"
|
||||
|
||||
master.vm.provision "docker-build-ufw-docker-agent", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "docker-build-ufw-docker-agent", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
docker build -t #{ufw_docker_agent_image} /vagrant
|
||||
docker push #{ufw_docker_agent_image}
|
||||
suffix="$(iptables --version | grep -o '\\(nf_tables\\|legacy\\)')"
|
||||
docker build -t "#{ufw_docker_agent_image}-${suffix}" /vagrant
|
||||
docker push "#{ufw_docker_agent_image}-${suffix}"
|
||||
|
||||
echo "export UFW_DOCKER_AGENT_IMAGE=#{ufw_docker_agent_image}" > /etc/profile.d/ufw-docker.sh
|
||||
echo "export UFW_DOCKER_AGENT_IMAGE=#{ufw_docker_agent_image}-${suffix}" > /etc/profile.d/ufw-docker.sh
|
||||
echo "export DEBUG=true" >> /etc/profile.d/ufw-docker.sh
|
||||
|
||||
echo "Defaults env_keep += UFW_DOCKER_AGENT_IMAGE" > /etc/sudoers.d/98_ufw-docker
|
||||
echo "Defaults env_keep += DEBUG" >> /etc/sudoers.d/98_ufw-docker
|
||||
SHELL
|
||||
|
||||
master.vm.provision "swarm-init", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "swarm-init", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
docker info | fgrep 'Swarm: active' && exit 0
|
||||
|
||||
docker swarm init --advertise-addr eth1
|
||||
docker swarm init --advertise-addr "#{master_ip_address}"
|
||||
docker swarm join-token worker --quiet > /vagrant/.vagrant/docker-join-token
|
||||
SHELL
|
||||
|
||||
master.vm.provision "build-webapp", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "build-webapp", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
docker build -t #{private_registry}/chaifeng/hostname-webapp - <<\\DOCKERFILE
|
||||
FROM httpd:alpine
|
||||
|
||||
RUN { echo '#!/bin/sh'; \\
|
||||
echo 'set -e; (echo -n "${name:-Hi} "; hostname;) > /usr/local/apache2/htdocs/index.html'; \\
|
||||
echo 'grep "^Listen 7000" || echo Listen 7000 >> /usr/local/apache2/conf/httpd.conf'; \\
|
||||
echo 'grep "^Listen 8080" || echo Listen 8080 >> /usr/local/apache2/conf/httpd.conf'; \\
|
||||
echo 'exec "$@"'; \\
|
||||
} > /entrypoint.sh; chmod +x /entrypoint.sh
|
||||
|
||||
|
@ -111,7 +128,7 @@ DOCKERFILE
|
|||
docker push #{private_registry}/chaifeng/hostname-webapp
|
||||
SHELL
|
||||
|
||||
master.vm.provision "local-webapp", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "local-webapp", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
for name in public:18080 local:8000; do
|
||||
webapp="${name%:*}_webapp"
|
||||
|
@ -125,7 +142,30 @@ DOCKERFILE
|
|||
ufw-docker allow public_webapp
|
||||
SHELL
|
||||
|
||||
master.vm.provision "swarm-webapp", type: 'shell', inline: <<-SHELL
|
||||
master.vm.provision "multiple-network", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
if ! docker network ls | grep -F foo-internal; then
|
||||
docker network create --internal foo-internal
|
||||
fi
|
||||
if ! docker network ls | grep -F bar-external; then
|
||||
docker network create bar-external
|
||||
fi
|
||||
|
||||
for app in internal-multinet-app:7000 public-multinet-app:17070; do
|
||||
if ! docker inspect "${app%:*}" &>/dev/null; then
|
||||
docker run -d --restart unless-stopped --name "${app%:*}" \
|
||||
-p "${app#*:}":80 --env name="${app}" \
|
||||
--network foo-internal \
|
||||
192.168.56.130:5000/chaifeng/hostname-webapp
|
||||
docker network connect bar-external "${app%:*}"
|
||||
fi
|
||||
done
|
||||
|
||||
ufw-docker allow public-multinet-app 80 bar-external
|
||||
ufw-docker allow internal-multinet-app 80 foo-internal
|
||||
SHELL
|
||||
|
||||
master.vm.provision "swarm-webapp", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
for name in public:29090 local:9000; do
|
||||
webapp="${name%:*}_service"
|
||||
|
@ -136,6 +176,14 @@ DOCKERFILE
|
|||
done
|
||||
|
||||
ufw-docker service allow public_service 80/tcp
|
||||
|
||||
docker service inspect "public_multiport" ||
|
||||
docker service create --name "public_multiport" \
|
||||
--publish "40080:80" --publish "47000:7000" --publish "48080:8080" \
|
||||
--env name="public_multiport" --replicas 3 #{private_registry}/chaifeng/hostname-webapp
|
||||
|
||||
ufw-docker service allow public_multiport 80/tcp
|
||||
ufw-docker service allow public_multiport 8080/tcp
|
||||
SHELL
|
||||
end
|
||||
|
||||
|
@ -144,7 +192,7 @@ DOCKERFILE
|
|||
node.vm.hostname = "node#{ip}"
|
||||
node.vm.network "private_network", ip: "#{ip_prefix}.#{ 130 + ip }"
|
||||
|
||||
node.vm.provision "swarm-join", type: 'shell', inline: <<-SHELL
|
||||
node.vm.provision "swarm-join", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
docker info | fgrep 'Swarm: active' && exit 0
|
||||
|
||||
|
@ -154,21 +202,38 @@ DOCKERFILE
|
|||
end
|
||||
end
|
||||
|
||||
config.vm.define "node-internal" do |node|
|
||||
node.vm.hostname = "node-internal"
|
||||
node.vm.network "private_network", ip: "#{ip_prefix}.142"
|
||||
end
|
||||
|
||||
config.vm.define "external" do |external|
|
||||
external.vm.hostname = "external"
|
||||
external.vm.network "private_network", ip: "#{ip_prefix}.127"
|
||||
|
||||
external.vm.provision "testing", type: 'shell', inline: <<-SHELL
|
||||
external.vm.provision "testing", preserve_order: true, type: 'shell', inline: <<-SHELL
|
||||
set -euo pipefail
|
||||
set -x
|
||||
server="http://#{ip_prefix}.130"
|
||||
function test-webapp() { timeout 3 curl --silent "$@"; }
|
||||
function test-webapp() {
|
||||
if timeout 3 curl --silent "$@"
|
||||
then echo "Success: $*"
|
||||
else echo "Cannot visit: $*"; return 1
|
||||
fi
|
||||
}
|
||||
test-webapp "$server:18080"
|
||||
! test-webapp "$server:8000"
|
||||
|
||||
test-webapp "$server:17070" # multiple networks app
|
||||
! test-webapp "$server:7000" # internal multiple networks app
|
||||
|
||||
test-webapp "$server:29090"
|
||||
! test-webapp "$server:9000"
|
||||
|
||||
test-webapp "$server:40080"
|
||||
test-webapp "$server:48080"
|
||||
! test-webapp "$server:47000"
|
||||
|
||||
echo "====================="
|
||||
echo " TEST DONE "
|
||||
echo "====================="
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ff948334df72f25410d03cbff72b5eaa5e9de409
|
||||
Subproject commit 27885eb79c11e4652dede994c886ae5f9e30994f
|
|
@ -12,12 +12,20 @@ source "$working_dir"/bach/bach.sh
|
|||
@mocktrue ufw status
|
||||
@mocktrue grep -Fq "Status: active"
|
||||
|
||||
@ignore remove_blank_lines
|
||||
@mock iptables --version
|
||||
@mocktrue grep -F '(legacy)'
|
||||
|
||||
@mocktrue docker -v
|
||||
@mock docker -v === @stdout Docker version 0.0.0, build dummy
|
||||
|
||||
@mockpipe remove_blank_lines
|
||||
@ignore echo
|
||||
@ignore err
|
||||
|
||||
DEFAULT_PROTO=tcp
|
||||
GREP_REGEXP_INSTANCE_NAME="[-_.[:alnum:]]\\+"
|
||||
|
||||
UFW_DOCKER_AGENT_IMAGE=chaifeng/ufw-docker-agent:090502-legacy
|
||||
}
|
||||
|
||||
function ufw-docker() {
|
||||
|
@ -30,6 +38,41 @@ function load-ufw-docker-function() {
|
|||
@load_function "$working_dir/../ufw-docker" "$1"
|
||||
}
|
||||
|
||||
test-ufw-docker-init-legacy() {
|
||||
@mocktrue grep -F '(legacy)'
|
||||
@source <(@sed '/PATH=/d' "$working_dir/../ufw-docker") help
|
||||
}
|
||||
test-ufw-docker-init-legacy-assert() {
|
||||
iptables --version
|
||||
test -n chaifeng/ufw-docker-agent:090502-legacy
|
||||
trap on-exit EXIT INT TERM QUIT ABRT ERR
|
||||
@dryrun cat
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker-init-nf_tables() {
|
||||
@mockfalse grep -F '(legacy)'
|
||||
@source <(@sed '/PATH=/d' "$working_dir/../ufw-docker") help
|
||||
}
|
||||
test-ufw-docker-init-nf_tables-assert() {
|
||||
iptables --version
|
||||
test -n chaifeng/ufw-docker-agent:090502-nf_tables
|
||||
trap on-exit EXIT INT TERM QUIT ABRT ERR
|
||||
@dryrun cat
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker-init() {
|
||||
UFW_DOCKER_AGENT_IMAGE=chaifeng/ufw-docker-agent:100917
|
||||
@source <(@sed '/PATH=/d' "$working_dir/../ufw-docker") help
|
||||
}
|
||||
test-ufw-docker-init-assert() {
|
||||
test -n chaifeng/ufw-docker-agent:100917
|
||||
trap on-exit EXIT INT TERM QUIT ABRT ERR
|
||||
@dryrun cat
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker-help() {
|
||||
ufw-docker help
|
||||
}
|
||||
|
@ -48,11 +91,23 @@ test-ufw-docker-without-parameters-assert() {
|
|||
|
||||
test-ufw-is-disabled() {
|
||||
@mockfalse grep -Fq "Status: active"
|
||||
@mock iptables --version === @stdout 'iptables v1.8.4 (legacy)'
|
||||
|
||||
ufw-docker
|
||||
}
|
||||
test-ufw-is-disabled-assert() {
|
||||
die "UFW is disabled or you are not root user."
|
||||
die "UFW is disabled or you are not root user, or mismatched iptables legacy/nf_tables, current iptables v1.8.4 (legacy)"
|
||||
ufw-docker--help
|
||||
}
|
||||
|
||||
|
||||
test-docker-is-installed() {
|
||||
@mockfalse docker -v
|
||||
|
||||
ufw-docker
|
||||
}
|
||||
test-docker-is-installed-assert() {
|
||||
die "Docker executable not found."
|
||||
ufw-docker--help
|
||||
}
|
||||
|
||||
|
@ -143,7 +198,7 @@ test-ufw-docker-list-httpd() {
|
|||
ufw-docker list httpd
|
||||
}
|
||||
test-ufw-docker-list-httpd-assert() {
|
||||
ufw-docker--list httpd-container-name "" tcp
|
||||
ufw-docker--list httpd-container-name "" tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,7 +207,7 @@ test-ufw-docker-allow-httpd() {
|
|||
ufw-docker allow httpd
|
||||
}
|
||||
test-ufw-docker-allow-httpd-assert() {
|
||||
ufw-docker--allow httpd-container-name "" tcp
|
||||
ufw-docker--allow httpd-container-name "" tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -161,7 +216,7 @@ test-ufw-docker-allow-httpd-80() {
|
|||
ufw-docker allow httpd 80
|
||||
}
|
||||
test-ufw-docker-allow-httpd-80-assert() {
|
||||
ufw-docker--allow httpd-container-name 80 tcp
|
||||
ufw-docker--allow httpd-container-name 80 tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -170,7 +225,7 @@ test-ufw-docker-allow-httpd-80tcp() {
|
|||
ufw-docker allow httpd 80/tcp
|
||||
}
|
||||
test-ufw-docker-allow-httpd-80tcp-assert() {
|
||||
ufw-docker--allow httpd-container-name 80 tcp
|
||||
ufw-docker--allow httpd-container-name 80 tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,7 +234,7 @@ test-ufw-docker-allow-httpd-80udp() {
|
|||
ufw-docker allow httpd 80/udp
|
||||
}
|
||||
test-ufw-docker-allow-httpd-80udp-assert() {
|
||||
ufw-docker--allow httpd-container-name 80 udp
|
||||
ufw-docker--allow httpd-container-name 80 udp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +251,7 @@ test-ufw-docker-list-httpd() {
|
|||
ufw-docker list httpd
|
||||
}
|
||||
test-ufw-docker-list-httpd-assert() {
|
||||
ufw-docker--list httpd-container-name "" tcp
|
||||
ufw-docker--list httpd-container-name "" tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,7 +260,7 @@ test-ufw-docker-delete-allow-httpd() {
|
|||
ufw-docker delete allow httpd
|
||||
}
|
||||
test-ufw-docker-delete-allow-httpd-assert() {
|
||||
ufw-docker--delete httpd-container-name "" tcp
|
||||
ufw-docker--delete httpd-container-name "" tcp ""
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,6 +278,16 @@ function setup-ufw-docker--allow() {
|
|||
|
||||
@mocktrue docker inspect instance-name
|
||||
@mock docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{"\n"}}{{end}}' instance-name === @stdout 172.18.0.3
|
||||
@mock docker inspect --format='{{range $k, $v := .NetworkSettings.Networks}}{{printf "%s\n" $k}}{{end}}' instance-name === @stdout default
|
||||
@mock docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{with $conf}}{{$p}}{{"\n"}}{{end}}{{end}}' instance-name === @stdout 5000/tcp 8080/tcp 5353/udp
|
||||
}
|
||||
|
||||
function setup-ufw-docker--allow--multinetwork() {
|
||||
load-ufw-docker-function ufw-docker--allow
|
||||
|
||||
@mocktrue docker inspect instance-name
|
||||
@mock docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{"\n"}}{{end}}' instance-name === @stdout 172.18.0.3 172.19.0.7
|
||||
@mock docker inspect --format='{{range $k, $v := .NetworkSettings.Networks}}{{printf "%s\n" $k}}{{end}}' instance-name === @stdout default awesomenet
|
||||
@mock docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{with $conf}}{{$p}}{{"\n"}}{{end}}{{end}}' instance-name === @stdout 5000/tcp 8080/tcp 5353/udp
|
||||
}
|
||||
|
||||
|
@ -269,7 +334,7 @@ test-ufw-docker--allow-instance-and-match-the-port() {
|
|||
ufw-docker--allow instance-name 5000 tcp
|
||||
}
|
||||
test-ufw-docker--allow-instance-and-match-the-port-assert() {
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp default
|
||||
}
|
||||
|
||||
|
||||
|
@ -279,9 +344,9 @@ test-ufw-docker--allow-instance-all-published-port() {
|
|||
ufw-docker--allow instance-name "" ""
|
||||
}
|
||||
test-ufw-docker--allow-instance-all-published-port-assert() {
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 8080 tcp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5353 udp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp default
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 8080 tcp default
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5353 udp default
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,14 +356,39 @@ test-ufw-docker--allow-instance-all-published-tcp-port() {
|
|||
ufw-docker--allow instance-name "" tcp
|
||||
}
|
||||
test-ufw-docker--allow-instance-all-published-tcp-port-assert() {
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 8080 tcp
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5353 udp # FIXME
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp default
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 8080 tcp default
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5353 udp default # FIXME
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker--allow-instance-all-published-port-multinetwork() {
|
||||
setup-ufw-docker--allow--multinetwork
|
||||
|
||||
ufw-docker--allow instance-name "" ""
|
||||
}
|
||||
test-ufw-docker--allow-instance-all-published-port-multinetwork-assert() {
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5000 tcp default
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 5000 tcp awesomenet
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 8080 tcp default
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 8080 tcp awesomenet
|
||||
ufw-docker--add-rule instance-name 172.18.0.3 5353 udp default
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 5353 udp awesomenet
|
||||
}
|
||||
|
||||
test-ufw-docker--allow-instance-all-published-port-multinetwork-select-network() {
|
||||
setup-ufw-docker--allow--multinetwork
|
||||
|
||||
ufw-docker--allow instance-name "" "" awesomenet
|
||||
}
|
||||
test-ufw-docker--allow-instance-all-published-port-multinetwork-select-network-assert() {
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 5000 tcp awesomenet
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 8080 tcp awesomenet
|
||||
ufw-docker--add-rule instance-name 172.19.0.7 5353 udp awesomenet
|
||||
}
|
||||
|
||||
test-ufw-docker--add-rule-a-non-existing-rule() {
|
||||
@mockfalse ufw-docker--list webapp 5000 tcp
|
||||
@mockfalse ufw-docker--list webapp 5000 tcp ""
|
||||
|
||||
load-ufw-docker-function ufw-docker--add-rule
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp
|
||||
|
@ -307,29 +397,39 @@ test-ufw-docker--add-rule-a-non-existing-rule-assert() {
|
|||
ufw route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp"
|
||||
}
|
||||
|
||||
test-ufw-docker--add-rule-a-non-existing-rule-with-network() {
|
||||
@mockfalse ufw-docker--list webapp 5000 tcp default
|
||||
|
||||
load-ufw-docker-function ufw-docker--add-rule
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp default
|
||||
}
|
||||
test-ufw-docker--add-rule-a-non-existing-rule-with-network-assert() {
|
||||
ufw route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp default"
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker--add-rule-modify-an-existing-rule() {
|
||||
@mocktrue ufw-docker--list webapp 5000 tcp
|
||||
@mocktrue ufw --dry-run route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp"
|
||||
@mocktrue ufw-docker--list webapp 5000 tcp default
|
||||
@mocktrue ufw --dry-run route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp default"
|
||||
@mockfalse grep "^Skipping"
|
||||
|
||||
load-ufw-docker-function ufw-docker--add-rule
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp default
|
||||
}
|
||||
test-ufw-docker--add-rule-modify-an-existing-rule-assert() {
|
||||
ufw-docker--delete webapp 5000 tcp
|
||||
ufw-docker--delete webapp 5000 tcp default
|
||||
|
||||
ufw route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp"
|
||||
ufw route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp default"
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker--add-rule-skip-an-existing-rule() {
|
||||
@mocktrue ufw-docker--list webapp 5000 tcp
|
||||
@mocktrue ufw-docker--list webapp 5000 tcp ""
|
||||
@mocktrue ufw --dry-run route allow proto tcp from any to 172.18.0.4 port 5000 comment "allow webapp 5000/tcp"
|
||||
@mocktrue grep "^Skipping"
|
||||
|
||||
load-ufw-docker-function ufw-docker--add-rule
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp
|
||||
ufw-docker--add-rule webapp 172.18.0.4 5000 tcp ""
|
||||
}
|
||||
test-ufw-docker--add-rule-skip-an-existing-rule-assert() {
|
||||
@do-nothing
|
||||
|
@ -337,17 +437,17 @@ test-ufw-docker--add-rule-skip-an-existing-rule-assert() {
|
|||
|
||||
|
||||
test-ufw-docker--add-rule-modify-an-existing-rule-without-port() {
|
||||
@mocktrue ufw-docker--list webapp "" tcp
|
||||
@mocktrue ufw-docker--list webapp "" tcp ""
|
||||
|
||||
@mocktrue ufw --dry-run route allow proto tcp from any to 172.18.0.4 comment "allow webapp"
|
||||
@mockfalse grep "^Skipping"
|
||||
|
||||
load-ufw-docker-function ufw-docker--add-rule
|
||||
|
||||
ufw-docker--add-rule webapp 172.18.0.4 "" tcp
|
||||
ufw-docker--add-rule webapp 172.18.0.4 "" tcp ""
|
||||
}
|
||||
test-ufw-docker--add-rule-modify-an-existing-rule-without-port-assert() {
|
||||
ufw-docker--delete webapp "" tcp
|
||||
ufw-docker--delete webapp "" tcp ""
|
||||
|
||||
ufw route allow proto tcp from any to 172.18.0.4 comment "allow webapp"
|
||||
}
|
||||
|
@ -365,7 +465,7 @@ test-ufw-docker--instance-name-found-a-name() {
|
|||
}
|
||||
test-ufw-docker--instance-name-found-a-name-assert() {
|
||||
docker inspect --format="{{.Name}}" foo
|
||||
echo -n foo
|
||||
@dryrun echo -n foo
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,7 +488,7 @@ test-ufw-docker--list-name() {
|
|||
ufw-docker--list foo
|
||||
}
|
||||
test-ufw-docker--list-name-assert() {
|
||||
grep "# allow foo\\( [[:digit:]]\\+\\/\\(tcp\\|udp\\)\\)\\?\$"
|
||||
grep "# allow foo\\( [[:digit:]]\\+\\/\\(tcp\\|udp\\)\\)\\( [[:graph:]]*\\)\$"
|
||||
}
|
||||
|
||||
test-ufw-docker--list-name-udp() {
|
||||
|
@ -397,7 +497,7 @@ test-ufw-docker--list-name-udp() {
|
|||
ufw-docker--list foo "" udp
|
||||
}
|
||||
test-ufw-docker--list-name-udp-assert() {
|
||||
grep "# allow foo\\( [[:digit:]]\\+\\/\\(tcp\\|udp\\)\\)\\?\$"
|
||||
grep "# allow foo\\( [[:digit:]]\\+\\/\\(tcp\\|udp\\)\\)\\( [[:graph:]]*\\)\$"
|
||||
}
|
||||
|
||||
|
||||
|
@ -407,7 +507,7 @@ test-ufw-docker--list-name-80() {
|
|||
ufw-docker--list foo 80
|
||||
}
|
||||
test-ufw-docker--list-name-80-assert() {
|
||||
grep "# allow foo\\( 80\\/tcp\\)\\?\$"
|
||||
grep "# allow foo\\( 80\\/tcp\\)\\( [[:graph:]]*\\)\$"
|
||||
}
|
||||
|
||||
|
||||
|
@ -417,7 +517,30 @@ test-ufw-docker--list-name-80-udp() {
|
|||
ufw-docker--list foo 80 udp
|
||||
}
|
||||
test-ufw-docker--list-name-80-udp-assert() {
|
||||
grep "# allow foo\\( 80\\/udp\\)\\?\$"
|
||||
grep "# allow foo\\( 80\\/udp\\)\\( [[:graph:]]*\\)\$"
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker--list-grep-without-network() {
|
||||
@mocktrue ufw status numbered
|
||||
@mockfalse grep "# allow foo\\( 80\\/udp\\)\\( [[:graph:]]*\\)\$"
|
||||
load-ufw-docker-function ufw-docker--list
|
||||
ufw-docker--list foo 80 udp
|
||||
}
|
||||
test-ufw-docker--list-grep-without-network-assert() {
|
||||
grep "# allow foo\\( 80\\/udp\\)\$"
|
||||
}
|
||||
|
||||
|
||||
test-ufw-docker--list-grep-without-network-and-port() {
|
||||
@mocktrue ufw status numbered
|
||||
@mockfalse grep "# allow foo\\( 80\\/udp\\)\\( [[:graph:]]*\\)\$"
|
||||
@mockfalse grep "# allow foo\\( 80\\/udp\\)\$"
|
||||
load-ufw-docker-function ufw-docker--list
|
||||
ufw-docker--list foo 80 udp
|
||||
}
|
||||
test-ufw-docker--list-grep-without-network-and-port-assert() {
|
||||
grep "# allow foo\$"
|
||||
}
|
||||
|
||||
|
||||
|
@ -434,7 +557,7 @@ test-ufw-docker--list-number-assert() {
|
|||
|
||||
test-ufw-docker--delete-empty-result() {
|
||||
@mock ufw-docker--list-number webapp 80 tcp === @stdout ""
|
||||
@mock sort -rn
|
||||
@mockpipe sort -rn
|
||||
|
||||
load-ufw-docker-function ufw-docker--delete
|
||||
ufw-docker--delete webapp 80 tcp
|
||||
|
@ -446,7 +569,7 @@ test-ufw-docker--delete-empty-result-assert() {
|
|||
|
||||
test-ufw-docker--delete-all() {
|
||||
@mock ufw-docker--list-number webapp 80 tcp === @stdout 5 8 9
|
||||
@mock sort -rn
|
||||
@mockpipe sort -rn
|
||||
|
||||
load-ufw-docker-function ufw-docker--delete
|
||||
ufw-docker--delete webapp 80 tcp
|
||||
|
|
116
ufw-docker
116
ufw-docker
|
@ -5,13 +5,23 @@ set -euo pipefail
|
|||
LANG=en_US.UTF-8
|
||||
LANGUAGE=en_US:
|
||||
LC_ALL=en_US.UTF-8
|
||||
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
PATH="/bin:/usr/bin:/sbin:/usr/sbin:/snap/bin/"
|
||||
|
||||
GREP_REGEXP_INSTANCE_NAME="[-_.[:alnum:]]\\+"
|
||||
DEFAULT_PROTO=tcp
|
||||
|
||||
ufw_docker_agent=ufw-docker-agent
|
||||
ufw_docker_agent_image="${UFW_DOCKER_AGENT_IMAGE:-chaifeng/${ufw_docker_agent}:200812}"
|
||||
ufw_docker_agent_image="${UFW_DOCKER_AGENT_IMAGE:-chaifeng/${ufw_docker_agent}:221002-nf_tables}"
|
||||
|
||||
if [[ "${ufw_docker_agent_image}" = *-@(legacy|nf_tables) ]]; then
|
||||
if iptables --version | grep -F '(legacy)' &>/dev/null; then
|
||||
ufw_docker_agent_image="${ufw_docker_agent_image%-*}-legacy"
|
||||
else
|
||||
ufw_docker_agent_image="${ufw_docker_agent_image%-*}-nf_tables"
|
||||
fi
|
||||
fi
|
||||
|
||||
test -n "$ufw_docker_agent_image"
|
||||
|
||||
function ufw-docker--status() {
|
||||
ufw-docker--list "$GREP_REGEXP_INSTANCE_NAME"
|
||||
|
@ -21,12 +31,20 @@ function ufw-docker--list() {
|
|||
local INSTANCE_NAME="$1"
|
||||
local INSTANCE_PORT="${2:-}"
|
||||
local PROTO="${3:-${DEFAULT_PROTO}}"
|
||||
local NETWORK="${4:-}"
|
||||
|
||||
if [[ -z "$INSTANCE_PORT" ]]; then
|
||||
INSTANCE_PORT="[[:digit:]]\\+"
|
||||
PROTO="\\(tcp\\|udp\\)"
|
||||
fi
|
||||
ufw status numbered | grep "# allow ${INSTANCE_NAME}\\( ${INSTANCE_PORT}\\/${PROTO}\\)\\?\$"
|
||||
|
||||
if [[ -z "$NETWORK" ]]; then
|
||||
NETWORK="[[:graph:]]*"
|
||||
fi
|
||||
|
||||
ufw status numbered | grep "# allow ${INSTANCE_NAME}\\( ${INSTANCE_PORT}\\/${PROTO}\\)\\( ${NETWORK}\\)\$" || \
|
||||
ufw status numbered | grep "# allow ${INSTANCE_NAME}\\( ${INSTANCE_PORT}\\/${PROTO}\\)\$" || \
|
||||
ufw status numbered | grep "# allow ${INSTANCE_NAME}\$"
|
||||
}
|
||||
|
||||
function ufw-docker--list-number() {
|
||||
|
@ -44,6 +62,7 @@ function ufw-docker--allow() {
|
|||
local INSTANCE_NAME="$1"
|
||||
local INSTANCE_PORT="$2"
|
||||
local PROTO="$3"
|
||||
local NETWORK="${4:-}"
|
||||
|
||||
docker inspect "$INSTANCE_NAME" &>/dev/null ||
|
||||
die "Docker instance \"$INSTANCE_NAME\" doesn't exist."
|
||||
|
@ -52,6 +71,7 @@ function ufw-docker--allow() {
|
|||
|
||||
[[ -z "${INSTANCE_IP_ADDRESSES:-}" ]] && die "Could not find a running instance \"$INSTANCE_NAME\"."
|
||||
|
||||
mapfile -t INSTANCE_NETWORK_NAMES < <(docker inspect --format='{{range $k, $v := .NetworkSettings.Networks}}{{printf "%s\n" $k}}{{end}}' "$INSTANCE_NAME" 2>/dev/null | remove_blank_lines)
|
||||
mapfile -t PORT_PROTO_LIST < <(docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{with $conf}}{{$p}}{{"\n"}}{{end}}{{end}}' "$INSTANCE_NAME" | remove_blank_lines)
|
||||
|
||||
if [[ -z "${PORT_PROTO_LIST:-}" ]]; then
|
||||
|
@ -62,8 +82,14 @@ function ufw-docker--allow() {
|
|||
RETVAL=1
|
||||
for PORT_PROTO in "${PORT_PROTO_LIST[@]}"; do
|
||||
if [[ -z "$INSTANCE_PORT" || "$PORT_PROTO" = "${INSTANCE_PORT}/${PROTO}" ]]; then
|
||||
ITER=0
|
||||
for IP in "${INSTANCE_IP_ADDRESSES[@]}"; do
|
||||
ufw-docker--add-rule "$INSTANCE_NAME" "$IP" "${PORT_PROTO%/*}" "${PORT_PROTO#*/}"
|
||||
INSTANCE_NETWORK="${INSTANCE_NETWORK_NAMES[$ITER]}"
|
||||
ITER=$((ITER+1))
|
||||
if [[ -n "$NETWORK" ]] && [[ "$NETWORK" != "$INSTANCE_NETWORK" ]]; then
|
||||
continue
|
||||
fi
|
||||
ufw-docker--add-rule "$INSTANCE_NAME" "$IP" "${PORT_PROTO%/*}" "${PORT_PROTO#*/}" "${INSTANCE_NETWORK}"
|
||||
RETVAL="$?"
|
||||
done
|
||||
fi
|
||||
|
@ -92,10 +118,11 @@ function ufw-docker--add-rule() {
|
|||
local INSTANCE_IP_ADDRESS="$2"
|
||||
local PORT="$3"
|
||||
local PROTO="$4"
|
||||
local NETWORK="${5:-}"
|
||||
|
||||
declare comment
|
||||
|
||||
echo "allow ${INSTANCE_NAME} ${PORT}/${PROTO}"
|
||||
echo "allow ${INSTANCE_NAME} ${PORT}/${PROTO} ${NETWORK}"
|
||||
typeset -a UFW_OPTS
|
||||
UFW_OPTS=(route allow proto "${PROTO}"
|
||||
from any to "$INSTANCE_IP_ADDRESS")
|
||||
|
@ -104,12 +131,15 @@ function ufw-docker--add-rule() {
|
|||
UFW_OPTS+=(port "${PORT}")
|
||||
comment="$comment ${PORT}/${PROTO}"
|
||||
}
|
||||
[[ -n "$NETWORK" ]] && {
|
||||
comment="$comment ${NETWORK}"
|
||||
}
|
||||
UFW_OPTS+=(comment "$comment")
|
||||
|
||||
if ufw-docker--list "$INSTANCE_NAME" "$PORT" "$PROTO" &>/dev/null; then
|
||||
if ufw-docker--list "$INSTANCE_NAME" "$PORT" "$PROTO" "$NETWORK" &>/dev/null; then
|
||||
ufw --dry-run "${UFW_OPTS[@]}" | grep "^Skipping" && return 0
|
||||
err "Remove outdated rule."
|
||||
ufw-docker--delete "$INSTANCE_NAME" "$PORT" "$PROTO"
|
||||
ufw-docker--delete "$INSTANCE_NAME" "$PORT" "$PROTO" "$NETWORK"
|
||||
fi
|
||||
echo ufw "${UFW_OPTS[@]}"
|
||||
ufw "${UFW_OPTS[@]}"
|
||||
|
@ -262,34 +292,34 @@ function ufw-docker--raw-command() {
|
|||
after_rules="/etc/ufw/after.rules"
|
||||
|
||||
function ufw-docker--check() {
|
||||
err "\\n########## iptables -n -L DOCKER-USER ##########"
|
||||
iptables -n -L DOCKER-USER
|
||||
err "\\n########## iptables -n -L DOCKER-USER ##########"
|
||||
iptables -n -L DOCKER-USER
|
||||
|
||||
err "\\n\\n########## diff $after_rules ##########"
|
||||
ufw-docker--check-install && err "\\nCheck done."
|
||||
err "\\n\\n########## diff $after_rules ##########"
|
||||
ufw-docker--check-install && err "\\nCheck done."
|
||||
}
|
||||
|
||||
declare -a files_to_be_deleted
|
||||
|
||||
function rm-on-exit() {
|
||||
[[ $# -gt 0 ]] && files_to_be_deleted+=("$@")
|
||||
[[ $# -gt 0 ]] && files_to_be_deleted+=("$@")
|
||||
}
|
||||
|
||||
function on-exit() {
|
||||
for file in "${files_to_be_deleted[@]:-}"; do
|
||||
[[ -f "$file" ]] && rm -r "$file"
|
||||
done
|
||||
files_to_be_deleted=()
|
||||
for file in "${files_to_be_deleted[@]:-}"; do
|
||||
[[ -f "$file" ]] && rm -r "$file"
|
||||
done
|
||||
files_to_be_deleted=()
|
||||
}
|
||||
|
||||
trap on-exit EXIT INT TERM QUIT ABRT ERR
|
||||
|
||||
function ufw-docker--check-install() {
|
||||
after_rules_tmp="${after_rules_tmp:-$(mktemp)}"
|
||||
rm-on-exit "$after_rules_tmp"
|
||||
after_rules_tmp="${after_rules_tmp:-$(mktemp)}"
|
||||
rm-on-exit "$after_rules_tmp"
|
||||
|
||||
sed "/^# BEGIN UFW AND DOCKER/,/^# END UFW AND DOCKER/d" "$after_rules" > "$after_rules_tmp"
|
||||
>> "${after_rules_tmp}" cat <<-\EOF
|
||||
sed "/^# BEGIN UFW AND DOCKER/,/^# END UFW AND DOCKER/d" "$after_rules" > "$after_rules_tmp"
|
||||
>> "${after_rules_tmp}" cat <<-\EOF
|
||||
# BEGIN UFW AND DOCKER
|
||||
*filter
|
||||
:ufw-user-forward - [0:0]
|
||||
|
@ -319,30 +349,30 @@ function ufw-docker--check-install() {
|
|||
# END UFW AND DOCKER
|
||||
EOF
|
||||
|
||||
diff -u --color=auto "$after_rules" "$after_rules_tmp"
|
||||
diff -u --color=auto "$after_rules" "$after_rules_tmp"
|
||||
}
|
||||
|
||||
function ufw-docker--install() {
|
||||
if ! ufw-docker--check-install; then
|
||||
local after_rules_bak
|
||||
after_rules_bak="${after_rules}-ufw-docker~$(date '+%Y-%m-%d-%H%M%S')~"
|
||||
err "\\nBacking up $after_rules to $after_rules_bak"
|
||||
cp "$after_rules" "$after_rules_bak"
|
||||
cat "$after_rules_tmp" > "$after_rules"
|
||||
err "Please restart UFW service manually by using the following command:"
|
||||
if type systemctl &>/dev/null; then
|
||||
err " sudo systemctl restart ufw"
|
||||
else
|
||||
err " sudo service ufw restart"
|
||||
if ! ufw-docker--check-install; then
|
||||
local after_rules_bak
|
||||
after_rules_bak="${after_rules}-ufw-docker~$(date '+%Y-%m-%d-%H%M%S')~"
|
||||
err "\\nBacking up $after_rules to $after_rules_bak"
|
||||
cp "$after_rules" "$after_rules_bak"
|
||||
cat "$after_rules_tmp" > "$after_rules"
|
||||
err "Please restart UFW service manually by using the following command:"
|
||||
if type systemctl &>/dev/null; then
|
||||
err " sudo systemctl restart ufw"
|
||||
else
|
||||
err " sudo service ufw restart"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function ufw-docker--help() {
|
||||
cat <<-EOF >&2
|
||||
cat <<-EOF >&2
|
||||
Usage:
|
||||
ufw-docker <list|allow> [docker-instance-id-or-name [port[/tcp|/udp]]]
|
||||
ufw-docker delete allow [docker-instance-id-or-name [port[/tcp|/udp]]]
|
||||
ufw-docker <list|allow> [docker-instance-id-or-name [port[/tcp|/udp]] [network]]
|
||||
ufw-docker delete allow [docker-instance-id-or-name [port[/tcp|/udp]] [network]]
|
||||
|
||||
ufw-docker service allow <swarm-service-id-or-name <port</tcp|/udp>>>
|
||||
ufw-docker service delete allow <swarm-service-id-or-name>
|
||||
|
@ -363,10 +393,11 @@ function ufw-docker--help() {
|
|||
ufw-docker allow httpd
|
||||
ufw-docker allow httpd 80
|
||||
ufw-docker allow httpd 80/tcp
|
||||
ufw-docker allow httpd 80/tcp default
|
||||
|
||||
ufw-docker delete allow httpd
|
||||
ufw-docker delete allow httpd 80/tcp
|
||||
|
||||
ufw-docker delete allow httpd 80/tcp default
|
||||
|
||||
ufw-docker service allow httpd 80/tcp
|
||||
|
||||
|
@ -390,7 +421,11 @@ function die() {
|
|||
# __main__
|
||||
|
||||
if ! ufw status 2>/dev/null | grep -Fq "Status: active" ; then
|
||||
die "UFW is disabled or you are not root user."
|
||||
die "UFW is disabled or you are not root user, or mismatched iptables legacy/nf_tables, current $(iptables --version)"
|
||||
fi
|
||||
|
||||
if ! docker -v &> /dev/null; then
|
||||
die "Docker executable not found."
|
||||
fi
|
||||
|
||||
ufw_action="${1:-help}"
|
||||
|
@ -418,10 +453,13 @@ case "$ufw_action" in
|
|||
if [[ "$INSTANCE_PORT" = */udp ]]; then
|
||||
PROTO=udp
|
||||
fi
|
||||
shift || true
|
||||
|
||||
NETWORK="${1:-}"
|
||||
|
||||
INSTANCE_PORT="${INSTANCE_PORT%/*}"
|
||||
|
||||
"ufw-docker--$ufw_action" "$INSTANCE_NAME" "$INSTANCE_PORT" "$PROTO"
|
||||
"ufw-docker--$ufw_action" "$INSTANCE_NAME" "$INSTANCE_PORT" "$PROTO" "$NETWORK"
|
||||
;;
|
||||
service|raw-command|add-service-rule)
|
||||
shift || true
|
||||
|
|
Loading…
Add table
Reference in a new issue