haugene / docker-transmission-openvpn

Docker container running Transmission torrent client with WebUI over an OpenVPN tunnel
GNU General Public License v3.0
4.12k stars 1.21k forks source link

Problems authenticating with Mullvad #707

Closed avamk closed 5 years ago

avamk commented 5 years ago

Hello,

New Docker user here, so please excuse my ignorance.

I've installed a fresh copy of Scientific Linux 7.6 (derived from RHEL 7.6) and tried to run the haugene/transmission-openvpn container, but it fails to start because when I run sudo docker ps it shows no running containers.

The Linux kernel version is 3.10.0, and the output of docker version is:

Client:
 Version:         1.13.1
 API version:     1.26
 Package version: docker-1.13.1-91.git07f3374.sl7.x86_64
 Go version:      go1.9.4
 Git commit:      07f3374/1.13.1
 Built:           Mon Feb 11 08:56:53 2019
 OS/Arch:         linux/amd64

Server:
 Version:         1.13.1
 API version:     1.26 (minimum version 1.12)
 Package version: docker-1.13.1-91.git07f3374.sl7.x86_64
 Go version:      go1.9.4
 Git commit:      07f3374/1.13.1
 Built:           Mon Feb 11 08:56:53 2019
 OS/Arch:         linux/amd64
 Experimental:    false

The steps I took to set up this container are:

  1. Install a fresh copy of Scientific Linux 7.6 then run sudo yum update to update all default packages.

  2. Install, enable, and start the docker service via sudo yum install docker, sudo systemctl enable docker, and sudo systemctl start docker. I can confirm that the docker service is running with sudo systemctl status docker. (note: I had to use sudo for all docker commands to avoid permission denied errors)

  3. Run the following command derived from this repository's README: sudo docker run --cap-add=NET_ADMIN --device=/dev/net/tun -d -v /home/[my username]/[desired data directory]:/data -v /etc/localtime:/etc/localtime:ro -e OPENVPN_PROVIDER=MULLVAD -e OPENVPN_CONFIG=mullvad_jp_udp -e OPENVPN_USERNAME=[account number] -e OPENVPN_PASSWORD= -e WEBPROXY_ENABLED=false -e LOCAL_NETWORK=10.0.2.0/24 -p 9091:9091 haugene/transmission-openvpn (note that MULLVAD VPN only has user account numbers and no password, and that my machine has a local IP in the form of 10.0.2.*)

  4. The only output from running the command above is something like "f4f55404963f4c68247ea8bc7508c22ae24f71c6331bca41d5733ad4bf7e301f".

  5. Running sudo docker ps shows no running containers.

How do I troubleshoot this or find log files to identify what went wrong? I am new to docker so would appreciate any help you can provide. Thank you!

haugene commented 5 years ago

The output is expected. The -d flag runs the container as daemon and you get the container ID back. That's the long hexa string you're seeing.

sudo docker ps -a would show you the container, which is exited. and sudo docker logs f4f55 would give you the logs (the ID you get back, but you only need enough character to be unique).

Get those logs and see if they make sense. If not. Post them here.

avamk commented 5 years ago

Thank you very much @haugene for getting back to me so quickly! Indeed sudo docker ps -a produced the exited output that you predicted:

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                      PORTS               NAMES
4b6463fa7142        haugene/transmission-openvpn   "dumb-init /etc/op..."   8 seconds ago       Exited (1) 6 seconds ago                        elegant_northcutt

As for sudo docker logs 4b646, it does show an fatal error (I think in the final two lines):

Using OpenVPN provider: MULLVAD
Starting OpenVPN using config mullvad_jp_udp.ovpn
Setting OPENVPN credentials...
adding route to local network 10.0.2.0/24 via 172.17.0.1 dev eth0
Tue Feb 12 14:20:13 2019 Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.
Tue Feb 12 14:20:13 2019 OpenVPN 2.4.6 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Apr 24 2018
Tue Feb 12 14:20:13 2019 library versions: OpenSSL 1.0.2g  1 Mar 2016, LZO 2.08
Tue Feb 12 14:20:13 2019 neither stdin nor stderr are a tty device and you have neither a controlling tty nor systemd - can't ask for 'Enter Auth Password:'.  If you used --daemon, you need to use --askpass to make passphrase-protected keys work, and you can not use --auth-nocache.
Tue Feb 12 14:20:13 2019 Exiting due to fatal error

