はじめに
Ubuntuのファイアウォールの設定をしたことがなかったので、想定通りの挙動になるのかコマンドの確認を行った。
環境
【ホストOS】
・Ubuntu 18.04 LTS(GCP上)
IPアドレス・ポート制限の設定方法
1.ローカルPCから各ポートへの接続確認
2.ufw
コマンドを使ったファイアウォール設定
3./etc/hosts.allow
と/etc/hosts.deny
を使った接続制限
1.ローカルPCから各ポートへの接続確認
まずはローカルPCから各サービスにアクセスできる様にしておく。
・SSH接続(デフォルトport:22)
※GCPのVMインスタンスへのSSH接続はこちらを参考に
・httpアクセス(port:80)
※事前準備
・GCP上のファイアウォール設定からローカルPCのグローバルIPに対する上記ポート接続を許可する。
・httpアクセス確認のために、以下を実行。
# パッケージ管理ツールを最新にアップデート
$ sudo apt update
$ sudo apt -y upgrade
# Apacheのインストール
$ sudo apt install -y apache2
2.ufw
コマンドを使ったファイアウォール設定
デフォルトのファイアウォールの状態を確認
$ sudo ufw status
Status: inactiveufw status
⇒デフォルトでは非アクティブとなっている。
まず、SSHの接続は許可して、ファイアウォールを有効化してみる。
$ sudo ufw allow ssh
Rule added
Rule added (v6)
# sudo ufw allow 22 ← こちらのコマンドでも同じ
$ sudo ufw enable
Rule added
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
※デフォルトはall deny
になっているため、何もIPやポートの設定をしないで有効化してしまうと入れなくなる可能性があるので注意。
この状態でhttpにアクセスしようとすると、もちろんできなくなっている。
再起動を行うと、この設定は効いたままになるのか?
# 再起動後にステータス確認
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
再起動してもルールがなくなってしまうという事はなさそう。
特定のIPアドレスのみ通信を許可する書き方。
$ sudo ufw allow from xxx.xxx.xxx.xxx to any port 22
Rule added
$ sudo ufw reload
Firewall reloaded
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
22/tcp ALLOW xxx.xxx.xxx.xxx
22/tcp (v6) ALLOW Anywhere (v6)
ルール削除の書き方。
$ sudo ufw delete allow from xxx.xxx.xxx.xxx to any port ssh
# ネットワークレベルで許可したい場合は、[from xxx.xxx.xxx.0/24 to] の様な書き方でOK。
Rule deleted
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
3./etc/hosts.allow
と/etc/hosts.deny
を使った接続制限
基本的にはスーパーデーモン(xinetd)経由で起動されるデーモンへのアクセス制御をするため、TCP Wrapper(tcpdデーモン)がクライアントのサービス接続許可情報を確認するのに/etc/hosts.allow
と/etc/hosts.deny
のホストアクセスファイルを参照している。
しかし、「sshd」などスーパーデーモンを経由しないものでもアクセス制御を行えるものがある。
※inetd(xinetd)が各デーモンを呼び出す前にアクセス許可と不許可とのリスト(/etc/hosts.allow、/etc/hosts.denyファイル)を参照し、許可されていれば該当デーモンを起動させている。
inted自体はアクセス制御の機能を持っていないので、このtcpdと組み合わせてアクセス制御を行っていた。ただし、tcpdのアクセス制御は、接続先のIPアドレスのみによるものであり、さらに、inetd経由で使用されるTCPポートしか監視することはできなかった。
そのため、tcpdのアクセス制御はかなり限定されており、よりきめ細かな設定を行うことができるスーパーサーバとして、xinetdが利用されるようになってきた。
ルールは以下の感じらしい。
(1) /etc/hosts.allow
に記述されたホストからのアクセスを許可
(2)1に該当しなかった場合、/etc/hosts.deny
に記述されたホストからのアクセスを拒否
(3)1にも2にも該当しなかった場合、アクセスはすべて許可
SSH接続
試しにSSHの接続設定を以下の様にしたら、ローカルPCから接続できなくなるのか確認。
ALL 127.0.0.1
sshd : 【ローカルPCのグローバルIP】
# Webサービスは接続できない状態の記述イメージ
httpd : ALL
apache2 : ALL
特にサービスやシステムの再起動なく、ローカルPCからの接続ができなくなった。
※ファイアウォールで切られているわけではないので、ユーザ入力やパスフレーズ入力まではいくが、その後接続の確立が上手くいかない。
以下の様に/etc/hosts.allow
を編集したら、ローカルPCから接続できる様になるのか確認。
ALL 127.0.0.1
sshd :【ローカルPCのグローバルIP】
想定通り、SSH接続はできる様になった。
http接続
上記設定の状態でhttp接続も同じように確認してみると、こちらは見れる状態となっている。
理由は、TCP Wrapper が制御対象とするサービスは「TCP でラップしたサービス」であり、httpサービスはそこに含まれていないため。
(参考2)https://nwengblog.com/rhel-tcpwrapper/
補足
TCPでラップされているサービスは以下の様に調べる事が可能。
# sshd サービスについて確認する場合
$ ldd /usr/sbin/sshd | grep libwrap
libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007f0cb589d000)
# apache2 サービス(http)について確認する場合
$ ldd /usr/sbin/apache2 | grep libwrap
# 出力なし。
※ライブラリ毎に設定しているため、一覧として確認することは難しそう。