mirror of
https://github.com/aljazceru/cyphernode.git
synced 2026-02-01 10:44:26 +01:00
TOR keys and hostname not created during setup
This commit is contained in:
@@ -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: {
|
||||
|
||||
47
cyphernodeconf_docker/lib/torgen.js
Normal file
47
cyphernodeconf_docker/lib/torgen.js
Normal 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 "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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?
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
},
|
||||
"then": {
|
||||
"required": [
|
||||
"tor_datapath"
|
||||
"tor_datapath",
|
||||
"torifyables",
|
||||
"clearnet"
|
||||
]
|
||||
|
||||
@@ -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
|
||||
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
21
dist/setup.sh
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user