Hello, Habr users! Have you ever found yourself in a situation where you really wanted to virtually transport yourself to another city, country, or even another continent? I find myself in need of such a solution quite often, which is why having my own VPN server that I can set up anywhere in just a couple of seconds has been a pressing requirement. In this article, I want to share my project that I conceived while searching for a ready-made solution—in this case, a Docker image that would allow me to quickly deploy an OpenVPN server with minimal configuration and an acceptable level of security.
Background
The ability to run the service on any machine—whether it's a physical server, a virtual private server, or even a containerized space within another container management system—was critically important. My focus immediately turned to Docker. Firstly, this service is gaining popularity, meaning more and more providers are offering ready-made solutions with it pre-installed; secondly, there is a centralized repository of images from which you can download and run the service with a single command in the terminal. The idea that such a project must already exist crossed my mind, and I diligently searched for it. However, most of the projects I found were either too cumbersome (as they required creating a container for persistent data storage and launching the application container multiple times with different parameters), lacking reasonable documentation, or completely abandoned. Finding nothing suitable, I began work on my own project. Ahead lay countless sleepless nights studying documentation, writing code, and debugging, but ultimately, my service saw the light and lit up in all the colors of my router's monochrome LED panel. So, please welcome— . I even came up with a logo (above, before the cut), but please don't judge it harshly, as I am not a designer (anymore). When I was implementing this project, I prioritized deployment speed, minimal configuration, and an acceptable level of security. Through trial and error, I found the optimal balance of these criteria; however, in some cases, I had to sacrifice deployment speed for security, and the minimum configuration came at the cost of portability: in the current setup, a container created on one server cannot be moved and launched on another. For instance, all client and server certificates are generated upon service launch, which takes about 2 seconds. However, the generation of the Diffie-Hellman file had to be moved to the build-time: it is created during the Docker image build and can take up to 10 minutes. I would really like to get a security audit of such a solution from the highly respected community.
Start
To launch the service we need a few things:
- A server: physical or virtual. Theoretically, you can run it in a Docker-in-Docker mode, but I haven't conducted extensive testing of this option;
- Docker itself. Many hosting providers offer ready-made solutions with Docker 'on board';
- A public IP address.
If all credentials are in place, the next step is to run the following command in your server's console:
docker run --cap-add=NET_ADMIN
-it -p 1194:1194/udp -p 80:8080/tcp
-e HOST_ADDR=$(curl -s https://api.ipify.org)
alekslitvinenk/openvpnThe attentive reader might have noticed that the server's IP address is automatically determined using ipify.org. If, for any reason, this does not work, you can specify the address manually. If all previous steps were performed correctly, we should see something like this 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/
Sun Jun 9 08:56:12 2019 NOTE: After you download your client config, the http server will be shut down!We are close to the goal: now we need to copy (in your case, it will be the address of your server) and paste it into your browser's address bar. After you hit Enter, the client.ovpn file will be downloaded, and the http server will cease to exist. If this solution raises doubts, you can use the following trick: run the previous command and add flags zip and password. Now, if you paste the generated link into the browser window, you will get a zip archive with the password. Once you have the file with the 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 on DigitalOcean.

EDIT1:
- Corrected errors in the publication,
- In response to comments, I decided to bring this information here: the --privileged flag is needed for working with iptables
EDIT2:
- Improved the image launch command: now it does not require the --privileged flag
- Added a link to a Russian-language video guide:
Source: habr.com
