auth: config for a non dev mode,

self gen tls certs, force https in non dev

Change-Id: I7faa6b35f44a7925b06d22ade7f5986a12728362
This commit is contained in:
mpl 2011-11-10 16:20:22 +01:00
parent edf4da987e
commit e233c981e0
4 changed files with 351 additions and 5 deletions

View File

@ -1,6 +1,7 @@
{ "_for-emacs": "-*- mode: js2;-*-",
"baseURL": ["_env", "${CAMLI_BASEURL}"],
"password": ["_env", "${CAMLI_PASSWORD}"],
"httpsOnly": false,
"prefixes": {
"/": {
"handler": "root",

179
config/server-config.json Normal file
View File

@ -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"
}
}
}
}

View File

@ -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)
}
}

92
start-server Executable file
View File

@ -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);