Giter VIP home page Giter VIP logo

myproxystarv3's Introduction

Contents of this file:

-Installation Guide --> How to set up the environment

-Simulation Guide --> Obtain a STAR certificate yourself

-Round-Trips Guide --> In depth explanation of every step in STAR

Parts involved in STAR: 1.Boulder/STAR Server 2.DNO/ STAR Proxy 3.CDN/ Star Client

INSTALLATION GUIDE

These are the steps to get the whole simulation going:

  • Prepare 3 VM using ubuntu: Server, Proxy, Client

Prepare the Server:

  • In your home directory create: ~/gopath/src/github.com/letsencrypt/boulder and place all the files there.(the files that are currently in https://github.com/diegoDAguilar/myBoulder. NOTE: When you have everything copied you should't have a myBoulder file, everything must be inside letsencrypt/boulder/, if you do an "ls" in letsencrypt/boulder/, it must return the files that are currently under myBoulder/boulder)

  • Install GO and set environment variable PATH to /usr/local/go/bin. My version ($go version) "go1.8.1 linux/amd64"

  • Fully install Docker and Docker-Compose: https://docs.docker.com/compose/install/ just follow the steps and test that the hello-world image works. I m using version 17.03.1-ce for Docker and version 1.12.0 for Docker-Compose.

  • Go to boulder/test/config/va.json and make sure your port config in va is : 80 for httpPort, 5001 for httpsPort and 5001 for tlsPort.(Some of these changes may be redundant, but this way it works, so don't ask ;) )

  • Go to boulder/docker-compose.yml and check that in the list of ports you have 80:80 and 443:443, be careful not to tab as it is an illegal char (these 2 steps are already done if you download my repo, do them if you are using common Boulder)

  • Back in boulder/docker-compose.yml change the FAKE_DNS field to the IP of the VM that will act as your server.

  • Set ufw status to inactive: sudo ufw disable

  • Check your iptables policy: "sudo iptables -L" and set CHAIN FORWARD policy to accept if it is currently in DROP mode: "sudo iptables -P FORWARD ACCEPT"

  • Make sure you can reach the other machines by pinging them and change the route table if needed.

  • Open /etc/hosts and add these 2:

    172.17.0.4 acme-v01.api.letsencrypt.org boulder //this is the local IP of Boulder at least in my machine //If using "ifconfig" in the server returns you an interface //called docker0 172.17.0.1, then it should be the same.

    "proxy's IP" bye.com //this is the web hosted for the example. Because it is not available in the Web, the server must know that it is in the proxy machine, so here //we make sure of it.

Prepare the Proxy:

-The current proxy has been tested being root in the VM so: "sudo -i" and place a new directory there with all the files in https://github.com/diegoDAguilar/MyProxy so that the end directory of files such as proxySTAR.go and exeAutoRenew.sh is /root/

  • Go to certbot/ and type: "source ./venv/bin/activate" (You always need this ON so remember to execute this command again if you exit the VM)

  • Declare global environment: export SERVER=http://172.17.0.4:4000/directory (this is where Boulder is listening)

  • Install Go, my version ($go version) is : go1.8.2 linux/amd64

  • Set GOPATH to /root/gopath and PATH to /root/go/bin

  • Make the same ping and iptables checks that we did preparing the server: chain policy set to ACCEPT, pinging between vm.

  • Host some website. This is the site for which we are gonna request the certificates. The way I did it is using Apache (e.g. bye.com):

    1. Place an html file in /var/www/bye.com/html/bye.html. An example could be:
     <HTML>
      <HEAD>
     		<TITLE>
     			 A Small bye placed in 192.168.122.125 PROXY
     		</TITLE>
      </HEAD>
     <BODY>
      <H1>Bye</H1>
      <P>This is a very minimal "bye bye cruel world" HTML document.</P>
     </BODY>
     </HTML>
    
     2. Go to /etc/apache2/sites-available and copy a file called 000-default.conf in the same directory as bye.com.conf: "sudo cp 000-default.conf bye.com.conf"
     3. Open this new file and make sure VirtualHost in the first line is set to *:80 and the rest of the fields look like this (although ServerAdmin isn't important for now so leave it out if you want):
     			ServerAdmin [email protected]
         ServerName bye.com
         ServerAlias www.bye.com
         DocumentRoot /var/www/bye.com/html
    4. In sites-available run this commands:
     	sudo a2ensite bye.com.conf
     	sudo a2dissite 000-default.conf
     	sudo service apache2 restart
    
  • Now it comes the most difficult step: Preparing the proxy for the http challenge. This is the challenge that we will use in the request. Create 2 directories so the result is like this: /var/www/bye.com/html/.well-known/acme-challenge

  • IMPORTANT: Now you have to make sure that you can access the directory acme-challenge, so place a hello.html file there and try to reach it with curl from the server, if it works feel free to delete it. If it doesn't, change the file permissions going to /var/www and typing "sudo chmod -R 644 bye.com" and change the user so it isn't root: "sudo chown -R user:user bye.com" <----IMPORTANT: user:user is your name and group, so if your user in the VM is Josh from the Goonies--> sudo chown -R Josh:Goonies bye.com

-For the simulation to work, you also need to generate a certificate using openSSL so that proxy and client can use https: "openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365" This generates a certificate and a key that have to be kept in the same directory as proxySTAR.go, I am including a cert and key in the Github, but they may be outdated.

-Give execution permisions to all bash scripts executing in /root/: "sudo +x chmod *.sh"

SIMULATION GUIDE

HOW TO RUN A FULL SIMULATION

  1. If you have restarted the server VM and want to ask for new certificates or mainly if some error happens but it is not fatal for the CA (if it is still UP), then go to the proxy and execute: "sudo rm -rf /etc/letsencrypt"

  2. In the server go to ~/gopath/src/github.com/letsencrypt/boulder

  3. Run the renewalManager in background: "go run renewalManager.go &" //Uncomment the line that says "Message" in function checkStatus() if you want to get notified when the renewal does a check. ...and these 2 commands to run Boulder: docker-compose build docker-compose up

    And wait until it says "All servers running. Hit ^C to kill", the first time it may take a while

  4. Go to proxy as superuser ("sudo -i") and type in ~/certbot# source ./venv/bin/activate

  5. Then: export SERVER=http://172.17.0.4:4000/directory 4.5 If you just followed the installation there's not need to do 3 & 4, you just did them.

  6. Now you are ready to go: "go run proxySTAR.go" You will see a message: "Proxy STAR status in middlebox is: ACTIVE"

  7. Go to client VM and POST at https://certProxy:443/star/registration (Don't forget to add certProxy to your /etc/hosts as the Proxy's IP). For now the full command looks like this: curl --cacert /usr/share/ca-certificates/mozilla/server.crt
    -H "Content-Type: application/json" -X POST -d
    @fullCSR2 https://certProxy:443/star/registration

     *server.crt is an openssl cert I generated so proxy and client can use https, it is the same certificate that we obtained for the proxy with openSSL in the installation guide.
     *fullCSR2 is a textfile that contains a basic CSR with the domain name bye.com as SN field
     (subject name) plus lifetime and validity in format:
    
     {"csr":"-----BEGIN CERTIFICATE REQUEST-----\n
     MIICmDCCAYACAQAwUzELMAkGA1UEBhMCTU0xCjAIBgNVBAgMAWsxDDAKBgNVBAcM\n
     A2xsbDEKMAgGA1UECgwBdDEMMAoGA1UECwwDdGlkMRAwDgYDVQQDDAdieWUuY29t\n
     MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmm74/AotkDGzsdVsn+Vu\n
     Z4FHW2+lf3HrLcDlpWHvBl3WSLg2TJHXdl8F6GtI3w91Cws/8wT4g+W33GYB0WAF\n
     WIGvzTPajeZ3jQt4t98bpzbuaFZz8QCoQVuEOuk8CCQ5/Cezbml3loMtXTuR+R1c\n
     OuVB9sFXbpoGvGL2fbAmrTtmOY9ZoXaLQmN7sj+4TjKRtZvVdpiLRaYp608ct2h3\n
     E6R2Nzm0OHdI35y61jaw46WiXCM30W/V2/Ia0c35Jdy4vbPybH1+k4ajmrlwiFrO\n
     986AlAxvxDZIKtahQFqMdH3hEuzTR6OnDwMlDtkLXThE9XSmcAhdYd9RLC8hF33A\n
     SQIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAF7ja2QCYDPfJ3kY0f4eSYaAaQba\n
     bQ6TA2dS5AFz+WSdzBQTTa8uTzgrKOwe8mQoHhjsNHW6aRpYCxje2v0pzTMw27g2\n
     YmXdfEfmWsF4GHk2NZ3ECE7LwA0YlsGZXpmYkUT89+69cJiiqiWUpwaGQdbx2Ozs\n
     N7tlHLlLDufQubnMetOfNb7SbyMpCdNssAaj7gkkmeOHk9rjlkrpkBJf8lBb2xIo\n
     XFH3iswaojVO3pAKZytDPrx9tsAsLstx6Jv6+O5lfr9rS4+EAT19yeZgd/64qTjl\n
     yx1r4nkEp7Z/brWh4X3q8zUhBQCLSeHIXp9nWj69WGXFtTOqcyx+uruc/Qw=\n
     -----END CERTIFICATE REQUEST-----","lifetime":365,"validity":21}
    
     To generate this text file first generate a private key and a CSR:
     "openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key"
    
     See its contents:
     "cat CSR.csr"
    
     And copy it into a new file following the format above. Dont forget to add lifetime and validity at the end and "\n" 	
     after each row. I ll remove this asap so it less tedious.
    
  8. After the client executes the command in step 6 it will get a message similar to this one: "Location: https://certProxy/star/registration/0" Now if the client goes to this URI: "curl --cacert /usr/share/ca-certificates/mozilla/server.crt https://certProxy:443/star/registration/0" It will get a message back. This response can be {pending} or {status, lifetime,the uuid4 that serves as URI} E.g. {valid 365 20b1bac1-db72-42f4-9620-add03c789e36}

  9. The client can retrieve the chained cert by using: curl http://172.17.0.4:9898/20b1bac1-db72-42f4-9620-add03c789e36

    *20b1bac1...is this example's certificate URI

  10. To check that the renewalManager has done it's job -or if you forgot to run it, you can do so now and it will still work- put the Boulder in background: "^Z" "bg" And check the crontab: "sudo crontab -l",

  11. Renewals will be at the same URI that the first certificate, so DNO is not needed and can be turned OFF if you want so.

11.Note that a new directory has been created in the Server VM, this directory contains NEEDED information for the renewal so deleting it will cause renewals to fail.

ROUND-TRIPS GUIDE

Time 0: SERVER: Boulder is running RenewalManager in the CA is running Proxy: Proxy is running Proxy hosts a web using apache

Communication between Proxy and Client is safe: Proxy has a cert issued by openssl and the client acknowledges the site as safe.
READ BOTH INSTALLATION AND SIMULATION GUIDE IF YOU ARE ALREADY LOST :)

Time 1:

Client:
		It calls the proxy with https by using the certificate with argument --cacert:

		curl --cacert /usr/share/ca-certificates/mozilla/server.crt -H \
		"Content-Type: application/json" -X POST -d @fullCSR https://cert\
		Proxy:443/star/registration

Proxy: proxySTAR.go
		function parseJsonPOST handles :443 /star/registration requests

		parseJsonPOST translates the block of data into a struct {csr,lifetime, validity}
		if lifetime and validity are appropiate it then proceeds to call decodeCsr.

		func decodeCsr uses a helper script called getCsrAsText.sh and finally returns the csr field
		as plain text, keeping a copy in the file tmpCsr, that will be deleted afterwards.

		Back in parseJsonPOST it uses the csr (now a string) as a parameter for func parseFieldsOfCsr.
		This function shall retrieve the domain contained in the csr field of the already mentioned struct and returns
		it as a string called subjectName.

		At this point in time, the proxy has info about: domain, lifetime and validity and has validated that both
		lifetime and validity are OK so it sends back the URL where the info about the certificate will be posted:

		Location: https://certProxy/star/registration/$ID

		As time goes on and multiple requests are made the $ID will increase.

		Function storeIssuedCerts is called. This will storage all the information
		processed by the proxy so that Certbot can read it when it gets executed.
		If these files dont exist Certbot client will ignore STAR.

		parseJsonPOST executes function callCertbot

Time 2:

Proxy: proxySTAR.go

		function callCertbot runs cerbot application by passing the csr and the domain names as arguments.
		It uses cerbotCall.sh to do the execution.

Proxy: Certbot
		Normal execution of the Certbot client with csr as a parameter but with 4 extra fields sent in the POST to
		Boulder added in acme/acme/client.py and messages.py.
		These fields are:
		{recurrent_cert_uuid,
		recurrent,
		recurrent_cert_validity,
		recurrent_cert_lifetime}

		recurrent_cert_uuid: contains the UUID where certificates will be posted
		recurrent: contains parameter true and it serves to turn STAR ON
		recurrent_cert_validity: validity for STAR certificates
		recurrent_cert_lifetime: contains the lifetime, so it is key for renewal

		When certbot is called it checks if file the tmp files with the STAR information exist, if so, it then reads the
		these files, deletes them and sends them to Boulder in the same certificate request.

Boulder: wfe.go
		If Boulder function verifyPOST reads field "recurrent: true" in the Json sent by Certbot then it starts STAR. It
		reads all the recurrent fields and saves them into temporary files and finally to a directory with these
		features:
			The main directory is "./starCerts" and will be created in the same directory where Boulder is. This
			means, in my case it is in:

			~/gopath/src/github.com/letsencrypt/boulder/starCerts

			In ./starCerts files with the cert uuid as its name will be created, inside each file the info for the
			certificate renewal will be storaged:

			certificate.pem
			csr
			validity

			Why lifetime isn't in this file will be explained later.

		Before the csr is saved, STAR function repairCsr will make sure the csr is valid for future operations. The
		reason why this is a MUST is because at this point the csr has lost its base64 format and has lost the
		noninformation bits(stuffing).


		After this operation, server operations continue as normal, forwarding the csr until it reaches the CA.

Boulder: ca.go

		When the time to create the certificate comes, function issueCertificate looks for the temporary files created
		in wfe.go and if it finds them, it issues a short-term certificate. If it doesn't find it, duration is set to 3
		months.

		WARNING: In case the config file is set to other value it won't read it.

		STAR function postAtUuid serves the file certificate.pem at:
		172.17.0.4:9898/$URI
		this means that it will be serving a STAR certificate for every STAR URI.

		STAR function addSTARToCron creates a file called "./renewMTmp/renew1" and it
		saves info for the renewals: {domain, lifetime, uuid}
		The reason why it saves information for the renewal instead of just adding it
		to cron right away is because ca.go is running inside a docker and the docker
		doesn't have a crontab so another process running outside of the docker needs to
		pick up the information inside this file "./renewMTmp/renew1" and add it to the
		system's crontab.

Boulder: ra.go

		Function NewCertificate checks if STAR is ON (again thanks to the tmp files) and then storages the
		certificate in the file certificate.pem mentioned before, the key part is that it adds a chain of
		certificates by using the CA root certificate.

Time 3:

Proxy: certbot

	Proxy's certbot side receives confirmation that the certificate challenge and certificate issuance have succeeded.

Proxy: proxySTAR.go
	proxy then storages all the info about the certificate it just issued incluiding:
	certificate.pem: It is an isntace of the first certificate.
	csr: The csr the client used.
	uri: The uri where the STAR certificates are posted (unique for each certificate)
	validity: validity of every STAR

	Keeping these files isn't NEEDED for STAR but because the Proxy is the real owner of the domains, it is considered that
	knowing what name delegations are active is key. What's more, keeping the uri will allow the DNO to terminate the
	renewals.

Time 4:

Client:
	If the client executes a curl to reach /star/registration/$ID will obtain:
	{
		status: valid,
		lifetime: 365, //just an example
		certificate: 609577eb-f47b-4443-8df6-ba926dbdcd6c //URI where the certificate is
																											//available at 172.17.0.4:9898
	}

Time 5:

	CA: renewalManager.go
		The renewal manager is running in the CA background.
		It tries to read file "./renewMTmp/renew1" every 10 seconds (this time can be modified in function checkStatus)
		and adds a cronjob that will execute itself every 24h and will look like this:

		50 8 * * * sh /home/acme-server2/gopath/src/github.com/letsencrypt/boulder/exeAutoRenew.sh  bye7.com 04 08 
		6d53bdbb-beed-41d5-ae12-fe71bfe71b880ea26

		The first 5 parameters ensure the 24h execution at 8:50 everyday.
		The next one is a script: exeAutoRenew.sh that executes with 4 parameters:
		{domain, day and month when the lifetime expires(NOTE: it is the STAR lifetime, not a cert's lifetime), uri}

	CA: exeAutoRenew.sh
		This script first checks if its day&month arguments match the current day, if they match, it deletes the cronjob
		that executes this script every 24h.
		If they don't match, it means certificate's lifetime hasn't expired and will renew the cert.
		The cert is renew using openssl with all the parameters that had been saved so a new certificate will be
		generated.
		The most important part of this new issued certificate is that it contains the same key Boulder uses and that is
		located in boulder/test/test-ca.key

myproxystarv3's People

Watchers

James Cloos avatar

Forkers

trellixvulnteam

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.