Clean readme
This commit is contained in:
parent
7ae94371a8
commit
b8ad9c1c03
3 changed files with 27 additions and 841 deletions
323
README.md
323
README.md
|
|
@ -1,116 +1,4 @@
|
|||
# TLS power measure benchmark
|
||||
|
||||
Goal: measure the power overhead of adding TLS to a client or a server, on realistic loads.
|
||||
|
||||
Realistic load implies using a real-world client (such as a web browser on a low-end device) and server (such as a video streaming platform on a typical server).
|
||||
|
||||
Problem: realistic clients have complex behaviors that go beyond a simple OpenSSL example code, and modern browsers and website won't work without HTTPS.
|
||||
|
||||
Assumption: most of the load added by the security layers is decoupled from the application (in both web browsers and web servers).
|
||||
|
||||
```
|
||||
Experiments:
|
||||
1: (Client) <=[TLS]=> (Proxy 1) <-[plain]-> (Proxy 2) <-[plain]-> (Proxy 3) <=[TLS]=> (Server)
|
||||
2: (Client) <=[TLS]=> (Proxy 1) <==[TLS]==> (Proxy 2) <-[plain]-> (Proxy 3) <=[TLS]=> (Server)
|
||||
3: (Client) <=[TLS]=> (Proxy 1) <-[plain]-> (Proxy 2) <==[TLS]==> (Proxy 3) <=[TLS]=> (Server)
|
||||
^measure^
|
||||
```
|
||||
|
||||
Client and server are identical in all experiments. The only modification made to the client is to add a trusted certificate owned by Proxy 1.
|
||||
|
||||
Only Proxy 2 must be a dedicated machine. The other parties may be placed on the same machine.
|
||||
|
||||
Call E1, E2, E3 the energy measured for Proxy 2 in experiments 1, 2, 3.
|
||||
|
||||
E2-E1 is the energy used to operate the server's half of a TLS connection.
|
||||
|
||||
E3-E1 is the energy used to operate the client's half of a TLS connection.
|
||||
|
||||
Client:
|
||||
* Web browser trusting a certificate owned by Proxy 1
|
||||
|
||||
## Things to experiment
|
||||
|
||||
* Implementations
|
||||
* OpenSSL 1.0.2
|
||||
* OpenSSL 1.1.1
|
||||
* OpenSSL 3.0
|
||||
* OpenSSL 3.2
|
||||
* OpenSSL 3.3
|
||||
* OpenSSL 3.4
|
||||
* OpenSSL 3.5
|
||||
* OpenSSL 3.6
|
||||
* [WolfSSL](https://github.com/wolfSSL/wolfssl)
|
||||
* GnuTLS
|
||||
* [NSS](https://github.com/nss-dev/nss) (used by Firefox) (?)
|
||||
* opencryptoki (?)
|
||||
* AWS-LC
|
||||
* [BoringSSL](https://github.com/google/boringssl) (Chrome, Android)
|
||||
* LibreSSL
|
||||
* [SymCrypt](https://github.com/microsoft/SymCrypt) (used by Windows) ([install manually](https://github.com/microsoft/SymCrypt/releases))
|
||||
* Versions
|
||||
* TLS 1.2
|
||||
* TLS 1.3
|
||||
* Features
|
||||
* TLS
|
||||
* Ciphers
|
||||
* TLS_AES_128_GCM_SHA256
|
||||
* TLS_AES_256_GCM_SHA384
|
||||
* TLS_CHACHA20_POLY1305_SHA256
|
||||
* TLS_AES_128_CCM_SHA256
|
||||
* TLS_AES_128_CCM_8_SHA256
|
||||
* Key exchange groups
|
||||
* secp256r1
|
||||
* secp384r1
|
||||
* secp521r1
|
||||
* x25519
|
||||
* x448
|
||||
* ffdhe2048
|
||||
* ffdhe3072
|
||||
* ffdhe4096
|
||||
* ffdhe6144
|
||||
* ffdhe8192
|
||||
* Signatures
|
||||
* rsa_pkcs1_sha256
|
||||
* rsa_pkcs1_sha384
|
||||
* rsa_pkcs1_sha512
|
||||
* ecdsa_secp256r1_sha256
|
||||
* ecdsa_secp384r1_sha384
|
||||
* ecdsa_secp521r1_sha512
|
||||
* rsa_pss_rsae_sha256
|
||||
* rsa_pss_rsae_sha384
|
||||
* rsa_pss_rsae_sha512
|
||||
* ed25519
|
||||
* ed448
|
||||
* rsa_pss_pss_sha256
|
||||
* rsa_pss_pss_sha384
|
||||
* rsa_pss_pss_sha512
|
||||
* rsa_pkcs1_sha1
|
||||
* ecdsa_sha1
|
||||
* X.509
|
||||
* Signature algorithm
|
||||
* RSA2048
|
||||
* RSA3072
|
||||
* RSA4096
|
||||
* EC 256
|
||||
* EC 384
|
||||
* SCT
|
||||
* TODO !!!
|
||||
* Usages
|
||||
* Video streaming
|
||||
* Full-speed download
|
||||
* Real-time video call
|
||||
* Mostly text browsing
|
||||
* With or without ads
|
||||
|
||||
Most of the implementations can be used through RusTLS.
|
||||
|
||||
However RusTLS clients won't enable to force TLS1.2 if 1.3 is available.
|
||||
|
||||
* séparer conso crypto / trafic
|
||||
* mesure avec debugger : quelles fonctions consomment
|
||||
* mesure mémoire
|
||||
* mesure overhead
|
||||
# TLS
|
||||
|
||||
### WolfSSL
|
||||
|
||||
|
|
@ -123,89 +11,16 @@ make
|
|||
sudo make install
|
||||
```
|
||||
|
||||
## State of the art
|
||||
|
||||
* https://pub.h-brs.de/frontdoor/deliver/index/docId/4771/file/2019-ESP32-TLS-Power.pdf
|
||||
* 2019
|
||||
* TLS 1.2, 1.3
|
||||
* ESP32
|
||||
* WolfSSL
|
||||
* https://www.semanticscholar.org/paper/Energy-Consumption-Framework-and-Analysis-of-on-Patterson-Buchanan/706736a29cef777e5dc50ba22b4788b2bfb4c6ef
|
||||
* 2025
|
||||
* RaspberryPi
|
||||
* OpenSSL
|
||||
* ML-KEM
|
||||
* https://www.semanticscholar.org/paper/Energy-Profiling-and-Comparison-of-TLS-Protocols-Gatram-Reddy/9c061fe57a0008574b85919bc70fc803c6e66f06
|
||||
* Energy Profiling and Comparison of TLS Protocols for Embedded Devices: Experimental Study
|
||||
* 2024
|
||||
* RaspberryPi
|
||||
* TLS PQ, TLS KEM, TLS
|
||||
* https://www.semanticscholar.org/paper/Energy-Consumption-Evaluation-of-Post-Quantum-TLS-Tasopoulos-Dimopoulos/2ffc6d13349e2fa5f89aaf18e69ce2044ecef4fe
|
||||
* 2023
|
||||
* STM Nucleo
|
||||
* WolfSSL
|
||||
* TLS 1.3 PQ
|
||||
* https://arxiv.org/pdf/2508.04583v2
|
||||
* 2025
|
||||
* TLS 1.3
|
||||
* Nginx + Python requests
|
||||
* https://github.com/MarcT0K/privacy-carbon-experiments
|
||||
* https://davidtnaylor.com/CostOfTheS.pdf
|
||||
* 2014
|
||||
* https://www.researchgate.net/publication/359906722_Performance_Analysis_of_SSLTLS_Crypto_Libraries_Based_on_Operating_Platform
|
||||
* 2022
|
||||
* throughput & cpu
|
||||
* OpenSSL, GnuTLS, Boring, S2n, NSS, Cryptlib
|
||||
* https://www.haproxy.com/blog/state-of-ssl-stacks
|
||||
* 2025
|
||||
* OpenSSL
|
||||
* https://ieeexplore.ieee.org/abstract/document/5983970
|
||||
* TLS and energy consumption on a mobile device: A measurement study
|
||||
* 2011
|
||||
* TLS
|
||||
* Nokia phone
|
||||
* https://dspace.mit.edu/handle/1721.1/111861
|
||||
* Energy-efficient protocols and hardware architectures for transport layer security
|
||||
* 2017
|
||||
* https://dl.acm.org/doi/abs/10.1145/871506.871518
|
||||
* Analyzing the energy consumption of security protocols
|
||||
* 2003
|
||||
* SSL
|
||||
* https://ieeexplore.ieee.org/abstract/document/1563998
|
||||
* A study of the energy consumption characteristics of cryptographic algorithms and security protocols
|
||||
* 2003
|
||||
* SSL
|
||||
* https://ieeexplore.ieee.org/abstract/document/8598334
|
||||
* Energy and Processing Demand Analysis of TLS Protocol in Internet of Things Applications
|
||||
* 2016
|
||||
* TLS
|
||||
* https://dl.acm.org/doi/10.1145/3345768.3355924
|
||||
* A Comprehensive Empirical Analysis of TLS Handshake and Record Layer on IoT Platforms
|
||||
* 2019
|
||||
* IoT, TLS
|
||||
* https://hal.science/hal-04197885/document
|
||||
* Empreinte carbone de la transmission de données sur le backbone RENATER
|
||||
* 2021
|
||||
* https://ieeexplore.ieee.org/document/10971851/
|
||||
* Optimizing TLS/SSL for IoT Devices: Performance Enhancements and Security Considerations
|
||||
* 2024
|
||||
* https://ieeexplore.ieee.org/document/10060762/
|
||||
* Performance Evaluation of Quantum-Resistant TLS for Consumer IoT Devices
|
||||
* 2023
|
||||
*
|
||||
* Evaluating the Energy Profile of Tasks Managed by Build Automation Tools in Continuous Integration Workflows: The Case of Apache Maven and Gradle
|
||||
* 2025
|
||||
|
||||
## Sources
|
||||
|
||||
* [RFC8446 (TLS 1.3)](https://datatracker.ietf.org/doc/html/rfc8446)
|
||||
|
||||
## Reproduce
|
||||
|
||||
### Record
|
||||
|
||||
On the controler machine.
|
||||
|
||||
#### Installation
|
||||
|
||||
Build netreplay and copy it in this folder.
|
||||
|
||||
Authorize netreplay to bind to ports 80 and 443:
|
||||
```bash
|
||||
sudo setcap CAP_NET_BIND_SERVICE=+eip netreplay
|
||||
|
|
@ -221,11 +36,10 @@ In settings, disable DNS security.
|
|||
|
||||
In `about:config`, set `network.dns.forceResolve` to `127.0.0.1`.
|
||||
|
||||
Run the shell commands:
|
||||
Run the shell command:
|
||||
|
||||
```bash
|
||||
python exp.py make debug -c
|
||||
python exp.py update-certs debug
|
||||
```
|
||||
|
||||
In Firefox, go to security settings, Certificates, import `/dev/shm/exp/certs/prime256v1/ca.crt` and trust it for identifying websites.
|
||||
|
|
@ -240,85 +54,40 @@ Start the record proxy:
|
|||
./netreplay records/mynewrecord record
|
||||
```
|
||||
|
||||
Just browse. Any traffic to and from the selected names will be recorded. Terminate netplayer with CTRL+C when finished.
|
||||
|
||||
#### Incomplete records
|
||||
|
||||
The last HTTP payload of a record may be incomplete. If that happens, the run command will hang and display the faulty record number after a timeout.
|
||||
Re-run with `-d --record <record-number>` and note the missing packet number.
|
||||
Run `netreplay <record-file> remove <new-record-file> <record-number> <packet-number>` to remove the packet.
|
||||
Just browse. Any traffic will be recorded. Terminate netplayer with CTRL+C when finished.
|
||||
|
||||
### Measure
|
||||
|
||||
Measure resource cost on a different machine.
|
||||
Copy the tlsbench folder on the target.
|
||||
Build netreplay with the wanted cryptographic backends on the target (one build per backend), and place each version in tlsbench, named `netreplay-aws-lc`, `netreplay-boring`, etc.
|
||||
|
||||
Add p2 the `/etc/hosts`:
|
||||
|
||||
```
|
||||
192.168.3.14 p2
|
||||
```
|
||||
|
||||
Install things on p2:
|
||||
Install dependencies on the target:
|
||||
|
||||
```bash
|
||||
sudo apt install acct dtach
|
||||
sudo chmod +s /sbin/sa
|
||||
```
|
||||
|
||||
Modify experiment parameters at the top of `exp.py` to suit your setup and the wanted experiments.
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python exp.py make pi -c
|
||||
python exp.py send pi
|
||||
python exp.py update-certs pi # also do this command on p2
|
||||
python exp.py run pi --idle
|
||||
python exp.py make pi3 -c
|
||||
python exp.py send pi3
|
||||
python exp.py run pi3 --idle
|
||||
```
|
||||
|
||||
On Debian, update-certs says 0 certs added even if it has actually updated some certs. This step is still needed.
|
||||
It may be needed to keep an SSH connection to the target open during the experiment, and to set `RemoveIPC=no` in `/etc/systemd/logind.conf` (then `systemctl restart systemd-logind`).
|
||||
|
||||
### Profile
|
||||
|
||||
Profile code execution on the local machine.
|
||||
|
||||
Add the domains the `/etc/hosts`:
|
||||
|
||||
```
|
||||
127.0.0.1 youtube.com.localhost
|
||||
127.0.0.1 www.youtube.com.localhost
|
||||
127.0.0.1 i.ytimg.com.localhost
|
||||
127.0.0.1 fonts.gstatic.com.localhost
|
||||
127.0.0.1 www.gstatic.com.localhost
|
||||
127.0.0.1 www.google.com.localhost
|
||||
127.0.0.1 accounts.google.com.localhost
|
||||
127.0.0.1 yt3.ggpht.com.localhost
|
||||
127.0.0.1 rr1---sn-gxo5uxg-jqbl.googlevideo.com.localhost
|
||||
127.0.0.1 rr2---sn-gxo5uxg-jqbl.googlevideo.com.localhost
|
||||
127.0.0.1 rr4---sn-q4fl6nds.googlevideo.com.localhost
|
||||
127.0.0.1 fr.wikipedia.org.localhost
|
||||
127.0.0.1 upload.wikimedia.org.localhost
|
||||
127.0.0.1 apple.com.localhost
|
||||
127.0.0.1 www.apple.com.localhost
|
||||
192.168.3.1 youtube.com
|
||||
192.168.3.1 www.youtube.com
|
||||
192.168.3.1 i.ytimg.com
|
||||
192.168.3.1 fonts.gstatic.com
|
||||
192.168.3.1 www.gstatic.com
|
||||
192.168.3.1 www.google.com
|
||||
192.168.3.1 accounts.google.com
|
||||
192.168.3.1 yt3.ggpht.com
|
||||
192.168.3.1 rr1---sn-gxo5uxg-jqbl.googlevideo.com
|
||||
192.168.3.1 rr2---sn-gxo5uxg-jqbl.googlevideo.com
|
||||
192.168.3.1 rr4---sn-q4fl6nds.googlevideo.com
|
||||
192.168.3.1 fr.wikipedia.org
|
||||
192.168.3.1 upload.wikimedia.org
|
||||
192.168.3.1 apple.com
|
||||
192.168.3.1 www.apple.com
|
||||
```
|
||||
|
||||
Install sa:
|
||||
|
||||
```bash
|
||||
sudo apt install acct python3-invoke python3-fabric
|
||||
sudo apt install acct dtach python3-invoke python3-fabric
|
||||
sudo chmod +s /sbin/sa
|
||||
```
|
||||
|
||||
|
|
@ -336,12 +105,9 @@ Install OpenSSL with debug symbols:
|
|||
To build netreplay with this openssl:
|
||||
|
||||
```bash
|
||||
OPENSSL_LIB_DIR=/home/pi/reps/openssl-openssl-3.6.0/ OPENSSL_DIR=/home/pi/reps/openssl-openssl-3.6.0/ cargo build --release
|
||||
OPENSSL_LIB_DIR=/home/pi/reps/openssl-openssl-3.6.1/ OPENSSL_DIR=/home/pi/reps/openssl-openssl-3.6.1/ cargo build --release
|
||||
```
|
||||
|
||||
Or: Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones.
|
||||
It would be simpler with `LD_PRELOAD` but Rust loads dynamic libraries in a particuliar way so it doesn't work.
|
||||
|
||||
Authorize non-root users to use perf:
|
||||
|
||||
```bash
|
||||
|
|
@ -352,8 +118,6 @@ Run:
|
|||
|
||||
```bash
|
||||
python exp.py make local -c
|
||||
python exp.py send local
|
||||
python exp.py update-certs local
|
||||
python exp.py run local
|
||||
python plots.py prof <path/to/log>
|
||||
```
|
||||
|
|
@ -381,10 +145,9 @@ python exp.py make g5k -c
|
|||
python exp.py send g5k
|
||||
|
||||
# Notes
|
||||
scp /lib/x86_64-linux-gnu/libssl.so.3.6 lyon.g5k:~/
|
||||
scp /lib/x86_64-linux-gnu/libcrypto.so.3.6 lyon.g5k:~/
|
||||
scp /lib/x86_64-linux-gnu/libssl.so.3.6 nancy.g5k:~/
|
||||
scp /lib/x86_64-linux-gnu/libcrypto.so.3.6 nancy.g5k:~/
|
||||
scp records/wikipedia nancy.g5k:tlsbench/records/
|
||||
LD_PRELOAD="/home/pengelib/tlsbench/libssl.so.3.6 /home/pengelib/tlsbench/libcrypto.so.3.6" ./netreplay --help
|
||||
```
|
||||
|
||||
#### Wattmetre
|
||||
|
|
@ -392,49 +155,3 @@ LD_PRELOAD="/home/pengelib/tlsbench/libssl.so.3.6 /home/pengelib/tlsbench/libcry
|
|||
API timestamp at Paris time.
|
||||
|
||||
https://api.grid5000.fr/stable/sites/nancy/metrics?nodes=gros-69&metrics=bmc_node_power_watt&start_time=2026-02-26T14:00&end_time=2026-02-26T14:40
|
||||
|
||||
## Problems
|
||||
|
||||
### Youtube
|
||||
|
||||
Youtube utilise des trucs aléatoires en `RANDOM.googlevideo.com` pour la vidéo. Cependant il y a quelques domaines utilisés qui ne changent pas, du moins sur un même navigateur avec la même vidéo et sur une courte période.
|
||||
Avant d'enregistrer le trafic, il faut observer les domaines utilisés puis générer les certificats et les redirections en fonction.
|
||||
|
||||
## Notes
|
||||
|
||||
### CertVerify
|
||||
|
||||
CertVerify est l'extension dans le ServerHello qui signe la discussion passée avec la clé secrète du certificat.
|
||||
|
||||
Il a fallu désactiver la réutilisation de session, qui en TLS1.3 passe par le PSK, pour pouvoir mesurer le CertVerify.
|
||||
|
||||
### Size overhead and usage survey
|
||||
|
||||
```bash
|
||||
openssl s_server -port 8000 -cert /dev/shm/exp/certs/prime256v1/wikipedia.org.crt -key /dev/shm/exp/certs/prime256v1/wikipedia.org.key
|
||||
curl https://wikipedia.org --tlsv1.3 --curves x25519 --connect-to wikipedia.org:443:127.0.0.1:8000 -k
|
||||
```
|
||||
|
||||
Get the most used domains here https://www.akamai.com/fr/security-research/akarank
|
||||
|
||||
```bash
|
||||
python crawler.py crawl /dev/shm/top1K.csv
|
||||
python crawler.py stat /dev/shm/crawl.json
|
||||
```
|
||||
|
||||
### 0-RTT
|
||||
|
||||
```bash
|
||||
echo "hello world" > /dev/shm/ed
|
||||
openssl s_server -port 8000 -cert /dev/shm/exp/certs/prime256v1/wikipedia.org.crt -key /dev/shm/exp/certs/prime256v1/wikipedia.org.key -early_data
|
||||
# First req, without early data
|
||||
echo | openssl s_client -no-interactive -keylogfile /dev/shm/client.txt -sess_out sessions 127.0.0.1:8000
|
||||
# Second req, using 0-RTT for early data
|
||||
echo | openssl s_client -no-interactive -early_data /dev/shm/ed -keylogfile /dev/shm/client.txt -sess_in sessions 127.0.0.1:8000
|
||||
```
|
||||
|
||||
### Re-issuing certificates
|
||||
|
||||
```bash
|
||||
openssl x509 -in oldcert -CA cacertfile -CAkey capkeyfile -out newcert -days 365
|
||||
```
|
||||
|
|
|
|||
10
exp.py
10
exp.py
|
|
@ -260,7 +260,9 @@ CONFIGS = {
|
|||
True,
|
||||
],
|
||||
"records": [
|
||||
{ "filename": "wikipedia", "repeat": 12000, "time": 60 },
|
||||
# Can't repeat more than 8000 times here
|
||||
# TODO check if netreplay client frees ports correctly, or try to reuse ports
|
||||
{ "filename": "wikipedia", "repeat": 8000, "time": 45 },
|
||||
],
|
||||
"repo_dir": "/home/pengelib/tlsbench",
|
||||
"exp_dir": "/dev/shm/exp",
|
||||
|
|
@ -275,7 +277,7 @@ CONFIGS = {
|
|||
"rapl": False,
|
||||
"sa": False,
|
||||
"listen_port": 8080,
|
||||
"idle": "idle - - - - - - - - - 1772205368.593937 1772206568.6941307 1200.1001937389374 0 298843 2217803 16.6 0 -",
|
||||
"idle": "idle - - - - - - - - - 1772205368.593937 1772206568.6941307 1200.1001937389374 0 298843 2217803 5.53333333333333 0 -",
|
||||
"notify_listen": ("0.0.0.0", 8090),
|
||||
"notify_addr": "TODO:8090",
|
||||
"ld_preload": {
|
||||
|
|
@ -326,6 +328,8 @@ DOMAINS_ = [
|
|||
"en.wikipedia.org", "auth.wikimedia.org", "upload.wikimedia.org", "meta.wikimedia.org", "intake-analytics.wikimedia.org",
|
||||
# Google search
|
||||
"www.google.com", "www.googleadservices.com", "www.gstatic.com", "csp.withgoogle.com", "ogads-pa.clients6.google.com", "play.google.com", "ssl.gstatic.com", "fonts.gstatic.com", "ogs.google.com",
|
||||
# Firefox extensions
|
||||
"addons.mozilla.org",
|
||||
]
|
||||
|
||||
CERT_SIGN_ALGS = [
|
||||
|
|
@ -929,7 +933,7 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False):
|
|||
session_count = 0
|
||||
try:
|
||||
while True:
|
||||
rec_count = int.from_bytes(notify_socket.recv(4))
|
||||
rec_count = int.from_bytes(notify_socket.recv(4), "big")
|
||||
if rec_count == 0xffffffff:
|
||||
break
|
||||
if rec_count > session_count:
|
||||
|
|
|
|||
535
exp_proxies.py
535
exp_proxies.py
|
|
@ -1,535 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# OLD VERSION
|
||||
# using 3 proxies between actual browser and actual server
|
||||
|
||||
import os, sys, subprocess
|
||||
|
||||
REPODIR = "/home/tuxmain/Documents/doc/tlsbench"
|
||||
P2_SSH = "exp@p2"
|
||||
P2_PSW = "exp"
|
||||
P2_REPODIR = "/home/exp/exp"
|
||||
EXPDIR = "/dev/shm/exp"
|
||||
DOMAINS_ = [
|
||||
# Apple
|
||||
"apple.com", "www.apple.com", "graffiti-tags.apple.com",
|
||||
"store.storeimages.cdn-apple.com",
|
||||
"mzstatic.com", "is1-ssl.mzstatic.com"
|
||||
# Youtube video
|
||||
"youtube.com", "www.youtube.com", "i.ytimg.com", "fonts.gstatic.com", "www.google.com", "accounts.google.com", "yt3.ggpht.com", "www.gstatic.com", "fonts.googleapis.com", "www.googleadservices.com",
|
||||
# W3C
|
||||
"w3.org", "www.w3.org",
|
||||
# Amazon
|
||||
"amazon.com", "www.amazon.com",
|
||||
# JA3 fingerprint test
|
||||
"www.edgecomputing.live",
|
||||
# JA4 fingerprint test
|
||||
"ja4db.com",
|
||||
# Local test
|
||||
"foo.home",
|
||||
# Peertube
|
||||
"flim.txmn.tk",
|
||||
]
|
||||
|
||||
#URL = "https://www.youtube.com/watch?v=IBWezPN4Ep8"
|
||||
#URL = "https://www.edgecompute.live/tls/ja3"
|
||||
#URL = "https://ja4db.com/id/ja4/"
|
||||
#URL = "https://www.w3.org/"
|
||||
#URL = "http://foo.home:8080/?hello=hi"
|
||||
#URL = "https://www.apple.com/"
|
||||
#URL = "https://www.amazon.com/"
|
||||
URL = "https://flim.txmn.tk/w/4zpfvGB72oTL4hcSqdAwx8"
|
||||
|
||||
URLS = [
|
||||
# Heavy showcase website
|
||||
"https://www.apple.com/",
|
||||
# Light showcase website
|
||||
"https://librezo.fr/",
|
||||
# Long Wikipedia article
|
||||
"https://fr.wikipedia.org/wiki/Sp%C3%A9cial:Recherche?search=Victor+Hugo&sourceid=Mozilla-search",
|
||||
# Youtube video
|
||||
"https://www.youtube.com/watch?v=IBWezPN4Ep8",
|
||||
# Peertube video
|
||||
"https://videos.domainepublic.net/videos/watch/eaee7866-d209-4e5c-b7b0-443395b79c82",
|
||||
# Google search
|
||||
"https://www.google.com/search?q=where+do+birds+go+when+it+rains"
|
||||
]
|
||||
|
||||
CERT_SIGN_ALGS = [
|
||||
"prime256v1", # widely used
|
||||
"secp384r1", # rarely used but supported by browsers because it's NIST standard
|
||||
#"secp521r1", # not supported by browsers because NIST said it was not needed
|
||||
"rsa2048", "rsa3072", "rsa4096", # widely used
|
||||
]
|
||||
IMPLS = [
|
||||
#"aws_lc", # Amazon's Rust crypto widely used in Rust stuff
|
||||
#"boring", # Google's fork of OpenSSL used in Chrome and Android
|
||||
#"openssl", # widely used
|
||||
"ring", # used in most Rust stuff
|
||||
#"symcrypt", # Microsoft's crypto
|
||||
#"wolfcrypt" # used in embedded (won't build with rpxy for now)
|
||||
]
|
||||
# Symmetric ciphers
|
||||
# They also allow to choose the TLS version.
|
||||
CIPHERS = [
|
||||
# TLS 1.3
|
||||
"AES_256_GCM_SHA384",
|
||||
"AES_128_GCM_SHA256",
|
||||
"CHACHA20_POLY1305_SHA256",
|
||||
# TLS 1.2
|
||||
# ECDSA vs RSA refers to the certificate signature algorithm.
|
||||
# DH is EC is aither case, using the group specified below.
|
||||
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
]
|
||||
KEXES = [
|
||||
"X25519",
|
||||
"SECP256R1",
|
||||
"SECP384R1",
|
||||
]
|
||||
|
||||
# Testing all combinations would be too much. Instead we isolate independent parts.
|
||||
EXPERIMENTS = {
|
||||
# Compare ciphers among implementations and TLS versions
|
||||
"impl-cipher-ver": {
|
||||
"impls": IMPLS,
|
||||
"urls": [URL],
|
||||
"ciphers": [
|
||||
"AES_128_GCM_SHA256",
|
||||
"AES_256_GCM_SHA384",
|
||||
"CHACHA20_POLY1305_SHA256",
|
||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
],
|
||||
"kexes": ["X25519"],
|
||||
"cert": ["prime256v1"],
|
||||
},
|
||||
# Compare signatures among implementations and TLS versions
|
||||
"impl-cert-ver": {
|
||||
"impls": IMPLS,
|
||||
"urls": [URL],
|
||||
"ciphers": [
|
||||
"AES_128_GCM_SHA256",
|
||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
],
|
||||
"kexes": ["X25519"],
|
||||
"cert": ["prime256v1", "secp384r1", "rsa2048", "rsa3072", "rsa4096"],
|
||||
},
|
||||
# Compare key exchange groups among implementations and TLS versions
|
||||
"impl-kex-ver": {
|
||||
"impls": IMPLS,
|
||||
"urls": [URL],
|
||||
"ciphers": [
|
||||
"AES_128_GCM_SHA256",
|
||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
],
|
||||
"kexes": ["X25519", "SECP256R1", "SECP384R1"],
|
||||
"cert": ["prime256v1"],
|
||||
},
|
||||
}
|
||||
|
||||
DOMAINS = []
|
||||
for domain in DOMAINS_:
|
||||
if not domain in DOMAINS:
|
||||
DOMAINS.append(domain)
|
||||
|
||||
# JS to redirect the target domains to local (bypass DNS without altering system's config or webpages or packets)
|
||||
SCRIPT_FIREFOX_HOSTS = """const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService(Ci.nsINativeDNSResolverOverride);
|
||||
gOverride.clearOverrides();
|
||||
var names = """+str(DOMAINS)+""";
|
||||
for(var i in names) {
|
||||
gOverride.addIPOverride(names[i], "127.0.0.1");
|
||||
}
|
||||
"""
|
||||
|
||||
def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str:
|
||||
if arg in args and len(args) > args.index(arg)+n:
|
||||
return args[args.index(arg)+n]
|
||||
else:
|
||||
return default
|
||||
|
||||
def sh(cmds):
|
||||
if type(cmds) == list:
|
||||
for cmd in cmds:
|
||||
os.system(cmd)
|
||||
elif type(cmds) == str:
|
||||
os.system(cmds)
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
def make_sk(outpath, alg):
|
||||
sh({
|
||||
"ed25519": [
|
||||
f"openssl genpkey -out {outpath}.sec1 -algorithm ed25519",
|
||||
f"openssl pkcs8 -topk8 -nocrypt -in {outpath}.sec1 -out {outpath} -outform PEM"
|
||||
],
|
||||
"prime256v1": [
|
||||
f"openssl ecparam -genkey -name prime256v1 -noout -out {outpath}.sec1",
|
||||
f"openssl pkcs8 -topk8 -nocrypt -in {outpath}.sec1 -out {outpath} -outform PEM"
|
||||
],
|
||||
"rsa2048": [
|
||||
f"openssl genrsa -out {outpath} 2048"
|
||||
],
|
||||
"rsa3072": [
|
||||
f"openssl genrsa -out {outpath} 3072"
|
||||
],
|
||||
"rsa4096": [
|
||||
f"openssl genrsa -out {outpath} 4096"
|
||||
],
|
||||
"secp384r1": [
|
||||
f"openssl ecparam -genkey -name secp384r1 -noout -out {outpath}.sec1",
|
||||
f"openssl pkcs8 -topk8 -nocrypt -in {outpath}.sec1 -out {outpath} -outform PEM"
|
||||
],
|
||||
}[alg])
|
||||
|
||||
def make_ca_cert(outpath, skpath):
|
||||
sh(f"openssl req -x509 -new -key {skpath} -sha256 -days 730 -out {outpath} -subj '/CN=Foobar Root CA/C=AT/ST=Lyon/L=Lyon/O=Foobar'")
|
||||
|
||||
def make_cert(outpath, skpath, capath, caskpath, name, domains):
|
||||
sh(f"openssl req -new -key {skpath} -sha256 -out /tmp/tmp.csr -subj '/CN={name}/C=AT/ST=Lyon/L=Lyon/O={name}'")
|
||||
ext = open("/tmp/tmp.v3.ext", "w")
|
||||
ext.write("""authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
""")
|
||||
i = 1
|
||||
for domain in domains:
|
||||
ext.write(f"DNS.{i} = {domain}\n")
|
||||
i += 1
|
||||
ext.write(f"DNS.{i} = {domain}.localhost\n")
|
||||
i += 1
|
||||
ext.write(f"DNS.{i} = {domain}.p2\n")
|
||||
i += 1
|
||||
ext.write(f"DNS.{i} = {domain}.p3\n")
|
||||
i += 1
|
||||
ext.close()
|
||||
|
||||
sh(f"openssl x509 -req -in /tmp/tmp.csr -CA {capath} -CAkey {caskpath} -CAcreateserial -out {outpath} -days 365 -sha256 -extfile /tmp/tmp.v3.ext")
|
||||
|
||||
def get_domain_root(domain):
|
||||
last_dot = domain.rfind(".")
|
||||
penultimate_dot = domain.rfind(".", 0, last_dot)
|
||||
return domain[penultimate_dot+1:]
|
||||
|
||||
# Issue secret keys, CA cert and signed certs for given domains
|
||||
# All using the same algorithm
|
||||
def make_certs(outdir, domains, alg):
|
||||
if outdir[-1] != "/":
|
||||
outdir += "/"
|
||||
|
||||
make_sk(outdir+"ca.key", alg)
|
||||
make_ca_cert(outdir+"ca.crt", outdir+"ca.key")
|
||||
|
||||
# Only make certs for root domains, and include subdomains
|
||||
roots = {}
|
||||
for domain in domains:
|
||||
root = domain
|
||||
if domain.count(".") > 1:
|
||||
root = get_domain_root(domain)
|
||||
if root in roots:
|
||||
roots[root].append(domain)
|
||||
else:
|
||||
roots[root] = [domain]
|
||||
for root in roots:
|
||||
make_sk(outdir+root+".key", alg)
|
||||
make_cert(outdir+root+".crt", outdir+root+".key", outdir+"ca.crt", outdir+"ca.key", root, roots[root])
|
||||
|
||||
RPXY_CONFIGS = {
|
||||
"p1_plain": {
|
||||
"listen_http": 80,
|
||||
"listen_https": 443,
|
||||
"app": """[apps.{app}]
|
||||
server_name = "{domain}"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p2:42002" }}]}}]
|
||||
[apps.{app}_localhost]
|
||||
server_name = "{domain}.localhost"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p2:42002" }}]}}]
|
||||
"""
|
||||
},
|
||||
"p1_tls": {
|
||||
"listen_http": 80,
|
||||
"listen_https": 443,
|
||||
"app": """[apps.{app}]
|
||||
server_name = "{domain}"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p2:43002", tls = true }}], set_host = "{domain}.p2"}}]
|
||||
[apps.{app}_localhost]
|
||||
server_name = "{domain}.localhost"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p2:43002", tls = true }}], set_host = "{domain}.p2"}}]
|
||||
"""
|
||||
},
|
||||
"p2_plain": {
|
||||
"listen_http": 42002,
|
||||
"listen_https": 43002,
|
||||
"app": """[apps.{app}]
|
||||
server_name = "{domain}"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:42003" }}], set_host = "{domain}.p3"}}]
|
||||
[apps.{app}_localhost]
|
||||
server_name = "{domain}.localhost"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:42003" }}], set_host = "{domain}.p3"}}]
|
||||
[apps.{app}_p2]
|
||||
server_name = "{domain}.p2"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:42003" }}], set_host = "{domain}.p3"}}]
|
||||
"""
|
||||
},
|
||||
"p2_tls": {
|
||||
"listen_http": 42002,
|
||||
"listen_https": 43002,
|
||||
"app": """[apps.{app}]
|
||||
server_name = "{domain}"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:43003", tls = true }}], set_host = "{domain}.p3"}}]
|
||||
[apps.{app}_localhost]
|
||||
server_name = "{domain}.localhost"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:43003", tls = true }}], set_host = "{domain}.p3"}}]
|
||||
[apps.{app}_p2]
|
||||
server_name = "{domain}.p2"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}.p3:43003", tls = true }}], set_host = "{domain}.p3"}}]
|
||||
"""
|
||||
},
|
||||
"p3": {
|
||||
"listen_http": 42003,
|
||||
"listen_https": 43003,
|
||||
"app": """[apps.{app}]
|
||||
server_name = "{domain}"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}", tls = true }}], set_host = "{domain}"}}]
|
||||
[apps.{app}_localhost]
|
||||
server_name = "{domain}.localhost"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}", tls = true }}], set_host = "{domain}"}}]
|
||||
[apps.{app}_p3]
|
||||
server_name = "{domain}.p3"
|
||||
tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }}
|
||||
reverse_proxy = [{{ upstream = [{{ location = "{domain}", tls = true }}], set_host = "{domain}"}}]
|
||||
"""
|
||||
},
|
||||
}
|
||||
|
||||
SETUPS = {
|
||||
#"none": {
|
||||
# "rpxy_configs": ["p1_plain", "p2_plain", "p3"],
|
||||
#},
|
||||
#"client": {
|
||||
# "rpxy_configs": ["p1_plain", "p2_tls", "p3"],
|
||||
#},
|
||||
"server": {
|
||||
"rpxy_configs": ["p1_tls", "p2_plain", "p3"],
|
||||
},
|
||||
}
|
||||
|
||||
def make_rpxy_config(outdir, domains, cryptodir):
|
||||
if outdir[-1] != "/":
|
||||
outdir += "/"
|
||||
if cryptodir[-1] != "/":
|
||||
cryptodir += "/"
|
||||
|
||||
for config_name in RPXY_CONFIGS:
|
||||
config = RPXY_CONFIGS[config_name]
|
||||
f = open(outdir+config_name+".toml", "w")
|
||||
f.write("listen_port = {}\nlisten_port_tls = {}\n".format(config["listen_http"], config["listen_https"]))
|
||||
for domain in domains:
|
||||
app = domain.replace(".", "_")
|
||||
root = get_domain_root(domain)
|
||||
f.write(config["app"].format(
|
||||
app=app,
|
||||
domain=domain,
|
||||
cert=cryptodir+root+".crt",
|
||||
key=cryptodir+root+".key",
|
||||
))
|
||||
f.close()
|
||||
|
||||
def make_everything(expdir, domains):
|
||||
os.makedirs(expdir, exist_ok=True)
|
||||
if expdir[-1] != "/":
|
||||
expdir += "/"
|
||||
for alg in CERT_SIGN_ALGS:
|
||||
algdir = expdir+"certs/"+alg
|
||||
os.makedirs(algdir, exist_ok=True)
|
||||
make_certs(algdir, domains, alg)
|
||||
# this will be a symbolic link to the chosen certs directory
|
||||
cryptodir = expdir+"current_certs"
|
||||
for setup in SETUPS:
|
||||
setupdir = expdir+"setups/"+setup
|
||||
os.makedirs(setupdir, exist_ok=True)
|
||||
make_rpxy_config(setupdir, domains, cryptodir)
|
||||
|
||||
def choose_cert_alg(expdir, alg):
|
||||
if expdir[-1] != "/":
|
||||
expdir += "/"
|
||||
try:
|
||||
os.unlink(expdir+"current_certs")
|
||||
except FileNotFoundError as e:
|
||||
pass
|
||||
# WHY is dst pointing to src?????
|
||||
os.symlink(expdir+"certs/"+alg, expdir+"current_certs", True)
|
||||
|
||||
def choose_impl(expdir, p, impl):
|
||||
if expdir[-1] != "/":
|
||||
expdir += "/"
|
||||
os.symlink(os.getcwd()+"/rpxy_rustls_"+impl, expdir+str(p)+"_rpxy", False)
|
||||
|
||||
def run_rpxy(expdir, repodir, setup, p, impl, ciphers=None, kexes=None):
|
||||
if expdir[-1] != "/":
|
||||
expdir += "/"
|
||||
repodir = repodir.removesuffix("/")
|
||||
env = {"RUST_LOG": "debug"}
|
||||
if ciphers:
|
||||
env["CIPHERS"] = ",".join(ciphers)
|
||||
if kexes:
|
||||
env["KEXES"] = ",".join(KEXES)
|
||||
print("RUN", [repodir+"/rpxy_rustls_"+impl, "--config", expdir+"setups/"+setup+"/"+p+".toml"])
|
||||
return subprocess.Popen([repodir+"/rpxy_rustls_"+impl, "--config", expdir+"setups/"+setup+"/"+p+".toml"], env=env)
|
||||
|
||||
# https://stackoverflow.com/questions/8775598/how-to-start-a-background-process-with-nohup-using-fabric
|
||||
def runbg(ssh, cmd, vars={}):
|
||||
strvars = ""
|
||||
for var in vars:
|
||||
strvars += f"export {var}="+vars[var]+" && "
|
||||
return ssh.run(f"{strvars}dtach -n `mktemp -u /tmp/dtach.XXXX` {cmd}")
|
||||
|
||||
def run_exp(ssh, expdir, p2_path, exps):
|
||||
from selenium import webdriver
|
||||
import time
|
||||
import invoke
|
||||
|
||||
logfile = open(expdir+"/log-"+str(int(time.time())), "w")
|
||||
|
||||
driver = webdriver.Firefox()
|
||||
driver.get("about:config")
|
||||
driver.execute_script(SCRIPT_FIREFOX_HOSTS)
|
||||
time.sleep(1)
|
||||
for expname in exps:
|
||||
exp = exps[expname]
|
||||
for impl in exp["impls"]:
|
||||
sh(f"killall rpxy_rustls_{impl}")
|
||||
try:
|
||||
ssh.run(f"killall rpxy_rustls_{impl}")
|
||||
except invoke.exceptions.UnexpectedExit as e:
|
||||
pass
|
||||
for impl in exp["impls"]:
|
||||
for alg in exp["cert"]:
|
||||
for kex in exp["kexes"]:
|
||||
for cipher in exp["ciphers"]:
|
||||
choose_cert_alg(expdir, alg)
|
||||
ssh.run(f"python {p2_path}/exp.py cert {alg}")
|
||||
for setup in SETUPS:
|
||||
print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} {setup}")
|
||||
setupdir = expdir+"setups/"+setup
|
||||
p1 = run_rpxy(expdir, REPODIR, setup, SETUPS[setup]["rpxy_configs"][0], impl)
|
||||
p3 = run_rpxy(expdir, REPODIR, setup, SETUPS[setup]["rpxy_configs"][2], impl)
|
||||
p2_rpxy_config = SETUPS[setup]["rpxy_configs"][1]
|
||||
vars = {"CIPHERS": cipher, "KEXES": kex}
|
||||
|
||||
runbg(ssh, f"{p2_path}/rpxy_rustls_{impl} --config {expdir}/setups/{setup}/{p2_rpxy_config}.toml --log-dir /dev/shm", vars)
|
||||
|
||||
start = time.time()
|
||||
for url in exp["urls"]:
|
||||
driver.get(url)
|
||||
#time.sleep(20)
|
||||
input("???")
|
||||
end = time.time()
|
||||
logfile.write(f"{expname} {impl} {alg} {kex} {cipher} {setup} {start} {end}\n")
|
||||
|
||||
# DO the experiment
|
||||
|
||||
p1.kill()
|
||||
p3.kill()
|
||||
ssh.run(f"killall rpxy_rustls_{impl}")
|
||||
ssh.run(f"killall dtach")
|
||||
logfile.flush()
|
||||
driver.quit()
|
||||
|
||||
def update_certs():
|
||||
import platform
|
||||
dist = platform.freedesktop_os_release()["ID"]
|
||||
if dist == "debian":
|
||||
for alg in CERT_SIGN_ALGS:
|
||||
sh([
|
||||
f"sudo cp {EXPDIR}/certs/{alg}/ca.crt /usr/local/share/ca-certificates/ca-{alg}.crt",
|
||||
f"sudo chown root:root /usr/local/share/ca-certificates/ca-{alg}.crt"
|
||||
])
|
||||
sh("sudo update-ca-certificates")
|
||||
elif dist == "arch":
|
||||
for alg in CERT_SIGN_ALGS:
|
||||
sh([
|
||||
f"sudo cp {EXPDIR}/certs/{alg}/ca.crt /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt",
|
||||
f"sudo chown root:root /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt"
|
||||
])
|
||||
sh("sudo update-ca-trust extract")
|
||||
|
||||
# copy local dir src to remote parent dir dst (src's copy will be a subdir of dst)
|
||||
def upload_dir(ssh, src, dst):
|
||||
src = src.removesuffix("/")
|
||||
src_name = src.split("/")[-1]
|
||||
os.chdir(f"{src}/..")
|
||||
os.system(f"tar -czf {src}/../tmp.tar.gz {src_name}")
|
||||
print(ssh.put(src+"/../tmp.tar.gz", dst))
|
||||
print(ssh.run(f"cd {dst} && tar -xf tmp.tar.gz"))
|
||||
|
||||
def connect_ssh():
|
||||
import fabric
|
||||
ssh_passphrase = "--passphrase" in sys.argv
|
||||
connect_kwargs = {}
|
||||
if ssh_passphrase:
|
||||
import getpass
|
||||
connect_kwargs["passphrase"] = getpass.getpass("Enter passphrase for SSH key: ")
|
||||
if P2_PSW != None:
|
||||
connect_kwargs["password"] = P2_PSW
|
||||
ssh = fabric.Connection(P2_SSH, connect_kwargs=connect_kwargs)
|
||||
return ssh
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2 or sys.argv[1] in ["h", "help", "?", "-h", "-help", "--help", "/?"]:
|
||||
print("""Options:
|
||||
make Create everything
|
||||
cert <alg> Select cert signature algorithm
|
||||
send
|
||||
update-certs
|
||||
run Run experiment
|
||||
|
||||
Signature algorithms:
|
||||
{sig_algs}
|
||||
|
||||
Implementations:
|
||||
{impls}
|
||||
|
||||
Run options:
|
||||
--passphrase Prompt SSH key decryption passphrase (when using pubkey login)
|
||||
""".format(
|
||||
sig_algs=" ".join(CERT_SIGN_ALGS),
|
||||
impls=" ".join(IMPLS),
|
||||
))
|
||||
exit()
|
||||
|
||||
opt = sys.argv[1]
|
||||
if opt == "make":
|
||||
make_everything(EXPDIR, DOMAINS)
|
||||
elif opt == "cert":
|
||||
alg = sys.argv[2]
|
||||
if not alg in CERT_SIGN_ALGS:
|
||||
print("Error: alg must be in", CERT_SIGN_ALGS)
|
||||
exit(1)
|
||||
choose_cert_alg(EXPDIR, alg)
|
||||
elif opt == "send":
|
||||
ssh = connect_ssh()
|
||||
upload_dir(ssh, EXPDIR, "/dev/shm")
|
||||
elif opt == "update-certs":
|
||||
update_certs()
|
||||
elif opt == "run":
|
||||
ssh = connect_ssh()
|
||||
run_exp(ssh, EXPDIR, P2_REPODIR, EXPERIMENTS)
|
||||
else:
|
||||
print("Unknown command, use help for help")
|
||||
exit(1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue