This shows you the differences between two versions of the page.
isc:labs:10 [2019/04/25 08:52] mihai.chiroiu [02. TOR] |
isc:labs:10 [2024/12/11 10:20] (current) radu.mantu [[20p] 0. Setup & EasyRSA certificate generation] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Lab 10 - Privacy Technologies====== | + | ====== Lab 10 - Tunnels. Remote Network Security ====== |
- | ===== Overview ===== | + | ===== Objectives ===== |
- | Privacy is a usually included in the larger security landscape, but it deals with aspects that concern people more that technologies and tries to answer a very tough question: "How to access/compute data without the owner know who you are?". While, like everything, is a sword with two blades, it tries to allow people own their data in the digital world and to provide anonymity while browsing the Internet. | + | Today, we're going to learn how to configure two of the most widely used |
+ | open-source VPN solutions: OpenVPN and WireGuard! | ||
- | ===== [BONUS] Completare formular de feedback ===== | + | * Set up OpenVPN and WireGuard servers on a Linux machine; |
+ | * Configure clients to connect to each VPN; | ||
+ | * Customize routing through the VPN. | ||
- | Vă invităm să evaluați activitatea echipei de ISC și să precizați punctele tari, punctele slabe și sugestiile voastre de îmbunătățire a materiei. Feedback-ul vostru este foarte important pentru noi să creștem calitatea materiei în anii următori și să îmbunătățim materiile pe care le veți face în continuare. | + | ===== Tasks ===== |
- | [[https://acs.curs.pub.ro/2018/mod/feedback/view.php?id=2010|Găsiți formularul de feedback aici]]. | + | As we will need at least two Linux systems (one for the VPN server, another for the client -- for OpenVPN, at least), you will need to work in pairs! |
- | Vă mulțumim! | + | ==== [20p] 0. Setup & EasyRSA certificate generation ==== |
- | -------- | + | |
- | \\ | + | |
- | ===== Exercises ===== | + | 1. Install the ''openvpn'' and ''wireguard-tools'' packages from the APT repository. |
- | ==== 00 [0p]. Users ==== | + | 2. We'll use EasyRSA to generate a PKI with CA & leaf certificates for server + clients: |
- | Create the following users: **//red//**, **//green//** and **//blue//**. | + | <code bash> |
+ | git clone https://github.com/OpenVPN/easy-rsa.git | ||
+ | cd easy-rsa/easyrsa3 | ||
+ | cp vars.example vars | ||
+ | vim vars # or nano, uncomment & edit COUNTRY, CITY, ORG etc. | ||
+ | ./easyrsa init-pki | ||
+ | ./easyrsa build-ca # and enter a min. 4 char password + remember it! | ||
+ | # verify CA details: | ||
+ | ./easyrsa show-ca | ||
+ | </code> | ||
- | <hidden> | + | <note important> |
- | <code> | + | Generally, the CA needs to be created by the VPN server provider, while the certificate requests must be done by each client, then transfer it to the server to be signed. |
- | sudo adduser red | + | But for simplity, we'll do them all on the same machine. |
- | sudo adduser green | + | </note> |
- | sudo adduser blue | + | |
+ | 3. Now use the [[https://github.com/OpenVPN/easy-rsa/blob/master/README.quickstart.md|official instructions here]] to request & sign both a "Server" and a "Client" certificate (use whatever Common Names you want, but make them at least descriptive). Note: you must supply a password, though you can disable this by editing the ''vars'' file and uncommenting the ''EASYRSA_NO_PASS 1'' line ;) . | ||
+ | |||
+ | Make sure to set the proper ''client'' or ''server'' certificate type for ''sign-req'''s argument! | ||
+ | |||
+ | Also note the generated certificates path! | ||
+ | You must transfer the CA + Client certificate + private key to the client machine (VM) -- you can do it now, or a bit later when told! | ||
+ | |||
+ | <solution -hidden> | ||
+ | <code bash> | ||
+ | ./easyrsa gen-req Server | ||
+ | ./easyrsa sign-req server Server | ||
+ | ./easyrsa gen-req Client | ||
+ | ./easyrsa sign-req client Client | ||
</code> | </code> | ||
- | </hidden> | + | </solution> |
- | ==== 01 [50p]. Pretty Good Privacy==== | + | ==== [40p] 1. OpenVPN Configuration ==== |
- | Pretty Good Privacy (PGP) is an encryption standard that can be used to authenticate in a distributed manner. GNU Privacy Guard (GPG) is an open-source implementation of the PGP standards. In this exercise you are required to send one file encrypted from one user to the other. | + | We will use EasyRSA to generate a CA: |
- | * Generate a private/public key using the gpg tool for each of the three users previously created. Don't forget to list all the keys and save their IDs. | + | |
- | <note> The description of fields is available [[https://github.com/gpg/gnupg/blob/master/doc/DETAILS#field-1---type-of-record|here]]. </note> | + | Now choose your role (and help your colleague!): |
- | <hidden> | + | |
+ | === A. OpenVPN Server === | ||
+ | |||
+ | **Note:** Must do all these steps logged in as ''root''! | ||
+ | |||
+ | 1. First, copy the server private key + certificate and the CA certificate to the OpenVPN's server configuration directory: | ||
<code> | <code> | ||
- | su - blue | + | root in /etc/openvpn/server … |
- | gpg --gen-key | + | ➜ ls -l |
- | su - red | + | total 16K |
- | gpg --gen-key | + | -rw------- 1 root root 1.2K 2024-12-08 19:56 ca.crt |
- | su - green | + | -rw------- 1 root root 4.5K 2024-12-08 19:56 Server.crt |
- | gpg --gen-key | + | -rw------- 1 root root 1.7K 2024-12-08 19:56 Server.key |
</code> | </code> | ||
- | </hidden> | ||
- | * First, we are going to send **//red//**'s public key to **//green//**. Export it into an ASCII file format and import it into **//green//**'s account. | ||
- | <note> After importing the key you should list it and double check that it was stored in the public ring. At this moment the key is not trusted yet, we will do this in a future step. </note> | ||
- | <hidden> | ||
- | <code> | ||
- | student@isc:~$sudo cp /home/red/pub_red.asc /home/green/. | ||
- | [sudo] password for student: | ||
- | student@isc:~$ sudo chown green:green /home/green/pub_red.asc | ||
- | green@isc:~$ gpg --list-keys | ||
- | /home/green/.gnupg/pubring.gpg | ||
- | ------------------------------ | ||
- | pub 2048R/13C73580 2019-04-23 | ||
- | uid green <green@cs.pub.ro> | ||
- | sub 2048R/F1C1FF9A 2019-04-23 | ||
- | pub 2048R/860244A1 2019-04-23 | + | 2. Copy the OpenVPN example ''server.conf'': |
- | uid red-student <red@cs.pub.ro> | + | <code bash> |
- | sub 2048R/E7626ADD 2019-04-23 | + | cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server/server.conf |
</code> | </code> | ||
- | </hidden> | ||
- | * Now, **//green//** can use **//red//**'s public key to authenticate him and send an encrypted file. Create a file containing a secret message, encrypt it and send it to the other party. | ||
- | <hidden> | ||
- | <code> | ||
- | green@isc:~$ echo "this is a secret message" > secret_file.txt | ||
- | green@isc:~$ gpg --encrypt --recipient red@cs.pub.ro secret_file.txt | ||
- | gpg: E7626ADD: There is no assurance this key belongs to the named user | ||
- | pub 2048R/E7626ADD 2019-04-23 red-student <red@cs.pub.ro> | + | Open the config with your favorite editor, then: |
- | Primary key fingerprint: 950D 2356 F2DB B4D7 F4FC 9BB2 EB86 5C35 8602 44A1 | + | * ensure that the ''ca'', ''cert'' and ''key'' point to the ones copied from EasyRSA (note: Linux is CaSe SeNsItiVe!); |
- | Subkey fingerprint: F07B EFBB 284A 99F3 10BF D964 517A 10DE E762 6ADD | + | * read the comments and generate ''ta.key''; |
+ | * read the comments and generate the Diffie-Hellman parameters file (''dh2048.pem''); | ||
- | It is NOT certain that the key belongs to the person named | + | 3. Start/restart the service: <code bash> |
- | in the user ID. If you *really* know what you are doing, | + | systemctl restart openvpn-server@server.service |
- | you may answer the next question with yes. | + | |
- | + | ||
- | Use this key anyway? (y/N) y | + | |
- | green@isc:~$ ls | + | |
- | pub_red.asc secret_file.txt secret_file.txt.gpg | + | |
</code> | </code> | ||
- | </hidden> | + | |
- | * Send the encrypted file back to **//red//** and decrypt it. | + | If it didn't complain, the congratulations! You're done with the server! |
- | <hidden> | + | |
- | <code> | + | Use ''journalctl -u openvpn-server@server -n 100 -f'' to display the log flow of the OpenVPN server (also check it in case of any service startup error). |
- | student@isc:~$ sudo cp /home/green/secret_file.txt.gpg /home/red/. | + | |
- | student@isc:~$ sudo chown red:red /home/red/secret_file.txt.gpg | + | === B. OpenVPN Client === |
- | student@isc:~$ su - red | + | |
- | Password: | + | 1. Transfer the Server CA (''ca.crt''), ''Client.key'' and ''Client.crt'' from the Server (check easyrsa's ''pki/'' directory). |
- | red@isc:~$ ls | + | |
- | pub_red.asc secret_file.txt.gpg | + | <note tip> |
- | red@isc:~$ gpg --decrypt secret_file.txt.gpg | + | Note: SSH is unusable without public key, so you'll need to do this using another service (e.g., paste bin, Teams / Discord / Messenger, netcat client/server text messaging etc.). |
- | gpg: encrypted with 2048-bit RSA key, ID E7626ADD, created 2019-04-23 | + | </note> |
- | "red-student <red@cs.pub.ro>" | + | |
- | this is a secret message | + | 2. Copy the example client configuration from ''/usr/share/doc/openvpn/examples/sample-config-files/client.conf'' somewhere you want (e.g., in your home, or inside ''/etc/openvpn/client'', it doesn't really matter). |
+ | |||
+ | 3. Edit the config and enter the server's external IP address (the VLAN9 network IP address if on OpenStack) specified using the ''remote'' variable, then also check (and modify) the ''ca'', ''cert'' and ''key'' variables to point to where you have these files (which you've transfered earlier, RIGHT?). | ||
+ | |||
+ | 4. Try to run your client using ''openvpn <path-to-client.conf>''. Inspect the error... Something about ''ta.key'' -- yep, that's right, bring it from the server :( | ||
+ | |||
+ | 5. Finally, connect to the VPN and (from another terminal, unless you spawned OpenVPN in daemon mode), ping it: <code> | ||
+ | ping 10.8.0.1 | ||
</code> | </code> | ||
- | </hidden> | ||
- | * The next step is to create a trust channel between **//blue//** and **//red//** using **//green//** as a trusted party. To do so, **//green//** must firstly sign **//red//**'s key and export both his key and **//red//**'s to **//blue//**. Move the exported files into **//blue//**'s directory and import them. After the import was done, list the keys available to **//blue//**. | ||
- | <note> The signing process typically involves manually verifying the fingerprint of the key </note> | ||
- | <hidden> | ||
- | <code> | ||
- | green@isc:~$ gpg --sign-key red@cs.pub.ro | ||
- | green@isc:~$ gpg --export -a green@cs.pub.ro > pub_green.asc | ||
- | green@isc:~$ gpg --export -a red@cs.pub.ro > pub_red_signed_by_green.asc | ||
- | green@isc:~$ exit | ||
- | logout | ||
- | student@isc:~$ sudo cp /home/green/pub_green.asc /home/blue/ | ||
- | student@isc:~$ sudo cp /home/green/pub_red_signed_by_green.asc /home/blue/ | ||
- | student@isc:~$ su - blue | ||
- | blue@isc:~$ gpg --import pub_green.asc | ||
- | blue@isc:~$ gpg --import pub_red_signed_by_green.asc | ||
- | blue@isc:~$ gpg --list-key | ||
- | /home/blue/.gnupg/pubring.gpg | ||
- | ----------------------------- | ||
- | pub 2048R/C1CD918F 2019-04-23 | ||
- | uid blue-student <blue@cs.pub.ro> | ||
- | sub 2048R/0F45CB72 2019-04-23 | ||
- | pub 2048R/13C73580 2019-04-23 | + | ==== [40p] 2. WireGuard ==== |
- | uid green <green@cs.pub.ro> | + | |
- | sub 2048R/F1C1FF9A 2019-04-23 | + | Wireguard is one of the latest open-source VPN technology, increasingly popular for its low complexity, straight-forward , security and performance due to its use of some modern cryptographic primitives (ChaCha20+Poly1305 for symmetric encryption, Curve25519 for ECDH, BLAKE2s for hashing). |
- | pub 2048R/860244A1 2019-04-23 | + | Authentication is done by simply exchanging public keys. Let's go! |
- | uid red-student <red@cs.pub.ro> | + | |
- | sub 2048R/E7626ADD 2019-04-23 | + | |
+ | 1. Both pairs should generate a private and public key pair and share the public counterpart. This is best done using the ''wg'' CLI utility: <code bash> | ||
+ | wg genkey | tee wg-priv.key | wg pubkey | tee wg-pub.key | ||
+ | # Q: what does `tee` do? (`man` it!) | ||
</code> | </code> | ||
- | </hidden> | ||
- | * Now, **//blue//** should mark **//green//**'s key as trusted (by signing it). After this, as the **//red//** user, create a file with an important message and sign it (do not encrypt it for this step). Transfer the file to **//blue//**, read the file and verify the signature. | ||
- | <hidden> | ||
- | <code> | ||
- | red@isc:~$ echo "this is an important message" > important_file.txt | ||
- | red@isc:~$ gpg --sign important_file.txt | ||
- | red@isc:~$ exit | ||
- | student@isc:~$ sudo cp /home/red/important_file.txt.gpg /home/blue/ | ||
- | student@isc:~$ sudo chown blue:blue /home/blue/important_file.txt.gpg | ||
- | student@isc:~$ su - blue | ||
- | Password: | ||
- | blue@isc:~$ ls | ||
- | important_file.txt.gpg pub_green.asc pub_red_signed_by_green.asc | ||
- | blue@mihai-isc:~$ gpg important_file.txt.gpg | ||
- | gpg: Signature made Tue 23 Apr 2019 02:25:50 PM UTC using RSA key ID 860244A1 | ||
- | gpg: Good signature from "red-student <red@cs.pub.ro>" | ||
- | gpg: WARNING: This key is not certified with a trusted signature! | ||
- | gpg: There is no indication that the signature belongs to the owner. | ||
- | Primary key fingerprint: 950D 2356 F2DB B4D7 F4FC 9BB2 EB86 5C35 8602 44A1 | ||
- | blue@isc:~$ cat important_file.txt | ||
- | this is an important message | ||
- | </code> | ||
- | </hidden> | ||
- | * In the default setup mode, the last step should have given a warning stating that the key is not trusted while still being valid ("Good signature"). This is because GPG uses a more complex trusted model. As a last step, login as the **//blue//** user and change the trust level for **//green//**'s key to "I trust ultimately". After this verify the previous file signature again. | ||
- | <note> The web of trust allows a more elaborate algorithm to be used to validate a key. A more flexible algorithm can now be used: a key K is considered valid if it meets two conditions: \\ 1. it is signed by enough valid keys, meaning \\ a. you have signed it personally, \\ b. it has been signed by one fully trusted key, or \\ c. it has been signed by three marginally trusted keys; and \\ 2. the path of signed keys leading from K back to your own key is five steps or shorter. [[https://www.gnupg.org/gph/en/manual.html#AEN335|ref]]</note> | ||
- | <hidden> | ||
- | <code> | ||
- | blue@isc:~$ gpg --edit-key green@cs.pub.ro | ||
- | gpg> trust | ||
- | Please decide how far you trust this user to correctly verify other users' keys | + | Only the public key is displayed on console (both are stored as files for backup!). Share it with your colleague! |
- | (by looking at passports, checking fingerprints from different sources, etc.) | + | |
- | 1 = I don't know or won't say | + | 2. Time to create our configuration file. Create a ''.conf'' file inside ''/etc/wireguard/'' (your choice of naming, though ''wg-isc'' sounds quite okay). |
- | 2 = I do NOT trust | + | |
- | 3 = I trust marginally | + | |
- | 4 = I trust fully | + | |
- | 5 = I trust ultimately | + | |
- | m = back to the main menu | + | |
- | Your decision? 5 | + | Use the following code template and fill the variables (also remove/replace the ''<..>'' placeholders!): <code> |
- | Do you really want to set this key to ultimate trust? (y/N) y | + | [Interface] |
+ | PrivateKey = <paste-your-private-key> | ||
+ | ListenPort = 55820 | ||
- | gpg> quit | + | [Peer] |
- | blue@isc:~$ gpg -v --verify-files important_file.txt.gpg | + | PublicKey = <paste-your-colleagues's-pub-key> |
- | gpg: original file name='important_file.txt' | + | Endpoint = <colleague-VM-IP>:55820 |
- | gpg: Signature made Tue 23 Apr 2019 02:44:00 PM UTC using RSA key ID 860244A1 | + | AllowedIPs = <your-tunnel-subnet>/<mask> |
- | gpg: using PGP trust model | + | |
- | gpg: checking the trustdb | + | |
- | gpg: 3 keys cached (8 signatures) | + | |
- | gpg: 3 keys processed (3 validity counts cleared) | + | |
- | gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model | + | |
- | gpg: depth: 0 valid: 2 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 2u | + | |
- | gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u | + | |
- | gpg: Good signature from "red-student <red@cs.pub.ro>" | + | |
- | gpg: binary signature, digest algorithm SHA1 | + | |
</code> | </code> | ||
- | </hidden> | ||
+ | Use a private space as the tunnel subnet address, e.g., ''10.12.34.252/30''. | ||
- | ==== 02. TOR ==== | + | 3. We'll create the wireguard interfaces the ''iproute2'' way (i.e., using the ''ip'' Linux utility): <code> |
+ | ip link add wg-isc type wireguard | ||
+ | wg setconf wg-isc /etc/wireguard/wg-isc.conf # or whatever you named your config | ||
+ | ip address add <your-address>/<mask> dev wg-isc | ||
+ | </code> | ||
- | The Tor (The Onion Routing) project is an implementation of the more generic "onion routing" idea that allows a user to gain network anonymity while surfing the Internet. The mechanism that allows for a private surfing is based on re-encryption and "randomly" routing of the packet at the level of each router within the network, allowing each router to only know the previous and the next router in the route (not the source/destination of the packet) [[https://www.torproject.org/about/history/|ref]]. Accessing the Tor network can be done either through a local proxy of via a Browser pre-configured with the proxy server. | + | 4. Connectivity test! <code> |
- | * The Tor proxy has already been deployed and configured (line 18 & 28 from /etc/tor/torrc) on the virtual machine. Verify that it is listening on an IPv4 port and write it down. | + | ping <colleague-private-tunnel-ip> |
- | <note> Tor only supports TCP traffic, some make sure your DNS queries are done over TCP.</note> | + | sudo wg # show wireguard statistics |
- | * //torsocks// is a tool that forces any opened program to use the Tor network for connectivity. Open a shell and find out your real IP address. Now, open a shell using //torsocks// and find out the IP address via the Tor network. Restart the **tor** service and discovery your newly allocated IP address. | + | |
- | <note tip><code>dig TXT +tcp +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}'</code></note> | + | |
- | <hidden> | + | |
- | <code> | + | |
- | root@mihai-isc:/etc/tor# torsocks --shell | + | |
- | /usr/bin/torsocks: New torified shell coming right up... | + | |
- | root@mihai-isc:/etc/tor# dig TXT +tcp +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}' | + | |
- | 199.249.230.72 | + | |
- | root@mihai-isc:/etc/tor# exit | + | |
- | exit | + | |
- | root@mihai-isc:/etc/tor# dig TXT +tcp +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}' | + | |
- | 141.85.241.165 | + | |
</code> | </code> | ||
- | </hidden> | ||
- | * You are going to configure your local Firefox browser to use the Tor proxy on the VM. First, edit the "Security Group Rules" from OpenStack and make sure that connections to Tor port (via TCP) are allowed. Next, change the **Firefox** Network Settings to use Socks5 proxy using the IP address and port from your VM. You can verify that your browser is using Tor by accessing the following [[https://check.torproject.org/|website]]. | ||
- | <hidden> | ||
- | [[https://1.bp.blogspot.com/-b-MahPstRzA/WvgwatvGq5I/AAAAAAAAQiA/e1rJp8RGKU08O-tV5W0oUA9kDGY5tEq5gCLcBGAs/s1600/proxy.png|Firefox Settings]] | ||
- | </hidden> | ||
- | * | + | <note tip> |
- | ==== 02. Bitcoin==== | + | **Note:** there are even simpler ways of configuring Wireguard, like [[https://www.man7.org/linux/man-pages/man8/wg-quick.8.html|wg-quick]] (automates interface creation & IP address/routes configuration using a similar .conf file) and [[https://github.com/wg-easy/wg-easy|wg-easy]] (Web GUI for Wireguard) -- but we wanted to demonstrate its purest form (: |
+ | </note> | ||