Using docker, this project converts VPN connecting into a proxy.
-
Proxy HTTP/HTTPS, SSH
-
Forward any data via port forwarding (like remote desktop)
-
Runs on any platform Docker supports, including Windows, Linux, and macOS!
- Clone the repo
- Create a copy of
.env.example
file and name the new file to exactly.env
under the cloned folder - Modify the
.env
file as follows:
# The command to connect to the VPN
CMD=
# HTTP Proxy port
PORT=8888
# Port forward
# The port in the host to listen to
# Even if you don't use port forwarding, you have to set the port here
PF_PORT=18889
# The destination for the port forwarding
# If you don't use port forwarding, leave this commented out
# PF_DEST=
Example CMD values of several universities are under the configs
file.
If your organization is included:
- Read the comments of the config file and modify the command accordingly
- Append the last uncommented line after
CMD=
in your.env
file
If not, you can do the followings to experiment and find the command to connect to VPN:
- Run
docker compose build
to build the image - Run
docker run -it --cap-add=NET_ADMIN ghcr.io/ddadaal/vpn-as-http-proxy:master
to start a container - Try connecting to your VPN with
openconnect
in one line - Append the command after
CMD=
in your.env
file - (Optional) Submit a pull request to add your organization's config in the repo!
Note:
- The command itself should be able to your VPN without any intervention (like inputting credentials), so all your configs, including credentials, should be included in the command
- The CMD will be wrapped inside a pair of single quotes to run, so use double quotes to wrap your strings in your command, and escape your command if necessary
- If
openconnect
does not exit, the connection is already successful. Some errors can be ignored in this case.
After the .env
file is configured, you can run the proxy:
- Run
docker compose up
to start the container- add
-d
option to run in the background docker compose
will pull the prebuilt image fromGitHub Package
. If it is too slow for you, you can build the images by adding--build
option
- add
- Set the proxy server of your apps to
http://localhost:{PORT}
(the PORT you set in the.env
file) - The container should keep running for the proxy to work.
- Press
Ctrl-C
or usedocker compose down
to stop the container.
It is tested that the VPN connected in one container are isolated with other containers, i.e. the other containers are not connected to the VPN connected by one container.
Set the HTTP/HTTPS proxy server of apps to http://localhost:{PORT}
(the PORT you set in the .env
file)
The followings are some examples. All examples use 8888 as the port number. Change it if needed.
# Only for the current repo
git config http.proxy http://localhost:8888
git config https.proxy http://localhost:8888
# Windows PowerShell
$env:HTTP_PROXY="http://localhost:8888"
$env:HTTPS_PROXY=$env:HTTP_PROXY
# Linux/macOS
export HTTP_PROXY=http://localhost:8888
export HTTPS_PROXY=$HTTP_PROXY
Install Proxy SwitchyOmega(Chrome Web Store)Extension, and configure it as follows:
- Create a new profile with any name. Set the type to Proxy Profile.
- Select the new profile, and set the protocol to HTTP, the Server to localhost, and the Port to 8888. Click the Apply changes button on the left.
- Select auto switch on the left, and set the domains you wish to use VPN to use the new profile. Set the default profile to system proxy. Click the Apply Changes button on the left.
- Click the menu button of the extension (usually besides the URL bar), and select auto switch.
Completed. When accessing the URLs set in the step 3, the browser proxies the traffic to the proxy.
There are mainly 2 ways to use SSH with proxy.
This is the recommended approach.
We can utilize SSH client's ProxyCommand
config to use HTTP proxy. With this setup, any client that uses local openssh client will be able to connect to the server through proxy, which also includes VSCode Remote SSH.
- Install needed programs
- In Arch Linux the programs are
openbsd-netcat
andconnect
. It differs in different distributions and OSs, so please check out the stackoverflow question above. - In Windows, we need
connect.exe
which is installed alongsideMinGW64
, which is installed withGit for Windows
. Therefore, you may find theconnect.exe
under themingw64/bin
folder under git's installation path
- In Arch Linux the programs are
- Add the following content into
~/.ssh/config
, replacing the content in {} accordingly
Host <The address to be connected with proxy>
ProxyCommand nc -X connect -x localhost:{proxy server port in .env} %h %p
# Windows user use the following path
# ProxyCommand {connect.exe path, quoted if necessary} -H localhost:{proxy server port in .env} %h %p
If you encounter any error, check out other answers and comments in this stackoverflow question (https://stackoverflow.com/questions/19161960/connect-with-ssh-through-a-proxy).
SSH is installed in the image. When the container is running, you can access the container by starting a /bin/bash
process. The ~/.ssh
directory is mapped to /root/.ssh
of the container, so the container shares SSH key pairs with the host.
Also, since the container is connected to the VPN, all apps running in the container will use VPN.
# 1. Access the container's bash
# Windows PowerShell
pwsh bash.sh
# Linux/macOS
./bash.sh
# 2. Connect by SSH
ssh username@ip
You can use this proxy to forward a local port to an destination. You can use this feature in non-HTTP scenarios like Windows Remote Desktop.
To configure it, set the following envs in .env
# The port in the host to listen to
PF_PORT=18889
# The destination for the port forwarding
PF_DEST=10.2.3.4:3389
When the proxy is up, all data to localhost:18889
will be forwarded to 10.2.3.4:3389
.
For example, if you have a Windows with RDP service running at 10.2.3.4:3389
, you can now use localhost:18889
to connect to it!
VPN is used to access internal resources that can only be obtained in the internal network of your corporation. However, connecting to VPN in your device makes all network traffic forwarded to the VPN, which adds network latency and affects speed for requests that can be accessed without VPN.
Most applications now support proxy. If a proxy is set for an app, all traffic from the app will go to the proxy instead of go directly to the Internet. The proxy will then sends the traffic to its real destinations.
Therefore, if we have a proxy that is connected to VPN, we can only set the proxy of the apps that needs internal resources. Only the traffic of these apps will go to the VPN. The apps whose proxy is not set will NOT go to the VPN, which addresses our original issue.
This project creates a docker container that does exactly what is mentioned above. This container does 2 things:
- connects to your VPN
- listens to a port, from which the container receives incoming HTTP requests and "re-sends" them
Set the proxy of your application to http://localhost:{port}
, and all the HTTP requests from the app will go to the container. The container just simply resends the requests without any modifications. Since the container is connected to a VPN, any network traffic coming from the container is tunneled to your VPN, and as a result, the application is now able to access internal resource.
Check out the related article on my blog, which explains VPN and proxy solution in detail.
- Base image:
debian:buster-slim
- VPN client:
openconnect
- Proxy:
tinyproxy