This shows you the differences between two versions of the page.
isc:labs:10 [2022/05/16 11:35] florin.stancu |
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! | ||
- | ===== Exercises ===== | + | * Set up OpenVPN and WireGuard servers on a Linux machine; |
+ | * Configure clients to connect to each VPN; | ||
+ | * Customize routing through the VPN. | ||
- | ==== 00 [0p]. Users ==== | + | ===== Tasks ===== |
- | Create the following users: **//red//**, **//green//** and **//blue//**. Make sure that you can ssh into the VM using this users. For example, copy the ".ssh/" directory from student to the newly added users and "chown" it accordingly. | + | 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! |
- | <hidden> | + | ==== [20p] 0. Setup & EasyRSA certificate generation ==== |
- | <code> | + | |
- | sudo adduser red | + | 1. Install the ''openvpn'' and ''wireguard-tools'' packages from the APT repository. |
- | sudo adduser green | + | |
- | sudo adduser blue | + | 2. We'll use EasyRSA to generate a PKI with CA & leaf certificates for server + clients: |
+ | |||
+ | <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> | </code> | ||
- | </hidden> | ||
- | ==== 01 [50p]. Pretty Good Privacy==== | + | <note important> |
+ | 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. | ||
+ | But for simplity, we'll do them all on the same machine. | ||
+ | </note> | ||
- | 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. | + | 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 ;) . |
- | For the next exercises, you will need to be logged in as users red/green/blue via ssh in order to generate the gpg key. | + | Make sure to set the proper ''client'' or ''server'' certificate type for ''sign-req'''s argument! |
- | * Unfortunately, gpg doesn't work when the user is with ''su'' (tty permission problems, owned by ''student''). If you want to do this, use ''tmux'' after logging in: it allocates a new TTY ;) | + | Also note the generated certificates path! |
- | * Generate a private/public key using the gpg tool for each of the three users previously created. **Use <red|green|blue>@cs.pub.ro for the emails ;) ** | + | 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! |
- | <hidden> | + | <solution -hidden> |
+ | <code bash> | ||
+ | ./easyrsa gen-req Server | ||
+ | ./easyrsa sign-req server Server | ||
+ | ./easyrsa gen-req Client | ||
+ | ./easyrsa sign-req client Client | ||
+ | </code> | ||
+ | </solution> | ||
+ | |||
+ | ==== [40p] 1. OpenVPN Configuration ==== | ||
+ | |||
+ | We will use EasyRSA to generate a CA: | ||
+ | |||
+ | Now choose your role (and help your colleague!): | ||
+ | |||
+ | === 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> | ||
- | sudo apt-get install rng-tools | + | 2. Copy the OpenVPN example ''server.conf'': |
- | sudo rngd -v -f -r /dev/urandom | + | <code bash> |
+ | cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server/server.conf | ||
</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> | ||
- | * You should see something similar (for red and green): <code> | ||
- | 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 | + | Open the config with your favorite editor, then: |
- | uid red-student <red@cs.pub.ro> | + | * ensure that the ''ca'', ''cert'' and ''key'' point to the ones copied from EasyRSA (note: Linux is CaSe SeNsItiVe!); |
- | sub 2048R/E7626ADD 2019-04-23 | + | * read the comments and generate ''ta.key''; |
+ | * read the comments and generate the Diffie-Hellman parameters file (''dh2048.pem''); | ||
+ | |||
+ | 3. Start/restart the service: <code bash> | ||
+ | systemctl restart openvpn-server@server.service | ||
</code> | </code> | ||
- | <note> The description of fields is available [[https://github.com/gpg/gnupg/blob/master/doc/DETAILS#field-1---type-of-record|here]]. </note> | ||
- | <hidden> | + | If it didn't complain, the congratulations! You're done with the server! |
- | <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 | + | |
- | </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> | + | 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). |
- | Primary key fingerprint: 950D 2356 F2DB B4D7 F4FC 9BB2 EB86 5C35 8602 44A1 | + | |
- | Subkey fingerprint: F07B EFBB 284A 99F3 10BF D964 517A 10DE E762 6ADD | + | |
- | It is NOT certain that the key belongs to the person named | + | === B. OpenVPN Client === |
- | in the user ID. If you *really* know what you are doing, | + | |
- | you may answer the next question with yes. | + | |
- | Use this key anyway? (y/N) y | + | 1. Transfer the Server CA (''ca.crt''), ''Client.key'' and ''Client.crt'' from the Server (check easyrsa's ''pki/'' directory). |
- | green@isc:~$ ls | + | |
- | pub_red.asc secret_file.txt secret_file.txt.gpg | + | |
- | </code> | + | |
- | </hidden> | + | |
- | * Send the encrypted file back to **//red//** and decrypt it. | + | |
- | <hidden> | + | |
- | <code> | + | |
- | student@isc:~$ sudo cp /home/green/secret_file.txt.gpg /home/red/. | + | |
- | student@isc:~$ sudo chown red:red /home/red/secret_file.txt.gpg | + | |
- | student@isc:~$ su - red | + | |
- | Password: | + | |
- | red@isc:~$ ls | + | |
- | pub_red.asc secret_file.txt.gpg | + | |
- | red@isc:~$ gpg --decrypt secret_file.txt.gpg | + | |
- | gpg: encrypted with 2048-bit RSA key, ID E7626ADD, created 2019-04-23 | + | |
- | "red-student <red@cs.pub.ro>" | + | |
- | this is a secret message | + | |
- | </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 | + | <note tip> |
- | uid green <green@cs.pub.ro> | + | 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.). |
- | sub 2048R/F1C1FF9A 2019-04-23 | + | </note> |
- | pub 2048R/860244A1 2019-04-23 | + | 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). |
- | uid red-student <red@cs.pub.ro> | + | |
- | sub 2048R/E7626ADD 2019-04-23 | + | |
+ | 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> | ||
- | * 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 | + | ==== [40p] 2. WireGuard ==== |
- | (by looking at passports, checking fingerprints from different sources, etc.) | + | |
- | 1 = I don't know or won't say | + | 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). |
- | 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 | + | Authentication is done by simply exchanging public keys. Let's go! |
- | Do you really want to set this key to ultimate trust? (y/N) y | + | |
- | gpg> quit | + | 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> |
- | blue@isc:~$ gpg -v --verify-files important_file.txt.gpg | + | wg genkey | tee wg-priv.key | wg pubkey | tee wg-pub.key |
- | gpg: original file name='important_file.txt' | + | # Q: what does `tee` do? (`man` it!) |
- | gpg: Signature made Tue 23 Apr 2019 02:44:00 PM UTC using RSA key ID 860244A1 | + | |
- | 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> | ||
+ | Only the public key is displayed on console (both are stored as files for backup!). Share it with your colleague! | ||
- | ==== 02. [40p] TOR ==== | + | 2. Time to create our configuration file. Create a ''.conf'' file inside ''/etc/wireguard/'' (your choice of naming, though ''wg-isc'' sounds quite okay). |
- | 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. | + | Use the following code template and fill the variables (also remove/replace the ''<..>'' placeholders!): <code> |
+ | [Interface] | ||
+ | PrivateKey = <paste-your-private-key> | ||
+ | ListenPort = 55820 | ||
- | * First, please install `tor`: <code> | + | [Peer] |
- | sudo apt update | + | PublicKey = <paste-your-colleagues's-pub-key> |
- | sudo apt install tor | + | Endpoint = <colleague-VM-IP>:55820 |
+ | AllowedIPs = <your-tunnel-subnet>/<mask> | ||
</code> | </code> | ||
- | * Enable SOCKS proxy by editing /etc/torrc and uncommenting ''SOCKSPort 9050'' ;) | + | |
- | <note> Tor only supports TCP traffic, some make sure your DNS queries are done over TCP.</note> | + | Use a private space as the tunnel subnet address, e.g., ''10.12.34.252/30''. |
- | <hidden> | + | |
- | <code> | + | 3. We'll create the wireguard interfaces the ''iproute2'' way (i.e., using the ''ip'' Linux utility): <code> |
- | root@isc:/etc/tor# netstat -nltp | + | ip link add wg-isc type wireguard |
- | Active Internet connections (only servers) | + | wg setconf wg-isc /etc/wireguard/wg-isc.conf # or whatever you named your config |
- | Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name | + | ip address add <your-address>/<mask> dev wg-isc |
- | tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1276/mysqld | + | |
- | tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 25926/sshd | + | |
- | tcp 0 0 0.0.0.0:9050 0.0.0.0:* LISTEN 1414/tor | + | |
- | tcp6 0 0 :::80 :::* LISTEN 3280/apache2 | + | |
- | tcp6 0 0 :::22 :::* LISTEN 25926/sshd | + | |
</code> | </code> | ||
- | </hidden> | ||
- | * //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@isc:/etc/tor# torsocks --shell | ||
- | /usr/bin/torsocks: New torified shell coming right up... | ||
- | root@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@isc:/etc/tor# exit | ||
- | exit | ||
- | root@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> | ||
- | </hidden> | ||
- | * You are going to configure your local Firefox browser to use the Tor proxy on the VM. First, use ssh local port forwarding to make port 9050 available to your machine: <code> | ||
- | ssh -i <fep_key_path> -o ProxyCommand="ssh <username>@fep.grid.pub.ro -W %h:%p" -L 9050:localhost:9050 student@<VM_IP> | ||
- | </code> | ||
- | * 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> | ||
- | ==== 11. [10p] Feedback ==== | + | 4. Connectivity test! <code> |
+ | ping <colleague-private-tunnel-ip> | ||
+ | sudo wg # show wireguard statistics | ||
+ | </code> | ||
- | Please take a minute to fill in the [[https://forms.gle/5Lu1mFa63zptk2ox9|feedback form]] for this lab. | + | <note tip> |
+ | **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> | ||