web-dev-qa-db-ja.com

Ubuntu Headlessでiptablesを使用してインターフェイスフィルタリングでDNSを許可するにはどうすればよいですか

静的DNS、openVPNサーバープッシュなどに関するいくつかの質問を見てきましたが、それらのいずれも実際には適用されないか、GUIツールが必要であり、SSHに使用するヘッドレスUbuntuコアを使用しています。

root@redacted:~# lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:        14.04
Codename:       trusty

マシンがeth0を介してローカルネットワークにのみ接続されている場合、すべてが正常に機能します。 IPを直接ping(8.8.8.8)して、ドメイン名(google.com)を解決できます。

wget -q -O - ipecho.net/plain #Shows my ISPs provided Public IP

マシンがtun0を介してVPNネットワークを使用して接続されている場合、IP(8.8.8.8)を直接pingし、ドメイン名(google.com)を解決できます。

wget -q -O - ipecho.net/plain #Shows my VPNs provided Public IP

これまでの予想通り...

ここで問題が発生します...特定のユーザーがtun0アダプターのみを使用できるように強制するために、次のiptablesルールを追加します。

Sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o lo -j ACCEPT
Sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o eth0 -p tcp -d 192.168.x.x/24 --sport xxxx -j ACCEPT
Sudo iptables -A OUTPUT -m owner --gid-owner vpnonly \! -o tun0 -j REJECT

好奇心が強い場合、2番目のルールは、ユーザーvpnonlyとして実行されるローカルネットワーク上でWebベースのUIにアクセスできるようにします。