Does it have something to do with the fact that there is no password for Mullvad VPN? Or is it something else? Thanks for your help!

haugene commented 5 years ago

Yes. This is due to missing credentials. Your environment variables are persisted to a file, and openvpn reads credentials from there. When they're not complete it would try to ask in the terminal, and then it errors.

I need to ask if you're sure that there is no password when connecting to Mullvad on openvpn. Some providers (like PIA that I use) have a set of credentials to log into the account, and there I need to generate openvpn credentials. If you're sure that you don't need it, OPENVPN_PASSWORD needs to be set to "dummy" or something anyways for openvpn not to fail.

avamk commented 5 years ago

Progress! I set a dummy password for OPENVPN_PASSWORD, and OpenVPN appeared to have started successfully.

Unfortunately, there seems to be a bunch of permissions problems.

  1. I've specified a directory in my user's home directory as the data directory for transmission (i.e. -v /home/[my username]/[desired data directory]:/data), but there were lots of permission denied errors.

  2. Trying to access the default transmission web UI via 127.0.0.1:9091 gave me a 403: Forbidden error saying "Unauthorized IP address".

  3. I also tried setting the web proxy with -e WEBPROXY_ENABLED=true -e WEBPROXY_PORT=8888, but trying to use it gave me a "proxy server is refusing connections" error.

  4. Lastly, I tried setting PUID and PGID to that of my user (both happen to be 1000), but that didn't help. BTW, I noticed in the logs below that it defaulted to a username of abc, does this matter?

Could all of this be a SELinux problem or something else? (I know RHEL-derivatives have SELinux enabled by default)

Here is the complete sudo docker logs [contrainer ID]:

