From charlesreid1

m (Replacing charlesreid1.com:3000 with git.charlesreid1.com)
 
(25 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Wifi Boat Overview=
=Wifi Pod Overview=


==Services==
==Services==


UGR wifi boat ships the following services in Docker containers:
UGR wifi pod ships the following services in Docker containers:
* stunnel server
* stunnel server
* web server (hello world, report, file management)
* web server (hello world, report, file management)
Line 13: Line 13:


Please make a note:
Please make a note:
* The UGR wifi boat does not receive or process raw packet data. The Raspberry Pi device will extract network data, either by using a tool that extracts relevant information or by running a tool like scapy or aircrack on the Raspberry Pi to capture and process network data local to the Pi. Only small, digested, processed data is sent back to the server.
* The UGR wifi pod does not receive or process raw packet data. The Raspberry Pi device will extract network data, either by using a tool that extracts relevant information or by running a tool like scapy or aircrack on the Raspberry Pi to capture and process network data local to the Pi. Only small, digested, processed data is sent back to the server.


==Getting Set Up For The Boat==
==Getting Set Up For The Pod==


Make sure your node is all set: [[Deployment/New Node Checklist]]
Make sure your node is all set: [[Deployment/New Node Checklist]]
Line 21: Line 21:
Make sure docker installed: [[Docker/Installing]]
Make sure docker installed: [[Docker/Installing]]


=Boat Containers=
=Pod Containers=


==Stunnel==
==Stunnel==
Line 28: Line 28:


Here's how the Stunnel Docker container will be set up:
Here's how the Stunnel Docker container will be set up:
* Create a Dockerfile or download a prepared one (they are easy enough to make that it is worth doing yourself.)
* Create a Dockerfile (you can download a prepared one, but they are easy enough to make that it is worth doing yourself.)
* Make a Docker Stunnel container image
* Make a Docker Stunnel container image
* Run a Docker Stunnel container image
* Run a Docker Stunnel container image
Line 34: Line 34:
* Ensure that networking with host is working and configured properly
* Ensure that networking with host is working and configured properly


===Create Dockerfile===
===Get Files===


Get the Dockerfile from the git.charlesreid1.com repo: https://git.charlesreid1.com/docker/d-stunnel


<pre>
$ mkdir ~/docker
$ cd ~/docker
$ git clone https://git.charlesreid1.com/docker/d-stunnel
$ cd d-stunnel
</pre>
This will also have some supporting scripts and example config files.
===Create Certificate===
Next step is to create a certificate.
See [[Stunnel#Certificate]]
Option 1 is to use Let's Encrypt (recommended). Use the [[LetsEncrypt]] page and the <code>generate_letsencrypt_cert.sh</code> script in the d-stunnel repository.
Option 2 is to use a self-signed certificate. See [[RaspberryPi/SSH Stunnel]] for details and use the <code>generate_ss_cert.sh</code> script in the d-stunnel repository.
Link to d-stunnel repository: https://git.charlesreid1.com/docker/d-stunnel
===Configure Client===
Next, configure your client stunnel using stunnel.conf. On a Mac, this will go in <code>/usr/local/etc/stunnel/stunnel.conf</code>. On Ubuntu/Linux, it will go in <code>/etc/stunnel/stunnel.conf</code>. The client machine's configuration should map ports matching whatever you're trying to do. There are some examples in the docker/d-stunnel repository on git.charlesreid1.com: https://git.charlesreid1.com/docker/d-stunnel
These pages have sample client configuration files:
* [[Stunnel/SSH]] - tunneling SSH over port 443
* [[Stunnel/Scp]] - tunneling secure copy over port 443
* [[Stunnel/HTTP]] - tunneling HTTP traffic over port 8000
====Configure Raspberry Pi Client====
Stunnel client config files for Raspberry Pi: https://git.charlesreid1.com/rpi/p-stunnel
===Configure Server===
Configure the server by setting the server's stunnel.conf file to match the client's and whatever service you're trying to access.


These pages have sample server configuration files:


* [[Stunnel/SSH]]
* [[Stunnel/Scp]]
* [[Stunnel/HTTP]]


This is the configuration file that will be copied into the Docker container and used with its stunnel instance. It is recommended you check out https://git.charlesreid1.com/docker/d-stunnel and put it into the d-stunnel/ directory.


===TLDR===


===Make Container===
You have to map ports from container to host, and your host and container have to share the same network interface. Here is what the final run command looks like:


<pre>
<pre>
$ mkdir ~/docker
docker run \
$ cd ~/docker
--network=host \
$ git clone https://github.com/taskworld/docker-stunnel.git
-p 443:443 -p 22:22 \
$ cd docker-stunnel
-ti cmr_stunnel \
$ docker build -t cmr_stunnel .
/bin/bash
</pre>
</pre>


This last command will build an image called cmr_stunnel, using the Dockerfile that's in the directory. The image itself is added to Docker's internal images directory, so we don't have to worry about image files floating around.
===Build Docker stunnel container image from Dockerfile===
 
From the git repo checked out above, which contains a Dockerfile, run docker build to build the image:


{{Scroll box|
<pre>
<pre>
$ docker build -t cmr_stunnel .
$ docker build -t cmr_stunnel .
Sending build context to Docker daemon 53.76 kB
Step 1/4 : FROM ubuntu
latest: Pulling from library/ubuntu
d54efb8db41d: Pull complete
f8b845f45a87: Pull complete
e8db7bf7c39f: Pull complete
9654c40e9079: Pull complete
6d9ef359eaaa: Pull complete
Digest: sha256:dd7808d8792c9841d0b460122f1acf0a2dd1f56404f8d1e56298048885e45535
Status: Downloaded newer image for ubuntu:latest
---> 0ef2e08ed3fa
Step 2/4 : RUN apt-get update
---> Running in 39b44f53986d
Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
kGet:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial/main Sources [1103 kB]
Get:5 http://archive.ubuntu.com/ubuntu xenial/restricted Sources [5179 B]
Get:6 http://archive.ubuntu.com/ubuntu xenial/universe Sources [9802 kB]
Get:7 http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1558 kB]
Get:8 http://archive.ubuntu.com/ubuntu xenial/restricted amd64 Packages [14.1 kB]
Get:9 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9827 kB]
Get:10 http://archive.ubuntu.com/ubuntu xenial-updates/main Sources [299 kB]
Get:11 http://archive.ubuntu.com/ubuntu xenial-updates/restricted Sources [3202 B]
Get:12 http://archive.ubuntu.com/ubuntu xenial-updates/universe Sources [183 kB]
Get:13 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [631 kB]
Get:14 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [13.2 kB]
Get:15 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [560 kB]
Get:16 http://archive.ubuntu.com/ubuntu xenial-security/main Sources [78.6 kB]
Get:17 http://archive.ubuntu.com/ubuntu xenial-security/restricted Sources [2779 B]
Get:18 http://archive.ubuntu.com/ubuntu xenial-security/universe Sources [28.5 kB]
Get:19 http://archive.ubuntu.com/ubuntu xenial-security/main amd64 Packages [290 kB]
Get:20 http://archive.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [12.8 kB]
Get:21 http://archive.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [120 kB]
Fetched 25.0 MB in 5s (4806 kB/s)
Reading package lists...
---> 538192504900
Removing intermediate container 39b44f53986d
Step 3/4 : RUN apt-get -y install stunnel
---> Running in b4054aeb5ffc
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  ifupdown iproute2 isc-dhcp-client isc-dhcp-common libatm1 libdns-export162
  libgdbm3 libisc-export160 libmnl0 libperl5.22 libssl1.0.0 libwrap0
  libxtables11 netbase openssl perl perl-modules-5.22 rename tcpd
Suggested packages:
  ppp rdnssd iproute2-doc resolvconf avahi-autoipd isc-dhcp-client-ddns
  apparmor ca-certificates perl-doc libterm-readline-gnu-perl
  | libterm-readline-perl-perl make logcheck-database
The following NEW packages will be installed:
  ifupdown iproute2 isc-dhcp-client isc-dhcp-common libatm1 libdns-export162
  libgdbm3 libisc-export160 libmnl0 libperl5.22 libssl1.0.0 libwrap0
  libxtables11 netbase openssl perl perl-modules-5.22 rename stunnel4 tcpd
0 upgraded, 20 newly installed, 0 to remove and 6 not upgraded.
Need to get 9866 kB of archives.
After this operation, 49.7 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu xenial/main amd64 libatm1 amd64 1:2.5.1-1.5 [24.2 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial/main amd64 libmnl0 amd64 1.0.3-5 [12.0 kB]
Get:3 http://archive.ubuntu.com/ubuntu xenial/main amd64 libgdbm3 amd64 1.8.3-13.1 [16.9 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial/main amd64 libwrap0 amd64 7.6.q-25 [46.2 kB]
Get:5 http://archive.ubuntu.com/ubuntu xenial/main amd64 perl-modules-5.22 all 5.22.1-9 [2641 kB]
Get:6 http://archive.ubuntu.com/ubuntu xenial/main amd64 libperl5.22 amd64 5.22.1-9 [3371 kB]
Get:7 http://archive.ubuntu.com/ubuntu xenial/main amd64 perl amd64 5.22.1-9 [237 kB]
Get:8 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libssl1.0.0 amd64 1.0.2g-1ubuntu4.6 [1082 kB]
Get:9 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 openssl amd64 1.0.2g-1ubuntu4.6 [492 kB]
Get:10 http://archive.ubuntu.com/ubuntu xenial/main amd64 netbase all 5.3 [12.9 kB]
Get:11 http://archive.ubuntu.com/ubuntu xenial/universe amd64 stunnel4 amd64 3:5.30-1 [146 kB]
Get:12 http://archive.ubuntu.com/ubuntu xenial/main amd64 iproute2 amd64 4.3.0-1ubuntu3 [522 kB]
Get:13 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 ifupdown amd64 0.8.10ubuntu1.2 [54.9 kB]
Get:14 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libisc-export160 amd64 1:9.10.3.dfsg.P4-8ubuntu1.5 [153 kB]
Get:15 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libdns-export162 amd64 1:9.10.3.dfsg.P4-8ubuntu1.5 [665 kB]
Get:16 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 isc-dhcp-client amd64 4.3.3-5ubuntu12.6 [223 kB]
Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 isc-dhcp-common amd64 4.3.3-5ubuntu12.6 [105 kB]
Get:18 http://archive.ubuntu.com/ubuntu xenial/main amd64 libxtables11 amd64 1.6.0-2ubuntu3 [27.2 kB]
Get:19 http://archive.ubuntu.com/ubuntu xenial/main amd64 rename all 0.20-4 [12.0 kB]
Get:20 http://archive.ubuntu.com/ubuntu xenial/main amd64 tcpd amd64 7.6.q-25 [23.0 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 9866 kB in 1s (5131 kB/s)
Selecting previously unselected package libatm1:amd64.
(Reading database ... 7256 files and directories currently installed.)
Preparing to unpack .../libatm1_1%3a2.5.1-1.5_amd64.deb ...
Unpacking libatm1:amd64 (1:2.5.1-1.5) ...
Selecting previously unselected package libmnl0:amd64.
Preparing to unpack .../libmnl0_1.0.3-5_amd64.deb ...
Unpacking libmnl0:amd64 (1.0.3-5) ...
Selecting previously unselected package libgdbm3:amd64.
Preparing to unpack .../libgdbm3_1.8.3-13.1_amd64.deb ...
Unpacking libgdbm3:amd64 (1.8.3-13.1) ...
Selecting previously unselected package libwrap0:amd64.
Preparing to unpack .../libwrap0_7.6.q-25_amd64.deb ...
Unpacking libwrap0:amd64 (7.6.q-25) ...
Selecting previously unselected package perl-modules-5.22.
Preparing to unpack .../perl-modules-5.22_5.22.1-9_all.deb ...
Unpacking perl-modules-5.22 (5.22.1-9) ...
Selecting previously unselected package libperl5.22:amd64.
Preparing to unpack .../libperl5.22_5.22.1-9_amd64.deb ...
Unpacking libperl5.22:amd64 (5.22.1-9) ...
Selecting previously unselected package perl.
Preparing to unpack .../perl_5.22.1-9_amd64.deb ...
Unpacking perl (5.22.1-9) ...
Selecting previously unselected package libssl1.0.0:amd64.
Preparing to unpack .../libssl1.0.0_1.0.2g-1ubuntu4.6_amd64.deb ...
Unpacking libssl1.0.0:amd64 (1.0.2g-1ubuntu4.6) ...
Selecting previously unselected package openssl.
Preparing to unpack .../openssl_1.0.2g-1ubuntu4.6_amd64.deb ...
Unpacking openssl (1.0.2g-1ubuntu4.6) ...
Selecting previously unselected package netbase.
Preparing to unpack .../archives/netbase_5.3_all.deb ...
Unpacking netbase (5.3) ...
Selecting previously unselected package stunnel4.
Preparing to unpack .../stunnel4_3%3a5.30-1_amd64.deb ...
Unpacking stunnel4 (3:5.30-1) ...
Selecting previously unselected package iproute2.
Preparing to unpack .../iproute2_4.3.0-1ubuntu3_amd64.deb ...
Unpacking iproute2 (4.3.0-1ubuntu3) ...
Selecting previously unselected package ifupdown.
Preparing to unpack .../ifupdown_0.8.10ubuntu1.2_amd64.deb ...
Unpacking ifupdown (0.8.10ubuntu1.2) ...
Selecting previously unselected package libisc-export160.
Preparing to unpack .../libisc-export160_1%3a9.10.3.dfsg.P4-8ubuntu1.5_amd64.deb ...
Unpacking libisc-export160 (1:9.10.3.dfsg.P4-8ubuntu1.5) ...
Selecting previously unselected package libdns-export162.
Preparing to unpack .../libdns-export162_1%3a9.10.3.dfsg.P4-8ubuntu1.5_amd64.deb ...
Unpacking libdns-export162 (1:9.10.3.dfsg.P4-8ubuntu1.5) ...
Selecting previously unselected package isc-dhcp-client.
Preparing to unpack .../isc-dhcp-client_4.3.3-5ubuntu12.6_amd64.deb ...
Unpacking isc-dhcp-client (4.3.3-5ubuntu12.6) ...
Selecting previously unselected package isc-dhcp-common.
Preparing to unpack .../isc-dhcp-common_4.3.3-5ubuntu12.6_amd64.deb ...
Unpacking isc-dhcp-common (4.3.3-5ubuntu12.6) ...
Selecting previously unselected package libxtables11:amd64.
Preparing to unpack .../libxtables11_1.6.0-2ubuntu3_amd64.deb ...
Unpacking libxtables11:amd64 (1.6.0-2ubuntu3) ...
Selecting previously unselected package rename.
Preparing to unpack .../archives/rename_0.20-4_all.deb ...
Unpacking rename (0.20-4) ...
Selecting previously unselected package tcpd.
Preparing to unpack .../tcpd_7.6.q-25_amd64.deb ...
Unpacking tcpd (7.6.q-25) ...
Processing triggers for libc-bin (2.23-0ubuntu5) ...
Processing triggers for systemd (229-4ubuntu16) ...
Setting up libatm1:amd64 (1:2.5.1-1.5) ...
Setting up libmnl0:amd64 (1.0.3-5) ...
Setting up libgdbm3:amd64 (1.8.3-13.1) ...
Setting up libwrap0:amd64 (7.6.q-25) ...
Setting up perl-modules-5.22 (5.22.1-9) ...
Setting up libperl5.22:amd64 (5.22.1-9) ...
Setting up perl (5.22.1-9) ...
update-alternatives: using /usr/bin/prename to provide /usr/bin/rename (rename) in auto mode
Setting up libssl1.0.0:amd64 (1.0.2g-1ubuntu4.6) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
Setting up openssl (1.0.2g-1ubuntu4.6) ...
Setting up netbase (5.3) ...
Setting up stunnel4 (3:5.30-1) ...
Warning: The home dir /var/run/stunnel4 you specified can't be accessed: No such file or directory
Adding system user `stunnel4' (UID 105) ...
Adding new group `stunnel4' (GID 106) ...
Adding new user `stunnel4' (UID 105) with group `stunnel4' ...
Not creating home directory `/var/run/stunnel4'.
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Setting up iproute2 (4.3.0-1ubuntu3) ...
Setting up ifupdown (0.8.10ubuntu1.2) ...
Creating /etc/network/interfaces.
Setting up libisc-export160 (1:9.10.3.dfsg.P4-8ubuntu1.5) ...
Setting up libdns-export162 (1:9.10.3.dfsg.P4-8ubuntu1.5) ...
Setting up isc-dhcp-client (4.3.3-5ubuntu12.6) ...
Setting up isc-dhcp-common (4.3.3-5ubuntu12.6) ...
Setting up libxtables11:amd64 (1.6.0-2ubuntu3) ...
Setting up rename (0.20-4) ...
update-alternatives: using /usr/bin/file-rename to provide /usr/bin/rename (rename) in auto mode
Setting up tcpd (7.6.q-25) ...
Processing triggers for libc-bin (2.23-0ubuntu5) ...
Processing triggers for systemd (229-4ubuntu16) ...
---> 2b56eadc5b36
Removing intermediate container b4054aeb5ffc
Step 4/4 : CMD stunnel
---> Running in aa489cb72225
---> 2b197f506e02
Removing intermediate container aa489cb72225
Successfully built 2b197f506e02
</pre>
</pre>
}}


Once that's finished we should be able to see the new image in the list of docker images available:
This may take a minute. Once that's finished make sure Docker now lists the image:


<pre>
<pre>
Line 255: Line 115:
===Networking/Ports Configuration===
===Networking/Ports Configuration===


The way Stunnel works is to expose 1 port externally (for clients to connect on), typically 443. This is the port on which all of the SSL-wrapped traffic will pass.
First, let's talk about how stunnel works, independently of Docker.
 
Stunnel will also expose that traffic to some other port, typically a local port - the external, encrypted traffic passes through stunnel and is stripped of the encryption layer, and is forwarded in to a local port, usually a local service that is not externally exposed.


We will set up the Stunnel container to listen on port 443 for encrypted traffic. That traffic will be passed along to local port 8443, where we will have a Python web server with a simple "HALLO WURLD" page listening.
Stunnel will expose one port externally (for clients to connect on). Typically, this is 443, but it can be any port. This is the port on which all of the SSL-wrapped traffic will pass. It then forwards that traffic on to another local port (typically this is a port with a service that is not externally exposed, but that isn't a requirement). The configuration file determines which local port the stunnel server will map traffic to.


Start with the configuration file for stunnel. It will live in <code>/etc/stunnel/stunnel.conf</code>. Here is what we will use:
Now let's talk about how to do this when running stunnel from within Docker.


<pre>
The Docker container will be running an stunnel service that listens on some port (say 443) and forwards that traffic on to some other port. The hitch is, Docker containers are not, by default, connected to host ports, so we need to explicitly link ports from the container to ports on the host.
output = /var/log/stunnel4/stunnel.log
cert=/etc/stunnel/stunnel.pem
key=/etc/stunnel/stunnel.pem
pid=/var/run/stunnel4/stunnel.pid
client=yes
[ssh]
accept = 443
connect = 127.0.0.1:8443
</pre>


This will accept inbound encrypted connections on 443, and will decrypt them and forward them along to local port 8443, where Python will be listening. Because this is a server, we are emulating inbound requests, just like a web server. Stunnel will be wrapping HTTP requests from a browser with SSL.
The first port we want to map is the port on which stunnel is listening - if stunnel listens on 443 inside the container, we can make that available on the host port 443 by specifying <code>-p 443:443</code> when we run the docker container.  


Now that we have an Stunnel configuration file ready to go we can start the stunnel docker image and use this configuration file for that stunnel instance.
However, we also need to map the destination port, where stunnel is forwarding traffic to, to the host destination port. If we use a simple example of tunneling SSH traffic through stunnel, we need to link the stunnel Docker container's port 22 to the host's port 22.


===Loading Image with Correct Config Files===
Finally, we also need the docker container to share a networking interface with the host - otherwise, the host needs to dedicate a separate listener (on the host) listening to each of the ports that we map. This creates a conflict if there is already an SSH server listening on the port we're trying to bind to. Since these two services are just talking to each other, they should be able to bind to the same network interface. Use the <code>--network=host</code> to force the container and host to share the same network interface.


[[Docker/Boats/Wifi/ConfigFail1]]
See [[Docker/Networking]] for the setup and configuration files for tunneling SSH over an stunnel SSL connection on port 443.


===Load Image with Networking/Ports Configured===
Here is what the final run command looks like:


<pre>
docker run \
--network=host \
-p 443:443 -p 22:22 \
-ti cmr_stunnel \
/bin/bash
</pre>


===Links===
===Run the Docker stunnel container image===


Stunnel documentation (man page): https://www.stunnel.org/static/stunnel.html
You can fire up the docker container and get a Bash shell:


Stunnel Dockerfile that is about as simple as it is going to get: https://github.com/taskworld/docker-stunnel/blob/master/Dockerfile
<pre>
 
docker run \
Note: ufw needs to accept, not drop, traffic: [https://www.digitalocean.com/community/tutorials/docker-explained-how-to-create-docker-containers-running-memcached]
--network=host \
 
-p 443:443 -p 22:22 \
Note: container needs to bind to 0.0.0.0, not localhost, or it won't be accessible outside the container: [http://serverfault.com/questions/714340/ssh-tunnel-to-docker-container]
-ti cmr_stunnel \
/bin/bash
</pre>


Running the stunnel command should work okay.


=Flags=


{{DockerFlag}}


[[Category:Docker]]
[[Category:Docker]]
[[Category:Boats]]
[[Category:Docker Pods]]
[[Category:Wireless]]
[[Category:Wireless]]



Latest revision as of 03:22, 9 October 2019

Wifi Pod Overview

Services

UGR wifi pod ships the following services in Docker containers:

  • stunnel server
  • web server (hello world, report, file management)
  • https web server 9hello world)
  • mongodb database

Stretch goals:

  • Data to inform the server about processes that are running? How to install a program that runs on the pi and tries to call home and send updates on information going on with the operating system, running processes, etc.?

Please make a note:

  • The UGR wifi pod does not receive or process raw packet data. The Raspberry Pi device will extract network data, either by using a tool that extracts relevant information or by running a tool like scapy or aircrack on the Raspberry Pi to capture and process network data local to the Pi. Only small, digested, processed data is sent back to the server.

Getting Set Up For The Pod

Make sure your node is all set: Deployment/New Node Checklist

Make sure docker installed: Docker/Installing

Pod Containers

Stunnel

Stunnel is a server/client service that allows arbitrary traffic to be transported through an encrypted HTTP over SSL layer (HTTPS). Since port 443 is usually open even on locked-down networks, this is an extremely handy tool for punching through firewalls. Due to the nature of encrypted traffic, the contents of an HTTPS packet cannot be inspected, so services that would otherwise be blocked due to their protocols, like SSH, can pass in and out of the network just fine by being wrapped up in HTTPS.

Here's how the Stunnel Docker container will be set up:

  • Create a Dockerfile (you can download a prepared one, but they are easy enough to make that it is worth doing yourself.)
  • Make a Docker Stunnel container image
  • Run a Docker Stunnel container image
  • Ensure that Stunnel is working and configured properly (ignoring network)
  • Ensure that networking with host is working and configured properly

Get Files

Get the Dockerfile from the git.charlesreid1.com repo: https://git.charlesreid1.com/docker/d-stunnel

$ mkdir ~/docker
$ cd ~/docker
$ git clone https://git.charlesreid1.com/docker/d-stunnel
$ cd d-stunnel

This will also have some supporting scripts and example config files.

Create Certificate

Next step is to create a certificate.

See Stunnel#Certificate

Option 1 is to use Let's Encrypt (recommended). Use the LetsEncrypt page and the generate_letsencrypt_cert.sh script in the d-stunnel repository.

Option 2 is to use a self-signed certificate. See RaspberryPi/SSH Stunnel for details and use the generate_ss_cert.sh script in the d-stunnel repository.

Link to d-stunnel repository: https://git.charlesreid1.com/docker/d-stunnel

Configure Client

Next, configure your client stunnel using stunnel.conf. On a Mac, this will go in /usr/local/etc/stunnel/stunnel.conf. On Ubuntu/Linux, it will go in /etc/stunnel/stunnel.conf. The client machine's configuration should map ports matching whatever you're trying to do. There are some examples in the docker/d-stunnel repository on git.charlesreid1.com: https://git.charlesreid1.com/docker/d-stunnel

These pages have sample client configuration files:

Configure Raspberry Pi Client

Stunnel client config files for Raspberry Pi: https://git.charlesreid1.com/rpi/p-stunnel

Configure Server

Configure the server by setting the server's stunnel.conf file to match the client's and whatever service you're trying to access.

These pages have sample server configuration files:

This is the configuration file that will be copied into the Docker container and used with its stunnel instance. It is recommended you check out https://git.charlesreid1.com/docker/d-stunnel and put it into the d-stunnel/ directory.

TLDR

You have to map ports from container to host, and your host and container have to share the same network interface. Here is what the final run command looks like:

docker run \
	--network=host \
	-p 443:443 -p 22:22 \
	-ti cmr_stunnel \
	/bin/bash

Build Docker stunnel container image from Dockerfile

From the git repo checked out above, which contains a Dockerfile, run docker build to build the image:

$ docker build -t cmr_stunnel .

This may take a minute. Once that's finished make sure Docker now lists the image:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
cmr_stunnel         latest              2b197f506e02        59 seconds ago      219 MB

Networking/Ports Configuration

First, let's talk about how stunnel works, independently of Docker.

Stunnel will expose one port externally (for clients to connect on). Typically, this is 443, but it can be any port. This is the port on which all of the SSL-wrapped traffic will pass. It then forwards that traffic on to another local port (typically this is a port with a service that is not externally exposed, but that isn't a requirement). The configuration file determines which local port the stunnel server will map traffic to.

Now let's talk about how to do this when running stunnel from within Docker.

The Docker container will be running an stunnel service that listens on some port (say 443) and forwards that traffic on to some other port. The hitch is, Docker containers are not, by default, connected to host ports, so we need to explicitly link ports from the container to ports on the host.

The first port we want to map is the port on which stunnel is listening - if stunnel listens on 443 inside the container, we can make that available on the host port 443 by specifying -p 443:443 when we run the docker container.

However, we also need to map the destination port, where stunnel is forwarding traffic to, to the host destination port. If we use a simple example of tunneling SSH traffic through stunnel, we need to link the stunnel Docker container's port 22 to the host's port 22.

Finally, we also need the docker container to share a networking interface with the host - otherwise, the host needs to dedicate a separate listener (on the host) listening to each of the ports that we map. This creates a conflict if there is already an SSH server listening on the port we're trying to bind to. Since these two services are just talking to each other, they should be able to bind to the same network interface. Use the --network=host to force the container and host to share the same network interface.

See Docker/Networking for the setup and configuration files for tunneling SSH over an stunnel SSL connection on port 443.

Here is what the final run command looks like:

docker run \
	--network=host \
	-p 443:443 -p 22:22 \
	-ti cmr_stunnel \
	/bin/bash

Run the Docker stunnel container image

You can fire up the docker container and get a Bash shell:

docker run \
	--network=host \
	-p 443:443 -p 22:22 \
	-ti cmr_stunnel \
	/bin/bash

Running the stunnel command should work okay.

Flags