# Network Namespace setup using SSH SOCKS proxy Create network namespace where all¹ network requests go via socks proxy. ## Dependency Depends on [tun2socks][4]. Install from [AUR][5] or compile from [source][6]. ## Installing 1. Install from [AUR][2]. 2. Manual installation: This will install under `/usr` ```sh sudo make install ``` Change install directory using `PREFIX` ```sh sudo make PREFIX=/usr/local install ``` For uninstall, run `make uninstall` or `make PREFIX= uninstall` ## Type A: Use ssh to create socks proxy 1. Create a simple ssh config at `/etc/nnss//config`. This will be included with [other settings][0]. 2. Copy your ssh private key to `/etc/nnss//privatekey` 3. [Edit][1] your application's service file to include below properties ```systemd [Unit] Requires=nnssA@.service After=nnssA@.service [Service] NetworkNamespacePath=/run/netns/ns ``` ### Example ```bash ❯ sudo mkdir /etc/nnss/vps1 ❯ sudo tee /etc/nnss/vps1/config > /dev/null Hostname xx.xx.xx.xx User vps_user_name_here Port 8822 # If the ssh server is not on default port 22 ❯ cp ~/.ssh/id_ed25519_for_vps1 /etc/nnss/vps1/privatekey ``` ### Testing namespace ```bash ❯ sudo systemd-run \ --property=NetworkNamespacePath=/run/netns/vps1ns \ --property=User=$USER \ --property=Requires=nnssA@vps1.service \ --property=After=nnssA@vps1.service \ --shell [sudo] password for balki: Running as unit: run-p233279-i233579.service Press ^] three times within 1s to disconnect TTY. ❯ curl https://ip.balki.me/ip xx.xx.xx.xx ❯ ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host proto kernel_lo valid_lft forever preferred_lft forever 18: tunvps1: mtu 1500 qdisc fq_codel state UP group default qlen 500 link/none inet 198.19.1.1/30 scope global tunvps1 valid_lft forever preferred_lft forever inet6 fe80::fd64:c3f3:ce6:650c/64 scope link stable-privacy proto kernel_ll valid_lft forever preferred_lft forever ``` ## Type B: Use existing socks proxy 1. Create an environment file at `/etc/nnss/env_`. This file should contain one environment variable `SOCKS_PROXY`. See example below 2. [Edit][1] your application's service file to include below properties ```systemd [Unit] Requires=nnssB@.service After=nnssB@.service [Service] NetworkNamespacePath=/run/netns/ns ``` ### Example Assuming tor daemon is running configured to listen on socks proxy on port 9050. ```bash ❯ sudo tee /etc/nnss/env_tor > /dev/null SOCKS_PROXY=socks5://127.0.0.1:9050 ``` Create a shell inside tor namespace ```bash ❯ sudo systemd-run \ --property=NetworkNamespacePath=/run/netns/torns \ --property=User=$USER \ --property=Requires=nnssB@tor.service \ --property=After=nnssB@tor.service \ --shell ``` Quick check: ```bash ❯ curl --silent https://check.torproject.org | grep -E "Sorry|Congratulations" Congratulations. This browser is configured to use Tor. ``` ### Comparison with torsocks [torsocks][7] can be used to run a program to connect via tor. This works by replacing network function calls in libc using `LD_PRELOAD`. This does not work with programs not using libc functions for networking. E.g. go programs. Or when a sub-process is created wihtout passing down `LD_PRELOAD`. Network namespaces are more secure and works for any program. ## ¹DNS DNS by default still goes via host. [0]: ./ssh_config [1]: https://wiki.archlinux.org/title/Systemd#Editing_provided_units [2]: https://aur.archlinux.org/packages/nnss [4]: https://github.com/xjasonlyu/tun2socks [5]: https://aur.archlinux.org/packages/tun2socks-git [6]: https://github.com/xjasonlyu/tun2socks/wiki/Install-from-Source [7]: https://gitlab.torproject.org/tpo/core/torsocks