Using OpenVPN provider: MULLVAD
Starting OpenVPN using config mullvad_jp_udp.ovpn
Setting OPENVPN credentials...
adding route to local network 10.0.2.0/24 via 172.17.0.1 dev eth0
Tue Feb 12 14:46:46 2019 Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.
Tue Feb 12 14:46:46 2019 OpenVPN 2.4.6 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Apr 24 2018
Tue Feb 12 14:46:46 2019 library versions: OpenSSL 1.0.2g  1 Mar 2016, LZO 2.08
Tue Feb 12 14:46:46 2019 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Tue Feb 12 14:46:46 2019 TCP/UDP: Preserving recently used remote address: [AF_INET]82.102.28.114:1194
Tue Feb 12 14:46:46 2019 Socket Buffers: R=[212992->425984] S=[212992->425984]
Tue Feb 12 14:46:46 2019 UDP link local: (not bound)
Tue Feb 12 14:46:46 2019 UDP link remote: [AF_INET]82.102.28.114:1194
Tue Feb 12 14:46:46 2019 TLS: Initial packet from [AF_INET]82.102.28.114:1194, sid=17fe775d 94038308
Tue Feb 12 14:46:46 2019 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Tue Feb 12 14:46:47 2019 VERIFY OK: depth=2, C=SE, ST=Gotaland, L=Gothenburg, O=Amagicom AB, OU=Mullvad, CN=Mullvad Root CA v2, emailAddress=security@mullvad.net
Tue Feb 12 14:46:47 2019 VERIFY OK: depth=1, C=SE, ST=Gotaland, O=Amagicom AB, OU=Mullvad, CN=Mullvad Transition-Intermediate CA v1, emailAddress=security@mullvad.net
Tue Feb 12 14:46:47 2019 VERIFY KU OK
Tue Feb 12 14:46:47 2019 Validating certificate extended key usage
Tue Feb 12 14:46:47 2019 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Tue Feb 12 14:46:47 2019 VERIFY EKU OK
Tue Feb 12 14:46:47 2019 VERIFY OK: depth=0, C=SE, ST=Gotaland, O=Amagicom AB, OU=Mullvad, CN=jp-tyo-001.mullvad.net, emailAddress=security@mullvad.net
Tue Feb 12 14:46:47 2019 WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1557', remote='link-mtu 1558'
Tue Feb 12 14:46:47 2019 WARNING: 'comp-lzo' is present in remote config but missing in local config, remote='comp-lzo'
Tue Feb 12 14:46:47 2019 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 DHE-RSA-AES256-GCM-SHA384, 4096 bit RSA
Tue Feb 12 14:46:47 2019 [jp-tyo-001.mullvad.net] Peer Connection Initiated with [AF_INET]82.102.28.114:1194
Tue Feb 12 14:46:48 2019 SENT CONTROL [jp-tyo-001.mullvad.net]: 'PUSH_REQUEST' (status=1)
Tue Feb 12 14:46:53 2019 SENT CONTROL [jp-tyo-001.mullvad.net]: 'PUSH_REQUEST' (status=1)
Tue Feb 12 14:46:53 2019 PUSH: Received control message: 'PUSH_REPLY,dhcp-option DNS 10.8.0.1,redirect-gateway def1 bypass-dhcp,route-ipv6 0000::/2,route-ipv6 4000::/2,route-ipv6 8000::/2,route-ipv6 C000::/2,comp-lzo no,route-gateway 10.8.0.1,topology subnet,socket-flags TCP_NODELAY,ifconfig-ipv6 fdda:d0d0:cafe:1194::1000/64 fdda:d0d0:cafe:1194::,ifconfig 10.8.0.2 255.255.0.0,peer-id 0,cipher AES-256-GCM'
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: compression parms modified
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: --socket-flags option modified
Tue Feb 12 14:46:53 2019 NOTE: setsockopt TCP_NODELAY=1 failed
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: --ifconfig/up options modified
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: route options modified
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: route-related options modified
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: peer-id set
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: adjusting link_mtu to 1624
Tue Feb 12 14:46:53 2019 OPTIONS IMPORT: data channel crypto options modified
Tue Feb 12 14:46:53 2019 Data Channel: using negotiated cipher 'AES-256-GCM'
Tue Feb 12 14:46:53 2019 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Tue Feb 12 14:46:53 2019 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Tue Feb 12 14:46:53 2019 ROUTE_GATEWAY 172.17.0.1/255.255.0.0 IFACE=eth0 HWADDR=02:42:ac:11:00:02
Tue Feb 12 14:46:53 2019 GDG6: remote_host_ipv6=n/a
Tue Feb 12 14:46:53 2019 ROUTE6: default_gateway=UNDEF
Tue Feb 12 14:46:53 2019 TUN/TAP device tun0 opened
Tue Feb 12 14:46:53 2019 TUN/TAP TX queue length set to 100
Tue Feb 12 14:46:53 2019 do_ifconfig, tt->did_ifconfig_ipv6_setup=1
Tue Feb 12 14:46:53 2019 /sbin/ip link set dev tun0 up mtu 1500
Tue Feb 12 14:46:53 2019 /sbin/ip addr add dev tun0 10.8.0.2/16 broadcast 10.8.255.255
Tue Feb 12 14:46:53 2019 /sbin/ip -6 addr add fdda:d0d0:cafe:1194::1000/64 dev tun0
Tue Feb 12 14:46:53 2019 /etc/openvpn/tunnelUp.sh tun0 1500 1552 10.8.0.2 255.255.0.0 init
Up script executed with tun0 1500 1552 10.8.0.2 255.255.0.0 init
Updating TRANSMISSION_BIND_ADDRESS_IPV4 to the ip of tun0 : 10.8.0.2
Generating transmission settings.json from env variables
mkdir: cannot create directory '/data/transmission-home': Permission denied
2019/02/12 14:46:53 unable to create open /data/transmission-home/settings.json: no such file or directory
sed'ing True to true
sed: can't read /data/transmission-home/settings.json: No such file or directory
mkdir: cannot create directory '/data/transmission-home': Permission denied
mkdir: cannot create directory '/data/completed': Permission denied
mkdir: cannot create directory '/data/incomplete': Permission denied
mkdir: cannot create directory '/data/watch': Permission denied
Enforcing ownership on transmission config directories
chown: cannot access '/data/transmission-home': No such file or directory
Applying permissions to transmission config directories
Setting owner for transmission paths to 1000:1000
Setting permission for files (644) and directories (755)
chmod: cannot access '/data/transmission-home': No such file or directory
chown: cannot access '/data/completed': No such file or directory
chown: cannot access '/data/incomplete': No such file or directory
chown: cannot access '/data/watch': No such file or directory
chmod: cannot access '/data/completed': No such file or directory
chmod: cannot access '/data/incomplete': No such file or directory
chmod: cannot access '/data/watch': No such file or directory
-------------------------------------
Transmission will run as
-------------------------------------
User name:   abc
User uid:    1000
User gid:    1000
-------------------------------------
STARTING TRANSMISSION
NO PORT UPDATER FOR THIS PROVIDER
Transmission startup script complete.
STARTING TINYPROXY
Setting tinyproxy port to 8888
Couldn't (re)open log file "/data/transmission-home/transmission.log": No such file or directory
Starting tinyproxy: tinyproxy.
Tinyproxy startup script complete.
Tue Feb 12 14:46:53 2019 /sbin/ip route add 82.102.28.114/32 via 172.17.0.1
Tue Feb 12 14:46:53 2019 /sbin/ip route add 0.0.0.0/1 via 10.8.0.1
Tue Feb 12 14:46:53 2019 /sbin/ip route add 128.0.0.0/1 via 10.8.0.1
Tue Feb 12 14:46:53 2019 add_route_ipv6(::/2 -> fdda:d0d0:cafe:1194:: metric -1) dev tun0
Tue Feb 12 14:46:53 2019 /sbin/ip -6 route add ::/2 dev tun0
Tue Feb 12 14:46:53 2019 add_route_ipv6(4000::/2 -> fdda:d0d0:cafe:1194:: metric -1) dev tun0
Tue Feb 12 14:46:53 2019 /sbin/ip -6 route add 4000::/2 dev tun0
Tue Feb 12 14:46:53 2019 add_route_ipv6(8000::/2 -> fdda:d0d0:cafe:1194:: metric -1) dev tun0
Tue Feb 12 14:46:53 2019 /sbin/ip -6 route add 8000::/2 dev tun0
Tue Feb 12 14:46:53 2019 add_route_ipv6(c000::/2 -> fdda:d0d0:cafe:1194:: metric -1) dev tun0
Tue Feb 12 14:46:53 2019 /sbin/ip -6 route add c000::/2 dev tun0
Tue Feb 12 14:46:53 2019 Initialization Sequence Completed

