web-dev-qa-db-ja.com

Dockerコンテナからの発信トラフィックをホワイトリストに登録する

次の構成で複数のDockerコンテナーを実行しているサーバーがあります。

  • コンテナの1つは、他のコンテナの公開ポートにバインドするリバースプロキシです。これは、httpポート80で外部からの接続を受け入れる唯一のコンテナです。
  • 他のすべてのコンテナーは、ttyシェルを実行する開発環境です。これらはホスト上のポートを公開していますが、ホスト上のEC2セキュリティグループ設定のため、これらのポートは外部に公開されていません。したがって、それらと通信する唯一の方法は、リバースプロキシを経由することです。リバースプロキシは、公開されたポートを介してそれらと通信します。
    n.b。新しい開発コンテナごとにリバースプロキシコンテナを再起動したくないため、ここではコンテナリンクを使用できません。

                    |                                DEV Env Docker
                    |                              / 
OUTSIDE WORLD <-----|------> REVERSE PROXY DOCKER  - DEV Env Docker
                    |                              \ 
                    |                                DEV Env Docker

ユーザーはリバースプロキシを介して開発コンテナにアクセスし、そのコンテナ内でコマンドを実行できるという考え方です。

接続できるドメインをホワイトリストに登録して、ユーザーが外部に接続するコマンドを実行できないようにしたい。

Squid3をインストールし、構成ファイルに次の行を追加してホワイトリストを設定しました。

acl whitelist dstdomain "/etc/squid3/whitelist.txt"
http_access allow whitelist

また、次のiptablesコマンドを使用して、Dockerコンテナからsquidにトラフィックをリダイレクトすることもできました。iptables-tnat -A PREROUTING -i docker0 -p tcp -d 0/0 -j REDIRECT --to-port 3128

私が抱えている問題は、Dev Envコンテナーからの発信トラフィックにのみsquidを通過させたいということですが、「信じている」ので、PREROUTINGを使用する必要があるため、リバースプロキシに着信するトラフィックも含めて、すべてのトラフィックがsquidを通過します。

Web経由でリバースプロキシにアクセスしようとすると、Squidから次のエラーが表示されます

ERROR
The requested URL could not be retrieved
The following error was encountered while trying to retrieve the URL: /
Invalid URL
Some aspect of the requested URL is incorrect.
Some possible problems are:
Missing or incorrect access protocol (should be http:// or similar)
Missing hostname
Illegal double-escape in the URL-Path
Illegal character in hostname; underscores are not allowed.
Your cache administrator is webmaster.
Generated Fri, 06 Nov 2015 18:56:54 GMT by ip-10-0-1-201 (squid/3.3.8)

質問:着信と発信の両方でリバースプロキシコンテナーに関連するすべてのトラフィックを無視するようにsquidを取得するにはどうすればよいですか?

私のiptablesはこんな感じです

# Generated by iptables-save v1.4.21 on Fri Nov  6 18:54:09 2015
*nat
:PREROUTING ACCEPT [30:1796]
:INPUT ACCEPT [28:1680]
:OUTPUT ACCEPT [37:2388]
:POSTROUTING ACCEPT [46:2964]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A PREROUTING -i docker0 -p tcp -d 0/0 -j REDIRECT --to-port 3128
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 8000 -    j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j     MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 172.17.0.3:8000
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8192 -j DNAT --to-destination 172.17.0.3:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
COMMIT
# Completed on Fri Nov  6 18:54:09 2015
# Generated by iptables-save v1.4.21 on Fri Nov  6 18:54:09 2015
*filter
:INPUT ACCEPT [1891:3910112]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1500:1500230]
:DOCKER - [0:0]
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8000 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Fri Nov  6 18:54:09 2015

----編集-----コメントに示されているようにhttp_portに変更を加えた後のSquid会議の完全版。

