TOR keys and hostname not created during setup

This commit is contained in:
kexkey
2019-12-05 21:17:27 -05:00
committed by kexkey
parent 4fd8f445f4
commit 51cb4a2e9a
9 changed files with 162 additions and 131 deletions

View File

@@ -14,6 +14,7 @@ const ejsRenderFileAsync = promisify( ejs.renderFile ).bind( ejs );
const html2ansi = require('./html2ansi.js');
const name = require('./name.js');
const Archive = require('./archive.js');
const TorGen = require('./torgen.js');
const ApiKey = require('./apikey.js');
const Cert = require('./cert.js');
const htpasswd = require( './htpasswd.js');
@@ -271,6 +272,12 @@ module.exports = class App {
async processProps() {
// TOR...
if( this.isChecked( 'features', 'tor' ) ) {
const torgen = new TorGen(this.destinationPath( path.join( destinationDirName, 'tor/hidden_service' ) ));
this.sessionData.tor_hostname = await torgen.generateTorFiles();
}
// creates keys if they don't exist or we say so.
if( this.config.data.gatekeeper_recreatekeys ||
this.config.data.gatekeeper_keys.configEntries.length===0 ) {
@@ -479,7 +486,7 @@ module.exports = class App {
networks: ['cyphernodenet', 'cyphernodeappsnet'],
docker: "cyphernode/tor:" + this.config.docker_versions['cyphernode/tor'],
extra: {
hostname: 'tor_hostname_placeholder',
hostname: this.sessionData.tor_hostname,
}
},
otsclient: {

View File

@@ -0,0 +1,47 @@
const spawn = require('child_process').spawn;
const stringio = require('@rauschma/stringio');
const fs = require('fs');
const chalk = require('chalk');
module.exports = class TorGen {
constructor( path ) {
this.path = path || './'
}
async generateTorFiles() {
// console.log(chalk.green( 'TOR datapath=' + this.path ));
if( !fs.existsSync(this.path) ) {
console.log(chalk.green( 'Creating TOR Hidden Service directory...' ));
fs.mkdirSync(this.path, { recursive: true });
}
if( !fs.existsSync(this.path + '/hostname') ) {
console.log(chalk.bold.green( 'Generating TOR Hidden Service secret key, public key and hostname...' ));
const torgenbin = spawn('./torgen/torgen', [this.path]);
try {
await stringio.onExit( torgenbin );
} catch( err ) {
console.log(chalk.bold.red('Error: ' + err) );
return "";
}
// console.log(chalk.bold.green( 'Generated TOR Hidden Service secret key, public key and hostname.' ));
} else {
console.log(chalk.red('TOR config files already exist, skipping generation') );
}
try {
var data = fs.readFileSync(this.path + '/hostname', 'utf8');
return data.slice(0, -1);
} catch (err) {
console.log(chalk.bold.red('Error: ' + err) );
return "";
}
}
}

View File

@@ -27,22 +27,22 @@ module.exports = {
name: 'torifyables',
message: prefix()+'What features do you want to TORify?'+utils.getHelp('torifyables'),
choices: utils.torifyableChoices()
},
{
when: featureCondition,
type: 'checkbox',
name: 'clearnet',
default: utils.getDefault( 'clearnet' ),
message: prefix()+'What features do you want to allow using clearnet?'+utils.getHelp('clearnet'),
choices: [{
name: "Bitcoin Node",
value: "clearnet_bitcoinnode"
},{
name: "LN Node",
value: "clearnet_lnnode"
}]
}];
},
{
when: featureCondition,
type: 'checkbox',
name: 'clearnet',
default: utils.getDefault( 'clearnet' ),
message: prefix()+'What features do you want to allow using clearnet?'+utils.getHelp('clearnet'),
choices: [{
name: "Bitcoin Node",
value: "clearnet_bitcoinnode"
},{
name: "LN Node",
value: "clearnet_lnnode"
}]
},
templates: function( props ) {
return [ 'torrc' ];
}
@@ -67,11 +67,11 @@ module.exports = {
// - Address Watches Callbacks (webhooks)
// - TXID Watches Callbacks (webhooks)
Certain services can also use clearnet. What do you want to allow to use clearnet?
- Bitcoin Node
- LN Node
Do you want to announce your LN node onion address and/or IP address?
What is your public IP address?
// Certain services can also use clearnet. What do you want to allow to use clearnet?
// - Bitcoin Node
// - LN Node
//
// Do you want to announce your LN node onion address and/or IP address?
//
// What is your public IP address?

View File

@@ -99,7 +99,7 @@
},
"then": {
"required": [
"tor_datapath"
"tor_datapath",
"torifyables",
"clearnet"
]

View File

@@ -16,10 +16,10 @@ rgb=<%= lightning_nodecolor %>
addr=0.0.0.0:9735
<% if ( features.indexOf('tor_lnnode') !== -1 ) { %>
<% if ( torifyables.indexOf('tor_lnnode') !== -1 ) { %>
#tor
proxy=tor:9050
<% if ( features.indexOf('clearnet_lnnode') == -1 ) { %>
<% if ( clearnet.indexOf('clearnet_lnnode') == -1 ) { %>
always-use-proxy=true
<% } %>
#disable-dns
@@ -29,10 +29,11 @@ announce-addr=<%= locals.lightning_external_ip %>:9735
<% } %>
<% } %>
<% if (lightning_announce) { %>
<% if ( features.indexOf('tor_lnnode') !== -1 ) { %>
<% if ( torifyables.indexOf('tor_lnnode') !== -1 ) { %>
announce-addr=<%= locals.lightning_external_ip %>:1234
<% if ( features.indexOf('clearnet_lnnode') == -1 ) { %>
announce-addr=onionaddress:9735
<% if ( clearnet.indexOf('clearnet_lnnode') == -1 ) { %>
announce-addr=<%= locals.tor_hostname %>:9735
<% } %>
<% } %>
<% } %>

View File

@@ -1,4 +1,4 @@
<% if ( features.indexOf('tor_hiddenservice') !== -1 ) { %>
<% if ( torifyables.indexOf('tor_hiddenservice') !== -1 ) { %>
HiddenServiceDir /tor/hidden_service/
HiddenServiceVersion 3
HiddenServicePort 80 traefik:80

View File

@@ -25,101 +25,101 @@
package main
import (
"bytes"
"encoding/base32"
"fmt"
"os"
"path"
"strings"
"bytes"
"encoding/base32"
"fmt"
"os"
"path"
"strings"
"crypto/ed25519"
"crypto/sha512"
"crypto/ed25519"
"crypto/sha512"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/sha3"
)
func main() {
path := path.Clean(os.Args[1])
fmt.Println("path=" + path)
path := path.Clean(os.Args[1])
fmt.Println("path=" + path)
/**
About the key files format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_format.c?h=tor-0.4.1.6#n34
/**
About the key files format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_format.c?h=tor-0.4.1.6#n34
Write the <b>datalen</b> bytes from <b>data</b> to the file named
<b>fname</b> in the tagged-data format. This format contains a
32-byte header, followed by the data itself. The header is the
NUL-padded string "== <b>typestring</b>: <b>tag</b> ==". The length
of <b>typestring</b> and <b>tag</b> must therefore be no more than
24.
Write the <b>datalen</b> bytes from <b>data</b> to the file named
<b>fname</b> in the tagged-data format. This format contains a
32-byte header, followed by the data itself. The header is the
NUL-padded string "== <b>typestring</b>: <b>tag</b> ==". The length
of <b>typestring</b> and <b>tag</b> must therefore be no more than
24.
About the secret key format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_ed25519.h?h=tor-0.4.1.6#n29
About the secret key format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_ed25519.h?h=tor-0.4.1.6#n29
Note that we store secret keys in an expanded format that doesn't match
the format from standard ed25519. Ed25519 stores a 32-byte value k and
expands it into a 64-byte H(k), using the first 32 bytes for a multiplier
of the base point, and second 32 bytes as an input to a hash function
for deriving r. But because we implement key blinding, we need to store
keys in the 64-byte expanded form.
**/
Note that we store secret keys in an expanded format that doesn't match
the format from standard ed25519. Ed25519 stores a 32-byte value k and
expands it into a 64-byte H(k), using the first 32 bytes for a multiplier
of the base point, and second 32 bytes as an input to a hash function
for deriving r. But because we implement key blinding, we need to store
keys in the 64-byte expanded form.
**/
// Key pair generation
fmt.Println("Generating ed25519 keys...")
publicKey, privateKey, _ := ed25519.GenerateKey(nil)
// Key pair generation
fmt.Println("Generating ed25519 keys...")
publicKey, privateKey, _ := ed25519.GenerateKey(nil)
// Convert seed to expanded private key...
// Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/ed25519/donna/ed25519_tor.c?h=tor-0.4.1.6#n61
// Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/curve25519_donna/README?h=tor-0.4.1.6#n28
fmt.Println("Converting keys for TOR...")
h := sha512.Sum512(privateKey[:32])
h[0] &= 248
h[31] &= 127
h[31] |= 64
// Convert seed to expanded private key...
// Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/ed25519/donna/ed25519_tor.c?h=tor-0.4.1.6#n61
// Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/curve25519_donna/README?h=tor-0.4.1.6#n28
fmt.Println("Converting keys for TOR...")
h := sha512.Sum512(privateKey[:32])
h[0] &= 248
h[31] &= 127
h[31] |= 64
// Create the Tor Hidden Service private key file
fmt.Println("Creating secret file...")
var fileBytes bytes.Buffer
fileBytes.Write([]byte("== ed25519v1-secret: type0 =="))
fileBytes.Write(bytes.Repeat([]byte{0x00}, 3))
fileBytes.Write(h[:])
// Create the Tor Hidden Service private key file
fmt.Println("Creating secret file...")
var fileBytes bytes.Buffer
fileBytes.Write([]byte("== ed25519v1-secret: type0 =="))
fileBytes.Write(bytes.Repeat([]byte{0x00}, 3))
fileBytes.Write(h[:])
prvFile, _ := os.Create(path + "/hs_ed25519_secret_key")
fileBytes.WriteTo(prvFile)
prvFile.Close()
prvFile, _ := os.Create(path + "/hs_ed25519_secret_key")
fileBytes.WriteTo(prvFile)
prvFile.Close()
// Create the Tor Hidden Service public key file
fmt.Println("Creating public file...")
fileBytes.Reset()
fileBytes.Write([]byte("== ed25519v1-public: type0 =="))
fileBytes.Write(bytes.Repeat([]byte{0x00}, 3))
fileBytes.Write([]byte(publicKey))
// Create the Tor Hidden Service public key file
fmt.Println("Creating public file...")
fileBytes.Reset()
fileBytes.Write([]byte("== ed25519v1-public: type0 =="))
fileBytes.Write(bytes.Repeat([]byte{0x00}, 3))
fileBytes.Write([]byte(publicKey))
pubFile, _ := os.Create(path + "/hs_ed25519_public_key")
fileBytes.WriteTo(pubFile)
pubFile.Close()
pubFile, _ := os.Create(path + "/hs_ed25519_public_key")
fileBytes.WriteTo(pubFile)
pubFile.Close()
// From https://github.com/rdkr/oniongen-go
// checksum = H(".onion checksum" || pubkey || version)
fmt.Println("Creating onion address...")
var checksumBytes bytes.Buffer
checksumBytes.Write([]byte(".onion checksum"))
checksumBytes.Write([]byte(publicKey))
checksumBytes.Write([]byte{0x03})
checksum := sha3.Sum256(checksumBytes.Bytes())
// From https://github.com/rdkr/oniongen-go
// checksum = H(".onion checksum" || pubkey || version)
fmt.Println("Creating onion address...")
var checksumBytes bytes.Buffer
checksumBytes.Write([]byte(".onion checksum"))
checksumBytes.Write([]byte(publicKey))
checksumBytes.Write([]byte{0x03})
checksum := sha3.Sum256(checksumBytes.Bytes())
// onion_address = base32(pubkey || checksum || version)
var onionAddressBytes bytes.Buffer
onionAddressBytes.Write([]byte(publicKey))
onionAddressBytes.Write([]byte(checksum[:2]))
onionAddressBytes.Write([]byte{0x03})
onionAddress := base32.StdEncoding.EncodeToString(onionAddressBytes.Bytes())
// onion_address = base32(pubkey || checksum || version)
var onionAddressBytes bytes.Buffer
onionAddressBytes.Write([]byte(publicKey))
onionAddressBytes.Write([]byte(checksum[:2]))
onionAddressBytes.Write([]byte{0x03})
onionAddress := base32.StdEncoding.EncodeToString(onionAddressBytes.Bytes())
// Create the Tor Hidden Service hostname file
fmt.Println("Creating onion address file...")
nameFile, _ := os.Create(path + "/hostname")
nameFile.WriteString(strings.ToLower(onionAddress) + ".onion\n")
nameFile.Close()
// Create the Tor Hidden Service hostname file
fmt.Println("Creating onion address file...")
nameFile, _ := os.Create(path + "/hostname")
nameFile.WriteString(strings.ToLower(onionAddress) + ".onion\n")
nameFile.Close()
fmt.Println("Done!")
fmt.Println("Done!")
}

21
dist/setup.sh vendored
View File

@@ -407,6 +407,7 @@ install_docker() {
fi
copy_file $cyphernodeconf_filepath/tor/torrc $TOR_DATAPATH/torrc 1 $SUDO_REQUIRED
copy_file $cyphernodeconf_filepath/tor/hidden_service/* $TOR_DATAPATH/hidden_service/ 1 $SUDO_REQUIRED
fi
@@ -721,22 +722,6 @@ install() {
fi
}
manage_tor_keys() {
until [ -f hostname ] && [ -f hs_ed25519_secret_key ] && [ -f hs_ed25519_public_key ]
do
sleep 0.1
max=$(($max-1))
if [[ $max == 0 ]]
then
# Kill Tor on timeout and exit with error code 1.
kill -9 $pid >/dev/null 2>&1
rm -f torrc hostname hs_ed25519_secret_key hs_ed25519_public_key
popd >/dev/null 2>&1
exit 1
fi
done
}
CONFIGURE=0
INSTALL=0
RECREATE=0
@@ -829,10 +814,6 @@ if [[ $CONFIGURE == 1 ]]; then
configure $RECREATE
fi
# If TOR is installed, we want to create the Hidden Serivce hostname now to make it
# available to LN and whatever needs it at this point...
manage_tor_keys
if [[ -f "$cyphernodeconf_filepath/installer/config.sh" ]]; then
. "$cyphernodeconf_filepath/installer/config.sh"
fi

View File

@@ -79,12 +79,7 @@ main() {
installation_info)
# GET http://192.168.111.152:8080/info
if [ -f "$DB_PATH/info.json" ]; then
if [ -f "tor/hidden_service/hostname" ]; then
# Replace tor_hostname_placeholder with actual tor hostname from tor file
response=$(sed "s/tor_hostname_placeholder/`tr -d '\n\r' < tor/hidden_service/hostname`/g" "$DB_PATH/info.json")
else
response=$(cat "$DB_PATH/info.json")
fi
response=$(cat "$DB_PATH/info.json")
else
response='{ "error": "missing installation data" }'
fi