254 lines
7.5 KiB
Markdown
254 lines
7.5 KiB
Markdown
|
+++
|
|||
|
title = "Playing with containers and Tor"
|
|||
|
author = ["Elia el Lazkani"]
|
|||
|
date = 2021-06-21T21:00:00+02:00
|
|||
|
lastmod = 2021-06-28T00:00:39+02:00
|
|||
|
tags = ["docker", "linux", "ubuntu", "fedora", "proxy", "privoxy"]
|
|||
|
categories = ["container", "text-editors"]
|
|||
|
draft = false
|
|||
|
+++
|
|||
|
|
|||
|
As my followers well know, by now, I am a tinkerer at heart. Why do I do things ? No one knows ! I don't even know.
|
|||
|
|
|||
|
All I know, all I can tell you is that I like to see what can I do with the tools I have at hand. How can I bend them to my will.
|
|||
|
Why, you may ask. The answer is a bit complicated; part of who I am, part of what I do as a DevOps. End line is, this time I was curious.
|
|||
|
|
|||
|
I went down a road that taught me so much more about _containers_, _docker_, _docker-compose_ and even _Linux_ itself.
|
|||
|
|
|||
|
The question I had was simple, **can I run a container only through Tor running in another container?**
|
|||
|
|
|||
|
<!--more-->
|
|||
|
|
|||
|
|
|||
|
## Tor {#tor}
|
|||
|
|
|||
|
I usually like to start topics that I haven't mentioned before with definitions. In this case, what is [Tor](https://2019.www.torproject.org/index.html.en), you may ask ?
|
|||
|
|
|||
|
> Tor is free software and an open network that helps you defend against traffic analysis, a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security.
|
|||
|
|
|||
|
Although that _home_ page is obscure because it was replaced by the new _design_ of the website.
|
|||
|
Although I love what **Tor** has done with all the services they offer, don't get me wrong.
|
|||
|
But giving so much importance on the browser only and leaving the rest for dead when it comes to website, I have to say, I'm a bit sad.
|
|||
|
|
|||
|
Anyway, let's share the love for **Tor** and thank them for the beautiful project they offered humanity.
|
|||
|
|
|||
|
Now that we thanked them, let's abuse it.
|
|||
|
|
|||
|
|
|||
|
### Tor in a container {#tor-in-a-container}
|
|||
|
|
|||
|
The task I set to discover relied on **Tor** being containerized.
|
|||
|
The first thing I do is, simply, not re-invent the wheel.
|
|||
|
Let's find out if someone already took that task.
|
|||
|
|
|||
|
With a litte bit of search, I found the [dperson/torproxy](https://hub.docker.com/r/dperson/torproxy) docker image.
|
|||
|
It isn't ideal but I _believe_ it is written to be rebuilt.
|
|||
|
|
|||
|
Can we run it ?
|
|||
|
|
|||
|
```bash
|
|||
|
docker run -it -p 127.0.0.1:8118:8118 -d dperson/torproxy
|
|||
|
```
|
|||
|
|
|||
|
```bash
|
|||
|
curl -Lx http://localhost:8118 http://jsonip.com/
|
|||
|
```
|
|||
|
|
|||
|
And this is **definitely** not your IP. Don't take _my word_ for it!
|
|||
|
Go to [http://jsonip.com/](http://jsonip.com/) in a browser and see for yourself.
|
|||
|
|
|||
|
Now that we **know** we can run **Tor** in a container effectively, let's kick it up a _notch_.
|
|||
|
|
|||
|
|
|||
|
## docker-compose {#docker-compose}
|
|||
|
|
|||
|
I will be _testing_ and making changes as I go along. For this reason, it's a good idea to use [docker-compose](https://docs.docker.com/compose/) to do this.
|
|||
|
|
|||
|
> Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
|
|||
|
|
|||
|
_Now_ that we saw what the **docker** team has to say about **docker-compose**, let's go ahead and use it.
|
|||
|
|
|||
|
First, let's implement what we just ran _ad-hoc_ in **docker-compose**.
|
|||
|
|
|||
|
```yaml
|
|||
|
---
|
|||
|
version: '3.9'
|
|||
|
services:
|
|||
|
torproxy:
|
|||
|
image: dperson/torproxy
|
|||
|
container_name: torproxy
|
|||
|
restart: unless-stopped
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
## Air-gapped container {#air-gapped-container}
|
|||
|
|
|||
|
The next piece of the puzzle is to figure out **if** and **how** can we create an _air-gapped container_.
|
|||
|
|
|||
|
It turns out, we can create an `internal` network in _docker_ that has no access to the internet.
|
|||
|
|
|||
|
First, the _air-gapped container_.
|
|||
|
|
|||
|
```yaml
|
|||
|
air-gapped:
|
|||
|
image: ubuntu
|
|||
|
container_name: air-gapped
|
|||
|
restart: unless-stopped
|
|||
|
command:
|
|||
|
- bash
|
|||
|
- -c
|
|||
|
- sleep infinity
|
|||
|
networks:
|
|||
|
- no-internet
|
|||
|
```
|
|||
|
|
|||
|
Then comes the network.
|
|||
|
|
|||
|
```yaml
|
|||
|
networks:
|
|||
|
no-internet:
|
|||
|
driver: bridge
|
|||
|
internal: true
|
|||
|
```
|
|||
|
|
|||
|
Let's put it all together in a `docker-compose.yaml` file and run it.
|
|||
|
|
|||
|
```bash
|
|||
|
docker-compose up -d
|
|||
|
```
|
|||
|
|
|||
|
Keep that terminal open, and let's put the _hypothesis_ to the test and see if rises up to be a _theory_.
|
|||
|
|
|||
|
```bash
|
|||
|
docker exec air-gapped apt-get update
|
|||
|
```
|
|||
|
|
|||
|
Aaaaand...
|
|||
|
|
|||
|
```text
|
|||
|
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
|
|||
|
Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
|
|||
|
Temporary failure resolving 'security.ubuntu.com'
|
|||
|
Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
|
|||
|
Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
Err:4 http://archive.ubuntu.com/ubuntu focal-backports InRelease
|
|||
|
Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
Reading package lists...
|
|||
|
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-updates/InRelease Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-backports/InRelease Temporary failure resolving 'archive.ubuntu.com'
|
|||
|
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/focal-security/InRelease Temporary failure resolving 'security.ubuntu.com'
|
|||
|
W: Some index files failed to download. They have been ignored, or old ones used instead.
|
|||
|
```
|
|||
|
|
|||
|
looks like it's real peeps, **hooray** !
|
|||
|
|
|||
|
|
|||
|
## Putting everything together {#putting-everything-together}
|
|||
|
|
|||
|
Okay, now let's put everything together. The list of changes we need to make are minimal.
|
|||
|
First, I will list them, then I will simply write them out in **docker-compose**.
|
|||
|
|
|||
|
- Create an `internet` network for the **Tor** container
|
|||
|
- Attach the `internet` network to the **Tor** container
|
|||
|
- Attach the `no-internet` network to the **Tor** container so that our _air-gapped_ container can access it.
|
|||
|
|
|||
|
Let's get to work.
|
|||
|
|
|||
|
```yaml
|
|||
|
---
|
|||
|
version: '3.9'
|
|||
|
services:
|
|||
|
|
|||
|
torproxy:
|
|||
|
image: dperson/torproxy
|
|||
|
container_name: torproxy
|
|||
|
restart: unless-stopped
|
|||
|
networks:
|
|||
|
- no-internet
|
|||
|
- internet
|
|||
|
|
|||
|
air-gapped:
|
|||
|
image: ubuntu
|
|||
|
container_name: air-gapped
|
|||
|
restart: unless-stopped
|
|||
|
command:
|
|||
|
- bash
|
|||
|
- -c
|
|||
|
- sleep infinity
|
|||
|
networks:
|
|||
|
- no-internet
|
|||
|
|
|||
|
networks:
|
|||
|
no-internet:
|
|||
|
driver: bridge
|
|||
|
internal: true
|
|||
|
internet:
|
|||
|
driver: bridge
|
|||
|
internal: false
|
|||
|
```
|
|||
|
|
|||
|
Run everything.
|
|||
|
|
|||
|
```bash
|
|||
|
docker-compose up -d
|
|||
|
```
|
|||
|
|
|||
|
Yes, this will run it in the background and there is **no** need for you to open another terminal.
|
|||
|
It's always _good_ to know **both** ways. Anyway, let's test.
|
|||
|
|
|||
|
let's `exec` into the container.
|
|||
|
|
|||
|
```bash
|
|||
|
docker exec -it air-gapped bash
|
|||
|
```
|
|||
|
|
|||
|
Then we configure `apt` to use our `torproxy` service.
|
|||
|
|
|||
|
```bash
|
|||
|
echo 'Acquire::http::Proxy "http://torproxy:8118/";' > /etc/apt/apt.conf.d/proxy
|
|||
|
echo "export HTTP_PROXY=http://torproxy:8118/" >> ~/.bashrc
|
|||
|
echo "export HTTPS_PROXY=http://torproxy:8118/" >> ~/.bashrc
|
|||
|
export HTTP_PROXY=http://torproxy:8118/
|
|||
|
export HTTPS_PROXY=http://torproxy:8118/
|
|||
|
apt-get update
|
|||
|
apt-get upgrade -y
|
|||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y curl
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
## Harvesting the fruits of our labour {#harvesting-the-fruits-of-our-labour}
|
|||
|
|
|||
|
First, we **always** check if everything is set correctly.
|
|||
|
|
|||
|
While inside the container, we check the _environment variables_.
|
|||
|
|
|||
|
```bash
|
|||
|
env | grep HTTP
|
|||
|
```
|
|||
|
|
|||
|
You should see.
|
|||
|
|
|||
|
```text
|
|||
|
HTTPS_PROXY=http://torproxy:8118/
|
|||
|
HTTP_PROXY=http://torproxy:8118/
|
|||
|
```
|
|||
|
|
|||
|
Then, we curl our **IP**.
|
|||
|
|
|||
|
```bash
|
|||
|
curl https://jsonip.com/
|
|||
|
```
|
|||
|
|
|||
|
And that is also not your **IP**.
|
|||
|
|
|||
|
It works !
|
|||
|
|
|||
|
|
|||
|
## Conclusion {#conclusion}
|
|||
|
|
|||
|
Is it possible to route a container through another **Tor** container ?
|
|||
|
|
|||
|
The answer is _obviously_ **Yes** and this is the way to do it. Enjoy.
|