-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sudip Bhattarai
committed
Jan 12, 2023
0 parents
commit ec23bae
Showing
9 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# usernetns | ||
Helpers for Setting private network namespace per-user basis. It provides cli helper and example systemd-service file. | ||
|
||
## Install | ||
``` | ||
sudo ./install.sh | ||
``` | ||
|
||
## Quick Start | ||
1) Run a command inside network namespace ( create if not present ) | ||
``` | ||
sudo usenetnsexe "$(whoami)" ifconfig | ||
``` | ||
|
||
2) Run [test-systemd-service](./lib/systemd/system/usernetnstest%40.service) | ||
``` | ||
sudo systemctl start "usernetnstest@$(whoami)".service | ||
journalctl -a --no-pager -u "usernetnstest@$(whoami)".service | ||
``` | ||
|
||
|
||
## Commands provided | ||
- `makebridge name ipAddress ` : Helper for creating bridge interface and setting it up | ||
- `makeusernetns userName` : Setup namespace for a user | ||
- `usernetnsexe userName command` : Setup namespace if not set up and run a command on namespace of that user. The command is run as root. | ||
|
||
## Services | ||
|
||
1) `usernetns-bridge.service` : Sets up bridge for working with user network namespaces | ||
|
||
2) `usernetns@.service` : Sets up network namespace for per-user | ||
Usage: let's say that your username is `username`, to setup network namespace for `username` | ||
|
||
`systemctl start usernetns@myusername.service` | ||
|
||
3) `usernetnstest@.service` : An example service that can be started per-user basis, on that user's network namespace. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
USERNETNS_BRIDGE=userswitch | ||
USERNETNS_BRIDGE_IP=172.31.6.0/24 | ||
USERNETNS_DNS=172.21.0.6 | ||
USERNETNS_NAMESPACE_DEV=eth0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/bin/bash | ||
INSTALL_PATH=${INSTALL_PATH:-""} | ||
|
||
function doInstall(){ | ||
local arg1="$1" | ||
shift | ||
echo + install ".$arg1" " $INSTALL_PATH$arg1" "$@" | ||
install "./$arg1" "$INSTALL_PATH$arg1" "$@" | ||
} | ||
function doUninstall(){ | ||
echo + rm -f "$1" | ||
rm -f "$1" | ||
|
||
} | ||
function perform(){ | ||
$1 /lib/systemd/system/usernetns-bridge.service | ||
$1 /lib/systemd/system/usernetnstest@.service | ||
$1 /lib/systemd/system/usernetns@.service | ||
$1 /usr/local/bin/makebridge | ||
$1 /usr/local/bin/makeusernetns | ||
$1 /usr/local/bin/usernetnsexec | ||
$1 /etc/usernetns.conf | ||
|
||
} | ||
|
||
if [ "$1" == "uninstall" ] | ||
then | ||
perform doUninstall | ||
elif [ "$#" == "0" ] || [ "$1" == "install"] | ||
then | ||
set -e | ||
perform doInstall | ||
else | ||
echo "Unknown options: " "$@" 1>&2 | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[Unit] | ||
Description=Bridge for per-user network namespace | ||
|
||
After=network-online.target nss-lookup.target | ||
Wants=network-online.target nss-lookup.target | ||
|
||
[Service] | ||
Type=oneshot | ||
RemainAfterExit=yes | ||
EnvironmentFile=/etc/usernetns.conf | ||
|
||
ExecStartPost=iptables -A FORWARD -i ${USERNETNS_BRIDGE} -j ACCEPT | ||
ExecStartPost=iptables -A FORWARD -o ${USERNETNS_BRIDGE} -j ACCEPT | ||
ExecStartPost=iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE | ||
|
||
ExecStart=makebridge ${USERNETNS_BRIDGE} USERNETNS_BRIDGE_IP | ||
|
||
ExecStopPost=iptables -D FORWARD -i ${USERNETNS_BRIDGE} -j ACCEPT | ||
ExecStopPost=iptables -D FORWARD -o ${USERNETNS_BRIDGE} -j ACCEPT | ||
ExecStopPost=iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE | ||
|
||
|
||
[Install] | ||
WantedBy=multi-user.target | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[Unit] | ||
Description=Setup private network namespace for user (%i) | ||
After=usernetns-bridge.service | ||
Wants=usernetns-bridge.service | ||
|
||
[Service] | ||
Type=oneshot | ||
RemainAfterExit=yes | ||
ExecStart=makeusernetns %i | ||
ExecStop=ip netns delete %i | ||
|
||
[Install] | ||
WantedBy=multi-user.target | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[Unit] | ||
Description=Demo usernetns instance (%i) | ||
After=usernetns@%i.service | ||
Wants=usernetns@%i.service | ||
|
||
[Service] | ||
NetworkNamespacePath=/var/run/netns/%i | ||
WorkingDirectory=/home/%i | ||
PrivateMounts=true | ||
User= %i | ||
Group= %i | ||
BindPaths=/etc/netns/%i/resolv.conf:/etc/resolv.conf | ||
Type=oneshot | ||
#ExecStartPre=!mount --bind /etc/netns/%i/resolv.conf /etc/resolv.conf | ||
#ExecStartPre=!mount -t sysfs none /sys | ||
ExecStart=/bin/bash -c "set -x ;whoami; ip addr show; ip route; cat /etc/resolv.conf ;ls /sys/class/net | head; " | ||
[Install] | ||
WantedBy=multi-user.target | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/bash | ||
|
||
|
||
set -e | ||
if (( $# != 2 )); then | ||
|
||
>&2 echo "Usage: makebridge name ipAddress" | ||
>&2 echo "eg :" | ||
>&2 echo " : makebridge br0 10.0.1.0/24" | ||
|
||
exit 1 | ||
fi | ||
|
||
|
||
BRIDGE_DEV=$1 | ||
BRIDGE_IP=$2 | ||
NAMESPACE_DEV=eth0 | ||
|
||
|
||
set -x | ||
# setup bridge | ||
function makebridge() { | ||
ip link add ${BRIDGE_DEV} type bridge | ||
ip link set ${BRIDGE_DEV} up | ||
|
||
# setup bridge ip | ||
ip addr add ${BRIDGE_IP} dev ${BRIDGE_DEV} | ||
} | ||
(ip link show ${BRIDGE_DEV} && ip link delete $BRIDGE_DEV && false ) || makebridge | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/bin/bash | ||
source /etc/usernetns.conf | ||
set -e | ||
if (( $# != 1 && $# != 2 )); then | ||
|
||
>&2 echo "Usage: makeusernetns UserName [bridge=userswitch]" | ||
exit 1 | ||
fi | ||
|
||
function failreturn(){ | ||
>&2 echo "makeusernetns: $1" && false | ||
} | ||
|
||
USERNETNS_BRIDGE_IP=172.31.31.0/24 | ||
|
||
USERNAME=$1 | ||
USERID="$(id -u $USERNAME )" | ||
|
||
test $USERID -ge 1000 || failreturn "Expected uid to be > 1000"; | ||
test $USERID -lt 1252 || failreturn "Expected uid to be < 1252" | ||
|
||
|
||
NAMESPACE=$USERNAME | ||
USERNETNS_BRIDGE=${2:-"${USERNETNS_BRIDGE:-userswitch}"} | ||
USERNETNS_NAMESPACE_DEV="${USERNETNS_NAMESPACE_DEV:-eth0}" | ||
USERNETNS_DNS=${USERNETNS_DNS:-"8.8.8.8"} | ||
|
||
|
||
ip link show ${USERNETNS_BRIDGE} 2>&1 >/dev/null || failreturn "Bridge \"$USERNETNS_BRIDGE\" doesn't exist" | ||
|
||
BRIDGE_IP="$(ip -4 addr show $USERNETNS_BRIDGE | grep inet | grep -oe '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | tail -n 1)" | ||
IP_PREFIX="$(echo $BRIDGE_IP | grep -oe '^[0-9]*\.[0-9]*\.[0-9]*' | tail -n 1)" | ||
NAMESPACE_IP="$IP_PREFIX.$(( $USERID - 999 ))/24" | ||
|
||
|
||
test ! -z "$BRIDGE_IP" || failreturn "Bridge \"$USERNETNS_BRIDGE\" doesn't have ip set" | ||
mkdir -p /etc/netns/$NAMESPACE | ||
set -x | ||
test -f "/etc/netns/$NAMESPACE/resolve.conf" || echo "nameserver $USERNETNS_DNS" > "/etc/netns/$NAMESPACE/resolv.conf" | ||
# delete namespace if exists | ||
(ip netns list | grep -e '^\w*' -o | grep -e '^'$NAMESPACE'$' 2>&1 >/dev/null ) && ip netns delete $NAMESPACE | ||
|
||
|
||
# create namespace | ||
ip netns add $NAMESPACE | ||
|
||
# create veth link | ||
ip link delete "veth_$NAMESPACE" || true | ||
ip link add "veth_$NAMESPACE" type veth peer name $USERNETNS_NAMESPACE_DEV netns $NAMESPACE | ||
ip link set "veth_$NAMESPACE" up | ||
ip link set "veth_$NAMESPACE" master ${USERNETNS_BRIDGE} | ||
|
||
ip netns exec $NAMESPACE sh -c "\ | ||
ip link set dev $USERNETNS_NAMESPACE_DEV up && \ | ||
ip link set dev lo up &&\ | ||
ip addr add $NAMESPACE_IP dev $USERNETNS_NAMESPACE_DEV &&\ | ||
ip route add default via ${BRIDGE_IP} dev $USERNETNS_NAMESPACE_DEV" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/bin/bash | ||
|
||
source /etc/usernetns.conf | ||
set -e | ||
if (( $# < 2 )); then | ||
>&2 echo "usernetnsexec" | ||
>&2 echo " Automatically makes bridge and namespace if required and runs the program on that namespace " | ||
>&2 echo " runonusernetns UserName command [commandargs]" | ||
exit 1 | ||
fi | ||
|
||
function failreturn(){ | ||
>&2 echo $1 && false | ||
} | ||
|
||
NAMESPACE=$1 | ||
USERNETNS_BRIDGE=${USERNETNS_BRIDGE:-"userswitch"} | ||
USERNETNS_BRIDGE_IP=${USERNETNS_BRIDGE_IP:-"172.31.31.0/24"} | ||
|
||
# make bridge if not exists | ||
ip link show ${BRIDGE_DEV} > /dev/null|| makebridge ${BRIDGE_DEV} ${BRIDGE_IP}/24 | ||
|
||
# make namespace if not exists | ||
(ip netns list | grep -e '^\w*' -o | grep -e '^'$NAMESPACE'$' 2>&1 >/dev/null ) || makeusernetns | ||
|
||
shift | ||
exec ip netns exec $NAMESPACE su - $USERNAME -c "$*" | ||
|