blog.yuzu441.com

ubuntuでdockerを動かしてfirewallを有効にする

ubuntuでdockerを動かして-pオプションでportを指定するとufwでssh用の22番しか許可していなくても設定を超えてポートが開いてしまうらしいので検証と対処方法を調べたメモ。

経緯

今回はnginxで確認しているけどmysqlなどをdockerで-p 3306:3306などをした時に外部から接続できてしまうのでそれの対策として調べている

vultrでvmを作る

確認には以前遊んでた時のクレジットが残っていたのでvultrでubuntuを立てる。そんなに性能はいらないので比較的最低スペックで作る

  • Cloud Compute - Shared CPU
  • Osaka(やってみたかっただけなのでTokyoなど近い所で良い)
  • ubuntu 24.04 lts
  • 25 GB NVMe 1 vCPU 1 GB 25 GB NVMe 2 TB $6/month $0.009/hour
  • Auto Backupを外す

dockerのインストール

Install Docker Engine on Ubuntu | Docker Docs を参考に適当にいれる

ufwを設定してもポートが開いていることを検証

ufwでssh用の22番ポート以外はdenyを設定する。ただvultrのvmはデフォルトで設定されて起動していたので他でやるなら以下のイメージ

sudo ufw default deny

sudo ufw allow 22

sudo ufw enable

dockerでnginxを起動してアクセスできてしまうことを確認する

sudo docker run -p 80:80 --rm  nginx

ターミナルをもう一つ起動してvultrのインスタンスに対してhttpのリクエストを投げる

# nginxの内容が表示される
curl http://xxx

iptablesの設定を確認すると以下のようになっていた(無関係の部分は省略しています

sudo iptables -L
Chain DOCKER (1 references)
target     prot opt source               destination

# 別ターミナルでnginxをdockerで起動
sudo iptables -L
Chain DOCKER (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             xxx           tcp dpt:http

nginxを停止し、これが通信できないようにする

ufwが有効になるようにする

ufw-dockerを設定してあげると良いらしい

/etc/ufw/after.rulesに設定を加える(# BEGIN UFW AND DOCKER の上がデフォルトで書かれていた分)

#
# rules.input-after
#
# Rules that should be run after the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-after-input
#   ufw-after-output
#   ufw-after-forward
#

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-after-input - [0:0]
:ufw-after-output - [0:0]
:ufw-after-forward - [0:0]
# End required lines

# don't log noisy services by default
-A ufw-after-input -p udp --dport 137 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp --dport 138 -j ufw-skip-to-policy-input
-A ufw-after-input -p tcp --dport 139 -j ufw-skip-to-policy-input
-A ufw-after-input -p tcp --dport 445 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp --dport 67 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp --dport 68 -j ufw-skip-to-policy-input

# don't log noisy broadcast
-A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT


# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN

-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP

COMMIT
# END UFW AND DOCKER

ufwの設定をreloadする

sudo ufw reload

アクセスできないことを確認

これで再度nginxを起動してアクセスする

sudo docker run -p 80:80 --rm  nginx

別ターミナルで

# nginxの内容が表示される
curl http://xxx

レスポンスが返ってこず、nmapで接続してもポートが開いていない事が確認できる

namp -p 80 xxx

参考