Hosting a static site quickly as a Tor hidden service with docker-compose

This sample bakes a private key into the resulting docker image that contains the Tor daemon. The only thing you need to edit are args and volumes in docker-compose.yml.

docker-compose.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3"
services:
hidden_service:
# we want to pass in the details of our hs AT BUILD TIME..
build:
context: .
dockerfile: Dockerfile.hidden_service
args:
TARGET_PORT: 8123
ONION_HOSTNAME: abcdefghijklmnop.onion
ONION_PRIVATE_KEY: -----BEGIN RSA PRIVATE KEY-----\nMIIC[REDACTED]\n...\n...\n-----END RSA PRIVATE KEY-----
restart: always
web_host:
image: nginx:alpine
volumes:
- "~/my/static_site:/usr/share/nginx/html"
ports:
- "8123:80"
restart: always

ONION_PRIVATE_KEY is what belongs in /var/lib/tor/hidden_service/private_key, ONION_HOSTNAME is what belongs in /var/lib/tor/hidden_service/hostname.

Dockerfile.hidden_service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
FROM alpine:latest
ARG TARGET_PORT
ARG ONION_HOSTNAME
ARG ONION_PRIVATE_KEY
RUN apk update && apk add bind-tools && apk add curl && apk add \
tor \
--update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ \
&& rm -rf /var/cache/apk/*
EXPOSE 9050
RUN mkdir -p /etc/tor
RUN chown -R tor /etc/tor
RUN echo $'HiddenServiceDir /var/lib/tor/hidden_service \n\
HiddenServicePort 80 web_host:80' > /etc/tor/torrc
run mkdir -p /var/lib/tor/hidden_service
run chmod 700 /var/lib/tor/hidden_service
RUN echo -e $ONION_PRIVATE_KEY > /var/lib/tor/hidden_service/private_key
# RUN cat /var/lib/tor/hidden_service/private_key
RUN chmod 600 /var/lib/tor/hidden_service/private_key
RUN echo ${ONION_HOSTNAME} > /var/lib/tor/hidden_service/hostname
run chown -R tor /var/lib/tor/hidden_service
USER tor
ENTRYPOINT [ "tor" ]
CMD [ "-f", "/etc/tor/torrc" ]

Dockerfile.web_host

1
FROM nginx:alpine

Copy these three into a folder, then do docker-compose up from within said folder.

First Foray into MIPS Assembly

Task: Print Hello World 10 times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.data
hello_str: .asciiz "Hello World!n"
.text
.globl main
main:
subu $sp, $sp, 4 # create a word on the stack
sw $ra, 4($sp) # store the return address
# put main function code here
li $t0, 10 #the number at which we want to end our loop.
li $t1, 0 #start counting from 0; we are going to increment this counter 10 times.
li $v0, 4 # set $v0 to print_string; http://courses.missouristate.edu/kenvollmar/mars/Help/SyscallHelp.html
la $a0, hello_str # load the string
loop:
beq $t1, $t0, end # if t1 == 10 we are done
syscall # execute the function described by
addi $t1, $t1, 1 # add 1 to t1
j loop # jump back to the top
end:
li $v0, 10
syscall

recorded_compressed

First foray into Haskell.

Defining the combination formula (nCr) recursively.

1
2
3
4
5
Prelude> let ncr n k | k == 0 = 1 | n == k = 1 | otherwise = ncr (n-1) k + ncr (n-1) (k-1)
Prelude> ncr 3 2
3
Prelude> ncr 15 4
1365

This works because http://www.cs.nott.ac.uk/~vxc/g51mcs/ch05_combinatorics.pdf , page 9.

How I understand RSA

wpid-wp-1402514522645-1024x735.jpeg Euler’s totient function is defined as the number of positive integers relatively prime to n (including 1). E.g. φ(12) = 4 ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), and φ(15) = 8. http://www.thescienceforum.com/mathematics/14111-modular-multiplicative-inverse-context-rsa.html https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm https://docs.google.com/viewer?url=www.math.utah.edu/~fguevara/ACCESS2013/Euclid.pdf as to why the extended Euclid’s algo can be used to find the modular multiplicative inverse wpid-wp-1402514649564-1024x767.jpeg wpid-wp-1402514730357-1024x491.jpeg https://docs.google.com/viewer?url=ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf https://docs.google.com/viewer?url=ftp://ftp.rsasecurity.com/pub/rsalabs/rsa_algorithm/rsa-oaep_spec.pdf In particular, ^ page 9. OAEP is the padding scheme ( http://crypto.stackexchange.com/questions/10145/rsa-pcks1-v2-1-rsaes-oaep-algorithm http://crypto.stackexchange.com/questions/2074/rsa-oaep-input-parameters ) , whereas I2OSP and OS2IP (on page 4); what really helped things come full circle for me is realizing how they represent arbitrary data as an integer (first converting it to an octet string). Without further do, let’s test our generated keys by encrypting and decrypting the number 521 (any number smaller than 527, our modulus, will do. ( http://stackoverflow.com/questions/10061626/message-length-restriction-in-rsa ) )

1
2
3
4
5
6
7
8
$ python
Python 2.7.5+ (default, Feb 27 2014, 19:37:08)
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print 521**41 % 527
346
>>> print 346**281 % 527
521

Note that if we try with a larger number…

1
2
3
4
>>> print 1000**41 % 527
411
>>> print 411**281 % 527
473

Nope. What really helped things come full circle once again (or full sphere..) http://en.wikipedia.org/wiki/Pretty_Good_Privacy#Confidentiality http://superuser.com/questions/383732/how-does-ssh-encryption-work It makes more sense to use a symmetric encryption algorithm with high throughput to encrypt the data first, then use PKI to encrypt and transfer the key. And that is how the world works.

Good First Bug

https://wiki.mozilla.org/Good_first_bug So!… I realize the change isn’t as trivial in FF 29+ since the switch to the nasty curved tabs. Regardless, here’s my solution: http://forums.mozillazine.org/viewtopic.php?f=38&t=2799203 and add the code to remove sidebars and this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.tabbrowser-tab {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
}
.tabbrowser-tab[selected="true"] {
font-weight: bold !important;
color: rgba(255,255,255,1) !important;
background-image: linear-gradient(rgba(102,51,102,.85), rgba(102,51,102,.85) 50%),
linear-gradient(-moz-dialog, -moz-dialog) !important;
}
tab:not([selected="true"]) {
background-color: #2F0 !important;
color: gray !important;
}

into browser.css ](/wp-content/uploads/2014/05/green_tabs-150x91.jpg)

Proof by contradiction (aka a LaTeX test)

What is a proof by contradiction? A proof by contradiction is if $\neg P \Rightarrow F$ is true.

One assumes that a proposition P is False, and uses that to derive until a contradiction is reached, which can’t be True.

A popular example: Let’s prove that $\sqrt2$ is irrational. An irrational number is something that cannot be expanded into a fraction. (A common misconception is that Pi is $\frac{22}{7}$ and therefore rational; no it is not exactly $\frac{22}{7}$.

See http://mathworld.wolfram.com/PiFormulas.html

Assume that $\sqrt2$ is rational; such that we can represent it as $\frac{a}{b}$, where $\frac{a}{b}$ is a fraction in lowest terms.

$\Rightarrow \sqrt2 = \frac{a}{b}$ $\Rightarrow 2 = \frac{a^2}{b^2}$ $\Rightarrow 2b^2 = a^2$ $\Rightarrow 2 \mid a$ $\Rightarrow 4 \mid a^2$ $\Rightarrow 4 \mid 2b^2$ $\Rightarrow 2 \mid b^2$ $\Rightarrow 2 \mid b$ If both $a$ and $b$ are even, they are not in lowest terms, as both can be divided by 2 for further simplification. Hence we have a contradiction. $\square$

On calling su in an Android App

http://su.chainfire.eu/#how I noticed that https://github.com/koush/Superuser‘s su binary requires quotes around the target command, or else it won’t execute properly.

1
2
3
4
5
6
7
8
9
u0_a156@aries:/ $ su -c ping 8.8.8.8
su -c ping 8.8.8.8
Unknown id: 8.8.8.8
u0_a156@aries:/ $ su -c "ping 8.8.8.8"
su -c "ping 8.8.8.8"
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=3 ttl=39 time=262 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=39 time=271 ms

The “solution” is to write the intended su -c command to a shell script file and then call it with ProcessBuilder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
try {
String samplePingCommand = new String("su -c ""+"ping 8.8.8.8"+""");
FileOutputStream fOut = getActivity().openFileOutput("test_ping.sh", MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write(samplePingCommand);
osw.flush();
osw.close();
ProcessBuilder testPingCommand = new ProcessBuilder("sh", getActivity().getFilesDir()+"/test_ping.sh");
testPingCommand.redirectErrorStream(true);
Process startTestPingCommand = testPingCommand.start();
BufferedReader testPingCommandOut = new BufferedReader(new InputStreamReader(startTestPingCommand.getInputStream()));
String testPingCommandSingleLine;
while ((testPingCommandSingleLine = testPingCommandOut.readLine()) != null) {
/*Log.e("Ping Command Output", testPingCommandSingleLine); */
}
catch (Exception e) {
Log.e("Ping Command", "Error", e);
}