そのため、パブリックIPを介して通信したくないプロセスを実行するときに、VPNがダウン/切断などした場合のリークを防止するために、vpnonlyのみで実行します。vpnonlyは唯一のグループです。 [〜#〜] however [〜#〜] vpnonlyとしてプロセスを実行すると、IPを直接pingできます(8.8.8.8)しかし、できませんドメイン名を解決します( Google COM)。

root@redacted:~# Sudo -u vpnonly ping -c 2 google.com
ping: unknown Host google.com

ドメイン名を再度解決するためにそれを取得できたとしても、それで十分ですが、私が本当にやりたいのは、個別の特定のDNSを使用するようにVPNを設定し、eth0に8.8.8.8、8.8を使用することです。 4.4。

私はこれに関連して考えられるすべてをグーグルで調べましたが、解決することはできません...私は十分な詳細を追加したいと思っていますが、リクエストに応じて喜んで追加します

編集1:完全なiptables

root@redacted:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             owner GID match vpnonly
ACCEPT     tcp  --  anywhere             192.168.x.x/24       owner GID match vpnonly tcp spt:xxxx
REJECT     all  --  anywhere             anywhere             owner GID match vpnonly reject-with icmp-port-unreachable

-

root@redacted:~# iptables -L -v
Chain INPUT (policy ACCEPT 16407 packets, 12M bytes)
 pkts bytes target     prot opt in     out     source               destination   

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   

Chain OUTPUT (policy ACCEPT 6230 packets, 675K bytes)
 pkts bytes target     prot opt in     out     source               destination   
 3751 2800K ACCEPT     all  --  any    lo      anywhere             anywhere             owner GID match vpnonly
 6635 3332K ACCEPT     tcp  --  any    eth0    anywhere             192.168.x.x/24       owner GID match vpnonly tcp spt:xxxx
    4   224 REJECT     all  --  any    !tun0   anywhere             anywhere             owner GID match vpnonly reject-with icmp-port-unreachable

編集2:

Iptablesルールが追加されるまで、すべてが適切に機能しますが、その時点で私が被る唯一の問題はドメイン名の解決です。私のvpnは、非ロギングDNSも提供します。これに対する解決策は、/ etc/network/interfacesネームサーバーエントリを192.168.x.1からVPNが提供するDNS IPアドレスに変更し、拒否する前にそのDNS IPへのすべての接続を許可することですか?私はそれを試す前に質問したかった。1つはそれが論理的に信じられるのと同じくらい安全であることを確かめるためであり、2つはとにかく賞金を提供している。リークがないことを確認し、DNS経由でリークを導入したくない...

インターフェースを変更するのではなく、さらに啓発した後、拒否する前に192.168.x.1とVPN DNS IPを明示的に許可する必要がありますか?

本当にしたいのは、これらのDNSクエリをtun0アダプターに強制し、可能な限りユーザー「vpnonly」からの外部との通信をVPNに送信することです。

1
DeeJayh

簡単な方法は、好きなiptablesルールを保持するサービス.confを作成することです。

これを行うためのパッケージをインストールできますが、手動の方法は次のとおりです。

Sudo vi /etc/init/persist-iptables.conf

好きな名前を付けることができます。/etc/init/にあり、.confで終わることを確認してください

次に、次の行を挿入します。

description "Persist IPTables on Boot"

start on runlevel [2345]

script
        # Accept all loopback traffic localhost or 127.0.0.1
        iptables -A INPUT -i lo -j ACCEPT
        iptables -A OUTPUT -o lo -j ACCEPT

        # Accept any DNS traffic, I use a DD-WRT router with
        # Force DNS Redirection to a non-logging DNS
        iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT
        iptables -A INPUT -s 255.255.255.255 -j ACCEPT

        # Accept all local traffic from 192.168.1.1-192.168.1.255
        iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
        iptables -A OUTPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT

        # Forward all eth0, eth1, etc through tun interfaces
        iptables -A FORWARD -i eth+ -o tun+ -j ACCEPT
        iptables -A FORWARD -i tun+ -o eth+ -j ACCEPT

        # Postroute masquerade through tun interfaces
        iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE

        # Drop any other traffic through eth adapters
        iptables -A OUTPUT -o eth+ ! -d a.b.c.d -j DROP
end script

これで、システムが再起動すると(IPテーブルがクリアされます)、これが自動的に実行され、iptablesが再度更新されます。 Sudo service persist-iptables startを使用して自分で呼び出すこともできます

このファイルは、すべてのlocalhostトラフィックを許可し、すべてのDNSトラフィックを許可し(ルーターからの正しいDNSであることを確認するのはあなた次第です)、すべてのローカルトラフィックを許可し、ethアダプターからtunアダプターにトラフィックを転送し、最終的にmasq他のトラフィックをドロップします。

0
DeeJayh

最初の質問は、DNSサーバーにアクセスできますか? tun0以外のすべてへのアクセスをブロックしている場合、DNSアクセスをブロックしている可能性があります。

何らかの種類のDNSサーバーをローカルで実行している場合、Bindでいっぱいになるか、dnsmasqのようなサービスもインターネットにアクセスできる必要があります。

拒否する前にiptablesにログエントリを追加して、拒否されているトラフィックを確認することをお勧めします。

ポート53の使用はセキュリティを無効にする標準的な方法であるため、*:53を開くことはおそらく賢明ではないため、トラフィックの受け入れ可能なターゲットとしてDNSサーバー(ローカルおよびアップストリーム)を具体的に指定するのが最善です。 --sport xxxxは、Webサービスに:80ではなく非標準ポートを使用していることを意味すると思います。そうでない場合は、192.168ルールでそれを指定する必要があります(IPについても同様に、/ 32アドレスで完全になります)。

また、pingを使用してテストする場合は、ICMPのiptableエントリをセットアップする必要があることを忘れないでください。 ICMP 8(エコー)はping、ICMP 0はping応答です。

また、トラフィックのデフォルトルートがtun0であることを確認する必要があるため、使用しているルートを検討する価値があります。 tun0のみが許可されるインターフェイスである場合、必要なすべてのルートがトラフィックをそのように送信するようにする必要があります。

それでも問題が診断されない場合は、ethtoolを使用してネットワークスニッフィングを行い、どの会話がそれを作っているのか、何が会話をしていないのかを確認します。 REQは許可されているが、ACKが返ってこないなど、奇妙なものになる可能性があります。

0
sibaz