Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map Server as a Service #44

Merged
merged 62 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
bf5e77f
Added duration and duration wrapper from scionproto.
juagargi Jun 30, 2023
b14cfbb
New mapserver command that starts the mapserver.
juagargi Jul 3, 2023
d87adbe
Updated go modules.
juagargi Jul 3, 2023
25b8dd5
Fix bad configuration.
juagargi Jul 12, 2023
297082e
Fix config test to use different package than main.
juagargi Jul 12, 2023
483af0e
Reset flags before setting our own.
juagargi Jul 12, 2023
c2bf54c
Add signal handler.
juagargi Jul 12, 2023
55886fa
Configure connection to DB.
juagargi Jul 12, 2023
118f817
MapResponder created with RSA key argument.
juagargi Jul 12, 2023
1e8f44b
pretty print when the mapserver starts/ends an update.
juagargi Jul 12, 2023
ed6fe0c
Listen scaffolding.
juagargi Jul 12, 2023
a7fe2c2
More Go idiomatic in the run function.
juagargi Jul 12, 2023
e921e50
Ticker and test.
juagargi Jul 12, 2023
ae9096b
RunWhen admits a start time.
juagargi Jul 12, 2023
2a7a69e
Obtain next time of day with same HH:MM:SS.NNNNN
juagargi Jul 12, 2023
90c144e
Finish update ticker.
juagargi Jul 12, 2023
ce6fc79
LogFetcher can retrieve the size of the CT log server.
juagargi Jul 13, 2023
0113ec8
Better test GetSize.
juagargi Aug 7, 2023
fd22669
Use log fetcher interface in map updater.
juagargi Aug 7, 2023
fa8f661
Map udater has a NextBatch() and GetNextBatch methods.
juagargi Aug 7, 2023
7ec7bfb
Connect in testdb takes a tests.T
juagargi Aug 8, 2023
3c2909d
Store and retrieve last index in DB.
juagargi Aug 8, 2023
0babb02
Mapserver updater can continue from last go.
juagargi Aug 8, 2023
5892d6d
Ticker functionallity takes a context when running.
juagargi Aug 8, 2023
960a40f
Adapt the mapserver command to the new changes.
juagargi Aug 8, 2023
d72bd5f
Remove unnecessary stop signal.
juagargi Aug 8, 2023
25d91b3
Cleanup mapserver/updater.
juagargi Aug 8, 2023
313aa87
MapServer uses same timer to update and prune.
juagargi Aug 8, 2023
f6ebdcc
Better RandomX509Cert now.
juagargi Aug 10, 2023
6ee6e36
Create random x509 certs with somewhat valid expirations.
juagargi Aug 11, 2023
db52808
Add Prune certs to DB.
juagargi Aug 11, 2023
06bfa3c
Add mapserver systemd service file.
juagargi Aug 11, 2023
6d95455
Add tool to fix the permissions of mysql.
juagargi Aug 16, 2023
1cc3bf7
Stored proc and funcs for better pruning expired certs.
juagargi Aug 17, 2023
71839ae
The mapserver service correctly prunes now.
juagargi Aug 17, 2023
88d35cc
Comment out all of the pca and policy log integration test.
juagargi Aug 17, 2023
9dbe380
Add the STH as part of the server state.
juagargi Oct 25, 2023
1078926
Cleanup.
juagargi Oct 25, 2023
c680d7f
Multiple fetchers per updater.
juagargi Oct 27, 2023
61c9f10
Add mapserver to Makefile.
juagargi Oct 27, 2023
f8678d8
Moved mapserver configuration to pkg.
juagargi Oct 27, 2023
d222154
Improved RuntimeTest.
juagargi Oct 27, 2023
a53b977
Move MapServer to pkg.
juagargi Oct 27, 2023
ce13513
Update mapserver sample config.
juagargi Oct 27, 2023
9ae98b6
Cleanup, fix call to create test object,
juagargi Oct 27, 2023
f1ca1ed
WIP integration test for mapserver.
juagargi Oct 27, 2023
3b031da
WIP HTTPS API server.
juagargi Oct 28, 2023
933785f
WIP mapserver API.
juagargi Oct 28, 2023
15ab76b
MapServer integration test.
juagargi Oct 28, 2023
3e6fb7f
Add a benchmark for the MapServer responder API.
juagargi Oct 28, 2023
62abeb6
Added benchmark for GetPayloads too.
juagargi Oct 28, 2023
6dcee63
Fix timeout too short, add test.
juagargi Oct 29, 2023
5104e77
Add suggestion.
juagargi Oct 29, 2023
00395dd
Add integration tests rule to Makefile.
juagargi Oct 29, 2023
c03cc85
Changes from review.
juagargi Oct 29, 2023
fa5a145
Skip parsing X509 certs if CSV indicates cert is expired.
juagargi Oct 29, 2023
96b68c2
Add ingest to Makefile.
juagargi Oct 29, 2023
c78755f
Add comment.
juagargi Oct 29, 2023
dcdced0
Added comment, removed unused integration test.
juagargi Oct 31, 2023
94ae7ef
Extract expiration from CSV as last column. Comments.
juagargi Dec 18, 2023
9475b96
API point to obtain policy payloads.
juagargi Dec 18, 2023
af7492b
Wording.
juagargi Dec 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 17 additions & 36 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,56 +1,37 @@
.PHONY: all clean test policy_log

