Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ii:labs:05:tasks:01 [2022/01/18 13:02]
radu.mantu
ii:labs:05:tasks:01 [2025/01/11 20:05] (current)
florin.stancu
Line 1: Line 1:
-==== 01. [15pInitial setup ====+==== 01. [25pCommit signatures ​====
  
-=== [5p] Google Cloud account ===+When looking at the ''​git log''​ of a repository, you would normally see a sequence of entries such as this:
  
-While there are many cloud providers (e.g.: AWS, Microsoft Azure, DigitalOcean,​ etc.), today we are going to use Google Cloud. By signing up [[https://gcp.secure.force.com/​GCPEDU?​cid=k4l6271rTi0S8SnO6%2BrfXcBFnHHDEQtClCxOaWyWLFIbAyObouJ8kUfSNviwEShL/​|here]] with your university email (''​${YOUR_ID}@stud.acs.upb.ro''​ most likely), you will get %%$%%50 in credits to play around with their infrastructure up until the 10<​sup>​th<​/sup> of April. In case you aren't forwarding your UPB emails to/from your main account via [[https://support.google.com/mail/answer/7104828?​hl=en|IMAP/POP]], you can access them in [[https://outlook.office365.com/​|outlook]].+[[https://ocw.cs.pub.ro/courses/_media/ii/labs/05/tasks/git_log.png|{{ :ii:labs:05:git_log.png?​700 ​|}}]]
  
-=== [5p] Google Cloud SDK ===+Each commit is identified via a 40-character long **hexstring**. A hexstring is the hexadecimal representation of a sequence of bytes, where every nibble (i.e.: 4 bits) is represented by a character ranging from //'​0'//​ (0b0000) to //'​F'//​ (0b1111). But how is this identifier calculated?
  
-Normally, cloud provides give you the option to access a [[https://​console.cloud.google.com/|web dashboard]]. Using this is fine for starting up one virtual machine, ​or checking your billing settings. Howeverif you want to do some automation work, you will want to utilize ​the [[https://cloud.google.com/sdk/docs/​install|gcloud SDK]]. By following ​the instructions hereyou should ​be able to install ​the **gcloud** CLI application. If the steps for Ubuntu don't work (very likely on WSL)try the more generic approach for [[https://cloud.google.com/sdk/docs/install#​linux|Linux]] (i.e.: download ​//.tar.gz// ​and run the install script)Remember: Ubuntu is a Linux distribution! Finallyyou will be asked to run:+Well... this commit identifier ​is called a **hash value** ​or a **digest**and is the output of a [[https://en.wikipedia.org/wiki/Hash_function|hash function]]. A hash function takes an arbitrary amount of data and outputs a fixed-size bit array that is representative of the input. Normallyone would be weary of collisions: if the function'​s domain is virtually infinite and the co-domain is not only finite but rather small in comparison, wouldn'​t it be possible ​to create two commits with the same digest? Possible -- yes, likely -- no. Git uses **SHA1**, [[https://en.wikipedia.org/wiki/Cryptographic_hash_function|cryptographic hash function]]. What makes a __cryptographic__ hash function so special is that it provides certain guaranteesFor example, it should be impossible to calculate potential messages from digest (meaning that the function is non-invertible)Moreover, any change in the input -- no matter how small, should change the hash value so extensively that the new value and the old should appear uncorrelatedConsequentlybeing able to //craft// a commit such that it's not only comprehensible,​ but also creates a certain desired digest is so unlikely that it occurring naturally should not pose any risk.
  
-<code bash> +There is, however, a more significant risk here. What guarantee do you have that the author of the commit above is actually Linus himself? Using something like [[https://​github.com/​jayphelps/​git-blame-someone-else|git-blame-someone-else]],​ you could overwrite commits and change their author only to then ''​%%git push --force%%''​ and replace the remote history (don't do this on the master branch if you're not working alone). The answer to this problem is **commit signing**. Cryptographic algorithms can be loosely categorized an **symmetric** and **asymmetric**. Symmetric algorithms like [[https://​en.wikipedia.org/​wiki/​Advanced_Encryption_Standard|AES]] use the same key for both encryption ​//and// decryption. Asymmetric algorithms like [[https://​en.wikipedia.org/​wiki/​RSA_(cryptosystem)|RSA]],​ on the other hand, utilize two keys. One for encryption and one for decryption. Usually, the one used for encryption is called the private key and the one used for decryption, the public key. The private key is your identity, so you don't share it with anyone. The public key you configure on remote servers to give them the ability to verify your identity (e.g.: configuring SSH keys on fep.grid.pub.ro). As a rule, you use asymmetric cryptography in cases where you need to prove your identity to a remote host, establish secure communication channels over an untrusted network, etc. The reason for this is that asymmetric algorithms are __orders of magnitude slower__ than their symmetric counterparts. While encrypting the output of a **SHA256** function (32 bytes) with a 4096-bit RSA key takes about 5ms on regular CPUs, it takes almost a __full minute__ on an Arduino Mega (with a MCU running at 16MHz). AES-256 on the other hand, encrypts the same amount of data in less than 5 __microseconds__. The downside is that you need to share your key with other systems for them to extract the plaintext message.
-# create default configuration ​for usage with gcloud +
-$ gcloud init +
-</code>+
  
-<​note>​ +In the following tasks we will introduce **GNU Privacy Guard (gpg)** an open source encryption and signing tool. **git** can use **gpg** ​to sign your commits as you create them. For it to work, you will also have to upload your public key to [[https://github.com/settings/keys|github]].
-In addition ​to logging in with your Google account, you will also be asked to create a new project. Because of how Google Cloud is designed, this project must have a //globally unique// IDSo don't go for something obvious like //"​lab-ii"//,​ but in stead derive something from your university account nameThat should be unique enough. +
-</​note>​+
  
-=== [5pBilling ​===+=== [15pTask A - GNU Privacy Guard ===
  
-CLI tools like **ip** and **gcloud** work based on a more modern paradigmIf older programs mainly use flags (i.e.: ​''​%%--%%this, -t''​) to specify what functionality should be invoked at runtimethese use [[https://​clig.dev/#​subcommands|commands and subcommands]] for a more intuitive classification. For example:+As we mentioned before, ​**gpg** is an encryption ​and signing tool. Additionally,​ it also handles key management. When you first create a keypair, it will also construct you a **key ring**. This key ring can store both private keys (i.e.: ​your keys -- you can have more than oneand multiple public keys. These public keys can belong solely ​to youor to persons that you trust.
  
-<code bash> +Let's say that you have //Person A//'s public key and //Person B// has your public key. If you want to introduce //Person A// to //Person B//, you can give his public key (that you have on your key ring) to //Person B//. If you're doing this over a secure channel (e.g.: you write it on a piece of paper and then hand it to //Person B//) all's well and good. However, if you send it over an untrusted medium (e.g.: the Internet), you should sign //Person A//'s public key with your private key. As a result, //Person B// can validate the integrity of //Person A//'s key with your public key.
-# <​tool_name>​ <​subject>​ <​action>​ +
-$ gcloud projects list               +
-PROJECT_ID ​     NAME            PROJECT_NUMBER +
-lab-radumantu ​  ​lab-radumantu ​  ​1234567890 +
-</code>+
  
-<note tip> +This example with //Persons A and B// is characteristic of the [[https://​en.wikipedia.org/​wiki/​Web_of_trust|Web of Trust]] model. In itevery participant is responsible not only for his own key, but for those that he decides to add to his key ring -- and thus, implicitly trustAs you can imaginevalidating each new person (or server) that you communicate with can become taxing. Consequently,​ it's no surprise that the most prevalent model today is the [[https://en.wikipedia.org/wiki/Public_key_infrastructure|Public Key Infrastructure]]. Further discussing the differences between these two models falls beyond the scope of this lab. However, this is a topic that you should research sooner rather than later (so don't wait for it to be mentioned during lectures).
-If you're unsure what a command does, add ''​%%--%%help''​ anywhere to get a manual pageOtherwisecheck the [[https://cloud.google.com/sdk/gcloud/​reference|web reference]].+
  
-----+For now, let's get you started by generating a brand new 4096-bit RSA keypair. Make sure to introduce your __real__ name and email. At some point, you will be prompted for a password. That password is to secure your key ring. Its only purpose is to prevent attackers that have gained access to your computer from using your keys. Otherwise, the password will not factor in any of the cryptographic operations that **gpg** performs.
  
-If you're still using **zsh**, first of all congrats. Second, try tab completion to get a list of possible commands based on what you've already written:+<code bash> 
 +# generate key 
 +$ gpg --full-generate-key
  
-<code bash> +# list keys 
-gcloud compute networks <​TAB>​ +gpg --list-public-keys 
-create ​                  get-effective-firewalls ​ subnets ​                                         +$ gpg --list-secret-keys
-delete ​                  list                     update ​                                         ​ +
-describe ​                ​peerings ​                vpc-access ​+
 </​code>​ </​code>​
-</​note>​ 
  
-Note that sometimesthe feature that you want to access is in fact hidden behind the **alpha** or **beta** commandsThese commands indicate that the development version ​of regular commands should be used in stead.+Nowlet's upload your public key to [[https://​github.com/​settings/​keys]]. Click on ''​New GPG key''​ and copy paste the output ​of the following command:
  
 <code bash> <code bash>
-try to list your configured billing accounts +export public key 
-gcloud billing accounts list +gpg --armor --export ${YOUR_MAIL_GOES_HERE}
-ERROR: (gcloud.billing) Invalid choice: '​accounts'​. +
-This command is available in one or more alternate release tracks. ​ Try: +
-  gcloud alpha billing accounts +
-  gcloud beta billing accounts +
-   +
-# now try the same thing with the alpha variant of the command +
-$ gcloud alpha billing accounts list +
-ACCOUNT_ID ​           NAME                           ​OPEN ​  ​MASTER_ACCOUNT_ID +
-XXXXXX-XXXXXX-XXXXXX ​ Billing Account for Education ​ True+
 </​code>​ </​code>​
  
-Now knowing ​your //project ID// and your //billing account ID//it's time to link the two. This waywhen you request resource allocation from the **gcloud compute** engine, Google will know to use the %%$%%50 credit account (charges are usually made at the end of the month)While there'​s also an [[https://cloud.google.com/​sdk/​gcloud/​reference/​alpha/billing/accounts/​projects/​link|alpha version]] of the following commandwe'll be using the //recommended// **beta** variant:+<note important>​ 
 +In the example commands, we will use the bash / shell syntax for variable interpolation:​ ''​${VARIABLE_NAME}''​. 
 +You can either define that variable in your shell instance (e.g., ''​VARIABLE_NAME="​value"''​ or simply replace the variable reference with your desired value when typing the command, e.g., ''​gpg --armor --export my.email@gmail.com''​) 
 +</note> 
 + 
 +Notice the ''​%%--armor%%''​ flag. Without it, the command above would write your key in a binary format to //stdout//. With it, **ASCII armor** is applied ​to the outputASCII armor is a technique that encodes your binary data using algorithms such as [[https://en.wikipedia.org/wiki/Base64|base64]] in order to make it ASCII-printable. Because only a subset ​of 8-bit values are printable, a number of bits smaller than 8 (e.g.: for b64 encoding that number is 6) are expanded to a full ASCII printable byte. Naturally, this leads to output inflation but at the very least you can copy paste data or send it via email without attachments. 
 + 
 +From now onyou can add the ''​%%-s,​ --signoff%%''​ flag to ''​git commit''​ and it will automatically add a //"​Signed by ..."// message at the end of your commit message and sign it with your default private key. Alternatively,​ if you don't want that trailing message, you can use ''​%%-S,​ --gpg-sign[=<​keyid>​]%%''​. If you want to configure ​**git** to automatically sign all commits with a certain key, you can do so thusly:
  
 <code bash> <code bash>
-link billing account to gcloud project +get your private key fingerprint (long upper case hexstring) 
-gcloud beta billing projects link ${PROJECT_ID} --billing-account ​${BILLING_ACC_ID}+gpg --list-secret-keys 
 +  
 +# configure your default signing key (git user.{name,emailmust match those in key) 
 +$ git config ​--global user.signingkey ​${PRIVATE_KEY_FINGERPRINT} 
 + 
 +# enable autosigning 
 +$ git config --global commit.gpgsign true
 </​code>​ </​code>​
  
-Before we proceed to actually starting instances in different locations, here's one final config that we should do. +=== [10p] Task B - Your first signed commit ===
-<code bash>+
  
-# set default project id +Create a public repository on GitHub and [[:​ii:​labs:​04|add your music bot]] from lab 4 as a first commit. Make sure you use ''​git commit -s'',​ then push your changes to remote. Go to the //"​github.com/​.../​commits"//​ page of your repo and check that your commit has a green //"​Verified"//​ tag next to it.
-$ gcloud config set core/project ${PROJECT_ID}+
  
-# check that new value was saved +<​note>​ 
-$ gcloud ​config ​list +__**Troubleshooting**__ 
-[core] + 
-... +If ''​git commit -s''​ fails, there are usually two reasons. Prepend ''​GIT_TRACE=1''​ to the command and run it again. Look for the last command executed in the background by **git** before the error occurred (most likely an invocation of **gpg**) and run it separately. This will give you a more verbose error that will let you determine the problem. Here are the usual suspects: 
-project ​= ${PROJECT_ID+  * The ''​user.name''​ and ''​user.email''​ values that you previously ​ configured with ''​%%git ​config [--global]%%''​ differ from what you specified when creating the **gpg** public keypairRemember that ''​user.name''​ is not the same as your account username on GitHubIt is the name under which you publish your commits and can be whatever you want it to be, but be consistent! 
-</code>+  * **gpg** has no idea how to ask you for the passphrase needed to decrypt your keyring. This might be an issue when invoking it indirectly from **git**, usually from [[https://​docs.microsoft.com/​en-us/​windows/​wsl/​install|wsl]]. Add ''​export GPG_TTY=$(tty)''​ to your //.zshrc// or //.bashrc// and source it. This environment variable will let **gpg** know that it should use an [[https://​en.wikipedia.org/​wiki/​Ncurses#:​~:​text=ncurses%20(new%20curses)%20is%20a,​runs%20under%20a%20terminal%20emulator.|ncurses]]-based terminal prompt. Note that after you input your passphrase once, it will be temporarily cached by a daemon named **gpg-agent**. As a last resort, try running ''​%%gpg --sign ​${SOME_FILE}%%''​ just so ''​git commit -s''​ won't ask you for it afterwards. Again, this is only a workaround, not a solution. Ask your assistant for help! 
 +</note>
  
-Setting the //​core/​project//​ propriety is optional. However, not setting it would have meant that every time you invoked a **gcloud compute** command, you would have been required to also pass a ''​%%--%%project=${PROJECT_ID}''​ flag. Which is annoying... 
ii/labs/05/tasks/01.1642503720.txt.gz · Last modified: 2022/01/18 13:02 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0