web-dev-qa-db-ja.com

WireGuard:この自動IP割り当ての何が問題になっていますか

WireGuard は、最新の暗号化に基づく非常にシンプルで高速なカーネルスペースVPNです。本番環境で使用したいのですが、新しいピアに自動IP割り当てが必要です。このプロジェクトは、サーバーとクライアントにこれを行う2つの短いスクリプトを提供します。ただし states

本番環境ではこれらのスクリプトを使用しないでください。これらは単にwg(8)ツールがコマンドラインでいかに簡単かを示すものですが、実際にこれらを使用しようとするべきではありません。それらは恐ろしく安全ではなく、WireGuardの目的を無効にします。離れて!

スクリプトは次のとおりです。
サーバー

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2018 Jason A. Donenfeld <[email protected]>. All Rights Reserved.

if [[ -z $NCAT_REMOTE_ADDR ]]; then
    ip link del dev wg0 2>/dev/null
    set -e
    ip link add dev wg0 type wireguard
    ip address add 192.168.4.1/24 dev wg0
    wg set wg0 private-key <(wg genkey) listen-port 12912
    ip link set up dev wg0
    exec ncat -e "$(readlink -f "$0")" -k -l -p 42912 -v
fi
read -r public_key
[[ $(wg show wg0 peers | wc -l) -ge 253 ]] && wg set wg0 peer $(wg show wg0 latest-handshakes | sort -k 2 -b -n | head -n 1 | cut -f 1) remove
next_ip=$(all="$(wg show wg0 allowed-ips)"; for ((i=2; i<=254; i++)); do ip="192.168.4.$i"; [[ $all != *$ip/32* ]] && echo $ip && break; done)
wg set wg0 peer "$public_key" allowed-ips $next_ip/32 2>/dev/null && echo "OK:$(wg show wg0 private-key | wg pubkey):$(wg show wg0 listen-port):$next_ip" || echo ERROR

クライアント

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2018 Jason A. Donenfeld <[email protected]>. All Rights Reserved.

set -e
[[ $UID == 0 ]] || { echo "You must be root to run this."; exit 1; }
umask 077
trap 'rm -f /tmp/wg_private_key' EXIT INT TERM
exec 3<>/dev/tcp/demo.wireguard.com/42912
wg genkey | tee /tmp/wg_private_key | wg pubkey >&3
IFS=: read -r status server_pubkey server_port internal_ip <&3
[[ $status == OK ]]
ip link del dev wg0 2>/dev/null || true
ip link add dev wg0 type wireguard
wg set wg0 private-key /tmp/wg_private_key peer "$server_pubkey" allowed-ips 0.0.0.0/0 endpoint "demo.wireguard.com:$server_port" persistent-keepalive 25
ip address add "$internal_ip"/24 dev wg0
ip link set up dev wg0
if [ "$1" == "default-route" ]; then
    Host="$(wg show wg0 endpoints | sed -n 's/.*\t\(.*\):.*/\1/p')"
    ip route add $(ip route get $Host | sed '/ via [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/{s/^\(.* via [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/}' | head -n 1) 2>/dev/null || true
    ip route add 0/1 dev wg0
    ip route add 128/1 dev wg0
fi

質問:

  1. これらのスクリプトの何が問題になっていますか?最悪のケースは何ですか?
  2. これらの問題を修正する方法はありますか?
  3. それらのスクリプトの各行が何をするのか、誰かが短いコメントを書くことができますか?

更新:WireGuardの作成者は、「問題は、認証されていないTCPを使用していることです」と述べています。それで、最悪のケースは何ですか、そしてそれはどのように修正できますか? TCP SSHトンネル内のソケットを提供できますか?

5
user1876484

問題は、第3のポイントに要約されます。あなたわからない詳細に読まずに何をするか、そしてそれはかなり多くの不潔なコードを含んでいます。

おそらく「うまくいく」でしょうが、何かが失敗した場合、エラー処理は実装されていません。さらに、それはそれらの出力フォーマットが修正されているかどうかを知らずにいくつかのシェルユーティリティを画面にかき集めます。多分あなたはあなたのディストリビューションをアップグレードして、ツールの1つの新しいバージョンを得て、突然スクリプトは失敗します。

最悪のケースは何ですか

一部の出力解析が失敗し、次のコマンドが文字化けした出力を取得し、/homeを削除します。スクリプトを分析した実際の結果ではなく、適切なエラー処理なしでシェルスクリプトで発生する可能性があり、過去に発生したもの(つまり、rm -r $uninitialized/*)。

発生する可能性が最も高いエラーは、ネットワークが切断されたままであり、スクリプトの説明を求める必要があるためです(問題ありません。そのリスクを完全に理解するには、かなり前に調査する必要があります)。再起動して、システムを再び一貫した状態にします。

これ自体はinsecureではありませんが、-sloppyであり、安全でない可能性があります。ルートとして実行され、重要なものをセットアップするスクリプトの場合、失敗する可能性のあるものごとに慎重なエラー処理を行う必要があります。

一般的な工夫は、安全であることが証明されるまで、すべてが安全でないというリスクがあるということです。安全な場合はスクリプトを検証することもできますが、アンチパターンがいくつかあるため(つまり、(まだ)安定していないことが出力の解析、正規表現でのIPの処理、ラインのクリーンアップがないため)価値はありません。失敗した場合)、より安全な方法で書き換えることをお勧めします。

たとえば、VPNを使用して、暗号化されていない会社の機密データがインターネット経由で送信されるのを防ぐことができます。 VPNスクリプトが(サイレントで)VPNのセットアップに成功しなかった場合、データが安全に送信されない可能性があります。

これらの問題を修正する方法はありますか?

各コマンドの後で、慎重にエラーを処理して書き換えます。おそらく、bashよりも適した言語で、他のプログラムを画面スクレイピングする代わりに、APIを使用してデータを読み取ります。

3
allo

最悪のケースは、攻撃者に直接接続して、攻撃者からの無害化された入力を読み取ることです。

このスクリプトは、DNSからのみ学習した外部ホストにシェルを直接接続します。選択したMITMは非常に適切に機能するため、おそらく世界中の半分は予期したパーティではない可能性があります。

1
Matthias š