mirror of https://github.com/perkeep/perkeep.git
auth: config for a non dev mode,
self gen tls certs, force https in non dev Change-Id: I7faa6b35f44a7925b06d22ade7f5986a12728362
This commit is contained in:
parent
edf4da987e
commit
e233c981e0
|
@ -1,6 +1,7 @@
|
|||
{ "_for-emacs": "-*- mode: js2;-*-",
|
||||
"baseURL": ["_env", "${CAMLI_BASEURL}"],
|
||||
"password": ["_env", "${CAMLI_PASSWORD}"],
|
||||
"httpsOnly": false,
|
||||
"prefixes": {
|
||||
"/": {
|
||||
"handler": "root",
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
{ "_for-emacs": "-*- mode: js2;-*-",
|
||||
"baseURL": ["_env", "${CAMLI_BASEURL}"],
|
||||
"password": ["_env", "${CAMLI_PASSWORD}"],
|
||||
"httpsOnly": true,
|
||||
"TLSCertFile": "config/selfgen_cert.pem",
|
||||
"TLSKeyFile": "config/selfgen_key.pem",
|
||||
"prefixes": {
|
||||
"/": {
|
||||
"handler": "root",
|
||||
"handlerArgs": {
|
||||
"stealth": false
|
||||
}
|
||||
},
|
||||
|
||||
"/blog/": {
|
||||
"handler": "publish",
|
||||
"handlerArgs": {
|
||||
"rootName": "dev-blog-root",
|
||||
"blobRoot": "/bs/",
|
||||
"searchRoot": "/my-search/",
|
||||
"cache": "/cache/",
|
||||
"devBootstrapPermanodeUsing": "/sighelper/"
|
||||
}
|
||||
},
|
||||
|
||||
"/pics/": {
|
||||
"handler": "publish",
|
||||
"handlerArgs": {
|
||||
"rootName": "dev-pics-root",
|
||||
"blobRoot": "/bs/",
|
||||
"searchRoot": "/my-search/",
|
||||
"cache": "/cache/",
|
||||
"scaledImage": "lrucache",
|
||||
"css": ["pics.css"],
|
||||
"js": ["camli.js", "pics.js"],
|
||||
"devBootstrapPermanodeUsing": "/sighelper/"
|
||||
}
|
||||
},
|
||||
|
||||
"/stub-test-disable/": {
|
||||
"handler": "publish",
|
||||
"enabled": false,
|
||||
"handlerArgs": {
|
||||
}
|
||||
},
|
||||
|
||||
"/ui/": {
|
||||
"handler": "ui",
|
||||
"handlerArgs": {
|
||||
"blobRoot": "/bs-and-maybe-also-index/",
|
||||
"searchRoot": "/my-search/",
|
||||
"jsonSignRoot": "/sighelper/",
|
||||
"cache": "/cache/",
|
||||
"scaledImage": "lrucache",
|
||||
"publishRoots": ["/blog/", "/pics/"]
|
||||
}
|
||||
},
|
||||
|
||||
"/sync/": {
|
||||
"handler": "sync",
|
||||
"handlerArgs": {
|
||||
"from": "/bs/",
|
||||
"to": "/indexer/"
|
||||
}
|
||||
},
|
||||
|
||||
"/sighelper/": {
|
||||
"handler": "jsonsign",
|
||||
"handlerArgs": {
|
||||
"secretRing": ["_env", "${CAMLI_SECRET_RING}"],
|
||||
"keyId": "26F5ABDA",
|
||||
"publicKeyDest": "/bs/"
|
||||
}
|
||||
},
|
||||
|
||||
"/bs-and-index/": {
|
||||
"handler": "storage-replica",
|
||||
"handlerArgs": {
|
||||
"backends": ["/bs/", "/indexer/"]
|
||||
}
|
||||
},
|
||||
|
||||
"/bs-and-maybe-also-index/": {
|
||||
"handler": "storage-cond",
|
||||
"handlerArgs": {
|
||||
"write": {
|
||||
"if": "isSchema",
|
||||
"then": "/bs-and-index/",
|
||||
"else": "/bs/"
|
||||
},
|
||||
"read": "/bs/"
|
||||
}
|
||||
},
|
||||
|
||||
"/bs/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/cache/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_CACHE}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/sharder/": {
|
||||
"handler": "storage-shard",
|
||||
"handlerArgs": {
|
||||
"backends": ["/s1/", "/s2/"]
|
||||
}
|
||||
},
|
||||
|
||||
"/s1/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_SHARD1}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/s2/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_SHARD2}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/repl/": {
|
||||
"handler": "storage-replica",
|
||||
"handlerArgs": {
|
||||
"backends": ["/r1/", "/r2/", "/r3/"],
|
||||
"minWritesForSuccess": 2
|
||||
}
|
||||
},
|
||||
|
||||
"/r1/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_REPLICA1}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/r2/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_REPLICA2}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/r3/": {
|
||||
"handler": "storage-filesystem",
|
||||
"handlerArgs": {
|
||||
"path": ["_env", "${CAMLI_ROOT_REPLICA3}"]
|
||||
}
|
||||
},
|
||||
|
||||
"/indexer/": {
|
||||
"handler": "storage-mysqlindexer",
|
||||
"handlerArgs": {
|
||||
"database": ["_env", "${CAMLI_DBNAME}"],
|
||||
"user": "root",
|
||||
"password": "root",
|
||||
"host": "127.0.0.1",
|
||||
"blobSource": "/bs/"
|
||||
}
|
||||
},
|
||||
|
||||
"/my-search/": {
|
||||
"handler": "search",
|
||||
"handlerArgs": {
|
||||
"index": "/indexer/",
|
||||
"owner": "sha1-ad87ca5c78bd0ce1195c46f7c98e6025abbaf007"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,11 +17,18 @@ limitations under the License.
|
|||
package main
|
||||
|
||||
import (
|
||||
"big"
|
||||
"crypto/x509/pkix"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -42,6 +49,9 @@ import (
|
|||
_ "camli/server" // UI, publish, etc
|
||||
)
|
||||
|
||||
const defCert = "config/selfgen_cert.pem"
|
||||
const defKey = "config/selfgen_key.pem"
|
||||
|
||||
var flagConfigFile = flag.String("configfile", "serverconfig",
|
||||
"Config file to use, relative to camli config dir root, or blank to not use config files.")
|
||||
|
||||
|
@ -53,6 +63,60 @@ func exitFailure(pattern string, args ...interface{}) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Mostly copied from $GOROOT/src/pkg/crypto/tls/generate_cert.go
|
||||
func genSelfTLS() os.Error {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate private key: %s", err)
|
||||
}
|
||||
|
||||
now := time.Seconds()
|
||||
|
||||
baseurl := os.Getenv("CAMLI_BASEURL")
|
||||
if baseurl == "" {
|
||||
return fmt.Errorf("CAMLI_BASEURL is not set")
|
||||
}
|
||||
split := strings.Split(baseurl, ":")
|
||||
hostname := split[1]
|
||||
hostname = hostname[2:len(hostname)]
|
||||
println(hostname)
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: new(big.Int).SetInt64(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: hostname,
|
||||
Organization: []string{hostname},
|
||||
},
|
||||
NotBefore: time.SecondsToUTC(now - 300),
|
||||
NotAfter: time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year.
|
||||
|
||||
SubjectKeyId: []byte{1, 2, 3, 4},
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create certificate: %s", err)
|
||||
}
|
||||
|
||||
certOut, err := os.Create(defCert)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open %s for writing: %s", defCert, err)
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
log.Printf("written %s\n", defCert)
|
||||
|
||||
keyOut, err := os.OpenFile(defKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open %s for writing:", defKey, err)
|
||||
}
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
log.Printf("written %s\n", defKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
|
@ -69,11 +133,21 @@ func main() {
|
|||
baseURL := ws.BaseURL()
|
||||
|
||||
{
|
||||
cert, key := config.OptionalString("TLSCertFile", ""), config.OptionalString("TLSKeyFile", "")
|
||||
if (cert != "") != (key != "") {
|
||||
exitFailure("TLSCertFile and TLSKeyFile must both be either present or absent")
|
||||
}
|
||||
if cert != "" {
|
||||
secure := config.OptionalBool("httpsOnly", true)
|
||||
if secure {
|
||||
cert, key := config.OptionalString("TLSCertFile", ""), config.OptionalString("TLSKeyFile", "")
|
||||
if (cert != "") != (key != "") {
|
||||
exitFailure("TLSCertFile and TLSKeyFile must both be either present or absent")
|
||||
}
|
||||
|
||||
if cert == "" && key == "" {
|
||||
err = genSelfTLS()
|
||||
if err != nil {
|
||||
exitFailure("pb generating the self signed creds: %q", err)
|
||||
}
|
||||
cert = defCert
|
||||
key = defKey
|
||||
}
|
||||
ws.SetTLS(cert, key)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use FindBin qw($Bin);
|
||||
use Getopt::Long;
|
||||
|
||||
sub usage {
|
||||
die "Usage: server [--wipe] <portnumber> -- [other_blobserver_opts]";
|
||||
}
|
||||
|
||||
my $opt_wipe;
|
||||
my $opt_nobuild;
|
||||
my $opt_all; # listen on all interfaces
|
||||
GetOptions("wipe" => \$opt_wipe,
|
||||
"all" => \$opt_all,
|
||||
"nobuild" => \$opt_nobuild,
|
||||
)
|
||||
or usage();
|
||||
|
||||
my $port = shift;
|
||||
$port = "3179" unless defined($port);
|
||||
usage() unless $port =~ /^\d+$/;
|
||||
|
||||
unless ($opt_nobuild) {
|
||||
system("./build.pl", "server/go/camlistored") and die "Failed to build camlistored";
|
||||
system("./build.pl", "clients/go/camdbinit") and die "Failed to build camdbinit";
|
||||
}
|
||||
|
||||
my $root = "/tmp/camliroot-$ENV{USER}/port$port/";
|
||||
if ($opt_wipe && -d $root) {
|
||||
print "Wiping $root\n";
|
||||
system("rm", "-rf", $root) and die "Failed to wipe $root.\n";
|
||||
}
|
||||
|
||||
my $suffixdir = sub {
|
||||
my $suffix = shift;
|
||||
my $root = "$root/$suffix";
|
||||
unless (-d $root) {
|
||||
system("mkdir", "-p", $root) and die "Failed to create $root.\n";
|
||||
}
|
||||
return $root;
|
||||
};
|
||||
|
||||
my $DBNAME = "devcamli$ENV{USER}";
|
||||
my @opts;
|
||||
if ($opt_wipe) {
|
||||
push @opts, "-wipe";
|
||||
} else {
|
||||
push @opts, "-ignoreexists";
|
||||
}
|
||||
|
||||
system("./clients/go/camdbinit/camdbinit",
|
||||
"-user=root",
|
||||
"-password=root",
|
||||
"-host=localhost",
|
||||
"-database=$DBNAME",
|
||||
@opts) and die "Failed to run camdbinit.\n";
|
||||
|
||||
my $base = "https://localhost:$port";
|
||||
my $listen = "127.0.0.1:$port";
|
||||
if ($opt_all) {
|
||||
$listen = "0.0.0.0:$port";
|
||||
my $host = `hostname`;
|
||||
chomp $host;
|
||||
$base = "https://$host:$port";
|
||||
}
|
||||
|
||||
print "Starting dev server on $base/ui/ with password \"pass$port\"\n";
|
||||
|
||||
$ENV{CAMLI_BASEURL} = $base;
|
||||
$ENV{CAMLI_PASSWORD} = "pass$port";
|
||||
# do we simply set that one to empty in non dev, or do we deal with it in auth/auth.go ?
|
||||
$ENV{CAMLI_ADVERTISED_PASSWORD} = ""; # public password
|
||||
$ENV{CAMLI_ROOT} = $suffixdir->("bs");
|
||||
$ENV{CAMLI_ROOT_SHARD1} = $suffixdir->("s1");
|
||||
$ENV{CAMLI_ROOT_SHARD2} = $suffixdir->("s2");
|
||||
$ENV{CAMLI_ROOT_REPLICA1} = $suffixdir->("r1");
|
||||
$ENV{CAMLI_ROOT_REPLICA2} = $suffixdir->("r2");
|
||||
$ENV{CAMLI_ROOT_REPLICA3} = $suffixdir->("r3");
|
||||
$ENV{CAMLI_ROOT_CACHE} = $suffixdir->("cache");
|
||||
$ENV{CAMLI_PORT} = $port;
|
||||
$ENV{CAMLI_SECRET_RING} = "$Bin/lib/go/camli/jsonsign/testdata/test-secring.gpg";
|
||||
$ENV{CAMLI_DBNAME} = $DBNAME;
|
||||
|
||||
# To use resources from disk, instead of the copies linked into the
|
||||
# binary:
|
||||
$ENV{CAMLI_DEV_UI_FILES} = "$FindBin::Bin/server/go/camlistored/ui"; # set in server/go/camlistored/ui/fileembed.go
|
||||
|
||||
exec("$FindBin::Bin/server/go/camlistored/camlistored",
|
||||
"-configfile=$Bin/config/server-config.json",
|
||||
"-listen=$listen",
|
||||
@ARGV);
|
Loading…
Reference in New Issue