RedHat系LinuxのFirewallというと、Firewalldでの設定がデフォルトになっています。今でもiptablesで直接設定する機会も多いですが、特別な理由が無い限りFirewalldでの設定にも慣れておいた方が良いと思います。

今回は、Firewallを設定する上で設定する機会が多いが、ちょっと複雑な設定がいるようなパターンを解説します。そのパターンは「SSH接続ポートを22番以外にし、特定の接続元(IPアドレス)からのみ接続を許可する」というものです。

現状の設定の確認

設定を追加する前に、現状の設定の確認を実施しておきます。

ゾーンの割当の確認

以下のコマンド、どのインターフェイスにどのゾーンが割り当てられているか確認することができます。
以下の例だと、eth0にはpublicゾーンが割り当てられているのが分かります。

# firewall-cmd --get-active-zones
public
  interfaces: eth0

ゾーンの内容を確認

先ほど確認したゾーンの中身を確認してみます。あるゾーンのFW設定を確認するには、firewall-cmd --list-all --zone=[ゾーン名]で確認できます。
以下の例だと、http・https・sshの3種類のServiceが許可されていることが分かります。

# firewall-cmd --list-all --zone=public
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: http https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:

サービス「SSH」の設定内容を確認

先ほど、Zone「Public」にはHTTP・HTTPS・SSHの3つのServiceが許可されていることが分かりました。
それぞれのServiceがどう定義されているのか確認しましょう。

各サービスは、/usr/lib/firewalld/services/ 配下にXML形式で格納されています。今回、ssh.xmlを確認します。

# cd /usr/lib/firewalld/services/
# cat ssh.xml

XMLを開くと、プロトコルがTCPでポート番号が22と言うことが分かります。

<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>

つまり、サービスSSHがpublicゾーンに追加されているということは、eth0経由のTCP22番ポート宛ての通信のIN通信を許可するという意味になります。

馴染みのあるiptablesの記述だと以下の様な記述に近くなると思います。

-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT

RichRuleの追加

現状の確認ができましたので、「SSHの接続(22番ポート以外)を特定のIPアドレスからのみ許可」という設定を行っていきたいと思います。

PublicゾーンからSSHサービスを削除

既存の設定では、publicゾーンにSSHサービスが追加されています。デフォルトのSSHサービスは、TCP22番ポート宛ての通信を全許可する内容でした。今回の設定したい内容には適さないのでpublicゾーンから削除します。

削除するには、firewall-cmd --remove-service=[サービス名] --zone=[ゾーン名] で行います。

今回の場合は、publicゾーンからsshサービスを削除するので、以下の様になります。

# firewall-cmd --remove-service=ssh --zone=public

削除できたか、firewall-cmd --list-all で確認してみましょう。SSHサービスがなくなっていることが確認できます。

# firewall-cmd --list-all --zone=public
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: http https
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:

このままでは、22番ポート宛てのTCP通信の許可を削除=拒否しただけです。新たに変更後のポートからのSSH通信を特定のIPからのみ許可する設定を追加する必要があります。

今回は、以下のポート・IPを例とします。

  • ポート:2222
  • IP:x.x.x.x

「特定のIPから特定のプロトコルで特定ポートへの通信を許可する」といった少し複雑なルールをFirewalldで実現するにはRichRulesを使用することができます。

RichRuleを追加するには、firewall-cmd --zone=public --add-rich-rule='ルール' で追加できます。

今回の例は以下の様になります。

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="x.x.x.x" port port="2222" protocol="tcp" accept'

設定内容を確認してみましょう。rich rulesが追加されていると思います。

# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: http https
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="x.x.x.x" port port="2222" protocol="tcp" accept

この状態で、現在接続しているSSHセッションなどは残したまま、新たにSSH接続が可能か確認して、うまくいけば成功です。

以下のコマンドで設定を保存してください。以下のコマンドを実行しないと再起動などでfirewalldの設定内容が元に戻ってしまいます。設定を投入するコマンドへのpermanentオプションの付与でその場で保存も可能ですがオススメしません。設定内容の正常性を確認後、保存(永続化)することで、うまくいかなかった場合に切り戻しが容易になります。

# firewall-cmd --runtime-to-permanent

万が一、設定内容が間違っていた場合は、以下のコマンドで切り戻しが可能です。

# firewall-cmd --reload

PVアクセスランキング にほんブログ村

Twitterでフォローしよう

おすすめの記事