fcwu / docker-ubuntu-vnc-desktop

A Docker image to provide web VNC interface to access Ubuntu LXDE/LxQT desktop environment.
Apache License 2.0
3.94k stars 1.42k forks source link

Embed OpenVPN connection #160

Open myacidpacemaker opened 4 years ago

myacidpacemaker commented 4 years ago

Describe the solution you'd like It would be good if you could embed an OpenVPN client into the image so that the container boots directly into a tunnel rather than the local network. My use case is I need a linux desktop that connects to a VPN client.

Describe alternatives you've considered I've tried installing the OpenVPN package within the container as well as standalone VPN applications but both failed (systemd issues, network-manager issues), I have found a firefox extension that will tunnel browser traffic but this isn't ideal as it leaves the OS traffic open.

Additional context Ideally implement in a similar manner to how haugene/transmission-openvpn package does.

jamesfreeman959 commented 4 years ago

If it's of any assistance, I forked this repo and merged in a selection of the code from haugene/transmission-openvpn. I haven't had a lot of time to work on it, so it's a bit basic in places and I've coded it specifically to work with my VPN provider - however I do believe it could be developed further and made better. I'd used UFW to precent anything that isn't the VPN tunnel going outbound (so no non-VPN leakage), added the transmission daemon to supervisord, and openvpn also gets added to supervisord on container start.

@fcwu thank you for your amazing work - I really love this container! I've just finished merging the v2.0.0 release of your code with the VPN/Transmission components - if I can help with integrating this I'd be happy to help.

fcwu commented 4 years ago

@jamesfreeman959 Cool! Could I try your Docker image first? I may not merge your code, because I like to keep this Docker image simple, but I am willing to add a link to your image if it works well~

jamesfreeman959 commented 4 years ago