Thank you!

avamk commented 5 years ago

@haugene Update: I temporarily set SELinux to permissive mode (instead of enforcing mode), and transmission within the container started with no problems.

  1. Is there a way to make SELinux in enforcing mode work with this container?

  2. The WEBPROXY still doesn't work and I get a connection refused error when trying access it via a FoxyProxy HTTP proxy. Anything else I can try?

Thanks!

haugene commented 5 years ago

Great stuff 👍

  1. Don't know
  2. a) Have you added port forwards for the http proxy? Port 8888. b) Exec into the container and install telnet, then do telnet localhost 8888, if something is answering there, the rest is networking
avamk commented 5 years ago

OK @haugene more progress! I managed to use sudo docker exec -it [container name] /bin/bash to get into the container. To test it, I first did:

telnet 127.0.0.1

Which got a "connection refused" error (which I expected). Then I tried:

telnet 127.0.0.1 8888

Which gave:

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

I think that means telnet works inside the container??? If so, I also ran ip address in the container and noticed three interfaces: lo for loopback, tun0 which is presumably the VPN (?), and an eth0@if15 with the address 172.17.0.2.

Outside of the container (in the host machine), I also ran ip address and see that there is a docker0 interface that has an IP of 172.17.0.1, which suggested to me that it's the same network as that the container is "plugged in" to. So in my host system's web browser, I changed the HTTP proxy to 172.17.0.2:8888, and it worked!

So far so good, but my question is:

The host system's IP on the "real", local network is 10.0.2.15 (IPs in this network are in the form of 10.0.2.*), and I can see that address on the host's eth0 network interface. For the container, I used the option -e LOCAL_NETWORK=10.0.2.0/24 thinking that the container would then get an IP in that network, such as 10.0.2.16. But as you can see above, the container does not have such an IP, it's only got 172.17.0.2. If so, did I do something wrong when using the LOCAL_NETWORK option? Thanks for your patience!

