実は守れていないローカルネットワーク

(Last Updated On: 2018年8月30日)

ファイアーウォールで守っている、プロキシも使っている、だからインターネットからローカルネットワークは守られている!

半分あたりですが、半分はずれです。よくあるネットワークシステムではローカルネットワークはインターネットから半分くらいしか守っていません。

まだ対策をしていない場合は実施することを強くお勧めします。

クロスサイト攻撃からローカルネットワークを守ることは簡単です。簡単なので会社、特にシステム開発/運用部門は必ずローカルネットワークへのクロスサイトアクセスを禁止&検出すべきです。クロスサイト攻撃とはクロスサイトスクリプティング(XSS)やクロスサイトリクエストフォージェリ(CSRF)の事です。基本的な対策ですが、意外に実施されていることが少ないようです。

クロスサイト攻撃はWebシステムに対するよくある攻撃手法です。少しの手間でインターネットからローカルネットワークに対するクロスサイト攻撃を完全に防止することが可能です。

知らない間に危険に晒されている内部ネットワーク

Webブラウザを利用して、プライベートアドレスのネットワークを外部(インターネット)からスキャンできます。ツールも公開されているので簡単です。

スキャンした後は攻撃です。ルーターなどには脆弱性があることが多いです。酷い場合はルーターを丸ごと乗っ取られます。こういった問題はWiFiルーターに限らず、プリンタやIoTデバイスに多数見つかっています。

ブラウザを利用したこれらの攻撃には罠サイトとクロスサイト攻撃が利用されます。ローカルネットワークへのWebアクセスを禁止すると、原理的にクロスサイト攻撃ができなくなり安全性が向上します。

罠サイトとクロスサイト攻撃

インターネットのWebサイトにアクセスした場合でも、ネットワークファイアーウォール(NATなど)で守られていれば内部ネットワークは大丈夫!ではありません。JavaScriptのAJAXリクエストが同一生成元ポリシーで守られているから大丈夫!でもありません。

インターネットからでも内部ネットワークスキャンを可能です。例えば、

https://defuse.ca/in-browser-port-scanning.htm

は内部ネットワークスキャンが可能であることをデモしています。罠サイトにアクセスしてしまうと、色々と出来てしまいます。サイト自体は問題なかったとしても、広告に問題がある場合もあります。

インターネット上のWebサイトからでも

<a href="//192.168.1.1/path/to/file?evil=param">Click Here</a>

といった感じで内部のネットワークへ攻撃を行えます。こういった攻撃がクロスサイト攻撃です。

実際の攻撃はもっと高度でページを見ただけで攻撃可能です。インターネット上の罠サイトから脆弱な内部ルーターを攻撃する方法も考案されています。罠サイトにアクセスするだけで、ルーターのファームウェア(基本ソフト)さえ書き換え可能です。

DNS Rebinding

現在のブラウザはDNSレコードの変更(IPアドレスの変更)をキャッシュし、直ぐに変更しないことにより罠ページのリンクが攻撃に利用できにくいようにしてい緩和しています。とは言ってもDNS Rebinding攻撃は可能です。

試してみないと判りませんが、DNS Rebinding攻撃はFirefoxのABE拡張でもうまく守れないのではないか?と思います。ABEはアプリケーション境界(内部サイトと外部サイト)をサイトのIPアドレスで判断しています。Rebindingで罠サイトのIPが内部IPになると、内部IP → 内部IPになりアクセスを遮断できない可能性があります。

防御方法 – プロキシによる分離が有効

ルーター/ファイアーウォールによるフィルタリングだけでは防御できません。内部ネットワークは分離されているようで、完全には分離されていません

インターネットを参照する場合、インターネットしか参照できない仕組みにするとクロスサイト攻撃を防止できます。先に紹介したデモサイトでは”FirefoxのNoScript拡張のABE(後述)を有効にしている場合動作ない”としています。ABEはプライベートネットワークへのアクセスを禁止しているからです。

プロキシを使えば、ネットワークレベルでABEと同じくプライベートアドレスへのアクセスを禁止できます。

この場合、内部ネットワークのWebサイトにアクセスできなくなるので

  • プロキシを切り換える(Chrome, Edge)
  • 異なるプロキシのプロファイルのブラウザを使う(Firefox)

といった使い方になります。

localhostを指定した場合は有無を言わさずブラウザがlocalhostへアクセスできるようにするRFCドラフトが議論されています。セキュリティ的にはとんでもない改悪ですが、もしかすると標準化されるかも知れません。標準策定の動向には注意が必要です。

Dockerの場合

Dockerがインストール済みなら直ぐに使ええます。dockerイメージはこちらです。

