単一プロセスの(発信)ネットワークアクセスをブロックすることは可能ですか?
localhost
、(同じマシンへの)ネットワークアクセスを使用してジョブを実行します。
単一プロセスの(発信)ネットワークアクセスをブロックすることは可能ですか?
localhost
、(同じマシンへの)ネットワークアクセスを使用してジョブを実行します。
回答:
Linux 2.6.24+では(2.6.29までは実験的と見なされていました)、そのためにネットワーク名前空間を使用できます。ツールを使用して、カーネル(CONFIG_NET_NS=y
)およびutil-linuxで「ネットワーク名前空間」を有効にする必要がありunshare
ます。
次に、ネットワークアクセスなしでプロセスを開始するのは簡単です。
unshare -n program ...
これにより、プロセスの空のネットワーク名前空間が作成されます。つまり、ループバックを含め、ネットワークインターフェイスなしで実行されます。以下の例では、現在の有効なユーザーIDとグループIDがスーパーユーザーのIDにマッピングされた後にのみプログラムを実行する-rを追加します(sudoを回避)。
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
アプリにネットワークインターフェイスが必要な場合は、新しいインターフェイスを設定できます。
$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms
これにより、新しいローカルループバックが作成されることに注意してください。つまり、生成されたプロセスは、ホストのの開いているポートにアクセスできません127.0.0.1
。
名前空間内の元のネットワークにアクセスする必要がある場合は、を使用nsenter
して他の名前空間を入力できます。
次の例ping
は、PID 1で使用されるネットワーク名前空間で実行されます(それはを通じて指定されます-t 1
)。
$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms
--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms
unshare -n
root
特権なしで「許可されていない操作」をスローするようです、私はそれについて何も欠けていますか?
sudo unshare -n
ルート権を継承するなど、共有を解除したいプログラムがあるようです。unshareを呼び出すにはsudoが必要なので、呼び出されたプログラムにroot権限がないことをどのように確認できるか疑問に思っています。
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Linuxには、ネットワーク名前空間と呼ばれる機能があります。これにより、同じマシン上に複数のネットワークスタックを基本的に配置し、実行時にプログラムに割り当てることができます。これは、通常コンテナで使用される機能ですが、目的を達成するために使用することもできます。
ip netns
サブコマンドは、それを管理します。何にもアクセスできない新しいネットワーク名前空間を作成するのは簡単です。これは新しい名前空間のデフォルトの状態です。
root@host:~# ip netns add jail
これで、そのネームスペースに切り替えると、かなり簡単に構成できます。あなたはおそらくそこにloを持ち出したいと思うでしょう、それはそれです:
root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit
これで、ネットワークなしでコマンドを実行したい場合は、その刑務所で実行するだけです:
root@host:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
ネットワークは、必要に応じて到達不能です。(別のネットワークスタックにはiptables
ルールなどが含まれているため、あらゆる種類の興味深いことができます。)
sudo ip
ipコマンドを実行する必要がありましたが、bashになってからsu someuser
、ユーザー 'someuser'の非特権シェルを取得するために実行しました。
iptablesを使用して、そのプロセスをcgroupに移動できます。
mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid
iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP
echo [pid] > /sys/fs/cgroup/net_cls/block/tasks
/sys/fs/cgroup/net_cls/tasks
(パスに「ブロック」はありません)
はい、カスタマイズされた装甲プロファイル、すなわち
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
しかし、その方法では、アクセスを許可するファイルのリストも生成する必要があります。手順全体が少し複雑になる可能性があります。そして、ここでのヘルプ文書を参照してください
firejailサンドボックスを使用できます(seccomp機能を備えたカーネルで動作するはずです)。
使用するには
firejail --noprofile --net=none <path to executable>
--noprofile
デフォルトのサンドボックスを--net=none
無効にし、ネットワークを無効にします
ほとんどのディストリビューションはすでにパッケージを提供していると思いますが、firejailがなくても、ビルドツールチェーンと名前空間/ seccomp対応カーネル以外の依存関係はほとんどありません。
firejailにfirejail --help
は、ネットワークに関して表示できる他の優れた機能(ループバックインターフェイスの提供やip / dnのブロックなど)がありますが、これでうまくいくはずです。また、それdoesn't require root
。
iptablesだけではできません。この機能は簡単に存在していましたが、確実に動作させることができず、放棄されました。
専用のユーザーIDとしてプロセスを実行できる場合、iptablesはowner
モジュールでそれを実行できます。
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Iptablesの例を参照してください:conntrackと所有者との発信トラフィックのマッチング。XYアプリケーション/ユーザーのみを許可するための奇妙なドロップ、iptables / pfルールで動作しますか?
独自のコンテナでプロセスを実行できる場合は、そのコンテナを個別にファイアウォールで保護できます(ネットワークから完全に切断することもできます)。
セキュリティモジュールは、ネットワーク機能へのプロセスのアクセスをフィルタリングできます。warl0ckの答えは、AppArmorの例を示しています。
解決策1:ファイアウォール:
DouaneやOpensnitchなどのファイアウォールを使用できますが、これらのアプリケーションは100%効率的ではないか、開発の初期段階にあります(2019年時点で多くのバグなどがあります)
解決策2:カーネルMAC:
カーネルMACは、最も知られているTomoyo、Selinux、およびApparmorとしてファイアウォールとして使用できます。 このソリューションは、安定性と効率(ファイアウォールソリューション)に関しては最高のソリューションですが、ほとんどの場合、これはやや複雑です。
解決策3:Firejail:
Firejailを使用して、アプリケーションのネットワークアクセスをブロックできます。これにより、すべてのユーザーが恩恵を受けることができるルートは不要です。
firejail --noprofile --net=none command-application
解決策4:共有解除
Unshareは、ネットワークなしで別のネームスペースでアプリケーションを起動できますが、これにはroot firejailのソリューションがほぼ同じことを必要としますが、rootは必要ありません
unshare -r -n application-comand
解決策5:Proxify:
1つの解決策は、アプリケーションをnull /偽のプロキシにプロキシ化することです。tsocksまたはproxyboundを使用できます。ここではいくつかあるのセットアップに関する詳細
解決策6:Iptables:
他の簡単な解決策はiptablesです。アプリケーションをブロックするようにセットアップできます
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
check with:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
4.以下を実行して、Firefoxなどで確認します。
no-internet "firefox"
5.例外を作成し、プログラムがローカルネットワークにアクセスできるようにする場合:
iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
6.永続化する
ブート時にiptablesルールを適用する1つの方法は、systemdでルールをサービスとして追加することです
cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service
[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh
sg no-internet
、今のところ使用しています。
seccomp-bpfを使用して、一部のシステムコールをブロックできます。たとえば、プロセスがソケットFDを作成するのを防ぐために、socket
システムコールをブロックすることができます。
このapprocahの例を書いたので、libseccompをsocket
使用して作業するためのシステムコールを防ぎます。要約は次のとおりです(エラーチェックなし)。
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);
これにはルート権限は必要ありません。
ただし、完全なサンドボックスははるかに複雑なので、この非順序を使用して非協力的/悪意のあるプログラムをブロックしないでください。
「proxychains」と呼ばれるコマンドラインプログラムを使用して、次の可能性のいずれかを試すことができます。
使用するようにセットアップします...
私はそれを自分でテストしていないので、それが機能するかどうかわかりません...