@fcwu of course! I have tried to maintain full credit for your work in the code but if there's anything you want changing please let me know and I'll fix it. The container works well for me (been using it daily for some months now), but I would certainly welcome more testing (and I can merge in a wider array of VPN providers as in the haugene container if there is sufficient interest.

fcwu commented 4 years ago

I have a self-hosting OpenVPN server. After I read haugene's document, I realize

  1. OSX looks not to work. So I change to Ubuntu 20.04 Beta

  2. I need to insert kernel modules (machine on linode not works)

sudo modprobe nf_conntrack_ftp nf_conntrack_netbios_ns nf_nat_ftp iptable_filter tun
  1. Following is my docker run command (very hard to know correct command)
docker run -it --rm --cap-add=NET_ADMIN -e CREATE_TUN_DEVICE=true -v ${PWD}/CLIENTNAME.ovpn:/etc/openvpn/custom/default.ovpn -e OPENVPN_PROVIDER=custom -e OPENVPN_CONFIG=default -e OPENVPN_USERNAME= -e OPENVPN_PASSWORD= -p 6080:80 -v /dev/shm:/dev/shm -v /lib/modules/:/lib/modules/:ro jamesfreeman959/docker-ubuntu-transmission-openvpn-vnc-desktop
  1. I don't know why network not work at startup, but it back by
ufw default allow outgoing

If we have better document and testing, I like OpenVPN as a built-in function. Before this, I also like to know image size after installing OpenVPN.

jamesfreeman959 commented 4 years ago

@fcwu great feedback - so to answer your points and hopefully produce a better image for everyone:

0 & 1. I have only tested this so far on Ubuntu Server LTS releases (not 20.04 yet though - I'll await the final release in a few days). These were normal libvirtd virtual machines running Docker, so I didn't need to insert any kernel modules, but I can see that on another platform this will be necessary. Do you have a recommended or preferred platform for your testing that I should target for testing so I can document required modules?

  1. Good point - I launch the container using a Docker Compose file - here is a sanitized version of mine which hopefully helps - note I'm using MACVLAN networking which isn't necessary, but I like it for the network setup I have at home:
    
    version: '3.2'

services: transmission: image: jamesfreeman959/docker-ubuntu-transmission-openvpn-vnc-desktop:latest environment:

  1. I didn't want anything from this container to leak out onto the LAN, so all outbound traffic is blocked by default - however if the VPN comes up the traffic is allowed to flow over the VPN. This could be changed - ufw is configured in rootfs/firewall.sh. I know this setup is crude and I think haugene has improved his container since I started work on this - I haven't had time to port over his improvements yet.

  2. Image size:

    $ docker images
    REPOSITORY                                                       TAG                 IMAGE ID            CREATED             SIZE
    jamesfreeman959/docker-ubuntu-transmission-openvpn-vnc-desktop   latest              79f3a78e8339        4 weeks ago         1.32GB

I hope this helps!

fcwu commented 4 years ago

@jamesfreeman959 do you plan to pull request for this?

jamesfreeman959 commented 4 years ago

@fcwu I'm open minded on this. Happy to if my little bit of hacking can enhance your original project. But if you feel it's best to keep it separate then I can do this and will try and enhance the documentation and code as time and interest permits.

fcwu commented 4 years ago

@jamesfreeman959 Sure, I would like to make this happen (yes, I am excited anyone PR for new function).

I hope OpenVPN is one of flavors. This repo already has configuration file, such as https://github.com/fcwu/docker-ubuntu-vnc-desktop/tree/develop/flavors, which can install additional package as you needed. You may also create a new doc folder to write the document to introduce how to start image with OpenVPN.

If you are willing to join, I can invite you as collaborator that we can branch and do any modification on the branch. Until we feel the function is mature, I will set auto build on Docker Hub.

jamesfreeman959 commented 4 years ago

@fcwu great - I am really looking forward to working with you.

I reviewed the code in the flavors directory - I can implement the additional packages required in a new file (or set of files) in this directory. How would you like me to add some of my additional scripts (e.g. firewall.sh - won't be required except in the OpenVPN flavor)? Should I package them into a DEB file? Or is maybe we can expand the Jinja2 template to conditionally include some scripts based on the flavor?

I'm finishing off a project this week but I'll be able to make a start on this soon.

fcwu commented 4 years ago

You may put firewall.sh or any script into rootfs/usr/local/bin. It's ok even other flavors are not using.

jamesfreeman959 commented 4 years ago

You just gave me an idea. What if we create rootfs/usr/local/<flavor>? Then in the Dockerfile, we add a simple command to merge that with /usr/local (e.g. rootfs/usr/local/openvpn/bin --> /usr/local/bin for the openvpn flavor only? We could do this with a simple rsync/copy command, or something like stow? That way only relevant flavor files are in /usr/local/ depending on the build.

fcwu commented 4 years ago

Dockerfile which having a line add rootfs / will put everything into root file system by default. It's fine without modifying Dockerfile, i.e., we put these files in every flavor, if /usr/local/<flavor>/bin is small, probably under 1 MB. If exceeding 1 MB, I prefer put into flavor/openvpn/* and add add line in Dockerfile.

jamesfreeman959 commented 4 years ago

Hi there! So sorry about how long it has taken to get back to you - I was finishing editing a book which is due for release this summer.

So finally I've got a proposal for merging my transmission/OpenVPN container with your original code. I forked your repository again (to start from a clean copy) and then created a branch called "transmission". This has the following changes:

  1. flavors/*.yml now has a new option:

    mergeroot: true

    If this is set, Dockerfile.j2 will try and also copy from flavors/{{ flavor }}/rootfs and copy this over the top of the rootfs that was copied previously. I have some other ideas for workloads on this container so I wanted to create a framework that was flexible. I like this but you are welcome to tell me otherwise :)

  2. Dockerfile.j2 has been edited according to the above

  3. rootfs/startup.sh is now renamed to startup.j2 - I have added the capability to include additional content from flavors/{{ flavor }}/rootfs/startup.additions so each flavor can have its own unique startup steps.

  4. The change in 3 necessitated an enhancement to jinja2cli - a pull request is open on the project for including files from other directories, but it hasn't been merged in over 12 months. As a result I forked the repo, applied the fix, uploaded it to PyPI, then forked the vikingco container and created my own container. The Makefile now uses this new container.

So far I've been able to test the following:

a. The original builds seem to work as they used to, which was intended - I didn't want to cause any need to edit existing code. b. I've tried building my code - I can only get it to build with IMAGE=ubuntu:18.04 - if I use 20.04, it fails with a repository error. It looks like one of the repos used in the build hasn't been updated to support focal yet. c. My build succeeds as follows:

IMAGE=ubuntu:18.04 ARCH=amd64 FLAVOR=lxde-transmission-openvpn make build

However it won't quote start up - I'm seeing:

Traceback (most recent call last):
  File "/usr/local/lib/web/backend/run.py", line 9, in <module>
    from vnc.util import ignored
  File "/usr/local/lib/web/backend/vnc/util.py", line 5, in <module>
    from gevent import GreenletExit
ModuleNotFoundError: No module named 'gevent'
2020-05-27 11:14:33,259 INFO exited: web (exit status 1; not expected)

Not sure if this is something I broke?

TODO:

  1. Complete documentation - I created a Makefile in flavors/lxde-transmission-openvpn with some of the requirements needed to run the container to help users - but as the container won't start I can't be sure if it's complete. Also I remember you said you identified some issues - I'm testing on CentOS 8.1 - are there other systems I should test on?
  2. I'd like to add a README.md to this directory also just explaining a little more about how this flavor works - I'll get this done once the container is working and we're both happy with the development effort.

I haven't created a pull request yet because the code isn't finished, but I wanted to share my progress. I know this is a little different to our discussion and I can change it - I just wanted to demonstrate my proposal to you first. Happy to receive your feedback!

izzyiceberg commented 4 years ago

Is this thread still alive or has it been abandoned?

jamesfreeman959 commented 4 years ago

Hi @izzyiceberg - still here - haven't had a lot of time to work on my fork recently - I was quite happy with the direction in which it was heading as I feel I've got a fairly generic framework that can be expanded upon as required. I haven't tried to merge and build @fcwu's latest code yet either so need to revisit that. However if you want to check out the progress on this and have any feedback I'd welcome your input.

recolic commented 3 years ago

I think this is a lightweight webVNC image. It's better to keep it simple and light.

Not a good idea to embed some very specific applications.