https://hub.docker.com/r/yohgaki/squid-no-local/

コマンドラインから

docker pull yohgaki/squid-no-local
docker run -d --rm --name squid-no-local yohgaki/squid-no-local

を実行し、プロキシのIPを127.0.0.1、ポートを3128にするだけです。

グローバルIPでも3218ポートで待機します。ファイアーウォール設定を変更すれば、他のPCからも利用できます。

Fedoraの場合

DockerでなくてもSquidを導入し、設定変更するだけです。以下はFedoraでの例です。

# dnf install squid

以下のパッチを/etc/squid/squid.confに当てる

diff --git a/squid/squid.conf b/squid/squid.conf
index 1e1694e..2b0570a 100644
--- a/squid/squid.conf
+++ b/squid/squid.conf
@@ -8,12 +8,24 @@
 acl localnet src 172.16.0.0/12         # RFC 1918 local private network (LAN)
 acl localnet src 192.168.0.0/16                # RFC 1918 local private network (LAN)
 acl localnet src fc00::/7              # RFC 4193 local private network range
 acl localnet src fe80::/10             # RFC 4291 link-local (directly plugged) machines
 
+acl localdst dst 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
+acl localdst dst 10.0.0.0/8            # RFC 1918 local private network (LAN)
+acl localdst dst 100.64.0.0/10         # RFC 6598 shared address space (CGN)
+acl localdst dst 169.254.0.0/16        # RFC 3927 link-local (directly plugged) machines
+acl localdst dst 172.16.0.0/12         # RFC 1918 local private network (LAN)
+acl localdst dst 192.168.0.0/16                # RFC 1918 local private network (LAN)
+acl localdst dst fc00::/7              # RFC 4193 local private network range
+acl localdst dst fe80::/10             # RFC 4291 link-local (directly plugged) machines
+acl localdst dst 127.0.0.0/8
+acl localdst dst ::1
+
 acl SSL_ports port 443
 acl Safe_ports port 80         # http
 acl Safe_ports port 21         # ftp
@@ -52,6 +64,7 @@ http_access deny manager
 # Example rule allowing access from your local networks.
 # Adapt localnet in the ACL section to list your (internal) IP networks
 # from where browsing should be allowed
+http_access deny localdst
 http_access allow localnet
 http_access allow localhost

インストールしたsquidを有効化&起動する

# systemctl enable squid
Created symlink /etc/systemd/system/multi-user.target.wants/squid.service → /usr/lib/systemd/system/squid.service.
# systemctl start squid

プロキシの設定(Gnomeの場合)

ローカルホストのsquidをプロキシにする

たったコレだけで自分のPCを経由したクロスサイト攻撃からローカルシステムを守れるます。

例えば、localhostにアクセスする以下のようにアクセスできません。

クラウドなどに非公開の自社システムがある場合は、そのIPアドレスをsquid.confに追加すればそれらのリモートシステムに対するクロスサイト攻撃を根こそぎ防げます。

追加ですべきは、ローカルネットワークへのアクセスがあった場合にシステム管理者にアラートを送るようにすることをです。これはログ管理システムなどに設定すると良いでしょう。

ここでは説明を簡略化するためローカルホスト用に設定しました。基本を知っていれば、会社全体や部門用のプロキシサーバーを設定することは難しくないと思います。

個人で対策するならFirefox + NoScript

プロキシを作ったり手間をかけれない!といった場合、FirefoxのNoScript拡張を使うとABEで同様の防御を実現できます。(ABEはインターネットサイトからローカルネットワークへのクロスサイト攻撃を防止できる)

簡単にインターネットから内部ネットワークを守る方法

まとめ

セキュリティ対策の基本が出来ている会社であれば、会社や開発/運用環境のネットワークをこのブログに書いたようにプロキシで守っていると思います。

多くの場合、VLANで会社業務やシステムの実験/開発/運用を区別しインターネットへのアクセスを制限していると思います。このように区別した環境を用意しているのに、クロスサイト攻撃を根こそぎ防止していないのは勿体ないです。

自分の環境はそうなっていない!という開発者の方は自分のLinuxだけなら簡単にクロスサイト攻撃を防止できます。入れてみるのも良いと思います。

ここで紹介した設定はlocalhost(127.0.0.1、::1)に対するアクセスも防止しています。特に開発環境ではlocalhostへのアクセスを許すのはリスクが高いです。インターネットRFCではlocalhostにアクセスした場合、常にlocalhostにアクセスできるような仕様が検討されています。セキュリティ問題の原因になるのでこういう余計や仕様を作るのではなく、localhostへのアクセスが必要である、という旨をアプリが表示するようにすれば良いだけではないでしょうか?

投稿者: yohgaki