ElasticSearchコンテナーを会社のLaravel app。上記のLaravelアプリの特定のIPからのみアクセスできます。
調査中、多くの人がDockerによって転送されたポートへのトラフィックが完全に公開され、適切にファイアウォールを設定できないというこれらの問題を抱えていることに気付きました。
私はいくつかのsolutionsを過去6時間で見つけましたが、どれも機能していませんでした。これはDockerがインバウンドトラフィックを処理/転送する方法に関係していると思います。iptablesの知識はそれほど大きくないため、自分で何が起こっているのかを理解できます。
これは私のdocker-compose.ymlです(価値あるもの):
version: '3.4'
services:
elasticsearch:
image: khezen/elasticsearch:6.1.1
container_name: elasticsearch
environment:
NETWORK_Host: 0.0.0.0
HOSTS: 127.0.0.1
CLUSTER_NAME: fd-es
NODE_NAME: node-1
HEAP_SIZE: 31g
HTTP_SSL: "true"
ELASTIC_PWD: "somepasswd"
HTTP_CORS_ENABLE: "true"
HTTP_CORS_ALLOW_Origin: /https?:\/\/localhost(:[0-9]+)?/
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./config/elasticsearch.yml:/elasticsearch/config/elasticsearch.yml
- ./data:/elasticsearch/data
- ./logs:/elasticsearch/logs
ports:
- 9200:9200
networks:
- es-network
restart: always
networks:
es-network:
driver: bridge
これらは現在使用しているiptablesルールで、ある程度は必要ですが、任意のクライアントからポート9200へのすべてのトラフィックは、アプリからのみアクセスできるのではなく、そのまま通過します。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [779:162776]
:DOCKER - [0:0]
-A DOCKER -s xxx.xxx.xxx.xxx -p tcp -m tcp --dport 9200 -j ACCEPT
-A DOCKER -o docker0 -p tcp -m tcp --dport 9200 -j ACCEPT
-A DOCKER -p tcp --dport 9200 -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 44344 -j ACCEPT
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A INPUT -j DROP
Dockerのiptablesサポートを無効にし、ブリッジネットワークを無効にして、iptablesルールを数十回微調整しましたが、役に立ちませんでした。
私はこの問題のアイデアと検索結果が足りないので、どんな提案やこれを実現する手助けをいただければ幸いです。
前もって感謝します!
この問題の解決策を探しているすべての人にとって、答えはこれです。
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:FILTERS - [0:0]
:DOCKER-USER - [0:0]
-F INPUT
-F DOCKER-USER
-F FILTERS
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A INPUT -j FILTERS
-A DOCKER-USER -i ens33 -j FILTERS
-A FILTERS -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A FILTERS -j REJECT --reject-with icmp-Host-prohibited
COMMIT
ここで見つかりました: https://unrouted.io/2017/08/15/docker-firewall/
完璧に動作します。
私があなたが達成したいことをテストした私のシナリオを説明します。
ポート9010がポート8080に転送されるDockerコンテナーを起動しました。
docker run -p 9010:8080 swaggerapi/swagger-editor
Dockerは、ポート9010からポート8080にトラフィックを転送するPREROUTINGチェーンのDNATルールを作成します。
DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9010 to:172.17.0.5:8080
Dockerは、DOCKERチェーンにルールを作成し、コンテナーのIPアドレスとポート8080に送信されるすべてのトラフィックを許可します。
ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.5 tcp dpt:8080
DOCKERチェーンはFORWARDチェーンで使用され、docker0ブリッジに送信されるすべてのトラフィックはDOCKERチェーンのルールによって処理されます。
DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
次に、ポート8080に送信されるトラフィック(ポート9010へのトラフィックはPREROUTINGによって処理され、ポート8080に送信されるトラフィックです)をフィルター処理して、IP 192.168.1.142からのトラフィックを許可しながらすべてのIPアドレスをブロックします。もちろん、コンテナのIPアドレスをこれらのルールに追加して、より細かい粒度にすることもできます。
[〜#〜] forward [〜#〜]チェーンの先頭に次のルールを追加します。または、FORWARDをDOCKERに置き換えることもできます。
iptables -I FORWARD -p tcp --dport 8080 -j DROP
iptables -I FORWARD -p tcp -s 192.168.1.142 --dport 8080 -j ACCEPT
これらのルールのおかげで、コンテナが使用する8080ポートに到達できるのはIP 192.168.1.142だけです。
この回答にアクセスする場合、1つの特定のIPアドレスにのみコンテナーへのアクセスを許可する場合は、 Docker docs で提案されているiptablesコマンドを使用します。