isetta
is a small command line tool to configure your Windows WSL2 environment to work through a company proxy. isetta
runs inside WSL2 and requires Px or a different proxy forwarder to exist on the Windows side.
Disclaimer: This is a hobbyist software project which is not related to the 50ies Isetta microcar. However, the software tool tries to be as nimble and puristic as this old beauty π.
- Px proxy
- WSL2 already installed
Note: gontlm-proxy and winfoom look like good replacements for Px proxy but I did not test them.
$ sudo isetta
Info: Detecting network connection
Info: Found internet access via proxy
Info: Done setting up Linux network via proxy
$ source <(isetta -env-settings)
$ curl www.google.com
isetta
comes as a single binary which should be copied to a directory inside your PATH
.
I suggest to have your own local /home/your-username/bin
directory which is added to the PATH
environment variable, either in .bashrc
(bash) or .zshrc
(zsh)
Example:
# considering a local ~/bin directory exists
cd ~/bin
wget https://github.com/samba2/isetta/releases/download/<version number>/isetta
chmod u+x isetta
If accessing the internet is problematic (this is probably the reason why you want to use isetta π), you can also:
- use your Windows browser and download the binary to the Windows downloads folder
- copy it from there to your Linux environment (e.g.
~/bin/
)
cp /mnt/c/<User>/Downloads/isetta ~/bin/
chmod u+x isetta
isetta
needs to know your internal (aka "cooperate") DNS server. This information is stored in the ~/.isetta
config file in TOML format.
This copy+paste snippet create a minimal configuration which just needs your cooperate DNS server to be adjusted.
cat > ~/.isetta <<EOL
[dns]
# adjust this to your company's DNS server address
internal_server = "42.42.42.42"
EOL
There are various ways to find out about your cooperate DNS server. Here is one way (which worked for me):
- in Windows, run
cmd.exe
- enter
nslookup
- you enter an interactive prompt, the second line
Address
tells you the DNS server
For an example configuration file containing all supported options and their description, see here.
To perform the network configuration (main use case), run:
$ sudo isetta
Additionaly, isetta
also prints out the correct HTTPS_PROXY
variables:
$ isetta -env-settings
Example output when connected to a cooperate network with internet access via proxy:
export HTTPS_PROXY=http://169.254.254.1:3128
export HTTP_PROXY=http://169.254.254.1:3128
export https_proxy=http://169.254.254.1:3128
export http_proxy=http://169.254.254.1:3128
export NO_PROXY=localhost,127.0.0.1,169.254.254.1
Output with direct internet connection (unset all proxy variables):
unset HTTPS_PROXY
unset HTTP_PROXY
unset https_proxy
unset http_proxy
unset NO_PROXY
To let isetta
do both, configure your network and set the HTTPS_PROXY
variables of your current shell correctly, run:
# configure network and
# set the proxy environment variables of this shell
sudo isetta && source <(isetta -env-settings)
isetta
configures WSL2 internet access for these scenarios:
- connected to cooperate network, internet via proxy
- connected to cooperate network via VPN, internet via proxy
- directly connected
isetta
automatically detects these scenarios. To update your network configuration, you only need to re-run the above commands.
isetta
does configuration changes on the Linux and on the Windows side. For this, it needs Linux root and Windows admin rights.
For Linux root rights, sudo
is used. For admin rights on Windows, isetta
ships with an embedded copy of gsudo
and, if needed, will prompt the user for it's Windows admin credentials.
sudo
requires you to enter your Linux root password. To make using isetta
more convenient, you can disable this check.
Open either /etc/sudoers
directly or (e.g. on Ubuntu) create a dedicated new config file like /etc/sudoers.d/no_wsl_sudo_pw
.
Then, add one of the following lines:
# assuming your username is "peter"
# ask for no password when executing /home/peter/bin/isetta
peter ALL= NOPASSWD: /home/peter/bin/isetta
Alternatively, you can disable sudo
password checking entirely:
peter ALL=(ALL) NOPASSWD: ALL
By default, executing sudo
gives a minimal shell with almost none of the environment variables of the original user shell (run sudo env
to see what you've got). To disable this behaviour and inherit the user's environment variables, the following line needs to be set in the sudo
config files:
Defaults !env_reset
This config change is helpful if your copy of isetta
is living in your own private bin
directory which part of your user's PATH
variable. Through this config change, this PATH
is also available for the root user.
For more background, read on here.
You can access the sudo config file by running sudo visudo
.
Depending your environment, you may need to add the following to your sudo config.
- Add the following to the
secure_path
variable:
:/home/<user>/bin:/mnt/c/Windows/system32:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/
- Add the
env_keep
variable line as:
Defaults env_keep += "PATH"
isetta
detects existing NO_PROXY
configurations at two locations:
- an existing
NO_PROXY
environment variable - a list of hosts in the network/no_proxy section of the
.isetta
config file. See here for an example.
Entries of both locations will be appended to the export NO_PROXY
line when running isetta -env-settings
.
As already mentioned, isetta
was tested in these WSL2 networking scenarios:
- connected to cooperate network, internet via proxy
- connected to cooperate network via VPN, internet via proxy
- directly connected
The first two scenarios require the same setup effort. The direct connection scenario is supported to also switch back from a cooperate network connection.
This is rather complex:
WSL2 internet access via cooperate proxy
isetta
performs these configurations:
- create a new point-to-point network between WSL2 and Windows. This became necessary as the default WSL2-to-Windows network used a subnet which was sometimes blocked by a local firewall and/ or was not routed via the VPN.
- configure a Windows port proxy to allow WSL2 traffic to talk to Px proxy on Windows
- adjust the default route on the Linux side
- set the DNS lookup configuration in
/etc/resolve.conf
to the configured internal (aka cooperate) DNS server
isetta
allows you to easily switch back the above configuration if it detects a direct network connection. In this case:
- the DNS server in
/etc/resolve.conf
is changed to the public DNS server - if executed with the
-env-settings
flag, it unsets theHTTPS_PROXY
variables to disable routing via Px proxy. See above for a usage example.
isetta
was born out of multiple intends:
- Existing WSL2 network config scripts were too inconvenient and also did not always "just work".
- I was looking for a real world use-case to do something with Golang.
The result is isetta
- a glorified shellscript with a funky architecture π.
isetta
is a command line application with many specific (I/O) dependencies. This makes it usually hard to automatically test.
To improve here, isetta
uses a ports and adapter architecture, also known as hexagonal architecture.
the core...
- lives in core
- provides its ports via interfaces
- has no knowledge about concrete implementations
- test coverage is quite extensive and heavily backed up by mocks
the adapters...
- live in adapter/
- talk to the disk, configure Linux and Windows networking and do other OS dependent, hard-to test stuff
- should be slim and contain as little business logic as possible
dependency injection...
- manually takes place, together with general application startup in main.go
Although ports and adapters might seem to be a bit heavy for a simple command line app, I was aiming for simple testing of business logic, independent of the actual IO dependencies. Also, I was hoping to improve separation of concerns.
In my eyes introducing decoupled adapters improved the clarity of the code a lot. It was great to reason if this "if/else" is now part of the business logic or still belongs to the adapter.
However, looking at the heavy mocking for the core tests still feels odd. It feels like I reversely repeated the implementation.
isetta
uses go tags to categorize unit and integration tests.
The aim is to allow non-WSl2 users (like a CI/CD pipeline) to execute the cross platform part of the test suite.
Description | go test tags | make command |
---|---|---|
cross platform tests | - | make unit-test |
cross platform tests and WSL2 specific tests (require cmd.exe and powershell.exe in path) |
wsl |
make unit-test-with-wsl |
cross platform test, WSL2 specific tests and interactive tests | wsl,interactive |
make unit-test-with-wsl-interactive |
Hint: To configure the go tags in VS Code, add e.g. "go.testTags": "wsl,interactive"
to your .settings.json
file.
- to the colleges how invested sweat and tears to come up with working Powershell scripts for the WSL2 proxy setup. These scripts were a crucial starting point for
isetta
π - to the Leipzig Golang meetup crew who happen to be extraordinary friendly and supportive people ππ§‘