Skip to content
Snippets Groups Projects
Commit 94e2a4c3 authored by Arti's avatar Arti
Browse files

Merge branch 'issue11-documentation' into 'no-masters'

documentation

See merge request !1
parents 29a891d1 4bb3bbf9
No related branches found
No related tags found
1 merge request!1documentation
......@@ -22,6 +22,7 @@ other code projects.
## Useful pointers
* Obfuscating OpenVPN with ObfsVPN: [The Long How-To](./tutorial.md).
* The [invisible library](https://github.com/leapcode/library).
* [obfsvpn](https://0xacab.org/leap/obfsvpn)
* consolidated [documentation](https://0xacab.org/leap/dev-documentation) of the LEAP VPN API and overall architecture.
......
## Overview
In this tutorial, we will be setting up 1 openvpn server, a.k.a the Gateway, and 2 obfs4 bridges to connect to this gateway in an obfuscated manner.
Why on Earth would we need 3 extra servers to just browse the internet?
Short answer: because there is more than one attacker we want protection from.
First is the website itself: it logs user IP and tries to fingerprint browser.
Second is the user's ISP, it logs the websites which the user tries to visit and can block requests at will.
The Gateway provides improved privacy for the user when browsing the public internet
Websites see all user's traffic as originating from the Gateway, which acts as a facade address for several people at once.
While we do try to conceal user's true IP, at the network layer we can't stop browser fingerprinting, this is for browser to handle.
Gateway also makes it harder for ISP to see which sites are accessed. Because user contacts only one server - the Gateway.
However, if the user is from a censored country, it is easy for a censor to block the user from connecting to the Gateway.
First of all, openvpn traffic is fingerprintable.
Secondly, gateways are globally listable for high amounts of outgoing traffic or incredibly famous like riseup.
We can't use openvpn protocol to the gateway if, for example, connecting from Iran, Russia or China.
To hide openvpn protocol from censor, we are going to use another protocol, obfs4, to encapsulate openvpn data.
Obfs4 is designed to look like nothing, a random encrypted flow of bytes. [Specification](https://github.com/Yawning/obfs4/blob/master/doc/obfs4-spec.txt)
We will create a separately hosted obfs server to be a bridge between the user and the gateway.
User will send to it inconspicious obfuscated bytes to fool ISP, the bridge will unwrap them into an openvpn connection to Gateway, and Gateway will forward them to the public internet.
To extra-confuse censors, we support automatic change of bridges at random intervals, this will be covered in part 2.
:grin: :grin:
## Setting up OpenVPN Gateway
### Log in to your cloud provider
In this tutorial, we are going to use Digital Ocean, but feel free to use any hosting you like.
* In the create tab, select "create new droplet"
* Choose default ubuntu
* Choose the cheapest plan (we do not need anything special for Openvpn to work)
* Call the droplet "obfsvpn-gateway"
* Do not finish creation yet
### Make new SSH key
This and the next section assume unixlike environment.
* Click "add ssh key". You should be shown a field to put the key into
* In terminal: `cd .ssh`
* Make a new key with `ssh-keygen`
* Copy your public key into the field
* Finish making the droplet. DO will show you the IP of the new machine
### Connect to your new machine
Open your terminal.
* `ssh -i yourkeyfile root@<ip_that_digitalocean_shows>`
* After entering the passphrase that you set on ssh key generation stage, you should see root console
* We will only need to install openvpn and easy-rsa to prepare for next stage
* `apt install openvpn easy-rsa`
### Create a Public Key infrastructure directory for openvpn
Hint: it will store keys.
Ubuntu's easy-rsa package does not put easyrsa on PATH, so we copy the whole easyrsa dir to our would-be key dir:
* `cp -r /usr/share/easy-rsa /etc/openvpn`
* `cd /etc/openvpn/easy-rsa`
Then we init our empty pki dir with:
* `./easyrsa init-pki`
#### The first part of Public Key Infrastructure is a Certificate Authority
When 2 parties want to communicate securely, they exchange public encryption keys.
However, how would one know if they use a CORRECT key that truly belongs to another party?
A TLS certificate contains not only the key itself, but also a signature from some trusted entity that this key belongs to what it claims to belong to.
In this tutorial, we will make this trusted entity, the almighty Certificate Authority all by ourselves.
With exactly one command.
* `./easyrsa build-ca`
* Copy the generated ca.crt somewhere, we will need it later on a client machine
#### Generate a key for our second actor, the Openvpn Server
* `./easyrsa gen-req server`
and sign
* `./easyrsa sign-req server server server`
Yes, this machine will be both our vpn server AND certificate authority.
Now, as an extra layer of security besides TLS, openvpn can have an extra protection of a preshared static key. Generate it with
`openvpn --gen-key > ta.key`
ta.key we also will need to copy to client afterwards.
Finally, generate parameters for Diffie Hellman handshakes. These won't be shared.
* `openssl dhparam -out dh2048.pem 2048`
### Compose our openvpn server config file.
Start by copying an example config from the openvpn documentation folder.
* `cd ..`
* `cp /usr/share/doc/openvpn/examples/configs/server.conf .`
Then edit server.conf like
````
proto tcp
ca easy-rsa/pki/ca.crt
cert easy-rsa/pki/issued/server.crt
key easy-rsa/pki/private/server.key
````
### Start openvpn
* `openvpn --config server.conf`
* Normal output ends with "completed"
* If this works, stop it with `ctrl+c`, then
* `systemctl enable openvpn@server.service`
* `systemctl start openvpn@server.service`
* This will make it run on background and autostart at machine boot
### Enable routing to internet
Right now the packets that go to our VPN can only reach our VPN, you cannot use duckduckgo over it.
To change this, we alter iptables rules.
* `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE`
## Setting up OBFS4 Bridge
To connect obscurely.
### Make a machine
* Log into Digital Ocean
* Make a new droplet with minimal specifications
* Call it obfs-bridge
* Note down its IP
* Connect to it with ssh similarly to as you did in openvpn set up
* You are the root!
### Prepare binaries
* `apt install golang make git`
* `git clone https://0xacab.org/leap/obfsvpn`
* `cd obfsvpn/cmd/server`
* `make build`
### Copy certificates
As per documentation in /doc, you will need to copy server certificate and certificate authority's ca.crt into /tmp for bridge to work.
However, /tmp is volatile and will destroy itself on machine restart.
So, to do this more conveniently, make a certificates folder right on spot.
* `mkdir certificates`
* From your openvpn server copy `pki/issued/server.crt` into local `certificates/server.pem`
* And `pki/ca.crt` into local `certificates/ca.crt`
* Then, add the following lines to Makefile:
```
certs:
cp certificates/* /tmp
```
This way, next time you want to start your server, you will only run `make certs` to get files to the needed place.
We will also copy over some placeholder obfs keys: see Appendix to know how to generate them.
* `cp -r ../../server/test_data .`
### Set target gateway
In the similar vein of easy reuse, we will export some variables.
* `export LHOST=<your BRIDGE ip>`
* `export LPORT=<any port you want>`
* `export RHOST=<your Gateway ip:port>`
### Start!
* `make certs`
* `./server -addr ${LHOST} -port ${LPORT} -vpn ${RHOST} -state test_data -c test_data/obfs4.json`
### Obfs4 client
On any machine you want to connect from
* `apt install golang make git`
* `git clone https://0xacab.org/leap/obfsvpn`
* `cd obfsvpn/cmd/client`
* `make build` or `CGO_ENABLED=0 go build` (will PR the makefile shortly)
* `./client -c <certificate string from your obfs4.json> -r <your bridge ip, LHOST> -rp <your bridge port, LPORT>`
* If all goes good, this reports that the socks5 port is open at 8080
* However, to use it, we need to set up our openvpn client
### Openvpn Client setup:
* Repeat the steps for openvpn server but stop after generation of pki dir
* Copy ta.key from server to openvpn folder
* Copy ca.crt from server to pki dir
* From /etc/openvpn/easy-rsa, generate a client request-for-certificate:
* On client: `./easyrsa gen-req server`
* Copy it over to server's pki/reqs directory:
* On server: `./easyrsa sign-req client client client`
* Copy pki/issued certificate to client's pki folder
* Copy sample client file
* `cp /usr/share/doc/openvpn/examples/configs/client.conf .`
* Edit it to point to your files and to your gateway
```
proto tcp
remote <gateway host> <gateway port>
ca easy-rsa/pki/ca.crt
cert easy-rsa/pki/client.crt
key easy-rsa/pki/private/client.key
```
* Check that direct connection to gateway succeeds:
* `openvpn -c client.conf`
* Check that output ends with `completed`
* On the gateway, `ip addr`
* Find the IP of tun0 interface
* On client: `ping -I tun0 <gateway tun0 ip>`
* If it succeeds:`ping -I tun0 8.8.8.8`
* Congrats, at least direct openvpn tunnel is working
* Now, let's check a concealed openvpn tunnel!
* `openvpn -c client.conf --remote <obfs4_ip> <obfs4_port> --socks-proxy 127.0.0.1 8080`
* If it succeeds:`ping -I tun0 8.8.8.8`
* Is it working? Yes? You are golden! No? Send us your error so we write a troubleshooting section
### Appendix: Making your own obfs4 certificate
* `apt install python3-pysodium`
* `wget -O gen-shapeshifter-state.py https://0xacab.org/leap/container-platform/lilypad/-/raw/main/playbooks/scripts/gen-shapeshifter-state.py?inline=false`
* `python3 gen-shapeshifter-state.py statedir`
* fetch your files from `statedir` folder
## PART 2 : Automatic Bridge Switching (aka Hopping)
Now let's make the censors' heads spin with switching from one bridge to next.
### Adjusting the Gateway
We will need to make it use udp and add a few more tricks
* open the gateway machine shell
* `cd /etc/openvpn`
* `cp server.conf server-hopping.conf`
* edit `server-hopping.conf` like this:
```
proto udp
push "ip link set mtu 48000 dev tun0"
float
tun-mtu 48000
fragment 0
mssfix 0
cipher AES-256-CBC
```
### Restart Gateway with New Settings
* `systemctl stop openvpn@server.service`
* `systemctl start openvpn@server-hopping.service`
### Set up Second Bridge
* make a new obfs bridge, following the instructions until it is time to [start the bridge up](./tutorial.md#start).
* `make certs`
* `./server -addr 0.0.0.0 -h -state test_data -c test_data/obfs4_state.json -v -vpn $RHOST`
* For hopping, we do not need to specify the port - ports are generated at random.
### Adjust the first one, too
* connect to your first bridge, and stop it if it is running
* then, use the same line as above to restart it.
### Start the OBFS Client in Hopping Mode
* back at your client machine, we will make adjustments to obfs:
* first, stop the client by pressing `ctrl+c` in the terminal with the running client.
* restart the client with new arguments:
`./client -h -c <bridge1_cert>,<bridge2_cert> -r <bridge_ip_1>,<bridge_ip_2>`
### Adjust Your OpenVPN Client
* `cd /etc/openvpn`
* `sudo su`
* `cp client.conf client-hopping.conf`
* edit client-hopping.conf like this:
```
proto udp
replay-window 65535
tun-mtu 48000
fragment 0
mssfix 0
cipher AES-256-CBC
```
### Start it!
Hopping mode is significantly different in a way that we do not use Socks between openvpn and obfsvpn client.
Instead, we connect to obfsvpn client over udp like if this client was an openvpn server.
* `openvpn --config client-hopping.conf --remote 127.0.0.1:8080`
* Hopefully, this ends with successful initialization
Using the hopping mode is similar to non-hopping.
HAPPY CIRCUMVENTING!
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment