CentOS7では、ポートのアクセス制御をfirewalld で行います。この記事ではfirewalldの設定方法を紹介します。
CentOS6で使われていたiptablesから変更になっているので、戸惑うかもしれませんが、慣れると便利ですよ。
ポート制限でセキュリティを高めましょう
記事「windowsにvagrantとvirtualboxでWeb開発環境をつくろう。(その4)手作業でLAMP環境構築」では、仮想マシン上にCentOS7を使ってLAMP環境を構築していますが、firewalldは起動されていないままになってます。
仮想環境ではfirewalldまで使用する必要はないと思うからですが、外部のサーバーを使う場合には、セキュリティを高めるために必要です。
不要なポートを閉じたり、SSHのポートは、特定のIPアドレスからだけアクセスできるようにしたりと、なるべく、外部に公開する部分を必要最小限にすることが、セキュリティを高めるコツです。
では、説明しますね。
firewalldによるポートアクセス制御
firewalld が起動されているか確認
systemctrl status で確認できます。
「disabled」は、OS起動時の自動起動がOFFということ、「Active: inactive」は起動していないという意味です。
1 2 3 4 5 |
[taka@manu ~]$ systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1) |
firewall-cmd というfirewalldを操作するコマンドを実行してみても、firewalldが起動しているかを確認できます。
1 2 3 |
[taka@manu ~]$ sudo firewall-cmd --list-all [sudo] taka のパスワード: FirewallD is not running |
firewalld をスタートするには
他のサービスと同じで systemctl start を使います。
1 |
[taka@manu ~]$ sudo systemctl start firewalld |
実行後のステータスを見ると、「Active: active(running)」になってます。
1 2 3 4 5 6 7 8 9 10 11 |
[taka@manu ~]$ systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: active (running) since 金 2019-03-29 13:21:01 JST; 4s ago Docs: man:firewalld(1) Main PID: 3707 (firewalld) CGroup: /system.slice/firewalld.service └─3707 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid 3月 29 13:21:00 manu systemd[1]: Starting firewalld - dynamic firewall daemon... 3月 29 13:21:01 manu systemd[1]: Started firewalld - dynamic firewall daemon. |
自動起動もONにしましょう。
systemctl enable を使います。
1 2 3 |
[taka@manu ~]$ sudo systemctl enable firewalld Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service. Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service. |
statusを見ると、「Loaded: loaded ・・・; enabled;」と、自動起動ONになりましたね。
1 2 3 4 5 6 7 8 9 10 11 12 |
[taka@manu ~]$ systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since 金 2019-03-29 13:21:01 JST; 47s ago Docs: man:firewalld(1) Main PID: 3707 (firewalld) CGroup: /system.slice/firewalld.service └─3707 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid 3月 29 13:21:00 manu systemd[1]: Starting firewalld - dynamic firewall daemon... 3月 29 13:21:01 manu systemd[1]: Started firewalld - dynamic firewall daemon. [taka@manu ~]$ |
firewalldの状態を確認
起動状態は確認できました。
では、現在のポートの状況を確認してみましょう。
firewalldの操作には、 firewall-cmd コマンドを使います。
firewall-cmd list-all で現在の状況が表示されます。
例として、下リストに、vagrant でbento/centos-7.5 のboxをインストールした後の仮想マシンで実行したリストを載せます。
この環境では、デフォルト(素の状態)では、public ゾーンがアクティブになってます。
で、NICはeth0、eth1あって、ポートがオープンになっているのは、sshとdhcpv6-client だけになってます。
ここに、httpのポートをオープンしたりしていきましょう。
仮想マシンなので、このままで全然よいのですが、固定IPアドレスを使っているか、IPv4を使っている場合は、dhcpv6-client を開けておく必要はありませんね。また、SSHは、指定したIPアドレスからだけアクセスできるように変更するなどした方がよいですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[taka@manu ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: |
ゾーンとは
firewalldにはゾーンという概念があります。
ゾーンごとに別々のポートやIPアドレスのアクセス制御を設定することができて、使っているゾーンを変更すれば、アクセス制御を一気に切り替えることができるんです。
また、NICごとにゾーンを指定できるので、内部用とか外部用でNICを分けて管理するのに便利です。
最初はデフォルトゾーンとして public というゾーンが選択されているので、それをベースに変更させていけば良いと思います。
※firewalldに最初からあるゾーンは、publicを合わせて9種類あります。
firewall-cmd --list-all-zones オプションでそれぞれの設定を表示できます。確認してみましょう。dropとかblock はポートを遮断してますね。
blockの場合は、内部からアクセスしたときの返答の通信は許可されます。dropはそれすらできないため、クライアントとしても外部にアクセスして結果を得ることができなくなります。
また、trustedゾーンでは、target: ACCEPTになってますが、ルールがなくてもすべてのポートが許可になってます。サーバーとしては要注意ですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
[taka@manu ~]$ firewall-cmd --list-all-zones Authorization failed. Make sure polkit agent is running or run the application as superuser. [taka@manu ~]$ sudo firewall-cmd --list-all-zones [sudo] taka のパスワード: block target: %%REJECT%% icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: dmz target: default icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: drop target: DROP icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: external target: default icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: masquerade: yes forward-ports: source-ports: icmp-blocks: rich rules: home target: default icmp-block-inversion: no interfaces: sources: services: ssh mdns samba-client dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: internal target: default icmp-block-inversion: no interfaces: sources: services: ssh mdns samba-client dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: trusted target: ACCEPT icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: work target: default icmp-block-inversion: no interfaces: sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: |
設定変更手順
サービス追加
サービス追加すると、そのサービスの規定ポート(これをWell Known Portと言います)のアクセスを許可することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[taka@manu ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: |
上リストのようにデフォルトではserviceとして、ssh と dhcp しか開いてないです。
ウェブサーバーとするために、httpとhttpsをオープンしておきましょう。
サービス追加するには、
firewall-cmd で
--add-service オプションを指定して実行します。
しくじったとき、先起動できるように、一時的な変更がデフォルトになるため、再起動しても変更したままにするために
--permanent オプションも指定しておきます。
1 2 3 4 |
[taka@localhost ~]$ sudo firewall-cmd --permanent --add-service=http success [taka@localhost ~]$ sudo firewall-cmd --permanent --add-service=https success |
追加したら、有効にするために、 --reload オプションを指定して firewall-cmd を実行します。
1 2 |
[taka@localhost ~]$ sudo firewall-cmd --reload success |
実行後は以下のように http、https がサービスに追加されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[taka@localhost ~]$ sudo firewall-cmd --list-all [sudo] taka のパスワード: public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: ssh dhcpv6-client http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: |
この状態で、外部からブラウザでウェブページにアクセスできます。
サービス削除
サービスの削除するには、 --remove-service オプションを指定します。
※注意:ssh を削除すると、当然ですが ssh でログインできなくなります。(ただし、その時点でログインしているものはログインしたままになります)。
※この例では、sshを削除した後、指定したIPアドレスからだけsshアクセス(ポート番号22)からアクセスできるように設定しています。sshサービスを削除するときには、直接端末へアクセスできるのでなければ、同時にIPアドレス限定でのsshポートの開放をしましょう。
では、まず、サービスの削除です。
下では、 --permanent でさっきと同様に恒久指定してるほかに、 --zone でpublic を指定しています。が、現在 public ゾーンが有効なので、この指定はなくてもOKです。
1 2 |
[taka@localhost ~]$ sudo firewall-cmd --permanent --zone=public --remove-service=ssh success |
設定を有効にするには、 --reload オプションの実行が必要ですが、その前に、IPアドレス指定でsshのポート開放をしておきます。(仮想マシンだとssh以外でアクセスできないためリスク回避のため)。
アクセス元を指定してポートの開放(rich-rule使用)
指定したIPアドレスからだけポートを開放したい場合は、 --add-rich-rule オプションを指定します。長いですが、間違えないように指定しましょう。
下の例では、仮想マシンに対して、ホストマシンが192.168.33.1 となってるので、このアドレスからのアクセスのみSSHのポート22を開放してます。
1 2 3 |
[taka@localhost ~]$ sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.33.1" port port="22" protocol="tcp" accept' [sudo] taka のパスワード: success |
有効にするために、 --reloadオプションを実行します。
1 2 |
[taka@localhost ~]$ sudo firewall-cmd --reload success |
--list-all で確認してみましょう。services からはsshがなくなり、その代わり、rich rulesに、ポート22へのアクセスがaccept(許可)されていることが分かります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[taka@localhost ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: dhcpv6-client http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.33.1" port port="22" protocol="tcp" accept |
※ssh の設定を変更している場合、現在SSHログインしている端末はそのままにして、別に端末ウィンドウを起動して、SSHログインできるか確認してください。
最悪、設定を間違えていると、サーバーへアクセスできなくなります。
アクセステスト
では、別の端末ウィンドウからアクセスしてみます。
許可されたIPアドレスからのアクセス
まず、ipアドレス192.168.33.1のホストOSからのアクセスです。sshで192.168.33.10にログインできました!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
user@cf-nx2 MINGW64 /c/data/tk/vagrant $ wincmd ipconfig|grep 192 IPv4 アドレス . . . . . . . . . . . .: 192.168.0.10 デフォルト ゲートウェイ . . . . . . .: 192.168.0.1 IPv4 アドレス . . . . . . . . . . . .: 192.168.56.1 IPv4 アドレス . . . . . . . . . . . .: 192.168.33.1 user@cf-nx2 MINGW64 /c/data/tk/vagrant $ ssh taka@192.168.33.10 taka@192.168.33.10's password: Last login: Fri Apr 5 17:21:41 2019 from 192.168.33.11 [taka@localhost ~]$ ログアウト Connection to 192.168.33.10 closed. user@cf-nx2 MINGW64 /c/data/tk/vagrant $ |
禁止されたIPアドレスからのアクセス
禁止する前は、下リストのようにIPアドレス192.168.33.11の仮想マシンからもログインできました。
1 2 3 4 5 6 7 |
[taka@manu ~]$ ifconfig|grep 192 inet 192.168.33.11 netmask 255.255.255.0 broadcast 192.168.33.255 [taka@manu ~]$ ssh taka@192.168.33.10 taka@192.168.33.10's password: Last login: Fri Apr 5 17:03:29 2019 from 192.168.33.1 [taka@localhost ~]$ ログアウト Connection to 192.168.33.10 closed. |
禁止後は、下リストのようにちゃんと拒否されてます。
1 2 3 |
[taka@manu ~]$ ssh taka@192.168.33.10 ssh: connect to host 192.168.33.10 port 22: No route to host [taka@manu ~]$ |
※アクセスできることが確認出来たら、SSHのポート設定を変更をした端末からログアウトしても大丈夫です。
rich-listの削除手順
rich-listを削除する方法です。
例えば、先ほど追加したのは、192.168.33.1 からのアクセス許可でしたが、IPアドレスを192.168.33.0/30 と範囲指定すると、最後の2ビット(32-30=2)は気にしないという意味になり、192.168.33.0~192.168.33.3 までの4つのIPアドレスからのアクセスが許可されます。実際には 末尾 0 はホスト割当としては使えないので、末尾1~3の3台ですね。
ということで、rich-listの削除方法ですが、 --remove-rich-rule オプションを指定します。内容には、 --add-rich-rule で設定した部分すべての指定が必要になるため、いったん --list-all でルールを表示させて、ルール部分をすべて コピーペーストするようにしましょう。
ということで、下リストが list-all の結果です。下の例ではすでに、プリフィックス表示(/30でネットワーク部を指定している表示方式)のrich rule を追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[taka@localhost ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: dhcpv6-client http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.33.1" port port="22" protocol="tcp" accept rule family="ipv4" source address="192.168.33.0/30" port port="22" protocol="tcp" accept |
では、「rule family=”ipv4″ source address=”192.168.33.1″ port port=”22″ protocol=”tcp” accept」の部分を丸々コピーして、 --remove-rich-rule を実行しましょう。
コピーしたルールには、「”」(ダブルクォーテーション)が使われているので「’」(シングルクォーテーション)でくくります。
1 2 |
[taka@localhost ~]$ sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.33.1" port port="22" protocol="tcp" accept' success |
--reload で設定を有効にして、 --list-all で設定を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[taka@localhost ~]$ sudo firewall-cmd --reload success [taka@localhost ~]$ sudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: dhcpv6-client http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.33.0/30" port port="22" protocol="tcp" accept [taka@localhost ~]$ |
これで、削除できました。
※繰り返しになりますが、SSHのポート変更したときは、ログアウトする前に、別端末でログインできるかのチェックをしておきましょう。
※vagrant使ってる場合について注意 vagrant up で接続できなくなります
vagrant の仮想マシンの場合、IPアドレスで制限するなら、10.0.2.2からのアクセスも許可しておきましょう。
192.168.33.1 など、Vagrantfileで設定したIPアドレス空間のホストOS側IPアドレスでだけポート22の許可をすると、 vagrant up の起動時にsshすることができず、初期化ができません。その結果、/vagrant のマウントができません。
vagrant up の時、または、 vagrant ssh でのログインは、10.0.2.2 からのアクセスになるようです。
これは、Vagrantファイルで、
1 |
config.vm.network "private_network", ip: "192.168.33.10" |
のネットワーク設定をしなくても、 vagrant up 時に接続して設定できることや、 vagrant ssh できることからも別系統でひそかにつながっているということが分かりますよね。
vagrantの仮想マシン(ゲストOS)側からは、常にホストOSに 10.0.2.2 でアクセスできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
user@cf-nx2 MINGW64 /c/data/tk/vagrant/centos7 (master) $ ssh taka@test.lhost taka@test.lhost's password: Last login: Thu Apr 11 03:24:35 2019 from 192.168.33.1 [taka@localhost ~]$ ping 10.0.2.2 PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data. 64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.245 ms 64 bytes from 10.0.2.2: icmp_seq=2 ttl=64 time=0.300 ms 64 bytes from 10.0.2.2: icmp_seq=3 ttl=64 time=0.495 ms 64 bytes from 10.0.2.2: icmp_seq=4 ttl=64 time=0.181 ms 64 bytes from 10.0.2.2: icmp_seq=5 ttl=64 time=0.465 ms ^C --- 10.0.2.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4008ms rtt min/avg/max/mdev = 0.181/0.337/0.495/0.123 ms [taka@localhost ~]$ |
まとめ
CentOS7 にデフォルトで入っているfirewalld というファイアーウォールアプリを使った、ポート制御の方法を説明しました。
この記事の内容を理解しておけば、とりあえずは、困ることはないと思います。ぜひ、トライしてみて下さい。
SSHは、安全性を高めるため、特定IPアドレスからだけアクセスを許可することが望ましいです。SSHに関しては、ほかにも、公開鍵を使ってパスワードをネットワーク上で転送しないような方法も使った方がより安全なため、また、別途、やり方を記事にしたいと思います。
ちなみにホストOSからしかアクセスしない仮想マシンでは、firewalld を起動する必要はないですが、本番サーバーの設定前に試すという意味では、有効ですね。
コメント