h45rd commented 5 years ago

I would suggest you have a look at the docker documentation, more specifically the section about networking. It is a quick and very informative read. Once you understand the underlying principles of docker and it's networking, implementing a solution that suits your needs will be a breeze.

Depending on what you want to achieve, you will have to either use one of the -p/-P directives to publish a certain/all container port(s) via the host's IP, forgo docker's internal NATing by using host networking or set up macvlan networks to give your container's network interface it's own MAC address and "direct" access to the hosts physical network.

The environment variable LOCAL_NETWORK is specific to this container and only controls it's internal firewall rules.

avamk commented 5 years ago

Thank you @h45rd , that really helped me understand, and I'll read the documentation you linked to. :)

One last thing: As seen in the log output above, I've managed to set the uid and gid of transmission:

-------------------------------------
Transmission will run as
-------------------------------------
User name:   abc
User uid:    1000
User gid:    1000
-------------------------------------

But the user name became abc. Does that matter? Or is there a way to custom-set the user name, too?

haugene commented 5 years ago

Username doesn't matter. Unix systems care about uid and gid. There is a user created inside the container called abc. When you provide your gid/uid we set those to the abc user.

So user abc inside the container has the same uid/gid as your user outside the container. Files that are written will then have the correct uid/gid and both sides will be happy.

avamk commented 5 years ago

Great! I just tested it and it behaved exactly as you described. BTW, I managed to find a quick (and dirty?) solution to the SELinux problem:

In the command that runs the container, the volume (-v) argument should be appended by :z (which allows other containers to access the volume) or :Z (only allow this container access to the volume). Using the example from this repo's README, it would be -v /your/storage/path/:/data:z (note the :z at the end). Basically this tells docker to manage the SELinux labels behind the scenes to make everything work [1]. Not sure if enough people care about SELinux to append this to the README, but if there is I'm happy to submit a patch for the README.

As a bonus, I'm interested in if a NFS share can be mounted as this container's volume with SELinux enabled, but that's a whole other beast...

Thank you again @haugene for your patience and making this project!

[1] https://www.projectatomic.io/blog/2015/06/using-volumes-with-docker-can-cause-problems-with-selinux/

haugene commented 5 years ago

Cool, and np. Glad you got it working. As for the SELinux stuff - I'm not sure. The focus is more on a "turnkey" solution for many people not too familiar with Docker or Linux. The README has been growing for a while, and I'm thinking of rewriting it to a wiki. I think a section on SELinux in a wiki could be interesting, and if you don't want to wait around for it I'd accept a PR to put it somewhere in the lower end of the README and then migrate it when the time comes.

At least we could rename this issue again so that it's easier for others to find when searching.

h45rd commented 5 years ago

I think best practice (security, statefulness, etc.) would be to handle network mounts directly on the host and pass them to the container as a host volume. If you wanted to mount from within the container, you would probably have to run it at least in privileged mode, among other possible pitfalls. Or did I misunderstand your intention?

avamk commented 5 years ago

@haugene Wiki certainly sounds like a better idea than a long README. I'll be happy to help add a few sentences on SELinux if and when such a wiki is set up.

@h45rd Yes, I meant "mount from within the container", though as you suggested it might be better to have the host mount the NFS share, then pass it to the container. I will experiment, and if successful I will report back!

Thanks.

mrmike1987x commented 5 years ago

Just a heads up if you have not figured this out yet. Mullvad does require a password for openVPN. The password is "m".

From mullvad's guide

"Enter your mullvad account number as in the User name field and enter "m" in the password field"

https://mullvad.net/en/guides/linux-openvpn-installation/

avamk commented 5 years ago

Just a heads up if you have not figured this out yet. Mullvad does require a password for openVPN. The password is "m".

From mullvad's guide

"Enter your mullvad account number as in the User name field and enter "m" in the password field"

https://mullvad.net/en/guides/linux-openvpn-installation/

Thanks for the link. Just to be clear, the password can be anything, not just "m". For example, I've set mine to be "foobar". I suspect whatever you specify as the password is simply ignored...