Hi, habrovchane! Have you ever faced a situation where you would really like to be virtually transferred to another city, country or another continent? I have such a need often enough, so the opportunity to have my own VPN server, which can be run anywhere, in a couple of seconds, was quite acute. an image that would allow to quickly raise the OpenVPN server, with a minimum of settings and an acceptable level of security.
Prehistory
The ability to run the service on any machine: be it a physical server, or a virtual private server, or even a container space inside another container management system - was crucial. My gaze immediately fell on Docker. Firstly, this service is gaining popularity, and therefore, more and more providers provide ready-made solutions with its pre-installation; secondly - there is a centralized image repository, where you can download and start the service with the help of one command in the terminal. The idea that such a project should already exist, visited me and I persistently searched. But most of the projects that I found were either too cumbersome (it was necessary to create a container for permanent storage of data and run the container several times with the application with different parameters), or without any sane documentation, or completely abandoned. Without finding anything acceptable, I started work on your project. Ahead were sleepless nights studying documentation, writing code and debugging, but eventually my service saw the light and played with all the colors of the monochrome LED panel of the router. So, I beg to love and favor -
Docker-OpenVPN . I even came up with the logo (above, before the cut), but do not judge it strictly, because I am not a designer (already). When I implemented this project, I put the deployment speed, the minimum of settings and an acceptable security level at the forefront. Through trial and error, I found the optimal balance of these criteria, although in some places I had to sacrifice deployment speed for the sake of security, and for a minimum of settings I had to pay portability: in the current configuration, a container once created on one server cannot be transferred and run on another. For example, all client and server certificates are generated when starting the service and it takes about 2 seconds. However, the generation of the Defi Hellman file had to be rendered into build-time: it is created during the build of the docker image and can last up to 10 minutes. I would very much like to receive a security audit of such a decision from a respected community.
Launch
To start the service we need a few things:
- Server: physical or virtual. Theoretically, you can run in docker-in-docker mode, but I did not conduct extensive testing of this option;
- Actually Docker. Many hosting providers provide turnkey solutions with Docker on board;
- Public IP address.
If all the details are in place, then it remains for us to run the following command in the console of your server:
docker run --privileged -it --rm --name dovpn -p 1194:1194/udp -p 8080:8080/tcp -e HOST_ADDR=$(curl -s https://api.ipify.org) alekslitvinenk/openvpn
The attentive reader might have noticed that the server’s IP address is automatically determined using
ipify.org . If for some reason this does not work, then you can specify the address manually. If all the previous steps have been performed correctly, then we should see something similar in the console:
Sun Jun 9 08:56:11 2019 Initialization Sequence Completed Sun Jun 9 08:56:12 2019 Client.ovpn file has been generated Sun Jun 9 08:56:12 2019 Config server started, download your client.ovpn config at http://example.com:8080/ Sun Jun 9 08:56:12 2019 NOTE: After you download you client config, http server will be shut down!
We are close to the goal: now we need to copy
example.com : 8080 / (in your case there will be the address of your server) and paste it into the address bar of the browser. After you press Enter, the client.ovpn file will be downloaded, and the http server itself will go into oblivion. If this solution is in doubt, you can use the following trick: run the previous command and add the
zp flags and password. Now, if you paste the generated link into the browser window, you will receive a zip archive with a password. When you have a file with a client configuration, you can use any suitable client. I use Tunnelblick for Mac.
Video tutorial
This video tutorial contains detailed instructions for deploying the service to DigitalOcean. So far in English, but I plan to make a version in Russian soon.

PS If you find this project useful, please put an asterisk on the GitHub, fork it and tell your friends. Contributors and security audits are also widely welcome.
PPS If this article goes to Habr, then I plan to write the following about how I ran docker-in-docker and docker-in-docker-in-docker, why I did it and what came of it.
EDIT1:- Fixed errors in the publication,
- Responding to comments, I decided to bring this information here: the --privileged flag is needed to work with iptables