all: build_policy_log build_integration_test build_benchmark
all: build_mapserver build_ingest build_policy_log build_integration_test

clean:
@rm -f bin/*

test:
@go test ./...
@echo "Tests OK"

integration: build_integration_test
@# ./bin/test_policylog_interaction
@# ./bin/test_smt
./bin/test_mapserver
@echo "All integration tests OK"

build_mapserver:
@go build -o bin/mapserver ./cmd/mapserver/

build_ingest:
@go build -o bin/ingest ./cmd/ingest/

build_policy_log:
@go build -o bin/logserver_exec cmd/logserver/logserver_exec.go
@go build -o bin/logsigner_exec cmd/logsigner/logsigner_exec.go

setup_db: create_log_database create_fpki_table

create_fpki_schema_replace_old:
@./tools/create_schema.sh

create_log_database:
@./scripts/reset_db/resetdb.sh

build_integration_test:
@go build -o ./bin/test_policylog_interaction ./tests/integration/policylog_interaction
@go build -o ./bin/test_domainowner_pca_policlog_interaction ./tests/integration/domainowner_pca_policlog_interaction
@go build -o ./bin/test_mapserver ./tests/integration/mapserver
@go build -o ./bin/test_smt ./tests/integration/smt
@go build -o ./bin/test_grpc ./tests/integration/grpc_test
@# @go build -o ./bin/test_policylog_interaction ./tests/integration/policylog_interaction
@# @go build -o ./bin/test_smt ./tests/integration/smt
@go build -o ./bin/test_mapserver ./tests/integration/mapserver/

drop_cacheTable:
@mysql -u root -e "DROP TABLE map.deleteTest;"

run_integration_test:
@./scripts/integration_tests.sh

build_benchmark:
@go build -o ./bin/log_benchmark ./tests/benchmark/logserver_benchmark
@go build -o ./bin/smt_benchmark ./tests/benchmark/smt_benchmark
@go build -o ./bin/db_benchmark ./tests/benchmark/db_benchmark
@go build -o ./bin/updater_benchmark ./tests/benchmark/mapserver_benchmark/updater_benchmark
@go build -o ./bin/responder_benchmark ./tests/benchmark/mapserver_benchmark/responder_benchmark

run_log_benchmark:
@./scripts/log_benchmark.sh

run_smt_benchmark:
@./bin/smt_benchmark

run_db_benchmark:
@./bin/db_benchmark

run_updater_benchmark:
@./bin/updater_benchmark

run_responder_benchmark:
@./bin/responder_benchmark
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# FPKI

TODO: This information is old and outdated.

## Features

- Issuance and logging of RPC (Root Policy Certificate)
Expand Down
2 changes: 1 addition & 1 deletion cmd/ingest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func mainFunction() int {

// Now update the SMT Trie with the changed domains:
fmt.Println("Starting SMT update ...")
err = updater.UpdateSMT(ctx, conn, 32)
err = updater.UpdateSMT(ctx, conn)
exitIfError(err)
fmt.Println("Done SMT update.")

Expand Down
31 changes: 31 additions & 0 deletions cmd/ingest/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -172,6 +173,17 @@ func (p *Processor) ingestWithCSV(fileReader io.Reader) error {
reader.FieldsPerRecord = -1 // don't check number of fields

parseFunction := func(fields []string, lineNo int) error {
// First avoid even parsing already expired certs.
n, err := getExpiration(fields)
if err != nil {
return err
}
if p.now.After(time.Unix(n, 0)) {
// Skip this certificate.
return nil
}

// From this point on, we need to parse the certificate.
rawBytes, err := base64.StdEncoding.DecodeString(fields[CertificateColumn])
if err != nil {
return err
Expand Down Expand Up @@ -277,3 +289,22 @@ func (p *Processor) processErrorChannel() error {
}
return nil
}

// getExpiration returns the expiration time in seconds. It is stored already in seconds on the
// last column of the CSV entry, usually index 7.
func getExpiration(fields []string) (int64, error) {
// Because some entries in the CSVs are malformed by not escaping their SAN field, we cannot
// reliably use a column index, but the last column of the entry.
expirationColumn := len(fields) - 1

s := strings.Split(fields[expirationColumn], ".")
if len(s) != 2 {
return 0, fmt.Errorf("unrecognized timestamp in 7th column: %s", fields[expirationColumn])
}
exp, err := strconv.ParseInt(s[0], 10, 64)
if err != nil {
return 0, fmt.Errorf("parsing the expiration time \"%s\" got: %w",
fields[expirationColumn], err)
}
return exp, nil
}
26 changes: 26 additions & 0 deletions cmd/mapserver/config_sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"CTLogServerURLs": [
"https://ct.googleapis.com/logs/xenon2023/"
],
"DBConfig": {
"Dsn": "",
"DBName": "",
"Values": {
"DBNAME": "fpki",
"MYSQL_HOST": "127.0.0.1",
"MYSQL_LOCALSOCKET": "/var/run/mysqld/mysqld.sock",
"MYSQL_PASSWORD": "",
"MYSQL_PORT": "",
"MYSQL_USER": "root",
"collation": "binary",
"interpolateParams": "true",
"maxAllowedPacket": "1073741824",
"parseTime": "true"
},
"CheckSchema": false
},
"CertificatePemFile": "tests/testdata/servercert.pem",
"PrivateKeyPemFile": "tests/testdata/serverkey.pem",
"UpdateAt": "03:00:00",
"UpdateTimer": "1d"
}
145 changes: 145 additions & 0 deletions cmd/mapserver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package main

import (
"context"
"flag"
"fmt"
"os"
"syscall"
"time"

"github.com/netsec-ethz/fpki/pkg/db"
"github.com/netsec-ethz/fpki/pkg/db/mysql"
"github.com/netsec-ethz/fpki/pkg/mapserver"
"github.com/netsec-ethz/fpki/pkg/mapserver/config"
"github.com/netsec-ethz/fpki/pkg/util"
)

const waitForExitBeforePanicTime = 10 * time.Second

func main() {
os.Exit(mainFunc())
}

func mainFunc() int {
// Because some packages (glog) change the flags to main, and we don't want/need them, reset
// the flags before touching them.
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)

// Prepare our flags.
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage:\n%s configuration_file\n", os.Args[0])
flag.PrintDefaults()
}
updateVar := flag.Bool("updateNow", true, "Immediately trigger an update cycle")
createSampleConfig := flag.Bool("createSampleConfig", false,
"Create configuration file specified by positional argument")
flag.Parse()

// We need the configuration file as the first positional argument.
if flag.NArg() != 1 {
flag.Usage()
return 1
}

var err error
if *createSampleConfig {
err = writeSampleConfig()
} else {
err = run(*updateVar)
}

// We have finished. Probably the context created in run was been cancelled (exit request).
// Print message in case of error.
return manageError(err)
}

func writeSampleConfig() error {
dbConfig := db.NewConfig(
mysql.WithDefaults(),
mysql.WithEnvironment(),
mysql.WithLocalSocket("/var/run/mysqld/mysqld.sock"),
)
conf := &config.Config{
DBConfig: dbConfig,
CTLogServerURLs: []string{"https://ct.googleapis.com/logs/xenon2023/"},
CertificatePemFile: "tests/testdata/servercert.pem",
PrivateKeyPemFile: "tests/testdata/serverkey.pem",

UpdateAt: util.NewTimeOfDay(3, 00, 00, 00),
UpdateTimer: util.DurationWrap{
Duration: 24 * time.Hour,
},
}

return config.WriteConfigurationToFile(flag.Arg(0), conf)
}

func run(updateNow bool) error {
ctx := context.Background()

// Set SIGTERM handler. The context we get is cancelled if one of those signals is caught.
ctx = util.SetSignalHandler(ctx, waitForExitBeforePanicTime, syscall.SIGTERM, syscall.SIGINT)

// Load configuration and run with it.
config, err := config.ReadConfigFromFile(flag.Arg(0))
if err != nil {
return err
}

return runWithConfig(ctx, config, updateNow)
}

// runWithConfig examines the configuration, and according to its values, starts a timer to
// run the update cycle at the corresponding time.
func runWithConfig(
ctx context.Context,
conf *config.Config,
updateNow bool,
) error {

server, err := mapserver.NewMapServer(ctx, conf)
if err != nil {
return err
}

// Should update now?
if updateNow {
err := server.PruneAndUpdate(ctx)
if err != nil {
return fmt.Errorf("performing initial update: %w", err)
}
}

// Set update cycle timer.
util.RunWhen(ctx, conf.UpdateAt.NextTimeOfDay(), conf.UpdateTimer.Duration,
func(ctx context.Context) {
err := server.PruneAndUpdate(ctx)
if err != nil {
fmt.Printf("ERROR: update returned %s\n", err)
}
})

// Listen in responder.
err = server.Listen(ctx)

// Regardless of the error, clean everything up.
cleanUp()

// Return the error from the responder.
return err
}

func cleanUp() {
fmt.Println("cleaning up")
}

func manageError(err error) int {
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}

fmt.Println("exiting")
return 0
}
18 changes: 18 additions & 0 deletions cmd/mapserver/mapserver.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Description=Map Server Service. Updates automatically depending on configuration.
Documentation=https://github.com/netsec-ethz/fpki
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=fpki
Group=fpki
ExecStart=/usr/bin/mapserver --config /etc/fpki/config.json
Restart=always
RestartSec=5 # wait 5 seconds if app crashes
RemainAfterExit=False # report status bad if process is not running
KillMode=control-group

[Install]
WantedBy=multi-user.target
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ require (
github.com/stretchr/testify v1.7.4
github.com/transparency-dev/merkle v0.0.1
go.uber.org/atomic v1.9.0
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad
golang.org/x/net v0.1.0
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
google.golang.org/grpc v1.47.0
google.golang.org/protobuf v1.28.0
Expand Down Expand Up @@ -105,12 +106,12 @@ require (
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.org/x/tools v0.2.0 // indirect
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
google.golang.org/api v0.77.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand Down
Loading