My first foray into Brainfuck

Print damned.

1
print "damned"

Obfuscate it.

1
print 'qnzarq'.decode('rot13')

Now print “damned” in Brainfuck, and let’s play codegolf.

1
++++++++++[>++++++++++>+++++++++++<<-]>.---.>-.+.<++++.-.

Challenge accepted.

1
-[>++>++>++<<<-----]>--.---.>+++++++.+.>-.-.

http://www.iamcal.com/misc/bf_debug/ Debugger to help you visualize what’s going on. The first brainfuck works by incrementing the first cell to 10, then the loop increments the second cell to 100 and the 3rd cell to 110, and the <<- decrements the loop “counter”, which is held by the first cell.

At the end of the loop we should have [0][100][110]. Everything after the loop just increments or decrements to the appropriate ascii decimal value and outputs to stdout.

http://www.asciitable.com/ The second one works by first decrementing the value of the first cell, which is 0; hopefully the bf interpreter will wrap around to 255. Not all bf interpreters do this; https://apps.ubuntu.com/cat/applications/saucy/bf/ does but http://swapped.cc/#!/bff doesn’t.

Since the ascii decimal codes of the letters d, m, n, e, d are all in between 100 and 110 (a is 97), the shortest way I could think of was to have a big number to use as the loop counter and decrement it in intervals. 102 is 40% of 255, or 2/5ths, so after incrementing twice for cells 1, 2, and 3 go back to cell 0 and decrement by 5. At the end of the loop we should have [0][102][102][102].

Some interesting bf-related links:

https://stackoverflow.com/questions/16836860/how-does-the-brainfuck-hello-world-actually-work
http://esoteric.sange.fi/brainfuck/impl/interp/i.html
http://esolangs.org/wiki/Brainfuck_algorithms add, dup, swap, mul, if implemented in bf.

http://www.reddit.com/r/tinycode/comments/1oqgwm/shortest_hello_world_brainfuck_code/

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×