ファイル転送をする際、最近やっと scp とか sftp が主流になってきた (もしまだならこちらを参照)
けれど、まだまだ FTP が蔓延っています。(主に Web デザイン系)
かつて Linux のファイアウォールといえば iptables (+ ip_conntrack_ftp) で構成するのが定番だったのが、
CentOS8 は firewalld (+ nf_conntrack_helper) で構成します。(CentOS7 は firewalld + nf_conntrack_ftp)
firewalld も万能ではないので、細かい設定には iptables も出番がありますが。
本稿では 172.16.0.0/24 をインターネットの代替としている。ファイアウォール (今回設定対象のサーバ)
項目 内容 備考 ホスト名 fw-svr - WAN 側 NIC 管理ゾーン名 external external ゾーンには指定しなくても標準で masquerade=yes が設定される IP アドレス 172.16.0.10/24 インターネットに公開する IP アドレス インタフェース ens10 以前は eth0 等の命名規則だった FTP コマンドポート 21 番 FTP の Well known ポートをそのまま使う。
パッシブモードで 20 番ポートは使用しない。LAN 側 NIC 管理ゾーン名 internal - IP アドレス 192.168.1.10/24 - インタフェース ens11 - OS CentOS 8.3.2011 本稿記述時の最新版
FTP サーバ (LAN 内に既設)
項目 内容 備考 ホスト名 ftp-svr - IP アドレス 192.168.1.20/24 - GW アドレス 192.168.1.10 fw-svr の LAN 側 NIC をデフォルトルートとする。
こうしないと fw-svr の external 側にパケットが到達しない。
(「ルート指定すれば…」と思う人は分かっている人なので勝手にやってください)FTP コマンドポート 21 番 FTP の Well known ポートをそのまま使う。
パッシブモードで 20 番ポートは使用しない。基本ソフトウェア Linux / FreeDOS / Windows / 他 PASV (パッシブ) モード(*)で動作する FTP サーバなら何でも良い
FTP クライアント (動作確認用 PC)
項目 内容 備考 ホスト名 ftp-pc 今回は Linux を使用するが、動作確認さえできれば Windows 等でも構わない IP アドレス 172.16.0.100/24 external 側 (インターネット) から fw-svr へ接続する
(*)パッシブモード
FTP のパッシブモードとは、FTP サーバがデータ転送専用の待ち受けポートを適宜に用意 (データ転送の都度、何度も変わる) し、
FTP クライアントがその用意された待ち受けポートに接続するプロトコルのこと。
(正確には、FTP サーバが PASV コマンドを受信したときに変わる)
多くの場合、FTP サーバはパッシブモードで動作する。
その反対を PORT モード (アクティブモードともいう) と言い、このモードは「FTP サーバ → FTP クライアント」の接続が発生するため、クライアント側にファイアウォールがある現代的なネットワークでは使い物にならない。
1-1. カーネルオプション nf_conntrack_helper を有効化する。
$ su1-2. 管理ゾーンとインタフェースを紐付ける。
# cat /proc/sys/net/netfilter/nf_conntrack_helper
# echo net.netfilter.nf_conntrack_helper=1 > /etc/sysctl.d/10-nf_conntrack_helper.conf← 無効になっている
0
# sysctl -p /etc/sysctl.d/10-nf_conntrack_helper.conf
# cat /proc/sys/net/netfilter/nf_conntrack_helper
CentOS7 の時はこっちだった← 有効になった
1
firewalld の FTP サービスに nf_conntrack_ftp があることを確認する。
$ cat /usr/lib/firewalld/services/ftp.xml | grep nf_conntrack_ftp
<module name="nf_conntrack_ftp"/>
# firewall-cmd --zone=external --change-interface=ens10 --permanent1-3. FTP サービスの許可とコマンドポートの転送を指定する。
# firewall-cmd --zone=internal --change-interface=ens11 --permanent
# firewall-cmd --zone=external --add-service=ftp --permanent1-4. ファイアウォール設定を反映させる。
# firewall-cmd --zone=external --add-forward-port=port=21:proto=tcp:toport=21:toaddr=192.168.1.20 --permanent
# firewall-cmd --reload1-5. ファイアウォール設定を確認する。
# firewall-cmd --zone=external --list-all
# firewall-cmd --zone=internal --list-all上記作業によって変更された設定 (太文字部分)。
external (active) target: default icmp-block-inversion: no interfaces: ens10 sources: services: ftp ssh ports: protocols: masquerade: yes forward-ports: port=21:proto=tcp:toport=21:toaddr=192.168.1.20 source-ports: icmp-blocks: rich rules:
masquerade は最初から yes になっている。
# firewall-cmd --list-all-zones # ← 全てのゾーンを表示するならこちら。上記作業によって変更された設定 (太文字部分)。
internal (active) target: default icmp-block-inversion: no interfaces: ens11 sources: services: cockpit dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
internal はインタフェースだけ変更した。
# exit
$
FTP クライアントからテストする。
ftp-pc: 172.16.0.100 → fw-svr: 172.16.0.10
fw-svr が応答しているように見えるが、
$ echo test > test.txt $ lftp -u who,password 172.16.0.10 lftp who@172.16.0.10:~> dir lftp who@172.16.0.10:~> put test.txt 5 bytes transferred lftp who@172.16.0.10:~> dir -rw-r--r-- 1 1001 1001 5 Mar 03 17:30 test.txt lftp who@172.16.0.10:~> !rm test.txt lftp who@172.16.0.10:~> get test.txt 5 bytes transferred lftp who@172.16.0.10:~> rm test.txt rm 成功、`test.txt' を削除しました lftp who@172.16.0.10:~> quit $
実際は ftp-svr が応答している。
詳細にトレースするには、fw-svr で「tcpdump -t -q -i ens10 host 172.16.0.100」を実行する。
(本当はダンプを掲載したかったが、-t -q オプションを使用してもなお冗長なので割愛する)