cloud-sre
Polygon Erigon アーカイブノードで 8545 を閉じた理由
Polygon Erigon archive node を allow-all の security group から最小限の公開入口へ収束させた実践記録。
ブロックチェーンのアーカイブノードは、すべてのポートをインターネットに公開したまま運用されがちです。特にノードがまだ同期中で負荷が高い状態では危険です。公開スキャナーが JSON-RPC を継続的に探査し、ログには eth_accounts や eth_sendRawTransaction のような意味のない呼び出しが増えます。
この記事では、Polygon Erigon archive node の security group を収束させた実例を整理します。P2P ネットワークに必要な公開ポートだけを残し、public JSON-RPC、metrics、private API、SSH を閉じました。
背景
対象は Polygon Mainnet archive node です。Polygon の公式 archive node ドキュメントでは、16-core CPU、64GB RAM、mainnet archive node で約 15TB のストレージが基準として示されています。ストレージは io1 以上、20k+ IOPS、RAID-0、SSD または NVMe が推奨されています [1]。
Erigon の起動パラメータでは HTTP JSON-RPC が有効でした。
--http
--ws
--http.addr=0.0.0.0
--http.port=8545
--http.api=web3,net,eth,trace
これはコンテナ内でサービスが全アドレスに bind しているという意味です。EC2 security group でも 8545/tcp の公网アクセスを許可していれば、JSON-RPC がインターネットに直接露出します。
何が問題だったのか
ノードのログには、外部 IP から RPC method が呼ばれた記録がありました。すでに deprecated な eth_accounts のような呼び出しも含まれていました。この種のトラフィックは業務アクセスではなく、公開スキャンや探査です。
Erigon README は Public RPC について、--http.api に admin を入れないこと、広すぎる CORS を避けること、DoS リスクを下げるために batch 関連パラメータを絞ることを説明しています [2]。
より直接的な対策は単純です。このノードを public RPC service として提供しないなら、security group で 8545 を公開しないことです。
Security Group の判断
最終的な security group では、入站ルールを次の三つだけにしました。
| Port | Protocol | Source | Purpose |
|---|---|---|---|
30303 | TCP | 0.0.0.0/0 | Erigon P2P peering |
30303 | UDP | 0.0.0.0/0 | Erigon P2P peering |
42069 | UDP | 0.0.0.0/0 | Erigon torrent / snapshot peer |
次の公開入口は閉じました。
| Port | Reason |
|---|---|
8545/tcp | JSON-RPC。このノードから public RPC を提供する要件がないため。 |
6060/tcp | metrics / pprof 系の観測ポート。内部監視またはローカル調査向け。 |
9090/tcp | Erigon private API。Erigon の例でも private.api.addr は 127.0.0.1:9090 です。 |
8546/tcp | WebSocket RPC。公開 WebSocket RPC の要件がないため。 |
8551/tcp | Engine API / JWT auth。外部ユーザー向け入口ではありません。 |
22/tcp | SSH。運用アクセスは SSM Session Manager を使うため。 |
この判断は Erigon の default port guidance とも一致します。30303 と 30304 は公開 peering port、42069 は snap sync、8545 は RPC、metrics/private/Engine API 系のポートは private として扱うべきです [3]。
なぜ outbound は開けたままにしたのか
今回収束させたのは inbound だけです。outbound は開けたままにしました。Polygon Erigon は外部依存に対して自分から接続する必要があります。
- P2P peers
- remote Heimdall API
- snapshot / torrent peers
- system maintenance、image pull、package repository への HTTPS
Polygon 公式ドキュメントでは、local Heimdall を使わない場合、--bor.heimdall=<your heimdall url> で remote Heimdall を指定できると説明されています。PoS mainnet の endpoint は https://heimdall-api.polygon.technology です [1]。
そのため、outbound は 0.0.0.0/0 のままにし、inbound だけを最小限にする、という判断にしました。
AWS Security Group は stateful な仮想 firewall です。関連付けられた resource に入る通信と出る通信を制御します。新しい security group はデフォルトで inbound rule を持たず、default outbound rule はすべての outbound traffic を許可します [4][5]。
Terraform での表現
Terraform では Polygon ノードを共有の allow-all security group から専用 security group に移しました。
security_group_ids = [aws_security_group.polygon_node_sg.id]
専用 security group では P2P と torrent の inbound だけを残します。
ingress {
description = "Polygon P2P TCP"
from_port = 30303
to_port = 30303
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Polygon P2P UDP"
from_port = 30303
to_port = 30303
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Polygon torrent UDP"
from_port = 42069
to_port = 42069
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}
8545 と 6060 は固定で公開せず、明示的な allowlist 変数にしました。
variable "polygon_rpc_allowed_cidr_blocks" {
description = "CIDR blocks allowed to access Polygon JSON-RPC on TCP 8545. Empty closes public RPC access."
type = list(string)
default = []
}
variable "polygon_metrics_allowed_cidr_blocks" {
description = "CIDR blocks allowed to access Polygon Erigon metrics on TCP 6060. Empty closes public metrics access."
type = list(string)
default = []
}
デフォルトは閉じた状態です。後で固定の office egress IP、monitoring VPC、reverse proxy からアクセスさせる必要が出た場合だけ、明示的に CIDR を追加します。
一時的なオンライン変更
Terraform provider のローカル問題で即時 apply できない場合は、AWS CLI で同等の変更を先に適用できます。
aws ec2 create-security-group \
--region ap-northeast-1 \
--group-name polygon-node-sg \
--description "Polygon Erigon node security group" \
--vpc-id <vpc-id>
その後、必要な inbound だけを許可します。
aws ec2 authorize-security-group-ingress \
--region ap-northeast-1 \
--group-id <polygon-node-sg-id> \
--ip-permissions \
'IpProtocol=tcp,FromPort=30303,ToPort=30303,IpRanges=[{CidrIp=0.0.0.0/0,Description="Polygon P2P TCP"}]' \
'IpProtocol=udp,FromPort=30303,ToPort=30303,IpRanges=[{CidrIp=0.0.0.0/0,Description="Polygon P2P UDP"}]' \
'IpProtocol=udp,FromPort=42069,ToPort=42069,IpRanges=[{CidrIp=0.0.0.0/0,Description="Polygon torrent UDP"}]'
最後に instance を新しい security group に切り替えます。
aws ec2 modify-instance-attribute \
--region ap-northeast-1 \
--instance-id <instance-id> \
--groups <polygon-node-sg-id>
この操作では EC2 も container も再起動しません。ENI に関連付けられている security group rule が変わるだけです。
検証
外部からの 8545 は失敗するべきです。
curl -sS --connect-timeout 5 -m 8 \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://<public-ip>:8545
期待する結果は timeout または connection failure です。
一方、instance 内部から local RPC は引き続き使えるべきです。
curl -sS -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://127.0.0.1:8545 | jq
これは RPC service 自体を止めたのではなく、public internet から到達できないようにしただけであることを確認します。
同期も継続していることを確認します。
curl -sS -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \
http://127.0.0.1:8545 | jq
currentBlock が増え続け、ログに Execution の進行が出ていれば、P2P、Heimdall、local RPC は引き続き機能しています。
後続作業
手作業で作った security group は Terraform state に import する必要があります。
terraform import aws_security_group.polygon_node_sg <polygon-node-sg-id>
その後、通常どおり terraform plan と terraform apply を実行し、Terraform が同名 security group を重複作成しないようにします。
次の改善は RPC を再公開することではありません。RPC を明確な境界の内側に置くことです。
- internal-only access
- 固定された office egress IP
- 認証、rate limit、access log を持つ reverse proxy
- archive node 本体ではなく、別の read-only RPC layer
アーカイブノードの主目的は安定した追従同期と内部 query service です。public RPC product として明示的に運用するのでなければ、8545 を public internet に置くべきではありません。
参考文献
[1] Polygon Labs. “Run an Erigon archive node.” Polygon Docs. https://docs.polygon.technology/pos/how-to/erigon-archive-node
[2] Erigon Contributors. “Public RPC.” Erigon README. https://github.com/erigontech/erigon#public-rpc
[3] Erigon Contributors. “Default Ports and Firewalls.” Erigon README. https://github.com/erigontech/erigon#default-ports-and-firewalls
[4] Amazon Web Services. “Control traffic to AWS resources using security groups.” Amazon VPC User Guide. https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html
[5] Amazon Web Services. “Security group rules.” Amazon VPC User Guide. https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html