acl SSL_ports port 443
acl Safe_ports port 80      # http
acl Safe_ports port 21      # ftp
acl Safe_ports port 443     # https
acl Safe_ports port 70      # Gopher
acl Safe_ports port 210     # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280     # http-mgmt
acl Safe_ports port 488     # gss-http
acl Safe_ports port 591     # filemaker
acl Safe_ports port 777     # multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access allow localhost manager
http_access deny manager
acl allowed_ips src 172.17.0.0-172.17.0.254
http_access allow allowed_ips
http_access allow localhost
http_access deny all
http_port 3128 accel vhost allow-direct
coredump_dir /var/spool/squid3
refresh_pattern ^ftp:       1440    20% 10080
refresh_pattern ^Gopher:    1440    0%  1440
refresh_pattern -i (/cgi-bin/|\?) 0 0%  0
refresh_pattern (Release|Packages(.gz)*)$      0       20%     2880
refresh_pattern .       0   20% 4320

私はあなたが提供できるすべての助けに感謝します。

5
ajaali

秘訣は、IPtablesを取得してDEVEnvコンテナーからの接続のみをリダイレクトすることです。これを行うには、リバースプロキシからのすべての接続を受け入れるルールを追加します。したがって、IPテーブルルールは次のようになります。

-A PREROUTING -i docker0 -s 172.17.0.2/32 -j ACCEPT
-A PREROUTING -i docker0 -s 172.17.0.1/32 -j ACCEPT
-A PREROUTING -i docker0 -p tcp -d 0/0 -j REDIRECT --to-port 3128

Dockerは動的にIPを割り当てるため。 Dockerコンテナを再実行するか、サーバーを再起動する場合は、使用するIPを更新する必要があります。また、docker0ipである172.17.0.1のルールを追加しました。

これらのルールは、リバースプロキシコンテナとdocker Host自体を除いて、docker0インターフェイスから発信された他のすべてのトラフィックがsquidにリダイレクトされることを意味します。

Squid内では、次の行を使用して、ドメインを好きなようにホワイトリストに登録できます。

acl allowed_domain dstdomain google.com
http_access allow allowed_domain

完全なiptablesルールは次のとおりです。

# Generated by iptables-save v1.4.21 on Fri Nov  6 18:54:09 2015
*nat
:PREROUTING ACCEPT [30:1796]
:INPUT ACCEPT [28:1680]
:OUTPUT ACCEPT [37:2388]
:POSTROUTING ACCEPT [46:2964]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A PREROUTING -i docker0 -s 172.17.0.2/32 -j ACCEPT
-A PREROUTING -i docker0 -s 172.17.0.1/32 -j ACCEPT
-A PREROUTING -i docker0 -p tcp -d 0/0 -j REDIRECT --to-port 3128
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 8000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 172.17.0.3:8000
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8192 -j DNAT --to-destination 172.17.0.3:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
COMMIT
# Completed on Fri Nov  6 18:54:09 2015
# Generated by iptables-save v1.4.21 on Fri Nov  6 18:54:09 2015
*filter
:INPUT ACCEPT [1891:3910112]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1500:1500230]
:DOCKER - [0:0]
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8000 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Fri Nov  6 18:54:09 2015

完全なイカのルールは次のとおりです。

acl SSL_ports port 443
acl Safe_ports port 80      # http
acl Safe_ports port 21      # ftp
acl Safe_ports port 443     # https
acl Safe_ports port 70      # Gopher
acl Safe_ports port 210     # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280     # http-mgmt
acl Safe_ports port 488     # gss-http
acl Safe_ports port 591     # filemaker
acl Safe_ports port 777     # multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access allow localhost manager
http_access deny manager
acl allowed_domain dstdomain google.com
http_access allow allowed_domain
http_access allow localhost
http_access deny all
http_port 3128 accel vhost allow-direct
coredump_dir /var/spool/squid3
refresh_pattern ^ftp:       1440    20% 10080
refresh_pattern ^Gopher:    1440    0%  1440
refresh_pattern -i (/cgi-bin/|\?) 0 0%  0
refresh_pattern (Release|Packages(.gz)*)$      0       20%     2880
refresh_pattern .       0   20% 4320
1
ajaali